From owner-freebsd-net@FreeBSD.ORG Sun Dec 24 09:40:14 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 11EF816A407 for ; Sun, 24 Dec 2006 09:40:14 +0000 (UTC) (envelope-from yar@comp.chem.msu.su) Received: from comp.chem.msu.su (comp.chem.msu.su [158.250.32.97]) by mx1.freebsd.org (Postfix) with ESMTP id 105FB13C473 for ; Sun, 24 Dec 2006 09:40:12 +0000 (UTC) (envelope-from yar@comp.chem.msu.su) Received: from comp.chem.msu.su (localhost [127.0.0.1]) by comp.chem.msu.su (8.13.4/8.13.3) with ESMTP id kBO9dw6r052074; Sun, 24 Dec 2006 12:39:58 +0300 (MSK) (envelope-from yar@comp.chem.msu.su) Received: (from yar@localhost) by comp.chem.msu.su (8.13.4/8.13.3/Submit) id kBO9dqHp052070; Sun, 24 Dec 2006 12:39:52 +0300 (MSK) (envelope-from yar) Date: Sun, 24 Dec 2006 12:39:51 +0300 From: Yar Tikhiy To: Julian Elischer Message-ID: <20061224093951.GD49045@comp.chem.msu.su> References: <457DCD47.5090004@elischer.org> <200612120045.41425.max@love2party.net> <4583119B.20608@elischer.org> <200612160446.02644.max@love2party.net> <4584CE0C.3020307@elischer.org> <458C426A.9060604@elischer.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <458C426A.9060604@elischer.org> User-Agent: Mutt/1.5.9i Cc: Max Laier , Andre Oppermann , freebsd-net@freebsd.org Subject: Re: [was] addition to ipfw (read vlans from bridge).. X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 24 Dec 2006 09:40:14 -0000 On Fri, Dec 22, 2006 at 12:39:06PM -0800, Julian Elischer wrote: > > 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. Excuse me, but I'd like to second Andre's opinion. We should stop fiddling with the mbuf contents in favour of teaching ipfw (or the interface code between bridge and ipfw) of 802.1q (or its generalisation.) Now that the 802.1q VLAN technology has been well integrated in the general Ethernet framework by IEEE, there is very litte sense left in such hacks. If ipfw is to stay L2-agnostic, then let's just pass the offset of the IP header into the mbuf to it. The 802.1q header is so nice and simple and easy to parse at any level. So this patch can be OK in 6.x for the only sake of preserving the pfil ABI, but it should die along with it. An extended interface is apparently called for in HEAD. There is also work in progress to introduce nested VLANs AKA Q-n-Q. They seem to present a challenge to the scheme you are implementing. > 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 > #include /* for struct arpcom */ > #include > +#include > #include > #include > > @@ -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 > _______________________________________________ > freebsd-net@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-net > To unsubscribe, send any mail to "freebsd-net-unsubscribe@freebsd.org" -- Yar