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,