Date: Mon, 3 Sep 2007 17:22:09 +0400 (MSD) From: Eygene Ryabinkin <rea-fbsd@codelabs.ru> To: FreeBSD-gnats-submit@FreeBSD.org Cc: rik@FreeBSD.org, thompsa@FreeBSD.org Subject: kern/116051: add local packet filtering on the physical interfaces of if_bridge Message-ID: <20070903132209.EE3541AF41E@void.codelabs.ru> Resent-Message-ID: <200709031330.l83DU15R089373@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 116051 >Category: kern >Synopsis: add local packet filtering on the physical interfaces of if_bridge >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Mon Sep 03 13:30:01 GMT 2007 >Closed-Date: >Last-Modified: >Originator: Eygene Ryabinkin >Release: FreeBSD 7.0-CURRENT i386 >Organization: Code Labs >Environment: System: FreeBSD XXX 7.0-CURRENT FreeBSD 7.0-CURRENT #9: Wed Aug 8 10:56:57 MSD 2007 root@XXX:/usr/src/sys/i386/compile/XXX i386 >Description: Currently, if we are running filtering L2-bridge with if_bridge it is not possible to filter the packets that are destined to the bridge itself (on the L2) basing on the physical incoming interface. Such packets are seen by pfil(9) only at the bridge interface itself. The common setup where such feature is desirable is the bridge that does simple IP-gatewaying or NAT for the number of the links bundled together on the L2. One can distinguish the packets only using its IP address, but it is sometimes desirable to add the incoming interface check to differentiate between network segments using physical network characteristics (switches and their ports or VLANs) and not only logical ones (MAC or IP in the packet header). >How-To-Repeat: Setup if_bridge, make it the default gateway for the network with the gateway's IP sitting on the bridge interface itself and set up IP forwarding. Try to filter the packets that are destined on the L2 to the gateway, but are the transit ones on the L3: you will see that such packets are seen by pfil(9) only at the bridge interface, but not at the physical incoming interface. One can inspect the /sys/net/if_bridge.c, rev. 1.102, starting from the line 2070 to see why filters see only the bridge interface. >Fix: The following patches implements additional filtering on the physical incoming interface and changing the manual page, describing the added option. This patch was tested for about half a year on the rather busy NAT box serving half hundred clients (on the 6.2, but now it was ported to the 7-CURRENT). Source patch: --- pfil-local-phys.patch begins here --- --- if_bridge.c.orig 2007-09-03 15:16:40.000000000 +0400 +++ if_bridge.c 2007-09-03 16:53:31.000000000 +0400 @@ -340,6 +340,8 @@ 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; /* show physical interface for the + bridge-destined packets */ static int log_stp = 0; /* log STP state changes */ SYSCTL_INT(_net_link_bridge, OID_AUTO, pfil_onlyip, CTLFLAG_RW, &pfil_onlyip, 0, "Only pass IP packets when pfil is enabled"); @@ -349,6 +351,8 @@ &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"); SYSCTL_INT(_net_link_bridge, OID_AUTO, log_stp, CTLFLAG_RW, &log_stp, 0, "Log STP state changes"); @@ -2070,6 +2074,21 @@ if (memcmp(eh->ether_dhost, IF_LLADDR(bifp), ETHER_ADDR_LEN) == 0) { /* + * Try to filter on the physical interface. + */ + if (pfil_local_phys && (PFIL_HOOKED(&inet_pfil_hook) +#ifdef INET6 + || PFIL_HOOKED(&inet6_pfil_hook) +#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 * local processing. --- pfil-local-phys.patch ends here --- Manpage patch: --- pfil-local-phys.man.patch begins here --- --- if_bridge.4.orig 2007-09-03 15:29:16.000000000 +0400 +++ if_bridge.4 2007-09-03 17:00:05.000000000 +0400 @@ -185,6 +185,20 @@ to .Li 0 to disable it. +.It Va net.link.bridge.pfil_local_phys +Set to +.Li 1 +to enable additional filtering on the physical incoming interface +using the +.Xr pfil 9 +framework when the packet is destined (on the layer 2) to the +bridge interface itself. +The filtering is done before the usual +.Xr pfil 9 +processing on the bridge interface. +Set to +.Li 0 +to disable this feature. .It Va net.link.bridge.ipfw Set to .Li 1 @@ -310,7 +324,9 @@ to assign the IP address only to the .Nm interface and not to the bridge members. -But your mileage may vary. +Enabling +.Va net.link.bridge.pfil_local_phys +will let you do the additional filtering using the physical interface name. .Sh EXAMPLES The following when placed in the file .Pa /etc/rc.conf --- pfil-local-phys.man.patch ends here --- >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20070903132209.EE3541AF41E>