* [PATCH 1/6] [PATCH] use nf_conntrack_get instead of atomic_inc
@ 2008-10-11 15:21 Pablo Neira Ayuso
2008-10-11 15:21 ` [PATCH 2/6] [PATCH] helper load-on-demand support for ctnetlink Pablo Neira Ayuso
` (4 more replies)
0 siblings, 5 replies; 11+ messages in thread
From: Pablo Neira Ayuso @ 2008-10-11 15:21 UTC (permalink / raw)
To: netfilter-devel; +Cc: kaber
Use nf_conntrack_get instead of the direct call to atomic_inc.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_conntrack_netlink.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index ff8deab..b7a6be8 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -1231,7 +1231,7 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
goto out_unlock;
}
master_ct = nf_ct_tuplehash_to_ctrack(master_h);
- atomic_inc(&master_ct->ct_general.use);
+ nf_conntrack_get(&master_ct->ct_general);
}
spin_unlock_bh(&nf_conntrack_lock);
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 2/6] [PATCH] helper load-on-demand support for ctnetlink
2008-10-11 15:21 [PATCH 1/6] [PATCH] use nf_conntrack_get instead of atomic_inc Pablo Neira Ayuso
@ 2008-10-11 15:21 ` Pablo Neira Ayuso
2008-10-11 15:22 ` [PATCH 3/6] [PATCH] deliver events for conntracks created via ctnetlink Pablo Neira Ayuso
` (3 subsequent siblings)
4 siblings, 0 replies; 11+ messages in thread
From: Pablo Neira Ayuso @ 2008-10-11 15:21 UTC (permalink / raw)
To: netfilter-devel; +Cc: kaber
This patch adds on-request module loading for helpers via ctnetlink.
To do so, we release the locks, load the module and check. If the
helper is present, then it returns EAGAIN to re-start the operation.
With this patch, we support explicit and implicit helper assignment.
This patch also modifies nfnetlink to handle EAGAIN appropriately.
This all is based on a suggestion from Patrick McHardy.
This patch also provides a refactorized function to lookup-and-set
the connection tracking helper. The function removes the exported
symbol __nf_ct_helper_find as it has not clients anymore.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/linux/netfilter/nfnetlink.h | 3 +
include/net/netfilter/nf_conntrack_helper.h | 5 +-
net/netfilter/nf_conntrack_core.c | 28 +---------
net/netfilter/nf_conntrack_helper.c | 33 +++++++++++-
net/netfilter/nf_conntrack_netlink.c | 73 ++++++++++++++++++++++++---
net/netfilter/nfnetlink.c | 12 +++-
6 files changed, 111 insertions(+), 43 deletions(-)
diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h
index 0d8424f..7d8e045 100644
--- a/include/linux/netfilter/nfnetlink.h
+++ b/include/linux/netfilter/nfnetlink.h
@@ -78,6 +78,9 @@ extern int nfnetlink_send(struct sk_buff *skb, u32 pid, unsigned group,
int echo);
extern int nfnetlink_unicast(struct sk_buff *skb, u_int32_t pid, int flags);
+extern void nfnl_lock(void);
+extern void nfnl_unlock(void);
+
#define MODULE_ALIAS_NFNL_SUBSYS(subsys) \
MODULE_ALIAS("nfnetlink-subsys-" __stringify(subsys))
diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h
index f8060ab..8eebf6e 100644
--- a/include/net/netfilter/nf_conntrack_helper.h
+++ b/include/net/netfilter/nf_conntrack_helper.h
@@ -39,9 +39,6 @@ struct nf_conntrack_helper
};
extern struct nf_conntrack_helper *
-__nf_ct_helper_find(const struct nf_conntrack_tuple *tuple);
-
-extern struct nf_conntrack_helper *
__nf_conntrack_helper_find_byname(const char *name);
extern int nf_conntrack_helper_register(struct nf_conntrack_helper *);
@@ -49,6 +46,8 @@ extern void nf_conntrack_helper_unregister(struct nf_conntrack_helper *);
extern struct nf_conn_help *nf_ct_helper_ext_add(struct nf_conn *ct, gfp_t gfp);
+extern int __nf_ct_set_helper(struct nf_conn *ct, gfp_t flags);
+
static inline struct nf_conn_help *nfct_help(const struct nf_conn *ct)
{
return nf_ct_ext_find(ct, NF_CT_EXT_HELPER);
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 27de3c7..54e35f3 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -581,14 +581,7 @@ init_conntrack(struct net *net,
nf_conntrack_get(&ct->master->ct_general);
NF_CT_STAT_INC(net, expect_new);
} else {
- struct nf_conntrack_helper *helper;
-
- helper = __nf_ct_helper_find(&repl_tuple);
- if (helper) {
- help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
- if (help)
- rcu_assign_pointer(help->helper, helper);
- }
+ __nf_ct_set_helper(ct, GFP_ATOMIC);
NF_CT_STAT_INC(net, new);
}
@@ -765,7 +758,6 @@ void nf_conntrack_alter_reply(struct nf_conn *ct,
const struct nf_conntrack_tuple *newreply)
{
struct nf_conn_help *help = nfct_help(ct);
- struct nf_conntrack_helper *helper;
/* Should be unconfirmed, so not in hash table yet */
NF_CT_ASSERT(!nf_ct_is_confirmed(ct));
@@ -778,23 +770,7 @@ void nf_conntrack_alter_reply(struct nf_conn *ct,
return;
rcu_read_lock();
- helper = __nf_ct_helper_find(newreply);
- if (helper == NULL) {
- if (help)
- rcu_assign_pointer(help->helper, NULL);
- goto out;
- }
-
- if (help == NULL) {
- help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
- if (help == NULL)
- goto out;
- } else {
- memset(&help->help, 0, sizeof(help->help));
- }
-
- rcu_assign_pointer(help->helper, helper);
-out:
+ __nf_ct_set_helper(ct, GFP_ATOMIC);
rcu_read_unlock();
}
EXPORT_SYMBOL_GPL(nf_conntrack_alter_reply);
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
index 9c06b9f..86cdbde 100644
--- a/net/netfilter/nf_conntrack_helper.c
+++ b/net/netfilter/nf_conntrack_helper.c
@@ -44,7 +44,7 @@ static unsigned int helper_hash(const struct nf_conntrack_tuple *tuple)
(__force __u16)tuple->src.u.all) % nf_ct_helper_hsize;
}
-struct nf_conntrack_helper *
+static struct nf_conntrack_helper *
__nf_ct_helper_find(const struct nf_conntrack_tuple *tuple)
{
struct nf_conntrack_helper *helper;
@@ -62,7 +62,6 @@ __nf_ct_helper_find(const struct nf_conntrack_tuple *tuple)
}
return NULL;
}
-EXPORT_SYMBOL_GPL(__nf_ct_helper_find);
struct nf_conntrack_helper *
__nf_conntrack_helper_find_byname(const char *name)
@@ -94,6 +93,36 @@ struct nf_conn_help *nf_ct_helper_ext_add(struct nf_conn *ct, gfp_t gfp)
}
EXPORT_SYMBOL_GPL(nf_ct_helper_ext_add);
+int __nf_ct_set_helper(struct nf_conn *ct, gfp_t flags)
+{
+ int ret = 0;
+ struct nf_conntrack_helper *helper;
+ struct nf_conn_help *help = nfct_help(ct);
+
+ helper = __nf_ct_helper_find(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
+ if (helper == NULL) {
+ if (help)
+ rcu_assign_pointer(help->helper, NULL);
+ ret = -ENOENT;
+ goto out;
+ }
+
+ if (help == NULL) {
+ help = nf_ct_helper_ext_add(ct, flags);
+ if (help == NULL) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ } else {
+ memset(&help->help, 0, sizeof(help->help));
+ }
+
+ rcu_assign_pointer(help->helper, helper);
+out:
+ return ret;
+}
+EXPORT_SYMBOL_GPL(__nf_ct_set_helper);
+
static inline int unhelp(struct nf_conntrack_tuple_hash *i,
const struct nf_conntrack_helper *me)
{
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index b7a6be8..8621b48 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -952,8 +952,23 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nlattr *cda[])
}
helper = __nf_conntrack_helper_find_byname(helpname);
- if (helper == NULL)
+ if (helper == NULL) {
+#ifdef CONFIG_KMOD
+ spin_unlock_bh(&nf_conntrack_lock);
+ nfnl_unlock();
+ if (request_module("nfct-helper-%s", helpname) < 0) {
+ nfnl_lock();
+ spin_lock_bh(&nf_conntrack_lock);
+ return -EOPNOTSUPP;
+ }
+ nfnl_lock();
+ spin_lock_bh(&nf_conntrack_lock);
+ helper = __nf_conntrack_helper_find_byname(helpname);
+ if (helper)
+ return -EAGAIN;
+#endif
return -EOPNOTSUPP;
+ }
if (help) {
if (help->helper == helper)
@@ -1117,7 +1132,6 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
{
struct nf_conn *ct;
int err = -EINVAL;
- struct nf_conn_help *help;
struct nf_conntrack_helper *helper;
ct = nf_conntrack_alloc(&init_net, otuple, rtuple, GFP_KERNEL);
@@ -1132,16 +1146,57 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
ct->status |= IPS_CONFIRMED;
rcu_read_lock();
- helper = __nf_ct_helper_find(rtuple);
- if (helper) {
- help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
- if (help == NULL) {
+ if (cda[CTA_HELP]) {
+ char *helpname;
+
+ err = ctnetlink_parse_help(cda[CTA_HELP], &helpname);
+ if (err < 0) {
+ rcu_read_unlock();
+ goto err;
+ }
+
+ helper = __nf_conntrack_helper_find_byname(helpname);
+ if (helper == NULL) {
+ rcu_read_unlock();
+#ifdef CONFIG_KMOD
+ nfnl_unlock();
+ if (request_module("nfct-helper-%s", helpname) < 0) {
+ nfnl_lock();
+ err = -EOPNOTSUPP;
+ goto err;
+ }
+ nfnl_lock();
+ rcu_read_lock();
+ helper = __nf_conntrack_helper_find_byname(helpname);
+ if (helper) {
+ rcu_read_unlock();
+ err = -EAGAIN;
+ goto err;
+ }
+ rcu_read_unlock();
+#endif
+ err = -EOPNOTSUPP;
+ goto err;
+ } else {
+ struct nf_conn_help *help;
+
+ help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
+ if (help == NULL) {
+ rcu_read_unlock();
+ err = -ENOMEM;
+ goto err;
+ }
+
+ /* not in hash table yet so not strictly necessary */
+ rcu_assign_pointer(help->helper, helper);
+ }
+ } else {
+ /* try an implicit helper assignation */
+ err = __nf_ct_set_helper(ct, GFP_ATOMIC);
+ if (err == -ENOMEM) {
rcu_read_unlock();
- err = -ENOMEM;
goto err;
}
- /* not in hash table yet so not strictly necessary */
- rcu_assign_pointer(help->helper, helper);
}
if (cda[CTA_STATUS]) {
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index b75c9c4..4739f9f 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -44,15 +44,17 @@ static struct sock *nfnl = NULL;
static const struct nfnetlink_subsystem *subsys_table[NFNL_SUBSYS_COUNT];
static DEFINE_MUTEX(nfnl_mutex);
-static inline void nfnl_lock(void)
+void nfnl_lock(void)
{
mutex_lock(&nfnl_mutex);
}
+EXPORT_SYMBOL_GPL(nfnl_lock);
-static inline void nfnl_unlock(void)
+void nfnl_unlock(void)
{
mutex_unlock(&nfnl_mutex);
}
+EXPORT_SYMBOL_GPL(nfnl_unlock);
int nfnetlink_subsys_register(const struct nfnetlink_subsystem *n)
{
@@ -132,6 +134,7 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
return 0;
type = nlh->nlmsg_type;
+replay:
ss = nfnetlink_get_subsys(type);
if (!ss) {
#ifdef CONFIG_KMOD
@@ -165,7 +168,10 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
} else
return -EINVAL;
- return nc->call(nfnl, skb, nlh, cda);
+ err = nc->call(nfnl, skb, nlh, cda);
+ if (err == -EAGAIN)
+ goto replay;
+ return err;
}
}
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 3/6] [PATCH] deliver events for conntracks created via ctnetlink
2008-10-11 15:21 [PATCH 1/6] [PATCH] use nf_conntrack_get instead of atomic_inc Pablo Neira Ayuso
2008-10-11 15:21 ` [PATCH 2/6] [PATCH] helper load-on-demand support for ctnetlink Pablo Neira Ayuso
@ 2008-10-11 15:22 ` Pablo Neira Ayuso
2008-10-11 15:22 ` [PATCH 4/6] [PATCH] bump the expectation helper name Pablo Neira Ayuso
` (2 subsequent siblings)
4 siblings, 0 replies; 11+ messages in thread
From: Pablo Neira Ayuso @ 2008-10-11 15:22 UTC (permalink / raw)
To: netfilter-devel; +Cc: kaber
As for now, the creation and update of conntracks via ctnetlink do not
propagate an event to userspace. This can result in inconsistent situations
if several userspace processes modify the connection tracking table by means
of ctnetlink at the same time. Specifically, using the conntrack command
line tool and conntrackd at the same time can trigger unconsistencies.
This patch also modifies the event cache infrastructure to pass the
process PID and the ECHO flag to nfnetlink_send() to report back
to userspace if the process that triggered the change needs so.
Based on a suggestion from Patrick McHardy.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_conntrack.h | 2 -
include/net/netfilter/nf_conntrack_ecache.h | 59 +++++++++++++++++-
include/net/netfilter/nf_conntrack_expect.h | 2 +
net/netfilter/nf_conntrack_core.c | 26 +++++++-
net/netfilter/nf_conntrack_ecache.c | 14 +++-
net/netfilter/nf_conntrack_expect.c | 43 +++++++++++--
net/netfilter/nf_conntrack_netlink.c | 90 ++++++++++++++++++++++-----
7 files changed, 201 insertions(+), 35 deletions(-)
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
index f11255e..2e0c536 100644
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -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,
diff --git a/include/net/netfilter/nf_conntrack_ecache.h b/include/net/netfilter/nf_conntrack_ecache.h
index 35f814c..d1054df 100644
--- a/include/net/netfilter/nf_conntrack_ecache.h
+++ b/include/net/netfilter/nf_conntrack_ecache.h
@@ -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);
@@ -39,22 +46,58 @@ 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);
@@ -66,9 +109,17 @@ static inline void nf_conntrack_event_cache(enum ip_conntrack_events event,
const struct sk_buff *skb) {}
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)
diff --git a/include/net/netfilter/nf_conntrack_expect.h b/include/net/netfilter/nf_conntrack_expect.h
index 37a7fc1..2414475 100644
--- a/include/net/netfilter/nf_conntrack_expect.h
+++ b/include/net/netfilter/nf_conntrack_expect.h
@@ -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*/
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 54e35f3..3a8d80f 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -174,7 +174,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:
@@ -965,8 +966,21 @@ 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;
}
@@ -980,9 +994,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);
@@ -998,7 +1016,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;
diff --git a/net/netfilter/nf_conntrack_ecache.c b/net/netfilter/nf_conntrack_ecache.c
index a5f5e2e..dee4190 100644
--- a/net/netfilter/nf_conntrack_ecache.c
+++ b/net/netfilter/nf_conntrack_ecache.c
@@ -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);
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
index 37a703b..c921b18 100644
--- a/net/netfilter/nf_conntrack_expect.c
+++ b/net/netfilter/nf_conntrack_expect.c
@@ -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;
@@ -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;
@@ -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;
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 8621b48..3d0e9f0 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -410,7 +410,8 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
struct nlmsghdr *nlh;
struct nfgenmsg *nfmsg;
struct nlattr *nest_parms;
- struct nf_conn *ct = (struct nf_conn *)ptr;
+ struct nf_ct_event *item = (struct nf_ct_event *)ptr;
+ struct nf_conn *ct = item->ct;
struct sk_buff *skb;
unsigned int type;
sk_buff_data_t b;
@@ -443,7 +444,7 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
b = skb->tail;
type |= NFNL_SUBSYS_CTNETLINK << 8;
- nlh = NLMSG_PUT(skb, 0, 0, type, sizeof(struct nfgenmsg));
+ nlh = NLMSG_PUT(skb, item->pid, 0, type, sizeof(struct nfgenmsg));
nfmsg = NLMSG_DATA(nlh);
nlh->nlmsg_flags = flags;
@@ -511,7 +512,7 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
rcu_read_unlock();
nlh->nlmsg_len = skb->tail - b;
- nfnetlink_send(skb, 0, group, 0);
+ nfnetlink_send(skb, item->pid, group, item->report);
return NOTIFY_DONE;
nla_put_failure:
@@ -787,7 +788,9 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY, u3);
else {
/* Flush the whole table */
- nf_conntrack_flush(&init_net);
+ nf_conntrack_flush(&init_net,
+ NETLINK_CB(skb).pid,
+ nlmsg_report(nlh));
return 0;
}
@@ -808,6 +811,14 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
}
}
+ nf_conntrack_event_report(IPCT_DESTROY,
+ ct,
+ NETLINK_CB(skb).pid,
+ nlmsg_report(nlh));
+
+ /* death_by_timeout would report the event again */
+ set_bit(IPS_DYING_BIT, &ct->status);
+
nf_ct_kill(ct);
nf_ct_put(ct);
@@ -1124,11 +1135,35 @@ ctnetlink_change_conntrack(struct nf_conn *ct, struct nlattr *cda[])
return 0;
}
+static inline void
+ctnetlink_event_report(struct nf_conn *ct, u32 pid, int report)
+{
+ unsigned int events = 0;
+
+ if (test_bit(IPS_EXPECTED_BIT, &ct->status))
+ events |= IPCT_RELATED;
+ else
+ events |= IPCT_NEW;
+
+ nf_conntrack_event_report(IPCT_STATUS |
+ IPCT_HELPER |
+ IPCT_REFRESH |
+ IPCT_PROTOINFO |
+ IPCT_NATSEQADJ |
+ IPCT_MARK |
+ events,
+ ct,
+ pid,
+ report);
+}
+
static int
ctnetlink_create_conntrack(struct nlattr *cda[],
struct nf_conntrack_tuple *otuple,
struct nf_conntrack_tuple *rtuple,
- struct nf_conn *master_ct)
+ struct nf_conn *master_ct,
+ u32 pid,
+ int report)
{
struct nf_conn *ct;
int err = -EINVAL;
@@ -1148,7 +1183,7 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
rcu_read_lock();
if (cda[CTA_HELP]) {
char *helpname;
-
+
err = ctnetlink_parse_help(cda[CTA_HELP], &helpname);
if (err < 0) {
rcu_read_unlock();
@@ -1228,9 +1263,12 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
ct->master = master_ct;
}
+ nf_conntrack_get(&ct->ct_general);
add_timer(&ct->timeout);
nf_conntrack_hash_insert(ct);
rcu_read_unlock();
+ ctnetlink_event_report(ct, pid, report);
+ nf_ct_put(ct);
return 0;
@@ -1295,7 +1333,9 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
err = ctnetlink_create_conntrack(cda,
&otuple,
&rtuple,
- master_ct);
+ master_ct,
+ NETLINK_CB(skb).pid,
+ nlmsg_report(nlh));
if (err < 0 && master_ct)
nf_ct_put(master_ct);
@@ -1307,6 +1347,8 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
* so there's no need to increase the refcount */
err = -EEXIST;
if (!(nlh->nlmsg_flags & NLM_F_EXCL)) {
+ struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h);
+
/* we only allow nat config for new conntracks */
if (cda[CTA_NAT_SRC] || cda[CTA_NAT_DST]) {
err = -EOPNOTSUPP;
@@ -1317,8 +1359,19 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
err = -EOPNOTSUPP;
goto out_unlock;
}
- err = ctnetlink_change_conntrack(nf_ct_tuplehash_to_ctrack(h),
- cda);
+
+ err = ctnetlink_change_conntrack(ct, cda);
+ if (err == 0) {
+ nf_conntrack_get(&ct->ct_general);
+ spin_unlock_bh(&nf_conntrack_lock);
+ ctnetlink_event_report(ct,
+ NETLINK_CB(skb).pid,
+ nlmsg_report(nlh));
+ nf_ct_put(ct);
+ } else
+ spin_unlock_bh(&nf_conntrack_lock);
+
+ return err;
}
out_unlock:
@@ -1453,7 +1506,8 @@ static int ctnetlink_expect_event(struct notifier_block *this,
{
struct nlmsghdr *nlh;
struct nfgenmsg *nfmsg;
- struct nf_conntrack_expect *exp = (struct nf_conntrack_expect *)ptr;
+ struct nf_exp_event *item = (struct nf_exp_event *)ptr;
+ struct nf_conntrack_expect *exp = item->exp;
struct sk_buff *skb;
unsigned int type;
sk_buff_data_t b;
@@ -1475,7 +1529,7 @@ static int ctnetlink_expect_event(struct notifier_block *this,
b = skb->tail;
type |= NFNL_SUBSYS_CTNETLINK_EXP << 8;
- nlh = NLMSG_PUT(skb, 0, 0, type, sizeof(struct nfgenmsg));
+ nlh = NLMSG_PUT(skb, item->pid, 0, type, sizeof(struct nfgenmsg));
nfmsg = NLMSG_DATA(nlh);
nlh->nlmsg_flags = flags;
@@ -1489,7 +1543,7 @@ static int ctnetlink_expect_event(struct notifier_block *this,
rcu_read_unlock();
nlh->nlmsg_len = skb->tail - b;
- nfnetlink_send(skb, 0, NFNLGRP_CONNTRACK_EXP_NEW, 0);
+ nfnetlink_send(skb, item->pid, NFNLGRP_CONNTRACK_EXP_NEW, item->report);
return NOTIFY_DONE;
nla_put_failure:
@@ -1703,7 +1757,7 @@ ctnetlink_change_expect(struct nf_conntrack_expect *x, struct nlattr *cda[])
}
static int
-ctnetlink_create_expect(struct nlattr *cda[], u_int8_t u3)
+ctnetlink_create_expect(struct nlattr *cda[], u_int8_t u3, u32 pid, int report)
{
struct nf_conntrack_tuple tuple, mask, master_tuple;
struct nf_conntrack_tuple_hash *h = NULL;
@@ -1750,7 +1804,7 @@ ctnetlink_create_expect(struct nlattr *cda[], u_int8_t u3)
memcpy(&exp->mask.src.u3, &mask.src.u3, sizeof(exp->mask.src.u3));
exp->mask.src.u.all = mask.src.u.all;
- err = nf_ct_expect_related(exp);
+ err = nf_ct_expect_related_report(exp, pid, report);
nf_ct_expect_put(exp);
out:
@@ -1783,8 +1837,12 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
if (!exp) {
spin_unlock_bh(&nf_conntrack_lock);
err = -ENOENT;
- if (nlh->nlmsg_flags & NLM_F_CREATE)
- err = ctnetlink_create_expect(cda, u3);
+ if (nlh->nlmsg_flags & NLM_F_CREATE) {
+ err = ctnetlink_create_expect(cda,
+ u3,
+ NETLINK_CB(skb).pid,
+ nlmsg_report(nlh));
+ }
return err;
}
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 4/6] [PATCH] bump the expectation helper name
2008-10-11 15:21 [PATCH 1/6] [PATCH] use nf_conntrack_get instead of atomic_inc Pablo Neira Ayuso
2008-10-11 15:21 ` [PATCH 2/6] [PATCH] helper load-on-demand support for ctnetlink Pablo Neira Ayuso
2008-10-11 15:22 ` [PATCH 3/6] [PATCH] deliver events for conntracks created via ctnetlink Pablo Neira Ayuso
@ 2008-10-11 15:22 ` Pablo Neira Ayuso
2008-10-11 15:22 ` [PATCH 5/6] [PATCH] dynamic calculation of event message size for ctnetlink Pablo Neira Ayuso
2008-10-11 15:23 ` [PATCH 6/6] [PATCH] remove module dependency between ctnetlink and nf_nat Pablo Neira Ayuso
4 siblings, 0 replies; 11+ messages in thread
From: Pablo Neira Ayuso @ 2008-10-11 15:22 UTC (permalink / raw)
To: netfilter-devel; +Cc: kaber
Include the expectation helper name at expectation dumping.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_conntrack_netlink.c | 9 +++++++++
1 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 3d0e9f0..1c459a8 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -1446,6 +1446,7 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb,
const struct nf_conntrack_expect *exp)
{
struct nf_conn *master = exp->master;
+ struct nf_conn_help *help = nfct_help(master);
long timeout = (exp->timeout.expires - jiffies) / HZ;
if (timeout < 0)
@@ -1463,6 +1464,14 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb,
NLA_PUT_BE32(skb, CTA_EXPECT_TIMEOUT, htonl(timeout));
NLA_PUT_BE32(skb, CTA_EXPECT_ID, htonl((unsigned long)exp));
+ if (help) {
+ struct nf_conntrack_helper *helper;
+
+ helper = rcu_dereference(help->helper);
+ if (helper)
+ NLA_PUT_STRING(skb, CTA_EXPECT_HELP_NAME, helper->name);
+ }
+
return 0;
nla_put_failure:
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 5/6] [PATCH] dynamic calculation of event message size for ctnetlink
2008-10-11 15:21 [PATCH 1/6] [PATCH] use nf_conntrack_get instead of atomic_inc Pablo Neira Ayuso
` (2 preceding siblings ...)
2008-10-11 15:22 ` [PATCH 4/6] [PATCH] bump the expectation helper name Pablo Neira Ayuso
@ 2008-10-11 15:22 ` Pablo Neira Ayuso
2008-10-11 15:23 ` [PATCH 6/6] [PATCH] remove module dependency between ctnetlink and nf_nat Pablo Neira Ayuso
4 siblings, 0 replies; 11+ messages in thread
From: Pablo Neira Ayuso @ 2008-10-11 15:22 UTC (permalink / raw)
To: netfilter-devel; +Cc: kaber
This patch adds dynamic message size calculation for ctnetlink. This
reduces CPU consumption since the overhead in the message trimming
is removed.
Based on a suggestion from Patrick McHardy.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_conntrack_l3proto.h | 2
include/net/netfilter/nf_conntrack_l4proto.h | 3 +
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 6 +
net/ipv4/netfilter/nf_conntrack_proto_icmp.c | 8 ++
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 6 +
net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | 8 ++
net/netfilter/nf_conntrack_core.c | 6 +
net/netfilter/nf_conntrack_netlink.c | 103 ++++++++++++++++++++++++
net/netfilter/nf_conntrack_proto_dccp.c | 10 ++
net/netfilter/nf_conntrack_proto_gre.c | 1
net/netfilter/nf_conntrack_proto_sctp.c | 12 +++
net/netfilter/nf_conntrack_proto_tcp.c | 14 +++
net/netfilter/nf_conntrack_proto_udp.c | 2
net/netfilter/nf_conntrack_proto_udplite.c | 2
14 files changed, 182 insertions(+), 1 deletions(-)
diff --git a/include/net/netfilter/nf_conntrack_l3proto.h b/include/net/netfilter/nf_conntrack_l3proto.h
index 0378676..e0007f9 100644
--- a/include/net/netfilter/nf_conntrack_l3proto.h
+++ b/include/net/netfilter/nf_conntrack_l3proto.h
@@ -55,6 +55,8 @@ struct nf_conntrack_l3proto
int (*nlattr_to_tuple)(struct nlattr *tb[],
struct nf_conntrack_tuple *t);
+
+ size_t (*nlattr_size)(void);
const struct nla_policy *nla_policy;
#ifdef CONFIG_SYSCTL
diff --git a/include/net/netfilter/nf_conntrack_l4proto.h b/include/net/netfilter/nf_conntrack_l4proto.h
index 7f2f43c..3c80479 100644
--- a/include/net/netfilter/nf_conntrack_l4proto.h
+++ b/include/net/netfilter/nf_conntrack_l4proto.h
@@ -72,6 +72,8 @@ struct nf_conntrack_l4proto
const struct nf_conntrack_tuple *t);
int (*nlattr_to_tuple)(struct nlattr *tb[],
struct nf_conntrack_tuple *t);
+ size_t (*nlattr_size)(void);
+ size_t (*nlattr_protoinfo_size)(void);
const struct nla_policy *nla_policy;
#ifdef CONFIG_SYSCTL
@@ -115,6 +117,7 @@ extern int nf_ct_port_tuple_to_nlattr(struct sk_buff *skb,
const struct nf_conntrack_tuple *tuple);
extern int nf_ct_port_nlattr_to_tuple(struct nlattr *tb[],
struct nf_conntrack_tuple *t);
+extern size_t nf_ct_port_nlattr_size(void);
extern const struct nla_policy nf_ct_port_nla_policy[];
#ifdef CONFIG_SYSCTL
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index 4a7c352..7b354e5 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -330,6 +330,11 @@ static int ipv4_nlattr_to_tuple(struct nlattr *tb[],
return 0;
}
+
+static size_t ipv4_nlattr_size(void)
+{
+ return nla_total_size(sizeof(u_int32_t))*2;
+}
#endif
static struct nf_sockopt_ops so_getorigdst = {
@@ -350,6 +355,7 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 __read_mostly = {
#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
.tuple_to_nlattr = ipv4_tuple_to_nlattr,
.nlattr_to_tuple = ipv4_nlattr_to_tuple,
+ .nlattr_size = ipv4_nlattr_size,
.nla_policy = ipv4_nla_policy,
#endif
#if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
index 4e88792..9e6bb21 100644
--- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
@@ -262,6 +262,13 @@ static int icmp_nlattr_to_tuple(struct nlattr *tb[],
return 0;
}
+
+static size_t icmp_nlattr_size(void)
+{
+ return nla_total_size(sizeof(u_int8_t)) +
+ nla_total_size(sizeof(u_int8_t)) +
+ nla_total_size(sizeof(u_int16_t));
+}
#endif
#ifdef CONFIG_SYSCTL
@@ -310,6 +317,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_icmp __read_mostly =
#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
.tuple_to_nlattr = icmp_tuple_to_nlattr,
.nlattr_to_tuple = icmp_nlattr_to_tuple,
+ .nlattr_size = icmp_nlattr_size,
.nla_policy = icmp_nla_policy,
#endif
#ifdef CONFIG_SYSCTL
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index e91db16..3bc103d 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -342,6 +342,11 @@ static int ipv6_nlattr_to_tuple(struct nlattr *tb[],
return 0;
}
+
+static size_t ipv6_nlattr_size(void)
+{
+ return nla_total_size(sizeof(u_int32_t)*4)*2;
+}
#endif
struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 __read_mostly = {
@@ -354,6 +359,7 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 __read_mostly = {
#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
.tuple_to_nlattr = ipv6_tuple_to_nlattr,
.nlattr_to_tuple = ipv6_nlattr_to_tuple,
+ .nlattr_size = ipv6_nlattr_size,
.nla_policy = ipv6_nla_policy,
#endif
#ifdef CONFIG_SYSCTL
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
index 0572617..1c32c71 100644
--- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -243,6 +243,13 @@ static int icmpv6_nlattr_to_tuple(struct nlattr *tb[],
return 0;
}
+
+static size_t icmpv6_nlattr_size(void)
+{
+ return nla_total_size(sizeof(u_int8_t)) +
+ nla_total_size(sizeof(u_int8_t)) +
+ nla_total_size(sizeof(u_int16_t));
+}
#endif
#ifdef CONFIG_SYSCTL
@@ -275,6 +282,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6 __read_mostly =
#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
.tuple_to_nlattr = icmpv6_tuple_to_nlattr,
.nlattr_to_tuple = icmpv6_nlattr_to_tuple,
+ .nlattr_size = icmpv6_nlattr_size,
.nla_policy = icmpv6_nla_policy,
#endif
#ifdef CONFIG_SYSCTL
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 3a8d80f..7ca33aa 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -897,6 +897,12 @@ int nf_ct_port_nlattr_to_tuple(struct nlattr *tb[],
return 0;
}
EXPORT_SYMBOL_GPL(nf_ct_port_nlattr_to_tuple);
+
+size_t nf_ct_port_nlattr_size(void)
+{
+ return nla_total_size(sizeof(u_int16_t))*2;
+}
+EXPORT_SYMBOL_GPL(nf_ct_port_nlattr_size);
#endif
/* Used by ipt_REJECT and ip6t_REJECT. */
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 1c459a8..d64f328 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -404,6 +404,107 @@ nla_put_failure:
}
#ifdef CONFIG_NF_CONNTRACK_EVENTS
+static inline size_t calculate_tuple_room_size(const struct nf_conn *ct)
+{
+ struct nf_conntrack_l3proto *l3proto;
+ struct nf_conntrack_l4proto *l4proto;
+ size_t size;
+
+ rcu_read_lock();
+ /* nested attributes CTA_TUPLE_[ORIG|REPLY] plus CTA_TUPLE_IP */
+ size = nla_total_size(0) * 2;
+ l3proto = __nf_ct_l3proto_find(nf_ct_l3num(ct));
+ if (likely(l3proto->nlattr_size))
+ size += l3proto->nlattr_size();
+
+ /* nested attributes CTA_TUPLE_PROTO plus CTA_PROTONUM */
+ size += nla_total_size(0) + nla_total_size(sizeof(u_int8_t));
+ l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct));
+ if (likely(l4proto->nlattr_size))
+ size += l4proto->nlattr_size();
+
+ rcu_read_unlock();
+ return size;
+}
+
+static inline size_t calculate_protoinfo_room_size(const struct nf_conn *ct)
+{
+ size_t size = 0;
+ struct nf_conntrack_l4proto *l4proto;
+
+ rcu_read_lock();
+ l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct));
+ if (l4proto->nlattr_protoinfo_size)
+ size = l4proto->nlattr_protoinfo_size();
+ rcu_read_unlock();
+
+ return size;
+}
+
+static inline size_t calculate_helper_room_size(const struct nf_conn *ct)
+{
+ const struct nf_conn_help *help = nfct_help(ct);
+ struct nf_conntrack_helper *helper;
+ size_t size;
+
+ if (!help)
+ goto out;
+
+ rcu_read_lock();
+ helper = rcu_dereference(help->helper);
+ if (!helper)
+ goto out_unlock;
+
+ size = nla_total_size(0) + /* CTA_HELP */
+ nla_total_size(strlen(helper->name));
+out_unlock:
+ rcu_read_unlock();
+out:
+ return size;
+}
+
+static inline size_t
+ctnetlink_calculate_room_size(const struct nf_conn *ct, unsigned long events)
+{
+ size_t size = NLMSG_SPACE(sizeof(struct nfgenmsg));
+
+ size += calculate_tuple_room_size(ct) * 2 + /* original and reply */
+ nla_total_size(sizeof(u_int32_t)) + /* status */
+ nla_total_size(sizeof(u_int32_t)); /* id */
+
+#ifdef CONFIG_NF_CONNTRACK_MARK
+ if (events & IPCT_MARK || ct->mark)
+ size += nla_total_size(sizeof(u_int32_t));
+#endif
+
+ if (events & IPCT_DESTROY) {
+ const struct nf_conn_counter *acct;
+
+ acct = nf_conn_acct_find(ct);
+ if (acct) {
+ size += nla_total_size(0) * 2 +
+ nla_total_size(sizeof(u_int64_t)) * 2 * 2;
+ }
+ return size;
+ }
+
+ size += nla_total_size(sizeof(u_int32_t)); /* CTA_TIMEOUT */
+ if (events & IPCT_PROTOINFO) {
+ size += calculate_protoinfo_room_size(ct);
+ }if (events & IPCT_HELPER || nfct_help(ct))
+ size += calculate_helper_room_size(ct);
+ if (events & IPCT_RELATED)
+ size += calculate_tuple_room_size(ct->master);
+ if (events & IPCT_NATSEQADJ)
+ size += nla_total_size(0) * 2 +
+ nla_total_size(sizeof(u_int32_t)) * 3 * 2;
+#ifdef CONFIG_NF_CONNTRACK_SECMARK
+ if (events & IPCT_SECMARK || ct->secmark)
+ size += nla_total_size(sizeof(u_int32_t));
+#endif
+ return size;
+}
+
static int ctnetlink_conntrack_event(struct notifier_block *this,
unsigned long events, void *ptr)
{
@@ -437,7 +538,7 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
if (!nfnetlink_has_listeners(group))
return NOTIFY_DONE;
- skb = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC);
+ skb = alloc_skb(ctnetlink_calculate_room_size(ct, events), GFP_ATOMIC);
if (!skb)
return NOTIFY_DONE;
diff --git a/net/netfilter/nf_conntrack_proto_dccp.c b/net/netfilter/nf_conntrack_proto_dccp.c
index 8fcf176..6694173 100644
--- a/net/netfilter/nf_conntrack_proto_dccp.c
+++ b/net/netfilter/nf_conntrack_proto_dccp.c
@@ -657,6 +657,12 @@ static int nlattr_to_dccp(struct nlattr *cda[], struct nf_conn *ct)
write_unlock_bh(&dccp_lock);
return 0;
}
+
+static size_t dccp_nlattr_protoinfo_size(void)
+{
+ return nla_total_size(0)*2 + /* CTA_PROTOINFO */
+ nla_total_size(sizeof(u_int8_t));
+}
#endif
#ifdef CONFIG_SYSCTL
@@ -749,6 +755,8 @@ static struct nf_conntrack_l4proto dccp_proto4 __read_mostly = {
.from_nlattr = nlattr_to_dccp,
.tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
.nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
+ .nlattr_size = nf_ct_port_nlattr_size,
+ .nlattr_protoinfo_size = dccp_nlattr_protoinfo_size,
.nla_policy = nf_ct_port_nla_policy,
#endif
#ifdef CONFIG_SYSCTL
@@ -774,6 +782,8 @@ static struct nf_conntrack_l4proto dccp_proto6 __read_mostly = {
.from_nlattr = nlattr_to_dccp,
.tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
.nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
+ .nlattr_size = nf_ct_port_nlattr_size,
+ .nlattr_protoinfo_size = dccp_nlattr_protoinfo_size,
.nla_policy = nf_ct_port_nla_policy,
#endif
#ifdef CONFIG_SYSCTL
diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c
index a2cdbcb..6e381c9 100644
--- a/net/netfilter/nf_conntrack_proto_gre.c
+++ b/net/netfilter/nf_conntrack_proto_gre.c
@@ -294,6 +294,7 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_gre4 __read_mostly = {
#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
.tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
.nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
+ .nlattr_size = nf_ct_port_nlattr_size,
.nla_policy = nf_ct_port_nla_policy,
#endif
};
diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c
index ae8c260..a867849 100644
--- a/net/netfilter/nf_conntrack_proto_sctp.c
+++ b/net/netfilter/nf_conntrack_proto_sctp.c
@@ -537,6 +537,14 @@ static int nlattr_to_sctp(struct nlattr *cda[], struct nf_conn *ct)
return 0;
}
+
+static size_t sctp_nlattr_protoinfo_size(void)
+{
+ return nla_total_size(0)*2 + /* CTA_PROTOINFO */
+ nla_total_size(sizeof(u_int8_t)) +
+ nla_total_size(sizeof(u_int32_t)) +
+ nla_total_size(sizeof(u_int32_t));
+}
#endif
#ifdef CONFIG_SYSCTL
@@ -671,6 +679,8 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 __read_mostly = {
.from_nlattr = nlattr_to_sctp,
.tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
.nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
+ .nlattr_size = nf_ct_port_nlattr_size,
+ .nlattr_protoinfo_size = sctp_nlattr_protoinfo_size,
.nla_policy = nf_ct_port_nla_policy,
#endif
#ifdef CONFIG_SYSCTL
@@ -699,6 +709,8 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 __read_mostly = {
.from_nlattr = nlattr_to_sctp,
.tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
.nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
+ .nlattr_size = nf_ct_port_nlattr_size,
+ .nlattr_protoinfo_size = sctp_nlattr_protoinfo_size,
.nla_policy = nf_ct_port_nla_policy,
#endif
#ifdef CONFIG_SYSCTL
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index f947ec4..ddc87a3 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -1181,6 +1181,16 @@ static int nlattr_to_tcp(struct nlattr *cda[], struct nf_conn *ct)
return 0;
}
+
+static size_t tcp_nlattr_protoinfo_size(void)
+{
+ return nla_total_size(0)*2 + /* CTA_PROTOINFO */
+ nla_total_size(sizeof(u_int8_t)) +
+ nla_total_size(sizeof(u_int8_t)) +
+ nla_total_size(sizeof(u_int8_t)) +
+ nla_total_size(sizeof(struct nf_ct_tcp_flags)) +
+ nla_total_size(sizeof(struct nf_ct_tcp_flags));
+}
#endif
#ifdef CONFIG_SYSCTL
@@ -1399,6 +1409,8 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4 __read_mostly =
.from_nlattr = nlattr_to_tcp,
.tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
.nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
+ .nlattr_size = nf_ct_port_nlattr_size,
+ .nlattr_protoinfo_size = tcp_nlattr_protoinfo_size,
.nla_policy = nf_ct_port_nla_policy,
#endif
#ifdef CONFIG_SYSCTL
@@ -1429,6 +1441,8 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6 __read_mostly =
.from_nlattr = nlattr_to_tcp,
.tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
.nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
+ .nlattr_size = nf_ct_port_nlattr_size,
+ .nlattr_protoinfo_size = tcp_nlattr_protoinfo_size,
.nla_policy = nf_ct_port_nla_policy,
#endif
#ifdef CONFIG_SYSCTL
diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c
index 7c2ca48..549da2c 100644
--- a/net/netfilter/nf_conntrack_proto_udp.c
+++ b/net/netfilter/nf_conntrack_proto_udp.c
@@ -193,6 +193,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4 __read_mostly =
#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
.tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
.nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
+ .nlattr_size = nf_ct_port_nlattr_size,
.nla_policy = nf_ct_port_nla_policy,
#endif
#ifdef CONFIG_SYSCTL
@@ -220,6 +221,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_udp6 __read_mostly =
#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
.tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
.nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
+ .nlattr_size = nf_ct_port_nlattr_size,
.nla_policy = nf_ct_port_nla_policy,
#endif
#ifdef CONFIG_SYSCTL
diff --git a/net/netfilter/nf_conntrack_proto_udplite.c b/net/netfilter/nf_conntrack_proto_udplite.c
index d22d839..70a21ff 100644
--- a/net/netfilter/nf_conntrack_proto_udplite.c
+++ b/net/netfilter/nf_conntrack_proto_udplite.c
@@ -181,6 +181,7 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite4 __read_mostly =
#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
.tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
.nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
+ .nlattr_size = nf_ct_port_nlattr_size,
.nla_policy = nf_ct_port_nla_policy,
#endif
#ifdef CONFIG_SYSCTL
@@ -204,6 +205,7 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite6 __read_mostly =
#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
.tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
.nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
+ .nlattr_size = nf_ct_port_nlattr_size,
.nla_policy = nf_ct_port_nla_policy,
#endif
#ifdef CONFIG_SYSCTL
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 6/6] [PATCH] remove module dependency between ctnetlink and nf_nat
2008-10-11 15:21 [PATCH 1/6] [PATCH] use nf_conntrack_get instead of atomic_inc Pablo Neira Ayuso
` (3 preceding siblings ...)
2008-10-11 15:22 ` [PATCH 5/6] [PATCH] dynamic calculation of event message size for ctnetlink Pablo Neira Ayuso
@ 2008-10-11 15:23 ` Pablo Neira Ayuso
2008-10-13 13:50 ` Patrick McHardy
4 siblings, 1 reply; 11+ messages in thread
From: Pablo Neira Ayuso @ 2008-10-11 15:23 UTC (permalink / raw)
To: netfilter-devel; +Cc: kaber
This patch removes the module dependency between ctnetlink and
nf_nat by means of an indirect call that is initialized when
nf_nat is loaded. Now, nf_conntrack_netlink only requires
nf_conntrack and nfnetlink.
This patch puts nfnetlink_parse_nat_setup_hook into the
nf_conntrack_core to avoid dependencies between ctnetlink,
nf_conntrack_ipv4 and nf_conntrack_ipv6.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_nat_core.h | 8 ++
net/ipv4/netfilter/nf_nat_core.c | 97 ++++++++++++++++++++++++++++
net/netfilter/nf_conntrack_core.c | 7 ++
net/netfilter/nf_conntrack_netlink.c | 118 +++++++++++-----------------------
4 files changed, 151 insertions(+), 79 deletions(-)
diff --git a/include/net/netfilter/nf_nat_core.h b/include/net/netfilter/nf_nat_core.h
index f29eeb9..5868406 100644
--- a/include/net/netfilter/nf_nat_core.h
+++ b/include/net/netfilter/nf_nat_core.h
@@ -25,4 +25,12 @@ static inline int nf_nat_initialized(struct nf_conn *ct,
else
return test_bit(IPS_DST_NAT_DONE_BIT, &ct->status);
}
+
+struct nlattr;
+
+extern int
+(*nfnetlink_parse_nat_setup_hook)(struct nf_conn *ct,
+ enum nf_nat_manip_type manip,
+ struct nlattr *attr);
+
#endif /* _NF_NAT_CORE_H */
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c
index 2ac9eaf..91ec535 100644
--- a/net/ipv4/netfilter/nf_nat_core.c
+++ b/net/ipv4/netfilter/nf_nat_core.c
@@ -584,6 +584,98 @@ static struct nf_ct_ext_type nat_extend __read_mostly = {
.flags = NF_CT_EXT_F_PREALLOC,
};
+#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
+
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netfilter/nfnetlink_conntrack.h>
+
+static const struct nla_policy protonat_nla_policy[CTA_PROTONAT_MAX+1] = {
+ [CTA_PROTONAT_PORT_MIN] = { .type = NLA_U16 },
+ [CTA_PROTONAT_PORT_MAX] = { .type = NLA_U16 },
+};
+
+static int nfnetlink_parse_nat_proto(struct nlattr *attr,
+ const struct nf_conn *ct,
+ struct nf_nat_range *range)
+{
+ struct nlattr *tb[CTA_PROTONAT_MAX+1];
+ const struct nf_nat_protocol *npt;
+ int err;
+
+ err = nla_parse_nested(tb, CTA_PROTONAT_MAX, attr, protonat_nla_policy);
+ if (err < 0)
+ return err;
+
+ npt = nf_nat_proto_find_get(nf_ct_protonum(ct));
+ if (npt->nlattr_to_range)
+ err = npt->nlattr_to_range(tb, range);
+ nf_nat_proto_put(npt);
+ return err;
+}
+
+static const struct nla_policy nat_nla_policy[CTA_NAT_MAX+1] = {
+ [CTA_NAT_MINIP] = { .type = NLA_U32 },
+ [CTA_NAT_MAXIP] = { .type = NLA_U32 },
+};
+
+static int
+nfnetlink_parse_nat(struct nlattr *nat,
+ const struct nf_conn *ct, struct nf_nat_range *range)
+{
+ struct nlattr *tb[CTA_NAT_MAX+1];
+ int err;
+
+ memset(range, 0, sizeof(*range));
+
+ err = nla_parse_nested(tb, CTA_NAT_MAX, nat, nat_nla_policy);
+ if (err < 0)
+ return err;
+
+ if (tb[CTA_NAT_MINIP])
+ range->min_ip = nla_get_be32(tb[CTA_NAT_MINIP]);
+
+ if (!tb[CTA_NAT_MAXIP])
+ range->max_ip = range->min_ip;
+ else
+ range->max_ip = nla_get_be32(tb[CTA_NAT_MAXIP]);
+
+ if (range->min_ip)
+ range->flags |= IP_NAT_RANGE_MAP_IPS;
+
+ if (!tb[CTA_NAT_PROTO])
+ return 0;
+
+ err = nfnetlink_parse_nat_proto(tb[CTA_NAT_PROTO], ct, range);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+
+static int
+nfnetlink_parse_nat_setup(struct nf_conn *ct,
+ enum nf_nat_manip_type manip,
+ struct nlattr *attr)
+{
+ struct nf_nat_range range;
+
+ if (nfnetlink_parse_nat(attr, ct, &range) < 0)
+ return -EINVAL;
+ if (nf_nat_initialized(ct, manip))
+ return -EEXIST;
+
+ return nf_nat_setup_info(ct, &range, manip);
+}
+#else
+static int
+nfnetlink_parse_nat_setup(struct nf_conn *ct,
+ enum nf_nat_manip_type manip,
+ struct nlattr *attr)
+{
+ return -EOPNOTSUPP;
+}
+#endif
+
static int __net_init nf_nat_net_init(struct net *net)
{
net->ipv4.nat_bysource = nf_ct_alloc_hashtable(&nf_nat_htable_size,
@@ -654,6 +746,9 @@ static int __init nf_nat_init(void)
BUG_ON(nf_nat_seq_adjust_hook != NULL);
rcu_assign_pointer(nf_nat_seq_adjust_hook, nf_nat_seq_adjust);
+ BUG_ON(nfnetlink_parse_nat_setup_hook != NULL);
+ rcu_assign_pointer(nfnetlink_parse_nat_setup_hook,
+ nfnetlink_parse_nat_setup);
return 0;
cleanup_extend:
@@ -667,10 +762,12 @@ static void __exit nf_nat_cleanup(void)
nf_ct_l3proto_put(l3proto);
nf_ct_extend_unregister(&nat_extend);
rcu_assign_pointer(nf_nat_seq_adjust_hook, NULL);
+ rcu_assign_pointer(nfnetlink_parse_nat_setup_hook, NULL);
synchronize_net();
}
MODULE_LICENSE("GPL");
+MODULE_ALIAS("nf-nat-ipv4");
module_init(nf_nat_init);
module_exit(nf_nat_cleanup);
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 7ca33aa..1b13d64 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -38,9 +38,16 @@
#include <net/netfilter/nf_conntrack_core.h>
#include <net/netfilter/nf_conntrack_extend.h>
#include <net/netfilter/nf_conntrack_acct.h>
+#include <net/netfilter/nf_nat.h>
#define NF_CONNTRACK_VERSION "0.5.0"
+unsigned int
+(*nfnetlink_parse_nat_setup_hook)(struct nf_conn *ct,
+ enum nf_nat_manip_type manip,
+ struct nlattr *attr) __read_mostly;
+EXPORT_SYMBOL_GPL(nfnetlink_parse_nat_setup_hook);
+
DEFINE_SPINLOCK(nf_conntrack_lock);
EXPORT_SYMBOL_GPL(nf_conntrack_lock);
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index d64f328..34fc1f5 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -445,7 +445,7 @@ static inline size_t calculate_helper_room_size(const struct nf_conn *ct)
{
const struct nf_conn_help *help = nfct_help(ct);
struct nf_conntrack_helper *helper;
- size_t size;
+ size_t size = 0;
if (!help)
goto out;
@@ -784,71 +784,6 @@ ctnetlink_parse_tuple(struct nlattr *cda[], struct nf_conntrack_tuple *tuple,
return 0;
}
-#ifdef CONFIG_NF_NAT_NEEDED
-static const struct nla_policy protonat_nla_policy[CTA_PROTONAT_MAX+1] = {
- [CTA_PROTONAT_PORT_MIN] = { .type = NLA_U16 },
- [CTA_PROTONAT_PORT_MAX] = { .type = NLA_U16 },
-};
-
-static int nfnetlink_parse_nat_proto(struct nlattr *attr,
- const struct nf_conn *ct,
- struct nf_nat_range *range)
-{
- struct nlattr *tb[CTA_PROTONAT_MAX+1];
- const struct nf_nat_protocol *npt;
- int err;
-
- err = nla_parse_nested(tb, CTA_PROTONAT_MAX, attr, protonat_nla_policy);
- if (err < 0)
- return err;
-
- npt = nf_nat_proto_find_get(nf_ct_protonum(ct));
- if (npt->nlattr_to_range)
- err = npt->nlattr_to_range(tb, range);
- nf_nat_proto_put(npt);
- return err;
-}
-
-static const struct nla_policy nat_nla_policy[CTA_NAT_MAX+1] = {
- [CTA_NAT_MINIP] = { .type = NLA_U32 },
- [CTA_NAT_MAXIP] = { .type = NLA_U32 },
-};
-
-static inline int
-nfnetlink_parse_nat(struct nlattr *nat,
- const struct nf_conn *ct, struct nf_nat_range *range)
-{
- struct nlattr *tb[CTA_NAT_MAX+1];
- int err;
-
- memset(range, 0, sizeof(*range));
-
- err = nla_parse_nested(tb, CTA_NAT_MAX, nat, nat_nla_policy);
- if (err < 0)
- return err;
-
- if (tb[CTA_NAT_MINIP])
- range->min_ip = nla_get_be32(tb[CTA_NAT_MINIP]);
-
- if (!tb[CTA_NAT_MAXIP])
- range->max_ip = range->min_ip;
- else
- range->max_ip = nla_get_be32(tb[CTA_NAT_MAXIP]);
-
- if (range->min_ip)
- range->flags |= IP_NAT_RANGE_MAP_IPS;
-
- if (!tb[CTA_NAT_PROTO])
- return 0;
-
- err = nfnetlink_parse_nat_proto(tb[CTA_NAT_PROTO], ct, range);
- if (err < 0)
- return err;
-
- return 0;
-}
-#endif
-
static inline int
ctnetlink_parse_help(struct nlattr *attr, char **helper_name)
{
@@ -986,6 +921,33 @@ out:
}
static int
+ctnetlink_parse_nat_setup(struct nf_conn *ct,
+ enum nf_nat_manip_type manip,
+ struct nlattr *attr)
+{
+ typeof(nfnetlink_parse_nat_setup_hook) parse_nat_setup;
+
+ parse_nat_setup = rcu_dereference(nfnetlink_parse_nat_setup_hook);
+ if (!parse_nat_setup) {
+#ifdef CONFIG_KMOD
+ spin_unlock_bh(&nf_conntrack_lock);
+ if (request_module("nf-nat-ipv4") < 0) {
+ spin_lock_bh(&nf_conntrack_lock);
+ return -EOPNOTSUPP;
+ }
+ spin_lock_bh(&nf_conntrack_lock);
+ parse_nat_setup =
+ rcu_dereference(nfnetlink_parse_nat_setup_hook);
+ if (parse_nat_setup)
+ return -EAGAIN;
+#endif
+ return -EOPNOTSUPP;
+ }
+
+ return parse_nat_setup(ct, manip, attr);
+}
+
+static int
ctnetlink_change_status(struct nf_conn *ct, struct nlattr *cda[])
{
unsigned long d;
@@ -1008,23 +970,21 @@ ctnetlink_change_status(struct nf_conn *ct, struct nlattr *cda[])
#ifndef CONFIG_NF_NAT_NEEDED
return -EOPNOTSUPP;
#else
- struct nf_nat_range range;
+ int ret;
if (cda[CTA_NAT_DST]) {
- if (nfnetlink_parse_nat(cda[CTA_NAT_DST], ct,
- &range) < 0)
- return -EINVAL;
- if (nf_nat_initialized(ct, IP_NAT_MANIP_DST))
- return -EEXIST;
- nf_nat_setup_info(ct, &range, IP_NAT_MANIP_DST);
+ ret = ctnetlink_parse_nat_setup(ct,
+ IP_NAT_MANIP_DST,
+ cda[CTA_NAT_DST]);
+ if (ret < 0)
+ return ret;
}
if (cda[CTA_NAT_SRC]) {
- if (nfnetlink_parse_nat(cda[CTA_NAT_SRC], ct,
- &range) < 0)
- return -EINVAL;
- if (nf_nat_initialized(ct, IP_NAT_MANIP_SRC))
- return -EEXIST;
- nf_nat_setup_info(ct, &range, IP_NAT_MANIP_SRC);
+ ret = ctnetlink_parse_nat_setup(ct,
+ IP_NAT_MANIP_SRC,
+ cda[CTA_NAT_SRC]);
+ if (ret < 0)
+ return ret;
}
#endif
}
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 6/6] [PATCH] remove module dependency between ctnetlink and nf_nat
2008-10-11 15:23 ` [PATCH 6/6] [PATCH] remove module dependency between ctnetlink and nf_nat Pablo Neira Ayuso
@ 2008-10-13 13:50 ` Patrick McHardy
2008-10-13 14:06 ` Pablo Neira Ayuso
0 siblings, 1 reply; 11+ messages in thread
From: Patrick McHardy @ 2008-10-13 13:50 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
[-- Attachment #1: Type: text/plain, Size: 884 bytes --]
I really can't get the other patches in at this point since they
don't really qualify as bug fixes. I'll start a nf-next tree once
Dave opens up the net-next tree, which will be in about two weeks.
Sorry about that, I know its partially my fault.
I've tried applying this without the others, and it applies and
compiled cleanly with one minor reject:
> --- a/net/netfilter/nf_conntrack_netlink.c
> +++ b/net/netfilter/nf_conntrack_netlink.c
> @@ -445,7 +445,7 @@ static inline size_t calculate_helper_room_size(const struct nf_conn *ct)
> {
> const struct nf_conn_help *help = nfct_help(ct);
> struct nf_conntrack_helper *helper;
> - size_t size;
> + size_t size = 0;
>
> if (!help)
> goto out;
This chunk doesn't apply, but it doesn't seem to belong in the patch
anyway.
Do you want me to apply the patch as attached to this email, or would
you prefer to rediff it?
[-- Attachment #2: x --]
[-- Type: text/plain, Size: 8392 bytes --]
diff --git a/include/net/netfilter/nf_nat_core.h b/include/net/netfilter/nf_nat_core.h
index f29eeb9..5868406 100644
--- a/include/net/netfilter/nf_nat_core.h
+++ b/include/net/netfilter/nf_nat_core.h
@@ -25,4 +25,12 @@ static inline int nf_nat_initialized(struct nf_conn *ct,
else
return test_bit(IPS_DST_NAT_DONE_BIT, &ct->status);
}
+
+struct nlattr;
+
+extern int
+(*nfnetlink_parse_nat_setup_hook)(struct nf_conn *ct,
+ enum nf_nat_manip_type manip,
+ struct nlattr *attr);
+
#endif /* _NF_NAT_CORE_H */
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c
index 2ac9eaf..91ec535 100644
--- a/net/ipv4/netfilter/nf_nat_core.c
+++ b/net/ipv4/netfilter/nf_nat_core.c
@@ -584,6 +584,98 @@ static struct nf_ct_ext_type nat_extend __read_mostly = {
.flags = NF_CT_EXT_F_PREALLOC,
};
+#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
+
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netfilter/nfnetlink_conntrack.h>
+
+static const struct nla_policy protonat_nla_policy[CTA_PROTONAT_MAX+1] = {
+ [CTA_PROTONAT_PORT_MIN] = { .type = NLA_U16 },
+ [CTA_PROTONAT_PORT_MAX] = { .type = NLA_U16 },
+};
+
+static int nfnetlink_parse_nat_proto(struct nlattr *attr,
+ const struct nf_conn *ct,
+ struct nf_nat_range *range)
+{
+ struct nlattr *tb[CTA_PROTONAT_MAX+1];
+ const struct nf_nat_protocol *npt;
+ int err;
+
+ err = nla_parse_nested(tb, CTA_PROTONAT_MAX, attr, protonat_nla_policy);
+ if (err < 0)
+ return err;
+
+ npt = nf_nat_proto_find_get(nf_ct_protonum(ct));
+ if (npt->nlattr_to_range)
+ err = npt->nlattr_to_range(tb, range);
+ nf_nat_proto_put(npt);
+ return err;
+}
+
+static const struct nla_policy nat_nla_policy[CTA_NAT_MAX+1] = {
+ [CTA_NAT_MINIP] = { .type = NLA_U32 },
+ [CTA_NAT_MAXIP] = { .type = NLA_U32 },
+};
+
+static int
+nfnetlink_parse_nat(struct nlattr *nat,
+ const struct nf_conn *ct, struct nf_nat_range *range)
+{
+ struct nlattr *tb[CTA_NAT_MAX+1];
+ int err;
+
+ memset(range, 0, sizeof(*range));
+
+ err = nla_parse_nested(tb, CTA_NAT_MAX, nat, nat_nla_policy);
+ if (err < 0)
+ return err;
+
+ if (tb[CTA_NAT_MINIP])
+ range->min_ip = nla_get_be32(tb[CTA_NAT_MINIP]);
+
+ if (!tb[CTA_NAT_MAXIP])
+ range->max_ip = range->min_ip;
+ else
+ range->max_ip = nla_get_be32(tb[CTA_NAT_MAXIP]);
+
+ if (range->min_ip)
+ range->flags |= IP_NAT_RANGE_MAP_IPS;
+
+ if (!tb[CTA_NAT_PROTO])
+ return 0;
+
+ err = nfnetlink_parse_nat_proto(tb[CTA_NAT_PROTO], ct, range);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+
+static int
+nfnetlink_parse_nat_setup(struct nf_conn *ct,
+ enum nf_nat_manip_type manip,
+ struct nlattr *attr)
+{
+ struct nf_nat_range range;
+
+ if (nfnetlink_parse_nat(attr, ct, &range) < 0)
+ return -EINVAL;
+ if (nf_nat_initialized(ct, manip))
+ return -EEXIST;
+
+ return nf_nat_setup_info(ct, &range, manip);
+}
+#else
+static int
+nfnetlink_parse_nat_setup(struct nf_conn *ct,
+ enum nf_nat_manip_type manip,
+ struct nlattr *attr)
+{
+ return -EOPNOTSUPP;
+}
+#endif
+
static int __net_init nf_nat_net_init(struct net *net)
{
net->ipv4.nat_bysource = nf_ct_alloc_hashtable(&nf_nat_htable_size,
@@ -654,6 +746,9 @@ static int __init nf_nat_init(void)
BUG_ON(nf_nat_seq_adjust_hook != NULL);
rcu_assign_pointer(nf_nat_seq_adjust_hook, nf_nat_seq_adjust);
+ BUG_ON(nfnetlink_parse_nat_setup_hook != NULL);
+ rcu_assign_pointer(nfnetlink_parse_nat_setup_hook,
+ nfnetlink_parse_nat_setup);
return 0;
cleanup_extend:
@@ -667,10 +762,12 @@ static void __exit nf_nat_cleanup(void)
nf_ct_l3proto_put(l3proto);
nf_ct_extend_unregister(&nat_extend);
rcu_assign_pointer(nf_nat_seq_adjust_hook, NULL);
+ rcu_assign_pointer(nfnetlink_parse_nat_setup_hook, NULL);
synchronize_net();
}
MODULE_LICENSE("GPL");
+MODULE_ALIAS("nf-nat-ipv4");
module_init(nf_nat_init);
module_exit(nf_nat_cleanup);
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 27de3c7..622d7c6 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -38,9 +38,16 @@
#include <net/netfilter/nf_conntrack_core.h>
#include <net/netfilter/nf_conntrack_extend.h>
#include <net/netfilter/nf_conntrack_acct.h>
+#include <net/netfilter/nf_nat.h>
#define NF_CONNTRACK_VERSION "0.5.0"
+unsigned int
+(*nfnetlink_parse_nat_setup_hook)(struct nf_conn *ct,
+ enum nf_nat_manip_type manip,
+ struct nlattr *attr) __read_mostly;
+EXPORT_SYMBOL_GPL(nfnetlink_parse_nat_setup_hook);
+
DEFINE_SPINLOCK(nf_conntrack_lock);
EXPORT_SYMBOL_GPL(nf_conntrack_lock);
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index cadfd15..48c9602 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -689,71 +689,6 @@ ctnetlink_parse_tuple(struct nlattr *cda[], struct nf_conntrack_tuple *tuple,
return 0;
}
-#ifdef CONFIG_NF_NAT_NEEDED
-static const struct nla_policy protonat_nla_policy[CTA_PROTONAT_MAX+1] = {
- [CTA_PROTONAT_PORT_MIN] = { .type = NLA_U16 },
- [CTA_PROTONAT_PORT_MAX] = { .type = NLA_U16 },
-};
-
-static int nfnetlink_parse_nat_proto(struct nlattr *attr,
- const struct nf_conn *ct,
- struct nf_nat_range *range)
-{
- struct nlattr *tb[CTA_PROTONAT_MAX+1];
- const struct nf_nat_protocol *npt;
- int err;
-
- err = nla_parse_nested(tb, CTA_PROTONAT_MAX, attr, protonat_nla_policy);
- if (err < 0)
- return err;
-
- npt = nf_nat_proto_find_get(nf_ct_protonum(ct));
- if (npt->nlattr_to_range)
- err = npt->nlattr_to_range(tb, range);
- nf_nat_proto_put(npt);
- return err;
-}
-
-static const struct nla_policy nat_nla_policy[CTA_NAT_MAX+1] = {
- [CTA_NAT_MINIP] = { .type = NLA_U32 },
- [CTA_NAT_MAXIP] = { .type = NLA_U32 },
-};
-
-static inline int
-nfnetlink_parse_nat(struct nlattr *nat,
- const struct nf_conn *ct, struct nf_nat_range *range)
-{
- struct nlattr *tb[CTA_NAT_MAX+1];
- int err;
-
- memset(range, 0, sizeof(*range));
-
- err = nla_parse_nested(tb, CTA_NAT_MAX, nat, nat_nla_policy);
- if (err < 0)
- return err;
-
- if (tb[CTA_NAT_MINIP])
- range->min_ip = nla_get_be32(tb[CTA_NAT_MINIP]);
-
- if (!tb[CTA_NAT_MAXIP])
- range->max_ip = range->min_ip;
- else
- range->max_ip = nla_get_be32(tb[CTA_NAT_MAXIP]);
-
- if (range->min_ip)
- range->flags |= IP_NAT_RANGE_MAP_IPS;
-
- if (!tb[CTA_NAT_PROTO])
- return 0;
-
- err = nfnetlink_parse_nat_proto(tb[CTA_NAT_PROTO], ct, range);
- if (err < 0)
- return err;
-
- return 0;
-}
-#endif
-
static inline int
ctnetlink_parse_help(struct nlattr *attr, char **helper_name)
{
@@ -879,6 +814,33 @@ out:
}
static int
+ctnetlink_parse_nat_setup(struct nf_conn *ct,
+ enum nf_nat_manip_type manip,
+ struct nlattr *attr)
+{
+ typeof(nfnetlink_parse_nat_setup_hook) parse_nat_setup;
+
+ parse_nat_setup = rcu_dereference(nfnetlink_parse_nat_setup_hook);
+ if (!parse_nat_setup) {
+#ifdef CONFIG_KMOD
+ spin_unlock_bh(&nf_conntrack_lock);
+ if (request_module("nf-nat-ipv4") < 0) {
+ spin_lock_bh(&nf_conntrack_lock);
+ return -EOPNOTSUPP;
+ }
+ spin_lock_bh(&nf_conntrack_lock);
+ parse_nat_setup =
+ rcu_dereference(nfnetlink_parse_nat_setup_hook);
+ if (parse_nat_setup)
+ return -EAGAIN;
+#endif
+ return -EOPNOTSUPP;
+ }
+
+ return parse_nat_setup(ct, manip, attr);
+}
+
+static int
ctnetlink_change_status(struct nf_conn *ct, struct nlattr *cda[])
{
unsigned long d;
@@ -901,23 +863,21 @@ ctnetlink_change_status(struct nf_conn *ct, struct nlattr *cda[])
#ifndef CONFIG_NF_NAT_NEEDED
return -EOPNOTSUPP;
#else
- struct nf_nat_range range;
+ int ret;
if (cda[CTA_NAT_DST]) {
- if (nfnetlink_parse_nat(cda[CTA_NAT_DST], ct,
- &range) < 0)
- return -EINVAL;
- if (nf_nat_initialized(ct, IP_NAT_MANIP_DST))
- return -EEXIST;
- nf_nat_setup_info(ct, &range, IP_NAT_MANIP_DST);
+ ret = ctnetlink_parse_nat_setup(ct,
+ IP_NAT_MANIP_DST,
+ cda[CTA_NAT_DST]);
+ if (ret < 0)
+ return ret;
}
if (cda[CTA_NAT_SRC]) {
- if (nfnetlink_parse_nat(cda[CTA_NAT_SRC], ct,
- &range) < 0)
- return -EINVAL;
- if (nf_nat_initialized(ct, IP_NAT_MANIP_SRC))
- return -EEXIST;
- nf_nat_setup_info(ct, &range, IP_NAT_MANIP_SRC);
+ ret = ctnetlink_parse_nat_setup(ct,
+ IP_NAT_MANIP_SRC,
+ cda[CTA_NAT_SRC]);
+ if (ret < 0)
+ return ret;
}
#endif
}
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 6/6] [PATCH] remove module dependency between ctnetlink and nf_nat
2008-10-13 13:50 ` Patrick McHardy
@ 2008-10-13 14:06 ` Pablo Neira Ayuso
2008-10-13 14:08 ` Pablo Neira Ayuso
2008-10-13 14:11 ` Patrick McHardy
0 siblings, 2 replies; 11+ messages in thread
From: Pablo Neira Ayuso @ 2008-10-13 14:06 UTC (permalink / raw)
To: Patrick McHardy; +Cc: netfilter-devel
Patrick McHardy wrote:
> I really can't get the other patches in at this point since they
> don't really qualify as bug fixes. I'll start a nf-next tree once
> Dave opens up the net-next tree, which will be in about two weeks.
OK, I'll keep the patches in a internal queue and I'll resend them once
you announce your nf-next tree in the ML.
BTW, should I re-send even those that didn't not hit 2.6.28 but you said
that were applied, I mean, for example:
http://marc.info/?l=netfilter-devel&m=122355881514337&w=2
http://marc.info/?l=netfilter-devel&m=122355885514404&w=2
http://marc.info/?l=netfilter-devel&m=122364391728099&w=2
I don't mind about doing so.
> Sorry about that, I know its partially my fault.
Never mind, shit happens, I'm fine with having these into 2.6.29. That
will give me more time to synchronize a conntrack-tools 1.0 and a
ctnetlink 1.0 release.
BTW, I still have to send three patches to -stable, I'm going to do that
now, but what tree should I use to diff the changes? The patch should go
into 2.6.24, .25, and .26.
> I've tried applying this without the others, and it applies and
> compiled cleanly with one minor reject:
>
>> --- a/net/netfilter/nf_conntrack_netlink.c
>> +++ b/net/netfilter/nf_conntrack_netlink.c
>> @@ -445,7 +445,7 @@ static inline size_t
>> calculate_helper_room_size(const struct nf_conn *ct)
>> {
>> const struct nf_conn_help *help = nfct_help(ct);
>> struct nf_conntrack_helper *helper;
>> - size_t size;
>> + size_t size = 0;
>>
>> if (!help)
>> goto out;
>
> This chunk doesn't apply, but it doesn't seem to belong in the patch
> anyway.
Sorry, this belongs to patch 5/6.
> Do you want me to apply the patch as attached to this email, or would
> you prefer to rediff it?
No, I'll send you a new patchset once you set your tree. This patch also
needs to include the nfnl_lock/nfnl_unlock logic.
--
"Los honestos son inadaptados sociales" -- Les Luthiers
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 6/6] [PATCH] remove module dependency between ctnetlink and nf_nat
2008-10-13 14:06 ` Pablo Neira Ayuso
@ 2008-10-13 14:08 ` Pablo Neira Ayuso
2008-10-13 14:11 ` Patrick McHardy
2008-10-13 14:11 ` Patrick McHardy
1 sibling, 1 reply; 11+ messages in thread
From: Pablo Neira Ayuso @ 2008-10-13 14:08 UTC (permalink / raw)
To: Patrick McHardy; +Cc: netfilter-devel
Pablo Neira Ayuso wrote:
> Patrick McHardy wrote:
>> Do you want me to apply the patch as attached to this email, or would
>> you prefer to rediff it?
>
> No, I'll send you a new patchset once you set your tree. This patch also
> needs to include the nfnl_lock/nfnl_unlock logic.
Oh, I see, since you want to put this into 2.6.27, I'll see you a patch
for the NAT issue asap and keep the other in the internal queue.
--
"Los honestos son inadaptados sociales" -- Les Luthiers
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 6/6] [PATCH] remove module dependency between ctnetlink and nf_nat
2008-10-13 14:06 ` Pablo Neira Ayuso
2008-10-13 14:08 ` Pablo Neira Ayuso
@ 2008-10-13 14:11 ` Patrick McHardy
1 sibling, 0 replies; 11+ messages in thread
From: Patrick McHardy @ 2008-10-13 14:11 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
Pablo Neira Ayuso wrote:
> Patrick McHardy wrote:
>> I really can't get the other patches in at this point since they
>> don't really qualify as bug fixes. I'll start a nf-next tree once
>> Dave opens up the net-next tree, which will be in about two weeks.
>
> OK, I'll keep the patches in a internal queue and I'll resend them once
> you announce your nf-next tree in the ML.
>
> BTW, should I re-send even those that didn't not hit 2.6.28 but you said
> that were applied, I mean, for example:
>
> http://marc.info/?l=netfilter-devel&m=122355881514337&w=2
> http://marc.info/?l=netfilter-devel&m=122355885514404&w=2
> http://marc.info/?l=netfilter-devel&m=122364391728099&w=2
>
> I don't mind about doing so.
Yes, those were the ones that are my fault :)
>> Sorry about that, I know its partially my fault.
>
> Never mind, shit happens, I'm fine with having these into 2.6.29. That
> will give me more time to synchronize a conntrack-tools 1.0 and a
> ctnetlink 1.0 release.
>
> BTW, I still have to send three patches to -stable, I'm going to do that
> now, but what tree should I use to diff the changes? The patch should go
> into 2.6.24, .25, and .26.
I don't think all of those are still maintained, probably just
2.6.26. The stable trees are on git.kernel.org:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-2.6.24.y.git
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-2.6.25.y.git
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-2.6.26.y.git
and you should diff against the tree(s) you want the patch applied to.
>> I've tried applying this without the others, and it applies and
>> compiled cleanly with one minor reject:
>>
>>> --- a/net/netfilter/nf_conntrack_netlink.c
>>> +++ b/net/netfilter/nf_conntrack_netlink.c
>>> @@ -445,7 +445,7 @@ static inline size_t
>>> calculate_helper_room_size(const struct nf_conn *ct)
>>> {
>>> const struct nf_conn_help *help = nfct_help(ct);
>>> struct nf_conntrack_helper *helper;
>>> - size_t size;
>>> + size_t size = 0;
>>>
>>> if (!help)
>>> goto out;
>> This chunk doesn't apply, but it doesn't seem to belong in the patch
>> anyway.
>
> Sorry, this belongs to patch 5/6.
>
>> Do you want me to apply the patch as attached to this email, or would
>> you prefer to rediff it?
>
> No, I'll send you a new patchset once you set your tree. This patch also
> needs to include the nfnl_lock/nfnl_unlock logic.
OK. This one would be suitable for 2.6.28 though.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 6/6] [PATCH] remove module dependency between ctnetlink and nf_nat
2008-10-13 14:08 ` Pablo Neira Ayuso
@ 2008-10-13 14:11 ` Patrick McHardy
0 siblings, 0 replies; 11+ messages in thread
From: Patrick McHardy @ 2008-10-13 14:11 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
Pablo Neira Ayuso wrote:
> Pablo Neira Ayuso wrote:
>> Patrick McHardy wrote:
>>> Do you want me to apply the patch as attached to this email, or would
>>> you prefer to rediff it?
>> No, I'll send you a new patchset once you set your tree. This patch also
>> needs to include the nfnl_lock/nfnl_unlock logic.
>
> Oh, I see, since you want to put this into 2.6.27, I'll see you a patch
> for the NAT issue asap and keep the other in the internal queue.
Great, thanks a lot.
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2008-10-13 14:11 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-10-11 15:21 [PATCH 1/6] [PATCH] use nf_conntrack_get instead of atomic_inc Pablo Neira Ayuso
2008-10-11 15:21 ` [PATCH 2/6] [PATCH] helper load-on-demand support for ctnetlink Pablo Neira Ayuso
2008-10-11 15:22 ` [PATCH 3/6] [PATCH] deliver events for conntracks created via ctnetlink Pablo Neira Ayuso
2008-10-11 15:22 ` [PATCH 4/6] [PATCH] bump the expectation helper name Pablo Neira Ayuso
2008-10-11 15:22 ` [PATCH 5/6] [PATCH] dynamic calculation of event message size for ctnetlink Pablo Neira Ayuso
2008-10-11 15:23 ` [PATCH 6/6] [PATCH] remove module dependency between ctnetlink and nf_nat Pablo Neira Ayuso
2008-10-13 13:50 ` Patrick McHardy
2008-10-13 14:06 ` Pablo Neira Ayuso
2008-10-13 14:08 ` Pablo Neira Ayuso
2008-10-13 14:11 ` Patrick McHardy
2008-10-13 14:11 ` Patrick McHardy
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.