mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 04:18:39 +08:00
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>
This commit is contained in:
parent
3fa29971c6
commit
3cccda8db2
@ -244,7 +244,6 @@ struct ipv6_pinfo {
|
|||||||
|
|
||||||
/* sockopt flags */
|
/* sockopt flags */
|
||||||
__u16 sndflow:1,
|
__u16 sndflow:1,
|
||||||
repflow:1,
|
|
||||||
pmtudisc:3,
|
pmtudisc:3,
|
||||||
padding:1, /* 1 bit hole */
|
padding:1, /* 1 bit hole */
|
||||||
srcprefs:3, /* 001: prefer temporary address
|
srcprefs:3, /* 001: prefer temporary address
|
||||||
|
@ -275,6 +275,7 @@ enum {
|
|||||||
INET_FLAGS_AUTOFLOWLABEL = 24,
|
INET_FLAGS_AUTOFLOWLABEL = 24,
|
||||||
INET_FLAGS_DONTFRAG = 25,
|
INET_FLAGS_DONTFRAG = 25,
|
||||||
INET_FLAGS_RECVERR6 = 26,
|
INET_FLAGS_RECVERR6 = 26,
|
||||||
|
INET_FLAGS_REPFLOW = 27,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* cmsg flags for inet */
|
/* cmsg flags for inet */
|
||||||
|
@ -679,7 +679,7 @@ ipv6_pktoptions:
|
|||||||
WRITE_ONCE(np->mcast_hops, ipv6_hdr(opt_skb)->hop_limit);
|
WRITE_ONCE(np->mcast_hops, ipv6_hdr(opt_skb)->hop_limit);
|
||||||
if (np->rxopt.bits.rxflow || np->rxopt.bits.rxtclass)
|
if (np->rxopt.bits.rxflow || np->rxopt.bits.rxtclass)
|
||||||
np->rcv_flowinfo = ip6_flowinfo(ipv6_hdr(opt_skb));
|
np->rcv_flowinfo = ip6_flowinfo(ipv6_hdr(opt_skb));
|
||||||
if (np->repflow)
|
if (inet6_test_bit(REPFLOW, sk))
|
||||||
np->flow_label = ip6_flowlabel(ipv6_hdr(opt_skb));
|
np->flow_label = ip6_flowlabel(ipv6_hdr(opt_skb));
|
||||||
if (ipv6_opt_accepted(sk, opt_skb,
|
if (ipv6_opt_accepted(sk, opt_skb,
|
||||||
&DCCP_SKB_CB(opt_skb)->header.h6)) {
|
&DCCP_SKB_CB(opt_skb)->header.h6)) {
|
||||||
|
@ -220,7 +220,8 @@ lookup_protocol:
|
|||||||
inet6_set_bit(MC6_LOOP, sk);
|
inet6_set_bit(MC6_LOOP, sk);
|
||||||
inet6_set_bit(MC6_ALL, sk);
|
inet6_set_bit(MC6_ALL, sk);
|
||||||
np->pmtudisc = IPV6_PMTUDISC_WANT;
|
np->pmtudisc = IPV6_PMTUDISC_WANT;
|
||||||
np->repflow = net->ipv6.sysctl.flowlabel_reflect & FLOWLABEL_REFLECT_ESTABLISHED;
|
inet6_assign_bit(REPFLOW, sk, net->ipv6.sysctl.flowlabel_reflect &
|
||||||
|
FLOWLABEL_REFLECT_ESTABLISHED);
|
||||||
sk->sk_ipv6only = net->ipv6.sysctl.bindv6only;
|
sk->sk_ipv6only = net->ipv6.sysctl.bindv6only;
|
||||||
sk->sk_txrehash = READ_ONCE(net->core.sysctl_txrehash);
|
sk->sk_txrehash = READ_ONCE(net->core.sysctl_txrehash);
|
||||||
|
|
||||||
|
@ -513,7 +513,7 @@ int ipv6_flowlabel_opt_get(struct sock *sk, struct in6_flowlabel_req *freq,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (np->repflow) {
|
if (inet6_test_bit(REPFLOW, sk)) {
|
||||||
freq->flr_label = np->flow_label;
|
freq->flr_label = np->flow_label;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -551,10 +551,10 @@ static int ipv6_flowlabel_put(struct sock *sk, struct in6_flowlabel_req *freq)
|
|||||||
if (freq->flr_flags & IPV6_FL_F_REFLECT) {
|
if (freq->flr_flags & IPV6_FL_F_REFLECT) {
|
||||||
if (sk->sk_protocol != IPPROTO_TCP)
|
if (sk->sk_protocol != IPPROTO_TCP)
|
||||||
return -ENOPROTOOPT;
|
return -ENOPROTOOPT;
|
||||||
if (!np->repflow)
|
if (!inet6_test_bit(REPFLOW, sk))
|
||||||
return -ESRCH;
|
return -ESRCH;
|
||||||
np->flow_label = 0;
|
np->flow_label = 0;
|
||||||
np->repflow = 0;
|
inet6_clear_bit(REPFLOW, sk);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -626,7 +626,7 @@ static int ipv6_flowlabel_get(struct sock *sk, struct in6_flowlabel_req *freq,
|
|||||||
|
|
||||||
if (sk->sk_protocol != IPPROTO_TCP)
|
if (sk->sk_protocol != IPPROTO_TCP)
|
||||||
return -ENOPROTOOPT;
|
return -ENOPROTOOPT;
|
||||||
np->repflow = 1;
|
inet6_set_bit(REPFLOW, sk);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -548,7 +548,7 @@ static int tcp_v6_send_synack(const struct sock *sk, struct dst_entry *dst,
|
|||||||
&ireq->ir_v6_rmt_addr);
|
&ireq->ir_v6_rmt_addr);
|
||||||
|
|
||||||
fl6->daddr = ireq->ir_v6_rmt_addr;
|
fl6->daddr = ireq->ir_v6_rmt_addr;
|
||||||
if (np->repflow && ireq->pktopts)
|
if (inet6_test_bit(REPFLOW, sk) && ireq->pktopts)
|
||||||
fl6->flowlabel = ip6_flowlabel(ipv6_hdr(ireq->pktopts));
|
fl6->flowlabel = ip6_flowlabel(ipv6_hdr(ireq->pktopts));
|
||||||
|
|
||||||
tclass = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_reflect_tos) ?
|
tclass = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_reflect_tos) ?
|
||||||
@ -797,7 +797,7 @@ static void tcp_v6_init_req(struct request_sock *req,
|
|||||||
(ipv6_opt_accepted(sk_listener, skb, &TCP_SKB_CB(skb)->header.h6) ||
|
(ipv6_opt_accepted(sk_listener, skb, &TCP_SKB_CB(skb)->header.h6) ||
|
||||||
np->rxopt.bits.rxinfo ||
|
np->rxopt.bits.rxinfo ||
|
||||||
np->rxopt.bits.rxoinfo || np->rxopt.bits.rxhlim ||
|
np->rxopt.bits.rxoinfo || np->rxopt.bits.rxhlim ||
|
||||||
np->rxopt.bits.rxohlim || np->repflow)) {
|
np->rxopt.bits.rxohlim || inet6_test_bit(REPFLOW, sk_listener))) {
|
||||||
refcount_inc(&skb->users);
|
refcount_inc(&skb->users);
|
||||||
ireq->pktopts = skb;
|
ireq->pktopts = skb;
|
||||||
}
|
}
|
||||||
@ -1055,10 +1055,8 @@ static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb)
|
|||||||
if (sk) {
|
if (sk) {
|
||||||
oif = sk->sk_bound_dev_if;
|
oif = sk->sk_bound_dev_if;
|
||||||
if (sk_fullsock(sk)) {
|
if (sk_fullsock(sk)) {
|
||||||
const struct ipv6_pinfo *np = tcp_inet6_sk(sk);
|
|
||||||
|
|
||||||
trace_tcp_send_reset(sk, skb);
|
trace_tcp_send_reset(sk, skb);
|
||||||
if (np->repflow)
|
if (inet6_test_bit(REPFLOW, sk))
|
||||||
label = ip6_flowlabel(ipv6h);
|
label = ip6_flowlabel(ipv6h);
|
||||||
priority = sk->sk_priority;
|
priority = sk->sk_priority;
|
||||||
txhash = sk->sk_txhash;
|
txhash = sk->sk_txhash;
|
||||||
@ -1247,7 +1245,7 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *
|
|||||||
newnp->mcast_oif = inet_iif(skb);
|
newnp->mcast_oif = inet_iif(skb);
|
||||||
newnp->mcast_hops = ip_hdr(skb)->ttl;
|
newnp->mcast_hops = ip_hdr(skb)->ttl;
|
||||||
newnp->rcv_flowinfo = 0;
|
newnp->rcv_flowinfo = 0;
|
||||||
if (np->repflow)
|
if (inet6_test_bit(REPFLOW, sk))
|
||||||
newnp->flow_label = 0;
|
newnp->flow_label = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1320,7 +1318,7 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *
|
|||||||
newnp->mcast_oif = tcp_v6_iif(skb);
|
newnp->mcast_oif = tcp_v6_iif(skb);
|
||||||
newnp->mcast_hops = ipv6_hdr(skb)->hop_limit;
|
newnp->mcast_hops = ipv6_hdr(skb)->hop_limit;
|
||||||
newnp->rcv_flowinfo = ip6_flowinfo(ipv6_hdr(skb));
|
newnp->rcv_flowinfo = ip6_flowinfo(ipv6_hdr(skb));
|
||||||
if (np->repflow)
|
if (inet6_test_bit(REPFLOW, sk))
|
||||||
newnp->flow_label = ip6_flowlabel(ipv6_hdr(skb));
|
newnp->flow_label = ip6_flowlabel(ipv6_hdr(skb));
|
||||||
|
|
||||||
/* Set ToS of the new socket based upon the value of incoming SYN.
|
/* Set ToS of the new socket based upon the value of incoming SYN.
|
||||||
@ -1546,7 +1544,7 @@ ipv6_pktoptions:
|
|||||||
ipv6_hdr(opt_skb)->hop_limit);
|
ipv6_hdr(opt_skb)->hop_limit);
|
||||||
if (np->rxopt.bits.rxflow || np->rxopt.bits.rxtclass)
|
if (np->rxopt.bits.rxflow || np->rxopt.bits.rxtclass)
|
||||||
np->rcv_flowinfo = ip6_flowinfo(ipv6_hdr(opt_skb));
|
np->rcv_flowinfo = ip6_flowinfo(ipv6_hdr(opt_skb));
|
||||||
if (np->repflow)
|
if (inet6_test_bit(REPFLOW, sk))
|
||||||
np->flow_label = ip6_flowlabel(ipv6_hdr(opt_skb));
|
np->flow_label = ip6_flowlabel(ipv6_hdr(opt_skb));
|
||||||
if (ipv6_opt_accepted(sk, opt_skb, &TCP_SKB_CB(opt_skb)->header.h6)) {
|
if (ipv6_opt_accepted(sk, opt_skb, &TCP_SKB_CB(opt_skb)->header.h6)) {
|
||||||
tcp_v6_restore_cb(opt_skb);
|
tcp_v6_restore_cb(opt_skb);
|
||||||
|
Loading…
Reference in New Issue
Block a user