diff options
| author | Subash Abhinov Kasiviswanathan <subashab@codeaurora.org> | 2017-04-18 15:22:01 -0600 |
|---|---|---|
| committer | Subash Abhinov Kasiviswanathan <subashab@codeaurora.org> | 2017-04-19 11:56:49 -0600 |
| commit | 6f6c1a1f8b7cf25b088d95525fa99d479e2d0931 (patch) | |
| tree | ad04dca53d7e32e14cdeef2f3f91318de7ee10e0 /net | |
| parent | d5311c5d4300455a7597b7edae08caba84c0a7f8 (diff) | |
net: ipv6: Optimize ipv6 packet matching
iptables matching for ipv6 always has a mask if an address is
specified for match. Adding a check for mask prior to that
helps to improve performance as it avoids the masked comparison.
This is achieved by defining a new feature IP6_NF_IPTABLES_128
which allows to perform 128 bit arithmetic while matching.
CRs-Fixed: 2034577
Change-Id: I9ffd34e29d1b06ad74545d4751aa0e1ea06ded49
Signed-off-by: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>
Diffstat (limited to 'net')
| -rw-r--r-- | net/ipv6/netfilter/Kconfig | 12 | ||||
| -rw-r--r-- | net/ipv6/netfilter/ip6_tables.c | 30 |
2 files changed, 29 insertions, 13 deletions
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig index e10a04c9cdc7..cf336d670f8b 100644 --- a/net/ipv6/netfilter/Kconfig +++ b/net/ipv6/netfilter/Kconfig @@ -135,6 +135,18 @@ config IP6_NF_IPTABLES if IP6_NF_IPTABLES +config IP6_NF_IPTABLES_128 + tristate "128 bit arithmetic for iptables matching" + depends on IP6_NF_IPTABLES + help + This enables 128 bit matching in ip6tables to help optimize cases + where there is no match required. ip6tables matching for ipv6 always + has a mask if an address is specified for match. Adding a check for + mask prior to that helps to improve performance as it avoids the + masked comparison. + + Note that this feature depends on the architecture. If unsure, say N. + # The simple matches. config IP6_NF_MATCH_AH tristate '"ah" match support' diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 22f39e00bef3..6fd784643d6e 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -94,22 +94,26 @@ ip6_packet_match(const struct sk_buff *skb, { unsigned long ret; const struct ipv6hdr *ipv6 = ipv6_hdr(skb); +#if IS_ENABLED(IP6_NF_IPTABLES_128) + const __uint128_t *ulm1 = (const __uint128_t *)&ip6info->smsk; + const __uint128_t *ulm2 = (const __uint128_t *)&ip6info->dmsk; +#endif #define FWINV(bool, invflg) ((bool) ^ !!(ip6info->invflags & (invflg))) - if (FWINV(ipv6_masked_addr_cmp(&ipv6->saddr, &ip6info->smsk, - &ip6info->src), IP6T_INV_SRCIP) || - FWINV(ipv6_masked_addr_cmp(&ipv6->daddr, &ip6info->dmsk, - &ip6info->dst), IP6T_INV_DSTIP)) { - dprintf("Source or dest mismatch.\n"); -/* - dprintf("SRC: %u. Mask: %u. Target: %u.%s\n", ip->saddr, - ipinfo->smsk.s_addr, ipinfo->src.s_addr, - ipinfo->invflags & IP6T_INV_SRCIP ? " (INV)" : ""); - dprintf("DST: %u. Mask: %u. Target: %u.%s\n", ip->daddr, - ipinfo->dmsk.s_addr, ipinfo->dst.s_addr, - ipinfo->invflags & IP6T_INV_DSTIP ? " (INV)" : "");*/ - return false; +#if IS_ENABLED(IP6_NF_IPTABLES_128) + if (*ulm1 || *ulm2) +#endif + { + if (FWINV(ipv6_masked_addr_cmp + (&ipv6->saddr, &ip6info->smsk, &ip6info->src), + IP6T_INV_SRCIP) || + FWINV(ipv6_masked_addr_cmp(&ipv6->daddr, &ip6info->dmsk, + &ip6info->dst), + IP6T_INV_DSTIP)) { + dprintf("Source or dest mismatch.\n"); + return false; + } } ret = ifname_compare_aligned(indev, ip6info->iniface, ip6info->iniface_mask); |
