When an interface loses link, we delete all directly connected and
cloned routes.  However, this means we also lose any BFD configuration
on those routes.

Surviving link-down is pretty much mandatory for BFD to work.

So instead, I bypass the route deletion, and clean up the link-local
gateway information.

$ arp -n | grep 203.0.113.9
203.0.113.9                          (incomplete)          em1 expired   

$ netstat -rnf inet | grep 203.0.113.9
203.0.113.9        link#2             HLcF       2       53     -     3 em1  

OK?

Index: sys/net/route.c
===================================================================
RCS file: /cvs/src/sys/net/route.c,v
retrieving revision 1.347
diff -u -p -u -p -r1.347 route.c
--- sys/net/route.c     20 Jan 2017 08:10:54 -0000      1.347
+++ sys/net/route.c     24 Jan 2017 01:32:23 -0000
@@ -1760,13 +1760,28 @@ rt_if_linkstate_change(struct rtentry *r
                         * new routes from a better source.
                         */
                        if (ISSET(rt->rt_flags, RTF_CLONED|RTF_DYNAMIC) &&
-                           !ISSET(rt->rt_flags, RTF_CACHED)) {
+                           !ISSET(rt->rt_flags, RTF_CACHED)
+#ifdef BFD
+                           && !ISSET(rt->rt_flags, RTF_BFD)
+#endif
+                           ) {
                                int error;
 
                                if ((error = rtdeletemsg(rt, ifp, id)))
                                        return (error);
                                return (EAGAIN);
                        }
+#ifdef BFD
+                       if (ISSET(rt->rt_flags, RTF_BFD) &&
+                           ISSET(rt->rt_flags, RTF_CLONED) &&
+                           (rt->rt_gateway->sa_family == AF_LINK)) {
+                               struct sockaddr_dl *sdl;
+                               sdl = (struct sockaddr_dl *)rt->rt_gateway;
+                               memset(sdl->sdl_data, 0, sdl->sdl_alen);
+                               sdl->sdl_alen = 0;
+                               rt->rt_expire = time_uptime;
+                       }
+#endif
                        /* take route down */
                        rt->rt_flags &= ~RTF_UP;
                        rtable_mpath_reprio(id, rt_key(rt),


-- 
Show me a man who is a good loser and I'll show you a man who is
playing golf with his boss.

Reply via email to