All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 7/7] dynamic calculation of event message size for ctnetlin
@ 2008-07-30 11:06 Pablo Neira Ayuso
  2008-07-31 16:26 ` Fabian Hugelshofer
  0 siblings, 1 reply; 4+ messages in thread
From: Pablo Neira Ayuso @ 2008-07-30 11:06 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: Netfilter Development Mailinglist, Fabian Hugelshofer

[-- Attachment #1: Type: text/plain, Size: 551 bytes --]

[PATCH] dynamic calculation of event message size for ctnetlink

This patch adds dynamic message size calculation for ctnetlink. This
reduces CPU consumption since the overhead in the message trimming
is removed.

Note that if we create an entry in the connection tracking for
any layer 3 or 4 protocol helper that is not loaded, eg. SCTP,
DCCP, IPv6, the calculated size is not accurate.

Based on a suggestion from Patrick McHardy.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

-- 
"Los honestos son inadaptados sociales" -- Les Luthiers

[-- Attachment #2: 07.patch --]
[-- Type: text/x-diff, Size: 4637 bytes --]

[PATCH] dynamic calculation of event message size for ctnetlink

This patch adds dynamic message size calculation for ctnetlink. This 
reduces CPU consumption since the overhead in the message trimming
is removed.

Note that if we create an entry in the connection tracking for
any layer 3 or 4 protocol helper that is not loaded, eg. SCTP, 
DCCP, IPv6, the calculated size is not accurate.

Based on a suggestion from Patrick McHardy.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

Index: net-next-2.6.git/net/netfilter/nf_conntrack_netlink.c
===================================================================
--- net-next-2.6.git.orig/net/netfilter/nf_conntrack_netlink.c	2008-07-30 09:10:09.000000000 +0200
+++ net-next-2.6.git/net/netfilter/nf_conntrack_netlink.c	2008-07-30 09:12:11.000000000 +0200
@@ -402,6 +402,127 @@ nla_put_failure:
 }
 
 #ifdef CONFIG_NF_CONNTRACK_EVENTS
+static inline size_t calculate_tuple_room_size(const struct nf_conn *ct)
+{
+	size_t size = nla_total_size(0);		/* CTA_TUPLE_XYZ */
+
+	size += nla_total_size(0);			/* CTA_TUPLE_IP */
+	switch(nf_ct_l3num(ct)) {
+	case AF_INET:
+		size += nla_total_size(sizeof(u_int32_t))*2;
+		break;
+	case AF_INET6:
+		size += nla_total_size(sizeof(u_int32_t)*4)*2;
+		break;
+	}
+
+	size += nla_total_size(0);			/* CTA_TUPLE_PROTO */
+	size += nla_total_size(sizeof(u_int8_t));	/* CTA_PROTONUM */
+	switch(nf_ct_protonum(ct)) {
+	case IPPROTO_TCP:
+	case IPPROTO_UDP:
+	case IPPROTO_UDPLITE:
+	case IPPROTO_DCCP:
+	case IPPROTO_SCTP:
+		size += nla_total_size(sizeof(u_int16_t))*2;
+		break;
+	case IPPROTO_ICMP:
+	case IPPROTO_ICMPV6:
+		size += nla_total_size(sizeof(u_int8_t)) +
+			nla_total_size(sizeof(u_int8_t)) +
+			nla_total_size(sizeof(u_int16_t));
+		break;
+	}
+
+	return size;
+}
+
+static inline size_t calculate_protoinfo_room_size(const struct nf_conn *ct)
+{
+	size_t size = 0;
+
+	switch(nf_ct_protonum(ct)) {
+	case IPPROTO_TCP:
+		size += 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));
+		break;
+	case IPPROTO_SCTP:
+		size += 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));
+		break;
+	case IPPROTO_DCCP:
+		size += nla_total_size(0)*2 +		/* CTA_PROTOINFO */
+			nla_total_size(sizeof(u_int8_t));
+		break;
+	}
+	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 = 0;
+
+	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 || (events & IPCT_COUNTER_FILLING)) {
+		size += nla_total_size(0) * 2 +
+			nla_total_size(sizeof(u_int32_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)
 {
@@ -435,7 +556,7 @@ static int ctnetlink_conntrack_event(str
 	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;
 

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2008-07-31 16:54 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-07-30 11:06 [PATCH 7/7] dynamic calculation of event message size for ctnetlin Pablo Neira Ayuso
2008-07-31 16:26 ` Fabian Hugelshofer
2008-07-31 16:42   ` Pablo Neira Ayuso
2008-07-31 16:54     ` Fabian Hugelshofer

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.