From nobody@FreeBSD.org  Thu Apr 14 21:40:29 2011
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id A58181065674
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 14 Apr 2011 21:40:29 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from red.freebsd.org (red.freebsd.org [IPv6:2001:4f8:fff6::22])
	by mx1.freebsd.org (Postfix) with ESMTP id 8899B8FC23
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 14 Apr 2011 21:40:29 +0000 (UTC)
Received: from red.freebsd.org (localhost [127.0.0.1])
	by red.freebsd.org (8.14.4/8.14.4) with ESMTP id p3ELeTXE028828
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 14 Apr 2011 21:40:29 GMT
	(envelope-from nobody@red.freebsd.org)
Received: (from nobody@localhost)
	by red.freebsd.org (8.14.4/8.14.4/Submit) id p3ELeTPT028827;
	Thu, 14 Apr 2011 21:40:29 GMT
	(envelope-from nobody)
Message-Id: <201104142140.p3ELeTPT028827@red.freebsd.org>
Date: Thu, 14 Apr 2011 21:40:29 GMT
From: "Alexander V. Chernikov" <melifaro@ipfw.ru>
To: freebsd-gnats-submit@FreeBSD.org
Subject: [patch][ipfw] tablearg option for ipfw setfib
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         156410
>Category:       kern
>Synopsis:       [patch][ipfw] tablearg option for ipfw setfib
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-ipfw
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Thu Apr 14 21:50:13 UTC 2011
>Closed-Date:    Tue Jun 14 04:38:37 UTC 2011
>Last-Modified:  Tue Jun 14 04:40:07 UTC 2011
>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@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:
Responsible-Changed-From-To: freebsd-bugs->freebsd-ipfw 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Sun Apr 17 01:01:13 UTC 2011 
Responsible-Changed-Why:  
Over to maintainer(s). 

http://www.freebsd.org/cgi/query-pr.cgi?pr=156410 
State-Changed-From-To: open->patched 
State-Changed-By: ae 
State-Changed-When: Mon May 30 05:39:27 UTC 2011 
State-Changed-Why:  
Commited to head/. Thanks! 

http://www.freebsd.org/cgi/query-pr.cgi?pr=156410 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/156410: commit references a PR
Date: Mon, 30 May 2011 05:37:40 +0000 (UTC)

 Author: ae
 Date: Mon May 30 05:37:26 2011
 New Revision: 222473
 URL: http://svn.freebsd.org/changeset/base/222473
 
 Log:
   Add tablearg support for ipfw setfib.
   
   PR:		kern/156410
   MFC after:	2 weeks
 
 Modified:
   head/sbin/ipfw/ipfw.8
   head/sbin/ipfw/ipfw2.c
   head/sys/netinet/ipfw/ip_fw2.c
   head/sys/netinet/ipfw/ip_fw_sockopt.c
 
 Modified: head/sbin/ipfw/ipfw.8
 ==============================================================================
 --- head/sbin/ipfw/ipfw.8	Mon May 30 04:23:33 2011	(r222472)
 +++ head/sbin/ipfw/ipfw.8	Mon May 30 05:37:26 2011	(r222473)
 @@ -1,7 +1,7 @@
  .\"
  .\" $FreeBSD$
  .\"
 -.Dd July 27, 2010
 +.Dd May 30, 2011
  .Dt IPFW 8
  .Os
  .Sh NAME
 @@ -871,13 +871,16 @@ for more information on
  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 @@ is used.
  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:
 
 Modified: head/sbin/ipfw/ipfw2.c
 ==============================================================================
 --- head/sbin/ipfw/ipfw2.c	Mon May 30 04:23:33 2011	(r222472)
 +++ head/sbin/ipfw/ipfw2.c	Mon May 30 05:37:26 2011	(r222473)
 @@ -2835,14 +2835,19 @@ chkarg:
  		size_t intsize = sizeof(int);
  
  		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");
 - 		av++;
 - 		break;
 +		NEED1("missing fib number");
 +		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;
  	    }
  
  	case TOK_REASS:
 
 Modified: head/sys/netinet/ipfw/ip_fw2.c
 ==============================================================================
 --- head/sys/netinet/ipfw/ip_fw2.c	Mon May 30 04:23:33 2011	(r222472)
 +++ head/sys/netinet/ipfw/ip_fw2.c	Mon May 30 05:37:26 2011	(r222473)
 @@ -2137,14 +2137,21 @@ do {								\
  				done = 1;       /* exit outer loop */
  				break;
  
 -			case O_SETFIB:
 +			case O_SETFIB: {
 +				uint32_t fib;
 +
  				f->pcnt++;	/* update stats */
  				f->bcnt += pktlen;
  				f->timestamp = time_uptime;
 -				M_SETFIB(m, cmd->arg1);
 -				args->f_id.fib = cmd->arg1;
 +				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;
 +		        }
  
  			case O_NAT:
   				if (!IPFW_NAT_LOADED) {
 
 Modified: head/sys/netinet/ipfw/ip_fw_sockopt.c
 ==============================================================================
 --- head/sys/netinet/ipfw/ip_fw_sockopt.c	Mon May 30 04:23:33 2011	(r222472)
 +++ head/sys/netinet/ipfw/ip_fw_sockopt.c	Mon May 30 05:37:26 2011	(r222473)
 @@ -606,7 +606,7 @@ check_ipfw_struct(struct ip_fw *rule, in
  		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;
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: patched->closed 
State-Changed-By: ae 
State-Changed-When: Tue Jun 14 04:38:12 UTC 2011 
State-Changed-Why:  
Merged to stable/8. Thanks! 

http://www.freebsd.org/cgi/query-pr.cgi?pr=156410 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/156410: commit references a PR
Date: Tue, 14 Jun 2011 04:37:23 +0000 (UTC)

 Author: ae
 Date: Tue Jun 14 04:37:09 2011
 New Revision: 223070
 URL: http://svn.freebsd.org/changeset/base/223070
 
 Log:
   MFC r222473:
     Add tablearg support for ipfw setfib.
   
     PR:		kern/156410
   
   MFC r222474:
     Wrap long line.
 
 Modified:
   stable/8/sbin/ipfw/ipfw.8
   stable/8/sbin/ipfw/ipfw2.c
   stable/8/sys/netinet/ipfw/ip_fw2.c
   stable/8/sys/netinet/ipfw/ip_fw_sockopt.c
 Directory Properties:
   stable/8/sbin/ipfw/   (props changed)
   stable/8/sys/   (props changed)
   stable/8/sys/amd64/include/xen/   (props changed)
   stable/8/sys/cddl/contrib/opensolaris/   (props changed)
   stable/8/sys/contrib/dev/acpica/   (props changed)
   stable/8/sys/contrib/pf/   (props changed)
 
 Modified: stable/8/sbin/ipfw/ipfw.8
 ==============================================================================
 --- stable/8/sbin/ipfw/ipfw.8	Tue Jun 14 04:34:20 2011	(r223069)
 +++ stable/8/sbin/ipfw/ipfw.8	Tue Jun 14 04:37:09 2011	(r223070)
 @@ -1,7 +1,7 @@
  .\"
  .\" $FreeBSD$
  .\"
 -.Dd July 27, 2010
 +.Dd May 30, 2011
  .Dt IPFW 8
  .Os
  .Sh NAME
 @@ -867,13 +867,16 @@ for more information on
  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.
 @@ -1697,7 +1700,7 @@ is used.
  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:
 
 Modified: stable/8/sbin/ipfw/ipfw2.c
 ==============================================================================
 --- stable/8/sbin/ipfw/ipfw2.c	Tue Jun 14 04:34:20 2011	(r223069)
 +++ stable/8/sbin/ipfw/ipfw2.c	Tue Jun 14 04:37:09 2011	(r223070)
 @@ -2826,14 +2826,19 @@ chkarg:	
  		size_t intsize = sizeof(int);
  
  		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");
 - 		av++;
 - 		break;
 +		NEED1("missing fib number");
 +		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;
  	    }
  
  	case TOK_REASS:
 
 Modified: stable/8/sys/netinet/ipfw/ip_fw2.c
 ==============================================================================
 --- stable/8/sys/netinet/ipfw/ip_fw2.c	Tue Jun 14 04:34:20 2011	(r223069)
 +++ stable/8/sys/netinet/ipfw/ip_fw2.c	Tue Jun 14 04:37:09 2011	(r223070)
 @@ -2101,14 +2101,21 @@ do {								\
  				done = 1;       /* exit outer loop */
  				break;
  
 -			case O_SETFIB:
 +			case O_SETFIB: {
 +				uint32_t fib;
 +
  				f->pcnt++;	/* update stats */
  				f->bcnt += pktlen;
  				f->timestamp = time_uptime;
 -				M_SETFIB(m, cmd->arg1);
 -				args->f_id.fib = cmd->arg1;
 +				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;
 +		        }
  
  			case O_NAT:
   				if (!IPFW_NAT_LOADED) {
 
 Modified: stable/8/sys/netinet/ipfw/ip_fw_sockopt.c
 ==============================================================================
 --- stable/8/sys/netinet/ipfw/ip_fw_sockopt.c	Tue Jun 14 04:34:20 2011	(r223069)
 +++ stable/8/sys/netinet/ipfw/ip_fw_sockopt.c	Tue Jun 14 04:37:09 2011	(r223070)
 @@ -605,7 +605,8 @@ check_ipfw_struct(struct ip_fw *rule, in
  		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;
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
>Unformatted:
