All of lore.kernel.org
 help / color / mirror / Atom feed
From: Pablo Neira Ayuso <pablo@netfilter.org>
To: Patrick McHardy <kaber@trash.net>
Cc: Netfilter Development Mailinglist
	<netfilter-devel@vger.kernel.org>,
	Fabian Hugelshofer <hugelshofer2006@gmx.ch>
Subject: [PATCH 7/7] dynamic calculation of event message size for ctnetlin
Date: Wed, 30 Jul 2008 13:06:31 +0200	[thread overview]
Message-ID: <48904B37.7090108@netfilter.org> (raw)

[-- 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;
 

             reply	other threads:[~2008-07-30 11:06 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-07-30 11:06 Pablo Neira Ayuso [this message]
2008-07-31 16:26 ` [PATCH 7/7] dynamic calculation of event message size for ctnetlin Fabian Hugelshofer
2008-07-31 16:42   ` Pablo Neira Ayuso
2008-07-31 16:54     ` Fabian Hugelshofer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=48904B37.7090108@netfilter.org \
    --to=pablo@netfilter.org \
    --cc=hugelshofer2006@gmx.ch \
    --cc=kaber@trash.net \
    --cc=netfilter-devel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.