aboutsummaryrefslogtreecommitdiffstats
path: root/include/net/netfilter/nf_conntrack_ecache.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/net/netfilter/nf_conntrack_ecache.h')
-rw-r--r--include/net/netfilter/nf_conntrack_ecache.h59
1 files changed, 28 insertions, 31 deletions
diff --git a/include/net/netfilter/nf_conntrack_ecache.h b/include/net/netfilter/nf_conntrack_ecache.h
index 5e05fb883ab1..96ba5f7dcab6 100644
--- a/include/net/netfilter/nf_conntrack_ecache.h
+++ b/include/net/netfilter/nf_conntrack_ecache.h
@@ -12,28 +12,12 @@
#include <linux/netfilter/nf_conntrack_tuple_common.h>
#include <net/netfilter/nf_conntrack_extend.h>
-/* Connection tracking event types */
-enum ip_conntrack_events {
- IPCT_NEW, /* new conntrack */
- IPCT_RELATED, /* related conntrack */
- IPCT_DESTROY, /* destroyed conntrack */
- IPCT_REPLY, /* connection has seen two-way traffic */
- IPCT_ASSURED, /* connection status has changed to assured */
- IPCT_PROTOINFO, /* protocol information has changed */
- IPCT_HELPER, /* new helper has been set */
- IPCT_MARK, /* new mark has been set */
- IPCT_NATSEQADJ, /* NAT is doing sequence adjustment */
- IPCT_SECMARK, /* new security mark has been set */
-};
-
-enum ip_conntrack_expect_events {
- IPEXP_NEW, /* new expectation */
-};
-
struct nf_conntrack_ecache {
- unsigned long cache; /* bitops want long */
- unsigned long missed; /* missed events */
- u32 pid; /* netlink pid of destroyer */
+ unsigned long cache; /* bitops want long */
+ unsigned long missed; /* missed events */
+ u16 ctmask; /* bitmask of ct events to be delivered */
+ u16 expmask; /* bitmask of expect events to be delivered */
+ u32 pid; /* netlink pid of destroyer */
};
static inline struct nf_conntrack_ecache *
@@ -43,14 +27,24 @@ nf_ct_ecache_find(const struct nf_conn *ct)
}
static inline struct nf_conntrack_ecache *
-nf_ct_ecache_ext_add(struct nf_conn *ct, gfp_t gfp)
+nf_ct_ecache_ext_add(struct nf_conn *ct, u16 ctmask, u16 expmask, gfp_t gfp)
{
struct net *net = nf_ct_net(ct);
+ struct nf_conntrack_ecache *e;
- if (!net->ct.sysctl_events)
+ if (!ctmask && !expmask && net->ct.sysctl_events) {
+ ctmask = ~0;
+ expmask = ~0;
+ }
+ if (!ctmask && !expmask)
return NULL;
- return nf_ct_ext_add(ct, NF_CT_EXT_ECACHE, gfp);
+ e = nf_ct_ext_add(ct, NF_CT_EXT_ECACHE, gfp);
+ if (e) {
+ e->ctmask = ctmask;
+ e->expmask = expmask;
+ }
+ return e;
};
#ifdef CONFIG_NF_CONNTRACK_EVENTS
@@ -83,6 +77,9 @@ nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct)
if (e == NULL)
return;
+ if (!(e->ctmask & (1 << event)))
+ return;
+
set_bit(event, &e->cache);
}
@@ -93,7 +90,6 @@ nf_conntrack_eventmask_report(unsigned int eventmask,
int report)
{
int ret = 0;
- struct net *net = nf_ct_net(ct);
struct nf_ct_event_notifier *notify;
struct nf_conntrack_ecache *e;
@@ -102,9 +98,6 @@ nf_conntrack_eventmask_report(unsigned int eventmask,
if (notify == NULL)
goto out_unlock;
- if (!net->ct.sysctl_events)
- goto out_unlock;
-
e = nf_ct_ecache_find(ct);
if (e == NULL)
goto out_unlock;
@@ -118,6 +111,9 @@ nf_conntrack_eventmask_report(unsigned int eventmask,
/* This is a resent of a destroy event? If so, skip missed */
unsigned long missed = e->pid ? 0 : e->missed;
+ if (!((eventmask | missed) & e->ctmask))
+ goto out_unlock;
+
ret = notify->fcn(eventmask | missed, &item);
if (unlikely(ret < 0 || missed)) {
spin_lock_bh(&ct->lock);
@@ -173,18 +169,19 @@ nf_ct_expect_event_report(enum ip_conntrack_expect_events event,
u32 pid,
int report)
{
- struct net *net = nf_ct_exp_net(exp);
struct nf_exp_event_notifier *notify;
+ struct nf_conntrack_ecache *e;
rcu_read_lock();
notify = rcu_dereference(nf_expect_event_cb);
if (notify == NULL)
goto out_unlock;
- if (!net->ct.sysctl_events)
+ e = nf_ct_ecache_find(exp->master);
+ if (e == NULL)
goto out_unlock;
- {
+ if (e->expmask & (1 << event)) {
struct nf_exp_event item = {
.exp = exp,
.pid = pid,