aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/ipv4/raw.c21
-rw-r--r--net/ipv6/raw.c18
2 files changed, 26 insertions, 13 deletions
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 747911a8241c..a490a9d54712 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -116,16 +116,15 @@ static void raw_v4_unhash(struct sock *sk)
116 raw_unhash_sk(sk, &raw_v4_hashinfo); 116 raw_unhash_sk(sk, &raw_v4_hashinfo);
117} 117}
118 118
119static struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num, 119static struct sock *__raw_v4_lookup(struct net *net, struct sock *sk,
120 __be32 raddr, __be32 laddr, 120 unsigned short num, __be32 raddr, __be32 laddr, int dif)
121 int dif)
122{ 121{
123 struct hlist_node *node; 122 struct hlist_node *node;
124 123
125 sk_for_each_from(sk, node) { 124 sk_for_each_from(sk, node) {
126 struct inet_sock *inet = inet_sk(sk); 125 struct inet_sock *inet = inet_sk(sk);
127 126
128 if (inet->num == num && 127 if (sk->sk_net == net && inet->num == num &&
129 !(inet->daddr && inet->daddr != raddr) && 128 !(inet->daddr && inet->daddr != raddr) &&
130 !(inet->rcv_saddr && inet->rcv_saddr != laddr) && 129 !(inet->rcv_saddr && inet->rcv_saddr != laddr) &&
131 !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif)) 130 !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
@@ -169,12 +168,15 @@ static int raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash)
169 struct sock *sk; 168 struct sock *sk;
170 struct hlist_head *head; 169 struct hlist_head *head;
171 int delivered = 0; 170 int delivered = 0;
171 struct net *net;
172 172
173 read_lock(&raw_v4_hashinfo.lock); 173 read_lock(&raw_v4_hashinfo.lock);
174 head = &raw_v4_hashinfo.ht[hash]; 174 head = &raw_v4_hashinfo.ht[hash];
175 if (hlist_empty(head)) 175 if (hlist_empty(head))
176 goto out; 176 goto out;
177 sk = __raw_v4_lookup(__sk_head(head), iph->protocol, 177
178 net = skb->dev->nd_net;
179 sk = __raw_v4_lookup(net, __sk_head(head), iph->protocol,
178 iph->saddr, iph->daddr, 180 iph->saddr, iph->daddr,
179 skb->dev->ifindex); 181 skb->dev->ifindex);
180 182
@@ -187,7 +189,7 @@ static int raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash)
187 if (clone) 189 if (clone)
188 raw_rcv(sk, clone); 190 raw_rcv(sk, clone);
189 } 191 }
190 sk = __raw_v4_lookup(sk_next(sk), iph->protocol, 192 sk = __raw_v4_lookup(net, sk_next(sk), iph->protocol,
191 iph->saddr, iph->daddr, 193 iph->saddr, iph->daddr,
192 skb->dev->ifindex); 194 skb->dev->ifindex);
193 } 195 }
@@ -273,6 +275,7 @@ void raw_icmp_error(struct sk_buff *skb, int protocol, u32 info)
273 int hash; 275 int hash;
274 struct sock *raw_sk; 276 struct sock *raw_sk;
275 struct iphdr *iph; 277 struct iphdr *iph;
278 struct net *net;
276 279
277 hash = protocol & (RAW_HTABLE_SIZE - 1); 280 hash = protocol & (RAW_HTABLE_SIZE - 1);
278 281
@@ -280,8 +283,10 @@ void raw_icmp_error(struct sk_buff *skb, int protocol, u32 info)
280 raw_sk = sk_head(&raw_v4_hashinfo.ht[hash]); 283 raw_sk = sk_head(&raw_v4_hashinfo.ht[hash]);
281 if (raw_sk != NULL) { 284 if (raw_sk != NULL) {
282 iph = (struct iphdr *)skb->data; 285 iph = (struct iphdr *)skb->data;
283 while ((raw_sk = __raw_v4_lookup(raw_sk, protocol, iph->daddr, 286 net = skb->dev->nd_net;
284 iph->saddr, 287
288 while ((raw_sk = __raw_v4_lookup(net, raw_sk, protocol,
289 iph->daddr, iph->saddr,
285 skb->dev->ifindex)) != NULL) { 290 skb->dev->ifindex)) != NULL) {
286 raw_err(raw_sk, skb, info); 291 raw_err(raw_sk, skb, info);
287 raw_sk = sk_next(raw_sk); 292 raw_sk = sk_next(raw_sk);
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
79static struct sock *__raw_v6_lookup(struct sock *sk, unsigned short num, 79static 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 }
231out: 237out:
@@ -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);