aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDaniel Lezcano <dlezcano@fr.ibm.com>2008-03-21 07:13:54 -0400
committerDavid S. Miller <davem@davemloft.net>2008-03-21 07:13:54 -0400
commitf40c8174d3c21bf178283f3ef3aa8c7bf238fdec (patch)
treee82b56babcf523676ebfa420f35b3bc459d80986 /net
parent8d9f1744cab50acb0c6c9553be533621e01f178b (diff)
[NETNS][IPV4] tcp - make proc handle the network namespaces
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>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/tcp_ipv4.c44
1 files changed, 35 insertions, 9 deletions
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index a79e324638eb..f9b30dc3bd6c 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1948,6 +1948,7 @@ static void *listening_get_next(struct seq_file *seq, void *cur)
1948 struct hlist_node *node; 1948 struct hlist_node *node;
1949 struct sock *sk = cur; 1949 struct sock *sk = cur;
1950 struct tcp_iter_state* st = seq->private; 1950 struct tcp_iter_state* st = seq->private;
1951 struct net *net = st->net;
1951 1952
1952 if (!sk) { 1953 if (!sk) {
1953 st->bucket = 0; 1954 st->bucket = 0;
@@ -1964,7 +1965,8 @@ static void *listening_get_next(struct seq_file *seq, void *cur)
1964 req = req->dl_next; 1965 req = req->dl_next;
1965 while (1) { 1966 while (1) {
1966 while (req) { 1967 while (req) {
1967 if (req->rsk_ops->family == st->family) { 1968 if (req->rsk_ops->family == st->family &&
1969 req->sk->sk_net == net) {
1968 cur = req; 1970 cur = req;
1969 goto out; 1971 goto out;
1970 } 1972 }
@@ -1988,7 +1990,7 @@ get_req:
1988 } 1990 }
1989get_sk: 1991get_sk:
1990 sk_for_each_from(sk, node) { 1992 sk_for_each_from(sk, node) {
1991 if (sk->sk_family == st->family) { 1993 if (sk->sk_family == st->family && sk->sk_net == net) {
1992 cur = sk; 1994 cur = sk;
1993 goto out; 1995 goto out;
1994 } 1996 }
@@ -2027,6 +2029,7 @@ static void *listening_get_idx(struct seq_file *seq, loff_t *pos)
2027static void *established_get_first(struct seq_file *seq) 2029static void *established_get_first(struct seq_file *seq)
2028{ 2030{
2029 struct tcp_iter_state* st = seq->private; 2031 struct tcp_iter_state* st = seq->private;
2032 struct net *net = st->net;
2030 void *rc = NULL; 2033 void *rc = NULL;
2031 2034
2032 for (st->bucket = 0; st->bucket < tcp_hashinfo.ehash_size; ++st->bucket) { 2035 for (st->bucket = 0; st->bucket < tcp_hashinfo.ehash_size; ++st->bucket) {
@@ -2037,7 +2040,8 @@ static void *established_get_first(struct seq_file *seq)
2037 2040
2038 read_lock_bh(lock); 2041 read_lock_bh(lock);
2039 sk_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) { 2042 sk_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) {
2040 if (sk->sk_family != st->family) { 2043 if (sk->sk_family != st->family ||
2044 sk->sk_net != net) {
2041 continue; 2045 continue;
2042 } 2046 }
2043 rc = sk; 2047 rc = sk;
@@ -2046,7 +2050,8 @@ static void *established_get_first(struct seq_file *seq)
2046 st->state = TCP_SEQ_STATE_TIME_WAIT; 2050 st->state = TCP_SEQ_STATE_TIME_WAIT;
2047 inet_twsk_for_each(tw, node, 2051 inet_twsk_for_each(tw, node,
2048 &tcp_hashinfo.ehash[st->bucket].twchain) { 2052 &tcp_hashinfo.ehash[st->bucket].twchain) {
2049 if (tw->tw_family != st->family) { 2053 if (tw->tw_family != st->family &&
2054 tw->tw_net != net) {
2050 continue; 2055 continue;
2051 } 2056 }
2052 rc = tw; 2057 rc = tw;
@@ -2065,6 +2070,7 @@ static void *established_get_next(struct seq_file *seq, void *cur)
2065 struct inet_timewait_sock *tw; 2070 struct inet_timewait_sock *tw;
2066 struct hlist_node *node; 2071 struct hlist_node *node;
2067 struct tcp_iter_state* st = seq->private; 2072 struct tcp_iter_state* st = seq->private;
2073 struct net *net = st->net;
2068 2074
2069 ++st->num; 2075 ++st->num;
2070 2076
@@ -2072,7 +2078,7 @@ static void *established_get_next(struct seq_file *seq, void *cur)
2072 tw = cur; 2078 tw = cur;
2073 tw = tw_next(tw); 2079 tw = tw_next(tw);
2074get_tw: 2080get_tw:
2075 while (tw && tw->tw_family != st->family) { 2081 while (tw && tw->tw_family != st->family && tw->tw_net != net) {
2076 tw = tw_next(tw); 2082 tw = tw_next(tw);
2077 } 2083 }
2078 if (tw) { 2084 if (tw) {
@@ -2093,7 +2099,7 @@ get_tw:
2093 sk = sk_next(sk); 2099 sk = sk_next(sk);
2094 2100
2095 sk_for_each_from(sk, node) { 2101 sk_for_each_from(sk, node) {
2096 if (sk->sk_family == st->family) 2102 if (sk->sk_family == st->family && sk->sk_net == net)
2097 goto found; 2103 goto found;
2098 } 2104 }
2099 2105
@@ -2201,6 +2207,7 @@ static int tcp_seq_open(struct inode *inode, struct file *file)
2201 struct tcp_seq_afinfo *afinfo = PDE(inode)->data; 2207 struct tcp_seq_afinfo *afinfo = PDE(inode)->data;
2202 struct seq_file *seq; 2208 struct seq_file *seq;
2203 struct tcp_iter_state *s; 2209 struct tcp_iter_state *s;
2210 struct net *net;
2204 int rc; 2211 int rc;
2205 2212
2206 if (unlikely(afinfo == NULL)) 2213 if (unlikely(afinfo == NULL))
@@ -2209,24 +2216,43 @@ static int tcp_seq_open(struct inode *inode, struct file *file)
2209 s = kzalloc(sizeof(*s), GFP_KERNEL); 2216 s = kzalloc(sizeof(*s), GFP_KERNEL);
2210 if (!s) 2217 if (!s)
2211 return -ENOMEM; 2218 return -ENOMEM;
2219
2220 rc = -ENXIO;
2221 net = get_proc_net(inode);
2222 if (!net)
2223 goto out_kfree;
2224
2212 s->family = afinfo->family; 2225 s->family = afinfo->family;
2213 s->seq_ops.start = tcp_seq_start; 2226 s->seq_ops.start = tcp_seq_start;
2214 s->seq_ops.next = tcp_seq_next; 2227 s->seq_ops.next = tcp_seq_next;
2215 s->seq_ops.show = afinfo->seq_show; 2228 s->seq_ops.show = afinfo->seq_show;
2216 s->seq_ops.stop = tcp_seq_stop; 2229 s->seq_ops.stop = tcp_seq_stop;
2230 s->net = net;
2217 2231
2218 rc = seq_open(file, &s->seq_ops); 2232 rc = seq_open(file, &s->seq_ops);
2219 if (rc) 2233 if (rc)
2220 goto out_kfree; 2234 goto out_put_net;
2221 seq = file->private_data; 2235 seq = file->private_data;
2222 seq->private = s; 2236 seq->private = s;
2223out: 2237out:
2224 return rc; 2238 return rc;
2239out_put_net:
2240 put_net(net);
2225out_kfree: 2241out_kfree:
2226 kfree(s); 2242 kfree(s);
2227 goto out; 2243 goto out;
2228} 2244}
2229 2245
2246static int tcp_seq_release(struct inode *inode, struct file *file)
2247{
2248 struct seq_file *seq = file->private_data;
2249 struct tcp_iter_state *s = seq->private;
2250
2251 put_net(s->net);
2252 seq_release_private(inode, file);
2253 return 0;
2254}
2255
2230int tcp_proc_register(struct tcp_seq_afinfo *afinfo) 2256int tcp_proc_register(struct tcp_seq_afinfo *afinfo)
2231{ 2257{
2232 int rc = 0; 2258 int rc = 0;
@@ -2238,7 +2264,7 @@ int tcp_proc_register(struct tcp_seq_afinfo *afinfo)
2238 afinfo->seq_fops->open = tcp_seq_open; 2264 afinfo->seq_fops->open = tcp_seq_open;
2239 afinfo->seq_fops->read = seq_read; 2265 afinfo->seq_fops->read = seq_read;
2240 afinfo->seq_fops->llseek = seq_lseek; 2266 afinfo->seq_fops->llseek = seq_lseek;
2241 afinfo->seq_fops->release = seq_release_private; 2267 afinfo->seq_fops->release = tcp_seq_release;
2242 2268
2243 p = proc_net_fops_create(&init_net, afinfo->name, S_IRUGO, afinfo->seq_fops); 2269 p = proc_net_fops_create(&init_net, afinfo->name, S_IRUGO, afinfo->seq_fops);
2244 if (p) 2270 if (p)