aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/udp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/udp.c')
-rw-r--r--net/ipv4/udp.c32
1 files changed, 28 insertions, 4 deletions
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)