Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 122375
b: refs/heads/master
c: 19abb7b
h: refs/heads/master
i:
  122373: 878a4b5
  122371: 7898bc5
  122367: b6d9ffb
v: v3
  • Loading branch information
Pablo Neira Ayuso authored and Patrick McHardy committed Nov 18, 2008
1 parent b7e86b9 commit de0b32a
Show file tree
Hide file tree
Showing 8 changed files with 198 additions and 35 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 226c0c0ef2abdf91b8d9cce1aaf7d4635a5e5926
refs/heads/master: 19abb7b090a6bce88d4e9b2914a0367f4f684432
2 changes: 1 addition & 1 deletion trunk/include/net/netfilter/nf_conntrack.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ __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_conntrack_flush(struct net *net);
extern void nf_conntrack_flush(struct net *net, u32 pid, int report);

extern bool nf_ct_get_tuplepr(const struct sk_buff *skb,
unsigned int nhoff, u_int16_t l3num,
Expand Down
57 changes: 53 additions & 4 deletions trunk/include/net/netfilter/nf_conntrack_ecache.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ struct nf_conntrack_ecache {
unsigned int events;
};

/* This structure is passed to event handler */
struct nf_ct_event {
struct nf_conn *ct;
u32 pid;
int report;
};

extern struct atomic_notifier_head nf_conntrack_chain;
extern int nf_conntrack_register_notifier(struct notifier_block *nb);
extern int nf_conntrack_unregister_notifier(struct notifier_block *nb);
Expand All @@ -39,22 +46,56 @@ nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct)
local_bh_enable();
}

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)
{
struct nf_ct_event item = {
.ct = ct,
.pid = pid,
.report = report
};
if (nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct))
atomic_notifier_call_chain(&nf_conntrack_chain, event, ct);
atomic_notifier_call_chain(&nf_conntrack_chain, event, &item);
}

static inline void
nf_conntrack_event(enum ip_conntrack_events event, struct nf_conn *ct)
{
nf_conntrack_event_report(event, ct, 0, 0);
}

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

extern struct atomic_notifier_head nf_ct_expect_chain;
extern int nf_ct_expect_register_notifier(struct notifier_block *nb);
extern int nf_ct_expect_unregister_notifier(struct notifier_block *nb);

static inline void
nf_ct_expect_event_report(enum ip_conntrack_expect_events event,
struct nf_conntrack_expect *exp,
u32 pid,
int report)
{
struct nf_exp_event item = {
.exp = exp,
.pid = pid,
.report = report
};
atomic_notifier_call_chain(&nf_ct_expect_chain, event, &item);
}

static inline void
nf_ct_expect_event(enum ip_conntrack_expect_events event,
struct nf_conntrack_expect *exp)
{
atomic_notifier_call_chain(&nf_ct_expect_chain, event, exp);
nf_ct_expect_event_report(event, exp, 0, 0);
}

extern int nf_conntrack_ecache_init(struct net *net);
Expand All @@ -66,9 +107,17 @@ 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 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 trunk/include/net/netfilter/nf_conntrack_expect.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ void nf_ct_expect_init(struct nf_conntrack_expect *, unsigned int, u_int8_t,
u_int8_t, const __be16 *, const __be16 *);
void nf_ct_expect_put(struct nf_conntrack_expect *exp);
int nf_ct_expect_related(struct nf_conntrack_expect *expect);
int nf_ct_expect_related_report(struct nf_conntrack_expect *expect,
u32 pid, int report);

#endif /*_NF_CONNTRACK_EXPECT_H*/

25 changes: 21 additions & 4 deletions trunk/net/netfilter/nf_conntrack_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,8 @@ destroy_conntrack(struct nf_conntrack *nfct)
NF_CT_ASSERT(atomic_read(&nfct->use) == 0);
NF_CT_ASSERT(!timer_pending(&ct->timeout));

nf_conntrack_event(IPCT_DESTROY, ct);
if (!test_bit(IPS_DYING_BIT, &ct->status))
nf_conntrack_event(IPCT_DESTROY, ct);
set_bit(IPS_DYING_BIT, &ct->status);

/* To make sure we don't get any weird locking issues here:
Expand Down Expand Up @@ -972,8 +973,20 @@ void nf_ct_iterate_cleanup(struct net *net,
}
EXPORT_SYMBOL_GPL(nf_ct_iterate_cleanup);

struct __nf_ct_flush_report {
u32 pid;
int report;
};

static int kill_all(struct nf_conn *i, void *data)
{
struct __nf_ct_flush_report *fr = (struct __nf_ct_flush_report *)data;

/* get_next_corpse sets the dying bit for us */
nf_conntrack_event_report(IPCT_DESTROY,
i,
fr->pid,
fr->report);
return 1;
}

Expand All @@ -987,9 +1000,13 @@ void nf_ct_free_hashtable(struct hlist_head *hash, int vmalloced, unsigned int s
}
EXPORT_SYMBOL_GPL(nf_ct_free_hashtable);

void nf_conntrack_flush(struct net *net)
void nf_conntrack_flush(struct net *net, u32 pid, int report)
{
nf_ct_iterate_cleanup(net, kill_all, NULL);
struct __nf_ct_flush_report fr = {
.pid = pid,
.report = report,
};
nf_ct_iterate_cleanup(net, kill_all, &fr);
}
EXPORT_SYMBOL_GPL(nf_conntrack_flush);

Expand All @@ -1005,7 +1022,7 @@ static void nf_conntrack_cleanup_net(struct net *net)
nf_ct_event_cache_flush(net);
nf_conntrack_ecache_fini(net);
i_see_dead_people:
nf_conntrack_flush(net);
nf_conntrack_flush(net, 0, 0);
if (atomic_read(&net->ct.count) != 0) {
schedule();
goto i_see_dead_people;
Expand Down
14 changes: 11 additions & 3 deletions trunk/net/netfilter/nf_conntrack_ecache.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,17 @@ static inline void
__nf_ct_deliver_cached_events(struct nf_conntrack_ecache *ecache)
{
if (nf_ct_is_confirmed(ecache->ct) && !nf_ct_is_dying(ecache->ct)
&& ecache->events)
atomic_notifier_call_chain(&nf_conntrack_chain, ecache->events,
ecache->ct);
&& ecache->events) {
struct nf_ct_event item = {
.ct = ecache->ct,
.pid = 0,
.report = 0
};

atomic_notifier_call_chain(&nf_conntrack_chain,
ecache->events,
&item);
}

ecache->events = 0;
nf_ct_put(ecache->ct);
Expand Down
43 changes: 36 additions & 7 deletions trunk/net/netfilter/nf_conntrack_expect.c
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ static inline int refresh_timer(struct nf_conntrack_expect *i)
return 1;
}

int nf_ct_expect_related(struct nf_conntrack_expect *expect)
static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect)
{
const struct nf_conntrack_expect_policy *p;
struct nf_conntrack_expect *i;
Expand All @@ -371,11 +371,8 @@ int nf_ct_expect_related(struct nf_conntrack_expect *expect)
struct net *net = nf_ct_exp_net(expect);
struct hlist_node *n;
unsigned int h;
int ret;

NF_CT_ASSERT(master_help);
int ret = 0;

spin_lock_bh(&nf_conntrack_lock);
if (!master_help->helper) {
ret = -ESHUTDOWN;
goto out;
Expand Down Expand Up @@ -409,18 +406,50 @@ int nf_ct_expect_related(struct nf_conntrack_expect *expect)
printk(KERN_WARNING
"nf_conntrack: expectation table full\n");
ret = -EMFILE;
goto out;
}
out:
return ret;
}

int nf_ct_expect_related(struct nf_conntrack_expect *expect)
{
int ret;

spin_lock_bh(&nf_conntrack_lock);
ret = __nf_ct_expect_check(expect);
if (ret < 0)
goto out;

nf_ct_expect_insert(expect);
atomic_inc(&expect->use);
spin_unlock_bh(&nf_conntrack_lock);
nf_ct_expect_event(IPEXP_NEW, expect);
ret = 0;
nf_ct_expect_put(expect);
return ret;
out:
spin_unlock_bh(&nf_conntrack_lock);
return ret;
}
EXPORT_SYMBOL_GPL(nf_ct_expect_related);

int nf_ct_expect_related_report(struct nf_conntrack_expect *expect,
u32 pid, int report)
{
int ret;

spin_lock_bh(&nf_conntrack_lock);
ret = __nf_ct_expect_check(expect);
if (ret < 0)
goto out;
nf_ct_expect_insert(expect);
out:
spin_unlock_bh(&nf_conntrack_lock);
if (ret == 0)
nf_ct_expect_event_report(IPEXP_NEW, expect, pid, report);
return ret;
}
EXPORT_SYMBOL_GPL(nf_ct_expect_related_report);

#ifdef CONFIG_PROC_FS
struct ct_expect_iter_state {
struct seq_net_private p;
Expand Down
Loading

0 comments on commit de0b32a

Please sign in to comment.