]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
bridge: mrp: Integrate MRP into the bridge
authorHoratiu Vultur <horatiu.vultur@microchip.com>
Sun, 26 Apr 2020 13:22:07 +0000 (15:22 +0200)
committerDavid S. Miller <davem@davemloft.net>
Mon, 27 Apr 2020 18:40:25 +0000 (11:40 -0700)
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: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/bridge/br_device.c
net/bridge/br_if.c
net/bridge/br_input.c
net/bridge/br_netlink.c
net/bridge/br_private.h

index 0e3dbc5f3c34f83203ffafcb944a89fed8043b25..8ec1362588af168ed366ee322089c29923b2fd04 100644 (file)
@@ -463,6 +463,9 @@ void br_dev_setup(struct net_device *dev)
        spin_lock_init(&br->lock);
        INIT_LIST_HEAD(&br->port_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);
 
        br->bridge_id.prio[0] = 0x80;
index 4fe30b182ee7e4fd7b8341353e266a5685e04627..ca685c0cdf9543665a4679d77a80f0081eee3f74 100644 (file)
@@ -333,6 +333,8 @@ static void del_nbp(struct net_bridge_port *p)
        br_stp_disable_port(p);
        spin_unlock_bh(&br->lock);
 
+       br_mrp_port_del(br, p);
+
        br_ifinfo_notify(RTM_DELLINK, NULL, p);
 
        list_del_rcu(&p->list);
index fcc2608400289570961728169b6df8e5953697fb..d5c34f36f0f4d7c1b312d9c27fbe010c0a63db39 100644 (file)
@@ -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:
        switch (p->state) {
        case BR_STATE_FORWARDING:
index 4084f1ef8641b379aab8331d21bdb0381578d70a..1a5e681a626a0fcb703d0f44be0b4055b725dd7b 100644 (file)
@@ -672,6 +672,11 @@ static int br_afspec(struct net_bridge *br,
                        if (err)
                                return err;
                        break;
+               case IFLA_BRIDGE_MRP:
+                       err = br_mrp_parse(br, p, attr, cmd, extack);
+                       if (err)
+                               return err;
+                       break;
                }
        }
 
index 835a70f8d3eac1fa4de9061199c3519c828c4dad..5835828320b66cad45e461153533892691064325 100644 (file)
@@ -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);
 #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 */
 extern struct rtnl_link_ops br_link_ops;
 int br_netlink_init(void);