pflow(4): export ingress/egress interface index

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

pflow(4): export ingress/egress interface index

Florian Obser-2
Chris Ivancic & Colin Ligertwood reported in January that the
"SolarWinds NetFlow Traffic Analyzer" doesn't like it if the
ingress/egress interface index is always 0 (v5) or not present at all
(v9/v10). This keeps track on which interface a packet for a state was
first observed / first left and exports it in pflow(4).

OK?

Index: if_pflow.c
===================================================================
RCS file: /cvs/src/sys/net/if_pflow.c,v
retrieving revision 1.28
diff -u -p -r1.28 if_pflow.c
--- if_pflow.c 10 Apr 2013 08:50:59 -0000 1.28
+++ if_pflow.c 3 May 2013 14:04:35 -0000
@@ -152,6 +152,12 @@ pflow_clone_create(struct if_clone *ifc,
  pflowif->sc_tmpl.ipv4_tmpl.dest_ip.field_id =
     htons(PFIX_IE_destinationIPv4Address);
  pflowif->sc_tmpl.ipv4_tmpl.dest_ip.len = htons(4);
+ pflowif->sc_tmpl.ipv4_tmpl.if_index_in.field_id =
+    htons(PFIX_IE_ingressInterface);
+ pflowif->sc_tmpl.ipv4_tmpl.if_index_in.len = htons(4);
+ pflowif->sc_tmpl.ipv4_tmpl.if_index_out.field_id =
+    htons(PFIX_IE_egressInterface);
+ pflowif->sc_tmpl.ipv4_tmpl.if_index_out.len = htons(4);
  pflowif->sc_tmpl.ipv4_tmpl.packets.field_id =
     htons(PFIX_IE_packetDeltaCount);
  pflowif->sc_tmpl.ipv4_tmpl.packets.len = htons(8);
@@ -191,6 +197,12 @@ pflow_clone_create(struct if_clone *ifc,
  pflowif->sc_tmpl.ipv6_tmpl.dest_ip.field_id =
     htons(PFIX_IE_destinationIPv6Address);
  pflowif->sc_tmpl.ipv6_tmpl.dest_ip.len = htons(16);
+ pflowif->sc_tmpl.ipv6_tmpl.if_index_in.field_id =
+    htons(PFIX_IE_ingressInterface);
+ pflowif->sc_tmpl.ipv6_tmpl.if_index_in.len = htons(4);
+ pflowif->sc_tmpl.ipv6_tmpl.if_index_out.field_id =
+    htons(PFIX_IE_egressInterface);
+ pflowif->sc_tmpl.ipv6_tmpl.if_index_out.len = htons(4);
  pflowif->sc_tmpl.ipv6_tmpl.packets.field_id =
     htons(PFIX_IE_packetDeltaCount);
  pflowif->sc_tmpl.ipv6_tmpl.packets.len = htons(8);
@@ -563,8 +575,10 @@ copy_flow_data(struct pflow_flow *flow1,
 
  flow1->dest_as = flow2->src_as =
     flow1->src_as = flow2->dest_as = 0;
- flow1->if_index_out = flow2->if_index_in =
-    flow1->if_index_in = flow2->if_index_out = 0;
+ flow1->if_index_in = htons(st->if_index_in);
+ flow1->if_index_out = htons(st->if_index_out);
+ flow2->if_index_in = htons(st->if_index_out);
+ flow2->if_index_out = htons(st->if_index_in);
  flow1->dest_mask = flow2->src_mask =
     flow1->src_mask = flow2->dest_mask = 0;
 
@@ -598,6 +612,11 @@ copy_flow4_data(struct pflow_flow4 *flow
  flow1->dest_ip = flow2->src_ip = sk->addr[dst].v4.s_addr;
  flow1->dest_port = flow2->src_port = sk->port[dst];
 
+ flow1->if_index_in = htonl(st->if_index_in);
+ flow1->if_index_out = htonl(st->if_index_out);
+ flow2->if_index_in = htonl(st->if_index_out);
+ flow2->if_index_out = htonl(st->if_index_in);
+
  flow1->flow_packets = htobe64(st->packets[0]);
  flow2->flow_packets = htobe64(st->packets[1]);
  flow1->flow_octets = htobe64(st->bytes[0]);
@@ -642,6 +661,11 @@ copy_flow6_data(struct pflow_flow6 *flow
  bcopy(&sk->addr[dst].v6, &flow1->dest_ip, sizeof(flow1->dest_ip));
  bcopy(&sk->addr[dst].v6, &flow2->src_ip, sizeof(flow2->src_ip));
  flow1->dest_port = flow2->src_port = sk->port[dst];
+
+ flow1->if_index_in = htonl(st->if_index_in);
+ flow1->if_index_out = htonl(st->if_index_out);
+ flow2->if_index_in = htonl(st->if_index_out);
+ flow2->if_index_out = htonl(st->if_index_in);
 
  flow1->flow_packets = htobe64(st->packets[0]);
  flow2->flow_packets = htobe64(st->packets[1]);
Index: if_pflow.h
===================================================================
RCS file: /cvs/src/sys/net/if_pflow.h,v
retrieving revision 1.7
diff -u -p -r1.7 if_pflow.h
--- if_pflow.h 5 Feb 2013 11:58:39 -0000 1.7
+++ if_pflow.h 3 May 2013 14:04:35 -0000
@@ -40,8 +40,10 @@
 #define PFIX_IE_ipClassOfService  5
 #define PFIX_IE_sourceTransportPort  7
 #define PFIX_IE_sourceIPv4Address  8
+#define PFIX_IE_ingressInterface 10
 #define PFIX_IE_destinationTransportPort 11
 #define PFIX_IE_destinationIPv4Address 12
+#define PFIX_IE_egressInterface 14
 #define PFIX_IE_flowEndSysUpTime 21
 #define PFIX_IE_flowStartSysUpTime 22
 #define PFIX_IE_sourceIPv6Address 27
@@ -91,11 +93,13 @@ struct pflow_tmpl_fspec {
  u_int16_t len;
 } __packed;
 
-/* update pflow_clone_create() when changing pflow_v10_tmpl_v4 */
+/* update pflow_clone_create() when changing pflow_tmpl_ipv4 */
 struct pflow_tmpl_ipv4 {
  struct pflow_tmpl_hdr h;
  struct pflow_tmpl_fspec src_ip;
  struct pflow_tmpl_fspec dest_ip;
+ struct pflow_tmpl_fspec if_index_in;
+ struct pflow_tmpl_fspec if_index_out;
  struct pflow_tmpl_fspec packets;
  struct pflow_tmpl_fspec octets;
  struct pflow_tmpl_fspec start;
@@ -104,15 +108,17 @@ struct pflow_tmpl_ipv4 {
  struct pflow_tmpl_fspec dest_port;
  struct pflow_tmpl_fspec tos;
  struct pflow_tmpl_fspec protocol;
-#define PFLOW_TMPL_IPV4_FIELD_COUNT 10
+#define PFLOW_TMPL_IPV4_FIELD_COUNT 12
 #define PFLOW_TMPL_IPV4_ID 256
 } __packed;
 
-/* update pflow_clone_create() when changing pflow_v10_tmpl_v6 */
+/* update pflow_clone_create() when changing pflow_tmpl_v6 */
 struct pflow_tmpl_ipv6 {
  struct pflow_tmpl_hdr h;
  struct pflow_tmpl_fspec src_ip;
  struct pflow_tmpl_fspec dest_ip;
+ struct pflow_tmpl_fspec if_index_in;
+ struct pflow_tmpl_fspec if_index_out;
  struct pflow_tmpl_fspec packets;
  struct pflow_tmpl_fspec octets;
  struct pflow_tmpl_fspec start;
@@ -121,7 +127,7 @@ struct pflow_tmpl_ipv6 {
  struct pflow_tmpl_fspec dest_port;
  struct pflow_tmpl_fspec tos;
  struct pflow_tmpl_fspec protocol;
-#define PFLOW_TMPL_IPV6_FIELD_COUNT 10
+#define PFLOW_TMPL_IPV6_FIELD_COUNT 12
 #define PFLOW_TMPL_IPV6_ID 257
 } __packed;
 
@@ -134,6 +140,8 @@ struct pflow_tmpl {
 struct pflow_flow4 {
  u_int32_t src_ip; /* sourceIPv4Address*/
  u_int32_t dest_ip; /* destinationIPv4Address */
+ u_int32_t if_index_in; /* ingressInterface */
+ u_int32_t if_index_out; /* egressInterface */
  u_int64_t flow_packets; /* packetDeltaCount */
  u_int64_t flow_octets; /* octetDeltaCount */
  u_int32_t flow_start; /* flowStartSysUpTime */
@@ -148,6 +156,8 @@ struct pflow_flow4 {
 struct pflow_flow6 {
  struct in6_addr src_ip; /* sourceIPv6Address */
  struct in6_addr dest_ip; /* destinationIPv6Address */
+ u_int32_t if_index_in; /* ingressInterface */
+ u_int32_t if_index_out; /* egressInterface */
  u_int64_t flow_packets; /* packetDeltaCount */
  u_int64_t flow_octets; /* octetDeltaCount */
  u_int32_t flow_start; /*
Index: pf.c
===================================================================
RCS file: /cvs/src/sys/net/pf.c,v
retrieving revision 1.822
diff -u -p -r1.822 pf.c
--- pf.c 10 Apr 2013 08:50:59 -0000 1.822
+++ pf.c 3 May 2013 14:04:35 -0000
@@ -7037,6 +7037,12 @@ done:
  action = pf_refragment6(m0, mtag, fwdir);
  }
 #endif
+ if (s && action != PF_DROP) {
+ if (!s->if_index_in && dir == PF_IN)
+ s->if_index_in = ifp->if_index;
+ else if (!s->if_index_out && dir == PF_OUT)
+ s->if_index_out = ifp->if_index;
+ }
 
  return (action);
 }
Index: pfvar.h
===================================================================
RCS file: /cvs/src/sys/net/pfvar.h,v
retrieving revision 1.377
diff -u -p -r1.377 pfvar.h
--- pfvar.h 11 Mar 2013 19:48:40 -0000 1.377
+++ pfvar.h 3 May 2013 14:04:35 -0000
@@ -851,6 +851,8 @@ struct pf_state {
  u_int8_t set_tos;
  u_int8_t set_prio[2];
  u_int16_t max_mss;
+ u_int16_t if_index_in;
+ u_int16_t if_index_out;
  u_int8_t pad2[2];
 };
 

--
I'm not entirely sure you are real.

Reply | Threaded
Open this post in threaded view
|

Re: pflow(4): export ingress/egress interface index

Mike Belopuhov-5
On 3 May 2013 16:28, Florian Obser <[hidden email]> wrote:
> Chris Ivancic & Colin Ligertwood reported in January that the
> "SolarWinds NetFlow Traffic Analyzer" doesn't like it if the
> ingress/egress interface index is always 0 (v5) or not present at all
> (v9/v10). This keeps track on which interface a packet for a state was
> first observed / first left and exports it in pflow(4).
>
> OK?
>

OK, but I think all pads should to be gone from struct pf_state
since it's not packed.  Whatever was the intention, it doesn't
seem to be relevant anymore.