Skip to contentSkip to conversation

use nf_conntrack_get instead of atomic_inc

PATCH In review Pablo Neira Ayuso 2 participants 11 messages Oct 11, 2008 – Oct 13, 2008

Subsystems (2)
lore
Share & tools
lore

Pablo Neira Ayuso

author maintainer
#0 lore raw

PATCH 1/6 use nf_conntrack_get instead of atomic_inc

Use nf_conntrack_get instead of the direct call to atomic_inc.

---

 net/netfilter/nf_conntrack_netlink.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
net/netfilter/nf_conntrack_netlink.c +1 -1
index ff8deab..b7a6be8 100644
@@ -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);
author maintainer
#1 lore raw

PATCH 2/6 helper load-on-demand support for ctnetlink

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.

---

 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(-)
include/linux/netfilter/nfnetlink.h +3 -0
index 0d8424f..7d8e045 100644
@@ -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))
 
include/net/netfilter/nf_conntrack_helper.h +2 -3
index f8060ab..8eebf6e 100644
@@ -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);
net/netfilter/nf_conntrack_core.c +2 -26
index 27de3c7..54e35f3 100644
@@ -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);
net/netfilter/nf_conntrack_helper.c +31 -2
index 9c06b9f..86cdbde 100644
@@ -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)
 {
net/netfilter/nf_conntrack_netlink.c +64 -9

95 lines not on this page · raw message

net/netfilter/nfnetlink.c +9 -3
index b75c9c4..4739f9f 100644
@@ -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;
 	}
 }
 
author maintainer
#2 lore raw

PATCH 3/6 deliver events for conntracks created via ctnetlink

In reply to Pablo Neira Ayuso

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.

---

 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(-)
include/net/netfilter/nf_conntrack.h +1 -1
index f11255e..2e0c536 100644
@@ -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,
include/net/netfilter/nf_conntrack_ecache.h +55 -4

92 lines not on this page · raw message

include/net/netfilter/nf_conntrack_expect.h +2 -0
index 37a7fc1..2414475 100644
@@ -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*/
 
net/netfilter/nf_conntrack_core.c +22 -4
index 54e35f3..3a8d80f 100644
@@ -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;
net/netfilter/nf_conntrack_ecache.c +11 -3
index a5f5e2e..dee4190 100644
@@ -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);
net/netfilter/nf_conntrack_expect.c +36 -7

72 lines not on this page · raw message

net/netfilter/nf_conntrack_netlink.c +74 -16

199 lines not on this page · raw message

author maintainer
#3 lore raw

PATCH 4/6 bump the expectation helper name

In reply to Pablo Neira Ayuso

Include the expectation helper name at expectation dumping.

---

 net/netfilter/nf_conntrack_netlink.c |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)
net/netfilter/nf_conntrack_netlink.c +9 -0
index 3d0e9f0..1c459a8 100644
@@ -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:
author maintainer
#4 lore raw

PATCH 5/6 dynamic calculation of event message size for ctnetlink

In reply to Pablo Neira Ayuso

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.

---

 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(-)
include/net/netfilter/nf_conntrack_l3proto.h +2 -0
index 0378676..e0007f9 100644
@@ -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
include/net/netfilter/nf_conntrack_l4proto.h +3 -0
index 7f2f43c..3c80479 100644
@@ -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
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +6 -0
index 4a7c352..7b354e5 100644
@@ -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)
net/ipv4/netfilter/nf_conntrack_proto_icmp.c +8 -0
index 4e88792..9e6bb21 100644
@@ -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
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +6 -0
index e91db16..3bc103d 100644
@@ -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
net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c +8 -0
index 0572617..1c32c71 100644
@@ -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
net/netfilter/nf_conntrack_core.c +6 -0
index 3a8d80f..7ca33aa 100644
@@ -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. */
net/netfilter/nf_conntrack_netlink.c +102 -1

115 lines not on this page · raw message

net/netfilter/nf_conntrack_proto_dccp.c +10 -0
index 8fcf176..6694173 100644
@@ -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
net/netfilter/nf_conntrack_proto_gre.c +1 -0
index a2cdbcb..6e381c9 100644
@@ -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
 };
net/netfilter/nf_conntrack_proto_sctp.c +12 -0
index ae8c260..a867849 100644
@@ -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
net/netfilter/nf_conntrack_proto_tcp.c +14 -0
index f947ec4..ddc87a3 100644
@@ -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
net/netfilter/nf_conntrack_proto_udp.c +2 -0
index 7c2ca48..549da2c 100644
@@ -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
net/netfilter/nf_conntrack_proto_udplite.c +2 -0
index d22d839..70a21ff 100644
@@ -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
author maintainer
#5 lore raw

PATCH 6/6 remove module dependency between ctnetlink and nf_nat

In reply to Pablo Neira Ayuso

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.

---

 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(-)
include/net/netfilter/nf_nat_core.h +8 -0
index f29eeb9..5868406 100644
@@ -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 */
net/ipv4/netfilter/nf_nat_core.c +97 -0

119 lines not on this page · raw message

net/netfilter/nf_conntrack_core.c +7 -0
index 7ca33aa..1b13d64 100644
@@ -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);
 
net/netfilter/nf_conntrack_netlink.c +39 -79

146 lines not on this page · raw message

#6 lore raw

Re: [PATCH 6/6] [PATCH] remove module dependency between ctnetlink and nf_nat

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:

net/netfilter/nf_conntrack_netlink.c static inline size_t calculate_helper_room_size(const struct nf_conn *ct) · line 451

Quoted 11 lines
net/netfilter/nf_conntrack_netlink.c +1 -1
@@ -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?

include/net/netfilter/nf_nat_core.h +8 -0
index f29eeb9..5868406 100644
@@ -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 */
net/ipv4/netfilter/nf_nat_core.c +97 -0

119 lines not on this page · raw message

net/netfilter/nf_conntrack_core.c +7 -0
index 27de3c7..622d7c6 100644
@@ -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);
 
net/netfilter/nf_conntrack_netlink.c +38 -78

138 lines not on this page · raw message

author maintainer
#7 lore raw

Re: [PATCH 6/6] [PATCH] remove module dependency between ctnetlink and nf_nat

Quoted 3 lines · Patrick McHardy

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.

Quoted 1 line

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.

Quoted 13 lines

I've tried applying this without the others, and it applies and compiled cleanly with one minor reject:

Quoted 10 lines
net/netfilter/nf_conntrack_netlink.c +1 -1
@@ -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;
 
Quoted 5 lines
Quoted 2 lines
net/netfilter/nf_conntrack_netlink.c +0 -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.

Quoted 2 lines

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.

Signature · 1 line
"Los honestos son inadaptados sociales" -- Les Luthiers
author maintainer
#8 lore raw

Re: [PATCH 6/6] [PATCH] remove module dependency between ctnetlink and nf_nat

Quoted 6 lines · Pablo Neira Ayuso
Quoted 2 lines · Patrick McHardy

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.

Signature · 1 line
"Los honestos son inadaptados sociales" -- Les Luthiers
#9 lore raw

Re: [PATCH 6/6] [PATCH] remove module dependency between ctnetlink and nf_nat

Quoted 9 lines · Pablo Neira Ayuso
Quoted 5 lines · Pablo Neira Ayuso
Quoted 2 lines · Patrick McHardy

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.

#10 lore raw

Re: [PATCH 6/6] [PATCH] remove module dependency between ctnetlink and nf_nat

In reply to Pablo Neira Ayuso
Quoted 8 lines · Pablo Neira Ayuso
Quoted 3 lines · Patrick McHardy

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.

Quoted 8 lines

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 :)

Quoted 9 lines
Quoted 1 line

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.

Quoted 18 lines
Quoted 13 lines

I've tried applying this without the others, and it applies and compiled cleanly with one minor reject:

Quoted 10 lines
net/netfilter/nf_conntrack_netlink.c +1 -1
@@ -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;
 
Quoted 4 lines
Quoted 2 lines
net/netfilter/nf_conntrack_netlink.c +0 -0
     if (!help)
         goto out;

This chunk doesn't apply, but it doesn't seem to belong in the patch anyway.

Quoted 7 lines

Sorry, this belongs to patch 5/6.

Quoted 2 lines

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.