Module Name:    src
Committed By:   snj
Date:           Sat Jul  1 08:56:07 UTC 2017

Modified Files:
        src/sys/net [netbsd-8]: if.c if.h
        src/sys/netinet [netbsd-8]: if_arp.c

Log Message:
Pull up following revision(s) (requested by roy in ticket #77):
        sys/net/if.h: revision 1.240
        sys/netinet/if_arp.c: revision 1.253
        sys/net/if.c: revision 1.395
Introduce if_get_bylla to find an interface with the active
local link address.
--
Use if_get_bylla() instead of just looking at the lla of the interface
the address belongs to.
This allows any ARP message we receieved from another interface to
be correctly dropped.
While here, move the protocol length check higher up the food chain.


To generate a diff of this commit:
cvs rdiff -u -r1.394 -r1.394.2.1 src/sys/net/if.c
cvs rdiff -u -r1.239 -r1.239.2.1 src/sys/net/if.h
cvs rdiff -u -r1.250 -r1.250.2.1 src/sys/netinet/if_arp.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/net/if.c
diff -u src/sys/net/if.c:1.394 src/sys/net/if.c:1.394.2.1
--- src/sys/net/if.c:1.394	Thu Jun  1 02:45:14 2017
+++ src/sys/net/if.c	Sat Jul  1 08:56:06 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: if.c,v 1.394 2017/06/01 02:45:14 chs Exp $	*/
+/*	$NetBSD: if.c,v 1.394.2.1 2017/07/01 08:56:06 snj Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc.
@@ -90,7 +90,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.394 2017/06/01 02:45:14 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.394.2.1 2017/07/01 08:56:06 snj Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_inet.h"
@@ -2599,8 +2599,8 @@ out:
 }
 
 /*
- * Release a reference of an ifnet object given by if_get or
- * if_get_byindex.
+ * Release a reference of an ifnet object given by if_get, if_get_byindex
+ * or if_get_bylla.
  */
 void
 if_put(const struct ifnet *ifp, struct psref *psref)
@@ -2643,6 +2643,29 @@ if_get_byindex(u_int idx, struct psref *
 	return ifp;
 }
 
+ifnet_t *
+if_get_bylla(const void *lla, unsigned char lla_len, struct psref *psref)
+{
+	ifnet_t *ifp;
+	int s;
+
+	s = pserialize_read_enter();
+	IFNET_READER_FOREACH(ifp) {
+		if (if_is_deactivated(ifp))
+			continue;
+		if (ifp->if_addrlen != lla_len)
+			continue;
+		if (memcmp(lla, CLLADDR(ifp->if_sadl), lla_len) == 0) {
+			psref_acquire(psref, &ifp->if_psref,
+			    ifnet_psref_class);
+			break;
+		}
+	}
+	pserialize_read_exit(s);
+
+	return ifp;
+}
+
 /*
  * Note that it's safe only if the passed ifp is guaranteed to not be freed,
  * for example using pserialize or the ifp is already held or some other

Index: src/sys/net/if.h
diff -u src/sys/net/if.h:1.239 src/sys/net/if.h:1.239.2.1
--- src/sys/net/if.h:1.239	Fri May 19 08:53:51 2017
+++ src/sys/net/if.h	Sat Jul  1 08:56:06 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: if.h,v 1.239 2017/05/19 08:53:51 ozaki-r Exp $	*/
+/*	$NetBSD: if.h,v 1.239.2.1 2017/07/01 08:56:06 snj Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -974,6 +974,7 @@ struct	ifnet *ifunit(const char *);
 struct	ifnet *if_get(const char *, struct psref *);
 ifnet_t *if_byindex(u_int);
 ifnet_t *if_get_byindex(u_int, struct psref *);
+ifnet_t *if_get_bylla(const void *, unsigned char, struct psref *);
 void	if_put(const struct ifnet *, struct psref *);
 void	if_acquire(struct ifnet *, struct psref *);
 #define	if_release	if_put

Index: src/sys/netinet/if_arp.c
diff -u src/sys/netinet/if_arp.c:1.250 src/sys/netinet/if_arp.c:1.250.2.1
--- src/sys/netinet/if_arp.c:1.250	Thu May 18 06:33:11 2017
+++ src/sys/netinet/if_arp.c	Sat Jul  1 08:56:06 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_arp.c,v 1.250 2017/05/18 06:33:11 ozaki-r Exp $	*/
+/*	$NetBSD: if_arp.c,v 1.250.2.1 2017/07/01 08:56:06 snj 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.250 2017/05/18 06:33:11 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.250.2.1 2017/07/01 08:56:06 snj Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ddb.h"
@@ -1020,6 +1020,16 @@ in_arpinput(struct mbuf *m)
 	ah = mtod(m, struct arphdr *);
 	op = ntohs(ah->ar_op);
 
+	if (ah->ar_pln != sizeof(struct in_addr))
+		goto out;
+
+	ifp = if_get_bylla(ar_sha(ah), ah->ar_hln, &psref);
+	if (ifp) {
+		if_put(ifp, &psref);
+		ARP_STATINC(ARP_STAT_RCVLOCALSHA);
+		goto out;	/* it's from me, ignore it. */
+	}
+
 	rcvif = ifp = m_get_rcvif_psref(m, &psref);
 	if (__predict_false(rcvif == NULL))
 		goto drop;
@@ -1041,9 +1051,6 @@ in_arpinput(struct mbuf *m)
 		break;
 	}
 
-	if (ah->ar_pln != sizeof(struct in_addr))
-		goto drop;
-
 	memcpy(&isaddr, ar_spa(ah), sizeof(isaddr));
 	memcpy(&itaddr, ar_tpa(ah), sizeof(itaddr));
 
@@ -1130,12 +1137,6 @@ in_arpinput(struct mbuf *m)
 	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,

Reply via email to