Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 12 Oct 2011 08:08:08 +0000 (UTC)
From:      Qing Li <qingli@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r226287 - stable/9/sys/netinet
Message-ID:  <201110120808.p9C8882u053933@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: qingli
Date: Wed Oct 12 08:08:08 2011
New Revision: 226287
URL: http://svn.freebsd.org/changeset/base/226287

Log:
  MFC 225946
  
  This patch allows ARP to work properly in the presence of
  self-referencing routes. This patch is a rework of r223862.
  
  Reviewed by:	bz, zec
  Approved by:	re (kib)

Modified:
  stable/9/sys/netinet/in.c
Directory Properties:
  stable/9/sys/   (props changed)
  stable/9/sys/amd64/include/xen/   (props changed)
  stable/9/sys/boot/   (props changed)
  stable/9/sys/boot/i386/efi/   (props changed)
  stable/9/sys/boot/ia64/efi/   (props changed)
  stable/9/sys/boot/ia64/ski/   (props changed)
  stable/9/sys/boot/powerpc/boot1.chrp/   (props changed)
  stable/9/sys/boot/powerpc/ofw/   (props changed)
  stable/9/sys/cddl/contrib/opensolaris/   (props changed)
  stable/9/sys/conf/   (props changed)
  stable/9/sys/contrib/dev/acpica/   (props changed)
  stable/9/sys/contrib/octeon-sdk/   (props changed)
  stable/9/sys/contrib/pf/   (props changed)
  stable/9/sys/contrib/x86emu/   (props changed)

Modified: stable/9/sys/netinet/in.c
==============================================================================
--- stable/9/sys/netinet/in.c	Wed Oct 12 07:16:38 2011	(r226286)
+++ stable/9/sys/netinet/in.c	Wed Oct 12 08:08:08 2011	(r226287)
@@ -1411,6 +1411,8 @@ static int
 in_lltable_rtcheck(struct ifnet *ifp, u_int flags, const struct sockaddr *l3addr)
 {
 	struct rtentry *rt;
+	struct ifnet *xifp;
+	int error = 0;
 
 	KASSERT(l3addr->sa_family == AF_INET,
 	    ("sin_family %d", l3addr->sa_family));
@@ -1418,30 +1420,35 @@ in_lltable_rtcheck(struct ifnet *ifp, u_
 	/* XXX rtalloc1 should take a const param */
 	rt = rtalloc1(__DECONST(struct sockaddr *, l3addr), 0, 0);
 
+	if (rt == NULL)
+		return (EINVAL);
+
 	/*
 	 * If the gateway for an existing host route matches the target L3
-	 * address, allow for ARP to proceed.
+	 * address, which is a special route inserted by some implementation
+	 * such as MANET, and the interface is of the correct type, then
+	 * allow for ARP to proceed.
 	 */
-	if (rt != NULL && (rt->rt_flags & (RTF_HOST|RTF_GATEWAY)) &&
-	    rt->rt_gateway->sa_family == AF_INET &&
-	    memcmp(rt->rt_gateway->sa_data, l3addr->sa_data, 4) == 0) {
-		RTFREE_LOCKED(rt);
-		return (0);
-	}
-
-	if (rt == NULL || (!(flags & LLE_PUB) &&
-			   ((rt->rt_flags & RTF_GATEWAY) || 
-			    (rt->rt_ifp != ifp)))) {
+	if (rt->rt_flags & (RTF_GATEWAY | RTF_HOST)) {
+		xifp = rt->rt_ifp;
+		
+		if (xifp && (xifp->if_type != IFT_ETHER ||
+		     (xifp->if_flags & (IFF_NOARP | IFF_STATICARP)) != 0))
+			error = EINVAL;
+
+		if (memcmp(rt->rt_gateway->sa_data, l3addr->sa_data,
+		    sizeof(in_addr_t)) != 0)
+			error = EINVAL;
+	} else if (!(flags & LLE_PUB) && ((rt->rt_flags & RTF_GATEWAY) ||
+	    (rt->rt_ifp != ifp))) {
 #ifdef DIAGNOSTIC
 		log(LOG_INFO, "IPv4 address: \"%s\" is not on the network\n",
 		    inet_ntoa(((const struct sockaddr_in *)l3addr)->sin_addr));
 #endif
-		if (rt != NULL)
-			RTFREE_LOCKED(rt);
-		return (EINVAL);
+		error = EINVAL;
 	}
 	RTFREE_LOCKED(rt);
-	return 0;
+	return (error);
 }
 
 /*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201110120808.p9C8882u053933>