Module Name:    src
Committed By:   roy
Date:           Tue Oct 11 12:32:30 UTC 2016

Modified Files:
        src/sys/net: if_llatbl.c
        src/sys/netinet: if_arp.c if_inarp.h ip_carp.c

Log Message:
Mark arprequest static and introduce arpannounce so that gratuitous
ARP requests are only send from valid addresses.


To generate a diff of this commit:
cvs rdiff -u -r1.14 -r1.15 src/sys/net/if_llatbl.c
cvs rdiff -u -r1.228 -r1.229 src/sys/netinet/if_arp.c
cvs rdiff -u -r1.49 -r1.50 src/sys/netinet/if_inarp.h
cvs rdiff -u -r1.77 -r1.78 src/sys/netinet/ip_carp.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_llatbl.c
diff -u src/sys/net/if_llatbl.c:1.14 src/sys/net/if_llatbl.c:1.15
--- src/sys/net/if_llatbl.c:1.14	Thu Jun 16 03:03:33 2016
+++ src/sys/net/if_llatbl.c	Tue Oct 11 12:32:30 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_llatbl.c,v 1.14 2016/06/16 03:03:33 ozaki-r Exp $	*/
+/*	$NetBSD: if_llatbl.c,v 1.15 2016/10/11 12:32:30 roy Exp $	*/
 /*
  * Copyright (c) 2004 Luigi Rizzo, Alessandro Cerri. All rights reserved.
  * Copyright (c) 2004-2008 Qing Li. All rights reserved.
@@ -60,6 +60,7 @@
 #include <net/if_dl.h>
 #include <net/route.h>
 #include <netinet/if_inarp.h>
+#include <netinet/in_var.h>
 #include <netinet6/in6_var.h>
 #include <netinet6/nd6.h>
 
@@ -671,11 +672,19 @@ lla_rt_output(const u_char rtm_type, con
 		IF_AFDATA_WUNLOCK(ifp);
 #if defined(INET) && NARP > 0
 		/* gratuitous ARP */
-		if ((laflags & LLE_PUB) && dst->sa_family == AF_INET)
-			arprequest(ifp,
-			    &((const struct sockaddr_in *)dst)->sin_addr,
-			    &((const struct sockaddr_in *)dst)->sin_addr,
-			    CLLADDR(dl));
+		if ((laflags & LLE_PUB) && dst->sa_family == AF_INET) {
+			const struct sockaddr_in *sin;
+			struct in_ifaddr *ia;
+			struct psref _psref;
+
+			sin = satocsin(dst);
+			ia = in_get_ia_on_iface_psref(sin->sin_addr,
+			    ifp, &_psref);
+			if (ia != NULL) {
+				arpannounce(ifp, &ia->ia_ifa, CLLADDR(dl));
+				ia4_release(ia, &_psref);
+			}
+		}
 #else
 		(void)laflags;
 #endif

Index: src/sys/netinet/if_arp.c
diff -u src/sys/netinet/if_arp.c:1.228 src/sys/netinet/if_arp.c:1.229
--- src/sys/netinet/if_arp.c:1.228	Mon Oct  3 11:06:06 2016
+++ src/sys/netinet/if_arp.c	Tue Oct 11 12:32:30 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_arp.c,v 1.228 2016/10/03 11:06:06 ozaki-r Exp $	*/
+/*	$NetBSD: if_arp.c,v 1.229 2016/10/11 12:32:30 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.228 2016/10/03 11:06:06 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.229 2016/10/11 12:32:30 roy Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ddb.h"
@@ -157,6 +157,10 @@ int		arp_debug = 0;
 
 static	void arp_init(void);
 
+static	void arprequest(struct ifnet *,
+    const struct in_addr *, const struct in_addr *,
+    const u_int8_t *);
+static	void arpannounce1(struct ifaddr *);
 static	struct sockaddr *arp_setgate(struct rtentry *, struct sockaddr *,
 	    const struct sockaddr *);
 static	void arptimer(void *);
@@ -452,22 +456,8 @@ arp_rtrequest(int req, struct rtentry *r
 	int s;
 
 	if (req == RTM_LLINFO_UPD) {
-		struct in_addr *in;
-
-		if ((ifa = info->rti_ifa) == NULL)
-			return;
-
-		in = &ifatoia(ifa)->ia_addr.sin_addr;
-
-		if (ifatoia(ifa)->ia4_flags &
-		    (IN_IFF_NOTREADY | IN_IFF_DETACHED))
-		{
-			arplog(LOG_DEBUG, "%s not ready\n", in_fmtaddr(*in));
-			return;
-		}
-
-		arprequest(ifa->ifa_ifp, in, in,
-		    CLLADDR(ifa->ifa_ifp->if_sadl));
+		if ((ifa = info->rti_ifa) != NULL)
+			arpannounce1(ifa);
 		return;
 	}
 
@@ -563,16 +553,11 @@ arp_rtrequest(int req, struct rtentry *r
 			struct psref psref;
 			ia = in_get_ia_on_iface_psref(
 			    satocsin(rt_getkey(rt))->sin_addr, ifp, &psref);
-			if (ia == NULL ||
-			    ia->ia4_flags & (IN_IFF_NOTREADY | IN_IFF_DETACHED))
-				;
-			else
-				arprequest(ifp,
-				    &satocsin(rt_getkey(rt))->sin_addr,
-				    &satocsin(rt_getkey(rt))->sin_addr,
+			if (ia != NULL) {
+				arpannounce(ifp, &ia->ia_ifa,
 				    CLLADDR(satocsdl(gate)));
-			if (ia != NULL)
 				ia4_release(ia, &psref);
+			}
 		}
 
 		if (gate->sa_family != AF_LINK ||
@@ -645,7 +630,7 @@ arp_rtrequest(int req, struct rtentry *r
  *	- arp header target ip address
  *	- arp header source ethernet address
  */
-void
+static void
 arprequest(struct ifnet *ifp,
     const struct in_addr *sip, const struct in_addr *tip,
     const u_int8_t *enaddr)
@@ -702,6 +687,26 @@ arprequest(struct ifnet *ifp,
 	if_output_lock(ifp, ifp, m, &sa, NULL);
 }
 
+void
+arpannounce(struct ifnet *ifp, struct ifaddr *ifa, const uint8_t *enaddr)
+{
+	struct in_ifaddr *ia = ifatoia(ifa);
+	struct in_addr *ip = &IA_SIN(ifa)->sin_addr;
+
+	if (ia->ia4_flags & (IN_IFF_NOTREADY | IN_IFF_DETACHED)) {
+		arplog(LOG_DEBUG, "%s not ready\n", in_fmtaddr(*ip));
+		return;
+	}
+	arprequest(ifp, ip, ip, enaddr);
+}
+
+static void
+arpannounce1(struct ifaddr *ifa)
+{
+
+	arpannounce(ifa->ifa_ifp, ifa, CLLADDR(ifa->ifa_ifp->if_sadl));
+}
+
 /*
  * Resolve an IP address into an ethernet address.  If success,
  * desten is filled in.  If there is no entry in arptab,
@@ -1353,7 +1358,6 @@ reply:
 		m->m_flags |= M_BCAST;
 		m->m_len = sizeof(*ah) + (2 * ah->ar_pln) + ah->ar_hln;
 		break;
-
 	default:
 		m->m_flags &= ~(M_BCAST|M_MCAST); /* never reply by broadcast */
 		m->m_len = sizeof(*ah) + (2 * ah->ar_pln) + (2 * ah->ar_hln);
@@ -1457,8 +1461,6 @@ arp_ifinit(struct ifnet *ifp, struct ifa
 	    (ia->ia4_flags & (IN_IFF_NOTREADY | IN_IFF_DETACHED)) == 0) {
 		struct llentry *lle;
 
-		arprequest(ifp, ip, ip, CLLADDR(ifp->if_sadl));
-
 		/*
 		 * interface address is considered static entry
 		 * because the output of the arp utility shows
@@ -1492,6 +1494,8 @@ arp_ifinit(struct ifnet *ifp, struct ifa
 		ia->ia_dad_stop = arp_dad_stop;
 		if (ia->ia4_flags & IN_IFF_TRYTENTATIVE)
 			ia->ia4_flags |= IN_IFF_TENTATIVE;
+		else
+			arpannounce1(ifa);
 	}
 }
 
@@ -1590,12 +1594,9 @@ arp_dad_start(struct ifaddr *ifa)
 		return;
 	}
 	if (!ip_dad_count) {
-		struct in_addr *ip = &IA_SIN(ifa)->sin_addr;
-
 		ia->ia4_flags &= ~IN_IFF_TENTATIVE;
 		rt_newaddrmsg(RTM_NEWADDR, ifa, 0, NULL);
-		arprequest(ifa->ifa_ifp, ip, ip,
-		    CLLADDR(ifa->ifa_ifp->if_sadl));
+		arpannounce1(ifa);
 		return;
 	}
 	KASSERT(ifa->ifa_ifp != NULL);
@@ -1674,7 +1675,6 @@ arp_dad_timer(struct ifaddr *ifa)
 {
 	struct in_ifaddr *ia = (struct in_ifaddr *)ifa;
 	struct dadq *dp;
-	struct in_addr *ip;
 
 	mutex_enter(softnet_lock);
 	KERNEL_LOCK(1, NULL);
@@ -1750,9 +1750,7 @@ announce:
 		/*
 		 * Announce the address.
 		 */
-		ip = &IA_SIN(ifa)->sin_addr;
-		arprequest(ifa->ifa_ifp, ip, ip,
-		    CLLADDR(ifa->ifa_ifp->if_sadl));
+		arpannounce1(ifa);
 		dp->dad_arp_acount++;
 		if (dp->dad_arp_acount < dp->dad_arp_announce) {
 			arp_dad_starttimer(dp, ANNOUNCE_INTERVAL * hz);

Index: src/sys/netinet/if_inarp.h
diff -u src/sys/netinet/if_inarp.h:1.49 src/sys/netinet/if_inarp.h:1.50
--- src/sys/netinet/if_inarp.h:1.49	Tue Apr 19 04:13:56 2016
+++ src/sys/netinet/if_inarp.h	Tue Oct 11 12:32:30 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_inarp.h,v 1.49 2016/04/19 04:13:56 ozaki-r Exp $	*/
+/*	$NetBSD: if_inarp.h,v 1.50 2016/10/11 12:32:30 roy Exp $	*/
 
 /*
  * Copyright (c) 1982, 1986, 1993
@@ -78,8 +78,7 @@ void arp_rtrequest(int, struct rtentry *
 int arpresolve(struct ifnet *, const struct rtentry *, struct mbuf *,
     const struct sockaddr *, void *, size_t);
 void arpintr(void);
-void arprequest(struct ifnet *, const struct in_addr *, const struct in_addr *,
-    const u_int8_t *);
+void arpannounce(struct ifnet *, struct ifaddr *, const uint8_t *);
 void arp_drain(void);
 int arpioctl(u_long, void *);
 void arpwhohas(struct ifnet *, struct in_addr *);

Index: src/sys/netinet/ip_carp.c
diff -u src/sys/netinet/ip_carp.c:1.77 src/sys/netinet/ip_carp.c:1.78
--- src/sys/netinet/ip_carp.c:1.77	Mon Aug  1 03:15:30 2016
+++ src/sys/netinet/ip_carp.c	Tue Oct 11 12:32:30 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_carp.c,v 1.77 2016/08/01 03:15:30 ozaki-r Exp $	*/
+/*	$NetBSD: ip_carp.c,v 1.78 2016/10/11 12:32:30 roy Exp $	*/
 /*	$OpenBSD: ip_carp.c,v 1.113 2005/11/04 08:11:54 mcbride Exp $	*/
 
 /*
@@ -33,7 +33,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_carp.c,v 1.77 2016/08/01 03:15:30 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_carp.c,v 1.78 2016/10/11 12:32:30 roy Exp $");
 
 /*
  * TODO:
@@ -1231,8 +1231,7 @@ carp_send_arp(struct carp_softc *sc)
 		if (ifa->ifa_addr->sa_family != AF_INET)
 			continue;
 
-		in = &ifatoia(ifa)->ia_addr.sin_addr;
-		arprequest(sc->sc_carpdev, in, in, CLLADDR(sc->sc_if.if_sadl));
+		arpannounce(sc->sc_carpdev, ifa, CLLADDR(sc->sc_if.if_sadl));
 	}
 	splx(s);
 	KERNEL_UNLOCK_ONE(NULL);

Reply via email to