aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/arp.c
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2008-01-24 03:13:18 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 18:00:03 -0500
commit426b5303eb435d98b9bee37a807be386bc2b3320 (patch)
tree86f7bd945101d9ac51afb22a210d22b8ff956a4e /net/ipv4/arp.c
parente1af9f270b69a3ad1dcbabb404dd1f40a96f43f5 (diff)
[NETNS]: Modify the neighbour table code so it handles multiple network namespaces
I'm actually surprised at how much was involved. At first glance it appears that the neighbour table data structures are already split by network device so all that should be needed is to modify the user interface commands to filter the set of neighbours by the network namespace of their devices. However a couple things turned up while I was reading through the code. The proxy neighbour table allows entries with no network device, and the neighbour parms are per network device (except for the defaults) so they now need a per network namespace default. So I updated the two structures (which surprised me) with their very own network namespace parameter. Updated the relevant lookup and destroy routines with a network namespace parameter and modified the code that interacts with users to filter out neighbour table entries for devices of other namespaces. I'm a little concerned that we can modify and display the global table configuration and from all network namespaces. But this appears good enough for now. I keep thinking modifying the neighbour table to have per network namespace instances of each table type would should be cleaner. The hash table is already dynamically sized so there are it is not a limiter. The default parameter would be straight forward to take care of. However when I look at the how the network table is built and used I still find some assumptions that there is only a single neighbour table for each type of table in the kernel. The netlink operations, neigh_seq_start, the non-core network users that call neigh_lookup. So while it might be doable it would require more refactoring than my current approach of just doing a little extra filtering in the code. Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/arp.c')
-rw-r--r--net/ipv4/arp.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index fdf12d1c350e..9eb6d3ab2977 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -837,7 +837,7 @@ static int arp_process(struct sk_buff *skb)
837 } else if (IN_DEV_FORWARD(in_dev)) { 837 } else if (IN_DEV_FORWARD(in_dev)) {
838 if ((rt->rt_flags&RTCF_DNAT) || 838 if ((rt->rt_flags&RTCF_DNAT) ||
839 (addr_type == RTN_UNICAST && rt->u.dst.dev != dev && 839 (addr_type == RTN_UNICAST && rt->u.dst.dev != dev &&
840 (arp_fwd_proxy(in_dev, rt) || pneigh_lookup(&arp_tbl, &tip, dev, 0)))) { 840 (arp_fwd_proxy(in_dev, rt) || pneigh_lookup(&arp_tbl, &init_net, &tip, dev, 0)))) {
841 n = neigh_event_ns(&arp_tbl, sha, &sip, dev); 841 n = neigh_event_ns(&arp_tbl, sha, &sip, dev);
842 if (n) 842 if (n)
843 neigh_release(n); 843 neigh_release(n);
@@ -980,7 +980,7 @@ static int arp_req_set_public(struct net *net, struct arpreq *r,
980 return -ENODEV; 980 return -ENODEV;
981 } 981 }
982 if (mask) { 982 if (mask) {
983 if (pneigh_lookup(&arp_tbl, &ip, dev, 1) == NULL) 983 if (pneigh_lookup(&arp_tbl, &init_net, &ip, dev, 1) == NULL)
984 return -ENOBUFS; 984 return -ENOBUFS;
985 return 0; 985 return 0;
986 } 986 }
@@ -1089,7 +1089,7 @@ static int arp_req_delete_public(struct net *net, struct arpreq *r,
1089 __be32 mask = ((struct sockaddr_in *)&r->arp_netmask)->sin_addr.s_addr; 1089 __be32 mask = ((struct sockaddr_in *)&r->arp_netmask)->sin_addr.s_addr;
1090 1090
1091 if (mask == htonl(0xFFFFFFFF)) 1091 if (mask == htonl(0xFFFFFFFF))
1092 return pneigh_delete(&arp_tbl, &ip, dev); 1092 return pneigh_delete(&arp_tbl, &init_net, &ip, dev);
1093 1093
1094 if (mask) 1094 if (mask)
1095 return -EINVAL; 1095 return -EINVAL;
@@ -1375,8 +1375,8 @@ static const struct seq_operations arp_seq_ops = {
1375 1375
1376static int arp_seq_open(struct inode *inode, struct file *file) 1376static int arp_seq_open(struct inode *inode, struct file *file)
1377{ 1377{
1378 return seq_open_private(file, &arp_seq_ops, 1378 return seq_open_net(inode, file, &arp_seq_ops,
1379 sizeof(struct neigh_seq_state)); 1379 sizeof(struct neigh_seq_state));
1380} 1380}
1381 1381
1382static const struct file_operations arp_seq_fops = { 1382static const struct file_operations arp_seq_fops = {
@@ -1384,7 +1384,7 @@ static const struct file_operations arp_seq_fops = {
1384 .open = arp_seq_open, 1384 .open = arp_seq_open,
1385 .read = seq_read, 1385 .read = seq_read,
1386 .llseek = seq_lseek, 1386 .llseek = seq_lseek,
1387 .release = seq_release_private, 1387 .release = seq_release_net,
1388}; 1388};
1389 1389
1390static int __init arp_proc_init(void) 1390static int __init arp_proc_init(void)