From patchwork Wed Mar 25 20:34:05 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: holger@eitzenberger.org X-Patchwork-Id: 25101 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by ozlabs.org (Postfix) with ESMTP id 86501DDDA0 for ; Thu, 26 Mar 2009 07:46:16 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753700AbZCYUqK (ORCPT ); Wed, 25 Mar 2009 16:46:10 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1753557AbZCYUqI (ORCPT ); Wed, 25 Mar 2009 16:46:08 -0400 Received: from moutng.kundenserver.de ([212.227.126.171]:65074 "EHLO moutng.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752098AbZCYUqH (ORCPT ); Wed, 25 Mar 2009 16:46:07 -0400 Received: from kruemel.eitzenberger.org (p54AD0D79.dip0.t-ipconnect.de [84.173.13.121]) by mrelayeu.kundenserver.de (node=mreu1) with ESMTP (Nemesis) id 0MKv1o-1LmZz82gUX-000jql; Wed, 25 Mar 2009 21:46:02 +0100 Received: from [192.168.11.10] (helo=jonathan.eitzenberger.org ident=holger) by kruemel.eitzenberger.org with smtp (Exim 4.50) id 1LmZz7-00005Q-18; Wed, 25 Mar 2009 21:46:02 +0100 Received: by jonathan.eitzenberger.org (sSMTP sendmail emulation); Wed, 25 Mar 2009 21:46:00 +0100 Message-Id: <20090325204600.456638455@jonathan.eitzenberger.org> References: <20090325203404.581023828@jonathan.eitzenberger.org> User-Agent: quilt/0.46-1 Date: Wed, 25 Mar 2009 21:34:05 +0100 From: Holger Eitzenberger To: Patrick McHardy Cc: pablo@netfilter.org, netfilter-devel@vger.kernel.org, netdev@vger.kernel.org Subject: [patch 1/3] ctnetlink: allocate right-sized ctnetlink skb Content-Disposition: inline; filename=ctnetlink-factor-out-alloc_skb-into-ctnetlink_all.diff X-Provags-ID: V01U2FsdGVkX1+rh1rs2DNXWVXI7q/+LJwdqvGch3YuWLT/Ren 8WMKoj0n5ADbab0PmdiDDE9ilF5OLcUcosImShkPkujM+gBQwW L7bDYUIbO27AWUZ2Ek8rBwd7lnkDdD2 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Try to allocate a Netlink skb roughly the size of the actual message, with the help from the l3 and l4 protocol helpers. This is all to prevent a reallocation in netlink_trim() later. The overhead of allocating the right-sized skb is rather small, with ctnetlink_alloc_skb() actually being inlined away on my x86_64 box. The size of the per-proto space is determined at registration time of the protocol helper. Signed-off-by: Holger Eitzenberger Index: nf-next-2.6/net/netfilter/nf_conntrack_netlink.c =================================================================== --- nf-next-2.6.orig/net/netfilter/nf_conntrack_netlink.c +++ nf-next-2.6/net/netfilter/nf_conntrack_netlink.c @@ -404,6 +404,69 @@ nla_put_failure: } #ifdef CONFIG_NF_CONNTRACK_EVENTS +/* + * The general structure of a ctnetlink event is + * + * CTA_TUPLE_ORIG + * + * CTA_TUPLE_REPLY + * + * CTA_ID + * ... + * CTA_PROTOINFO + * + * CTA_TUPLE_MASTER + * + * + * Therefore the formular is + * + * size = sizeof(headers) + sizeof(generic_nlas) + 3 * sizeof(tuple_nlas) + * + sizeof(protoinfo_nlas) + */ +static struct sk_buff * +ctnetlink_alloc_skb(const struct nf_conntrack_tuple *tuple, gfp_t gfp) +{ + struct nf_conntrack_l3proto *l3proto; + struct nf_conntrack_l4proto *l4proto; + int len; + +#define NLA_TYPE_SIZE(type) nla_total_size(sizeof(type)) + + /* proto independant part */ + len = NLMSG_SPACE(sizeof(struct nfgenmsg)) + + 3 * nla_total_size(0) /* CTA_TUPLE_ORIG|REPL|MASTER */ + + 3 * nla_total_size(0) /* CTA_TUPLE_IP */ + + 3 * nla_total_size(0) /* CTA_TUPLE_PROTO */ + + 3 * NLA_TYPE_SIZE(u_int8_t) /* CTA_PROTO_NUM */ + + NLA_TYPE_SIZE(u_int32_t) /* CTA_ID */ + + NLA_TYPE_SIZE(u_int32_t) /* CTA_STATUS */ + + 2 * nla_total_size(0) /* CTA_COUNTERS_ORIG|REPL */ + + 2 * NLA_TYPE_SIZE(uint64_t) /* CTA_COUNTERS_PACKETS */ + + 2 * NLA_TYPE_SIZE(uint64_t) /* CTA_COUNTERS_BYTES */ + + NLA_TYPE_SIZE(u_int32_t) /* CTA_TIMEOUT */ + + nla_total_size(0) /* CTA_PROTOINFO */ + + nla_total_size(0) /* CTA_HELP */ + + nla_total_size(NF_CT_HELPER_NAME_LEN) /* CTA_HELP_NAME */ + + NLA_TYPE_SIZE(u_int32_t) /* CTA_SECMARK */ + + 2 * nla_total_size(0) /* CTA_NAT_SEQ_ADJ_ORIG|REPL */ + + 2 * NLA_TYPE_SIZE(u_int32_t) /* CTA_NAT_SEQ_CORRECTION_POS */ + + 2 * NLA_TYPE_SIZE(u_int32_t) /* CTA_NAT_SEQ_CORRECTION_BEFORE */ + + 2 * NLA_TYPE_SIZE(u_int32_t) /* CTA_NAT_SEQ_CORRECTION_AFTER */ + + NLA_TYPE_SIZE(u_int32_t); /* CTA_MARK */ + +#undef NLA_TYPE_SIZE + + rcu_read_lock(); + l3proto = __nf_ct_l3proto_find(tuple->src.l3num); + len += l3proto->nla_size; + + l4proto = __nf_ct_l4proto_find(tuple->src.l3num, tuple->dst.protonum); + len += l4proto->nla_size; + rcu_read_unlock(); + + return alloc_skb(len, gfp); +} + static int ctnetlink_conntrack_event(struct notifier_block *this, unsigned long events, void *ptr) { @@ -437,7 +500,7 @@ static int ctnetlink_conntrack_event(str if (!item->report && !nfnetlink_has_listeners(group)) return NOTIFY_DONE; - skb = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC); + skb = ctnetlink_alloc_skb(tuple(ct, IP_CT_DIR_ORIGINAL), GFP_ATOMIC); if (!skb) return NOTIFY_DONE;