|
@@ -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,
|