Commit 22ec19f3 authored by Danielle Ratson's avatar Danielle Ratson Committed by Jakub Kicinski

bridge: switchdev: Notify about VLAN protocol changes

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: default avatarDanielle Ratson <danieller@nvidia.com>
Reviewed-by: default avatarPetr Machata <petrm@nvidia.com>
Acked-by: default avatarNikolay Aleksandrov <nikolay@nvidia.com>
Signed-off-by: default avatarIdo Schimmel <idosch@nvidia.com>
Reviewed-by: default avatarIvan Vecera <ivecera@redhat.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 80dfeafd
...@@ -38,6 +38,7 @@ enum switchdev_attr_id { ...@@ -38,6 +38,7 @@ enum switchdev_attr_id {
SWITCHDEV_ATTR_ID_PORT_MROUTER, SWITCHDEV_ATTR_ID_PORT_MROUTER,
SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME, SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME,
SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING, SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING,
SWITCHDEV_ATTR_ID_BRIDGE_VLAN_PROTOCOL,
SWITCHDEV_ATTR_ID_BRIDGE_MC_DISABLED, SWITCHDEV_ATTR_ID_BRIDGE_MC_DISABLED,
SWITCHDEV_ATTR_ID_BRIDGE_MROUTER, SWITCHDEV_ATTR_ID_BRIDGE_MROUTER,
#if IS_ENABLED(CONFIG_BRIDGE_MRP) #if IS_ENABLED(CONFIG_BRIDGE_MRP)
...@@ -58,6 +59,7 @@ struct switchdev_attr { ...@@ -58,6 +59,7 @@ struct switchdev_attr {
bool mrouter; /* PORT_MROUTER */ bool mrouter; /* PORT_MROUTER */
clock_t ageing_time; /* BRIDGE_AGEING_TIME */ clock_t ageing_time; /* BRIDGE_AGEING_TIME */
bool vlan_filtering; /* BRIDGE_VLAN_FILTERING */ bool vlan_filtering; /* BRIDGE_VLAN_FILTERING */
u16 vlan_protocol; /* BRIDGE_VLAN_PROTOCOL */
bool mc_disabled; /* MC_DISABLED */ bool mc_disabled; /* MC_DISABLED */
#if IS_ENABLED(CONFIG_BRIDGE_MRP) #if IS_ENABLED(CONFIG_BRIDGE_MRP)
u8 mrp_port_state; /* MRP_PORT_STATE */ u8 mrp_port_state; /* MRP_PORT_STATE */
......
...@@ -854,15 +854,25 @@ EXPORT_SYMBOL_GPL(br_vlan_get_proto); ...@@ -854,15 +854,25 @@ EXPORT_SYMBOL_GPL(br_vlan_get_proto);
int __br_vlan_set_proto(struct net_bridge *br, __be16 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; int err = 0;
struct net_bridge_port *p; struct net_bridge_port *p;
struct net_bridge_vlan *vlan; struct net_bridge_vlan *vlan;
struct net_bridge_vlan_group *vg; struct net_bridge_vlan_group *vg;
__be16 oldproto; __be16 oldproto = br->vlan_proto;
if (br->vlan_proto == proto) if (br->vlan_proto == proto)
return 0; 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. */ /* Add VLANs for the new proto to the device filter. */
list_for_each_entry(p, &br->port_list, list) { list_for_each_entry(p, &br->port_list, list) {
vg = nbp_vlan_group(p); vg = nbp_vlan_group(p);
...@@ -873,7 +883,6 @@ int __br_vlan_set_proto(struct net_bridge *br, __be16 proto) ...@@ -873,7 +883,6 @@ int __br_vlan_set_proto(struct net_bridge *br, __be16 proto)
} }
} }
oldproto = br->vlan_proto;
br->vlan_proto = proto; br->vlan_proto = proto;
recalculate_group_addr(br); recalculate_group_addr(br);
...@@ -889,6 +898,9 @@ int __br_vlan_set_proto(struct net_bridge *br, __be16 proto) ...@@ -889,6 +898,9 @@ int __br_vlan_set_proto(struct net_bridge *br, __be16 proto)
return 0; return 0;
err_filt: 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) list_for_each_entry_continue_reverse(vlan, &vg->vlan_list, vlist)
vlan_vid_del(p->dev, proto, vlan->vid); vlan_vid_del(p->dev, proto, vlan->vid);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment