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.