Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-9]: src/sys/netinet Pull up following revision(s) (requested by r...



details:   https://anonhg.NetBSD.org/src/rev/cff97dd827a9
branches:  netbsd-9
changeset: 1001412:cff97dd827a9
user:      martin <martin%NetBSD.org@localhost>
date:      Fri Jan 24 18:57:02 2020 +0000

description:
Pull up following revision(s) (requested by roy in ticket #645):

        sys/netinet/if_arp.c: revision 1.292

arp: find source address then target address when processing input

This fixes the case where another host having a duplicate ip address
starts using it right away without probing for it's availability.

While here, prefer ifatoia over a strict cast.

diffstat:

 sys/netinet/if_arp.c |  32 +++++++++++++++++++++++++-------
 1 files changed, 25 insertions(+), 7 deletions(-)

diffs (76 lines):

diff -r cb5a6de22ccb -r cff97dd827a9 sys/netinet/if_arp.c
--- a/sys/netinet/if_arp.c      Thu Jan 23 10:15:40 2020 +0000
+++ b/sys/netinet/if_arp.c      Fri Jan 24 18:57:02 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_arp.c,v 1.282.2.5 2019/10/11 18:22:14 martin Exp $  */
+/*     $NetBSD: if_arp.c,v 1.282.2.6 2020/01/24 18:57:02 martin Exp $  */
 
 /*
  * Copyright (c) 1998, 2000, 2008 The NetBSD Foundation, Inc.
@@ -68,7 +68,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.282.2.5 2019/10/11 18:22:14 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.282.2.6 2020/01/24 18:57:02 martin Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ddb.h"
@@ -1025,7 +1025,7 @@
        struct psref psref, psref_ia;
        int s;
        char ipbuf[INET_ADDRSTRLEN];
-       bool do_dad;
+       bool find_source, do_dad;
 
        if (__predict_false(m_makewritable(&m, 0, m->m_pkthdr.len, M_DONTWAIT)))
                goto out;
@@ -1060,11 +1060,20 @@
         * or any address on the interface to use
         * as a dummy address in the rest of this function.
         *
-        * If the target IP address is zero then try and find
-        * the sender address for DAD.
+        * First try and find the source address for early
+        * duplicate address detection.
         */
-       myaddr = in_nullhost(itaddr) ? isaddr : itaddr;
+       if (in_nullhost(isaddr)) {
+               if (in_nullhost(itaddr)) /* very bogus ARP */
+                       goto out;
+               find_source = false;
+               myaddr = itaddr;
+       } else {
+               find_source = true;
+               myaddr = isaddr;
+       }
        s = pserialize_read_enter();
+again:
        IN_ADDRHASH_READER_FOREACH(ia, myaddr.s_addr) {
                if (!in_hosteq(ia->ia_addr.sin_addr, myaddr))
                        continue;
@@ -1106,6 +1115,15 @@
                ifp = bridge_ia->ia_ifp;
        }
 #endif
+
+       /* If we failed to find the source address then find
+        * the target address. */
+       if (ia == NULL && find_source && !in_nullhost(itaddr)) {
+               find_source = false;
+               myaddr = itaddr;
+               goto again;
+       }
+
        if (ia != NULL)
                ia4_acquire(ia, &psref_ia);
        pserialize_read_exit(s);
@@ -1787,7 +1805,7 @@
 static void
 arp_dad_duplicated(struct ifaddr *ifa, const struct sockaddr_dl *from)
 {
-       struct in_ifaddr *ia = (struct in_ifaddr *)ifa;
+       struct in_ifaddr *ia = ifatoia(ifa);
        struct ifnet *ifp = ifa->ifa_ifp;
        char ipbuf[INET_ADDRSTRLEN], llabuf[LLA_ADDRSTRLEN];
        const char *iastr, *llastr;



Home | Main Index | Thread Index | Old Index