netfilter: ctnetlink: use dump structure instead of raw args
netlink_dump structure has a union of 'long args[6]' and a context buffer as scratch space. Convert ctnetlink to use a structure, its easier to read than the raw 'args' usage which comes with no type checks and no readable names. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
parent
98eee88b8d
commit
5948ed297e
|
@ -58,6 +58,12 @@
|
||||||
|
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
|
struct ctnetlink_list_dump_ctx {
|
||||||
|
struct nf_conn *last;
|
||||||
|
unsigned int cpu;
|
||||||
|
bool done;
|
||||||
|
};
|
||||||
|
|
||||||
static int ctnetlink_dump_tuples_proto(struct sk_buff *skb,
|
static int ctnetlink_dump_tuples_proto(struct sk_buff *skb,
|
||||||
const struct nf_conntrack_tuple *tuple,
|
const struct nf_conntrack_tuple *tuple,
|
||||||
const struct nf_conntrack_l4proto *l4proto)
|
const struct nf_conntrack_l4proto *l4proto)
|
||||||
|
@ -1694,14 +1700,18 @@ static int ctnetlink_get_conntrack(struct sk_buff *skb,
|
||||||
|
|
||||||
static int ctnetlink_done_list(struct netlink_callback *cb)
|
static int ctnetlink_done_list(struct netlink_callback *cb)
|
||||||
{
|
{
|
||||||
if (cb->args[1])
|
struct ctnetlink_list_dump_ctx *ctx = (void *)cb->ctx;
|
||||||
nf_ct_put((struct nf_conn *)cb->args[1]);
|
|
||||||
|
if (ctx->last)
|
||||||
|
nf_ct_put(ctx->last);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ctnetlink_dump_list(struct sk_buff *skb, struct netlink_callback *cb, bool dying)
|
ctnetlink_dump_list(struct sk_buff *skb, struct netlink_callback *cb, bool dying)
|
||||||
{
|
{
|
||||||
|
struct ctnetlink_list_dump_ctx *ctx = (void *)cb->ctx;
|
||||||
struct nf_conn *ct, *last;
|
struct nf_conn *ct, *last;
|
||||||
struct nf_conntrack_tuple_hash *h;
|
struct nf_conntrack_tuple_hash *h;
|
||||||
struct hlist_nulls_node *n;
|
struct hlist_nulls_node *n;
|
||||||
|
@ -1712,12 +1722,12 @@ ctnetlink_dump_list(struct sk_buff *skb, struct netlink_callback *cb, bool dying
|
||||||
struct hlist_nulls_head *list;
|
struct hlist_nulls_head *list;
|
||||||
struct net *net = sock_net(skb->sk);
|
struct net *net = sock_net(skb->sk);
|
||||||
|
|
||||||
if (cb->args[2])
|
if (ctx->done)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
last = (struct nf_conn *)cb->args[1];
|
last = ctx->last;
|
||||||
|
|
||||||
for (cpu = cb->args[0]; cpu < nr_cpu_ids; cpu++) {
|
for (cpu = ctx->cpu; cpu < nr_cpu_ids; cpu++) {
|
||||||
struct ct_pcpu *pcpu;
|
struct ct_pcpu *pcpu;
|
||||||
|
|
||||||
if (!cpu_possible(cpu))
|
if (!cpu_possible(cpu))
|
||||||
|
@ -1731,10 +1741,10 @@ restart:
|
||||||
ct = nf_ct_tuplehash_to_ctrack(h);
|
ct = nf_ct_tuplehash_to_ctrack(h);
|
||||||
if (l3proto && nf_ct_l3num(ct) != l3proto)
|
if (l3proto && nf_ct_l3num(ct) != l3proto)
|
||||||
continue;
|
continue;
|
||||||
if (cb->args[1]) {
|
if (ctx->last) {
|
||||||
if (ct != last)
|
if (ct != last)
|
||||||
continue;
|
continue;
|
||||||
cb->args[1] = 0;
|
ctx->last = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We can't dump extension info for the unconfirmed
|
/* We can't dump extension info for the unconfirmed
|
||||||
|
@ -1751,19 +1761,19 @@ restart:
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
if (!refcount_inc_not_zero(&ct->ct_general.use))
|
if (!refcount_inc_not_zero(&ct->ct_general.use))
|
||||||
continue;
|
continue;
|
||||||
cb->args[0] = cpu;
|
ctx->cpu = cpu;
|
||||||
cb->args[1] = (unsigned long)ct;
|
ctx->last = ct;
|
||||||
spin_unlock_bh(&pcpu->lock);
|
spin_unlock_bh(&pcpu->lock);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (cb->args[1]) {
|
if (ctx->last) {
|
||||||
cb->args[1] = 0;
|
ctx->last = NULL;
|
||||||
goto restart;
|
goto restart;
|
||||||
}
|
}
|
||||||
spin_unlock_bh(&pcpu->lock);
|
spin_unlock_bh(&pcpu->lock);
|
||||||
}
|
}
|
||||||
cb->args[2] = 1;
|
ctx->done = true;
|
||||||
out:
|
out:
|
||||||
if (last)
|
if (last)
|
||||||
nf_ct_put(last);
|
nf_ct_put(last);
|
||||||
|
@ -3877,6 +3887,8 @@ static int __init ctnetlink_init(void)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
BUILD_BUG_ON(sizeof(struct ctnetlink_list_dump_ctx) > sizeof_field(struct netlink_callback, ctx));
|
||||||
|
|
||||||
ret = nfnetlink_subsys_register(&ctnl_subsys);
|
ret = nfnetlink_subsys_register(&ctnl_subsys);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
pr_err("ctnetlink_init: cannot register with nfnetlink.\n");
|
pr_err("ctnetlink_init: cannot register with nfnetlink.\n");
|
||||||
|
|
Loading…
Reference in New Issue