Loading net/ipv6/netfilter/Kconfig +12 −0 Original line number Diff line number Diff line Loading @@ -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' Loading net/ipv6/netfilter/ip6_tables.c +17 −13 Original line number Diff line number Diff line Loading @@ -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); Loading Loading
net/ipv6/netfilter/Kconfig +12 −0 Original line number Diff line number Diff line Loading @@ -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' Loading
net/ipv6/netfilter/ip6_tables.c +17 −13 Original line number Diff line number Diff line Loading @@ -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); Loading