Hi All, I am testing a redundant firewall setup where I am trying to use relayd to make sure that the uplinks are reachable.
The relayd.conf is very simple: ------------------------------------------- # cat /etc/relayd.conf interval 5 table <gateways> { 10.0.0.1 ip ttl 1 retry 2 } router "uplinks" { route 0.0.0.0/0 forward to <gateways> check icmp timeout 1000 } ------------------------------------------- The default route is pointing to the carp0 interface which is bound to the em2 interface. ------------------------------------------- # route -n show -inet Routing tables Internet: Destination Gateway Flags Refs Use Mtu Prio Iface default 10.0.0.1 UGS 0 2719 - 8 carp0 <snip> # ifconfig em2 em2: flags=8b43<UP,BROADCAST,RUNNING,PROMISC,ALLMULTI,SIMPLEX,MULTICAST> mtu 1500 lladdr 00:15:17:b8:db:3e description: External Network priority: 0 media: Ethernet autoselect (1000baseT full-duplex,rxpause,txpause) status: active inet6 fe80::215:17ff:feb8:db3e%em2 prefixlen 64 scopeid 0x3 # ifconfig carp0 carp0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500 lladdr 00:00:5e:00:01:02 description: External Network Carp - em2 priority: 0 carp: MASTER carpdev em2 vhid 2 advbase 1 advskew 10 groups: carp egress inet6 fe80::200:5eff:fe00:102%carp0 prefixlen 64 scopeid 0x9 inet 10.0.0.2 netmask 0xfffffffc broadcast 10.0.0.3 ------------------------------------------- For the most part everything works great, when relayd cannot ping the 10.0.0.1 gateway it will remove the default route and when it can ping the gateway again relayd will add the default route back. The problem appears when the interface goes down, for example, when the cable is disconnected, duplex settings are changed, or the switchport stops forwarding traffic. All of these conditions generate the following: ------------------------------------------- # ping 10.0.0.1 PING 10.0.0.1 (10.0.0.1): 56 data bytes ping: sendto: Network is unreachable ping: wrote 10.0.0.1 64 chars, ret=-1 # ifconfig em2 em2: flags=8b43<UP,BROADCAST,RUNNING,PROMISC,ALLMULTI,SIMPLEX,MULTICAST> mtu 1500 lladdr 00:15:17:b8:db:3e description: External Network priority: 0 media: Ethernet autoselect (none) status: no carrier inet6 fe80::215:17ff:feb8:db3e%em2 prefixlen 64 scopeid 0x3 # ifconfig carp0 carp0: flags=8803<UP,BROADCAST,SIMPLEX,MULTICAST> mtu 1500 lladdr 00:00:5e:00:01:02 description: External Network Carp - em2 priority: 0 carp: INIT carpdev em2 vhid 2 advbase 1 advskew 10 groups: carp egress inet6 fe80::200:5eff:fe00:102%carp0 prefixlen 64 scopeid 0x9 inet 10.0.0.2 netmask 0xfffffffc broadcast 10.0.0.3 # route -n show -inet Routing tables Internet: Destination Gateway Flags Refs Use Mtu Prio Iface default 10.0.0.1 UGS 0 3034 - 8 carp0 <snip> ------------------------------------------- Please notice how the default route is still 'U'sable, because the carp0 interface is in the INIT state. However the pings do not go through and running relayd with 'relayd -v -d' produces no output. ------------------------------------------- # relayd -v -d startup ------------------------------------------- I am not sure what is the right way to fix this behavior. I know this problem can be solved by using ifstated, but the config can get a bit complex if multiple interfaces are involved. On the other hand, should the routes be 'U'sable if the underlaying carp interface is in the INIT state? I have tried adding a check to relayd/check_icmp.c that specifically tests for ENETUNREACH case which seems to work. However I am not sure if this is the right or best way to handle this situation. The patch was applied to 4.7-stable @ 2010.08.16. ------------------------------------------- # diff -d -u -p check_icmp.c.orig check_icmp.c --- check_icmp.c.orig Sat Oct 24 13:05:09 2009 +++ check_icmp.c Wed Aug 18 12:29:20 2010 @@ -243,7 +243,9 @@ send_icmp(int s, short event, void *arg) if (r == -1) { if (errno == EAGAIN || errno == EINTR) goto retry; - host->flags |= F_CHECK_SENT|F_CHECK_DONE; + if (errno != ENETUNREACH) { + host->flags |= F_CHECK_SENT|F_CHECK_DONE; + } host->up = HOST_DOWN; } else if (r != sizeof(packet)) goto retry; ------------------------------------------- Please let me know if there is a better way to do this or if I can help with testing. Thanks! --peter