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);
 }
 
 /*
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to