Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 497c615a authored by Herbert Xu's avatar Herbert Xu Committed by David S. Miller
Browse files

[IPV6]: Audit all ip6_dst_lookup/ip6_dst_store calls



The current users of ip6_dst_lookup can be divided into two classes:

1) The caller holds no locks and is in user-context (UDP).
2) The caller does not want to lookup the dst cache at all.

The second class covers everyone except UDP because most people do
the cache lookup directly before calling ip6_dst_lookup.  This patch
adds ip6_sk_dst_lookup for the first class.

Similarly ip6_dst_store users can be divded into those that need to
take the socket dst lock and those that don't.  This patch adds
__ip6_dst_store for those (everyone except UDP/datagram) that don't
need an extra lock.

Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 679e898a
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -139,16 +139,22 @@ extern rwlock_t rt6_lock;
/*
 *	Store a destination cache entry in a socket
 */
static inline void ip6_dst_store(struct sock *sk, struct dst_entry *dst,
static inline void __ip6_dst_store(struct sock *sk, struct dst_entry *dst,
				   struct in6_addr *daddr)
{
	struct ipv6_pinfo *np = inet6_sk(sk);
	struct rt6_info *rt = (struct rt6_info *) dst;

	write_lock(&sk->sk_dst_lock);
	sk_setup_caps(sk, dst);
	np->daddr_cache = daddr;
	np->dst_cookie = rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0;
}

static inline void ip6_dst_store(struct sock *sk, struct dst_entry *dst,
				 struct in6_addr *daddr)
{
	write_lock(&sk->sk_dst_lock);
	__ip6_dst_store(sk, dst, daddr);
	write_unlock(&sk->sk_dst_lock);
}

+3 −0
Original line number Diff line number Diff line
@@ -468,6 +468,9 @@ extern void ip6_flush_pending_frames(struct sock *sk);
extern int			ip6_dst_lookup(struct sock *sk,
					       struct dst_entry **dst,
					       struct flowi *fl);
extern int			ip6_sk_dst_lookup(struct sock *sk,
						  struct dst_entry **dst,
						  struct flowi *fl);

/*
 *	skb processing functions
+2 −2
Original line number Diff line number Diff line
@@ -230,7 +230,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
	ipv6_addr_copy(&np->saddr, saddr);
	inet->rcv_saddr = LOOPBACK4_IPV6;

	ip6_dst_store(sk, dst, NULL);
	__ip6_dst_store(sk, dst, NULL);

	icsk->icsk_ext_hdr_len = 0;
	if (np->opt != NULL)
@@ -863,7 +863,7 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
	 * comment in that function for the gory details. -acme
	 */

	ip6_dst_store(newsk, dst, NULL);
	__ip6_dst_store(newsk, dst, NULL);
	newsk->sk_route_caps = dst->dev->features & ~(NETIF_F_IP_CSUM |
						      NETIF_F_TSO);
	newdp6 = (struct dccp6_sock *)newsk;
+1 −1
Original line number Diff line number Diff line
@@ -658,7 +658,7 @@ int inet6_sk_rebuild_header(struct sock *sk)
			return err;
		}

		ip6_dst_store(sk, dst, NULL);
		__ip6_dst_store(sk, dst, NULL);
	}

	return 0;
+1 −1
Original line number Diff line number Diff line
@@ -185,7 +185,7 @@ int inet6_csk_xmit(struct sk_buff *skb, int ipfragok)
			return err;
		}

		ip6_dst_store(sk, dst, NULL);
		__ip6_dst_store(sk, dst, NULL);
	}

	skb->dst = dst_clone(dst);
Loading