Upgrading my firewall to OpenBSD 5.3 required updating my “multihoming-with-single-ISP” patch (see previous and original posts), as dhclient-script is no longer used. Instead, there is a new file, kroute.c. Luckily, moving the functionality from the shell script into C code was quite straightforward.
Here is the current patch to /usr/src/sbin/dhclient:
--- dhclient.c.orig 2013-08-02 10:17:29.000000000 +0300 +++ dhclient.c 2013-08-02 10:17:29.000000000 +0300 @@ -858,7 +858,10 @@ client->xid = arc4random(); make_request(client->active); - if (client->active->options[DHO_DHCP_SERVER_IDENTIFIER].len == 4) { + /*if (client->active->options[DHO_DHCP_SERVER_IDENTIFIER].len == 4) {*/ + if (0 && client->active->options[DHO_DHCP_SERVER_IDENTIFIER].len == 4) { memcpy(&client->destination.s_addr, client->active->options[DHO_DHCP_SERVER_IDENTIFIER].data, client->active->options[DHO_DHCP_SERVER_IDENTIFIER].len); --- kroute.c.orig 2013-08-02 10:17:29.000000000 +0300 +++ kroute.c 2013-08-02 20:20:42.000000000 +0300 @@ -256,6 +256,9 @@ struct sockaddr_rtlabel label; struct iovec iov[5]; int s, len, i, iovcnt = 0; + char buf[256]; /* * Add a default route via the specified address. @@ -339,6 +342,17 @@ iov[iovcnt].iov_base = &label; iov[iovcnt++].iov_len = sizeof(label); + /* Update next hop to pf route-to rules */ + snprintf(buf, 256, "/sbin/pfctl -t gw_%s -T flush", ifi->name); + if (system(buf)) + warning("failed to flush pf table: %s", strerror(errno)); + snprintf(buf, 256, "/sbin/pfctl -t gw_%s -T add %s", ifi->name, + inet_ntoa(gateway.sin_addr)); + if (system(buf)) + warning("failed to add to pf table: %s", strerror(errno)); + /* Check for EEXIST since other dhclient may not be done. */ for (i = 0; i < 5; i++) { if (writev(s, iov, iovcnt) != -1)
Here is the patch to /etc/rc:
--- rc.orig 2013-08-02 10:17:29.000000000 +0300 +++ rc 2013-08-02 10:17:29.000000000 +0300 @@ -357,6 +357,14 @@ mv -f /etc/resolv.conf.save /etc/resolv.conf touch /etc/resolv.conf fi + +# Allow em0 to receive vlan packets with different MAC addresses +ifconfig em0 up +ifconfig bridge0 create +brconfig bridge0 add em0 + . /etc/netstart echo rekey > /dev/arandom # any write triggers an RC4 rekey @@ -370,6 +378,16 @@ fi fi +# Initialise next hops for pf's route-to rules +pfctl -t gw_vlan201 -T add \ + `netstat -f inet -rn | grep default | grep vlan201 | awk '{print $2}'` +pfctl -t gw_vlan202 -T add \ + `netstat -f inet -T1 -rn | grep default | grep vlan202 | awk '{print $2}'` +pfctl -t gw_vlan203 -T add \ + `netstat -f inet -T2 -rn | grep default | grep vlan203 | awk '{print $2}'` + mount -s /usr >/dev/null 2>&1 mount -s /var >/dev/null 2>&1
And finally, this is a working /etc/pf.conf:
############################################################################### # Macros ############################################################################### if_int = "re0" if_ext1 = "vlan201" if_ext2 = "vlan202" if_ext3 = "vlan203" if_extv6 = "gif0" all_ifs = "{" $if_int $if_ext1 $if_ext2 $if_ext3 $if_extv6 "}" ext_ifs = "{" $if_ext1 $if_ext2 $if_ext3 $if_extv6 "}" ext_ifs_v4 = "{" $if_ext1 $if_ext2 $if_ext3 "}" ext_ifs_v6 = "{" $if_extv6 "}" if_int_v4 = "10.0.0.xx" home_net_v4 = "10.0.0.0/24" if_int_v6ll = "fe80::xxx" if_int_v6 = "2001:xxx" if_ext_v6 = "2001:xxx" home_net_v6 = "2001:xxx::/64" core7 = "10.0.0.xx" ps3 = "10.0.0.xx" ############################################################################### # Tables ############################################################################### tablepersist {} table persist {} table persist {} table const persist { \ 127.0.0.0/8 \ 10.0.0.0/8 \ 172.16.0.0/12 \ 192.168.0.0/16 \ } table const persist { \ x.x.x.x \ } table const persist { \ x.x.x.x \ } ############################################################################### # Options ############################################################################### set skip on lo0 set block-policy return set loginterface $if_ext1 set state-policy if-bound ############################################################################### # Packet normalisation ############################################################################### match on $if_ext1 all scrub (random-id reassemble tcp) match on $if_ext2 all scrub (random-id reassemble tcp) match on $if_ext3 all scrub (random-id) ## NOTE: "reassemble tcp" breaks PS3 downloads and may break something else too ############################################################################### # Translation/redirection rules ############################################################################### # FTP proxy states need to override the rules below anchor "ftp-proxy/*" # NAT match out on $if_ext3 inet from $ps3 to any nat-to $if_ext3 static-port match in on $if_ext3 inet from any to $if_ext3 rdr-to $ps3 rtable 0 match out on $if_ext2 inet from $core7 to any nat-to $if_ext2 static-port match in on $if_ext2 inet from any to $if_ext2 rdr-to $core7 rtable 0 match out on $if_ext1 from $home_net_v4 nat-to ($if_ext1) ############################################################################### # Filter rules ############################################################################### ## ## GENERAL ## # Block and log everything by default block log all # Antispoofing on all interfaces antispoof quick for $all_ifs # Block private addresses on external interfaces block drop in quick on $ext_ifs from block drop out quick on $ext_ifs to # Block IPv6 on external IPv4 interfaces block drop quick on $ext_ifs_v4 inet6 all # Block IPv4 on external IPv6 interfaces block drop quick on $ext_ifs_v6 inet all ## ## INCOMING ## ########## # if_int # ########## # FTP proxy pass in quick on $if_int inet proto tcp from $home_net_v4 to port ftp \ divert-to 127.0.0.1 port 8021 # ps3 pass in quick on $if_int from $ps3 to $if_int_v4 pass in quick on $if_int from $ps3 route-to ($if_ext3 ) # core7 pass in quick on $if_int from $core7 to $if_int_v4 pass in quick on $if_int from $core7 route-to ($if_ext2 ) # Other home network nodes pass in quick on $if_int from $home_net_v4 to $if_int_v4 pass in quick on $if_int from $home_net_v4 route-to ($if_ext1 ) # IPv6 pass in quick on $if_int from fe80::/16 to $if_int_v6ll pass in quick on $if_int from fe80::/16 to ff02::/16 pass in quick on $if_int from $home_net_v6 ########### # if_ext1 # ########### # IPv6 tunneling pass in quick on $if_ext1 proto icmp from a.b.c.d to ($if_ext1) pass in quick on $if_ext1 proto ipv6 from x.y.z.w to ($if_ext1) # Pass in SSH from addresses listed in ssh_ok table pass in quick on $if_ext1 proto tcp from to ($if_ext1) port ssh # Pass in HTTP from addresses listed in http_ok table pass in quick on $if_ext1 proto tcp from to ($if_ext1) port http ################### # if_ext2 (core7) # ################### # Steam (https://support.steampowered.com/kb_article.php?ref=8571-GLVN-8711) pass in quick on $if_ext2 proto tcp to $core7 port 27014:27050 pass in quick on $if_ext2 proto udp to $core7 port 4380 pass in quick on $if_ext2 proto udp to $core7 port 27000:27030 # Black Ops 2 pass in quick on $if_ext2 proto tcp to $core7 port 3074 pass in quick on $if_ext2 proto udp to $core7 port 3074 ################# # if_ext3 (ps3) # ################# # Nothing ## ## OUTGOING ## ########## # if_int # ########## # IPv4 from Internet to home network pass out quick on $if_int to $ps3 received-on $if_ext3 \ reply-to ($if_ext3 ) pass out quick on $if_int to $core7 received-on $if_ext2 \ reply-to ($if_ext2 ) pass out quick on $if_int to $home_net_v4 received-on $if_ext1 \ reply-to ($if_ext1 ) # IPv4 from fw to home network pass out quick on $if_int from $if_int_v4 to $home_net_v4 # IPv6 from fw to home network pass out quick on $if_int from $if_int_v6ll to fe80::/16 pass out quick on $if_int from $if_int_v6ll to ff02::/16 pass out quick on $if_int from $if_int_v6 to $home_net_v6 pass out quick on $if_int from $if_int_v6 to ff02::/16 ########### # if_ext1 # ########### # IPv6 tunneling pass out quick on $if_ext1 proto icmp from ($if_ext1) to a.b.c.d pass out quick on $if_ext1 proto ipv6 from ($if_ext1) to x.y.z.w # The rest pass out quick on $if_ext1 inet from ($if_ext1) modulate state ################### # if_ext2 (core7) # ################### pass out quick on $if_ext2 inet from ($if_ext2) modulate state rtable 1 ################# # if_ext3 (ps3) # ################# pass out quick on $if_ext3 inet from ($if_ext3) modulate state rtable 2 ############ # if_extv6 # ############ pass out quick on $if_extv6 inet6 from $if_int_v6ll modulate state pass out quick on $if_extv6 inet6 from $if_ext_v6 modulate state pass out quick on $if_extv6 inet6 from $home_net_v6 modulate state