[PATCH v2 net-next 10/11] ipv6: improve opt-less __ip6_make_skb()

From: Pavel Begunkov
Date: Thu Apr 28 2022 - 09:59:42 EST


We do a bit of a network header pointer shuffling in __ip6_make_skb()
expecting that ipv6_push_*frag_opts() might change the layout. Avoid it
with associated overhead when there are no opts.

Signed-off-by: Pavel Begunkov <asml.silence@xxxxxxxxx>
---
net/ipv6/ip6_output.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 43a541bbcf5f..416d14299242 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1880,22 +1880,20 @@ struct sk_buff *__ip6_make_skb(struct sock *sk,

/* Allow local fragmentation. */
skb->ignore_df = ip6_sk_ignore_df(sk);
- __skb_pull(skb, skb_network_header_len(skb));
-
final_dst = &fl6->daddr;
if (v6_cork->opt) {
struct ipv6_txoptions *opt = v6_cork->opt;

+ __skb_pull(skb, skb_network_header_len(skb));
if (opt->opt_flen)
ipv6_push_frag_opts(skb, opt, &proto);
if (opt->opt_nflen)
ipv6_push_nfrag_opts(skb, opt, &proto, &final_dst, &fl6->saddr);
+ skb_push(skb, sizeof(struct ipv6hdr));
+ skb_reset_network_header(skb);
}

- skb_push(skb, sizeof(struct ipv6hdr));
- skb_reset_network_header(skb);
hdr = ipv6_hdr(skb);
-
ip6_flow_hdr(hdr, v6_cork->tclass,
ip6_make_flowlabel(net, skb, fl6->flowlabel,
ip6_autoflowlabel(net, np), fl6));
--
2.36.0