Skip to content

Commit

Permalink
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/gi…
Browse files Browse the repository at this point in the history
…t/kaber/nf-next-2.6
  • Loading branch information
David S. Miller committed Jun 13, 2009
2 parents 5b54814 + 3dd5d7e commit eaae44d
Show file tree
Hide file tree
Showing 12 changed files with 431 additions and 220 deletions.
18 changes: 18 additions & 0 deletions include/linux/list_nulls.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,18 @@ static inline int hlist_nulls_empty(const struct hlist_nulls_head *h)
return is_a_nulls(h->first);
}

static inline void hlist_nulls_add_head(struct hlist_nulls_node *n,
struct hlist_nulls_head *h)
{
struct hlist_nulls_node *first = h->first;

n->next = first;
n->pprev = &h->first;
h->first = n;
if (!is_a_nulls(first))
first->pprev = &n->next;
}

static inline void __hlist_nulls_del(struct hlist_nulls_node *n)
{
struct hlist_nulls_node *next = n->next;
Expand All @@ -65,6 +77,12 @@ static inline void __hlist_nulls_del(struct hlist_nulls_node *n)
next->pprev = pprev;
}

static inline void hlist_nulls_del(struct hlist_nulls_node *n)
{
__hlist_nulls_del(n);
n->pprev = LIST_POISON2;
}

/**
* hlist_nulls_for_each_entry - iterate over list of given type
* @tpos: the type * to use as a loop cursor.
Expand Down
2 changes: 2 additions & 0 deletions include/net/netfilter/nf_conntrack.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,8 @@ extern struct nf_conntrack_tuple_hash *
__nf_conntrack_find(struct net *net, const struct nf_conntrack_tuple *tuple);

extern void nf_conntrack_hash_insert(struct nf_conn *ct);
extern void nf_ct_delete_from_lists(struct nf_conn *ct);
extern void nf_ct_insert_dying_list(struct nf_conn *ct);

extern void nf_conntrack_flush_report(struct net *net, u32 pid, int report);

Expand Down
175 changes: 105 additions & 70 deletions include/net/netfilter/nf_conntrack_ecache.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,61 +6,54 @@
#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 */
unsigned long missed; /* missed events */
u32 pid; /* netlink pid of destroyer */
};

/* 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;
Expand All @@ -76,53 +69,88 @@ 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)
static inline int
nf_conntrack_eventmask_report(unsigned int eventmask,
struct nf_conn *ct,
u32 pid,
int report)
{
int ret = 0;
struct net *net = nf_ct_net(ct);
struct nf_ct_event_notifier *notify;
struct nf_conntrack_ecache *e;

rcu_read_lock();
notify = rcu_dereference(nf_conntrack_event_cb);
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;

if (nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct)) {
struct nf_ct_event item = {
.ct = ct,
.pid = pid,
.pid = e->pid ? e->pid : pid,
.report = report
};
notify->fcn(event, &item);
/* This is a resent of a destroy event? If so, skip missed */
unsigned long missed = e->pid ? 0 : e->missed;

ret = notify->fcn(eventmask | missed, &item);
if (unlikely(ret < 0 || missed)) {
spin_lock_bh(&ct->lock);
if (ret < 0) {
/* This is a destroy event that has been
* triggered by a process, we store the PID
* to include it in the retransmission. */
if (eventmask & (1 << IPCT_DESTROY) &&
e->pid == 0 && pid != 0)
e->pid = pid;
else
e->missed |= eventmask;
} else
e->missed &= ~missed;
spin_unlock_bh(&ct->lock);
}
}
out_unlock:
rcu_read_unlock();
return ret;
}

static inline void
static inline int
nf_conntrack_event_report(enum ip_conntrack_events event, struct nf_conn *ct,
u32 pid, int report)
{
return nf_conntrack_eventmask_report(1 << event, ct, pid, report);
}

static inline int
nf_conntrack_event(enum ip_conntrack_events event, struct nf_conn *ct)
{
nf_conntrack_event_report(event, ct, 0, 0);
return nf_conntrack_eventmask_report(1 << event, ct, 0, 0);
}

struct nf_exp_event {
Expand All @@ -145,20 +173,24 @@ 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();
notify = rcu_dereference(nf_expect_event_cb);
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();
Expand All @@ -178,20 +210,23 @@ 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_event(enum ip_conntrack_events event,
struct nf_conn *ct) {}
static inline void nf_conntrack_event_report(enum ip_conntrack_events event,
struct nf_conn *ct,
u32 pid,
int report) {}
static inline int nf_conntrack_eventmask_report(unsigned int eventmask,
struct nf_conn *ct,
u32 pid,
int report) { return 0; }
static inline int nf_conntrack_event(enum ip_conntrack_events event,
struct nf_conn *ct) { return 0; }
static inline int nf_conntrack_event_report(enum ip_conntrack_events event,
struct nf_conn *ct,
u32 pid,
int report) { return 0; }
static inline void nf_ct_deliver_cached_events(const struct nf_conn *ct) {}
static inline void nf_ct_expect_event(enum ip_conntrack_expect_events event,
struct nf_conntrack_expect *exp) {}
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)
{
Expand Down
2 changes: 2 additions & 0 deletions include/net/netfilter/nf_conntrack_extend.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 2 additions & 0 deletions include/net/netfilter/nf_conntrack_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ extern struct nf_conn_help *nf_ct_helper_ext_add(struct nf_conn *ct, gfp_t gfp);

extern int __nf_ct_try_assign_helper(struct nf_conn *ct, gfp_t flags);

extern void nf_ct_helper_destroy(struct nf_conn *ct);

static inline struct nf_conn_help *nfct_help(const struct nf_conn *ct)
{
return nf_ct_ext_find(ct, NF_CT_EXT_HELPER);
Expand Down
7 changes: 4 additions & 3 deletions include/net/netns/conntrack.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,17 @@ struct netns_ct {
struct hlist_nulls_head *hash;
struct hlist_head *expect_hash;
struct hlist_nulls_head unconfirmed;
struct hlist_nulls_head dying;
struct ip_conntrack_stat *stat;
#ifdef CONFIG_NF_CONNTRACK_EVENTS
struct nf_conntrack_ecache *ecache;
#endif
int sysctl_events;
unsigned int sysctl_events_retry_timeout;
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;
Expand Down
Loading

0 comments on commit eaae44d

Please sign in to comment.