Author: qingli
Date: Tue Sep 15 22:37:17 2009
New Revision: 197238
URL: http://svn.freebsd.org/changeset/base/197238

Log:
  MFC   r197225
  
  This patch enables the node to respond to ARP requests for
  configured proxy ARP entries.
  
  Reviewed by:  bz
  Approved by:  re

Modified:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)
  stable/8/sys/netinet/if_ether.c

Modified: stable/8/sys/netinet/if_ether.c
==============================================================================
--- stable/8/sys/netinet/if_ether.c     Tue Sep 15 22:25:19 2009        
(r197237)
+++ stable/8/sys/netinet/if_ether.c     Tue Sep 15 22:37:17 2009        
(r197238)
@@ -694,62 +694,70 @@ reply:
        } else {
                struct llentry *lle = NULL;
 
-               if (!V_arp_proxyall)
-                       goto drop;
-
                sin.sin_addr = itaddr;
-               /* XXX MRT use table 0 for arp reply  */
-               rt = in_rtalloc1((struct sockaddr *)&sin, 0, 0UL, 0);
-               if (!rt)
-                       goto drop;
-
-               /*
-                * Don't send proxies for nodes on the same interface
-                * as this one came out of, or we'll get into a fight
-                * over who claims what Ether address.
-                */
-               if (!rt->rt_ifp || rt->rt_ifp == ifp) {
-                       RTFREE_LOCKED(rt);
-                       goto drop;
-               }
-               IF_AFDATA_LOCK(rt->rt_ifp); 
-               lle = lla_lookup(LLTABLE(rt->rt_ifp), 0, (struct sockaddr 
*)&sin);
-               IF_AFDATA_UNLOCK(rt->rt_ifp);
-               RTFREE_LOCKED(rt);
+               IF_AFDATA_LOCK(ifp); 
+               lle = lla_lookup(LLTABLE(ifp), 0, (struct sockaddr *)&sin);
+               IF_AFDATA_UNLOCK(ifp);
 
-               if (lle != NULL) {
+               if ((lle != NULL) && (lle->la_flags & LLE_PUB)) {
                        (void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln);
                        (void)memcpy(ar_sha(ah), &lle->ll_addr, ah->ar_hln);
                        LLE_RUNLOCK(lle);
-               } else
-                       goto drop;
+               } else {
 
-               /*
-                * Also check that the node which sent the ARP packet
-                * is on the the interface we expect it to be on. This
-                * avoids ARP chaos if an interface is connected to the
-                * wrong network.
-                */
-               sin.sin_addr = isaddr;
+                       if (lle != NULL)
+                               LLE_RUNLOCK(lle);
 
-               /* XXX MRT use table 0 for arp checks */
-               rt = in_rtalloc1((struct sockaddr *)&sin, 0, 0UL, 0);
-               if (!rt)
-                       goto drop;
-               if (rt->rt_ifp != ifp) {
-                       log(LOG_INFO, "arp_proxy: ignoring request"
-                           " from %s via %s, expecting %s\n",
-                           inet_ntoa(isaddr), ifp->if_xname,
-                           rt->rt_ifp->if_xname);
+                       if (!V_arp_proxyall)
+                               goto drop;
+                       
+                       sin.sin_addr = itaddr;
+                       /* XXX MRT use table 0 for arp reply  */
+                       rt = in_rtalloc1((struct sockaddr *)&sin, 0, 0UL, 0);
+                       if (!rt)
+                               goto drop;
+
+                       /*
+                        * Don't send proxies for nodes on the same interface
+                        * as this one came out of, or we'll get into a fight
+                        * over who claims what Ether address.
+                        */
+                       if (!rt->rt_ifp || rt->rt_ifp == ifp) {
+                               RTFREE_LOCKED(rt);
+                               goto drop;
+                       }
+                       RTFREE_LOCKED(rt);
+
+                       (void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln);
+                       (void)memcpy(ar_sha(ah), enaddr, ah->ar_hln);
+
+                       /*
+                        * Also check that the node which sent the ARP packet
+                        * is on the the interface we expect it to be on. This
+                        * avoids ARP chaos if an interface is connected to the
+                        * wrong network.
+                        */
+                       sin.sin_addr = isaddr;
+                       
+                       /* XXX MRT use table 0 for arp checks */
+                       rt = in_rtalloc1((struct sockaddr *)&sin, 0, 0UL, 0);
+                       if (!rt)
+                               goto drop;
+                       if (rt->rt_ifp != ifp) {
+                               log(LOG_INFO, "arp_proxy: ignoring request"
+                                   " from %s via %s, expecting %s\n",
+                                   inet_ntoa(isaddr), ifp->if_xname,
+                                   rt->rt_ifp->if_xname);
+                               RTFREE_LOCKED(rt);
+                               goto drop;
+                       }
                        RTFREE_LOCKED(rt);
-                       goto drop;
-               }
-               RTFREE_LOCKED(rt);
 
 #ifdef DEBUG_PROXY
-               printf("arp: proxying for %s\n",
-                      inet_ntoa(itaddr));
+                       printf("arp: proxying for %s\n",
+                              inet_ntoa(itaddr));
 #endif
+               }
        }
 
        if (itaddr.s_addr == myaddr.s_addr &&
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to