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 ==