On Thu, Jun 15, 2006 at 12:53:24PM -0700, Ben Greear wrote: > Frederik Deweerdt wrote: > >On Thu, Jun 15, 2006 at 07:44:35AM -0700, Ben Greear wrote: > >>With your change[1], I do not believe bridging two different VLAN ids will work. > >> > >>Might be we could hack the bridging code to allow something like this to > >>work, however.... > >> > >OK, thank you, I'll have a look at this. A wild guess though, couldn't we rely on > >(skb->net_device->br_port) and > >(skb->net_device->priv_flags & IFF_802_1Q_VLAN) > >to know if the skb we're handling has been bridged from a VLANized interface? > >The code wouldn't support double VLANs for bridged VLANized interfaces, but anything > >else would work. > > I think a better solution might > be to have the bridging code strip the VLAN tag before sending it to a VLAN of > a different VID, or pass a flag so that the VLAN code knows to (re) encapsulate > or not. Does this means modifiying (in net/bridge/*) if (skb->protocol == htons(ETH_P_8021Q)) { skb_pull(skb, VLAN_HLEN); skb->nh.raw += VLAN_HLEN; } to something along the lines of: while(vlan_tags_are_found(skb)) { skb_pull(skb, VLAN_HLEN); skb->nh.raw += VLAN_HLEN; } ? > > Another possible problem: what if you are trying to encapsulate vlan 7 inside > of vlan 7. How do you know to double-encapsulate? What if user-space is sending > a pre-built VLAN frame with a raw socket? I'm not sure there is enough info as to > the intent to encapsulate or not once the VLAN code receives the packet. I see how my proposal was wrong. Let me wild guess again :). I wondered if the following code could be better. The idea being that the code could determine the need for encapsulating or not from the interface's nesting level and the actual number of VLAN tags in the packet. static int vlan_tag_nesting_level(unsigned char* data) { vlan_ethhdr *p = (struct vlan_ethhdr *)data; int i=0; while (p->h_vlan_proto == __constant_htons(ETH_P_8021Q)) { p+=sizeof(VLAN_TAG); i++; } return i; } static int iface_nesting_level(struct net_device *vlan_dev) { int i=0; while (vlan_dev && (vlan_dev->priv_flags & IFF_802_1Q_VLAN)) { vlan_dev = VLAN_DEV_INFO(vlan_dev)->real_dev; i++; } return i; } ... in vlan_dev_hard_start_xmit ... - if (veth->h_vlan_proto != __constant_htons(ETH_P_8021Q)) { + if (iface_nesting_level(vlan_dev) != vlan_tag_nesting_level(skb->data)) { Thanks, Frederik [1] Proposed change was to suppress the if (veth->h_vlan_proto != __constant_htons(ETH_P_8021Q)) check in vlan_dev.c:vlan_dev_hard_start_xmit in order to get double stacked VLANs working