kern/156410: [patch][ipfw] tablearg option for ipfw setfib

Alexander V. Chernikov melifaro at ipfw.ru
Thu Apr 14 21:50:14 UTC 2011


>Number:         156410
>Category:       kern
>Synopsis:       [patch][ipfw] tablearg option for ipfw setfib
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Thu Apr 14 21:50:13 UTC 2011
>Closed-Date:
>Last-Modified:
>Originator:     Alexander V. Chernikov
>Release:        9.0-CURRENT
>Organization:
>Environment:
FreeBSD fbsd9.home.ipfw.ru 9.0-CURRENT FreeBSD 9.0-CURRENT #6: Tue Apr 12 21:08:14 MSD 2011     root at fbsd9.home.ipfw.ru:/var/xtmp/usj/obj/usr/src/sys/DEVEL  amd64

>Description:
The only way to implement setting fib based on some tablearg data is to use ipfw skipto with tablearg pointing to something like 

11000 setfib 0 ip from any to any
11001 skipto 12000 ip from any to any
11002 setfib 1 ip from any to any
11003 skipto 12000 ip from any to any
11004 setfib 2 ip from any to any
11005 skipto 12000 ip from any to any
11006 setfib 3 ip from any to any
11007 skipto 12000 ip from any to any
11008 setfib 4 ip from any to any
11009 skipto 12000 ip from any to any
...

which is not very effective (especially in cases with > 16 fibs) because of skipto implementation
>How-To-Repeat:

>Fix:


Patch attached with submission follows:

Index: sbin/ipfw/ipfw2.c
===================================================================
--- sbin/ipfw/ipfw2.c	(revision 4841)
+++ sbin/ipfw/ipfw2.c	(working copy)
@@ -2827,11 +2827,15 @@
 
 		action->opcode = O_SETFIB;
  		NEED1("missing fib number");
- 	        action->arg1 = strtoul(*av, NULL, 10);
-		if (sysctlbyname("net.fibs", &numfibs, &intsize, NULL, 0) == -1)
-			errx(EX_DATAERR, "fibs not suported.\n");
-		if (action->arg1 >= numfibs)  /* Temporary */
-			errx(EX_DATAERR, "fib too large.\n");
+		if (_substrcmp(*av, "tablearg") == 0) {
+			action->arg1 = IP_FW_TABLEARG;
+		} else {
+	 	        action->arg1 = strtoul(*av, NULL, 10);
+			if (sysctlbyname("net.fibs", &numfibs, &intsize, NULL, 0) == -1)
+				errx(EX_DATAERR, "fibs not suported.\n");
+			if (action->arg1 >= numfibs)  /* Temporary */
+				errx(EX_DATAERR, "fib too large.\n");
+		}
  		av++;
  		break;
 	    }
Index: sbin/ipfw/ipfw.8
===================================================================
--- sbin/ipfw/ipfw.8	2011-04-15 00:54:50.000000000 +0400
+++ sbin/ipfw/ipfw.8	2011-04-15 01:13:53.000000000 +0400
@@ -871,13 +871,16 @@
 and
 .Cm ngtee
 actions.
-.It Cm setfib Ar fibnum
+.It Cm setfib Ar fibnum | tablearg
 The packet is tagged so as to use the FIB (routing table)
 .Ar fibnum
 in any subsequent forwarding decisions.
 Initially this is limited to the values 0 through 15, see
 .Xr setfib 1 .
 Processing continues at the next rule.
+It is possible to use the 
+.Cm tablearg
+keyword with a setfib. If tablearg value is not within compiled FIB range packet fib is set to 0.
 .It Cm reass
 Queue and reassemble ip fragments.
 If the packet is not fragmented, counters are updated and processing continues with the next rule.
@@ -1711,7 +1714,7 @@
 The
 .Cm tablearg
 argument can be used with the following actions:
-.Cm nat, pipe , queue, divert, tee, netgraph, ngtee, fwd, skipto
+.Cm nat, pipe , queue, divert, tee, netgraph, ngtee, fwd, skipto, setfib,
 action parameters:
 .Cm tag, untag,
 rule options:Index: sys/netinet/ipfw/ip_fw_sockopt.c
===================================================================
--- sys/netinet/ipfw/ip_fw_sockopt.c	(revision 4841)
+++ sys/netinet/ipfw/ip_fw_sockopt.c	(working copy)
@@ -605,7 +605,7 @@
 		case O_SETFIB:
 			if (cmdlen != F_INSN_SIZE(ipfw_insn))
 				goto bad_size;
-			if (cmd->arg1 >= rt_numfibs) {
+			if ((cmd->arg1 != IP_FW_TABLEARG) && (cmd->arg1 >= rt_numfibs)) {
 				printf("ipfw: invalid fib number %d\n",
 					cmd->arg1);
 				return EINVAL;
Index: sys/netinet/ipfw/ip_fw2.c
===================================================================
--- sys/netinet/ipfw/ip_fw2.c	(revision 4841)
+++ sys/netinet/ipfw/ip_fw2.c	(working copy)
@@ -2096,8 +2096,11 @@
 				f->pcnt++;	/* update stats */
 				f->bcnt += pktlen;
 				f->timestamp = time_uptime;
-				M_SETFIB(m, cmd->arg1);
-				args->f_id.fib = cmd->arg1;
+				uint16_t fib = (cmd->arg1 == IP_FW_TABLEARG) ? tablearg : cmd->arg1;
+				if (fib >= rt_numfibs)
+					fib = 0;
+				M_SETFIB(m, fib);
+				args->f_id.fib = fib;
 				l = 0;		/* exit inner loop */
 				break;
 



>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list