[netflow-tools] Tagging

Damien Miller djm at mindrot.org
Thu May 3 08:19:34 EST 2007


On Wed, 2 May 2007, Damien Miller wrote:

> On Thu, 26 Apr 2007, Ralf Kleineisel wrote:
> 
> > Hi,
> > 
> > is it possible to tag flows by their input/output router interface index?
> 
> Not at present, though this patch should teach it how to do it. Are you
> able to test it?

Revised diff, with a fix from Matthew Smart:


Index: filter.c
===================================================================
RCS file: /var/cvs/flowd/filter.c,v
retrieving revision 1.25
diff -u -p -r1.25 filter.c
--- filter.c	12 Dec 2005 03:33:51 -0000	1.25
+++ filter.c	2 May 2007 22:17:42 -0000
@@ -67,6 +67,18 @@ format_rule(const struct filter_rule *ru
 		strlcat(rulebuf, tmpbuf, sizeof(rulebuf));
 	}
 
+	if (rule->match.match_what & FF_MATCH_IFNDX_IN) {
+		snprintf(tmpbuf, sizeof(tmpbuf), "in_ifndx %s%d ",
+		    FRNEG(IFNDX_IN), rule->match.ifndx_in);
+		strlcat(rulebuf, tmpbuf, sizeof(rulebuf));
+	}
+
+	if (rule->match.match_what & FF_MATCH_IFNDX_OUT) {
+		snprintf(tmpbuf, sizeof(tmpbuf), "out_ifndx %s%d ",
+		    FRNEG(IFNDX_OUT), rule->match.ifndx_out);
+		strlcat(rulebuf, tmpbuf, sizeof(rulebuf));
+	}
+
 	if (rule->match.match_what & FF_MATCH_AF) {
 		strlcat(rulebuf, FRNEG(AF), sizeof(rulebuf));
 		if (rule->match.af == AF_INET)
@@ -213,6 +225,16 @@ flow_match(const struct filter_rule *rul
 		    rule->match.agent_masklen) == 0);
 		if ((FRNEG(AGENT_ADDR) && m) || (!FRNEG(AGENT_ADDR) && !m))
 			return (0);
+	}
+
+	if (FRMATCH(IFNDX_IN)) {
+		m = flow->ifndx.if_index_in == rule->match.ifndx_in;
+		FRRET(IFNDX_IN);
+	}
+
+	if (FRMATCH(IFNDX_OUT)) {
+		m = flow->ifndx.if_index_out == rule->match.ifndx_out;
+		FRRET(IFNDX_OUT);
 	}
 
 	if (FRMATCH(AF)) {
Index: filter.h
===================================================================
RCS file: /var/cvs/flowd/filter.h,v
retrieving revision 1.17
diff -u -p -r1.17 filter.h
--- filter.h	12 Dec 2005 03:33:51 -0000	1.17
+++ filter.h	2 May 2007 00:49:52 -0000
@@ -45,6 +45,8 @@ struct filter_action {
 #define FF_MATCH_AF		(1<<8)
 #define FF_MATCH_DAYTIME	(1<<9)
 #define FF_MATCH_ABSTIME	(1<<10)
+#define FF_MATCH_IFNDX_IN	(1<<11)
+#define FF_MATCH_IFNDX_OUT	(1<<12)
 struct filter_match {
 	u_int32_t	match_what;
 	u_int32_t	match_negate;
@@ -55,6 +57,8 @@ struct filter_match {
 	struct xaddr	src_addr;
 	int		dst_masklen;
 	struct xaddr	dst_addr;
+	int		ifndx_in;
+	int		ifndx_out;
 	int		src_port;
 	int		dst_port;
 	int		proto;
Index: flowd.conf.5.in
===================================================================
RCS file: /var/cvs/flowd/flowd.conf.5.in,v
retrieving revision 1.13
diff -u -p -r1.13 flowd.conf.5.in
--- flowd.conf.5.in	12 Dec 2005 03:33:51 -0000	1.13
+++ flowd.conf.5.in	2 May 2007 01:14:58 -0000
@@ -320,6 +320,18 @@ within the packet itself.
 .Xc
 This rule applies to flows whose source or destination address family matches
 that specified.
+.It Ar in_ifndx Xo
+.Oo Ar !\& Oc
+.Ar <index>
+.Xc
+Match traffic whose input interface number matches
+.Ar index .
+.It Ar out_ifndx Xo
+.Oo Ar !\& Oc
+.Ar <index>
+.Xc
+Match traffic whose output interface number matches
+.Ar index .
 .It Ar src Xo
 .Oo !\& Oc
 .Ar <address>/<len> Oo port Oo !\& Oc <port> Oc
@@ -451,6 +463,8 @@ accept days Monday-Friday after 08:30:00
 discard days Sat,Sun
 # Ignore flows sent outside a certain date/time range
 discard after date 20051123 before date 20051124084459
+# Ignore flows coming in interface 10
+discard in_ifndx 10
 .Ed
 .Pp
 .Sh AUTHORS
Index: parse.y
===================================================================
RCS file: /var/cvs/flowd/parse.y,v
retrieving revision 1.34
diff -u -p -r1.34 parse.y
--- parse.y	12 Dec 2005 03:33:51 -0000	1.34
+++ parse.y	2 May 2007 01:04:27 -0000
@@ -105,6 +105,7 @@ static const char *longdays[7] = {
 %token	LISTEN ON JOIN GROUP LOGFILE LOGSOCK STORE PIDFILE FLOW SOURCE
 %token	ALL TAG ACCEPT DISCARD QUICK AGENT SRC DST PORT PROTO TOS ANY
 %token	TCP_FLAGS EQUALS MASK INET INET6 DAYS AFTER BEFORE DATE
+%token  IN_IFNDX OUT_IFNDX
 %token	ERROR
 %token	<v.string>		STRING
 %type	<v.number>		number quick logspec not octet tcp_flags tcp_mask af dayname dayrange daylist dayspec daytime abstime
@@ -112,7 +113,7 @@ static const char *longdays[7] = {
 %type	<v.addr>		address
 %type	<v.addrport>		address_port
 %type	<v.prefix>		prefix prefix_or_any
-%type	<v.filter_match>	match_agent match_src match_dst match_proto match_tos match_tcp_flags match_af match_day match_after match_before match_dayafter match_daybefore match_absafter match_absbefore
+%type	<v.filter_match>	match_agent match_src match_dst match_proto match_tos match_tcp_flags match_af match_day match_after match_before match_dayafter match_daybefore match_absafter match_absbefore match_if_in match_if_out
 %type	<v.filter_action>	action tag
 %%
 
@@ -480,7 +481,7 @@ logspec		: STRING	{
 			free($1);
 		}
 
-filterrule	: action tag quick match_agent match_af match_src match_dst match_proto match_tos match_tcp_flags match_day match_after match_before
+filterrule	: action tag quick match_agent match_if_in match_if_out match_af match_src match_dst match_proto match_tos match_tcp_flags match_day match_after match_before
 		{
 			struct filter_rule	*r;
 
@@ -503,49 +504,57 @@ filterrule	: action tag quick match_agen
 			r->match.match_what |= $4.match_what;
 			r->match.match_negate |= $4.match_negate;
 
-			r->match.af = $5.af;
+			r->match.ifndx_in = $5.ifndx_in;
 			r->match.match_what |= $5.match_what;
 			r->match.match_negate |= $5.match_negate;
 
-			r->match.src_addr = $6.src_addr;
-			r->match.src_masklen = $6.src_masklen;
-			r->match.src_port = $6.src_port;
+			r->match.ifndx_out = $6.ifndx_out;
 			r->match.match_what |= $6.match_what;
 			r->match.match_negate |= $6.match_negate;
-
-			r->match.dst_addr = $7.dst_addr;
-			r->match.dst_masklen = $7.dst_masklen;
-			r->match.dst_port = $7.dst_port;
+			
+			r->match.af = $7.af;
 			r->match.match_what |= $7.match_what;
 			r->match.match_negate |= $7.match_negate;
 
-			r->match.proto = $8.proto;
+			r->match.src_addr = $8.src_addr;
+			r->match.src_masklen = $8.src_masklen;
+			r->match.src_port = $8.src_port;
 			r->match.match_what |= $8.match_what;
 			r->match.match_negate |= $8.match_negate;
 
-			r->match.tos = $9.tos;
+			r->match.dst_addr = $9.dst_addr;
+			r->match.dst_masklen = $9.dst_masklen;
+			r->match.dst_port = $9.dst_port;
 			r->match.match_what |= $9.match_what;
 			r->match.match_negate |= $9.match_negate;
 
-			r->match.tcp_flags_mask = $10.tcp_flags_mask;
-			r->match.tcp_flags_equals = $10.tcp_flags_equals;
+			r->match.proto = $10.proto;
 			r->match.match_what |= $10.match_what;
 			r->match.match_negate |= $10.match_negate;
 
-			r->match.day_mask = $11.day_mask;
+			r->match.tos = $11.tos;
 			r->match.match_what |= $11.match_what;
 			r->match.match_negate |= $11.match_negate;
 
-			r->match.dayafter = $12.dayafter - 1;
-			r->match.absafter = $12.absafter;
+			r->match.tcp_flags_mask = $12.tcp_flags_mask;
+			r->match.tcp_flags_equals = $12.tcp_flags_equals;
 			r->match.match_what |= $12.match_what;
 			r->match.match_negate |= $12.match_negate;
 
-			r->match.daybefore = $13.daybefore - 1;
-			r->match.absbefore = $13.absbefore;
+			r->match.day_mask = $13.day_mask;
 			r->match.match_what |= $13.match_what;
 			r->match.match_negate |= $13.match_negate;
 
+			r->match.dayafter = $14.dayafter - 1;
+			r->match.absafter = $14.absafter;
+			r->match.match_what |= $14.match_what;
+			r->match.match_negate |= $14.match_negate;
+
+			r->match.daybefore = $15.daybefore - 1;
+			r->match.absbefore = $15.absbefore;
+			r->match.match_what |= $15.match_what;
+			r->match.match_negate |= $15.match_negate;
+
 			if ((r->match.match_what & FF_MATCH_DAYTIME) != 0) {
 				if (r->match.dayafter != 0 && 
 				    r->match.daybefore != 0 &&
@@ -670,6 +679,32 @@ match_agent	: /* empty */			{ bzero(&$$,
 af		: INET				{ $$ = AF_INET; }
 		| INET6				{ $$ = AF_INET6; }
 
+match_if_in	: /* empty */			{ bzero(&$$, sizeof($$)); }
+		| IN_IFNDX not number 		{
+			bzero(&$$, sizeof($$));
+			$$.ifndx_in = $3;
+			$$.match_what |= FF_MATCH_IFNDX_IN;
+			$$.match_negate |= $2 ? FF_MATCH_IFNDX_IN : 0;
+			if ($$.ifndx_in <= 0 || $$.ifndx_in > 65535) {
+				yyerror("invalid input interface index");
+				YYERROR;
+			}
+		}
+		;
+
+match_if_out	: /* empty */			{ bzero(&$$, sizeof($$)); }
+		| OUT_IFNDX not number 		{
+			bzero(&$$, sizeof($$));
+			$$.ifndx_out = $3;
+			$$.match_what |= FF_MATCH_IFNDX_OUT;
+			$$.match_negate |= $2 ? FF_MATCH_IFNDX_OUT : 0;
+			if ($$.ifndx_out <= 0 || $$.ifndx_out > 65535) {
+				yyerror("invalid output interface index");
+				YYERROR;
+			}
+		}
+		;
+
 match_af	: /* empty */			{ bzero(&$$, sizeof($$)); }
 		| not af		{
 			bzero(&$$, sizeof($$));
@@ -874,6 +909,7 @@ lookup(char *s)
 		{ "equals",		EQUALS},
 		{ "flow",		FLOW},
 		{ "group",		GROUP},
+		{ "in_ifndx",		IN_IFNDX},
 		{ "inet",		INET},
 		{ "inet6",		INET6},
 		{ "join",		JOIN},
@@ -882,6 +918,7 @@ lookup(char *s)
 		{ "logsock",		LOGSOCK},
 		{ "mask",		MASK},
 		{ "on",			ON},
+		{ "out_ifndx",		OUT_IFNDX},
 		{ "pidfile",		PIDFILE},
 		{ "port",		PORT},
 		{ "proto",		PROTO},


More information about the netflow-tools mailing list