mirror of
				https://kernel.googlesource.com/pub/scm/linux/kernel/git/stable/linux-stable.git
				synced 2025-11-04 07:44:51 +10:00 
			
		
		
		
	bridge: switchdev: Notify about VLAN protocol changes
[ Upstream commit22ec19f3ae] Drivers that support bridge offload need to be notified about changes to the bridge's VLAN protocol so that they could react accordingly and potentially veto the change. Add a new switchdev attribute to communicate the change to drivers. Signed-off-by: Danielle Ratson <danieller@nvidia.com> Reviewed-by: Petr Machata <petrm@nvidia.com> Acked-by: Nikolay Aleksandrov <nikolay@nvidia.com> Signed-off-by: Ido Schimmel <idosch@nvidia.com> Reviewed-by: Ivan Vecera <ivecera@redhat.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org> Stable-dep-of:9d45921ee4("bridge: switchdev: Fix memory leaks when changing VLAN protocol") Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
		
							parent
							
								
									f5cbd86ebf
								
							
						
					
					
						commit
						89a7f155e6
					
				@ -38,6 +38,7 @@ enum switchdev_attr_id {
 | 
			
		||||
	SWITCHDEV_ATTR_ID_PORT_MROUTER,
 | 
			
		||||
	SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME,
 | 
			
		||||
	SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING,
 | 
			
		||||
	SWITCHDEV_ATTR_ID_BRIDGE_VLAN_PROTOCOL,
 | 
			
		||||
	SWITCHDEV_ATTR_ID_BRIDGE_MC_DISABLED,
 | 
			
		||||
	SWITCHDEV_ATTR_ID_BRIDGE_MROUTER,
 | 
			
		||||
#if IS_ENABLED(CONFIG_BRIDGE_MRP)
 | 
			
		||||
@ -57,6 +58,7 @@ struct switchdev_attr {
 | 
			
		||||
		bool mrouter;				/* PORT_MROUTER */
 | 
			
		||||
		clock_t ageing_time;			/* BRIDGE_AGEING_TIME */
 | 
			
		||||
		bool vlan_filtering;			/* BRIDGE_VLAN_FILTERING */
 | 
			
		||||
		u16 vlan_protocol;			/* BRIDGE_VLAN_PROTOCOL */
 | 
			
		||||
		bool mc_disabled;			/* MC_DISABLED */
 | 
			
		||||
#if IS_ENABLED(CONFIG_BRIDGE_MRP)
 | 
			
		||||
		u8 mrp_port_role;			/* MRP_PORT_ROLE */
 | 
			
		||||
 | 
			
		||||
@ -855,15 +855,25 @@ EXPORT_SYMBOL_GPL(br_vlan_get_proto);
 | 
			
		||||
 | 
			
		||||
int __br_vlan_set_proto(struct net_bridge *br, __be16 proto)
 | 
			
		||||
{
 | 
			
		||||
	struct switchdev_attr attr = {
 | 
			
		||||
		.orig_dev = br->dev,
 | 
			
		||||
		.id = SWITCHDEV_ATTR_ID_BRIDGE_VLAN_PROTOCOL,
 | 
			
		||||
		.flags = SWITCHDEV_F_SKIP_EOPNOTSUPP,
 | 
			
		||||
		.u.vlan_protocol = ntohs(proto),
 | 
			
		||||
	};
 | 
			
		||||
	int err = 0;
 | 
			
		||||
	struct net_bridge_port *p;
 | 
			
		||||
	struct net_bridge_vlan *vlan;
 | 
			
		||||
	struct net_bridge_vlan_group *vg;
 | 
			
		||||
	__be16 oldproto;
 | 
			
		||||
	__be16 oldproto = br->vlan_proto;
 | 
			
		||||
 | 
			
		||||
	if (br->vlan_proto == proto)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	err = switchdev_port_attr_set(br->dev, &attr);
 | 
			
		||||
	if (err && err != -EOPNOTSUPP)
 | 
			
		||||
		return err;
 | 
			
		||||
 | 
			
		||||
	/* Add VLANs for the new proto to the device filter. */
 | 
			
		||||
	list_for_each_entry(p, &br->port_list, list) {
 | 
			
		||||
		vg = nbp_vlan_group(p);
 | 
			
		||||
@ -874,7 +884,6 @@ int __br_vlan_set_proto(struct net_bridge *br, __be16 proto)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	oldproto = br->vlan_proto;
 | 
			
		||||
	br->vlan_proto = proto;
 | 
			
		||||
 | 
			
		||||
	recalculate_group_addr(br);
 | 
			
		||||
@ -890,6 +899,9 @@ int __br_vlan_set_proto(struct net_bridge *br, __be16 proto)
 | 
			
		||||
	return 0;
 | 
			
		||||
 | 
			
		||||
err_filt:
 | 
			
		||||
	attr.u.vlan_protocol = ntohs(oldproto);
 | 
			
		||||
	switchdev_port_attr_set(br->dev, &attr);
 | 
			
		||||
 | 
			
		||||
	list_for_each_entry_continue_reverse(vlan, &vg->vlan_list, vlist)
 | 
			
		||||
		vlan_vid_del(p->dev, proto, vlan->vid);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user