OSEC

Neohapsis is currently accepting applications for employment. For more information, please visit our website www.neohapsis.com or email hr@neohapsis.com
pflow(4): export ingress/egress interface index

From: Florian Obser (florianopenbsd.org)
Date: Fri May 03 2013 - 09:28:59 CDT


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.