Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ipv6: move np->repflow to atomic flags

Move np->repflow to inet->inet_flags to fix data-races.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Eric Dumazet and committed by
David S. Miller
3cccda8d 3fa29971

+14 -15
-1
include/linux/ipv6.h
··· 244 244 245 245 /* sockopt flags */ 246 246 __u16 sndflow:1, 247 - repflow:1, 248 247 pmtudisc:3, 249 248 padding:1, /* 1 bit hole */ 250 249 srcprefs:3, /* 001: prefer temporary address
+1
include/net/inet_sock.h
··· 275 275 INET_FLAGS_AUTOFLOWLABEL = 24, 276 276 INET_FLAGS_DONTFRAG = 25, 277 277 INET_FLAGS_RECVERR6 = 26, 278 + INET_FLAGS_REPFLOW = 27, 278 279 }; 279 280 280 281 /* cmsg flags for inet */
+1 -1
net/dccp/ipv6.c
··· 679 679 WRITE_ONCE(np->mcast_hops, ipv6_hdr(opt_skb)->hop_limit); 680 680 if (np->rxopt.bits.rxflow || np->rxopt.bits.rxtclass) 681 681 np->rcv_flowinfo = ip6_flowinfo(ipv6_hdr(opt_skb)); 682 - if (np->repflow) 682 + if (inet6_test_bit(REPFLOW, sk)) 683 683 np->flow_label = ip6_flowlabel(ipv6_hdr(opt_skb)); 684 684 if (ipv6_opt_accepted(sk, opt_skb, 685 685 &DCCP_SKB_CB(opt_skb)->header.h6)) {
+2 -1
net/ipv6/af_inet6.c
··· 220 220 inet6_set_bit(MC6_LOOP, sk); 221 221 inet6_set_bit(MC6_ALL, sk); 222 222 np->pmtudisc = IPV6_PMTUDISC_WANT; 223 - np->repflow = net->ipv6.sysctl.flowlabel_reflect & FLOWLABEL_REFLECT_ESTABLISHED; 223 + inet6_assign_bit(REPFLOW, sk, net->ipv6.sysctl.flowlabel_reflect & 224 + FLOWLABEL_REFLECT_ESTABLISHED); 224 225 sk->sk_ipv6only = net->ipv6.sysctl.bindv6only; 225 226 sk->sk_txrehash = READ_ONCE(net->core.sysctl_txrehash); 226 227
+4 -4
net/ipv6/ip6_flowlabel.c
··· 513 513 return 0; 514 514 } 515 515 516 - if (np->repflow) { 516 + if (inet6_test_bit(REPFLOW, sk)) { 517 517 freq->flr_label = np->flow_label; 518 518 return 0; 519 519 } ··· 551 551 if (freq->flr_flags & IPV6_FL_F_REFLECT) { 552 552 if (sk->sk_protocol != IPPROTO_TCP) 553 553 return -ENOPROTOOPT; 554 - if (!np->repflow) 554 + if (!inet6_test_bit(REPFLOW, sk)) 555 555 return -ESRCH; 556 556 np->flow_label = 0; 557 - np->repflow = 0; 557 + inet6_clear_bit(REPFLOW, sk); 558 558 return 0; 559 559 } 560 560 ··· 626 626 627 627 if (sk->sk_protocol != IPPROTO_TCP) 628 628 return -ENOPROTOOPT; 629 - np->repflow = 1; 629 + inet6_set_bit(REPFLOW, sk); 630 630 return 0; 631 631 } 632 632
+6 -8
net/ipv6/tcp_ipv6.c
··· 548 548 &ireq->ir_v6_rmt_addr); 549 549 550 550 fl6->daddr = ireq->ir_v6_rmt_addr; 551 - if (np->repflow && ireq->pktopts) 551 + if (inet6_test_bit(REPFLOW, sk) && ireq->pktopts) 552 552 fl6->flowlabel = ip6_flowlabel(ipv6_hdr(ireq->pktopts)); 553 553 554 554 tclass = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_reflect_tos) ? ··· 797 797 (ipv6_opt_accepted(sk_listener, skb, &TCP_SKB_CB(skb)->header.h6) || 798 798 np->rxopt.bits.rxinfo || 799 799 np->rxopt.bits.rxoinfo || np->rxopt.bits.rxhlim || 800 - np->rxopt.bits.rxohlim || np->repflow)) { 800 + np->rxopt.bits.rxohlim || inet6_test_bit(REPFLOW, sk_listener))) { 801 801 refcount_inc(&skb->users); 802 802 ireq->pktopts = skb; 803 803 } ··· 1055 1055 if (sk) { 1056 1056 oif = sk->sk_bound_dev_if; 1057 1057 if (sk_fullsock(sk)) { 1058 - const struct ipv6_pinfo *np = tcp_inet6_sk(sk); 1059 - 1060 1058 trace_tcp_send_reset(sk, skb); 1061 - if (np->repflow) 1059 + if (inet6_test_bit(REPFLOW, sk)) 1062 1060 label = ip6_flowlabel(ipv6h); 1063 1061 priority = sk->sk_priority; 1064 1062 txhash = sk->sk_txhash; ··· 1245 1247 newnp->mcast_oif = inet_iif(skb); 1246 1248 newnp->mcast_hops = ip_hdr(skb)->ttl; 1247 1249 newnp->rcv_flowinfo = 0; 1248 - if (np->repflow) 1250 + if (inet6_test_bit(REPFLOW, sk)) 1249 1251 newnp->flow_label = 0; 1250 1252 1251 1253 /* ··· 1318 1320 newnp->mcast_oif = tcp_v6_iif(skb); 1319 1321 newnp->mcast_hops = ipv6_hdr(skb)->hop_limit; 1320 1322 newnp->rcv_flowinfo = ip6_flowinfo(ipv6_hdr(skb)); 1321 - if (np->repflow) 1323 + if (inet6_test_bit(REPFLOW, sk)) 1322 1324 newnp->flow_label = ip6_flowlabel(ipv6_hdr(skb)); 1323 1325 1324 1326 /* Set ToS of the new socket based upon the value of incoming SYN. ··· 1544 1546 ipv6_hdr(opt_skb)->hop_limit); 1545 1547 if (np->rxopt.bits.rxflow || np->rxopt.bits.rxtclass) 1546 1548 np->rcv_flowinfo = ip6_flowinfo(ipv6_hdr(opt_skb)); 1547 - if (np->repflow) 1549 + if (inet6_test_bit(REPFLOW, sk)) 1548 1550 np->flow_label = ip6_flowlabel(ipv6_hdr(opt_skb)); 1549 1551 if (ipv6_opt_accepted(sk, opt_skb, &TCP_SKB_CB(opt_skb)->header.h6)) { 1550 1552 tcp_v6_restore_cb(opt_skb);