>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 r...@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: _______________________________________________ freebsd-bugs@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-bugs To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"