浏览代码

[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>
Daniel Lezcano 17 年之前
父节点
当前提交
a91275eff4
共有 2 个文件被更改,包括 29 次插入4 次删除
  1. 1 0
      include/net/udp.h
  2. 28 4
      net/ipv4/udp.c

+ 1 - 0
include/net/udp.h

@@ -192,6 +192,7 @@ struct udp_seq_afinfo {
 };
 };
 
 
 struct udp_iter_state {
 struct udp_iter_state {
+	struct net              *net;
 	sa_family_t		family;
 	sa_family_t		family;
 	struct hlist_head	*hashtable;
 	struct hlist_head	*hashtable;
 	int			bucket;
 	int			bucket;

+ 28 - 4
net/ipv4/udp.c

@@ -1512,10 +1512,13 @@ static struct sock *udp_get_first(struct seq_file *seq)
 {
 {
 	struct sock *sk;
 	struct sock *sk;
 	struct udp_iter_state *state = seq->private;
 	struct udp_iter_state *state = seq->private;
+	struct net *net = state->net;
 
 
 	for (state->bucket = 0; state->bucket < UDP_HTABLE_SIZE; ++state->bucket) {
 	for (state->bucket = 0; state->bucket < UDP_HTABLE_SIZE; ++state->bucket) {
 		struct hlist_node *node;
 		struct hlist_node *node;
 		sk_for_each(sk, node, state->hashtable + state->bucket) {
 		sk_for_each(sk, node, state->hashtable + state->bucket) {
+			if (sk->sk_net != net)
+				continue;
 			if (sk->sk_family == state->family)
 			if (sk->sk_family == state->family)
 				goto found;
 				goto found;
 		}
 		}
@@ -1528,12 +1531,13 @@ found:
 static struct sock *udp_get_next(struct seq_file *seq, struct sock *sk)
 static struct sock *udp_get_next(struct seq_file *seq, struct sock *sk)
 {
 {
 	struct udp_iter_state *state = seq->private;
 	struct udp_iter_state *state = seq->private;
+	struct net *net = state->net;
 
 
 	do {
 	do {
 		sk = sk_next(sk);
 		sk = sk_next(sk);
 try_again:
 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) {
 	if (!sk && ++state->bucket < UDP_HTABLE_SIZE) {
 		sk = sk_head(state->hashtable + state->bucket);
 		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 udp_seq_afinfo *afinfo = PDE(inode)->data;
 	struct seq_file *seq;
 	struct seq_file *seq;
+	struct net *net;
 	int rc = -ENOMEM;
 	int rc = -ENOMEM;
 	struct udp_iter_state *s = kzalloc(sizeof(*s), GFP_KERNEL);
 	struct udp_iter_state *s = kzalloc(sizeof(*s), GFP_KERNEL);
 
 
 	if (!s)
 	if (!s)
 		goto out;
 		goto out;
+
+	rc = -ENXIO;
+	net = get_proc_net(inode);
+	if (!net)
+		goto out_kfree;
+
 	s->family		= afinfo->family;
 	s->family		= afinfo->family;
 	s->hashtable		= afinfo->hashtable;
 	s->hashtable		= afinfo->hashtable;
 	s->seq_ops.start	= udp_seq_start;
 	s->seq_ops.start	= udp_seq_start;
 	s->seq_ops.next		= udp_seq_next;
 	s->seq_ops.next		= udp_seq_next;
 	s->seq_ops.show		= afinfo->seq_show;
 	s->seq_ops.show		= afinfo->seq_show;
 	s->seq_ops.stop		= udp_seq_stop;
 	s->seq_ops.stop		= udp_seq_stop;
+	s->net                  = net;
 
 
 	rc = seq_open(file, &s->seq_ops);
 	rc = seq_open(file, &s->seq_ops);
 	if (rc)
 	if (rc)
-		goto out_kfree;
+		goto out_put_net;
 
 
-	seq	     = file->private_data;
+	seq = file->private_data;
 	seq->private = s;
 	seq->private = s;
 out:
 out:
 	return rc;
 	return rc;
+out_put_net:
+	put_net(net);
 out_kfree:
 out_kfree:
 	kfree(s);
 	kfree(s);
 	goto out;
 	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)
 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->open		= udp_seq_open;
 	afinfo->seq_fops->read		= seq_read;
 	afinfo->seq_fops->read		= seq_read;
 	afinfo->seq_fops->llseek	= seq_lseek;
 	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);
 	p = proc_net_fops_create(&init_net, afinfo->name, S_IRUGO, afinfo->seq_fops);
 	if (p)
 	if (p)