linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next 0/4] net: dsa: Improve dsa_untag_bridge_pvid()
@ 2020-10-02  2:42 Florian Fainelli
  2020-10-02  2:42 ` [PATCH net-next 1/4] net: dsa: Call dsa_untag_bridge_pvid() from dsa_switch_rcv() Florian Fainelli
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: Florian Fainelli @ 2020-10-02  2:42 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, Andrew Lunn, Vivien Didelot, David S. Miller,
	Jakub Kicinski, open list, vladimir.oltean, olteanv

Hi David, Jakub,

This patch series is based on the recent discussions with Vladimir:

https://lore.kernel.org/netdev/20201001030623.343535-1-f.fainelli@gmail.com/

the simplest way forward was to call dsa_untag_bridge_pvid() after
eth_type_trans() has been set which guarantees that skb->protocol is set
to a correct value and this allows us to utilize
__vlan_find_dev_deep_rcu() properly without playing or using the bridge
master as a net_device reference.

Florian Fainelli (4):
  net: dsa: Call dsa_untag_bridge_pvid() from dsa_switch_rcv()
  net: dsa: b53: Set untag_bridge_pvid
  net: dsa: Obtain VLAN protocol from skb->protocol
  net: dsa: Utilize __vlan_find_dev_deep_rcu()

 drivers/net/dsa/b53/b53_common.c |  1 +
 include/net/dsa.h                |  8 ++++++++
 net/dsa/dsa.c                    |  9 +++++++++
 net/dsa/dsa_priv.h               | 14 ++++----------
 net/dsa/tag_brcm.c               | 15 ++-------------
 5 files changed, 24 insertions(+), 23 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH net-next 1/4] net: dsa: Call dsa_untag_bridge_pvid() from dsa_switch_rcv()
  2020-10-02  2:42 [PATCH net-next 0/4] net: dsa: Improve dsa_untag_bridge_pvid() Florian Fainelli
@ 2020-10-02  2:42 ` Florian Fainelli
  2020-10-02  8:39   ` Vladimir Oltean
  2020-10-02  2:42 ` [PATCH net-next 2/4] net: dsa: b53: Set untag_bridge_pvid Florian Fainelli
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: Florian Fainelli @ 2020-10-02  2:42 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, Andrew Lunn, Vivien Didelot, David S. Miller,
	Jakub Kicinski, open list, vladimir.oltean, olteanv

When a DSA switch driver needs to call dsa_untag_bridge_pvid(), it can
set dsa_switch::untag_brige_pvid to indicate this is necessary.

This is a pre-requisite to making sure that we are always calling
dsa_untag_bridge_pvid() after eth_type_trans() has been called.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 include/net/dsa.h | 8 ++++++++
 net/dsa/dsa.c     | 9 +++++++++
 2 files changed, 17 insertions(+)

diff --git a/include/net/dsa.h b/include/net/dsa.h
index b502a63d196e..8b0696e08cac 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -308,6 +308,14 @@ struct dsa_switch {
 	 */
 	bool			configure_vlan_while_not_filtering;
 
+	/* If the switch driver always programs the CPU port as egress tagged
+	 * despite the VLAN configuration indicating otherwise, then setting
+	 * @untag_bridge_pvid will force the DSA receive path to pop the bridge's
+	 * default_pvid VLAN tagged frames to offer a consistent behavior
+	 * between a vlan_filtering=0 and vlan_filtering=1 bridge device.
+	 */
+	bool			untag_bridge_pvid;
+
 	/* In case vlan_filtering_is_global is set, the VLAN awareness state
 	 * should be retrieved from here and not from the per-port settings.
 	 */
diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
index 5c18c0214aac..dec4ab59b7c4 100644
--- a/net/dsa/dsa.c
+++ b/net/dsa/dsa.c
@@ -225,6 +225,15 @@ static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev,
 	skb->pkt_type = PACKET_HOST;
 	skb->protocol = eth_type_trans(skb, skb->dev);
 
+	if (unlikely(cpu_dp->ds->untag_bridge_pvid)) {
+		nskb = dsa_untag_bridge_pvid(skb);
+		if (!nskb) {
+			kfree_skb(skb);
+			return 0;
+		}
+		skb = nskb;
+	}
+
 	s = this_cpu_ptr(p->stats64);
 	u64_stats_update_begin(&s->syncp);
 	s->rx_packets++;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH net-next 2/4] net: dsa: b53: Set untag_bridge_pvid
  2020-10-02  2:42 [PATCH net-next 0/4] net: dsa: Improve dsa_untag_bridge_pvid() Florian Fainelli
  2020-10-02  2:42 ` [PATCH net-next 1/4] net: dsa: Call dsa_untag_bridge_pvid() from dsa_switch_rcv() Florian Fainelli
@ 2020-10-02  2:42 ` Florian Fainelli
  2020-10-02  8:40   ` Vladimir Oltean
  2020-10-02  2:42 ` [PATCH net-next 3/4] net: dsa: Obtain VLAN protocol from skb->protocol Florian Fainelli
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: Florian Fainelli @ 2020-10-02  2:42 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, Andrew Lunn, Vivien Didelot, David S. Miller,
	Jakub Kicinski, open list, vladimir.oltean, olteanv

Indicate to the DSA receive path that we need to untage the bridge PVID,
this allows us to remove the dsa_untag_bridge_pvid() calls from
net/dsa/tag_brcm.c.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/net/dsa/b53/b53_common.c |  1 +
 net/dsa/tag_brcm.c               | 15 ++-------------
 2 files changed, 3 insertions(+), 13 deletions(-)

diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
index 73507cff3bc4..ce18ba0b74eb 100644
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -2603,6 +2603,7 @@ struct b53_device *b53_switch_alloc(struct device *base,
 	dev->ops = ops;
 	ds->ops = &b53_switch_ops;
 	ds->configure_vlan_while_not_filtering = true;
+	ds->untag_bridge_pvid = true;
 	dev->vlan_enabled = ds->configure_vlan_while_not_filtering;
 	mutex_init(&dev->reg_mutex);
 	mutex_init(&dev->stats_mutex);
diff --git a/net/dsa/tag_brcm.c b/net/dsa/tag_brcm.c
index 69d6b8c597a9..ad72dff8d524 100644
--- a/net/dsa/tag_brcm.c
+++ b/net/dsa/tag_brcm.c
@@ -152,11 +152,6 @@ static struct sk_buff *brcm_tag_rcv_ll(struct sk_buff *skb,
 	/* Remove Broadcom tag and update checksum */
 	skb_pull_rcsum(skb, BRCM_TAG_LEN);
 
-	/* Set the MAC header to where it should point for
-	 * dsa_untag_bridge_pvid() to parse the correct VLAN header.
-	 */
-	skb_set_mac_header(skb, -ETH_HLEN);
-
 	skb->offload_fwd_mark = 1;
 
 	return skb;
@@ -187,7 +182,7 @@ static struct sk_buff *brcm_tag_rcv(struct sk_buff *skb, struct net_device *dev,
 		nskb->data - ETH_HLEN - BRCM_TAG_LEN,
 		2 * ETH_ALEN);
 
-	return dsa_untag_bridge_pvid(nskb);
+	return nskb;
 }
 
 static const struct dsa_device_ops brcm_netdev_ops = {
@@ -214,14 +209,8 @@ static struct sk_buff *brcm_tag_rcv_prepend(struct sk_buff *skb,
 					    struct net_device *dev,
 					    struct packet_type *pt)
 {
-	struct sk_buff *nskb;
-
 	/* tag is prepended to the packet */
-	nskb = brcm_tag_rcv_ll(skb, dev, pt, ETH_HLEN);
-	if (!nskb)
-		return nskb;
-
-	return dsa_untag_bridge_pvid(nskb);
+	return brcm_tag_rcv_ll(skb, dev, pt, ETH_HLEN);
 }
 
 static const struct dsa_device_ops brcm_prepend_netdev_ops = {
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH net-next 3/4] net: dsa: Obtain VLAN protocol from skb->protocol
  2020-10-02  2:42 [PATCH net-next 0/4] net: dsa: Improve dsa_untag_bridge_pvid() Florian Fainelli
  2020-10-02  2:42 ` [PATCH net-next 1/4] net: dsa: Call dsa_untag_bridge_pvid() from dsa_switch_rcv() Florian Fainelli
  2020-10-02  2:42 ` [PATCH net-next 2/4] net: dsa: b53: Set untag_bridge_pvid Florian Fainelli
@ 2020-10-02  2:42 ` Florian Fainelli
  2020-10-02  8:41   ` Vladimir Oltean
  2020-10-02  2:42 ` [PATCH net-next 4/4] net: dsa: Utilize __vlan_find_dev_deep_rcu() Florian Fainelli
  2020-10-02 20:36 ` [PATCH net-next 0/4] net: dsa: Improve dsa_untag_bridge_pvid() David Miller
  4 siblings, 1 reply; 10+ messages in thread
From: Florian Fainelli @ 2020-10-02  2:42 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, Andrew Lunn, Vivien Didelot, David S. Miller,
	Jakub Kicinski, open list, vladimir.oltean, olteanv

Now that dsa_untag_bridge_pvid() is called after eth_type_trans() we are
guaranteed that skb->protocol will be set to a correct value, thus
allowing us to avoid calling vlan_eth_hdr().

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 net/dsa/dsa_priv.h | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
index 0348dbab4131..d6ce8c2a2590 100644
--- a/net/dsa/dsa_priv.h
+++ b/net/dsa/dsa_priv.h
@@ -201,7 +201,6 @@ dsa_slave_to_master(const struct net_device *dev)
 static inline struct sk_buff *dsa_untag_bridge_pvid(struct sk_buff *skb)
 {
 	struct dsa_port *dp = dsa_slave_to_port(skb->dev);
-	struct vlan_ethhdr *hdr = vlan_eth_hdr(skb);
 	struct net_device *br = dp->bridge_dev;
 	struct net_device *dev = skb->dev;
 	struct net_device *upper_dev;
@@ -217,7 +216,7 @@ static inline struct sk_buff *dsa_untag_bridge_pvid(struct sk_buff *skb)
 		return skb;
 
 	/* Move VLAN tag from data to hwaccel */
-	if (!skb_vlan_tag_present(skb) && hdr->h_vlan_proto == htons(proto)) {
+	if (!skb_vlan_tag_present(skb) && skb->protocol == htons(proto)) {
 		skb = skb_vlan_untag(skb);
 		if (!skb)
 			return NULL;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH net-next 4/4] net: dsa: Utilize __vlan_find_dev_deep_rcu()
  2020-10-02  2:42 [PATCH net-next 0/4] net: dsa: Improve dsa_untag_bridge_pvid() Florian Fainelli
                   ` (2 preceding siblings ...)
  2020-10-02  2:42 ` [PATCH net-next 3/4] net: dsa: Obtain VLAN protocol from skb->protocol Florian Fainelli
@ 2020-10-02  2:42 ` Florian Fainelli
  2020-10-02  8:42   ` Vladimir Oltean
  2020-10-02 20:36 ` [PATCH net-next 0/4] net: dsa: Improve dsa_untag_bridge_pvid() David Miller
  4 siblings, 1 reply; 10+ messages in thread
From: Florian Fainelli @ 2020-10-02  2:42 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, Andrew Lunn, Vivien Didelot, David S. Miller,
	Jakub Kicinski, open list, vladimir.oltean, olteanv

Now that we are guaranteed that dsa_untag_bridge_pvid() is called after
eth_type_trans() we can utilize __vlan_find_dev_deep_rcu() which will
take care of finding an 802.1Q upper on top of a bridge master.

A common use case, prior to 12a1526d067 ("net: dsa: untag the bridge
pvid from rx skbs") was to configure a bridge 802.1Q upper like this:

ip link add name br0 type bridge vlan_filtering 0
ip link add link br0 name br0.1 type vlan id 1

in order to pop the default_pvid VLAN tag.

With this change we restore that behavior while still allowing the DSA
receive path to automatically pop the VLAN tag.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 net/dsa/dsa_priv.h | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
index d6ce8c2a2590..12998bf04e55 100644
--- a/net/dsa/dsa_priv.h
+++ b/net/dsa/dsa_priv.h
@@ -204,7 +204,6 @@ static inline struct sk_buff *dsa_untag_bridge_pvid(struct sk_buff *skb)
 	struct net_device *br = dp->bridge_dev;
 	struct net_device *dev = skb->dev;
 	struct net_device *upper_dev;
-	struct list_head *iter;
 	u16 vid, pvid, proto;
 	int err;
 
@@ -246,13 +245,9 @@ static inline struct sk_buff *dsa_untag_bridge_pvid(struct sk_buff *skb)
 	 * supports because vlan_filtering is 0. In that case, we should
 	 * definitely keep the tag, to make sure it keeps working.
 	 */
-	netdev_for_each_upper_dev_rcu(dev, upper_dev, iter) {
-		if (!is_vlan_dev(upper_dev))
-			continue;
-
-		if (vid == vlan_dev_vlan_id(upper_dev))
-			return skb;
-	}
+	upper_dev = __vlan_find_dev_deep_rcu(br, htons(proto), vid);
+	if (upper_dev)
+		return skb;
 
 	__vlan_hwaccel_clear_tag(skb);
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH net-next 1/4] net: dsa: Call dsa_untag_bridge_pvid() from dsa_switch_rcv()
  2020-10-02  2:42 ` [PATCH net-next 1/4] net: dsa: Call dsa_untag_bridge_pvid() from dsa_switch_rcv() Florian Fainelli
@ 2020-10-02  8:39   ` Vladimir Oltean
  0 siblings, 0 replies; 10+ messages in thread
From: Vladimir Oltean @ 2020-10-02  8:39 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: netdev, Andrew Lunn, Vivien Didelot, David S. Miller,
	Jakub Kicinski, open list, olteanv

On Thu, Oct 01, 2020 at 07:42:12PM -0700, Florian Fainelli wrote:
> When a DSA switch driver needs to call dsa_untag_bridge_pvid(), it can
> set dsa_switch::untag_brige_pvid to indicate this is necessary.
> 
> This is a pre-requisite to making sure that we are always calling
> dsa_untag_bridge_pvid() after eth_type_trans() has been called.
> 
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
> ---

Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>

>  include/net/dsa.h | 8 ++++++++
>  net/dsa/dsa.c     | 9 +++++++++
>  2 files changed, 17 insertions(+)
> 
> diff --git a/include/net/dsa.h b/include/net/dsa.h
> index b502a63d196e..8b0696e08cac 100644
> --- a/include/net/dsa.h
> +++ b/include/net/dsa.h
> @@ -308,6 +308,14 @@ struct dsa_switch {
>  	 */
>  	bool			configure_vlan_while_not_filtering;
>  
> +	/* If the switch driver always programs the CPU port as egress tagged
> +	 * despite the VLAN configuration indicating otherwise, then setting
> +	 * @untag_bridge_pvid will force the DSA receive path to pop the bridge's
> +	 * default_pvid VLAN tagged frames to offer a consistent behavior
> +	 * between a vlan_filtering=0 and vlan_filtering=1 bridge device.
> +	 */
> +	bool			untag_bridge_pvid;
> +
>  	/* In case vlan_filtering_is_global is set, the VLAN awareness state
>  	 * should be retrieved from here and not from the per-port settings.
>  	 */
> diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
> index 5c18c0214aac..dec4ab59b7c4 100644
> --- a/net/dsa/dsa.c
> +++ b/net/dsa/dsa.c
> @@ -225,6 +225,15 @@ static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev,
>  	skb->pkt_type = PACKET_HOST;
>  	skb->protocol = eth_type_trans(skb, skb->dev);
>  
> +	if (unlikely(cpu_dp->ds->untag_bridge_pvid)) {
> +		nskb = dsa_untag_bridge_pvid(skb);
> +		if (!nskb) {
> +			kfree_skb(skb);
> +			return 0;
> +		}
> +		skb = nskb;
> +	}
> +
>  	s = this_cpu_ptr(p->stats64);
>  	u64_stats_update_begin(&s->syncp);
>  	s->rx_packets++;
> -- 
> 2.25.1
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH net-next 2/4] net: dsa: b53: Set untag_bridge_pvid
  2020-10-02  2:42 ` [PATCH net-next 2/4] net: dsa: b53: Set untag_bridge_pvid Florian Fainelli
@ 2020-10-02  8:40   ` Vladimir Oltean
  0 siblings, 0 replies; 10+ messages in thread
From: Vladimir Oltean @ 2020-10-02  8:40 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: netdev, Andrew Lunn, Vivien Didelot, David S. Miller,
	Jakub Kicinski, open list, olteanv

On Thu, Oct 01, 2020 at 07:42:13PM -0700, Florian Fainelli wrote:
> Indicate to the DSA receive path that we need to untage the bridge PVID,
> this allows us to remove the dsa_untag_bridge_pvid() calls from
> net/dsa/tag_brcm.c.
> 
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
> ---

Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>

>  drivers/net/dsa/b53/b53_common.c |  1 +
>  net/dsa/tag_brcm.c               | 15 ++-------------
>  2 files changed, 3 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
> index 73507cff3bc4..ce18ba0b74eb 100644
> --- a/drivers/net/dsa/b53/b53_common.c
> +++ b/drivers/net/dsa/b53/b53_common.c
> @@ -2603,6 +2603,7 @@ struct b53_device *b53_switch_alloc(struct device *base,
>  	dev->ops = ops;
>  	ds->ops = &b53_switch_ops;
>  	ds->configure_vlan_while_not_filtering = true;
> +	ds->untag_bridge_pvid = true;
>  	dev->vlan_enabled = ds->configure_vlan_while_not_filtering;
>  	mutex_init(&dev->reg_mutex);
>  	mutex_init(&dev->stats_mutex);
> diff --git a/net/dsa/tag_brcm.c b/net/dsa/tag_brcm.c
> index 69d6b8c597a9..ad72dff8d524 100644
> --- a/net/dsa/tag_brcm.c
> +++ b/net/dsa/tag_brcm.c
> @@ -152,11 +152,6 @@ static struct sk_buff *brcm_tag_rcv_ll(struct sk_buff *skb,
>  	/* Remove Broadcom tag and update checksum */
>  	skb_pull_rcsum(skb, BRCM_TAG_LEN);
>  
> -	/* Set the MAC header to where it should point for
> -	 * dsa_untag_bridge_pvid() to parse the correct VLAN header.
> -	 */
> -	skb_set_mac_header(skb, -ETH_HLEN);
> -
>  	skb->offload_fwd_mark = 1;
>  
>  	return skb;
> @@ -187,7 +182,7 @@ static struct sk_buff *brcm_tag_rcv(struct sk_buff *skb, struct net_device *dev,
>  		nskb->data - ETH_HLEN - BRCM_TAG_LEN,
>  		2 * ETH_ALEN);
>  
> -	return dsa_untag_bridge_pvid(nskb);
> +	return nskb;
>  }
>  
>  static const struct dsa_device_ops brcm_netdev_ops = {
> @@ -214,14 +209,8 @@ static struct sk_buff *brcm_tag_rcv_prepend(struct sk_buff *skb,
>  					    struct net_device *dev,
>  					    struct packet_type *pt)
>  {
> -	struct sk_buff *nskb;
> -
>  	/* tag is prepended to the packet */
> -	nskb = brcm_tag_rcv_ll(skb, dev, pt, ETH_HLEN);
> -	if (!nskb)
> -		return nskb;
> -
> -	return dsa_untag_bridge_pvid(nskb);
> +	return brcm_tag_rcv_ll(skb, dev, pt, ETH_HLEN);
>  }
>  
>  static const struct dsa_device_ops brcm_prepend_netdev_ops = {
> -- 
> 2.25.1
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH net-next 3/4] net: dsa: Obtain VLAN protocol from skb->protocol
  2020-10-02  2:42 ` [PATCH net-next 3/4] net: dsa: Obtain VLAN protocol from skb->protocol Florian Fainelli
@ 2020-10-02  8:41   ` Vladimir Oltean
  0 siblings, 0 replies; 10+ messages in thread
From: Vladimir Oltean @ 2020-10-02  8:41 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: netdev, Andrew Lunn, Vivien Didelot, David S. Miller,
	Jakub Kicinski, open list, olteanv

On Thu, Oct 01, 2020 at 07:42:14PM -0700, Florian Fainelli wrote:
> Now that dsa_untag_bridge_pvid() is called after eth_type_trans() we are
> guaranteed that skb->protocol will be set to a correct value, thus
> allowing us to avoid calling vlan_eth_hdr().
> 
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
> ---

Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>

>  net/dsa/dsa_priv.h | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
> index 0348dbab4131..d6ce8c2a2590 100644
> --- a/net/dsa/dsa_priv.h
> +++ b/net/dsa/dsa_priv.h
> @@ -201,7 +201,6 @@ dsa_slave_to_master(const struct net_device *dev)
>  static inline struct sk_buff *dsa_untag_bridge_pvid(struct sk_buff *skb)
>  {
>  	struct dsa_port *dp = dsa_slave_to_port(skb->dev);
> -	struct vlan_ethhdr *hdr = vlan_eth_hdr(skb);
>  	struct net_device *br = dp->bridge_dev;
>  	struct net_device *dev = skb->dev;
>  	struct net_device *upper_dev;
> @@ -217,7 +216,7 @@ static inline struct sk_buff *dsa_untag_bridge_pvid(struct sk_buff *skb)
>  		return skb;
>  
>  	/* Move VLAN tag from data to hwaccel */
> -	if (!skb_vlan_tag_present(skb) && hdr->h_vlan_proto == htons(proto)) {
> +	if (!skb_vlan_tag_present(skb) && skb->protocol == htons(proto)) {
>  		skb = skb_vlan_untag(skb);
>  		if (!skb)
>  			return NULL;
> -- 
> 2.25.1
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH net-next 4/4] net: dsa: Utilize __vlan_find_dev_deep_rcu()
  2020-10-02  2:42 ` [PATCH net-next 4/4] net: dsa: Utilize __vlan_find_dev_deep_rcu() Florian Fainelli
@ 2020-10-02  8:42   ` Vladimir Oltean
  0 siblings, 0 replies; 10+ messages in thread
From: Vladimir Oltean @ 2020-10-02  8:42 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: netdev, Andrew Lunn, Vivien Didelot, David S. Miller,
	Jakub Kicinski, open list, olteanv

On Thu, Oct 01, 2020 at 07:42:15PM -0700, Florian Fainelli wrote:
> Now that we are guaranteed that dsa_untag_bridge_pvid() is called after
> eth_type_trans() we can utilize __vlan_find_dev_deep_rcu() which will
> take care of finding an 802.1Q upper on top of a bridge master.
> 
> A common use case, prior to 12a1526d067 ("net: dsa: untag the bridge
> pvid from rx skbs") was to configure a bridge 802.1Q upper like this:
> 
> ip link add name br0 type bridge vlan_filtering 0
> ip link add link br0 name br0.1 type vlan id 1
> 
> in order to pop the default_pvid VLAN tag.
> 
> With this change we restore that behavior while still allowing the DSA
> receive path to automatically pop the VLAN tag.
> 
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
> ---

Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>

>  net/dsa/dsa_priv.h | 11 +++--------
>  1 file changed, 3 insertions(+), 8 deletions(-)
> 
> diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
> index d6ce8c2a2590..12998bf04e55 100644
> --- a/net/dsa/dsa_priv.h
> +++ b/net/dsa/dsa_priv.h
> @@ -204,7 +204,6 @@ static inline struct sk_buff *dsa_untag_bridge_pvid(struct sk_buff *skb)
>  	struct net_device *br = dp->bridge_dev;
>  	struct net_device *dev = skb->dev;
>  	struct net_device *upper_dev;
> -	struct list_head *iter;
>  	u16 vid, pvid, proto;
>  	int err;
>  
> @@ -246,13 +245,9 @@ static inline struct sk_buff *dsa_untag_bridge_pvid(struct sk_buff *skb)
>  	 * supports because vlan_filtering is 0. In that case, we should
>  	 * definitely keep the tag, to make sure it keeps working.
>  	 */
> -	netdev_for_each_upper_dev_rcu(dev, upper_dev, iter) {
> -		if (!is_vlan_dev(upper_dev))
> -			continue;
> -
> -		if (vid == vlan_dev_vlan_id(upper_dev))
> -			return skb;
> -	}
> +	upper_dev = __vlan_find_dev_deep_rcu(br, htons(proto), vid);
> +	if (upper_dev)
> +		return skb;
>  
>  	__vlan_hwaccel_clear_tag(skb);
>  
> -- 
> 2.25.1
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH net-next 0/4] net: dsa: Improve dsa_untag_bridge_pvid()
  2020-10-02  2:42 [PATCH net-next 0/4] net: dsa: Improve dsa_untag_bridge_pvid() Florian Fainelli
                   ` (3 preceding siblings ...)
  2020-10-02  2:42 ` [PATCH net-next 4/4] net: dsa: Utilize __vlan_find_dev_deep_rcu() Florian Fainelli
@ 2020-10-02 20:36 ` David Miller
  4 siblings, 0 replies; 10+ messages in thread
From: David Miller @ 2020-10-02 20:36 UTC (permalink / raw)
  To: f.fainelli
  Cc: netdev, andrew, vivien.didelot, kuba, linux-kernel,
	vladimir.oltean, olteanv

From: Florian Fainelli <f.fainelli@gmail.com>
Date: Thu,  1 Oct 2020 19:42:11 -0700

> Hi David, Jakub,
> 
> This patch series is based on the recent discussions with Vladimir:
> 
> https://lore.kernel.org/netdev/20201001030623.343535-1-f.fainelli@gmail.com/
> 
> the simplest way forward was to call dsa_untag_bridge_pvid() after
> eth_type_trans() has been set which guarantees that skb->protocol is set
> to a correct value and this allows us to utilize
> __vlan_find_dev_deep_rcu() properly without playing or using the bridge
> master as a net_device reference.

Series applied, thanks.

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2020-10-02 20:36 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-02  2:42 [PATCH net-next 0/4] net: dsa: Improve dsa_untag_bridge_pvid() Florian Fainelli
2020-10-02  2:42 ` [PATCH net-next 1/4] net: dsa: Call dsa_untag_bridge_pvid() from dsa_switch_rcv() Florian Fainelli
2020-10-02  8:39   ` Vladimir Oltean
2020-10-02  2:42 ` [PATCH net-next 2/4] net: dsa: b53: Set untag_bridge_pvid Florian Fainelli
2020-10-02  8:40   ` Vladimir Oltean
2020-10-02  2:42 ` [PATCH net-next 3/4] net: dsa: Obtain VLAN protocol from skb->protocol Florian Fainelli
2020-10-02  8:41   ` Vladimir Oltean
2020-10-02  2:42 ` [PATCH net-next 4/4] net: dsa: Utilize __vlan_find_dev_deep_rcu() Florian Fainelli
2020-10-02  8:42   ` Vladimir Oltean
2020-10-02 20:36 ` [PATCH net-next 0/4] net: dsa: Improve dsa_untag_bridge_pvid() David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).