From patchwork Sun Jan 11 20:52:51 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Weinberger X-Patchwork-Id: 427519 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 6E9251401B1 for ; Mon, 12 Jan 2015 07:53:33 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752283AbbAKUxP (ORCPT ); Sun, 11 Jan 2015 15:53:15 -0500 Received: from mail.sigma-star.at ([95.130.255.111]:14388 "EHLO mail.sigma-star.at" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752141AbbAKUxF (ORCPT ); Sun, 11 Jan 2015 15:53:05 -0500 Received: from localhost (localhost.localdomain [127.0.0.1]) by mail.sigma-star.at (Postfix) with ESMTP id 5784724F8001; Sun, 11 Jan 2015 21:53:01 +0100 (CET) X-Virus-Scanned: amavisd-new at mail.sigma-star.at Received: from localhost.localdomain (chello213047235169.tirol.surfer.at [213.47.235.169]) by mail.sigma-star.at (Postfix) with ESMTPSA id 4EAEB24F8002; Sun, 11 Jan 2015 21:52:59 +0100 (CET) From: Richard Weinberger To: davem@davemloft.net Cc: coreteam@netfilter.org, netfilter-devel@vger.kernel.org, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, bhutchings@solarflare.com, john.fastabend@gmail.com, herbert@gondor.apana.org.au, vyasevic@redhat.com, jiri@resnulli.us, vfalico@gmail.com, therbert@google.com, edumazet@google.com, yoshfuji@linux-ipv6.org, jmorris@namei.org, kuznet@ms2.inr.ac.ru, kadlec@blackhole.kfki.hu, kaber@trash.net, pablo@netfilter.org, kay@vrfy.org, stephen@networkplumber.org, Richard Weinberger Subject: [PATCH 3/3] x_tables: Factor out 16bit aligment ifname_compare() Date: Sun, 11 Jan 2015 21:52:51 +0100 Message-Id: <1421009571-5279-4-git-send-email-richard@nod.at> X-Mailer: git-send-email 1.8.4.5 In-Reply-To: <1421009571-5279-1-git-send-email-richard@nod.at> References: <1421009571-5279-1-git-send-email-richard@nod.at> Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org arp_tables.c has a 16bit aligment ifname_compare(), factor it out to use it for all tables. Signed-off-by: Richard Weinberger --- include/linux/netfilter/x_tables.h | 25 ++++++++++++++++++------- net/ipv4/netfilter/arp_tables.c | 37 ++----------------------------------- 2 files changed, 20 insertions(+), 42 deletions(-) diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index 15bda23..26dddc1 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h @@ -331,14 +331,15 @@ static inline void xt_write_recseq_end(unsigned int addend) /* * This helper is performance critical and must be inlined */ -static inline unsigned long ifname_compare_aligned(const char *_a, - const char *_b, - const char *_mask) +static inline unsigned long ifname_compare(const char *_a, + const char *_b, + const char *_mask) { + unsigned long ret; +#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS const unsigned long *a = (const unsigned long *)_a; const unsigned long *b = (const unsigned long *)_b; const unsigned long *mask = (const unsigned long *)_mask; - unsigned long ret; ret = (a[0] ^ b[0]) & mask[0]; if (IFNAMSIZ > sizeof(unsigned long)) @@ -348,11 +349,21 @@ static inline unsigned long ifname_compare_aligned(const char *_a, if (IFNAMSIZ > 3 * sizeof(unsigned long)) ret |= (a[3] ^ b[3]) & mask[3]; BUILD_BUG_ON(IFNAMSIZ > 4 * sizeof(unsigned long)); +#else + const u16 *a = (const u16 *)_a; + const u16 *b = (const u16 *)_b; + const u16 *mask = (const u16 *)_mask; + int i; + + ret = 0; + for (i = 0; i < IFNAMSIZ/sizeof(u16); i++) + ret |= (a[i] ^ b[i]) & mask[i]; +#endif return ret; } /* - * A wrapper around ifname_compare_aligned() to match against dev->name and + * A wrapper around ifname_compare() to match against dev->name and * dev->ifalias. */ static inline unsigned long ifname_compare_all(const struct net_device *dev, @@ -364,9 +375,9 @@ static inline unsigned long ifname_compare_all(const struct net_device *dev, if (!dev) goto out; - res = ifname_compare_aligned(dev->name, name, mask); + res = ifname_compare(dev->name, name, mask); if (unlikely(dev->ifalias && res)) - res = ifname_compare_aligned(dev->ifalias, name, mask); + res = ifname_compare(dev->ifalias, name, mask); out: return res; diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index 457d4ed..c978691 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c @@ -76,39 +76,6 @@ static inline int arp_devaddr_compare(const struct arpt_devaddr_info *ap, return ret != 0; } -/* - * Unfortunately, _b and _mask are not aligned to an int (or long int) - * Some arches dont care, unrolling the loop is a win on them. - * For other arches, we only have a 16bit alignement. - */ -static unsigned long ifname_compare(const struct net_device *dev, - const char *_b, const char *_mask) -{ -#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS - unsigned long ret = ifname_compare_all(dev, _b, _mask); -#else - unsigned long ret = 0; - const u16 *a = (const u16 *)dev->name; - const u16 *b = (const u16 *)_b; - const u16 *mask = (const u16 *)_mask; - int i; - - for (i = 0; i < IFNAMSIZ/sizeof(u16); i++) - ret |= (a[i] ^ b[i]) & mask[i]; - - if (likely(!(dev->ifalias && ret))) - goto out; - - ret = 0; - a = (const u16 *)dev->ifalias; - for (i = 0; i < IFNAMSIZ/sizeof(u16); i++) - ret |= (a[i] ^ b[i]) & mask[i]; - -out: -#endif - return ret; -} - /* Returns whether packet matches rule or not. */ static inline int arp_packet_match(const struct arphdr *arphdr, struct net_device *dev, @@ -192,7 +159,7 @@ static inline int arp_packet_match(const struct arphdr *arphdr, } /* Look for ifname matches. */ - ret = ifname_compare(indev, arpinfo->iniface, arpinfo->iniface_mask); + ret = ifname_compare_all(indev, arpinfo->iniface, arpinfo->iniface_mask); if (FWINV(ret != 0, ARPT_INV_VIA_IN)) { dprintf("VIA in mismatch (%s vs %s).%s\n", @@ -201,7 +168,7 @@ static inline int arp_packet_match(const struct arphdr *arphdr, return 0; } - ret = ifname_compare(outdev, arpinfo->outiface, arpinfo->outiface_mask); + ret = ifname_compare_all(outdev, arpinfo->outiface, arpinfo->outiface_mask); if (FWINV(ret != 0, ARPT_INV_VIA_OUT)) { dprintf("VIA out mismatch (%s vs %s).%s\n",