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

Reply via email to