Horatiu Vultur
2020-May-20 13:09 UTC
[Bridge] [PATCH 0/3] net: bridge: mrp: Add small fixes to MRP
This patch series adds small fixes to MRP implementation. The following are fixed in this patch series: - now is not allow to add the same port to multiple MRP rings - remove unused variable - restore the port state according to the bridge state when the MRP instance is deleted Horatiu Vultur (3): bridge: mrp: Add br_mrp_unique_ifindex function switchdev: mrp: Remove the variable mrp_ring_state bridge: mrp: Restore port state when deleting MRP instance include/net/switchdev.h | 1 - net/bridge/br_mrp.c | 44 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 40 insertions(+), 5 deletions(-) -- 2.26.2
Horatiu Vultur
2020-May-20 13:09 UTC
[Bridge] [PATCH 1/3] bridge: mrp: Add br_mrp_unique_ifindex function
It is not allow to have the same net bridge port part of multiple MRP rings. Therefore add a check if the port is used already in a different MRP. In that case return failure. Fixes: 9a9f26e8f7ea ("bridge: mrp: Connect MRP API with the switchdev API") Signed-off-by: Horatiu Vultur <horatiu.vultur at microchip.com> --- net/bridge/br_mrp.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/net/bridge/br_mrp.c b/net/bridge/br_mrp.c index d7bc09de4c139..a5a3fa59c078a 100644 --- a/net/bridge/br_mrp.c +++ b/net/bridge/br_mrp.c @@ -37,6 +37,32 @@ static struct br_mrp *br_mrp_find_id(struct net_bridge *br, u32 ring_id) return res; } +static bool br_mrp_unique_ifindex(struct net_bridge *br, u32 ifindex) +{ + struct br_mrp *mrp; + bool res = true; + + rcu_read_lock(); + list_for_each_entry_rcu(mrp, &br->mrp_list, list, + lockdep_rtnl_is_held()) { + struct net_bridge_port *p; + + p = rcu_dereference(mrp->p_port); + if (p && p->dev->ifindex == ifindex) { + res = false; + break; + } + + p = rcu_dereference(mrp->s_port); + if (p && p->dev->ifindex == ifindex) { + res = false; + break; + } + } + rcu_read_unlock(); + return res; +} + static struct br_mrp *br_mrp_find_port(struct net_bridge *br, struct net_bridge_port *p) { @@ -255,6 +281,11 @@ int br_mrp_add(struct net_bridge *br, struct br_mrp_instance *instance) !br_mrp_get_port(br, instance->s_ifindex)) return -EINVAL; + /* It is not possible to have the same port part of multiple rings */ + if (!br_mrp_unique_ifindex(br, instance->p_ifindex) || + !br_mrp_unique_ifindex(br, instance->s_ifindex)) + return -EINVAL; + mrp = kzalloc(sizeof(*mrp), GFP_KERNEL); if (!mrp) return -ENOMEM; -- 2.26.2
Horatiu Vultur
2020-May-20 13:09 UTC
[Bridge] [PATCH 2/3] switchdev: mrp: Remove the variable mrp_ring_state
Remove the variable mrp_ring_state from switchdev_attr because is not used anywhere. The ring state is set using SWITCHDEV_OBJ_ID_RING_STATE_MRP. Fixes: c284b5459008 ("switchdev: mrp: Extend switchdev API to offload MRP") Signed-off-by: Horatiu Vultur <horatiu.vultur at microchip.com> --- include/net/switchdev.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/net/switchdev.h b/include/net/switchdev.h index ae7aeb0d1f9ca..db519957e134b 100644 --- a/include/net/switchdev.h +++ b/include/net/switchdev.h @@ -62,7 +62,6 @@ struct switchdev_attr { #if IS_ENABLED(CONFIG_BRIDGE_MRP) u8 mrp_port_state; /* MRP_PORT_STATE */ u8 mrp_port_role; /* MRP_PORT_ROLE */ - u8 mrp_ring_state; /* MRP_RING_STATE */ #endif } u; }; -- 2.26.2
Horatiu Vultur
2020-May-20 13:09 UTC
[Bridge] [PATCH 3/3] bridge: mrp: Restore port state when deleting MRP instance
When a MRP instance is deleted, then restore the port according to the bridge state. If the bridge is up then the ports will be in forwarding state otherwise will be in disabled state. Fixes: 9a9f26e8f7ea ("bridge: mrp: Connect MRP API with the switchdev API") Signed-off-by: Horatiu Vultur <horatiu.vultur at microchip.com> --- net/bridge/br_mrp.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/net/bridge/br_mrp.c b/net/bridge/br_mrp.c index a5a3fa59c078a..bdd8920c15053 100644 --- a/net/bridge/br_mrp.c +++ b/net/bridge/br_mrp.c @@ -229,6 +229,7 @@ static void br_mrp_test_work_expired(struct work_struct *work) static void br_mrp_del_impl(struct net_bridge *br, struct br_mrp *mrp) { struct net_bridge_port *p; + u8 state; /* Stop sending MRP_Test frames */ cancel_delayed_work_sync(&mrp->test_work); @@ -240,20 +241,24 @@ static void br_mrp_del_impl(struct net_bridge *br, struct br_mrp *mrp) p = rtnl_dereference(mrp->p_port); if (p) { spin_lock_bh(&br->lock); - p->state = BR_STATE_FORWARDING; + state = netif_running(br->dev) ? + BR_STATE_FORWARDING : BR_STATE_DISABLED; + p->state = state; p->flags &= ~BR_MRP_AWARE; spin_unlock_bh(&br->lock); - br_mrp_port_switchdev_set_state(p, BR_STATE_FORWARDING); + br_mrp_port_switchdev_set_state(p, state); rcu_assign_pointer(mrp->p_port, NULL); } p = rtnl_dereference(mrp->s_port); if (p) { spin_lock_bh(&br->lock); - p->state = BR_STATE_FORWARDING; + state = netif_running(br->dev) ? + BR_STATE_FORWARDING : BR_STATE_DISABLED; + p->state = state; p->flags &= ~BR_MRP_AWARE; spin_unlock_bh(&br->lock); - br_mrp_port_switchdev_set_state(p, BR_STATE_FORWARDING); + br_mrp_port_switchdev_set_state(p, state); rcu_assign_pointer(mrp->s_port, NULL); } -- 2.26.2