bridge: Separate egress policy bitmap
Add an ability to configure a separate "untagged" egress policy to the VLAN information of the bridge. This superseeds PVID policy and makes PVID ingress-only. The policy is configured with a new flag and is represented as a port bitmap per vlan. Egress frames with a VLAN id in "untagged" policy bitmap would egress the port without VLAN header. Signed-off-by: Vlad Yasevich <vyasevic@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
					parent
					
						
							
								bc9a25d21e
							
						
					
				
			
			
				commit
				
					
						35e03f3a02
					
				
			
		
					 4 changed files with 20 additions and 6 deletions
				
			
		|  | @ -121,6 +121,7 @@ enum { | |||
| 
 | ||||
| #define BRIDGE_VLAN_INFO_MASTER	(1<<0)	/* Operate on Bridge device as well */ | ||||
| #define BRIDGE_VLAN_INFO_PVID	(1<<1)	/* VLAN is PVID, ingress untagged */ | ||||
| #define BRIDGE_VLAN_INFO_UNTAGGED	(1<<2)	/* VLAN egresses untagged */ | ||||
| 
 | ||||
| struct bridge_vlan_info { | ||||
| 	u16 flags; | ||||
|  |  | |||
|  | @ -143,6 +143,10 @@ static int br_fill_ifinfo(struct sk_buff *skb, | |||
| 			vinfo.flags = 0; | ||||
| 			if (vid == pvid) | ||||
| 				vinfo.flags |= BRIDGE_VLAN_INFO_PVID; | ||||
| 
 | ||||
| 			if (test_bit(vid, pv->untagged_bitmap)) | ||||
| 				vinfo.flags |= BRIDGE_VLAN_INFO_UNTAGGED; | ||||
| 
 | ||||
| 			if (nla_put(skb, IFLA_BRIDGE_VLAN_INFO, | ||||
| 				    sizeof(vinfo), &vinfo)) | ||||
| 				goto nla_put_failure; | ||||
|  |  | |||
|  | @ -75,6 +75,7 @@ struct net_port_vlans { | |||
| 	}				parent; | ||||
| 	struct rcu_head			rcu; | ||||
| 	unsigned long			vlan_bitmap[BR_VLAN_BITMAP_LEN]; | ||||
| 	unsigned long			untagged_bitmap[BR_VLAN_BITMAP_LEN]; | ||||
| 	u16				num_vlans; | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -23,6 +23,15 @@ static void __vlan_delete_pvid(struct net_port_vlans *v, u16 vid) | |||
| 	v->pvid = 0; | ||||
| } | ||||
| 
 | ||||
| static void __vlan_add_flags(struct net_port_vlans *v, u16 vid, u16 flags) | ||||
| { | ||||
| 	if (flags & BRIDGE_VLAN_INFO_PVID) | ||||
| 		__vlan_add_pvid(v, vid); | ||||
| 
 | ||||
| 	if (flags & BRIDGE_VLAN_INFO_UNTAGGED) | ||||
| 		set_bit(vid, v->untagged_bitmap); | ||||
| } | ||||
| 
 | ||||
| static int __vlan_add(struct net_port_vlans *v, u16 vid, u16 flags) | ||||
| { | ||||
| 	struct net_bridge_port *p = NULL; | ||||
|  | @ -31,8 +40,7 @@ static int __vlan_add(struct net_port_vlans *v, u16 vid, u16 flags) | |||
| 	int err; | ||||
| 
 | ||||
| 	if (test_bit(vid, v->vlan_bitmap)) { | ||||
| 		if (flags & BRIDGE_VLAN_INFO_PVID) | ||||
| 			__vlan_add_pvid(v, vid); | ||||
| 		__vlan_add_flags(v, vid, flags); | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -69,8 +77,7 @@ static int __vlan_add(struct net_port_vlans *v, u16 vid, u16 flags) | |||
| 
 | ||||
| 	set_bit(vid, v->vlan_bitmap); | ||||
| 	v->num_vlans++; | ||||
| 	if (flags & BRIDGE_VLAN_INFO_PVID) | ||||
| 		__vlan_add_pvid(v, vid); | ||||
| 	__vlan_add_flags(v, vid, flags); | ||||
| 
 | ||||
| 	return 0; | ||||
| 
 | ||||
|  | @ -86,6 +93,7 @@ static int __vlan_del(struct net_port_vlans *v, u16 vid) | |||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	__vlan_delete_pvid(v, vid); | ||||
| 	clear_bit(vid, v->untagged_bitmap); | ||||
| 
 | ||||
| 	if (v->port_idx && vid) { | ||||
| 		struct net_device *dev = v->parent.port->dev; | ||||
|  | @ -144,11 +152,11 @@ struct sk_buff *br_handle_vlan(struct net_bridge *br, | |||
| 		goto out; | ||||
| 
 | ||||
| 	/* At this point, we know that the frame was filtered and contains
 | ||||
| 	 * a valid vlan id.  If the vlan id matches the pvid of current port | ||||
| 	 * a valid vlan id.  If the vlan id is set in the untagged bitmap, | ||||
| 	 * send untagged; otherwise, send taged. | ||||
| 	 */ | ||||
| 	br_vlan_get_tag(skb, &vid); | ||||
| 	if (vid == br_get_pvid(pv)) | ||||
| 	if (test_bit(vid, pv->untagged_bitmap)) | ||||
| 		skb = br_vlan_untag(skb); | ||||
| 	else { | ||||
| 		/* Egress policy says "send tagged".  If output device
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Vlad Yasevich
				Vlad Yasevich