Module Name:    src
Committed By:   roy
Date:           Wed Nov 13 09:25:52 UTC 2024

Modified Files:
        src/sys/netinet: if_arp.c
        src/sys/netinet6: nd6_nbr.c

Log Message:
ARP/ND6: Revert prior

Turns out some people actually use this behaviour and strictly speaking
it is allowed by RFC5227 2.4 where it says:

   At any time, if a host receives
   an ARP packet (Request *or* Reply) where the 'sender IP address' is
   (one of) the host's own IP address(es) configured on that interface,
   but the 'sender hardware address' does not match any of the host's
   own interface addresses, then this is a conflicting ARP packet

The key part is "any of the host's own interface addreses".


To generate a diff of this commit:
cvs rdiff -u -r1.316 -r1.317 src/sys/netinet/if_arp.c
cvs rdiff -u -r1.184 -r1.185 src/sys/netinet6/nd6_nbr.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/netinet/if_arp.c
diff -u src/sys/netinet/if_arp.c:1.316 src/sys/netinet/if_arp.c:1.317
--- src/sys/netinet/if_arp.c:1.316	Fri Oct  4 23:31:06 2024
+++ src/sys/netinet/if_arp.c	Wed Nov 13 09:25:52 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_arp.c,v 1.316 2024/10/04 23:31:06 roy Exp $	*/
+/*	$NetBSD: if_arp.c,v 1.317 2024/11/13 09:25:52 roy 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.316 2024/10/04 23:31:06 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.317 2024/11/13 09:25:52 roy Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ddb.h"
@@ -217,7 +217,7 @@ static struct ifnet *myip_ifp = NULL;
 
 static int arp_drainwanted;
 
-static int log_movements = 1;
+static int log_movements = 0;
 static int log_permanent_modify = 1;
 static int log_wrong_iface = 1;
 
@@ -793,6 +793,16 @@ in_arpinput(struct mbuf *m)
 	if (ah->ar_pln != sizeof(struct in_addr))
 		goto out;
 
+	/* RFC5227 2.4 says any of the host's own interface addresses
+	 * are not conflicting ARP packets. */
+	ifp = if_get_bylla(ar_sha(ah), ah->ar_hln, &psref);
+	if (ifp) {
+		/* it's from me, ignore it. */
+		if_put(ifp, &psref);
+		ARP_STATINC(ARP_STAT_RCVLOCALSHA);
+		goto out;
+	}
+
 	rcvif = ifp = m_get_rcvif_psref(m, &psref);
 	if (__predict_false(rcvif == NULL))
 		goto out;
@@ -903,12 +913,6 @@ again:
 	myaddr = ia->ia_addr.sin_addr;
 
 	/* XXX checks for bridge case? */
-	if (!memcmp(ar_sha(ah), CLLADDR(ifp->if_sadl), ifp->if_addrlen)) {
-		ARP_STATINC(ARP_STAT_RCVLOCALSHA);
-		goto out;	/* it's from me, ignore it. */
-	}
-
-	/* XXX checks for bridge case? */
 	if (!memcmp(ar_sha(ah), ifp->if_broadcastaddr, ifp->if_addrlen)) {
 		ARP_STATINC(ARP_STAT_RCVBCASTSHA);
 		log(LOG_ERR,

Index: src/sys/netinet6/nd6_nbr.c
diff -u src/sys/netinet6/nd6_nbr.c:1.184 src/sys/netinet6/nd6_nbr.c:1.185
--- src/sys/netinet6/nd6_nbr.c:1.184	Sat Oct  5 09:10:53 2024
+++ src/sys/netinet6/nd6_nbr.c	Wed Nov 13 09:25:52 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: nd6_nbr.c,v 1.184 2024/10/05 09:10:53 roy Exp $	*/
+/*	$NetBSD: nd6_nbr.c,v 1.185 2024/11/13 09:25:52 roy Exp $	*/
 /*	$KAME: nd6_nbr.c,v 1.61 2001/02/10 16:06:14 jinmei Exp $	*/
 
 /*
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.184 2024/10/05 09:10:53 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.185 2024/11/13 09:25:52 roy Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -677,12 +677,13 @@ nd6_na_input(struct mbuf *m, int off, in
 	}
 
 	if (ndopts.nd_opts_tgt_lladdr != NULL) {
+		struct ifnet *ifp_ll;
+		struct psref psref_ll;
+
 		lladdr = (char *)(ndopts.nd_opts_tgt_lladdr + 1);
 		lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3;
-	}
 
-	if (lladdr != NULL) {
-		if (((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {
+		if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {
 			nd6log(LOG_INFO, "lladdrlen mismatch for %s "
 			    "(if %d, NA packet %d)\n",
 			    IN6_PRINT(ip6buf, &taddr6),
@@ -690,8 +691,10 @@ nd6_na_input(struct mbuf *m, int off, in
 			goto bad;
 		}
 
-		if (!memcmp(lladdr, CLLADDR(ifp->if_sadl), ifp->if_addrlen)) {
+		ifp_ll = if_get_bylla(lladdr, ifp->if_addrlen, &psref_ll);
+		if (ifp_ll != NULL) {
 			/* it's from me, ignore it. */
+			if_put(ifp_ll, &psref_ll);
 			goto freeit;
 		}
 	}

Reply via email to