aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2006-05-29 21:24:58 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-06-18 00:29:03 -0400
commit89f2e21883b59a6ff1e64d0b4924d06b1c6101ba (patch)
tree86c26d648afcfa3a37270189a33867cbf0d38f9b /net/ipv4
parent3726add76643c715d437aceda320d319153b6113 (diff)
[NETFILTER]: ctnetlink: change table dumping not to require an unique ID
Instead of using the ID to find out where to continue dumping, take a reference to the last entry dumped and try to continue there. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/netfilter/ip_conntrack_netlink.c32
1 files changed, 24 insertions, 8 deletions
diff --git a/net/ipv4/netfilter/ip_conntrack_netlink.c b/net/ipv4/netfilter/ip_conntrack_netlink.c
index af152e3623dc..33891bb1fde4 100644
--- a/net/ipv4/netfilter/ip_conntrack_netlink.c
+++ b/net/ipv4/netfilter/ip_conntrack_netlink.c
@@ -399,38 +399,54 @@ nfattr_failure:
399static int ctnetlink_done(struct netlink_callback *cb) 399static int ctnetlink_done(struct netlink_callback *cb)
400{ 400{
401 DEBUGP("entered %s\n", __FUNCTION__); 401 DEBUGP("entered %s\n", __FUNCTION__);
402 if (cb->args[1])
403 ip_conntrack_put((struct ip_conntrack *)cb->args[1]);
402 return 0; 404 return 0;
403} 405}
404 406
405static int 407static int
406ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb) 408ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
407{ 409{
408 struct ip_conntrack *ct = NULL; 410 struct ip_conntrack *ct, *last;
409 struct ip_conntrack_tuple_hash *h; 411 struct ip_conntrack_tuple_hash *h;
410 struct list_head *i; 412 struct list_head *i;
411 u_int32_t *id = (u_int32_t *) &cb->args[1];
412 413
413 DEBUGP("entered %s, last bucket=%lu id=%u\n", __FUNCTION__, 414 DEBUGP("entered %s, last bucket=%lu id=%u\n", __FUNCTION__,
414 cb->args[0], *id); 415 cb->args[0], *id);
415 416
416 read_lock_bh(&ip_conntrack_lock); 417 read_lock_bh(&ip_conntrack_lock);
417 for (; cb->args[0] < ip_conntrack_htable_size; cb->args[0]++, *id = 0) { 418 for (; cb->args[0] < ip_conntrack_htable_size; cb->args[0]++) {
419restart:
420 last = (struct ip_conntrack *)cb->args[1];
418 list_for_each_prev(i, &ip_conntrack_hash[cb->args[0]]) { 421 list_for_each_prev(i, &ip_conntrack_hash[cb->args[0]]) {
419 h = (struct ip_conntrack_tuple_hash *) i; 422 h = (struct ip_conntrack_tuple_hash *) i;
420 if (DIRECTION(h) != IP_CT_DIR_ORIGINAL) 423 if (DIRECTION(h) != IP_CT_DIR_ORIGINAL)
421 continue; 424 continue;
422 ct = tuplehash_to_ctrack(h); 425 ct = tuplehash_to_ctrack(h);
423 if (ct->id <= *id) 426 if (last != NULL) {
424 continue; 427 if (ct == last) {
428 ip_conntrack_put(last);
429 cb->args[1] = 0;
430 last = NULL;
431 } else
432 continue;
433 }
425 if (ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).pid, 434 if (ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).pid,
426 cb->nlh->nlmsg_seq, 435 cb->nlh->nlmsg_seq,
427 IPCTNL_MSG_CT_NEW, 436 IPCTNL_MSG_CT_NEW,
428 1, ct) < 0) 437 1, ct) < 0) {
438 nf_conntrack_get(&ct->ct_general);
439 cb->args[1] = (unsigned long)ct;
429 goto out; 440 goto out;
430 *id = ct->id; 441 }
442 }
443 if (last != NULL) {
444 ip_conntrack_put(last);
445 cb->args[1] = 0;
446 goto restart;
431 } 447 }
432 } 448 }
433out: 449out:
434 read_unlock_bh(&ip_conntrack_lock); 450 read_unlock_bh(&ip_conntrack_lock);
435 451
436 DEBUGP("leaving, last bucket=%lu id=%u\n", cb->args[0], *id); 452 DEBUGP("leaving, last bucket=%lu id=%u\n", cb->args[0], *id);