Messages in this thread Patch in this message | | | From | Tim Shepard <> | Subject | Re: [PATCH] fix numbering of lines in /proc/net/tcp (linux-2.6.0-test7) | Date | Tue, 14 Oct 2003 14:14:52 -0400 |
| |
> > > I am not sure what the behavior is supposed to be. Is there a spec > > > anywhere for the interface with /proc/net/tcp? > > > > Yes, I think the original is okay because the bucket is shared between > > tcp6 and tcp4, and I don't want to change this behavior in 2.6 from 2.4.x. > > (so, we need to fix 2.6.x.) > > In the meantime I've applied Tim's patch because it is definitely > a step in the right direction and the current 2.6.x behavior makes > no sense at all :-)
Ok, that makes good sense to me.
> We can add a fix on top to make 2.6.x behave more closely to 2.4.x > (by sharing numbers between v4 and v6). If that proves to be very > difficult to do, it's not absolutely critical to preserve this behavior > I think.
Whoever dives in and fixes this (i.e. makes the linux-2.6 behavior exactly match linux-2.4 behavior) may want to start with a copy of net/ipv4/tcp_ipv4.c from 2.6.0-test7 without that patch applied because that patch rips out bits of code that was trying to increment st->num whenever sk->sk_family does not match st->family. Some of those bits of code will need to reappear to make linux-2.6 match linux-2.4 behavior. (Note, the patch below might contain some clues.)
When testing this stuff, you need to make sure that there is no dependence upon the buffer size that the user mode program is using to read from /proc/net/tcp and /proc/net/tcp6. (Use dd with different bs= arguments.)
I just quickly tried to make the linux-2.6 numbering behave identically to linux-2.4 (see patch below) but it did not work properly, and I have not figured out yet where I goofed.
Note: THIS PATCH IS WRONG. Do not apply this patch unless you want to help figure out why it does not work correctly. I was trying to make linux-2.6 number the lines the same way linux-2.4 did, but the numbers come out wrong.
This patch is against linux-2.6.0-test7 without my previous patch to fix the numbering.
-Tim Shepard shep@alum.mit.edu
--- ../pristine/linux-2.6.0-test7/net/ipv4/tcp_ipv4.c 2003-10-08 15:24:03.000000000 -0400 +++ net/ipv4/tcp_ipv4.c 2003-10-14 13:23:58.000000000 -0400 @@ -2136,29 +2136,29 @@ static void *listening_get_first(struct seq_file *seq) { struct tcp_iter_state* st = seq->private; void *rc = NULL; for (st->bucket = 0; st->bucket < TCP_LHTABLE_SIZE; ++st->bucket) { struct open_request *req; struct tcp_opt *tp; struct sock *sk = sk_head(&tcp_listening_hash[st->bucket]); if (!sk) continue; - ++st->num; if (sk->sk_family == st->family) { rc = sk; goto out; } + ++st->num; tp = tcp_sk(sk); read_lock_bh(&tp->syn_wait_lock); if (tp->listen_opt && tp->listen_opt->qlen) { st->uid = sock_i_uid(sk); st->syn_wait_sk = sk; st->state = TCP_SEQ_STATE_OPENREQ; for (st->sbucket = 0; st->sbucket < TCP_SYNQ_HSIZE; ++st->sbucket) { for (req = tp->listen_opt->syn_table[st->sbucket]; req; req = req->dl_next, ++st->num) { if (req->class->family != st->family) continue; @@ -2172,54 +2172,57 @@ } out: return rc; } static void *listening_get_next(struct seq_file *seq, void *cur) { struct tcp_opt *tp; struct hlist_node *node; struct sock *sk = cur; struct tcp_iter_state* st = seq->private; + ++st->num; + if (st->state == TCP_SEQ_STATE_OPENREQ) { struct open_request *req = cur; tp = tcp_sk(st->syn_wait_sk); req = req->dl_next; while (1) { while (req) { - ++st->num; if (req->class->family == st->family) { cur = req; goto out; } + ++st->num; req = req->dl_next; } if (++st->sbucket >= TCP_SYNQ_HSIZE) break; get_req: req = tp->listen_opt->syn_table[st->sbucket]; } sk = sk_next(st->syn_wait_sk); st->state = TCP_SEQ_STATE_LISTENING; read_unlock_bh(&tp->syn_wait_lock); } else sk = sk_next(sk); get_sk: sk_for_each_from(sk, node) { if (sk->sk_family == st->family) { cur = sk; goto out; } + ++st->num; tp = tcp_sk(sk); read_lock_bh(&tp->syn_wait_lock); if (tp->listen_opt && tp->listen_opt->qlen) { st->uid = sock_i_uid(sk); st->syn_wait_sk = sk; st->state = TCP_SEQ_STATE_OPENREQ; st->sbucket = 0; goto get_req; } read_unlock_bh(&tp->syn_wait_lock); } if (++st->bucket < TCP_LHTABLE_SIZE) { @@ -2275,24 +2278,26 @@ } out: return rc; } static void *established_get_next(struct seq_file *seq, void *cur) { struct sock *sk = cur; struct tcp_tw_bucket *tw; struct hlist_node *node; struct tcp_iter_state* st = seq->private; + ++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) { ++st->num; tw = tw_next(tw); } if (tw) { cur = tw; goto out; } @@ -2345,24 +2350,26 @@ if (!rc) { tcp_listen_unlock(); local_bh_disable(); st->state = TCP_SEQ_STATE_ESTABLISHED; rc = established_get_idx(seq, pos); } return rc; } static void *tcp_seq_start(struct seq_file *seq, loff_t *pos) { + struct tcp_iter_state* st = seq->private; + st->num = 0; return *pos ? tcp_get_idx(seq, *pos - 1) : SEQ_START_TOKEN; } static void *tcp_seq_next(struct seq_file *seq, void *v, loff_t *pos) { void *rc = NULL; struct tcp_iter_state* st; if (v == SEQ_START_TOKEN) { rc = tcp_get_idx(seq, 0); goto out; } - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |