Commit 65369933 authored by Horatiu Vultur's avatar Horatiu Vultur Committed by David S. Miller

bridge: mrp: Integrate MRP into the bridge

To integrate MRP into the bridge, the bridge needs to do the following:
- detect if the MRP frame was received on MRP ring port in that case it would be
  processed otherwise just forward it as usual.
- enable parsing of MRP
- before whenever the bridge was set up, it would set all the ports in
  forwarding state. Add an extra check to not set ports in forwarding state if
  the port is an MRP ring port. The reason of this change is that if the MRP
  instance initially sets the port in blocked state by setting the bridge up it
  would overwrite this setting.
Reviewed-by: default avatarNikolay Aleksandrov <nikolay@cumulusnetworks.com>
Signed-off-by: default avatarHoratiu Vultur <horatiu.vultur@microchip.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 4d02b8f0
...@@ -463,6 +463,9 @@ void br_dev_setup(struct net_device *dev) ...@@ -463,6 +463,9 @@ void br_dev_setup(struct net_device *dev)
spin_lock_init(&br->lock); spin_lock_init(&br->lock);
INIT_LIST_HEAD(&br->port_list); INIT_LIST_HEAD(&br->port_list);
INIT_HLIST_HEAD(&br->fdb_list); INIT_HLIST_HEAD(&br->fdb_list);
#if IS_ENABLED(CONFIG_BRIDGE_MRP)
INIT_LIST_HEAD(&br->mrp_list);
#endif
spin_lock_init(&br->hash_lock); spin_lock_init(&br->hash_lock);
br->bridge_id.prio[0] = 0x80; br->bridge_id.prio[0] = 0x80;
......
...@@ -333,6 +333,8 @@ static void del_nbp(struct net_bridge_port *p) ...@@ -333,6 +333,8 @@ static void del_nbp(struct net_bridge_port *p)
br_stp_disable_port(p); br_stp_disable_port(p);
spin_unlock_bh(&br->lock); spin_unlock_bh(&br->lock);
br_mrp_port_del(br, p);
br_ifinfo_notify(RTM_DELLINK, NULL, p); br_ifinfo_notify(RTM_DELLINK, NULL, p);
list_del_rcu(&p->list); list_del_rcu(&p->list);
......
...@@ -342,6 +342,9 @@ rx_handler_result_t br_handle_frame(struct sk_buff **pskb) ...@@ -342,6 +342,9 @@ rx_handler_result_t br_handle_frame(struct sk_buff **pskb)
} }
} }
if (unlikely(br_mrp_process(p, skb)))
return RX_HANDLER_PASS;
forward: forward:
switch (p->state) { switch (p->state) {
case BR_STATE_FORWARDING: case BR_STATE_FORWARDING:
......
...@@ -672,6 +672,11 @@ static int br_afspec(struct net_bridge *br, ...@@ -672,6 +672,11 @@ static int br_afspec(struct net_bridge *br,
if (err) if (err)
return err; return err;
break; break;
case IFLA_BRIDGE_MRP:
err = br_mrp_parse(br, p, attr, cmd, extack);
if (err)
return err;
break;
} }
} }
......
...@@ -1308,6 +1308,37 @@ unsigned long br_timer_value(const struct timer_list *timer); ...@@ -1308,6 +1308,37 @@ unsigned long br_timer_value(const struct timer_list *timer);
extern int (*br_fdb_test_addr_hook)(struct net_device *dev, unsigned char *addr); extern int (*br_fdb_test_addr_hook)(struct net_device *dev, unsigned char *addr);
#endif #endif
/* br_mrp.c */
#if IS_ENABLED(CONFIG_BRIDGE_MRP)
int br_mrp_parse(struct net_bridge *br, struct net_bridge_port *p,
struct nlattr *attr, int cmd, struct netlink_ext_ack *extack);
int br_mrp_process(struct net_bridge_port *p, struct sk_buff *skb);
bool br_mrp_enabled(struct net_bridge *br);
void br_mrp_port_del(struct net_bridge *br, struct net_bridge_port *p);
#else
static inline int br_mrp_parse(struct net_bridge *br, struct net_bridge_port *p,
struct nlattr *attr, int cmd,
struct netlink_ext_ack *extack)
{
return -EOPNOTSUPP;
}
static inline int br_mrp_process(struct net_bridge_port *p, struct sk_buff *skb)
{
return 0;
}
static inline bool br_mrp_enabled(struct net_bridge *br)
{
return 0;
}
static inline void br_mrp_port_del(struct net_bridge *br,
struct net_bridge_port *p)
{
}
#endif
/* br_netlink.c */ /* br_netlink.c */
extern struct rtnl_link_ops br_link_ops; extern struct rtnl_link_ops br_link_ops;
int br_netlink_init(void); int br_netlink_init(void);
......
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