Blame SOURCES/0065-xshared-Prefer-xtables_chain_protos-lookup-over-getp.patch

aca4c4
From daca1bc21c6fca067d861792c97357d7561a0564 Mon Sep 17 00:00:00 2001
aca4c4
From: Phil Sutter <phil@nwl.cc>
aca4c4
Date: Tue, 1 Mar 2022 23:05:29 +0100
aca4c4
Subject: [PATCH] xshared: Prefer xtables_chain_protos lookup over getprotoent
aca4c4
aca4c4
When dumping a large ruleset, common protocol matches such as for TCP
aca4c4
port number significantly slow down rule printing due to repeated calls
aca4c4
for getprotobynumber(). The latter does not involve any caching, so
aca4c4
/etc/protocols is consulted over and over again.
aca4c4
aca4c4
As a simple countermeasure, make functions converting between proto
aca4c4
number and name prefer the built-in list of "well-known" protocols. This
aca4c4
is not a perfect solution, repeated rules for protocol names libxtables
aca4c4
does not cache (e.g. igmp or dccp) will still be slow. Implementing
aca4c4
getprotoent() result caching could solve this.
aca4c4
aca4c4
As a side-effect, explicit check for pseudo-protocol "all" may be
aca4c4
dropped as it is contained in the built-in list and therefore immutable.
aca4c4
aca4c4
Also update xtables_chain_protos entries a bit to align with typical
aca4c4
/etc/protocols contents. The testsuite assumes those names, so the
aca4c4
preferred ones prior to this patch are indeed uncommon nowadays.
aca4c4
aca4c4
Signed-off-by: Phil Sutter <phil@nwl.cc>
aca4c4
Acked-by: Florian Westphal <fw@strlen.de>
aca4c4
(cherry picked from commit b6196c7504d4d41827cea86c167926125cdbf1f3)
aca4c4
---
aca4c4
 iptables/xshared.c   |  8 ++++----
aca4c4
 libxtables/xtables.c | 19 ++++++-------------
aca4c4
 2 files changed, 10 insertions(+), 17 deletions(-)
aca4c4
aca4c4
diff --git a/iptables/xshared.c b/iptables/xshared.c
aca4c4
index e3c8072b5ca96..dcc995a9cabe6 100644
aca4c4
--- a/iptables/xshared.c
aca4c4
+++ b/iptables/xshared.c
aca4c4
@@ -52,16 +52,16 @@ proto_to_name(uint8_t proto, int nolookup)
aca4c4
 {
aca4c4
 	unsigned int i;
aca4c4
 
aca4c4
+	for (i = 0; xtables_chain_protos[i].name != NULL; ++i)
aca4c4
+		if (xtables_chain_protos[i].num == proto)
aca4c4
+			return xtables_chain_protos[i].name;
aca4c4
+
aca4c4
 	if (proto && !nolookup) {
aca4c4
 		struct protoent *pent = getprotobynumber(proto);
aca4c4
 		if (pent)
aca4c4
 			return pent->p_name;
aca4c4
 	}
aca4c4
 
aca4c4
-	for (i = 0; xtables_chain_protos[i].name != NULL; ++i)
aca4c4
-		if (xtables_chain_protos[i].num == proto)
aca4c4
-			return xtables_chain_protos[i].name;
aca4c4
-
aca4c4
 	return NULL;
aca4c4
 }
aca4c4
 
aca4c4
diff --git a/libxtables/xtables.c b/libxtables/xtables.c
aca4c4
index 28ffffedd8147..58dd69440253d 100644
aca4c4
--- a/libxtables/xtables.c
aca4c4
+++ b/libxtables/xtables.c
aca4c4
@@ -2021,10 +2021,11 @@ const struct xtables_pprot xtables_chain_protos[] = {
aca4c4
 	{"udp",       IPPROTO_UDP},
aca4c4
 	{"udplite",   IPPROTO_UDPLITE},
aca4c4
 	{"icmp",      IPPROTO_ICMP},
aca4c4
-	{"icmpv6",    IPPROTO_ICMPV6},
aca4c4
 	{"ipv6-icmp", IPPROTO_ICMPV6},
aca4c4
+	{"icmpv6",    IPPROTO_ICMPV6},
aca4c4
 	{"esp",       IPPROTO_ESP},
aca4c4
 	{"ah",        IPPROTO_AH},
aca4c4
+	{"mobility-header", IPPROTO_MH},
aca4c4
 	{"ipv6-mh",   IPPROTO_MH},
aca4c4
 	{"mh",        IPPROTO_MH},
aca4c4
 	{"all",       0},
aca4c4
@@ -2040,23 +2041,15 @@ xtables_parse_protocol(const char *s)
aca4c4
 	if (xtables_strtoui(s, NULL, &proto, 0, UINT8_MAX))
aca4c4
 		return proto;
aca4c4
 
aca4c4
-	/* first deal with the special case of 'all' to prevent
aca4c4
-	 * people from being able to redefine 'all' in nsswitch
aca4c4
-	 * and/or provoke expensive [not working] ldap/nis/...
aca4c4
-	 * lookups */
aca4c4
-	if (strcmp(s, "all") == 0)
aca4c4
-		return 0;
aca4c4
+	for (i = 0; xtables_chain_protos[i].name != NULL; ++i) {
aca4c4
+		if (strcmp(s, xtables_chain_protos[i].name) == 0)
aca4c4
+			return xtables_chain_protos[i].num;
aca4c4
+	}
aca4c4
 
aca4c4
 	pent = getprotobyname(s);
aca4c4
 	if (pent != NULL)
aca4c4
 		return pent->p_proto;
aca4c4
 
aca4c4
-	for (i = 0; i < ARRAY_SIZE(xtables_chain_protos); ++i) {
aca4c4
-		if (xtables_chain_protos[i].name == NULL)
aca4c4
-			continue;
aca4c4
-		if (strcmp(s, xtables_chain_protos[i].name) == 0)
aca4c4
-			return xtables_chain_protos[i].num;
aca4c4
-	}
aca4c4
 	xt_params->exit_err(PARAMETER_PROBLEM,
aca4c4
 		"unknown protocol \"%s\" specified", s);
aca4c4
 	return -1;
aca4c4
-- 
aca4c4
2.34.1
aca4c4