aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Lezcano <dlezcano@fr.ibm.com>2008-03-21 07:11:58 -0400
committerDavid S. Miller <davem@davemloft.net>2008-03-21 07:11:58 -0400
commita91275eff43a527e1a25d6d034cbcd19ee323e64 (patch)
treeb4cb01b2bc5da9d5631be2eabab64671fdf766af
parentea82edf704f6bf3c3a51d0dbee816c5bbc6d3974 (diff)
[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 {
192}; 192};
193 193
194struct udp_iter_state { 194struct udp_iter_state {
195 struct net *net;
195 sa_family_t family; 196 sa_family_t family;
196 struct hlist_head *hashtable; 197 struct hlist_head *hashtable;
197 int bucket; 198 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)
1512{ 1512{
1513 struct sock *sk; 1513 struct sock *sk;
1514 struct udp_iter_state *state = seq->private; 1514 struct udp_iter_state *state = seq->private;
1515 struct net *net = state->net;
1515 1516
1516 for (state->bucket = 0; state->bucket < UDP_HTABLE_SIZE; ++state->bucket) { 1517 for (state->bucket = 0; state->bucket < UDP_HTABLE_SIZE; ++state->bucket) {
1517 struct hlist_node *node; 1518 struct hlist_node *node;
1518 sk_for_each(sk, node, state->hashtable + state->bucket) { 1519 sk_for_each(sk, node, state->hashtable + state->bucket) {
1520 if (sk->sk_net != net)
1521 continue;
1519 if (sk->sk_family == state->family) 1522 if (sk->sk_family == state->family)
1520 goto found; 1523 goto found;
1521 } 1524 }
@@ -1528,12 +1531,13 @@ found:
1528static struct sock *udp_get_next(struct seq_file *seq, struct sock *sk) 1531static struct sock *udp_get_next(struct seq_file *seq, struct sock *sk)
1529{ 1532{
1530 struct udp_iter_state *state = seq->private; 1533 struct udp_iter_state *state = seq->private;
1534 struct net *net = state->net;
1531 1535
1532 do { 1536 do {
1533 sk = sk_next(sk); 1537 sk = sk_next(sk);
1534try_again: 1538try_again:
1535 ; 1539 ;
1536 } while (sk && sk->sk_family != state->family); 1540 } while (sk && sk->sk_net != net && sk->sk_family != state->family);
1537 1541
1538 if (!sk && ++state->bucket < UDP_HTABLE_SIZE) { 1542 if (!sk && ++state->bucket < UDP_HTABLE_SIZE) {
1539 sk = sk_head(state->hashtable + state->bucket); 1543 sk = sk_head(state->hashtable + state->bucket);
@@ -1582,31 +1586,51 @@ static int udp_seq_open(struct inode *inode, struct file *file)
1582{ 1586{
1583 struct udp_seq_afinfo *afinfo = PDE(inode)->data; 1587 struct udp_seq_afinfo *afinfo = PDE(inode)->data;
1584 struct seq_file *seq; 1588 struct seq_file *seq;
1589 struct net *net;
1585 int rc = -ENOMEM; 1590 int rc = -ENOMEM;
1586 struct udp_iter_state *s = kzalloc(sizeof(*s), GFP_KERNEL); 1591 struct udp_iter_state *s = kzalloc(sizeof(*s), GFP_KERNEL);
1587 1592
1588 if (!s) 1593 if (!s)
1589 goto out; 1594 goto out;
1595
1596 rc = -ENXIO;
1597 net = get_proc_net(inode);
1598 if (!net)
1599 goto out_kfree;
1600
1590 s->family = afinfo->family; 1601 s->family = afinfo->family;
1591 s->hashtable = afinfo->hashtable; 1602 s->hashtable = afinfo->hashtable;
1592 s->seq_ops.start = udp_seq_start; 1603 s->seq_ops.start = udp_seq_start;
1593 s->seq_ops.next = udp_seq_next; 1604 s->seq_ops.next = udp_seq_next;
1594 s->seq_ops.show = afinfo->seq_show; 1605 s->seq_ops.show = afinfo->seq_show;
1595 s->seq_ops.stop = udp_seq_stop; 1606 s->seq_ops.stop = udp_seq_stop;
1607 s->net = net;
1596 1608
1597 rc = seq_open(file, &s->seq_ops); 1609 rc = seq_open(file, &s->seq_ops);
1598 if (rc) 1610 if (rc)
1599 goto out_kfree; 1611 goto out_put_net;
1600 1612
1601 seq = file->private_data; 1613 seq = file->private_data;
1602 seq->private = s; 1614 seq->private = s;
1603out: 1615out:
1604 return rc; 1616 return rc;
1617out_put_net:
1618 put_net(net);
1605out_kfree: 1619out_kfree:
1606 kfree(s); 1620 kfree(s);
1607 goto out; 1621 goto out;
1608} 1622}
1609 1623
1624static int udp_seq_release(struct inode *inode, struct file *file)
1625{
1626 struct seq_file *seq = file->private_data;
1627 struct udp_iter_state *s = seq->private;
1628
1629 put_net(s->net);
1630 seq_release_private(inode, file);
1631 return 0;
1632}
1633
1610/* ------------------------------------------------------------------------ */ 1634/* ------------------------------------------------------------------------ */
1611int udp_proc_register(struct udp_seq_afinfo *afinfo) 1635int udp_proc_register(struct udp_seq_afinfo *afinfo)
1612{ 1636{
@@ -1619,7 +1643,7 @@ int udp_proc_register(struct udp_seq_afinfo *afinfo)
1619 afinfo->seq_fops->open = udp_seq_open; 1643 afinfo->seq_fops->open = udp_seq_open;
1620 afinfo->seq_fops->read = seq_read; 1644 afinfo->seq_fops->read = seq_read;
1621 afinfo->seq_fops->llseek = seq_lseek; 1645 afinfo->seq_fops->llseek = seq_lseek;
1622 afinfo->seq_fops->release = seq_release_private; 1646 afinfo->seq_fops->release = udp_seq_release;
1623 1647
1624 p = proc_net_fops_create(&init_net, afinfo->name, S_IRUGO, afinfo->seq_fops); 1648 p = proc_net_fops_create(&init_net, afinfo->name, S_IRUGO, afinfo->seq_fops);
1625 if (p) 1649 if (p)