diff options
Diffstat (limited to 'net/ipv6/raw.c')
-rw-r--r-- | net/ipv6/raw.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index cb0b110a2ac8..6f20086064b2 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -76,8 +76,9 @@ static void raw_v6_unhash(struct sock *sk) | |||
76 | } | 76 | } |
77 | 77 | ||
78 | 78 | ||
79 | static struct sock *__raw_v6_lookup(struct sock *sk, unsigned short num, | 79 | static struct sock *__raw_v6_lookup(struct net *net, struct sock *sk, |
80 | struct in6_addr *loc_addr, struct in6_addr *rmt_addr, int dif) | 80 | unsigned short num, struct in6_addr *loc_addr, |
81 | struct in6_addr *rmt_addr, int dif) | ||
81 | { | 82 | { |
82 | struct hlist_node *node; | 83 | struct hlist_node *node; |
83 | int is_multicast = ipv6_addr_is_multicast(loc_addr); | 84 | int is_multicast = ipv6_addr_is_multicast(loc_addr); |
@@ -86,6 +87,9 @@ static struct sock *__raw_v6_lookup(struct sock *sk, unsigned short num, | |||
86 | if (inet_sk(sk)->num == num) { | 87 | if (inet_sk(sk)->num == num) { |
87 | struct ipv6_pinfo *np = inet6_sk(sk); | 88 | struct ipv6_pinfo *np = inet6_sk(sk); |
88 | 89 | ||
90 | if (sk->sk_net != net) | ||
91 | continue; | ||
92 | |||
89 | if (!ipv6_addr_any(&np->daddr) && | 93 | if (!ipv6_addr_any(&np->daddr) && |
90 | !ipv6_addr_equal(&np->daddr, rmt_addr)) | 94 | !ipv6_addr_equal(&np->daddr, rmt_addr)) |
91 | continue; | 95 | continue; |
@@ -165,6 +169,7 @@ static int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr) | |||
165 | struct sock *sk; | 169 | struct sock *sk; |
166 | int delivered = 0; | 170 | int delivered = 0; |
167 | __u8 hash; | 171 | __u8 hash; |
172 | struct net *net; | ||
168 | 173 | ||
169 | saddr = &ipv6_hdr(skb)->saddr; | 174 | saddr = &ipv6_hdr(skb)->saddr; |
170 | daddr = saddr + 1; | 175 | daddr = saddr + 1; |
@@ -182,7 +187,8 @@ static int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr) | |||
182 | if (sk == NULL) | 187 | if (sk == NULL) |
183 | goto out; | 188 | goto out; |
184 | 189 | ||
185 | sk = __raw_v6_lookup(sk, nexthdr, daddr, saddr, IP6CB(skb)->iif); | 190 | net = skb->dev->nd_net; |
191 | sk = __raw_v6_lookup(net, sk, nexthdr, daddr, saddr, IP6CB(skb)->iif); | ||
186 | 192 | ||
187 | while (sk) { | 193 | while (sk) { |
188 | int filtered; | 194 | int filtered; |
@@ -225,7 +231,7 @@ static int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr) | |||
225 | rawv6_rcv(sk, clone); | 231 | rawv6_rcv(sk, clone); |
226 | } | 232 | } |
227 | } | 233 | } |
228 | sk = __raw_v6_lookup(sk_next(sk), nexthdr, daddr, saddr, | 234 | sk = __raw_v6_lookup(net, sk_next(sk), nexthdr, daddr, saddr, |
229 | IP6CB(skb)->iif); | 235 | IP6CB(skb)->iif); |
230 | } | 236 | } |
231 | out: | 237 | out: |
@@ -359,6 +365,7 @@ void raw6_icmp_error(struct sk_buff *skb, int nexthdr, | |||
359 | struct sock *sk; | 365 | struct sock *sk; |
360 | int hash; | 366 | int hash; |
361 | struct in6_addr *saddr, *daddr; | 367 | struct in6_addr *saddr, *daddr; |
368 | struct net *net; | ||
362 | 369 | ||
363 | hash = nexthdr & (RAW_HTABLE_SIZE - 1); | 370 | hash = nexthdr & (RAW_HTABLE_SIZE - 1); |
364 | 371 | ||
@@ -367,8 +374,9 @@ void raw6_icmp_error(struct sk_buff *skb, int nexthdr, | |||
367 | if (sk != NULL) { | 374 | if (sk != NULL) { |
368 | saddr = &ipv6_hdr(skb)->saddr; | 375 | saddr = &ipv6_hdr(skb)->saddr; |
369 | daddr = &ipv6_hdr(skb)->daddr; | 376 | daddr = &ipv6_hdr(skb)->daddr; |
377 | net = skb->dev->nd_net; | ||
370 | 378 | ||
371 | while ((sk = __raw_v6_lookup(sk, nexthdr, saddr, daddr, | 379 | while ((sk = __raw_v6_lookup(net, sk, nexthdr, saddr, daddr, |
372 | IP6CB(skb)->iif))) { | 380 | IP6CB(skb)->iif))) { |
373 | rawv6_err(sk, skb, NULL, type, code, | 381 | rawv6_err(sk, skb, NULL, type, code, |
374 | inner_offset, info); | 382 | inner_offset, info); |