|
@@ -6,61 +6,52 @@
|
|
#define _NF_CONNTRACK_ECACHE_H
|
|
#define _NF_CONNTRACK_ECACHE_H
|
|
#include <net/netfilter/nf_conntrack.h>
|
|
#include <net/netfilter/nf_conntrack.h>
|
|
|
|
|
|
-#include <linux/interrupt.h>
|
|
|
|
#include <net/net_namespace.h>
|
|
#include <net/net_namespace.h>
|
|
#include <net/netfilter/nf_conntrack_expect.h>
|
|
#include <net/netfilter/nf_conntrack_expect.h>
|
|
|
|
+#include <linux/netfilter/nf_conntrack_common.h>
|
|
|
|
+#include <linux/netfilter/nf_conntrack_tuple_common.h>
|
|
|
|
+#include <net/netfilter/nf_conntrack_extend.h>
|
|
|
|
|
|
-/* Connection tracking event bits */
|
|
|
|
|
|
+/* Connection tracking event types */
|
|
enum ip_conntrack_events
|
|
enum ip_conntrack_events
|
|
{
|
|
{
|
|
- /* New conntrack */
|
|
|
|
- IPCT_NEW_BIT = 0,
|
|
|
|
- IPCT_NEW = (1 << IPCT_NEW_BIT),
|
|
|
|
-
|
|
|
|
- /* Expected connection */
|
|
|
|
- IPCT_RELATED_BIT = 1,
|
|
|
|
- IPCT_RELATED = (1 << IPCT_RELATED_BIT),
|
|
|
|
-
|
|
|
|
- /* Destroyed conntrack */
|
|
|
|
- IPCT_DESTROY_BIT = 2,
|
|
|
|
- IPCT_DESTROY = (1 << IPCT_DESTROY_BIT),
|
|
|
|
-
|
|
|
|
- /* Status has changed */
|
|
|
|
- IPCT_STATUS_BIT = 3,
|
|
|
|
- IPCT_STATUS = (1 << IPCT_STATUS_BIT),
|
|
|
|
|
|
+ IPCT_NEW = 0, /* new conntrack */
|
|
|
|
+ IPCT_RELATED = 1, /* related conntrack */
|
|
|
|
+ IPCT_DESTROY = 2, /* destroyed conntrack */
|
|
|
|
+ IPCT_STATUS = 3, /* status has changed */
|
|
|
|
+ IPCT_PROTOINFO = 4, /* protocol information has changed */
|
|
|
|
+ IPCT_HELPER = 5, /* new helper has been set */
|
|
|
|
+ IPCT_MARK = 6, /* new mark has been set */
|
|
|
|
+ IPCT_NATSEQADJ = 7, /* NAT is doing sequence adjustment */
|
|
|
|
+ IPCT_SECMARK = 8, /* new security mark has been set */
|
|
|
|
+};
|
|
|
|
|
|
- /* Update of protocol info */
|
|
|
|
- IPCT_PROTOINFO_BIT = 4,
|
|
|
|
- IPCT_PROTOINFO = (1 << IPCT_PROTOINFO_BIT),
|
|
|
|
|
|
+enum ip_conntrack_expect_events {
|
|
|
|
+ IPEXP_NEW = 0, /* new expectation */
|
|
|
|
+};
|
|
|
|
|
|
- /* New helper for conntrack */
|
|
|
|
- IPCT_HELPER_BIT = 5,
|
|
|
|
- IPCT_HELPER = (1 << IPCT_HELPER_BIT),
|
|
|
|
|
|
+struct nf_conntrack_ecache {
|
|
|
|
+ unsigned long cache; /* bitops want long */
|
|
|
|
+};
|
|
|
|
|
|
- /* Mark is set */
|
|
|
|
- IPCT_MARK_BIT = 6,
|
|
|
|
- IPCT_MARK = (1 << IPCT_MARK_BIT),
|
|
|
|
|
|
+static inline struct nf_conntrack_ecache *
|
|
|
|
+nf_ct_ecache_find(const struct nf_conn *ct)
|
|
|
|
+{
|
|
|
|
+ return nf_ct_ext_find(ct, NF_CT_EXT_ECACHE);
|
|
|
|
+}
|
|
|
|
|
|
- /* NAT sequence adjustment */
|
|
|
|
- IPCT_NATSEQADJ_BIT = 7,
|
|
|
|
- IPCT_NATSEQADJ = (1 << IPCT_NATSEQADJ_BIT),
|
|
|
|
|
|
+static inline struct nf_conntrack_ecache *
|
|
|
|
+nf_ct_ecache_ext_add(struct nf_conn *ct, gfp_t gfp)
|
|
|
|
+{
|
|
|
|
+ struct net *net = nf_ct_net(ct);
|
|
|
|
|
|
- /* Secmark is set */
|
|
|
|
- IPCT_SECMARK_BIT = 8,
|
|
|
|
- IPCT_SECMARK = (1 << IPCT_SECMARK_BIT),
|
|
|
|
-};
|
|
|
|
|
|
+ if (!net->ct.sysctl_events)
|
|
|
|
+ return NULL;
|
|
|
|
|
|
-enum ip_conntrack_expect_events {
|
|
|
|
- IPEXP_NEW_BIT = 0,
|
|
|
|
- IPEXP_NEW = (1 << IPEXP_NEW_BIT),
|
|
|
|
|
|
+ return nf_ct_ext_add(ct, NF_CT_EXT_ECACHE, gfp);
|
|
};
|
|
};
|
|
|
|
|
|
#ifdef CONFIG_NF_CONNTRACK_EVENTS
|
|
#ifdef CONFIG_NF_CONNTRACK_EVENTS
|
|
-struct nf_conntrack_ecache {
|
|
|
|
- struct nf_conn *ct;
|
|
|
|
- unsigned int events;
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
/* This structure is passed to event handler */
|
|
/* This structure is passed to event handler */
|
|
struct nf_ct_event {
|
|
struct nf_ct_event {
|
|
struct nf_conn *ct;
|
|
struct nf_conn *ct;
|
|
@@ -76,30 +67,30 @@ extern struct nf_ct_event_notifier *nf_conntrack_event_cb;
|
|
extern int nf_conntrack_register_notifier(struct nf_ct_event_notifier *nb);
|
|
extern int nf_conntrack_register_notifier(struct nf_ct_event_notifier *nb);
|
|
extern void nf_conntrack_unregister_notifier(struct nf_ct_event_notifier *nb);
|
|
extern void nf_conntrack_unregister_notifier(struct nf_ct_event_notifier *nb);
|
|
|
|
|
|
-extern void nf_ct_deliver_cached_events(const struct nf_conn *ct);
|
|
|
|
-extern void __nf_ct_event_cache_init(struct nf_conn *ct);
|
|
|
|
-extern void nf_ct_event_cache_flush(struct net *net);
|
|
|
|
|
|
+extern void nf_ct_deliver_cached_events(struct nf_conn *ct);
|
|
|
|
|
|
static inline void
|
|
static inline void
|
|
nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct)
|
|
nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct)
|
|
{
|
|
{
|
|
- struct net *net = nf_ct_net(ct);
|
|
|
|
- struct nf_conntrack_ecache *ecache;
|
|
|
|
-
|
|
|
|
- local_bh_disable();
|
|
|
|
- ecache = per_cpu_ptr(net->ct.ecache, raw_smp_processor_id());
|
|
|
|
- if (ct != ecache->ct)
|
|
|
|
- __nf_ct_event_cache_init(ct);
|
|
|
|
- ecache->events |= event;
|
|
|
|
- local_bh_enable();
|
|
|
|
|
|
+ struct nf_conntrack_ecache *e;
|
|
|
|
+
|
|
|
|
+ if (nf_conntrack_event_cb == NULL)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ e = nf_ct_ecache_find(ct);
|
|
|
|
+ if (e == NULL)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ set_bit(event, &e->cache);
|
|
}
|
|
}
|
|
|
|
|
|
static inline void
|
|
static inline void
|
|
-nf_conntrack_event_report(enum ip_conntrack_events event,
|
|
|
|
- struct nf_conn *ct,
|
|
|
|
- u32 pid,
|
|
|
|
- int report)
|
|
|
|
|
|
+nf_conntrack_eventmask_report(unsigned int eventmask,
|
|
|
|
+ struct nf_conn *ct,
|
|
|
|
+ u32 pid,
|
|
|
|
+ int report)
|
|
{
|
|
{
|
|
|
|
+ struct net *net = nf_ct_net(ct);
|
|
struct nf_ct_event_notifier *notify;
|
|
struct nf_ct_event_notifier *notify;
|
|
|
|
|
|
rcu_read_lock();
|
|
rcu_read_lock();
|
|
@@ -107,22 +98,32 @@ nf_conntrack_event_report(enum ip_conntrack_events event,
|
|
if (notify == NULL)
|
|
if (notify == NULL)
|
|
goto out_unlock;
|
|
goto out_unlock;
|
|
|
|
|
|
|
|
+ if (!net->ct.sysctl_events)
|
|
|
|
+ goto out_unlock;
|
|
|
|
+
|
|
if (nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct)) {
|
|
if (nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct)) {
|
|
struct nf_ct_event item = {
|
|
struct nf_ct_event item = {
|
|
.ct = ct,
|
|
.ct = ct,
|
|
.pid = pid,
|
|
.pid = pid,
|
|
.report = report
|
|
.report = report
|
|
};
|
|
};
|
|
- notify->fcn(event, &item);
|
|
|
|
|
|
+ notify->fcn(eventmask, &item);
|
|
}
|
|
}
|
|
out_unlock:
|
|
out_unlock:
|
|
rcu_read_unlock();
|
|
rcu_read_unlock();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static inline void
|
|
|
|
+nf_conntrack_event_report(enum ip_conntrack_events event, struct nf_conn *ct,
|
|
|
|
+ u32 pid, int report)
|
|
|
|
+{
|
|
|
|
+ nf_conntrack_eventmask_report(1 << event, ct, pid, report);
|
|
|
|
+}
|
|
|
|
+
|
|
static inline void
|
|
static inline void
|
|
nf_conntrack_event(enum ip_conntrack_events event, struct nf_conn *ct)
|
|
nf_conntrack_event(enum ip_conntrack_events event, struct nf_conn *ct)
|
|
{
|
|
{
|
|
- nf_conntrack_event_report(event, ct, 0, 0);
|
|
|
|
|
|
+ nf_conntrack_eventmask_report(1 << event, ct, 0, 0);
|
|
}
|
|
}
|
|
|
|
|
|
struct nf_exp_event {
|
|
struct nf_exp_event {
|
|
@@ -145,6 +146,7 @@ nf_ct_expect_event_report(enum ip_conntrack_expect_events event,
|
|
u32 pid,
|
|
u32 pid,
|
|
int report)
|
|
int report)
|
|
{
|
|
{
|
|
|
|
+ struct net *net = nf_ct_exp_net(exp);
|
|
struct nf_exp_event_notifier *notify;
|
|
struct nf_exp_event_notifier *notify;
|
|
|
|
|
|
rcu_read_lock();
|
|
rcu_read_lock();
|
|
@@ -152,13 +154,16 @@ nf_ct_expect_event_report(enum ip_conntrack_expect_events event,
|
|
if (notify == NULL)
|
|
if (notify == NULL)
|
|
goto out_unlock;
|
|
goto out_unlock;
|
|
|
|
|
|
|
|
+ if (!net->ct.sysctl_events)
|
|
|
|
+ goto out_unlock;
|
|
|
|
+
|
|
{
|
|
{
|
|
struct nf_exp_event item = {
|
|
struct nf_exp_event item = {
|
|
.exp = exp,
|
|
.exp = exp,
|
|
.pid = pid,
|
|
.pid = pid,
|
|
.report = report
|
|
.report = report
|
|
};
|
|
};
|
|
- notify->fcn(event, &item);
|
|
|
|
|
|
+ notify->fcn(1 << event, &item);
|
|
}
|
|
}
|
|
out_unlock:
|
|
out_unlock:
|
|
rcu_read_unlock();
|
|
rcu_read_unlock();
|
|
@@ -178,6 +183,10 @@ extern void nf_conntrack_ecache_fini(struct net *net);
|
|
|
|
|
|
static inline void nf_conntrack_event_cache(enum ip_conntrack_events event,
|
|
static inline void nf_conntrack_event_cache(enum ip_conntrack_events event,
|
|
struct nf_conn *ct) {}
|
|
struct nf_conn *ct) {}
|
|
|
|
+static inline void nf_conntrack_eventmask_report(unsigned int eventmask,
|
|
|
|
+ struct nf_conn *ct,
|
|
|
|
+ u32 pid,
|
|
|
|
+ int report) {}
|
|
static inline void nf_conntrack_event(enum ip_conntrack_events event,
|
|
static inline void nf_conntrack_event(enum ip_conntrack_events event,
|
|
struct nf_conn *ct) {}
|
|
struct nf_conn *ct) {}
|
|
static inline void nf_conntrack_event_report(enum ip_conntrack_events event,
|
|
static inline void nf_conntrack_event_report(enum ip_conntrack_events event,
|
|
@@ -191,7 +200,6 @@ static inline void nf_ct_expect_event_report(enum ip_conntrack_expect_events e,
|
|
struct nf_conntrack_expect *exp,
|
|
struct nf_conntrack_expect *exp,
|
|
u32 pid,
|
|
u32 pid,
|
|
int report) {}
|
|
int report) {}
|
|
-static inline void nf_ct_event_cache_flush(struct net *net) {}
|
|
|
|
|
|
|
|
static inline int nf_conntrack_ecache_init(struct net *net)
|
|
static inline int nf_conntrack_ecache_init(struct net *net)
|
|
{
|
|
{
|