summaryrefslogtreecommitdiffstats
path: root/net/dsa/tag_sja1105.c
diff options
context:
space:
mode:
authorVladimir Oltean <vladimir.oltean@nxp.com>2021-07-29 17:56:00 +0300
committerDavid S. Miller <davem@davemloft.net>2021-07-29 22:17:37 +0100
commitbea7907837c57a0aaac009931eb14efb056dafab (patch)
tree1c5a71e9888e77992f931ac97b93cadfa23c549a /net/dsa/tag_sja1105.c
parent57fb346cc7d0fc59af70b4650ee10048f61d7b4f (diff)
downloadlinux-bea7907837c57a0aaac009931eb14efb056dafab.tar.bz2
net: dsa: don't set skb->offload_fwd_mark when not offloading the bridge
DSA has gained the recent ability to deal gracefully with upper interfaces it cannot offload, such as the bridge, bonding or team drivers. When such uppers exist, the ports are still in standalone mode as far as the hardware is concerned. But when we deliver packets to the software bridge in order for that to do the forwarding, there is an unpleasant surprise in that the bridge will refuse to forward them. This is because we unconditionally set skb->offload_fwd_mark = true, meaning that the bridge thinks the frames were already forwarded in hardware by us. Since dp->bridge_dev is populated only when there is hardware offload for it, but not in the software fallback case, let's introduce a new helper that can be called from the tagger data path which sets the skb->offload_fwd_mark accordingly to zero when there is no hardware offload for bridging. This lets the bridge forward packets back to other interfaces of our switch, if needed. Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Reviewed-by: Tobias Waldekranz <tobias@waldekranz.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/dsa/tag_sja1105.c')
-rw-r--r--net/dsa/tag_sja1105.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/net/dsa/tag_sja1105.c b/net/dsa/tag_sja1105.c
index c1f993d592ef..664cb802b71a 100644
--- a/net/dsa/tag_sja1105.c
+++ b/net/dsa/tag_sja1105.c
@@ -405,8 +405,6 @@ static struct sk_buff *sja1105_rcv(struct sk_buff *skb,
is_link_local = sja1105_is_link_local(skb);
is_meta = sja1105_is_meta_frame(skb);
- skb->offload_fwd_mark = 1;
-
if (sja1105_skb_has_tag_8021q(skb)) {
/* Normal traffic path. */
sja1105_vlan_rcv(skb, &source_port, &switch_id, &vid);
@@ -437,6 +435,9 @@ static struct sk_buff *sja1105_rcv(struct sk_buff *skb,
return NULL;
}
+ if (!is_link_local)
+ dsa_default_offload_fwd_mark(skb);
+
return sja1105_rcv_meta_state_machine(skb, &meta, is_link_local,
is_meta);
}
@@ -480,7 +481,8 @@ static struct sk_buff *sja1110_rcv_meta(struct sk_buff *skb, u16 rx_header)
static struct sk_buff *sja1110_rcv_inband_control_extension(struct sk_buff *skb,
int *source_port,
- int *switch_id)
+ int *switch_id,
+ bool *host_only)
{
u16 rx_header;
@@ -494,6 +496,9 @@ static struct sk_buff *sja1110_rcv_inband_control_extension(struct sk_buff *skb,
*/
rx_header = ntohs(*(__be16 *)skb->data);
+ if (rx_header & SJA1110_RX_HEADER_HOST_ONLY)
+ *host_only = true;
+
if (rx_header & SJA1110_RX_HEADER_IS_METADATA)
return sja1110_rcv_meta(skb, rx_header);
@@ -545,13 +550,13 @@ static struct sk_buff *sja1110_rcv(struct sk_buff *skb,
struct packet_type *pt)
{
int source_port = -1, switch_id = -1;
+ bool host_only = false;
u16 vid;
- skb->offload_fwd_mark = 1;
-
if (sja1110_skb_has_inband_control_extension(skb)) {
skb = sja1110_rcv_inband_control_extension(skb, &source_port,
- &switch_id);
+ &switch_id,
+ &host_only);
if (!skb)
return NULL;
}
@@ -569,6 +574,9 @@ static struct sk_buff *sja1110_rcv(struct sk_buff *skb,
return NULL;
}
+ if (!host_only)
+ dsa_default_offload_fwd_mark(skb);
+
return skb;
}