diff options
Diffstat (limited to 'net/ipv4/ip_input.c')
-rw-r--r-- | net/ipv4/ip_input.c | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index 65631391d479..7b4bad6d572f 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c | |||
@@ -160,6 +160,7 @@ int ip_call_ra_chain(struct sk_buff *skb) | |||
160 | struct ip_ra_chain *ra; | 160 | struct ip_ra_chain *ra; |
161 | u8 protocol = ip_hdr(skb)->protocol; | 161 | u8 protocol = ip_hdr(skb)->protocol; |
162 | struct sock *last = NULL; | 162 | struct sock *last = NULL; |
163 | struct net_device *dev = skb->dev; | ||
163 | 164 | ||
164 | read_lock(&ip_ra_lock); | 165 | read_lock(&ip_ra_lock); |
165 | for (ra = ip_ra_chain; ra; ra = ra->next) { | 166 | for (ra = ip_ra_chain; ra; ra = ra->next) { |
@@ -170,7 +171,8 @@ int ip_call_ra_chain(struct sk_buff *skb) | |||
170 | */ | 171 | */ |
171 | if (sk && inet_sk(sk)->num == protocol && | 172 | if (sk && inet_sk(sk)->num == protocol && |
172 | (!sk->sk_bound_dev_if || | 173 | (!sk->sk_bound_dev_if || |
173 | sk->sk_bound_dev_if == skb->dev->ifindex)) { | 174 | sk->sk_bound_dev_if == dev->ifindex) && |
175 | sock_net(sk) == dev_net(dev)) { | ||
174 | if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) { | 176 | if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) { |
175 | if (ip_defrag(skb, IP_DEFRAG_CALL_RA_CHAIN)) { | 177 | if (ip_defrag(skb, IP_DEFRAG_CALL_RA_CHAIN)) { |
176 | read_unlock(&ip_ra_lock); | 178 | read_unlock(&ip_ra_lock); |
@@ -197,6 +199,8 @@ int ip_call_ra_chain(struct sk_buff *skb) | |||
197 | 199 | ||
198 | static int ip_local_deliver_finish(struct sk_buff *skb) | 200 | static int ip_local_deliver_finish(struct sk_buff *skb) |
199 | { | 201 | { |
202 | struct net *net = dev_net(skb->dev); | ||
203 | |||
200 | __skb_pull(skb, ip_hdrlen(skb)); | 204 | __skb_pull(skb, ip_hdrlen(skb)); |
201 | 205 | ||
202 | /* Point into the IP datagram, just past the header. */ | 206 | /* Point into the IP datagram, just past the header. */ |
@@ -212,7 +216,8 @@ static int ip_local_deliver_finish(struct sk_buff *skb) | |||
212 | raw = raw_local_deliver(skb, protocol); | 216 | raw = raw_local_deliver(skb, protocol); |
213 | 217 | ||
214 | hash = protocol & (MAX_INET_PROTOS - 1); | 218 | hash = protocol & (MAX_INET_PROTOS - 1); |
215 | if ((ipprot = rcu_dereference(inet_protos[hash])) != NULL) { | 219 | ipprot = rcu_dereference(inet_protos[hash]); |
220 | if (ipprot != NULL && (net == &init_net || ipprot->netns_ok)) { | ||
216 | int ret; | 221 | int ret; |
217 | 222 | ||
218 | if (!ipprot->no_policy) { | 223 | if (!ipprot->no_policy) { |
@@ -283,13 +288,14 @@ static inline int ip_rcv_options(struct sk_buff *skb) | |||
283 | } | 288 | } |
284 | 289 | ||
285 | iph = ip_hdr(skb); | 290 | iph = ip_hdr(skb); |
291 | opt = &(IPCB(skb)->opt); | ||
292 | opt->optlen = iph->ihl*4 - sizeof(struct iphdr); | ||
286 | 293 | ||
287 | if (ip_options_compile(NULL, skb)) { | 294 | if (ip_options_compile(dev_net(dev), opt, skb)) { |
288 | IP_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); | 295 | IP_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); |
289 | goto drop; | 296 | goto drop; |
290 | } | 297 | } |
291 | 298 | ||
292 | opt = &(IPCB(skb)->opt); | ||
293 | if (unlikely(opt->srr)) { | 299 | if (unlikely(opt->srr)) { |
294 | struct in_device *in_dev = in_dev_get(dev); | 300 | struct in_device *in_dev = in_dev_get(dev); |
295 | if (in_dev) { | 301 | if (in_dev) { |
@@ -297,7 +303,7 @@ static inline int ip_rcv_options(struct sk_buff *skb) | |||
297 | if (IN_DEV_LOG_MARTIANS(in_dev) && | 303 | if (IN_DEV_LOG_MARTIANS(in_dev) && |
298 | net_ratelimit()) | 304 | net_ratelimit()) |
299 | printk(KERN_INFO "source route option " | 305 | printk(KERN_INFO "source route option " |
300 | "%u.%u.%u.%u -> %u.%u.%u.%u\n", | 306 | NIPQUAD_FMT " -> " NIPQUAD_FMT "\n", |
301 | NIPQUAD(iph->saddr), | 307 | NIPQUAD(iph->saddr), |
302 | NIPQUAD(iph->daddr)); | 308 | NIPQUAD(iph->daddr)); |
303 | in_dev_put(in_dev); | 309 | in_dev_put(in_dev); |
@@ -351,7 +357,7 @@ static int ip_rcv_finish(struct sk_buff *skb) | |||
351 | if (iph->ihl > 5 && ip_rcv_options(skb)) | 357 | if (iph->ihl > 5 && ip_rcv_options(skb)) |
352 | goto drop; | 358 | goto drop; |
353 | 359 | ||
354 | rt = (struct rtable*)skb->dst; | 360 | rt = skb->rtable; |
355 | if (rt->rt_type == RTN_MULTICAST) | 361 | if (rt->rt_type == RTN_MULTICAST) |
356 | IP_INC_STATS_BH(IPSTATS_MIB_INMCASTPKTS); | 362 | IP_INC_STATS_BH(IPSTATS_MIB_INMCASTPKTS); |
357 | else if (rt->rt_type == RTN_BROADCAST) | 363 | else if (rt->rt_type == RTN_BROADCAST) |
@@ -372,9 +378,6 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, | |||
372 | struct iphdr *iph; | 378 | struct iphdr *iph; |
373 | u32 len; | 379 | u32 len; |
374 | 380 | ||
375 | if (dev->nd_net != &init_net) | ||
376 | goto drop; | ||
377 | |||
378 | /* When the interface is in promisc. mode, drop all the crap | 381 | /* When the interface is in promisc. mode, drop all the crap |
379 | * that it receives, do not try to analyse it. | 382 | * that it receives, do not try to analyse it. |
380 | */ | 383 | */ |