mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-19 12:24:34 +08:00
ipv6: lockless IPV6_ROUTER_ALERT_ISOLATE implementation
Reads from np->rtalert_isolate are racy. Move this flag 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
3cccda8db2
commit
83cd5eb654
@ -246,11 +246,10 @@ struct ipv6_pinfo {
|
||||
__u16 sndflow:1,
|
||||
pmtudisc:3,
|
||||
padding:1, /* 1 bit hole */
|
||||
srcprefs:3, /* 001: prefer temporary address
|
||||
srcprefs:3; /* 001: prefer temporary address
|
||||
* 010: prefer public address
|
||||
* 100: prefer care-of address
|
||||
*/
|
||||
rtalert_isolate:1;
|
||||
__u8 min_hopcount;
|
||||
__u8 tclass;
|
||||
__be32 rcv_flowinfo;
|
||||
|
@ -276,6 +276,7 @@ enum {
|
||||
INET_FLAGS_DONTFRAG = 25,
|
||||
INET_FLAGS_RECVERR6 = 26,
|
||||
INET_FLAGS_REPFLOW = 27,
|
||||
INET_FLAGS_RTALERT_ISOLATE = 28,
|
||||
};
|
||||
|
||||
/* cmsg flags for inet */
|
||||
|
@ -368,9 +368,8 @@ static int ip6_call_ra_chain(struct sk_buff *skb, int sel)
|
||||
if (sk && ra->sel == sel &&
|
||||
(!sk->sk_bound_dev_if ||
|
||||
sk->sk_bound_dev_if == skb->dev->ifindex)) {
|
||||
struct ipv6_pinfo *np = inet6_sk(sk);
|
||||
|
||||
if (np && np->rtalert_isolate &&
|
||||
if (inet6_test_bit(RTALERT_ISOLATE, sk) &&
|
||||
!net_eq(sock_net(sk), dev_net(skb->dev))) {
|
||||
continue;
|
||||
}
|
||||
|
@ -488,6 +488,11 @@ int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
|
||||
if (!val)
|
||||
skb_errqueue_purge(&sk->sk_error_queue);
|
||||
return 0;
|
||||
case IPV6_ROUTER_ALERT_ISOLATE:
|
||||
if (optlen < sizeof(int))
|
||||
return -EINVAL;
|
||||
inet6_assign_bit(RTALERT_ISOLATE, sk, valbool);
|
||||
return 0;
|
||||
}
|
||||
if (needs_rtnl)
|
||||
rtnl_lock();
|
||||
@ -936,12 +941,6 @@ done:
|
||||
goto e_inval;
|
||||
retv = ip6_ra_control(sk, val);
|
||||
break;
|
||||
case IPV6_ROUTER_ALERT_ISOLATE:
|
||||
if (optlen < sizeof(int))
|
||||
goto e_inval;
|
||||
np->rtalert_isolate = valbool;
|
||||
retv = 0;
|
||||
break;
|
||||
case IPV6_MTU_DISCOVER:
|
||||
if (optlen < sizeof(int))
|
||||
goto e_inval;
|
||||
@ -1452,7 +1451,7 @@ int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
|
||||
break;
|
||||
|
||||
case IPV6_ROUTER_ALERT_ISOLATE:
|
||||
val = np->rtalert_isolate;
|
||||
val = inet6_test_bit(RTALERT_ISOLATE, sk);
|
||||
break;
|
||||
|
||||
case IPV6_RECVERR_RFC4884:
|
||||
|
Loading…
Reference in New Issue
Block a user