diff --git a/include/linux/tcp.h b/include/linux/tcp.h index d18f7bc1e5d0..5a4c61fc240e 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -179,6 +179,9 @@ struct tcp_request_sock { u8 ao_rcv_next; bool used_tcp_ao; #endif +#if IS_ENABLED(CONFIG_IPV6) + __be32 syn_flowlabel; +#endif }; #define tcp_rsk(ptr) container_of_const(ptr, struct tcp_request_sock, req.req) diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index e006a30360ea..d406cd3c8cea 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -578,8 +578,8 @@ static int tcp_v6_send_synack(const struct sock *sk, struct dst_entry *dst, &ireq->ir_v6_rmt_addr); fl6->daddr = ireq->ir_v6_rmt_addr; - if (inet6_test_bit(REPFLOW, sk) && ireq->pktopts) - fl6->flowlabel = ip6_flowlabel(ipv6_hdr(ireq->pktopts)); + if (inet6_test_bit(REPFLOW, sk)) + fl6->flowlabel = tcp_rsk(req)->syn_flowlabel; tclass = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_reflect_tos) ? (tcp_rsk(req)->syn_tos & ~INET_ECN_MASK) | @@ -789,6 +789,7 @@ static void tcp_v6_init_req(struct request_sock *req, ireq->ir_v6_loc_addr = ipv6_hdr(skb)->daddr; ireq->ir_rmt_addr = LOOPBACK4_IPV6; ireq->ir_loc_addr = LOOPBACK4_IPV6; + tcp_rsk(req)->syn_flowlabel = ip6_flowlabel(ipv6_hdr(skb)); /* So that link locals have meaning */ if ((!sk_listener->sk_bound_dev_if || l3_slave) &&