* [PATCH] netfilter: ctnetlink: add expectation deletion events @ 2010-10-14 12:02 Pablo Neira Ayuso 2010-10-15 15:44 ` Patrick McHardy 0 siblings, 1 reply; 4+ messages in thread From: Pablo Neira Ayuso @ 2010-10-14 12:02 UTC (permalink / raw) To: netfilter-devel; +Cc: kaber This patch allows to listen to events that inform about expectations destroyed. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> --- include/linux/netfilter/nf_conntrack_common.h | 1 + include/net/netfilter/nf_conntrack_expect.h | 8 ++++++- net/netfilter/nf_conntrack_expect.c | 6 +++-- net/netfilter/nf_conntrack_netlink.c | 30 ++++++++++++++++++------- 4 files changed, 33 insertions(+), 12 deletions(-) diff --git a/include/linux/netfilter/nf_conntrack_common.h b/include/linux/netfilter/nf_conntrack_common.h index 23a1a08..50cdc25 100644 --- a/include/linux/netfilter/nf_conntrack_common.h +++ b/include/linux/netfilter/nf_conntrack_common.h @@ -98,6 +98,7 @@ enum ip_conntrack_events { enum ip_conntrack_expect_events { IPEXP_NEW, /* new expectation */ + IPEXP_DESTROY, /* destroyed expectation */ }; /* expectation flags */ diff --git a/include/net/netfilter/nf_conntrack_expect.h b/include/net/netfilter/nf_conntrack_expect.h index 416b838..0f8a8c5 100644 --- a/include/net/netfilter/nf_conntrack_expect.h +++ b/include/net/netfilter/nf_conntrack_expect.h @@ -82,7 +82,13 @@ struct nf_conntrack_expect * nf_ct_find_expectation(struct net *net, u16 zone, const struct nf_conntrack_tuple *tuple); -void nf_ct_unlink_expect(struct nf_conntrack_expect *exp); +void nf_ct_unlink_expect_report(struct nf_conntrack_expect *exp, + u32 pid, int report); +static inline void nf_ct_unlink_expect(struct nf_conntrack_expect *exp) +{ + nf_ct_unlink_expect_report(exp, 0, 0); +} + void nf_ct_remove_expectations(struct nf_conn *ct); void nf_ct_unexpect_related(struct nf_conntrack_expect *exp); void nf_ct_remove_userspace_expectations(void); diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c index b30a1f2..46e8966 100644 --- a/net/netfilter/nf_conntrack_expect.c +++ b/net/netfilter/nf_conntrack_expect.c @@ -41,7 +41,8 @@ static struct kmem_cache *nf_ct_expect_cachep __read_mostly; static HLIST_HEAD(nf_ct_userspace_expect_list); /* nf_conntrack_expect helper functions */ -void nf_ct_unlink_expect(struct nf_conntrack_expect *exp) +void nf_ct_unlink_expect_report(struct nf_conntrack_expect *exp, + u32 pid, int report) { struct nf_conn_help *master_help = nfct_help(exp->master); struct net *net = nf_ct_exp_net(exp); @@ -55,11 +56,12 @@ void nf_ct_unlink_expect(struct nf_conntrack_expect *exp) if (!(exp->flags & NF_CT_EXPECT_USERSPACE)) master_help->expecting[exp->class]--; + nf_ct_expect_event_report(IPEXP_DESTROY, exp, pid, report); nf_ct_expect_put(exp); NF_CT_STAT_INC(net, expect_delete); } -EXPORT_SYMBOL_GPL(nf_ct_unlink_expect); +EXPORT_SYMBOL_GPL(nf_ct_unlink_expect_report); static void nf_ct_expectation_timed_out(unsigned long ul_expect) { diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index b4077be..4b7989e 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -1632,17 +1632,20 @@ ctnetlink_expect_event(unsigned int events, struct nf_exp_event *item) struct nlmsghdr *nlh; struct nfgenmsg *nfmsg; struct sk_buff *skb; - unsigned int type; + unsigned int type, group; int flags = 0; - if (events & (1 << IPEXP_NEW)) { + if (events & (1 << IPEXP_DESTROY)) { + type = IPCTNL_MSG_EXP_DELETE; + group = NFNLGRP_CONNTRACK_EXP_DESTROY; + } else if (events & (1 << IPEXP_NEW)) { type = IPCTNL_MSG_EXP_NEW; flags = NLM_F_CREATE|NLM_F_EXCL; + group = NFNLGRP_CONNTRACK_EXP_NEW; } else return 0; - if (!item->report && - !nfnetlink_has_listeners(net, NFNLGRP_CONNTRACK_EXP_NEW)) + if (!item->report && !nfnetlink_has_listeners(net, group)) return 0; skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); @@ -1665,8 +1668,7 @@ ctnetlink_expect_event(unsigned int events, struct nf_exp_event *item) rcu_read_unlock(); nlmsg_end(skb, nlh); - nfnetlink_send(skb, net, item->pid, NFNLGRP_CONNTRACK_EXP_NEW, - item->report, GFP_ATOMIC); + nfnetlink_send(skb, net, item->pid, group, item->report, GFP_ATOMIC); return 0; nla_put_failure: @@ -1849,7 +1851,13 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb, } /* after list removal, usage count == 1 */ - nf_ct_unexpect_related(exp); + spin_lock_bh(&nf_conntrack_lock); + if (del_timer(&exp->timeout)) { + nf_ct_unlink_expect_report(exp, NETLINK_CB(skb).pid, + nlmsg_report(nlh)); + nf_ct_expect_put(exp); + } + spin_unlock_bh(&nf_conntrack_lock); /* have to put what we 'get' above. * after this line usage count == 0 */ nf_ct_expect_put(exp); @@ -1866,7 +1874,9 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb, m_help = nfct_help(exp->master); if (!strcmp(m_help->helper->name, name) && del_timer(&exp->timeout)) { - nf_ct_unlink_expect(exp); + nf_ct_unlink_expect_report(exp, + NETLINK_CB(skb).pid, + nlmsg_report(nlh)); nf_ct_expect_put(exp); } } @@ -1880,7 +1890,9 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb, &net->ct.expect_hash[i], hnode) { if (del_timer(&exp->timeout)) { - nf_ct_unlink_expect(exp); + nf_ct_unlink_expect_report(exp, + NETLINK_CB(skb).pid, + nlmsg_report(nlh)); nf_ct_expect_put(exp); } } ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] netfilter: ctnetlink: add expectation deletion events 2010-10-14 12:02 [PATCH] netfilter: ctnetlink: add expectation deletion events Pablo Neira Ayuso @ 2010-10-15 15:44 ` Patrick McHardy 2010-10-15 16:42 ` Pablo Neira Ayuso 0 siblings, 1 reply; 4+ messages in thread From: Patrick McHardy @ 2010-10-15 15:44 UTC (permalink / raw) To: Pablo Neira Ayuso; +Cc: netfilter-devel Am 14.10.2010 14:02, schrieb Pablo Neira Ayuso: > This patch allows to listen to events that inform about > expectations destroyed. This looks fine, but I'm wondering why we're not delivering events for expectations created and destroyed by helpers using nf_conntrack_expect_related()/nf_conntrack_unexpect_related(). ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] netfilter: ctnetlink: add expectation deletion events 2010-10-15 15:44 ` Patrick McHardy @ 2010-10-15 16:42 ` Pablo Neira Ayuso 2010-10-19 8:20 ` Patrick McHardy 0 siblings, 1 reply; 4+ messages in thread From: Pablo Neira Ayuso @ 2010-10-15 16:42 UTC (permalink / raw) To: Patrick McHardy; +Cc: netfilter-devel [-- Attachment #1: Type: text/plain, Size: 648 bytes --] On 15/10/10 17:44, Patrick McHardy wrote: > Am 14.10.2010 14:02, schrieb Pablo Neira Ayuso: >> This patch allows to listen to events that inform about >> expectations destroyed. > > This looks fine, but I'm wondering why we're not delivering > events for expectations created and destroyed by helpers using > nf_conntrack_expect_related()/nf_conntrack_unexpect_related(). We already deliver events for new expectations. Wrt. destroyed expectations, nf_ct_unexpect_related() internally calls nf_ct_unlink_expect(), so they are also delivered. BTW, you can test this patch with the following patch for the conntrack-tools (I didn't apply it yet). [-- Attachment #2: exp-destroy-ct.patch --] [-- Type: text/x-patch, Size: 3710 bytes --] conntrack: allow to listen to all kind of expectation events From: Pablo Neira Ayuso <pablo@netfilter.org> So far, conntrack only allows to listen to events of new expectations. With this patch, we can listen to events of destroyed expectations (it requires Linux kernel >= 2.6.37). Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> --- src/conntrack.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++------- 1 files changed, 55 insertions(+), 8 deletions(-) diff --git a/src/conntrack.c b/src/conntrack.c index 51ea472..2527953 100644 --- a/src/conntrack.c +++ b/src/conntrack.c @@ -671,6 +671,13 @@ enum { _O_ID = (1 << 3), }; +enum { + CT_EVENT_F_NEW = (1 << 0), + CT_EVENT_F_UPD = (1 << 1), + CT_EVENT_F_DEL = (1 << 2), + CT_EVENT_F_ALL = CT_EVENT_F_NEW | CT_EVENT_F_UPD | CT_EVENT_F_DEL, +}; + static struct parse_parameter { const char *parameter[6]; size_t size; @@ -679,8 +686,7 @@ static struct parse_parameter { { {"ASSURED", "SEEN_REPLY", "UNSET", "FIXED_TIMEOUT", "EXPECTED"}, 5, { IPS_ASSURED, IPS_SEEN_REPLY, 0, IPS_FIXED_TIMEOUT, IPS_EXPECTED} }, { {"ALL", "NEW", "UPDATES", "DESTROY"}, 4, - {~0U, NF_NETLINK_CONNTRACK_NEW, NF_NETLINK_CONNTRACK_UPDATE, - NF_NETLINK_CONNTRACK_DESTROY} }, + { CT_EVENT_F_ALL, CT_EVENT_F_NEW, CT_EVENT_F_UPD, CT_EVENT_F_DEL } }, { {"xml", "extended", "timestamp", "id" }, 4, { _O_XML, _O_EXT, _O_TMS, _O_ID }, }, @@ -1194,6 +1200,18 @@ static int dump_exp_cb(enum nf_conntrack_msg_type type, return NFCT_CB_CONTINUE; } +static int event_exp_cb(enum nf_conntrack_msg_type type, + struct nf_expect *exp, void *data) +{ + char buf[1024]; + + nfexp_snprintf(buf,sizeof(buf), exp, type, NFCT_O_DEFAULT, 0); + printf("%s\n", buf); + counter++; + + return NFCT_CB_CONTINUE; +} + static int count_exp_cb(enum nf_conntrack_msg_type type, struct nf_expect *exp, void *data) @@ -1667,11 +1685,23 @@ int main(int argc, char *argv[]) break; case CT_EVENT: - if (options & CT_OPT_EVENT_MASK) + if (options & CT_OPT_EVENT_MASK) { + unsigned int nl_events = 0; + + if (event_mask & CT_EVENT_F_NEW) + nl_events |= NF_NETLINK_CONNTRACK_NEW; + if (event_mask & CT_EVENT_F_UPD) + nl_events |= NF_NETLINK_CONNTRACK_UPDATE; + if (event_mask & CT_EVENT_F_DEL) + nl_events |= NF_NETLINK_CONNTRACK_DESTROY; + + cth = nfct_open(CONNTRACK, nl_events); + } else { cth = nfct_open(CONNTRACK, - event_mask & NFCT_ALL_CT_GROUPS); - else - cth = nfct_open(CONNTRACK, NFCT_ALL_CT_GROUPS); + NF_NETLINK_CONNTRACK_NEW | + NF_NETLINK_CONNTRACK_UPDATE | + NF_NETLINK_CONNTRACK_DESTROY); + } if (!cth) exit_error(OTHER_PROBLEM, "Can't open handler"); @@ -1701,12 +1731,29 @@ int main(int argc, char *argv[]) break; case EXP_EVENT: - cth = nfct_open(EXPECT, NF_NETLINK_CONNTRACK_EXP_NEW); + if (options & CT_OPT_EVENT_MASK) { + unsigned int nl_events = 0; + + if (event_mask & CT_EVENT_F_NEW) + nl_events |= NF_NETLINK_CONNTRACK_EXP_NEW; + if (event_mask & CT_EVENT_F_UPD) + nl_events |= NF_NETLINK_CONNTRACK_EXP_UPDATE; + if (event_mask & CT_EVENT_F_DEL) + nl_events |= NF_NETLINK_CONNTRACK_EXP_DESTROY; + + cth = nfct_open(CONNTRACK, nl_events); + } else { + cth = nfct_open(EXPECT, + NF_NETLINK_CONNTRACK_EXP_NEW | + NF_NETLINK_CONNTRACK_EXP_UPDATE | + NF_NETLINK_CONNTRACK_EXP_DESTROY); + } + if (!cth) exit_error(OTHER_PROBLEM, "Can't open handler"); signal(SIGINT, event_sighandler); signal(SIGTERM, event_sighandler); - nfexp_callback_register(cth, NFCT_T_ALL, dump_exp_cb, NULL); + nfexp_callback_register(cth, NFCT_T_ALL, event_exp_cb, NULL); res = nfexp_catch(cth); nfct_close(cth); break; ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] netfilter: ctnetlink: add expectation deletion events 2010-10-15 16:42 ` Pablo Neira Ayuso @ 2010-10-19 8:20 ` Patrick McHardy 0 siblings, 0 replies; 4+ messages in thread From: Patrick McHardy @ 2010-10-19 8:20 UTC (permalink / raw) To: Pablo Neira Ayuso; +Cc: netfilter-devel Am 15.10.2010 18:42, schrieb Pablo Neira Ayuso: > On 15/10/10 17:44, Patrick McHardy wrote: >> Am 14.10.2010 14:02, schrieb Pablo Neira Ayuso: >>> This patch allows to listen to events that inform about >>> expectations destroyed. >> >> This looks fine, but I'm wondering why we're not delivering >> events for expectations created and destroyed by helpers using >> nf_conntrack_expect_related()/nf_conntrack_unexpect_related(). > > We already deliver events for new expectations. Wrt. destroyed > expectations, nf_ct_unexpect_related() internally calls > nf_ct_unlink_expect(), so they are also delivered. I see. Applied, thanks Pablo. ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2010-10-19 8:20 UTC | newest] Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2010-10-14 12:02 [PATCH] netfilter: ctnetlink: add expectation deletion events Pablo Neira Ayuso 2010-10-15 15:44 ` Patrick McHardy 2010-10-15 16:42 ` Pablo Neira Ayuso 2010-10-19 8:20 ` Patrick McHardy
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.