diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/net/netfilter/nf_conntrack_ecache.h | 130 | ||||
-rw-r--r-- | include/net/netfilter/nf_conntrack_extend.h | 2 | ||||
-rw-r--r-- | include/net/netns/conntrack.h | 5 |
3 files changed, 73 insertions, 64 deletions
diff --git a/include/net/netfilter/nf_conntrack_ecache.h b/include/net/netfilter/nf_conntrack_ecache.h index 1afb907e015..e7ae297ba38 100644 --- a/include/net/netfilter/nf_conntrack_ecache.h +++ b/include/net/netfilter/nf_conntrack_ecache.h @@ -6,61 +6,52 @@ #define _NF_CONNTRACK_ECACHE_H #include <net/netfilter/nf_conntrack.h> -#include <linux/interrupt.h> #include <net/net_namespace.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 { - /* 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 -struct nf_conntrack_ecache { - struct nf_conn *ct; - unsigned int events; -}; - /* This structure is passed to event handler */ struct nf_ct_event { 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 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 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 -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; rcu_read_lock(); @@ -107,22 +98,32 @@ nf_conntrack_event_report(enum ip_conntrack_events event, if (notify == NULL) goto out_unlock; + if (!net->ct.sysctl_events) + goto out_unlock; + if (nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct)) { struct nf_ct_event item = { .ct = ct, .pid = pid, .report = report }; - notify->fcn(event, &item); + notify->fcn(eventmask, &item); } out_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 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 { @@ -145,6 +146,7 @@ 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; rcu_read_lock(); @@ -152,13 +154,16 @@ nf_ct_expect_event_report(enum ip_conntrack_expect_events event, if (notify == NULL) goto out_unlock; + if (!net->ct.sysctl_events) + goto out_unlock; + { struct nf_exp_event item = { .exp = exp, .pid = pid, .report = report }; - notify->fcn(event, &item); + notify->fcn(1 << event, &item); } out_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, 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, struct nf_conn *ct) {} 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, u32 pid, int report) {} -static inline void nf_ct_event_cache_flush(struct net *net) {} static inline int nf_conntrack_ecache_init(struct net *net) { diff --git a/include/net/netfilter/nf_conntrack_extend.h b/include/net/netfilter/nf_conntrack_extend.h index da8ee52613a..7f8fc5d123c 100644 --- a/include/net/netfilter/nf_conntrack_extend.h +++ b/include/net/netfilter/nf_conntrack_extend.h @@ -8,12 +8,14 @@ enum nf_ct_ext_id NF_CT_EXT_HELPER, NF_CT_EXT_NAT, NF_CT_EXT_ACCT, + NF_CT_EXT_ECACHE, NF_CT_EXT_NUM, }; #define NF_CT_EXT_HELPER_TYPE struct nf_conn_help #define NF_CT_EXT_NAT_TYPE struct nf_conn_nat #define NF_CT_EXT_ACCT_TYPE struct nf_conn_counter +#define NF_CT_EXT_ECACHE_TYPE struct nf_conntrack_ecache /* Extensions: optional stuff which isn't permanently in struct. */ struct nf_ct_ext { diff --git a/include/net/netns/conntrack.h b/include/net/netns/conntrack.h index 9dc58402bc0..505a51cd8c6 100644 --- a/include/net/netns/conntrack.h +++ b/include/net/netns/conntrack.h @@ -15,15 +15,14 @@ struct netns_ct { struct hlist_head *expect_hash; struct hlist_nulls_head unconfirmed; struct ip_conntrack_stat *stat; -#ifdef CONFIG_NF_CONNTRACK_EVENTS - struct nf_conntrack_ecache *ecache; -#endif + int sysctl_events; int sysctl_acct; int sysctl_checksum; unsigned int sysctl_log_invalid; /* Log invalid packets */ #ifdef CONFIG_SYSCTL struct ctl_table_header *sysctl_header; struct ctl_table_header *acct_sysctl_header; + struct ctl_table_header *event_sysctl_header; #endif int hash_vmalloc; int expect_vmalloc; |