kern/94408: if_bridge breaks proxy ARP functionality

Eygene A.Ryabinkin rea-fbsd at rea.mbslab.kiae.ru
Mon Mar 13 11:30:48 UTC 2006


>Number:         94408
>Category:       kern
>Synopsis:       if_bridge breaks proxy ARP functionality
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Mar 13 11:30:45 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator:     Eygene A. Ryabinkin
>Release:        FreeBSD 6.1-PRERELEASE i386
>Organization:
Code Labs
>Environment:
System: FreeBSD XXXX 6.1-PRERELEASE FreeBSD 6.1-PRERELEASE #X: Tue Mar 7 20:15:22 MSK 2006 root at XXXX:/usr/obj/usr/src/sys/XXXX i386


	
>Description:
 When many interfaces are bridged together via if_bridge (or old-style
BRIDGE) the proxy ARP functionality will not work for some interfaces of
the bridge: kern/75634 modified the source code of netinet/if_ether.c to
send proxied replies only if original ARP request came from the interface
proxy ARP entry belongs to.

 This is correct for the standalone interface, but if many interfaces
are bridged I expect (but it is only my expectations) to get the proxied
reply on any of the bridged interfaces if the proxy ARP entry exist for
at least one interface from that bridge.

 Another way to explain the problem: suppose we have the proxy ARP
entry for IP NN and MAC MM on the interface fxp0. And interfaces fxp0
and fxp1 are bridged via if_bridge. Then all ARP requests for NN coming
via fxp0 will answered with MAC MM, but none of the ARP requests for NN
coming via fxp1 will be answered, because the proxy ARP entry have fxp0
as the interface, not the fxp1.

>How-To-Repeat:
 Make two bridged interfaces. Make the proxy arp entry for one of them.
Do the ARP request from the subnet part that is behind another interface.
You will get no answer. Do the ARP request from the subnet part that
is behind the first interface: you will get the correct answer.

>Fix:
 
 The obvious way to fix the problem is to enable the proxy ARP answers
on any of the bridged interfaces if proxy record belongs to any of
the bridged interfaces. The following patch inhibits such behaviour for
if_bridge. I'm not using the old-style BRIDGE now, but I beleive that
the problem can be fixed for BRIDGE as well.

 The patch itself:
-----
--- if_ether.c.orig	Sun Mar 12 11:37:42 2006
+++ if_ether.c	Mon Mar 13 10:18:20 2006
@@ -863,10 +863,13 @@
 		} else {
 			/*
 			 * Return proxied ARP replies only on the interface
-			 * where this network resides. Otherwise we may
-			 * conflict with the host we are proxying for.
+			 * or bridge cluster where this network resides.
+			 * Otherwise we may conflict with the host we are
+			 * proxying for.
 			 */
-			if (rt->rt_ifp != ifp) {
+			if (rt->rt_ifp != ifp &&
+			    (rt->rt_ifp->if_bridge != ifp->if_bridge ||
+			    ifp->if_bridge == NULL)) {
 				RT_UNLOCK(rt);
 				goto drop;
 			}
-----

 I am almost sure that the behaviour my patch enables is the correct one:
this is bridge and ARP queries are broadcasts, so we should answer such
queries on any bridge interface. But someone who is better skilled with
the networking can correct me: please, do it if I am wrong.
>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list