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

From: Pavel Begunkov
Date: Fri May 13 2022 - 11:27:41 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 e2a6b9bdf79c..6ee44c509485 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1881,22 +1881,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