Re: [PATCH net-next 05/15] ipv6/gso: remove temporary HBH/jumbo header
From: Eric Dumazet <edumazet@google.com>
Date: 2022-02-04 01:48:24
On Thu, Feb 3, 2022 at 5:14 PM Eric Dumazet [off-list ref] wrote:
On Thu, Feb 3, 2022 at 4:27 PM Eric Dumazet [off-list ref] wrote:quoted
On Thu, Feb 3, 2022 at 4:05 PM Alexander Duyck [off-list ref] wrote:quoted
quoted
I get that. What I was getting at was that we might be able to process it in ipv6_gso_segment before we hand it off to either TCP or UDP gso handlers to segment. The general idea being we keep the IPv6 specific bits in the IPv6 specific code instead of having the skb_segment function now have to understand IPv6 packets. So what we would end up doing is having to do an skb_cow to replace the skb->head if any clones might be holding on it, and then just chop off the HBH jumbo header before we start the segmenting. The risk would be that we waste cycles removing the HBH header for a frame that is going to fail, but I am not sure how likely a scenario that is or if we need to optimize for that.I guess I can try this for the next version, thanks.I came up with: ommit 147f17169ccc6c2c38ea802e5728528ed54f492d Author: Eric Dumazet [off-list ref] Date: Sat Nov 20 16:49:35 2021 -0800 ipv6/gso: remove temporary HBH/jumbo header ipv6 tcp and gro stacks will soon be able to build big TCP packets, with an added temporary Hop By Hop header. If GSO is involved for these large packets, we need to remove the temporary HBH header before segmentation happens. v2: perform HBH removal from ipv6_gso_segment() instead of skb_segment() (Alexander feedback) Signed-off-by: Eric Dumazet [off-list ref]
Well, this does not work at all.
quoted hunk ↗ jump to hunk
static inline bool ipv6_accept_ra(struct inet6_dev *idev) { /* If forwarding is enabled, RA are not accepted unless the specialdiff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c index d37a79a8554e92a1dcaa6fd023cafe2114841ece..7f65097c8f30fa19a8c9c265eb4f027e91848021100644--- a/net/ipv6/ip6_offload.c +++ b/net/ipv6/ip6_offload.c@@ -87,6 +87,27 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, bool gso_partial; skb_reset_network_header(skb); + if (ipv6_has_hopopt_jumbo(skb)) { + const int hophdr_len = sizeof(struct hop_jumbo_hdr); + int err; + + err = skb_cow_head(skb, 0); + if (err < 0) + return ERR_PTR(err); + + /* remove the HBH header. + * Layout: [Ethernet header][IPv6 header][HBH][TCP header] + */ + memmove(skb->data + hophdr_len, + skb->data, + ETH_HLEN + sizeof(struct ipv6hdr)); + skb->data += hophdr_len; + skb->len -= hophdr_len; + skb->network_header += hophdr_len; + skb->mac_header += hophdr_len; + ipv6h = (struct ipv6hdr *)skb->data; + ipv6h->nexthdr = IPPROTO_TCP; + } nhoff = skb_network_header(skb) - skb_mac_header(skb); if (unlikely(!pskb_may_pull(skb, sizeof(*ipv6h)))) goto out;