netfilter: ctnetlink: allow to dump expectation per master conntrack
This patch adds the ability to dump all existing expectations per master conntrack. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
parent
b962abdc65
commit
e844a92843
|
@ -2409,6 +2409,92 @@ out:
|
||||||
return skb->len;
|
return skb->len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ctnetlink_exp_ct_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
|
||||||
|
{
|
||||||
|
struct nf_conntrack_expect *exp, *last;
|
||||||
|
struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
|
||||||
|
struct nf_conn *ct = cb->data;
|
||||||
|
struct nf_conn_help *help = nfct_help(ct);
|
||||||
|
u_int8_t l3proto = nfmsg->nfgen_family;
|
||||||
|
|
||||||
|
if (cb->args[0])
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
rcu_read_lock();
|
||||||
|
last = (struct nf_conntrack_expect *)cb->args[1];
|
||||||
|
restart:
|
||||||
|
hlist_for_each_entry(exp, &help->expectations, lnode) {
|
||||||
|
if (l3proto && exp->tuple.src.l3num != l3proto)
|
||||||
|
continue;
|
||||||
|
if (cb->args[1]) {
|
||||||
|
if (exp != last)
|
||||||
|
continue;
|
||||||
|
cb->args[1] = 0;
|
||||||
|
}
|
||||||
|
if (ctnetlink_exp_fill_info(skb, NETLINK_CB(cb->skb).portid,
|
||||||
|
cb->nlh->nlmsg_seq,
|
||||||
|
IPCTNL_MSG_EXP_NEW,
|
||||||
|
exp) < 0) {
|
||||||
|
if (!atomic_inc_not_zero(&exp->use))
|
||||||
|
continue;
|
||||||
|
cb->args[1] = (unsigned long)exp;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cb->args[1]) {
|
||||||
|
cb->args[1] = 0;
|
||||||
|
goto restart;
|
||||||
|
}
|
||||||
|
cb->args[0] = 1;
|
||||||
|
out:
|
||||||
|
rcu_read_unlock();
|
||||||
|
if (last)
|
||||||
|
nf_ct_expect_put(last);
|
||||||
|
|
||||||
|
return skb->len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ctnetlink_dump_exp_ct(struct sock *ctnl, struct sk_buff *skb,
|
||||||
|
const struct nlmsghdr *nlh,
|
||||||
|
const struct nlattr * const cda[])
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
struct net *net = sock_net(ctnl);
|
||||||
|
struct nfgenmsg *nfmsg = nlmsg_data(nlh);
|
||||||
|
u_int8_t u3 = nfmsg->nfgen_family;
|
||||||
|
struct nf_conntrack_tuple tuple;
|
||||||
|
struct nf_conntrack_tuple_hash *h;
|
||||||
|
struct nf_conn *ct;
|
||||||
|
u16 zone = 0;
|
||||||
|
struct netlink_dump_control c = {
|
||||||
|
.dump = ctnetlink_exp_ct_dump_table,
|
||||||
|
.done = ctnetlink_exp_done,
|
||||||
|
};
|
||||||
|
|
||||||
|
err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_MASTER, u3);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
if (cda[CTA_EXPECT_ZONE]) {
|
||||||
|
err = ctnetlink_parse_zone(cda[CTA_EXPECT_ZONE], &zone);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
h = nf_conntrack_find_get(net, zone, &tuple);
|
||||||
|
if (!h)
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
ct = nf_ct_tuplehash_to_ctrack(h);
|
||||||
|
c.data = ct;
|
||||||
|
|
||||||
|
err = netlink_dump_start(ctnl, skb, nlh, &c);
|
||||||
|
nf_ct_put(ct);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct nla_policy exp_nla_policy[CTA_EXPECT_MAX+1] = {
|
static const struct nla_policy exp_nla_policy[CTA_EXPECT_MAX+1] = {
|
||||||
[CTA_EXPECT_MASTER] = { .type = NLA_NESTED },
|
[CTA_EXPECT_MASTER] = { .type = NLA_NESTED },
|
||||||
[CTA_EXPECT_TUPLE] = { .type = NLA_NESTED },
|
[CTA_EXPECT_TUPLE] = { .type = NLA_NESTED },
|
||||||
|
@ -2439,11 +2525,15 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (nlh->nlmsg_flags & NLM_F_DUMP) {
|
if (nlh->nlmsg_flags & NLM_F_DUMP) {
|
||||||
struct netlink_dump_control c = {
|
if (cda[CTA_EXPECT_MASTER])
|
||||||
.dump = ctnetlink_exp_dump_table,
|
return ctnetlink_dump_exp_ct(ctnl, skb, nlh, cda);
|
||||||
.done = ctnetlink_exp_done,
|
else {
|
||||||
};
|
struct netlink_dump_control c = {
|
||||||
return netlink_dump_start(ctnl, skb, nlh, &c);
|
.dump = ctnetlink_exp_dump_table,
|
||||||
|
.done = ctnetlink_exp_done,
|
||||||
|
};
|
||||||
|
return netlink_dump_start(ctnl, skb, nlh, &c);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ctnetlink_parse_zone(cda[CTA_EXPECT_ZONE], &zone);
|
err = ctnetlink_parse_zone(cda[CTA_EXPECT_ZONE], &zone);
|
||||||
|
|
Loading…
Reference in New Issue