Re: [Bridge] [PATCH v7 net-next 01/12] bridge: Add vlan filtering infrastructure
From: Simon Barber <hidden>
Date: 2013-01-31 21:46:38
Also in:
bridge
Great - I look forward to seeing this functionality in the kernel - this will be very useful. Are you releasing brctl patches too? Simon On 01/31/2013 12:34 PM, Vlad Yasevich wrote:
On 01/31/2013 03:33 PM, Simon Barber wrote:quoted
I wrote a similar patch a few years ago: https://lists.linux-foundation.org/pipermail/bridge/2006-September/005046.html This patch also added the possibility to define a native vlan for each port and for the bridge port itself - is there any interest in this feature as well as the filtering?See patch 5 and 6 and the series :) -vladquoted
Simon On 01/31/2013 11:57 AM, Michał Mirosław wrote:quoted
2013/1/31 Vlad Yasevich [off-list ref]:quoted
Adds an optional infrustructure component to bridge that would allow native vlan filtering in the bridge. Each bridge port (as well as the bridge device) now get a VLAN bitmap. Each bit in the bitmap is associated with a vlan id. This way if the bit corresponding to the vid is set in the bitmap that the packet with vid is allowed to enter and exit the port. Write access the bitmap is protected by RTNL and read access protected by RCU.[...]quoted
+static int __vlan_del(struct net_port_vlans *v, u16 vid) +{ + unsigned long first_bit; + unsigned long last_bit; + + if (!test_bit(vid, v->vlan_bitmap)) + return -EINVAL; + + /* Check to see if any other vlans are in this table. If this + * is the last vlan, delete the whole structure. If this is not the + * last vlan, just clear the bit. + */ + first_bit = find_first_bit(v->vlan_bitmap, BR_VLAN_BITMAP_LEN); + last_bit = find_last_bit(v->vlan_bitmap, BR_VLAN_BITMAP_LEN); + + if (v->port_idx && vid) { + struct net_device *dev = vlans_to_port(v)->dev; + + if (dev->features & NETIF_F_HW_VLAN_FILTER) + dev->netdev_ops->ndo_vlan_rx_kill_vid(dev, vid); + } + + clear_bit(vid, v->vlan_bitmap); + if (first_bit == last_bit) {if (bitmap_empty(v->vlan_bitmap, BR_VLAN_BITMAP_LEN))quoted
+ if (v->port_idx) { + struct net_bridge_port *p = vlans_to_port(v); + rcu_assign_pointer(p->vlan_info, NULL); + } else { + struct net_bridge *br = vlans_to_bridge(v); + rcu_assign_pointer(br->vlan_info, NULL); + }You seem to use vlans_to_port/vlans_to_bridge only to get at vlan_info. Maybe that could be abstracted to a single interface, or even change v->parent to be a 'net_port_vlans **'? Best Regards, Michał Mirosław