Skip to content

Commit

Permalink
[NETNS][IPV6] udp - make proc handle the network namespace
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Daniel Lezcano authored and David S. Miller committed Mar 21, 2008
1 parent ea82edf commit a91275e
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 4 deletions.
1 change: 1 addition & 0 deletions include/net/udp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
32 changes: 28 additions & 4 deletions net/ipv4/udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -1528,12 +1531,13 @@ static struct sock *udp_get_first(struct seq_file *seq)
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);
Expand Down Expand Up @@ -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)
{
Expand All @@ -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)
Expand Down

0 comments on commit a91275e

Please sign in to comment.