Do not create ARP entries for RTF_BROADCAST routes.
authormpi <mpi@openbsd.org>
Tue, 26 May 2015 11:55:34 +0000 (11:55 +0000)
committermpi <mpi@openbsd.org>
Tue, 26 May 2015 11:55:34 +0000 (11:55 +0000)
This has been done because historically routes to broadcast addresses
were cloned like any ARP entry.  But for obvious reasons, no matching
Ethernet address could ever be resolved.  That's why we played tricks
with the expire timer.

Now that a RTF_BROADCAST route is created per configured IPv4 address,
we need to differenciate duplicated one.  And by not creating an ARP
entry we are allowed to write the IP address in the rt_gateway field,
which prevents MPATH conflicts.

This change is part of a fix to unbreak aliases since the kernel support
multiple connected routes for a subnet.

Found the hardway by djm@, ok claudio@

sys/netinet/if_ether.c

index be83797..724e77f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_ether.c,v 1.152 2015/05/15 12:00:57 claudio Exp $  */
+/*     $OpenBSD: if_ether.c,v 1.153 2015/05/26 11:55:34 mpi Exp $      */
 /*     $NetBSD: if_ether.c,v 1.31 1996/05/11 12:59:58 mycroft Exp $    */
 
 /*
@@ -171,7 +171,7 @@ arp_rtrequest(int req, struct rtentry *rt)
                timeout_add_sec(&arptimer_to, 1);
        }
 
-       if (rt->rt_flags & RTF_GATEWAY)
+       if (rt->rt_flags & (RTF_GATEWAY|RTF_BROADCAST))
                return;
 
        switch (req) {
@@ -231,18 +231,6 @@ arp_rtrequest(int req, struct rtentry *rt)
                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 ==
@@ -642,7 +630,7 @@ in_arpinput(struct mbuf *m)
                if (sdl->sdl_alen) {
                    if (memcmp(ea->arp_sha, LLADDR(sdl), sdl->sdl_alen)) {
                        if (rt->rt_flags &
-                           (RTF_PERMANENT_ARP|RTF_LOCAL|RTF_BROADCAST)) {
+                           (RTF_PERMANENT_ARP|RTF_LOCAL)) {
                                inet_ntop(AF_INET, &isaddr, addr, sizeof(addr));
                                log(LOG_WARNING,
                                   "arp: attempt to overwrite permanent "