* [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.