Commit 3fa29971 authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller
Browse files

ipv6: lockless IPV6_RECVERR implemetation



np->recverr is moved to inet->inet_flags to fix data-races.

Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Reviewed-by: default avatarDavid Ahern <dsahern@kernel.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1086ca7c
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -243,8 +243,7 @@ struct ipv6_pinfo {
	} rxopt;

	/* sockopt flags */
	__u16			recverr:1,
	                        sndflow:1,
	__u16			sndflow:1,
				repflow:1,
				pmtudisc:3,
				padding:1,	/* 1 bit hole */
+1 −0
Original line number Diff line number Diff line
@@ -274,6 +274,7 @@ enum {
	INET_FLAGS_AUTOFLOWLABEL_SET = 23,
	INET_FLAGS_AUTOFLOWLABEL = 24,
	INET_FLAGS_DONTFRAG	= 25,
	INET_FLAGS_RECVERR6	= 26,
};

/* cmsg flags for inet */
+1 −3
Original line number Diff line number Diff line
@@ -1303,9 +1303,7 @@ static inline int ip6_sock_set_v6only(struct sock *sk)

static inline void ip6_sock_set_recverr(struct sock *sk)
{
	lock_sock(sk);
	inet6_sk(sk)->recverr = true;
	release_sock(sk);
	inet6_set_bit(RECVERR6, sk);
}

static inline int __ip6_sock_set_addr_preferences(struct sock *sk, int val)
+1 −1
Original line number Diff line number Diff line
@@ -185,7 +185,7 @@ static int dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
		goto out;
	}

	if (!sock_owned_by_user(sk) && np->recverr) {
	if (!sock_owned_by_user(sk) && inet6_test_bit(RECVERR6, sk)) {
		sk->sk_err = err;
		sk_error_report(sk);
	} else {
+1 −1
Original line number Diff line number Diff line
@@ -581,7 +581,7 @@ void ping_err(struct sk_buff *skb, int offset, u32 info)
	 *	4.1.3.3.
	 */
	if ((family == AF_INET && !inet_test_bit(RECVERR, sk)) ||
	    (family == AF_INET6 && !inet6_sk(sk)->recverr)) {
	    (family == AF_INET6 && !inet6_test_bit(RECVERR6, sk))) {
		if (!harderr || sk->sk_state != TCP_ESTABLISHED)
			goto out;
	} else {
Loading