Message ID | 20201002024215.660240-2-f.fainelli@gmail.com |
---|---|
State | New |
Headers | show |
Series | net: dsa: Improve dsa_untag_bridge_pvid() | expand |
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 >
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++;
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(+)