Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 22 Dec 2006 12:39:06 -0800
From:      Julian Elischer <julian@elischer.org>
To:        Julian Elischer <julian@elischer.org>
Cc:        Max Laier <max@love2party.net>, Andre Oppermann <andre@freebsd.org>, freebsd-net@freebsd.org
Subject:   Re: [was] addition to ipfw (read vlans from bridge)..
Message-ID:  <458C426A.9060604@elischer.org>
In-Reply-To: <4584CE0C.3020307@elischer.org>
References:  <457DCD47.5090004@elischer.org>	<200612120045.41425.max@love2party.net>	<4583119B.20608@elischer.org>	<200612160446.02644.max@love2party.net> <4584CE0C.3020307@elischer.org>

next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------000200070908000402080801
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit


Taking to heart comments by Andre and Max (Laier),
I have redone this patch in a different manner.

The aim is to be able to see inside vlans when bridging.
Now, this is a 6.x patch to bridge.c because that is what we
are using, but I will make a similar patch to if_bridge.c
for 6 and 7 if this meets with approval.


Basically if it is a vlan packet, take off the whole vlan header instead 
of just the ether header, but pass to ipfw, an ether header with
the real protocol field substituted in.
when finishing put back everything we removed before.


The only addition I'd do to this would be to add a sysctl
to turn it on if people thought it would be break POLA too much
to have it work by default.

--------------000200070908000402080801
Content-Type: text/plain; x-mac-type="0"; x-mac-creator="0";
 name="vl.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="vl.diff"

Index: bridge.c
===================================================================
RCS file: /usr/local/cvsroot/freebsd/src/sys/net/Attic/bridge.c,v
retrieving revision 1.93.2.1
diff -u -r1.93.2.1 bridge.c
--- bridge.c	25 Aug 2005 05:01:19 -0000	1.93.2.1
+++ bridge.c	22 Dec 2006 20:29:16 -0000
@@ -103,6 +103,7 @@
 #include <net/if.h>
 #include <net/if_arp.h>		/* for struct arpcom */
 #include <net/if_types.h>
+#include <net/if_vlan_var.h>
 #include <net/if_var.h>
 #include <net/pfil.h>
 
@@ -932,13 +933,17 @@
 bdg_forward(struct mbuf *m0, struct ifnet *dst)
 {
 #define	EH_RESTORE(_m) do {						   \
-    M_PREPEND((_m), ETHER_HDR_LEN, M_DONTWAIT);			   	   \
+    M_PREPEND((_m), has_vlan_hdr? sizeof(evl):ETHER_HDR_LEN, M_DONTWAIT);  \
     if ((_m) == NULL) {							   \
 	bdg_dropped++;							   \
 	return NULL;							   \
     }									   \
     if (eh != mtod((_m), struct ether_header *))			   \
-	bcopy(&save_eh, mtod((_m), struct ether_header *), ETHER_HDR_LEN); \
+        if (has_vlan_hdr) {						   \
+	 bcopy(&save_eh, mtod((_m), struct ether_header *), ETHER_HDR_LEN); \
+	} else {							   \
+	 bcopy(&evl, mtod((_m), struct ether_header *), sizeof(evl));	   \
+	}								   \
     else								   \
 	bdg_predict++;							   \
 } while (0);
@@ -949,6 +954,8 @@
     int error;
     struct ifnet *real_dst = dst;	/* real dst from ether_output */
     struct ip_fw_args args;
+    int has_vlan_hdr;
+    struct ether_vlan_header evl;
     struct ether_header save_eh;
     struct mbuf *m;
 
@@ -1022,9 +1029,21 @@
 	 * Furthermore, the mbuf chain might be replaced at various
 	 * places.  To deal with this we copy the header to a temporary
 	 * location, strip the header, and restore it as needed.
+	 * If we have a vlan header we need to synthesize the 
+	 * encapsulated ether header and instead store the vlan header
+	 * for replacement later.
 	 */
-	bcopy(eh, &save_eh, ETHER_HDR_LEN);	/* local copy for restore */
-	m_adj(m0, ETHER_HDR_LEN);		/* temporarily strip header */
+	if (eh->ether_type == ETHERTYPE_VLAN) {
+		bcopy(eh, &evl, sizeof(evl));		/* local copy for restore */
+		bcopy(eh, &save_eh, ETHER_HDR_LEN);	/* what is passed to ipfw */
+		save_eh.ether_type = evl.evl_proto;		/* but with the final proto */
+		has_vlan_hdr = 1;
+		m_adj(m0, sizeof(evl));			/* temporarily strip header */
+	} else {
+		bcopy(eh, &save_eh, ETHER_HDR_LEN);	/* local copy for restore */
+		has_vlan_hdr = 0;
+		m_adj(m0, ETHER_HDR_LEN);		/* temporarily strip header */
+	}
 
 	/*
 	 * Check that the IP header is aligned before passing up to the packet

--------------000200070908000402080801--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?458C426A.9060604>