aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDenis V. Lunev <den@openvz.org>2008-03-24 18:28:12 -0400
committerDavid S. Miller <davem@davemloft.net>2008-03-24 18:28:12 -0400
commit49e8a279a1b79e14b51aa6d4102b3a3de39e7a5e (patch)
tree525cdb6a1f31e5ad32bc7d7ce8e4e8d9476a5af8 /net
parent2feb27dbe00cbb4f7d31f90acf6bd0d751dd0a50 (diff)
[NETNS]: Process ARP in the context of the correct namespace.
Get namespace from a device and pass it to the routing engine. Enable ARP packet processing and device notifiers after that. Signed-off-by: Denis V. Lunev <den@openvz.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/arp.c23
1 files changed, 9 insertions, 14 deletions
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index efe01df8fc0e..6d90ec524212 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->nd_net, 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->nd_net, 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->nd_net, 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->nd_net, &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);
@@ -477,7 +477,7 @@ int arp_find(unsigned char *haddr, struct sk_buff *skb)
477 477
478 paddr = skb->rtable->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->nd_net, 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);
@@ -709,6 +709,7 @@ static int arp_process(struct sk_buff *skb)
709 u16 dev_type = dev->type; 709 u16 dev_type = dev->type;
710 int addr_type; 710 int addr_type;
711 struct neighbour *n; 711 struct neighbour *n;
712 struct net *net = dev->nd_net;
712 713
713 /* arp_rcv below verifies the ARP header and verifies the device 714 /* arp_rcv below verifies the ARP header and verifies the device
714 * is ARP'able. 715 * is ARP'able.
@@ -804,7 +805,7 @@ static int arp_process(struct sk_buff *skb)
804 /* Special case: IPv4 duplicate address detection packet (RFC2131) */ 805 /* Special case: IPv4 duplicate address detection packet (RFC2131) */
805 if (sip == 0) { 806 if (sip == 0) {
806 if (arp->ar_op == htons(ARPOP_REQUEST) && 807 if (arp->ar_op == htons(ARPOP_REQUEST) &&
807 inet_addr_type(&init_net, tip) == RTN_LOCAL && 808 inet_addr_type(net, tip) == RTN_LOCAL &&
808 !arp_ignore(in_dev, sip, tip)) 809 !arp_ignore(in_dev, sip, tip))
809 arp_send(ARPOP_REPLY, ETH_P_ARP, sip, dev, tip, sha, 810 arp_send(ARPOP_REPLY, ETH_P_ARP, sip, dev, tip, sha,
810 dev->dev_addr, sha); 811 dev->dev_addr, sha);
@@ -834,7 +835,7 @@ static int arp_process(struct sk_buff *skb)
834 goto out; 835 goto out;
835 } else if (IN_DEV_FORWARD(in_dev)) { 836 } else if (IN_DEV_FORWARD(in_dev)) {
836 if (addr_type == RTN_UNICAST && rt->u.dst.dev != dev && 837 if (addr_type == RTN_UNICAST && rt->u.dst.dev != dev &&
837 (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))) {
838 n = neigh_event_ns(&arp_tbl, sha, &sip, dev); 839 n = neigh_event_ns(&arp_tbl, sha, &sip, dev);
839 if (n) 840 if (n)
840 neigh_release(n); 841 neigh_release(n);
@@ -864,7 +865,7 @@ static int arp_process(struct sk_buff *skb)
864 */ 865 */
865 if (n == NULL && 866 if (n == NULL &&
866 arp->ar_op == htons(ARPOP_REPLY) && 867 arp->ar_op == htons(ARPOP_REPLY) &&
867 inet_addr_type(&init_net, sip) == RTN_UNICAST) 868 inet_addr_type(net, sip) == RTN_UNICAST)
868 n = __neigh_lookup(&arp_tbl, &sip, dev, 1); 869 n = __neigh_lookup(&arp_tbl, &sip, dev, 1);
869 } 870 }
870 871
@@ -911,9 +912,6 @@ static int arp_rcv(struct sk_buff *skb, struct net_device *dev,
911{ 912{
912 struct arphdr *arp; 913 struct arphdr *arp;
913 914
914 if (dev->nd_net != &init_net)
915 goto freeskb;
916
917 /* ARP header, plus 2 device addresses, plus 2 IP addresses. */ 915 /* ARP header, plus 2 device addresses, plus 2 IP addresses. */
918 if (!pskb_may_pull(skb, arp_hdr_len(dev))) 916 if (!pskb_may_pull(skb, arp_hdr_len(dev)))
919 goto freeskb; 917 goto freeskb;
@@ -1198,9 +1196,6 @@ static int arp_netdev_event(struct notifier_block *this, unsigned long event, vo
1198{ 1196{
1199 struct net_device *dev = ptr; 1197 struct net_device *dev = ptr;
1200 1198
1201 if (dev->nd_net != &init_net)
1202 return NOTIFY_DONE;
1203
1204 switch (event) { 1199 switch (event) {
1205 case NETDEV_CHANGEADDR: 1200 case NETDEV_CHANGEADDR:
1206 neigh_changeaddr(&arp_tbl, dev); 1201 neigh_changeaddr(&arp_tbl, dev);