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

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