zed.0xff.me

[PATCH] ng_netflow: ifIndex from vlan

Во время оптимизации ng_netflow и выносом его на отдельную машину возникла такая проблема, что вместе с логами трафика из ng_netflow нужно сохранять и номер vlan’а, в котором пришел этот трафик.
Самое очевидное – использовать для этого netflow-поле ifIndex, благо трафик собирается с единственного (пока) роутера, и физических интерфейсов на нём негусто, так что ifIndex фактически не используется.
Самое неочевидное – заставить ng_netflow прописывать в потоках в ifIndex номер vlan’а..

Я пошел недеструктивным путём, и постарался при добавлении нового функционала ничего не сломать :)
В результате в команду NGM_NETFLOW_SETCONFIG добавлено новое значение: NG_NETFLOW_CONF_VLAN = 16, и включается новый режим на интерфейсе так:
(вместо iface=0 и conf=19 пропишите соответственно номер интерфейса и флаги, которые вам нужны, обращая внимание на +16 к значению conf если нужен новый режим установки ifIndex по vlan’у)

1
2
3
ngctl msg netflow: setconfig \{ iface=0 conf=19 \}   # 16 = NG_NETFLOW_CONF_VLAN
                                                     #  2 = NG_NETFLOW_CONF_EGRESS
                                                     #  1 = NG_NETFLOW_CONF_INGRESS

а вот, собственно, и патч:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
diff -ur /usr/src/sys/netgraph/netflow/ng_netflow.c kld/ng_netflow.c
--- /usr/src/sys/netgraph/netflow/ng_netflow.c        2009-04-15 09:14:26.000000000 +0600
+++ kld/ng_netflow.c        2009-09-04 06:25:42.000000000 +0600
@@ -486,7 +486,7 @@
         struct m_tag *mtag;
         int pullup_len = 0;
         int error = 0, bypass = 0;
-        unsigned int src_if_index;
+        unsigned int src_if_index = 0;
 
         if (hook == priv->export) {
                 /*
@@ -585,6 +585,10 @@
                         M_CHECK(sizeof(struct ip));
                         eh = mtod(m, struct ether_header *);
                         ip = (struct ip *)(eh + 1);
+                        if( (m->m_flags & M_VLANTAG) && (iface->info.conf & NG_NETFLOW_CONF_VLAN) ){
+                                // tag is stored out-of-band
+                                src_if_index = EVL_VLANOFTAG(m->m_pkthdr.ether_vtag);
+                        }
                         break;
                 case ETHERTYPE_VLAN:
                     {
@@ -596,6 +600,9 @@
                         if (ntohs(evh->evl_proto) == ETHERTYPE_IP) {
                                 M_CHECK(sizeof(struct ip));
                                 ip = (struct ip *)(evh + 1);
+                                if (iface->info.conf & NG_NETFLOW_CONF_VLAN){
+                                        src_if_index = evh->evl_tag;
+                                }
                                 break;
                         }
                     }
@@ -639,6 +647,10 @@
                 switch (ntohs(eh->ether_type)) {
                 case ETHERTYPE_IP:
                         ip = (struct ip *)(eh + 1);
+                        if( (m->m_flags & M_VLANTAG) && (iface->info.conf & NG_NETFLOW_CONF_VLAN) ){
+                                // tag is stored out-of-band
+                                src_if_index = EVL_VLANOFTAG(m->m_pkthdr.ether_vtag);
+                        }
                         break;
                 case ETHERTYPE_VLAN:
                     {
@@ -646,6 +658,9 @@
 
                         evh = mtod(m, struct ether_vlan_header *);
                         ip = (struct ip *)(evh + 1);
+                        if (iface->info.conf & NG_NETFLOW_CONF_VLAN){
+                                src_if_index = evh->evl_tag;
+                        }
                         break;
                      }
                 default:
@@ -662,13 +677,16 @@
 
 #undef        M_CHECK
 
+
         /* Determine packet input interface. Prefer configured. */
-        src_if_index = 0;
-        if (hook == iface->out || iface->info.ifinfo_index == 0) {
-                if (m->m_pkthdr.rcvif != NULL)
-                        src_if_index = m->m_pkthdr.rcvif->if_index;
-        } else
-                src_if_index = iface->info.ifinfo_index;
+        if(!(iface->info.conf & NG_NETFLOW_CONF_VLAN) || src_if_index == 0){
+                src_if_index = 0;
+                if (hook == iface->out || iface->info.ifinfo_index == 0) {
+                        if (m->m_pkthdr.rcvif != NULL)
+                                src_if_index = m->m_pkthdr.rcvif->if_index;
+                } else
+                        src_if_index = iface->info.ifinfo_index;
+        }
 
         error = ng_netflow_flow_add(priv, ip, src_if_index);
 
diff -ur /usr/src/sys/netgraph/netflow/ng_netflow.h kld/ng_netflow.h
--- /usr/src/sys/netgraph/netflow/ng_netflow.h        2009-04-15 09:14:26.000000000 +0600
+++ kld/ng_netflow.h        2009-09-03 19:27:03.000000000 +0600
@@ -98,6 +98,7 @@
 #define NG_NETFLOW_CONF_EGRESS                2
 #define NG_NETFLOW_CONF_ONCE                4
 #define NG_NETFLOW_CONF_THISONCE        8
+#define NG_NETFLOW_CONF_VLAN                16
 
 /* This structure is passed to NGM_NETFLOW_SETCONFIG */
 struct ng_netflow_setconfig {

оптимизировали ng_netflow

как было :( как стало :)

(картинки кликабельны)