From: Florian Fainelli <[email protected]> Commit 8db0a2ee2c63 ("net: bridge: reject DSA-enabled master netdevices as bridge members") added a special check in br_if.c in order to check for a DSA master network device with a tagging protocol configured. This was done because back then, such devices, once enslaved in a bridge would become inoperative and would not pass DSA tagged traffic anymore due to br_handle_frame returning RX_HANDLER_CONSUMED.
But right now we have valid use cases which do require bridging of DSA masters. One such example is when the DSA master ports are DSA switch ports themselves (in a disjoint tree setup). This should be completely equivalent, functionally speaking, from having multiple DSA switches hanging off of the ports of a switchdev driver. So we should allow the enslaving of DSA tagged master network devices. Make br_handle_frame() return RX_HANDLER_PASS in order to call into the DSA specific tagging protocol handlers, and lift the restriction from br_add_if. Signed-off-by: Florian Fainelli <[email protected]> Signed-off-by: Vladimir Oltean <[email protected]> --- net/bridge/br_if.c | 4 +--- net/bridge/br_input.c | 4 +++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index ca685c0cdf95..e0fbdb855664 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -18,7 +18,6 @@ #include <linux/rtnetlink.h> #include <linux/if_ether.h> #include <linux/slab.h> -#include <net/dsa.h> #include <net/sock.h> #include <linux/if_vlan.h> #include <net/switchdev.h> @@ -571,8 +570,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev, */ if ((dev->flags & IFF_LOOPBACK) || dev->type != ARPHRD_ETHER || dev->addr_len != ETH_ALEN || - !is_valid_ether_addr(dev->dev_addr) || - netdev_uses_dsa(dev)) + !is_valid_ether_addr(dev->dev_addr)) return -EINVAL; /* No bridging of bridges */ diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index d5c34f36f0f4..396bc0c18cb5 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c @@ -17,6 +17,7 @@ #endif #include <linux/neighbour.h> #include <net/arp.h> +#include <net/dsa.h> #include <linux/export.h> #include <linux/rculist.h> #include "br_private.h" @@ -263,7 +264,8 @@ rx_handler_result_t br_handle_frame(struct sk_buff **pskb) struct sk_buff *skb = *pskb; const unsigned char *dest = eth_hdr(skb)->h_dest; - if (unlikely(skb->pkt_type == PACKET_LOOPBACK)) + if (unlikely(skb->pkt_type == PACKET_LOOPBACK) || + netdev_uses_dsa(skb->dev)) return RX_HANDLER_PASS; if (!is_valid_ether_addr(eth_hdr(skb)->h_source)) -- 2.17.1
