aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter
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/netfilter
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/netfilter')
-rw-r--r--net/netfilter/nf_conntrack_netlink.c32
1 files changed, 24 insertions, 8 deletions
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 8f27fe9446f2..b8c7c567c9df 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -407,6 +407,8 @@ nfattr_failure:
407 407
408static int ctnetlink_done(struct netlink_callback *cb) 408static int ctnetlink_done(struct netlink_callback *cb)
409{ 409{
410 if (cb->args[1])
411 nf_ct_put((struct nf_conn *)cb->args[1]);
410 DEBUGP("entered %s\n", __FUNCTION__); 412 DEBUGP("entered %s\n", __FUNCTION__);
411 return 0; 413 return 0;
412} 414}
@@ -416,10 +418,9 @@ static int ctnetlink_done(struct netlink_callback *cb)
416static int 418static int
417ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb) 419ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
418{ 420{
419 struct nf_conn *ct = NULL; 421 struct nf_conn *ct, *last;
420 struct nf_conntrack_tuple_hash *h; 422 struct nf_conntrack_tuple_hash *h;
421 struct list_head *i; 423 struct list_head *i;
422 u_int32_t *id = (u_int32_t *) &cb->args[1];
423 struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh); 424 struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh);
424 u_int8_t l3proto = nfmsg->nfgen_family; 425 u_int8_t l3proto = nfmsg->nfgen_family;
425 426
@@ -427,7 +428,9 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
427 cb->args[0], *id); 428 cb->args[0], *id);
428 429
429 read_lock_bh(&nf_conntrack_lock); 430 read_lock_bh(&nf_conntrack_lock);
430 for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++, *id = 0) { 431 for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++) {
432restart:
433 last = (struct nf_conn *)cb->args[1];
431 list_for_each_prev(i, &nf_conntrack_hash[cb->args[0]]) { 434 list_for_each_prev(i, &nf_conntrack_hash[cb->args[0]]) {
432 h = (struct nf_conntrack_tuple_hash *) i; 435 h = (struct nf_conntrack_tuple_hash *) i;
433 if (DIRECTION(h) != IP_CT_DIR_ORIGINAL) 436 if (DIRECTION(h) != IP_CT_DIR_ORIGINAL)
@@ -438,17 +441,30 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
438 * then dump everything. */ 441 * then dump everything. */
439 if (l3proto && L3PROTO(ct) != l3proto) 442 if (l3proto && L3PROTO(ct) != l3proto)
440 continue; 443 continue;
441 if (ct->id <= *id) 444 if (last != NULL) {
442 continue; 445 if (ct == last) {
446 nf_ct_put(last);
447 cb->args[1] = 0;
448 last = NULL;
449 } else
450 continue;
451 }
443 if (ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).pid, 452 if (ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).pid,
444 cb->nlh->nlmsg_seq, 453 cb->nlh->nlmsg_seq,
445 IPCTNL_MSG_CT_NEW, 454 IPCTNL_MSG_CT_NEW,
446 1, ct) < 0) 455 1, ct) < 0) {
456 nf_conntrack_get(&ct->ct_general);
457 cb->args[1] = (unsigned long)ct;
447 goto out; 458 goto out;
448 *id = ct->id; 459 }
460 }
461 if (last != NULL) {
462 nf_ct_put(last);
463 cb->args[1] = 0;
464 goto restart;
449 } 465 }
450 } 466 }
451out: 467out:
452 read_unlock_bh(&nf_conntrack_lock); 468 read_unlock_bh(&nf_conntrack_lock);
453 469
454 DEBUGP("leaving, last bucket=%lu id=%u\n", cb->args[0], *id); 470 DEBUGP("leaving, last bucket=%lu id=%u\n", cb->args[0], *id);