diff options
Diffstat (limited to 'net/ipv4/arp.c')
-rw-r--r-- | net/ipv4/arp.c | 58 |
1 files changed, 33 insertions, 25 deletions
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 8e17f65f4002..3ce2e137e7bc 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c | |||
@@ -242,7 +242,7 @@ static int arp_constructor(struct neighbour *neigh) | |||
242 | return -EINVAL; | 242 | return -EINVAL; |
243 | } | 243 | } |
244 | 244 | ||
245 | neigh->type = inet_addr_type(&init_net, addr); | 245 | neigh->type = inet_addr_type(dev_net(dev), addr); |
246 | 246 | ||
247 | parms = in_dev->arp_parms; | 247 | parms = in_dev->arp_parms; |
248 | __neigh_parms_put(neigh->parms); | 248 | __neigh_parms_put(neigh->parms); |
@@ -341,14 +341,14 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb) | |||
341 | switch (IN_DEV_ARP_ANNOUNCE(in_dev)) { | 341 | switch (IN_DEV_ARP_ANNOUNCE(in_dev)) { |
342 | default: | 342 | default: |
343 | case 0: /* By default announce any local IP */ | 343 | case 0: /* By default announce any local IP */ |
344 | if (skb && inet_addr_type(&init_net, ip_hdr(skb)->saddr) == RTN_LOCAL) | 344 | if (skb && inet_addr_type(dev_net(dev), ip_hdr(skb)->saddr) == RTN_LOCAL) |
345 | saddr = ip_hdr(skb)->saddr; | 345 | saddr = ip_hdr(skb)->saddr; |
346 | break; | 346 | break; |
347 | case 1: /* Restrict announcements of saddr in same subnet */ | 347 | case 1: /* Restrict announcements of saddr in same subnet */ |
348 | if (!skb) | 348 | if (!skb) |
349 | break; | 349 | break; |
350 | saddr = ip_hdr(skb)->saddr; | 350 | saddr = ip_hdr(skb)->saddr; |
351 | if (inet_addr_type(&init_net, saddr) == RTN_LOCAL) { | 351 | if (inet_addr_type(dev_net(dev), saddr) == RTN_LOCAL) { |
352 | /* saddr should be known to target */ | 352 | /* saddr should be known to target */ |
353 | if (inet_addr_onlink(in_dev, target, saddr)) | 353 | if (inet_addr_onlink(in_dev, target, saddr)) |
354 | break; | 354 | break; |
@@ -424,7 +424,7 @@ static int arp_filter(__be32 sip, __be32 tip, struct net_device *dev) | |||
424 | int flag = 0; | 424 | int flag = 0; |
425 | /*unsigned long now; */ | 425 | /*unsigned long now; */ |
426 | 426 | ||
427 | if (ip_route_output_key(&init_net, &rt, &fl) < 0) | 427 | if (ip_route_output_key(dev_net(dev), &rt, &fl) < 0) |
428 | return 1; | 428 | return 1; |
429 | if (rt->u.dst.dev != dev) { | 429 | if (rt->u.dst.dev != dev) { |
430 | NET_INC_STATS_BH(LINUX_MIB_ARPFILTER); | 430 | NET_INC_STATS_BH(LINUX_MIB_ARPFILTER); |
@@ -475,9 +475,9 @@ int arp_find(unsigned char *haddr, struct sk_buff *skb) | |||
475 | return 1; | 475 | return 1; |
476 | } | 476 | } |
477 | 477 | ||
478 | paddr = ((struct rtable*)skb->dst)->rt_gateway; | 478 | paddr = skb->rtable->rt_gateway; |
479 | 479 | ||
480 | if (arp_set_predefined(inet_addr_type(&init_net, paddr), haddr, paddr, dev)) | 480 | if (arp_set_predefined(inet_addr_type(dev_net(dev), paddr), haddr, paddr, dev)) |
481 | return 0; | 481 | return 0; |
482 | 482 | ||
483 | n = __neigh_lookup(&arp_tbl, &paddr, dev, 1); | 483 | n = __neigh_lookup(&arp_tbl, &paddr, dev, 1); |
@@ -570,14 +570,13 @@ struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip, | |||
570 | * Allocate a buffer | 570 | * Allocate a buffer |
571 | */ | 571 | */ |
572 | 572 | ||
573 | skb = alloc_skb(sizeof(struct arphdr)+ 2*(dev->addr_len+4) | 573 | skb = alloc_skb(arp_hdr_len(dev) + LL_RESERVED_SPACE(dev), GFP_ATOMIC); |
574 | + LL_RESERVED_SPACE(dev), GFP_ATOMIC); | ||
575 | if (skb == NULL) | 574 | if (skb == NULL) |
576 | return NULL; | 575 | return NULL; |
577 | 576 | ||
578 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); | 577 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); |
579 | skb_reset_network_header(skb); | 578 | skb_reset_network_header(skb); |
580 | arp = (struct arphdr *) skb_put(skb,sizeof(struct arphdr) + 2*(dev->addr_len+4)); | 579 | arp = (struct arphdr *) skb_put(skb, arp_hdr_len(dev)); |
581 | skb->dev = dev; | 580 | skb->dev = dev; |
582 | skb->protocol = htons(ETH_P_ARP); | 581 | skb->protocol = htons(ETH_P_ARP); |
583 | if (src_hw == NULL) | 582 | if (src_hw == NULL) |
@@ -710,6 +709,7 @@ static int arp_process(struct sk_buff *skb) | |||
710 | u16 dev_type = dev->type; | 709 | u16 dev_type = dev->type; |
711 | int addr_type; | 710 | int addr_type; |
712 | struct neighbour *n; | 711 | struct neighbour *n; |
712 | struct net *net = dev_net(dev); | ||
713 | 713 | ||
714 | /* arp_rcv below verifies the ARP header and verifies the device | 714 | /* arp_rcv below verifies the ARP header and verifies the device |
715 | * is ARP'able. | 715 | * is ARP'able. |
@@ -805,7 +805,7 @@ static int arp_process(struct sk_buff *skb) | |||
805 | /* Special case: IPv4 duplicate address detection packet (RFC2131) */ | 805 | /* Special case: IPv4 duplicate address detection packet (RFC2131) */ |
806 | if (sip == 0) { | 806 | if (sip == 0) { |
807 | if (arp->ar_op == htons(ARPOP_REQUEST) && | 807 | if (arp->ar_op == htons(ARPOP_REQUEST) && |
808 | inet_addr_type(&init_net, tip) == RTN_LOCAL && | 808 | inet_addr_type(net, tip) == RTN_LOCAL && |
809 | !arp_ignore(in_dev, sip, tip)) | 809 | !arp_ignore(in_dev, sip, tip)) |
810 | arp_send(ARPOP_REPLY, ETH_P_ARP, sip, dev, tip, sha, | 810 | arp_send(ARPOP_REPLY, ETH_P_ARP, sip, dev, tip, sha, |
811 | dev->dev_addr, sha); | 811 | dev->dev_addr, sha); |
@@ -815,7 +815,7 @@ static int arp_process(struct sk_buff *skb) | |||
815 | if (arp->ar_op == htons(ARPOP_REQUEST) && | 815 | if (arp->ar_op == htons(ARPOP_REQUEST) && |
816 | ip_route_input(skb, tip, sip, 0, dev) == 0) { | 816 | ip_route_input(skb, tip, sip, 0, dev) == 0) { |
817 | 817 | ||
818 | rt = (struct rtable*)skb->dst; | 818 | rt = skb->rtable; |
819 | addr_type = rt->rt_type; | 819 | addr_type = rt->rt_type; |
820 | 820 | ||
821 | if (addr_type == RTN_LOCAL) { | 821 | if (addr_type == RTN_LOCAL) { |
@@ -835,7 +835,7 @@ static int arp_process(struct sk_buff *skb) | |||
835 | goto out; | 835 | goto out; |
836 | } else if (IN_DEV_FORWARD(in_dev)) { | 836 | } else if (IN_DEV_FORWARD(in_dev)) { |
837 | if (addr_type == RTN_UNICAST && rt->u.dst.dev != dev && | 837 | if (addr_type == RTN_UNICAST && rt->u.dst.dev != dev && |
838 | (arp_fwd_proxy(in_dev, rt) || pneigh_lookup(&arp_tbl, &init_net, &tip, dev, 0))) { | 838 | (arp_fwd_proxy(in_dev, rt) || pneigh_lookup(&arp_tbl, net, &tip, dev, 0))) { |
839 | n = neigh_event_ns(&arp_tbl, sha, &sip, dev); | 839 | n = neigh_event_ns(&arp_tbl, sha, &sip, dev); |
840 | if (n) | 840 | if (n) |
841 | neigh_release(n); | 841 | neigh_release(n); |
@@ -858,14 +858,14 @@ static int arp_process(struct sk_buff *skb) | |||
858 | 858 | ||
859 | n = __neigh_lookup(&arp_tbl, &sip, dev, 0); | 859 | n = __neigh_lookup(&arp_tbl, &sip, dev, 0); |
860 | 860 | ||
861 | if (IPV4_DEVCONF_ALL(dev->nd_net, ARP_ACCEPT)) { | 861 | if (IPV4_DEVCONF_ALL(dev_net(dev), ARP_ACCEPT)) { |
862 | /* Unsolicited ARP is not accepted by default. | 862 | /* Unsolicited ARP is not accepted by default. |
863 | It is possible, that this option should be enabled for some | 863 | It is possible, that this option should be enabled for some |
864 | devices (strip is candidate) | 864 | devices (strip is candidate) |
865 | */ | 865 | */ |
866 | if (n == NULL && | 866 | if (n == NULL && |
867 | arp->ar_op == htons(ARPOP_REPLY) && | 867 | arp->ar_op == htons(ARPOP_REPLY) && |
868 | inet_addr_type(&init_net, sip) == RTN_UNICAST) | 868 | inet_addr_type(net, sip) == RTN_UNICAST) |
869 | n = __neigh_lookup(&arp_tbl, &sip, dev, 1); | 869 | n = __neigh_lookup(&arp_tbl, &sip, dev, 1); |
870 | } | 870 | } |
871 | 871 | ||
@@ -912,13 +912,8 @@ static int arp_rcv(struct sk_buff *skb, struct net_device *dev, | |||
912 | { | 912 | { |
913 | struct arphdr *arp; | 913 | struct arphdr *arp; |
914 | 914 | ||
915 | if (dev->nd_net != &init_net) | ||
916 | goto freeskb; | ||
917 | |||
918 | /* ARP header, plus 2 device addresses, plus 2 IP addresses. */ | 915 | /* ARP header, plus 2 device addresses, plus 2 IP addresses. */ |
919 | if (!pskb_may_pull(skb, (sizeof(struct arphdr) + | 916 | if (!pskb_may_pull(skb, arp_hdr_len(dev))) |
920 | (2 * dev->addr_len) + | ||
921 | (2 * sizeof(u32))))) | ||
922 | goto freeskb; | 917 | goto freeskb; |
923 | 918 | ||
924 | arp = arp_hdr(skb); | 919 | arp = arp_hdr(skb); |
@@ -1201,9 +1196,6 @@ static int arp_netdev_event(struct notifier_block *this, unsigned long event, vo | |||
1201 | { | 1196 | { |
1202 | struct net_device *dev = ptr; | 1197 | struct net_device *dev = ptr; |
1203 | 1198 | ||
1204 | if (dev->nd_net != &init_net) | ||
1205 | return NOTIFY_DONE; | ||
1206 | |||
1207 | switch (event) { | 1199 | switch (event) { |
1208 | case NETDEV_CHANGEADDR: | 1200 | case NETDEV_CHANGEADDR: |
1209 | neigh_changeaddr(&arp_tbl, dev); | 1201 | neigh_changeaddr(&arp_tbl, dev); |
@@ -1385,13 +1377,29 @@ static const struct file_operations arp_seq_fops = { | |||
1385 | .release = seq_release_net, | 1377 | .release = seq_release_net, |
1386 | }; | 1378 | }; |
1387 | 1379 | ||
1388 | static int __init arp_proc_init(void) | 1380 | |
1381 | static int __net_init arp_net_init(struct net *net) | ||
1389 | { | 1382 | { |
1390 | if (!proc_net_fops_create(&init_net, "arp", S_IRUGO, &arp_seq_fops)) | 1383 | if (!proc_net_fops_create(net, "arp", S_IRUGO, &arp_seq_fops)) |
1391 | return -ENOMEM; | 1384 | return -ENOMEM; |
1392 | return 0; | 1385 | return 0; |
1393 | } | 1386 | } |
1394 | 1387 | ||
1388 | static void __net_exit arp_net_exit(struct net *net) | ||
1389 | { | ||
1390 | proc_net_remove(net, "arp"); | ||
1391 | } | ||
1392 | |||
1393 | static struct pernet_operations arp_net_ops = { | ||
1394 | .init = arp_net_init, | ||
1395 | .exit = arp_net_exit, | ||
1396 | }; | ||
1397 | |||
1398 | static int __init arp_proc_init(void) | ||
1399 | { | ||
1400 | return register_pernet_subsys(&arp_net_ops); | ||
1401 | } | ||
1402 | |||
1395 | #else /* CONFIG_PROC_FS */ | 1403 | #else /* CONFIG_PROC_FS */ |
1396 | 1404 | ||
1397 | static int __init arp_proc_init(void) | 1405 | static int __init arp_proc_init(void) |