Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 04 Oct 2007 11:52:05 +0300
From:      Tobias Ernst <tobi@casino.uni-stuttgart.de>
To:        freebsd-pf@freebsd.org
Subject:   Re: Filtering bridge - how to decide which of the bridge's interfaces a packet arrived on?
Message-ID:  <4704A9B5.8030805@casino.uni-stuttgart.de>
In-Reply-To: <47021088.4090808@casino.uni-stuttgart.de>
References:  <46EDE839.8060501@criticalmagic.com>	<20070917202951.GF2742@heff.fud.org.nz>	<46EEE5C9.8050103@criticalmagic.com>	<20070917204318.GB9614@heff.fud.org.nz>	<4701FAD7.4050600@casino.uni-stuttgart.de>	<20071002091610.GD38352@heff.fud.org.nz> <47021088.4090808@casino.uni-stuttgart.de>

next in thread | previous in thread | raw e-mail | index | archive | help
Tobias Ernst schrieb:

> I will try the patch from kern/116051 on my 6.2 sources, though. The
> description says that it has been tested on 6.2, and hopefully 6.3 will
> be out by the time my setup goes into production.

For the interested audience: Applying this patch to 6.2 requires some
modifications, but they are rather straightforward. My patch for 6.2 is
below.

After applying it, you can do

sysctl net.link.bridge.pfil_local_phys=1

After that, packets destined for an IP address of the local firewall
that is assigned to a bridge interface will show up in PF on the
individual bridge member that they physically arrive on (e.g. em0)
RATHER than on the bridge interface of which the physical interface is a
member (e.g. bridge0).

The packets will then be visible on the physical interface only, so if
you were previously filtering on bridge0, you now have to adapt your
rules to filter on each individual member interface.

Many thanks to Andrew for pointing me in the right direction, and of
course to Eygene for developing this patch.

Regards
Tobias

*** if_bridge.c.ORIG	Tue Oct  2 11:33:42 2007
--- if_bridge.c	Tue Oct  2 15:01:09 2007
***************
*** 281,286 ****
--- 281,287 ----
  static int pfil_member = 1; /* run pfil hooks on the member interface */
  static int pfil_ipfw = 0;   /* layer2 filter with ipfw */
  static int pfil_ipfw_arp = 0;   /* layer2 filter with ipfw */
+ static int pfil_local_phys = 0; /* PATCH show phys interface for
bridge-destined packages */
  SYSCTL_INT(_net_link_bridge, OID_AUTO, pfil_onlyip, CTLFLAG_RW,
      &pfil_onlyip, 0, "Only pass IP packets when pfil is enabled");
  SYSCTL_INT(_net_link_bridge, OID_AUTO, ipfw_arp, CTLFLAG_RW,
***************
*** 289,294 ****
--- 290,297 ----
      &pfil_bridge, 0, "Packet filter on the bridge interface");
  SYSCTL_INT(_net_link_bridge, OID_AUTO, pfil_member, CTLFLAG_RW,
      &pfil_member, 0, "Packet filter on the member interface");
+ SYSCTL_INT(_net_link_bridge, OID_AUTO, pfil_local_phys, CTLFLAG_RW,
+     &pfil_local_phys, 0, "Show physical interface for bridge-destined
packets");

  struct bridge_control {
  	int	(*bc_func)(struct bridge_softc *, void *);
***************
*** 1984,1989 ****
--- 1987,2006 ----

  	if (memcmp(eh->ether_dhost, IFP2ENADDR(bifp),
  	    ETHER_ADDR_LEN) == 0) {
+           /* Try to filter on the physical interface.
+            *
+            */
+           if (pfil_local_phys && ((inet_pfil_hook.ph_busy_count >= 0)
+ #ifdef INET6
+                                || (inet6_pfil_hook.ph_busy_count >= 0)
+ #endif
+ 	        )) {
+                     if (bridge_pfil(&m, ifp, NULL, PFIL_IN)!=0 ||
+                         m == NULL) {
+                               BRIDGE_UNLOCK(sc);
+                               return NULL;
+                     }
+                  }
  		/*
  		 * If the packet is for us, set the packets source as the
  		 * bridge, and return the packet back to ether_input for


-- 
Universität Stuttgart|Fakultät für Architektur und Stadtplanung|casinoIT
70174 Stuttgart Geschwister-Scholl-Straße 24D
T +49 (0)711 121-4228             F +49 (0)711 121-4276
E office@casino.uni-stuttgart.de  I http://www.casino.uni-stuttgart.de



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