Index: sbin/ipfw/ipfw.8 =================================================================== --- sbin/ipfw/ipfw.8 +++ sbin/ipfw/ipfw.8 @@ -3246,6 +3246,8 @@ Obey transparent proxy rules only, packet aliasing is not performed. .It Cm skip_global Skip instance in case of global state lookup (see below). +.It Cm fib Ar fib_no +Set the routing table (FIB) for the NAT instance. .El .Pp Some specials value can be supplied instead of Index: sbin/ipfw/ipfw2.h =================================================================== --- sbin/ipfw/ipfw2.h +++ sbin/ipfw/ipfw2.h @@ -228,6 +228,7 @@ TOK_REDIR_ADDR, TOK_REDIR_PORT, TOK_REDIR_PROTO, + TOK_ALIAS_FIB, TOK_IPV6, TOK_FLOWID, Index: sbin/ipfw/main.c =================================================================== --- sbin/ipfw/main.c +++ sbin/ipfw/main.c @@ -45,7 +45,7 @@ "[pipe|queue] {zero|delete|show} [N{,N}]\n" "nat N config {ip IPADDR|if IFNAME|log|deny_in|same_ports|unreg_only|unreg_cgn|\n" " reset|reverse|proxy_only|redirect_addr linkspec|\n" -" redirect_port linkspec|redirect_proto linkspec}\n" +" redirect_port linkspec|redirect_proto linkspec|fib fib_no}\n" "set [disable N... enable N...] | move [rule] X to Y | swap X Y | show\n" "set N {show|list|zero|resetlog|delete} [N{,N}] | flush\n" "table N {add ip[/bits] [value] | delete ip[/bits] | flush | list}\n" Index: sbin/ipfw/nat.c =================================================================== --- sbin/ipfw/nat.c +++ sbin/ipfw/nat.c @@ -68,6 +68,7 @@ { "redirect_addr", TOK_REDIR_ADDR }, { "redirect_port", TOK_REDIR_PORT }, { "redirect_proto", TOK_REDIR_PROTO }, + { "fib", TOK_ALIAS_FIB }, { NULL, 0 } /* terminator */ }; @@ -838,6 +839,12 @@ ac1--; } break; + case TOK_ALIAS_FIB: + if (ac1 == 0) + errx(EX_DATAERR, "missing option"); + av1++; + ac1--; + break; default: errx(EX_DATAERR, "unrecognised option ``%s''", av1[-1]); } @@ -924,6 +931,21 @@ n->redir_cnt++; off += i; break; + case TOK_ALIAS_FIB: { + int numfibs; + size_t intsize = sizeof(int); + if (sysctlbyname("net.fibs", &numfibs, &intsize, NULL, 0) == -1) + errx(EX_DATAERR, "multiple fibs not supported"); + if (ac == 0) + errx(EX_DATAERR, "missing option"); + i = strtol(av[0], &end, 10); + if (i < 0 || i >= numfibs) + errx(EX_DATAERR, "fib has to be between 0-%d", numfibs - 1); + n->fib = (uint16_t) i; + ac--; + av++; + break; + } } } Index: sys/netinet/ip_fw.h =================================================================== --- sys/netinet/ip_fw.h +++ sys/netinet/ip_fw.h @@ -550,6 +550,7 @@ struct in_addr ip; /* nat IPv4 address */ uint32_t mode; /* aliasing mode */ uint32_t redir_cnt; /* number of entry in spool chain */ + uint16_t fib; /* fib to route on */ }; /* Nat command. */ Index: sys/netpfil/ipfw/ip_fw_nat.c =================================================================== --- sys/netpfil/ipfw/ip_fw_nat.c +++ sys/netpfil/ipfw/ip_fw_nat.c @@ -93,6 +93,7 @@ /* chain of redir instances */ LIST_HEAD(redir_chain, cfg_redir) redir_chain; char if_name[IF_NAMESIZE]; /* interface name */ + uint16_t fib; /* fib we should route on */ }; static eventhandler_tag ifaddr_event_tag; @@ -454,6 +455,10 @@ mcl->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA; } } + + if (t->fib) + M_SETFIB(mcl, t->fib); + args->m = mcl; return (IP_FW_NAT); } @@ -529,6 +534,7 @@ ptr->ip = ucfg->ip; ptr->redir_cnt = ucfg->redir_cnt; ptr->mode = ucfg->mode; + ptr->fib = ucfg->fib; strlcpy(ptr->if_name, ucfg->if_name, sizeof(ptr->if_name)); LibAliasSetMode(ptr->lib, ptr->mode, ~0); LibAliasSetAddress(ptr->lib, ptr->ip);