diff options
author | Daniel Lezcano <dlezcano@fr.ibm.com> | 2008-03-21 07:13:54 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-03-21 07:13:54 -0400 |
commit | f40c8174d3c21bf178283f3ef3aa8c7bf238fdec (patch) | |
tree | e82b56babcf523676ebfa420f35b3bc459d80986 /net | |
parent | 8d9f1744cab50acb0c6c9553be533621e01f178b (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.c | 44 |
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 | } |
1989 | get_sk: | 1991 | get_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) | |||
2027 | static void *established_get_first(struct seq_file *seq) | 2029 | static 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); |
2074 | get_tw: | 2080 | get_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; |
2223 | out: | 2237 | out: |
2224 | return rc; | 2238 | return rc; |
2239 | out_put_net: | ||
2240 | put_net(net); | ||
2225 | out_kfree: | 2241 | out_kfree: |
2226 | kfree(s); | 2242 | kfree(s); |
2227 | goto out; | 2243 | goto out; |
2228 | } | 2244 | } |
2229 | 2245 | ||
2246 | static 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 | |||
2230 | int tcp_proc_register(struct tcp_seq_afinfo *afinfo) | 2256 | int 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) |