ipfw tablearg support for setfib

Paul Joe apauljoe at gmail.com
Thu Sep 30 20:03:57 UTC 2010


Hi,

The attached patch supports tablearg options to setfib.

With the patch, you can add rules like

ipfw add 100 setfib tablearg ip from 'table(1)' to any

It help in policy based routing as discussed in this thread.
http://docs.freebsd.org/cgi/getmsg.cgi?fetch=124951+0+archive/2009/freebsd-net/20090426.freebsd-net

Let me know your comments..


Thanks,
Joe
-------------- next part --------------
Index: src/sbin/ipfw/ipfw2.c
===================================================================
RCS file: /home/ncvs/src/sbin/ipfw/ipfw2.c,v
retrieving revision 1.159
diff -c -u -r1.159 ipfw2.c
--- src/sbin/ipfw/ipfw2.c	19 Apr 2010 16:35:47 -0000	1.159
+++ src/sbin/ipfw/ipfw2.c	30 Sep 2010 18:52:41 -0000
@@ -2833,11 +2833,17 @@
 
 		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(isdigit(**av)) {
+			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");
+		} else if (_substrcmp(*av, "tablearg") == 0)
+			action->arg1 = IP_FW_TABLEARG;
+		else
+			errx(EX_DATAERR, "illegal argument for %s", *(av - 1));
  		av++;
  		break;
 	    }
Index: src/sys/netinet/ipfw/ip_fw2.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/ipfw/ip_fw2.c,v
retrieving revision 1.45
diff -c -u -r1.45 ip_fw2.c
--- src/sys/netinet/ipfw/ip_fw2.c	27 Jul 2010 14:26:34 -0000	1.45
+++ src/sys/netinet/ipfw/ip_fw2.c	30 Sep 2010 18:52:43 -0000
@@ -2092,12 +2092,15 @@
 				done = 1;       /* exit outer loop */
 				break;
 
-			case O_SETFIB:
+			case O_SETFIB: {
+				uint32_t fibnum;
 				f->pcnt++;	/* update stats */
 				f->bcnt += pktlen;
 				f->timestamp = time_uptime;
-				M_SETFIB(m, cmd->arg1);
-				args->f_id.fib = cmd->arg1;
+				fibnum = (cmd->arg1 == IP_FW_TABLEARG)?
+					 tablearg : cmd->arg1;
+				M_SETFIB(m, fibnum);
+				args->f_id.fib = fibnum;
 				l = 0;		/* exit inner loop */
 				break;
 
Index: src/sys/netinet/ipfw/ip_fw_sockopt.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/ipfw/ip_fw_sockopt.c,v
retrieving revision 1.17
diff -c -u -r1.17 ip_fw_sockopt.c
--- src/sys/netinet/ipfw/ip_fw_sockopt.c	7 Apr 2010 08:23:58 -0000	1.17
+++ src/sys/netinet/ipfw/ip_fw_sockopt.c	30 Sep 2010 18:52:44 -0000
@@ -605,7 +605,8 @@
 		case O_SETFIB:
 			if (cmdlen != F_INSN_SIZE(ipfw_insn))
 				goto bad_size;
-			if (cmd->arg1 >= rt_numfibs) {
+			if (cmd->arg1 >= rt_numfibs &&
+			     cmd->arg1 != IP_FW_TABLEARG) {
 				printf("ipfw: invalid fib number %d\n",
 					cmd->arg1);
 				return EINVAL;


More information about the freebsd-net mailing list