Here's the last piece of information I'd like to *always* have in the
routing table in order to be able to replace the RB-tree.

This diff adds the configured broadcast addresses to the routing table
permanently.  Actually these addresses are handled like lladdr and are
removed when their timeout expires.

I also flag such routes as RTF_BROADCAST to be able to check for them
later on.  The difference in output is:

-192.168.70.255     link#1             UHLc       0        1     -     4 em0 
+192.168.70.255     link#1             UHLb       0        1     -     4 em0 

As usual, make sure it does not break your setup, oks are also welcome.

Index: net/route.c
===================================================================
RCS file: /home/ncvs/src/sys/net/route.c,v
retrieving revision 1.174
diff -u -p -r1.174 route.c
--- net/route.c 12 Jul 2014 18:44:22 -0000      1.174
+++ net/route.c 22 Jul 2014 11:23:52 -0000
@@ -1230,9 +1230,16 @@ rt_ifa_addloop(struct ifaddr *ifa)
        /* If there is no loopback entry, allocate one. */
        rt = rtalloc1(ifa->ifa_addr, 0, ifa->ifa_ifp->if_rdomain);
        if (rt == NULL || (rt->rt_flags & RTF_HOST) == 0 ||
-           (rt->rt_ifp->if_flags & IFF_LOOPBACK) == 0)
+           (rt->rt_ifp->if_flags & IFF_LOOPBACK) == 0) {
                rt_ifa_add(ifa, RTF_UP| RTF_HOST | RTF_LLINFO | RTF_LOCAL,
                    ifa->ifa_addr);
+
+               if ((ifa->ifa_ifp->if_flags & IFF_BROADCAST) &&
+                   ifa->ifa_broadaddr)
+                       rt_ifa_add(ifa, RTF_UP | RTF_HOST | RTF_LLINFO |
+                           RTF_BROADCAST, ifa->ifa_broadaddr);
+
+       }
        if (rt)
                rt->rt_refcnt--;
 }
@@ -1275,9 +1282,15 @@ rt_ifa_delloop(struct ifaddr *ifa)
         */
        rt = rtalloc1(ifa->ifa_addr, 0, ifa->ifa_ifp->if_rdomain);
        if (rt != NULL && (rt->rt_flags & RTF_HOST) != 0 &&
-           (rt->rt_ifp->if_flags & IFF_LOOPBACK) != 0)
+           (rt->rt_ifp->if_flags & IFF_LOOPBACK) != 0) {
                rt_ifa_del(ifa,  RTF_HOST | RTF_LLINFO | RTF_LOCAL,
                    ifa->ifa_addr);
+
+               if ((ifa->ifa_ifp->if_flags & IFF_BROADCAST) &&
+                   ifa->ifa_broadaddr)
+                       rt_ifa_del(ifa, RTF_HOST | RTF_LLINFO | RTF_BROADCAST,
+                           ifa->ifa_broadaddr);
+       }
        if (rt)
                rt->rt_refcnt--;
 }
Index: netinet/if_ether.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/if_ether.c,v
retrieving revision 1.131
diff -u -p -r1.131 if_ether.c
--- netinet/if_ether.c  12 Jul 2014 18:44:23 -0000      1.131
+++ netinet/if_ether.c  22 Jul 2014 11:23:52 -0000
@@ -227,6 +227,18 @@ arp_rtrequest(int req, struct rtentry *r
                rt->rt_flags |= RTF_LLINFO;
                LIST_INSERT_HEAD(&llinfo_arp, la, la_list);
 
+               /*
+                * Routes to broadcast addresses must be incomplete
+                * arp entries so that they won't be picked up, but
+                * since we expect them to always be present in the
+                * routing table, make sure arptimer() won't free
+                * them.
+                */
+               if (rt->rt_flags & RTF_BROADCAST) {
+                       rt->rt_expire = 0;
+                       break;
+               }
+
                TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
                        if ((ifa->ifa_addr->sa_family == AF_INET) &&
                            ifatoia(ifa)->ia_addr.sin_addr.s_addr ==

Reply via email to