summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Lezcano <dlezcano@fr.ibm.com>2008-03-21 04:11:58 -0700
committerDavid S. Miller <davem@davemloft.net>2008-03-21 04:11:58 -0700
commita91275eff43a527e1a25d6d034cbcd19ee323e64 (patch)
treeb4cb01b2bc5da9d5631be2eabab64671fdf766af
parentea82edf704f6bf3c3a51d0dbee816c5bbc6d3974 (diff)
downloadlinux-a91275eff43a527e1a25d6d034cbcd19ee323e64.tar.bz2
[NETNS][IPV6] udp - make proc handle the network namespace
This patch makes the common udp proc functions to take care of which socket they should show taking into account the namespace it belongs. Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/udp.h1
-rw-r--r--net/ipv4/udp.c32
2 files changed, 29 insertions, 4 deletions
diff --git a/include/net/udp.h b/include/net/udp.h
index c6669c0a74c7..a1b33d667199 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -192,6 +192,7 @@ struct udp_seq_afinfo {
};
struct udp_iter_state {
+ struct net *net;
sa_family_t family;
struct hlist_head *hashtable;
int bucket;
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 7ea1b67b6de1..049e92519616 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1512,10 +1512,13 @@ static struct sock *udp_get_first(struct seq_file *seq)
{
struct sock *sk;
struct udp_iter_state *state = seq->private;
+ struct net *net = state->net;
for (state->bucket = 0; state->bucket < UDP_HTABLE_SIZE; ++state->bucket) {
struct hlist_node *node;
sk_for_each(sk, node, state->hashtable + state->bucket) {
+ if (sk->sk_net != net)
+ continue;
if (sk->sk_family == state->family)
goto found;
}
@@ -1528,12 +1531,13 @@ found:
static struct sock *udp_get_next(struct seq_file *seq, struct sock *sk)
{
struct udp_iter_state *state = seq->private;
+ struct net *net = state->net;
do {
sk = sk_next(sk);
try_again:
;
- } while (sk && sk->sk_family != state->family);
+ } while (sk && sk->sk_net != net && sk->sk_family != state->family);
if (!sk && ++state->bucket < UDP_HTABLE_SIZE) {
sk = sk_head(state->hashtable + state->bucket);
@@ -1582,31 +1586,51 @@ static int udp_seq_open(struct inode *inode, struct file *file)
{
struct udp_seq_afinfo *afinfo = PDE(inode)->data;
struct seq_file *seq;
+ struct net *net;
int rc = -ENOMEM;
struct udp_iter_state *s = kzalloc(sizeof(*s), GFP_KERNEL);
if (!s)
goto out;
+
+ rc = -ENXIO;
+ net = get_proc_net(inode);
+ if (!net)
+ goto out_kfree;
+
s->family = afinfo->family;
s->hashtable = afinfo->hashtable;
s->seq_ops.start = udp_seq_start;
s->seq_ops.next = udp_seq_next;
s->seq_ops.show = afinfo->seq_show;
s->seq_ops.stop = udp_seq_stop;
+ s->net = net;
rc = seq_open(file, &s->seq_ops);
if (rc)
- goto out_kfree;
+ goto out_put_net;
- seq = file->private_data;
+ seq = file->private_data;
seq->private = s;
out:
return rc;
+out_put_net:
+ put_net(net);
out_kfree:
kfree(s);
goto out;
}
+static int udp_seq_release(struct inode *inode, struct file *file)
+{
+ struct seq_file *seq = file->private_data;
+ struct udp_iter_state *s = seq->private;
+
+ put_net(s->net);
+ seq_release_private(inode, file);
+ return 0;
+}
+
/* ------------------------------------------------------------------------ */
int udp_proc_register(struct udp_seq_afinfo *afinfo)
{
@@ -1619,7 +1643,7 @@ int udp_proc_register(struct udp_seq_afinfo *afinfo)
afinfo->seq_fops->open = udp_seq_open;
afinfo->seq_fops->read = seq_read;
afinfo->seq_fops->llseek = seq_lseek;
- afinfo->seq_fops->release = seq_release_private;
+ afinfo->seq_fops->release = udp_seq_release;
p = proc_net_fops_create(&init_net, afinfo->name, S_IRUGO, afinfo->seq_fops);
if (p)