Skip to content

Commit

Permalink
[NETFILTER]: ctnetlink: change table dumping not to require an unique ID
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Patrick McHardy authored and David S. Miller committed Jun 18, 2006
1 parent 3726add commit 89f2e21
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 16 deletions.
32 changes: 24 additions & 8 deletions net/ipv4/netfilter/ip_conntrack_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -399,38 +399,54 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
static int ctnetlink_done(struct netlink_callback *cb)
{
DEBUGP("entered %s\n", __FUNCTION__);
if (cb->args[1])
ip_conntrack_put((struct ip_conntrack *)cb->args[1]);
return 0;
}

static int
ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
{
struct ip_conntrack *ct = NULL;
struct ip_conntrack *ct, *last;
struct ip_conntrack_tuple_hash *h;
struct list_head *i;
u_int32_t *id = (u_int32_t *) &cb->args[1];

DEBUGP("entered %s, last bucket=%lu id=%u\n", __FUNCTION__,
cb->args[0], *id);

read_lock_bh(&ip_conntrack_lock);
for (; cb->args[0] < ip_conntrack_htable_size; cb->args[0]++, *id = 0) {
for (; cb->args[0] < ip_conntrack_htable_size; cb->args[0]++) {
restart:
last = (struct ip_conntrack *)cb->args[1];
list_for_each_prev(i, &ip_conntrack_hash[cb->args[0]]) {
h = (struct ip_conntrack_tuple_hash *) i;
if (DIRECTION(h) != IP_CT_DIR_ORIGINAL)
continue;
ct = tuplehash_to_ctrack(h);
if (ct->id <= *id)
continue;
if (last != NULL) {
if (ct == last) {
ip_conntrack_put(last);
cb->args[1] = 0;
last = NULL;
} else
continue;
}
if (ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).pid,
cb->nlh->nlmsg_seq,
IPCTNL_MSG_CT_NEW,
1, ct) < 0)
1, ct) < 0) {
nf_conntrack_get(&ct->ct_general);
cb->args[1] = (unsigned long)ct;
goto out;
*id = ct->id;
}
}
if (last != NULL) {
ip_conntrack_put(last);
cb->args[1] = 0;
goto restart;
}
}
out:
out:
read_unlock_bh(&ip_conntrack_lock);

DEBUGP("leaving, last bucket=%lu id=%u\n", cb->args[0], *id);
Expand Down
32 changes: 24 additions & 8 deletions net/netfilter/nf_conntrack_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,8 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,

static int ctnetlink_done(struct netlink_callback *cb)
{
if (cb->args[1])
nf_ct_put((struct nf_conn *)cb->args[1]);
DEBUGP("entered %s\n", __FUNCTION__);
return 0;
}
Expand All @@ -416,18 +418,19 @@ static int ctnetlink_done(struct netlink_callback *cb)
static int
ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
{
struct nf_conn *ct = NULL;
struct nf_conn *ct, *last;
struct nf_conntrack_tuple_hash *h;
struct list_head *i;
u_int32_t *id = (u_int32_t *) &cb->args[1];
struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh);
u_int8_t l3proto = nfmsg->nfgen_family;

DEBUGP("entered %s, last bucket=%lu id=%u\n", __FUNCTION__,
cb->args[0], *id);

read_lock_bh(&nf_conntrack_lock);
for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++, *id = 0) {
for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++) {
restart:
last = (struct nf_conn *)cb->args[1];
list_for_each_prev(i, &nf_conntrack_hash[cb->args[0]]) {
h = (struct nf_conntrack_tuple_hash *) i;
if (DIRECTION(h) != IP_CT_DIR_ORIGINAL)
Expand All @@ -438,17 +441,30 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
* then dump everything. */
if (l3proto && L3PROTO(ct) != l3proto)
continue;
if (ct->id <= *id)
continue;
if (last != NULL) {
if (ct == last) {
nf_ct_put(last);
cb->args[1] = 0;
last = NULL;
} else
continue;
}
if (ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).pid,
cb->nlh->nlmsg_seq,
IPCTNL_MSG_CT_NEW,
1, ct) < 0)
1, ct) < 0) {
nf_conntrack_get(&ct->ct_general);
cb->args[1] = (unsigned long)ct;
goto out;
*id = ct->id;
}
}
if (last != NULL) {
nf_ct_put(last);
cb->args[1] = 0;
goto restart;
}
}
out:
out:
read_unlock_bh(&nf_conntrack_lock);

DEBUGP("leaving, last bucket=%lu id=%u\n", cb->args[0], *id);
Expand Down

0 comments on commit 89f2e21

Please sign in to comment.