Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6f6c1a1f authored by Subash Abhinov Kasiviswanathan's avatar Subash Abhinov Kasiviswanathan
Browse files

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: default avatarSubash Abhinov Kasiviswanathan <subashab@codeaurora.org>
parent d5311c5d
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -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'
+17 −13
Original line number Diff line number Diff line
@@ -94,23 +94,27 @@ 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) ||
#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)) {
					       &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;
		}
	}

	ret = ifname_compare_aligned(indev, ip6info->iniface, ip6info->iniface_mask);