[PATCH RFC net-next 05/19] net: dsa: tag_ar9331: add GRO callbacks
STALE2452d
From: Alexander Lobakin <hidden>
Date: 2019-12-30 14:32:49
Also in:
linux-mediatek, lkml, netdev
Subsystem:
networking [dsa], networking [general], the rest · Maintainers:
Andrew Lunn, Vladimir Oltean, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
Add GRO callbacks to the AR9331 tagger so GRO layer can now process such frames. Signed-off-by: Alexander Lobakin <redacted> --- net/dsa/tag_ar9331.c | 77 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+)
diff --git a/net/dsa/tag_ar9331.c b/net/dsa/tag_ar9331.c
index c22c1b515e02..99cc7fd92d8e 100644
--- a/net/dsa/tag_ar9331.c
+++ b/net/dsa/tag_ar9331.c@@ -100,12 +100,89 @@ static void ar9331_tag_flow_dissect(const struct sk_buff *skb, __be16 *proto, *proto = ar9331_tag_encap_proto(skb->data); } +static struct sk_buff *ar9331_tag_gro_receive(struct list_head *head, + struct sk_buff *skb) +{ + const struct packet_offload *ptype; + struct sk_buff *p, *pp = NULL; + u32 data_off, data_end; + const u8 *data; + int flush = 1; + + data_off = skb_gro_offset(skb); + data_end = data_off + AR9331_HDR_LEN; + + data = skb_gro_header_fast(skb, data_off); + if (skb_gro_header_hard(skb, data_end)) { + data = skb_gro_header_slow(skb, data_end, data_off); + if (unlikely(!data)) + goto out; + } + + /* Data that is to the left from the current position is already + * pulled to the head + */ + if (unlikely(!ar9331_tag_sanity_check(skb->data + data_off))) + goto out; + + rcu_read_lock(); + + ptype = gro_find_receive_by_type(ar9331_tag_encap_proto(data)); + if (!ptype) + goto out_unlock; + + flush = 0; + + list_for_each_entry(p, head, list) { + if (!NAPI_GRO_CB(p)->same_flow) + continue; + + if (ar9331_tag_source_port(skb->data + data_off) ^ + ar9331_tag_source_port(p->data + data_off)) + NAPI_GRO_CB(p)->same_flow = 0; + } + + skb_gro_pull(skb, AR9331_HDR_LEN); + skb_gro_postpull_rcsum(skb, data, AR9331_HDR_LEN); + + pp = call_gro_receive(ptype->callbacks.gro_receive, head, skb); + +out_unlock: + rcu_read_unlock(); +out: + skb_gro_flush_final(skb, pp, flush); + + return pp; +} + +static int ar9331_tag_gro_complete(struct sk_buff *skb, int nhoff) +{ + const struct packet_offload *ptype; + int err = -ENOENT; + __be16 proto; + + proto = ar9331_tag_encap_proto(skb->data + nhoff); + nhoff += AR9331_HDR_LEN; + + rcu_read_lock(); + + ptype = gro_find_complete_by_type(proto); + if (ptype) + err = ptype->callbacks.gro_complete(skb, nhoff); + + rcu_read_unlock(); + + return err; +} + static const struct dsa_device_ops ar9331_netdev_ops = { .name = "ar9331", .proto = DSA_TAG_PROTO_AR9331, .xmit = ar9331_tag_xmit, .rcv = ar9331_tag_rcv, .flow_dissect = ar9331_tag_flow_dissect, + .gro_receive = ar9331_tag_gro_receive, + .gro_complete = ar9331_tag_gro_complete, .overhead = AR9331_HDR_LEN, };
--
2.24.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel