Skip to content

Commit

Permalink
[NETNS][IPV4] tcp - make proc handle the network namespaces
Browse files Browse the repository at this point in the history
This patch, like udp proc, makes the proc functions to take care of
which namespace the socket 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 8d9f174 commit f40c817
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 9 deletions.
1 change: 1 addition & 0 deletions include/net/tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -1328,6 +1328,7 @@ struct tcp_seq_afinfo {
};

struct tcp_iter_state {
struct net *net;
sa_family_t family;
enum tcp_seq_states state;
struct sock *syn_wait_sk;
Expand Down
44 changes: 35 additions & 9 deletions net/ipv4/tcp_ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -1948,6 +1948,7 @@ static void *listening_get_next(struct seq_file *seq, void *cur)
struct hlist_node *node;
struct sock *sk = cur;
struct tcp_iter_state* st = seq->private;
struct net *net = st->net;

if (!sk) {
st->bucket = 0;
Expand All @@ -1964,7 +1965,8 @@ static void *listening_get_next(struct seq_file *seq, void *cur)
req = req->dl_next;
while (1) {
while (req) {
if (req->rsk_ops->family == st->family) {
if (req->rsk_ops->family == st->family &&
req->sk->sk_net == net) {
cur = req;
goto out;
}
Expand All @@ -1988,7 +1990,7 @@ static void *listening_get_next(struct seq_file *seq, void *cur)
}
get_sk:
sk_for_each_from(sk, node) {
if (sk->sk_family == st->family) {
if (sk->sk_family == st->family && sk->sk_net == net) {
cur = sk;
goto out;
}
Expand Down Expand Up @@ -2027,6 +2029,7 @@ static void *listening_get_idx(struct seq_file *seq, loff_t *pos)
static void *established_get_first(struct seq_file *seq)
{
struct tcp_iter_state* st = seq->private;
struct net *net = st->net;
void *rc = NULL;

for (st->bucket = 0; st->bucket < tcp_hashinfo.ehash_size; ++st->bucket) {
Expand All @@ -2037,7 +2040,8 @@ static void *established_get_first(struct seq_file *seq)

read_lock_bh(lock);
sk_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) {
if (sk->sk_family != st->family) {
if (sk->sk_family != st->family ||
sk->sk_net != net) {
continue;
}
rc = sk;
Expand All @@ -2046,7 +2050,8 @@ static void *established_get_first(struct seq_file *seq)
st->state = TCP_SEQ_STATE_TIME_WAIT;
inet_twsk_for_each(tw, node,
&tcp_hashinfo.ehash[st->bucket].twchain) {
if (tw->tw_family != st->family) {
if (tw->tw_family != st->family &&
tw->tw_net != net) {
continue;
}
rc = tw;
Expand All @@ -2065,14 +2070,15 @@ static void *established_get_next(struct seq_file *seq, void *cur)
struct inet_timewait_sock *tw;
struct hlist_node *node;
struct tcp_iter_state* st = seq->private;
struct net *net = st->net;

++st->num;

if (st->state == TCP_SEQ_STATE_TIME_WAIT) {
tw = cur;
tw = tw_next(tw);
get_tw:
while (tw && tw->tw_family != st->family) {
while (tw && tw->tw_family != st->family && tw->tw_net != net) {
tw = tw_next(tw);
}
if (tw) {
Expand All @@ -2093,7 +2099,7 @@ static void *established_get_next(struct seq_file *seq, void *cur)
sk = sk_next(sk);

sk_for_each_from(sk, node) {
if (sk->sk_family == st->family)
if (sk->sk_family == st->family && sk->sk_net == net)
goto found;
}

Expand Down Expand Up @@ -2201,6 +2207,7 @@ static int tcp_seq_open(struct inode *inode, struct file *file)
struct tcp_seq_afinfo *afinfo = PDE(inode)->data;
struct seq_file *seq;
struct tcp_iter_state *s;
struct net *net;
int rc;

if (unlikely(afinfo == NULL))
Expand All @@ -2209,24 +2216,43 @@ static int tcp_seq_open(struct inode *inode, struct file *file)
s = kzalloc(sizeof(*s), GFP_KERNEL);
if (!s)
return -ENOMEM;

rc = -ENXIO;
net = get_proc_net(inode);
if (!net)
goto out_kfree;

s->family = afinfo->family;
s->seq_ops.start = tcp_seq_start;
s->seq_ops.next = tcp_seq_next;
s->seq_ops.show = afinfo->seq_show;
s->seq_ops.stop = tcp_seq_stop;
s->net = net;

rc = seq_open(file, &s->seq_ops);
if (rc)
goto out_kfree;
seq = file->private_data;
goto out_put_net;
seq = file->private_data;
seq->private = s;
out:
return rc;
out_put_net:
put_net(net);
out_kfree:
kfree(s);
goto out;
}

static int tcp_seq_release(struct inode *inode, struct file *file)
{
struct seq_file *seq = file->private_data;
struct tcp_iter_state *s = seq->private;

put_net(s->net);
seq_release_private(inode, file);
return 0;
}

int tcp_proc_register(struct tcp_seq_afinfo *afinfo)
{
int rc = 0;
Expand All @@ -2238,7 +2264,7 @@ int tcp_proc_register(struct tcp_seq_afinfo *afinfo)
afinfo->seq_fops->open = tcp_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 = tcp_seq_release;

p = proc_net_fops_create(&init_net, afinfo->name, S_IRUGO, afinfo->seq_fops);
if (p)
Expand Down

0 comments on commit f40c817

Please sign in to comment.