nf_conntrack_ecache.h 5.3 KB
Newer Older
1 2 3 4 5 6 7 8
/*
 * connection tracking event cache.
 */

#ifndef _NF_CONNTRACK_ECACHE_H
#define _NF_CONNTRACK_ECACHE_H
#include <net/netfilter/nf_conntrack.h>

9
#include <net/net_namespace.h>
10
#include <net/netfilter/nf_conntrack_expect.h>
11 12 13
#include <linux/netfilter/nf_conntrack_common.h>
#include <linux/netfilter/nf_conntrack_tuple_common.h>
#include <net/netfilter/nf_conntrack_extend.h>
14

15
/* Connection tracking event types */
16 17
enum ip_conntrack_events
{
18 19 20 21 22 23 24 25 26 27
	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 */
};
28

29 30 31
enum ip_conntrack_expect_events {
	IPEXP_NEW		= 0,	/* new expectation */
};
32

33 34 35
struct nf_conntrack_ecache {
	unsigned long cache;		/* bitops want long */
};
36

37 38 39 40 41
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);
}
42

43 44 45 46
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);
47

48 49
	if (!net->ct.sysctl_events)
		return NULL;
50

51
	return nf_ct_ext_add(ct, NF_CT_EXT_ECACHE, gfp);
52 53
};

54
#ifdef CONFIG_NF_CONNTRACK_EVENTS
55 56 57 58 59 60 61
/* This structure is passed to event handler */
struct nf_ct_event {
	struct nf_conn *ct;
	u32 pid;
	int report;
};

62 63 64 65 66 67 68
struct nf_ct_event_notifier {
	int (*fcn)(unsigned int events, struct nf_ct_event *item);
};

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);
69

70
extern void nf_ct_deliver_cached_events(struct nf_conn *ct);
71 72

static inline void
73
nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct)
74
{
75 76 77 78 79 80 81 82 83 84
	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);
85 86
}

87
static inline void
88 89 90 91
nf_conntrack_eventmask_report(unsigned int eventmask,
			      struct nf_conn *ct,
			      u32 pid,
			      int report)
92
{
93
	struct net *net = nf_ct_net(ct);
94 95 96 97 98 99 100
	struct nf_ct_event_notifier *notify;

	rcu_read_lock();
	notify = rcu_dereference(nf_conntrack_event_cb);
	if (notify == NULL)
		goto out_unlock;

101 102 103
	if (!net->ct.sysctl_events)
		goto out_unlock;

104 105 106 107 108 109
	if (nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct)) {
		struct nf_ct_event item = {
			.ct 	= ct,
			.pid	= pid,
			.report = report
		};
110
		notify->fcn(eventmask, &item);
111 112 113
	}
out_unlock:
	rcu_read_unlock();
114 115
}

116 117 118 119 120 121 122
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);
}

123 124 125
static inline void
nf_conntrack_event(enum ip_conntrack_events event, struct nf_conn *ct)
{
126
	nf_conntrack_eventmask_report(1 << event, ct, 0, 0);
127 128 129 130 131 132 133 134
}

struct nf_exp_event {
	struct nf_conntrack_expect *exp;
	u32 pid;
	int report;
};

135 136 137 138 139 140 141
struct nf_exp_event_notifier {
	int (*fcn)(unsigned int events, struct nf_exp_event *item);
};

extern struct nf_exp_event_notifier *nf_expect_event_cb;
extern int nf_ct_expect_register_notifier(struct nf_exp_event_notifier *nb);
extern void nf_ct_expect_unregister_notifier(struct nf_exp_event_notifier *nb);
142

143 144 145 146 147 148
static inline void
nf_ct_expect_event_report(enum ip_conntrack_expect_events event,
			  struct nf_conntrack_expect *exp,
			  u32 pid,
			  int report)
{
149
	struct net *net = nf_ct_exp_net(exp);
150 151 152 153 154 155 156
	struct nf_exp_event_notifier *notify;

	rcu_read_lock();
	notify = rcu_dereference(nf_expect_event_cb);
	if (notify == NULL)
		goto out_unlock;

157 158 159
	if (!net->ct.sysctl_events)
		goto out_unlock;

160 161 162 163 164 165
	{
		struct nf_exp_event item = {
			.exp	= exp,
			.pid	= pid,
			.report = report
		};
166
		notify->fcn(1 << event, &item);
167 168 169
	}
out_unlock:
	rcu_read_unlock();
170 171
}

172
static inline void
173 174
nf_ct_expect_event(enum ip_conntrack_expect_events event,
		   struct nf_conntrack_expect *exp)
175
{
176
	nf_ct_expect_event_report(event, exp, 0, 0);
177 178
}

179 180 181
extern int nf_conntrack_ecache_init(struct net *net);
extern void nf_conntrack_ecache_fini(struct net *net);

182 183 184
#else /* CONFIG_NF_CONNTRACK_EVENTS */

static inline void nf_conntrack_event_cache(enum ip_conntrack_events event,
185
					    struct nf_conn *ct) {}
186 187 188 189
static inline void nf_conntrack_eventmask_report(unsigned int eventmask,
						 struct nf_conn *ct,
						 u32 pid,
						 int report) {}
190 191
static inline void nf_conntrack_event(enum ip_conntrack_events event,
				      struct nf_conn *ct) {}
192 193 194 195
static inline void nf_conntrack_event_report(enum ip_conntrack_events event,
					     struct nf_conn *ct,
					     u32 pid,
					     int report) {}
196
static inline void nf_ct_deliver_cached_events(const struct nf_conn *ct) {}
197 198
static inline void nf_ct_expect_event(enum ip_conntrack_expect_events event,
				      struct nf_conntrack_expect *exp) {}
199 200 201 202
static inline void nf_ct_expect_event_report(enum ip_conntrack_expect_events e,
					     struct nf_conntrack_expect *exp,
 					     u32 pid,
 					     int report) {}
203 204 205 206

static inline int nf_conntrack_ecache_init(struct net *net)
{
	return 0;
207
}
208 209 210 211

static inline void nf_conntrack_ecache_fini(struct net *net)
{
}
212 213 214 215
#endif /* CONFIG_NF_CONNTRACK_EVENTS */

#endif /*_NF_CONNTRACK_ECACHE_H*/