diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2013-02-14 15:35:28 +1100 |
---|---|---|
committer | Stephen Rothwell <sfr@canb.auug.org.au> | 2013-02-14 15:35:28 +1100 |
commit | f600c997a1e930c3be312fdc4d1a67979d89173e (patch) | |
tree | 352f5d35d672887a5552730cb71af9d3f068fe19 /net/ipv6/raw.c | |
parent | 065957b017e290977dc5527ae4e21cff9d3fb5ec (diff) | |
parent | 0ef183f7f162a62662f6002b03bcf3ca2903c937 (diff) |
Merge branch 'akpm/master'
Diffstat (limited to 'net/ipv6/raw.c')
-rw-r--r-- | net/ipv6/raw.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 70fa81449997..e2405853ff40 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -71,10 +71,9 @@ static struct sock *__raw_v6_lookup(struct net *net, struct sock *sk, unsigned short num, const struct in6_addr *loc_addr, const struct in6_addr *rmt_addr, int dif) { - struct hlist_node *node; bool is_multicast = ipv6_addr_is_multicast(loc_addr); - sk_for_each_from(sk, node) + sk_for_each_from(sk) if (inet_sk(sk)->inet_num == num) { struct ipv6_pinfo *np = inet6_sk(sk); @@ -98,6 +97,24 @@ static struct sock *__raw_v6_lookup(struct net *net, struct sock *sk, } goto found; } + sk_for_each_from (sk) + if (inet_sk(sk)->inet_num == num) { + struct ipv6_pinfo *np=inet6_sk(sk); + if (!net_eq(sock_net(sk), net)) + continue; + if (!ipv6_addr_any(&np->daddr) && !ipv6_addr_equal(&np->daddr, rmt_addr)) + continue; + if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif) + continue; + if (!ipv6_addr_any(&np->rcv_saddr)) { + if (ipv6_addr_equal(&np->rcv_saddr, loc_addr)) + goto found; + if (is_multicast && inet6_mc_check(sk, loc_addr, rmt_addr)) + goto found; + continue; + } + goto found; + } sk = NULL; found: return sk; |