From rea-fbsd@codelabs.ru  Mon Sep  3 13:22:38 2007
Return-Path: <rea-fbsd@codelabs.ru>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 991B816A417
	for <FreeBSD-gnats-submit@freebsd.org>; Mon,  3 Sep 2007 13:22:38 +0000 (UTC)
	(envelope-from rea-fbsd@codelabs.ru)
Received: from pobox.codelabs.ru (pobox.codelabs.ru [144.206.177.45])
	by mx1.freebsd.org (Postfix) with ESMTP id 19E9413C45E
	for <FreeBSD-gnats-submit@freebsd.org>; Mon,  3 Sep 2007 13:22:38 +0000 (UTC)
	(envelope-from rea-fbsd@codelabs.ru)
Received: from void.codelabs.ru (void.codelabs.ru [144.206.177.25])
	by pobox.codelabs.ru with esmtps (TLSv1:CAMELLIA256-SHA:256)
	id 1ISBsY-000ARN-Ju; Mon, 03 Sep 2007 17:22:10 +0400
Message-Id: <20070903132209.EE3541AF41E@void.codelabs.ru>
Date: Mon,  3 Sep 2007 17:22:09 +0400 (MSD)
From: Eygene Ryabinkin <rea-fbsd@codelabs.ru>
Reply-To: Eygene Ryabinkin <rea-fbsd@codelabs.ru>
To: FreeBSD-gnats-submit@freebsd.org
Cc: thompsa@freebsd.org, rik@freebsd.org
Subject: add local packet filtering on the physical interfaces of if_bridge
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         116051
>Category:       kern
>Synopsis:       [if_bridge] [patch] add local packet filtering on the physical interfaces of if_bridge
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    thompsa
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Mon Sep 03 13:30:01 GMT 2007
>Closed-Date:    Thu Oct 11 20:31:13 UTC 2007
>Last-Modified:  Thu Oct 11 20:31:13 UTC 2007
>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:
Responsible-Changed-From-To: freebsd-bugs->thompsa 
Responsible-Changed-By: remko 
Responsible-Changed-When: Mon Sep 3 14:02:49 UTC 2007 
Responsible-Changed-Why:  
Over to maintainer 

http://www.freebsd.org/cgi/query-pr.cgi?pr=116051 

From: Andrew Thompson <thompsa@FreeBSD.org>
To: bug-followup@FreeBSD.org, rea-fbsd@codelabs.ru
Cc:  
Subject: Re: kern/116051: [if_bridge] [patch] add local packet filtering on the physical interfaces of if_bridge
Date: Mon, 10 Sep 2007 13:15:13 +1200

 I will look at this once 7.0 is out the door, thanks for the PR.
 
 
 Andrew

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/116051: commit references a PR
Date: Sun, 16 Sep 2007 21:09:24 +0000 (UTC)

 thompsa     2007-09-16 21:09:15 UTC
 
   FreeBSD src repository
 
   Modified files:
     share/man/man4       if_bridge.4 
     sys/net              if_bridge.c 
   Log:
   Allow additional packet filtering on the physical interface for locally
   destined packets, disabled by default.
   
   PR:             kern/116051
   Submitted by:   Eygene Ryabinkin
   Approved by:    re (bmah)
   MFC after:      2 weeks
   
   Revision  Changes    Path
   1.29      +10 -1     src/share/man/man4/if_bridge.4
   1.103     +20 -0     src/sys/net/if_bridge.c
 _______________________________________________
 cvs-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/cvs-all
 To unsubscribe, send any mail to "cvs-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: open->patched 
State-Changed-By: thompsa 
State-Changed-When: Sun Sep 16 21:11:43 UTC 2007 
State-Changed-Why:  
I managed to slip this in for 7.0 since its a safe change. Thanks for the PR! 

http://www.freebsd.org/cgi/query-pr.cgi?pr=116051 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/116051: commit references a PR
Date: Thu, 11 Oct 2007 20:29:00 +0000 (UTC)

 thompsa     2007-10-11 20:28:53 UTC
 
   FreeBSD src repository
 
   Modified files:        (Branch: RELENG_6)
     sys/net              if_bridge.c 
     share/man/man4       if_bridge.4 
   Log:
   MFC if_bridge.c r1.103, if_bridge.4 r1.29
     Allow additional packet filtering on the physical interface for locally
     destined packets, disabled by default.
   
   PR:             kern/116051
   Submitted by:   Eygene Ryabinkin
   
   Revision   Changes    Path
   1.5.2.16   +11 -2     src/share/man/man4/if_bridge.4
   1.11.2.53  +20 -0     src/sys/net/if_bridge.c
 _______________________________________________
 cvs-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/cvs-all
 To unsubscribe, send any mail to "cvs-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: patched->closed 
State-Changed-By: thompsa 
State-Changed-When: Thu Oct 11 20:30:45 UTC 2007 
State-Changed-Why:  
MFCed, thanks for the PR. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=116051 
>Unformatted:
