Categories
FreeBSD/Unix

pf rtables and setfib in FreeBSD

If one has multiple outgoing links to which one would like to use different routing tables the FreeBSD provides possibility through the setfib command but in order to have multiple routing tables one has to first compile a custom kernel with option ROUTETABLES in example simple kernel config:


include GENERIC
options         ROUTETABLES=4

After the kernel has been built and rebooted the different routing tables can be accessed as shown in the setfib(1) man page by issuing command setfib 0 netstat -rn. 0 is the default routing table.

After this one has to create the second routing table by prepending every route add command with setfib 1 route add… e.g:

# setfib 1 route add -net default 10.0.0.1

With packet filter one can control how the routing table is selected by using rtable option but it should be noted that this selection can only be done on the input of the packets as the routing decision is done at the input not at the output. Here is an example of very simple pf.conf that uses rtable rules and NATs everything to the external interface address:

#
# Macros
#
INT_IF = "em0"
EXT_IF = "bge0"
EXT_IF2 = "bge1"

table <private_nets> persist { 127/8, 172.16/12, 192.168/16, 169.254/16 }

#
# Options and default policy
#
set block-policy drop
set state-policy if-bound

#
# Packet normalization
#
scrub in                          all
scrub out on $EXT_IF all random-id
scrub        on $EXT_IF all reassemble tcp

#
# NAT/redirects
#

# NAT
nat on $EXT_IF from <private_nets> to any -> ($EXT_IF)
nat on $EXT_IF2 from <private_nets> to any -> ($EXT_IF2)

#
# Filter rules
#
pass all
pass in from 192.168.100.0/24 to any rtable 0
pass in from 192.168.150.0/24 to any rtable 1