import iptables-1.8.4-23.el8
This commit is contained in:
parent
ac8a609a4e
commit
24cde63f68
199
SOURCES/0063-nft-Simplify-immediate-parsing.patch
Normal file
199
SOURCES/0063-nft-Simplify-immediate-parsing.patch
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
From c65bd8b3c23f0fe5f824274467740a2d350dcb9c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Phil Sutter <phil@nwl.cc>
|
||||||
|
Date: Tue, 1 Mar 2022 18:59:31 +0100
|
||||||
|
Subject: [PATCH] nft: Simplify immediate parsing
|
||||||
|
|
||||||
|
Implementations of parse_immediate callback are mostly trivial, the only
|
||||||
|
relevant part is access to family-specific parts of struct
|
||||||
|
iptables_command_state when setting goto flag for iptables and
|
||||||
|
ip6tables. Refactor them into simple set_goto_flag callbacks.
|
||||||
|
|
||||||
|
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
||||||
|
Acked-by: Florian Westphal <fw@strlen.de>
|
||||||
|
(cherry picked from commit b5f2faea325a315bfb932ebc634f3298d4824cae)
|
||||||
|
---
|
||||||
|
iptables/nft-arp.c | 9 ---------
|
||||||
|
iptables/nft-bridge.c | 9 ---------
|
||||||
|
iptables/nft-ipv4.c | 12 +++---------
|
||||||
|
iptables/nft-ipv6.c | 12 +++---------
|
||||||
|
iptables/nft-shared.c | 17 +++++++----------
|
||||||
|
iptables/nft-shared.h | 2 +-
|
||||||
|
6 files changed, 14 insertions(+), 47 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/iptables/nft-arp.c b/iptables/nft-arp.c
|
||||||
|
index 7c61c31a13c40..0c37a762cd418 100644
|
||||||
|
--- a/iptables/nft-arp.c
|
||||||
|
+++ b/iptables/nft-arp.c
|
||||||
|
@@ -182,14 +182,6 @@ static void nft_arp_parse_meta(struct nft_xt_ctx *ctx, struct nftnl_expr *e,
|
||||||
|
fw->arp.invflags |= flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void nft_arp_parse_immediate(const char *jumpto, bool nft_goto,
|
||||||
|
- void *data)
|
||||||
|
-{
|
||||||
|
- struct iptables_command_state *cs = data;
|
||||||
|
-
|
||||||
|
- cs->jumpto = jumpto;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
static void parse_mask_ipv4(struct nft_xt_ctx *ctx, struct in_addr *mask)
|
||||||
|
{
|
||||||
|
mask->s_addr = ctx->bitwise.mask[0];
|
||||||
|
@@ -575,7 +567,6 @@ struct nft_family_ops nft_family_ops_arp = {
|
||||||
|
.print_payload = NULL,
|
||||||
|
.parse_meta = nft_arp_parse_meta,
|
||||||
|
.parse_payload = nft_arp_parse_payload,
|
||||||
|
- .parse_immediate = nft_arp_parse_immediate,
|
||||||
|
.print_header = nft_arp_print_header,
|
||||||
|
.print_rule = nft_arp_print_rule,
|
||||||
|
.save_rule = nft_arp_save_rule,
|
||||||
|
diff --git a/iptables/nft-bridge.c b/iptables/nft-bridge.c
|
||||||
|
index 2aa15e2d1e69d..e00a19e843d93 100644
|
||||||
|
--- a/iptables/nft-bridge.c
|
||||||
|
+++ b/iptables/nft-bridge.c
|
||||||
|
@@ -284,14 +284,6 @@ static void nft_bridge_parse_payload(struct nft_xt_ctx *ctx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void nft_bridge_parse_immediate(const char *jumpto, bool nft_goto,
|
||||||
|
- void *data)
|
||||||
|
-{
|
||||||
|
- struct iptables_command_state *cs = data;
|
||||||
|
-
|
||||||
|
- cs->jumpto = jumpto;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
/* return 0 if saddr, 1 if daddr, -1 on error */
|
||||||
|
static int
|
||||||
|
lookup_check_ether_payload(uint32_t base, uint32_t offset, uint32_t len)
|
||||||
|
@@ -948,7 +940,6 @@ struct nft_family_ops nft_family_ops_bridge = {
|
||||||
|
.print_payload = NULL,
|
||||||
|
.parse_meta = nft_bridge_parse_meta,
|
||||||
|
.parse_payload = nft_bridge_parse_payload,
|
||||||
|
- .parse_immediate = nft_bridge_parse_immediate,
|
||||||
|
.parse_lookup = nft_bridge_parse_lookup,
|
||||||
|
.parse_match = nft_bridge_parse_match,
|
||||||
|
.parse_target = nft_bridge_parse_target,
|
||||||
|
diff --git a/iptables/nft-ipv4.c b/iptables/nft-ipv4.c
|
||||||
|
index d8c48ce8817b6..c826ac153139f 100644
|
||||||
|
--- a/iptables/nft-ipv4.c
|
||||||
|
+++ b/iptables/nft-ipv4.c
|
||||||
|
@@ -241,15 +241,9 @@ static void nft_ipv4_parse_payload(struct nft_xt_ctx *ctx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void nft_ipv4_parse_immediate(const char *jumpto, bool nft_goto,
|
||||||
|
- void *data)
|
||||||
|
+static void nft_ipv4_set_goto_flag(struct iptables_command_state *cs)
|
||||||
|
{
|
||||||
|
- struct iptables_command_state *cs = data;
|
||||||
|
-
|
||||||
|
- cs->jumpto = jumpto;
|
||||||
|
-
|
||||||
|
- if (nft_goto)
|
||||||
|
- cs->fw.ip.flags |= IPT_F_GOTO;
|
||||||
|
+ cs->fw.ip.flags |= IPT_F_GOTO;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_fragment(unsigned int flags, unsigned int invflags,
|
||||||
|
@@ -473,7 +467,7 @@ struct nft_family_ops nft_family_ops_ipv4 = {
|
||||||
|
.is_same = nft_ipv4_is_same,
|
||||||
|
.parse_meta = nft_ipv4_parse_meta,
|
||||||
|
.parse_payload = nft_ipv4_parse_payload,
|
||||||
|
- .parse_immediate = nft_ipv4_parse_immediate,
|
||||||
|
+ .set_goto_flag = nft_ipv4_set_goto_flag,
|
||||||
|
.print_header = print_header,
|
||||||
|
.print_rule = nft_ipv4_print_rule,
|
||||||
|
.save_rule = nft_ipv4_save_rule,
|
||||||
|
diff --git a/iptables/nft-ipv6.c b/iptables/nft-ipv6.c
|
||||||
|
index a5481b3f77ac5..127bc96379968 100644
|
||||||
|
--- a/iptables/nft-ipv6.c
|
||||||
|
+++ b/iptables/nft-ipv6.c
|
||||||
|
@@ -180,15 +180,9 @@ static void nft_ipv6_parse_payload(struct nft_xt_ctx *ctx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void nft_ipv6_parse_immediate(const char *jumpto, bool nft_goto,
|
||||||
|
- void *data)
|
||||||
|
+static void nft_ipv6_set_goto_flag(struct iptables_command_state *cs)
|
||||||
|
{
|
||||||
|
- struct iptables_command_state *cs = data;
|
||||||
|
-
|
||||||
|
- cs->jumpto = jumpto;
|
||||||
|
-
|
||||||
|
- if (nft_goto)
|
||||||
|
- cs->fw6.ipv6.flags |= IP6T_F_GOTO;
|
||||||
|
+ cs->fw6.ipv6.flags |= IP6T_F_GOTO;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nft_ipv6_print_rule(struct nft_handle *h, struct nftnl_rule *r,
|
||||||
|
@@ -415,7 +409,7 @@ struct nft_family_ops nft_family_ops_ipv6 = {
|
||||||
|
.is_same = nft_ipv6_is_same,
|
||||||
|
.parse_meta = nft_ipv6_parse_meta,
|
||||||
|
.parse_payload = nft_ipv6_parse_payload,
|
||||||
|
- .parse_immediate = nft_ipv6_parse_immediate,
|
||||||
|
+ .set_goto_flag = nft_ipv6_set_goto_flag,
|
||||||
|
.print_header = print_header,
|
||||||
|
.print_rule = nft_ipv6_print_rule,
|
||||||
|
.save_rule = nft_ipv6_save_rule,
|
||||||
|
diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c
|
||||||
|
index 7f757d38ecaec..172cf2054a33c 100644
|
||||||
|
--- a/iptables/nft-shared.c
|
||||||
|
+++ b/iptables/nft-shared.c
|
||||||
|
@@ -510,9 +510,7 @@ static void nft_parse_counter(struct nftnl_expr *e, struct xt_counters *counters
|
||||||
|
static void nft_parse_immediate(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
|
||||||
|
{
|
||||||
|
const char *chain = nftnl_expr_get_str(e, NFTNL_EXPR_IMM_CHAIN);
|
||||||
|
- const char *jumpto = NULL;
|
||||||
|
- bool nft_goto = false;
|
||||||
|
- void *data = ctx->cs;
|
||||||
|
+ struct iptables_command_state *cs = ctx->cs;
|
||||||
|
int verdict;
|
||||||
|
|
||||||
|
if (nftnl_expr_is_set(e, NFTNL_EXPR_IMM_DATA)) {
|
||||||
|
@@ -535,23 +533,22 @@ static void nft_parse_immediate(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
|
||||||
|
/* Standard target? */
|
||||||
|
switch(verdict) {
|
||||||
|
case NF_ACCEPT:
|
||||||
|
- jumpto = "ACCEPT";
|
||||||
|
+ cs->jumpto = "ACCEPT";
|
||||||
|
break;
|
||||||
|
case NF_DROP:
|
||||||
|
- jumpto = "DROP";
|
||||||
|
+ cs->jumpto = "DROP";
|
||||||
|
break;
|
||||||
|
case NFT_RETURN:
|
||||||
|
- jumpto = "RETURN";
|
||||||
|
+ cs->jumpto = "RETURN";
|
||||||
|
break;;
|
||||||
|
case NFT_GOTO:
|
||||||
|
- nft_goto = true;
|
||||||
|
+ if (ctx->h->ops->set_goto_flag)
|
||||||
|
+ ctx->h->ops->set_goto_flag(cs);
|
||||||
|
/* fall through */
|
||||||
|
case NFT_JUMP:
|
||||||
|
- jumpto = chain;
|
||||||
|
+ cs->jumpto = chain;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
- ctx->h->ops->parse_immediate(jumpto, nft_goto, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nft_parse_limit(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
|
||||||
|
diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h
|
||||||
|
index 520a296fb530c..29f7056714235 100644
|
||||||
|
--- a/iptables/nft-shared.h
|
||||||
|
+++ b/iptables/nft-shared.h
|
||||||
|
@@ -89,7 +89,7 @@ struct nft_family_ops {
|
||||||
|
void *data);
|
||||||
|
void (*parse_lookup)(struct nft_xt_ctx *ctx, struct nftnl_expr *e,
|
||||||
|
void *data);
|
||||||
|
- void (*parse_immediate)(const char *jumpto, bool nft_goto, void *data);
|
||||||
|
+ void (*set_goto_flag)(struct iptables_command_state *cs);
|
||||||
|
|
||||||
|
void (*print_table_header)(const char *tablename);
|
||||||
|
void (*print_header)(unsigned int format, const char *chain,
|
||||||
|
--
|
||||||
|
2.34.1
|
||||||
|
|
119
SOURCES/0064-nft-Speed-up-immediate-parsing.patch
Normal file
119
SOURCES/0064-nft-Speed-up-immediate-parsing.patch
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
From 5d6c1effe324d1a2401a4315895fe72c7255a14d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Phil Sutter <phil@nwl.cc>
|
||||||
|
Date: Tue, 1 Mar 2022 19:46:21 +0100
|
||||||
|
Subject: [PATCH] nft: Speed up immediate parsing
|
||||||
|
|
||||||
|
Parsing of rules which jump to a chain pointlessly causes a call to
|
||||||
|
xtables_find_target() despite the code already knowing the outcome.
|
||||||
|
|
||||||
|
Avoid the significant delay for rulesets with many chain jumps by
|
||||||
|
performing the (standard) target lookup only for accept/drop/return
|
||||||
|
verdicts.
|
||||||
|
|
||||||
|
From a biased test-case on my VM:
|
||||||
|
|
||||||
|
| # iptables-nft-save | grep -c -- '-j'
|
||||||
|
| 133943
|
||||||
|
| # time ./old/iptables-nft-save >/dev/null
|
||||||
|
| real 0m45.566s
|
||||||
|
| user 0m1.308s
|
||||||
|
| sys 0m8.430s
|
||||||
|
| # time ./new/iptables-nft-save >/dev/null
|
||||||
|
| real 0m3.547s
|
||||||
|
| user 0m0.762s
|
||||||
|
| sys 0m2.476s
|
||||||
|
|
||||||
|
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
||||||
|
Acked-by: Florian Westphal <fw@strlen.de>
|
||||||
|
(cherry picked from commit 07ee529f5a62838d68be59683be99bf6a7cda0f2)
|
||||||
|
---
|
||||||
|
iptables/nft-bridge.c | 1 +
|
||||||
|
iptables/nft-shared.c | 37 ++++++++++++++++++-------------------
|
||||||
|
2 files changed, 19 insertions(+), 19 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/iptables/nft-bridge.c b/iptables/nft-bridge.c
|
||||||
|
index e00a19e843d93..3fd03fb8de4ff 100644
|
||||||
|
--- a/iptables/nft-bridge.c
|
||||||
|
+++ b/iptables/nft-bridge.c
|
||||||
|
@@ -530,6 +530,7 @@ static void nft_bridge_parse_target(struct xtables_target *t, void *data)
|
||||||
|
}
|
||||||
|
|
||||||
|
cs->target = t;
|
||||||
|
+ cs->jumpto = t->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nft_rule_to_ebtables_command_state(struct nft_handle *h,
|
||||||
|
diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c
|
||||||
|
index 172cf2054a33c..d73d0b6159be6 100644
|
||||||
|
--- a/iptables/nft-shared.c
|
||||||
|
+++ b/iptables/nft-shared.c
|
||||||
|
@@ -511,6 +511,8 @@ static void nft_parse_immediate(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
|
||||||
|
{
|
||||||
|
const char *chain = nftnl_expr_get_str(e, NFTNL_EXPR_IMM_CHAIN);
|
||||||
|
struct iptables_command_state *cs = ctx->cs;
|
||||||
|
+ struct xt_entry_target *t;
|
||||||
|
+ uint32_t size;
|
||||||
|
int verdict;
|
||||||
|
|
||||||
|
if (nftnl_expr_is_set(e, NFTNL_EXPR_IMM_DATA)) {
|
||||||
|
@@ -547,8 +549,21 @@ static void nft_parse_immediate(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
|
||||||
|
/* fall through */
|
||||||
|
case NFT_JUMP:
|
||||||
|
cs->jumpto = chain;
|
||||||
|
- break;
|
||||||
|
+ /* fall through */
|
||||||
|
+ default:
|
||||||
|
+ return;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ cs->target = xtables_find_target(cs->jumpto, XTF_TRY_LOAD);
|
||||||
|
+ if (!cs->target)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ size = XT_ALIGN(sizeof(struct xt_entry_target)) + cs->target->size;
|
||||||
|
+ t = xtables_calloc(1, size);
|
||||||
|
+ t->u.target_size = size;
|
||||||
|
+ t->u.user.revision = cs->target->revision;
|
||||||
|
+ strcpy(t->u.user.name, cs->jumpto);
|
||||||
|
+ cs->target->t = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nft_parse_limit(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
|
||||||
|
@@ -676,25 +691,8 @@ void nft_rule_to_iptables_command_state(struct nft_handle *h,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (cs->target != NULL) {
|
||||||
|
- cs->jumpto = cs->target->name;
|
||||||
|
- } else if (cs->jumpto != NULL) {
|
||||||
|
- struct xt_entry_target *t;
|
||||||
|
- uint32_t size;
|
||||||
|
-
|
||||||
|
- cs->target = xtables_find_target(cs->jumpto, XTF_TRY_LOAD);
|
||||||
|
- if (!cs->target)
|
||||||
|
- return;
|
||||||
|
-
|
||||||
|
- size = XT_ALIGN(sizeof(struct xt_entry_target)) + cs->target->size;
|
||||||
|
- t = xtables_calloc(1, size);
|
||||||
|
- t->u.target_size = size;
|
||||||
|
- t->u.user.revision = cs->target->revision;
|
||||||
|
- strcpy(t->u.user.name, cs->jumpto);
|
||||||
|
- cs->target->t = t;
|
||||||
|
- } else {
|
||||||
|
+ if (!cs->jumpto)
|
||||||
|
cs->jumpto = "";
|
||||||
|
- }
|
||||||
|
}
|
||||||
|
|
||||||
|
void nft_clear_iptables_command_state(struct iptables_command_state *cs)
|
||||||
|
@@ -991,6 +989,7 @@ void nft_ipv46_parse_target(struct xtables_target *t, void *data)
|
||||||
|
struct iptables_command_state *cs = data;
|
||||||
|
|
||||||
|
cs->target = t;
|
||||||
|
+ cs->jumpto = t->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nft_ipv46_rule_find(struct nft_handle *h, struct nftnl_rule *r, void *data)
|
||||||
|
--
|
||||||
|
2.34.1
|
||||||
|
|
@ -0,0 +1,104 @@
|
|||||||
|
From daca1bc21c6fca067d861792c97357d7561a0564 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Phil Sutter <phil@nwl.cc>
|
||||||
|
Date: Tue, 1 Mar 2022 23:05:29 +0100
|
||||||
|
Subject: [PATCH] xshared: Prefer xtables_chain_protos lookup over getprotoent
|
||||||
|
|
||||||
|
When dumping a large ruleset, common protocol matches such as for TCP
|
||||||
|
port number significantly slow down rule printing due to repeated calls
|
||||||
|
for getprotobynumber(). The latter does not involve any caching, so
|
||||||
|
/etc/protocols is consulted over and over again.
|
||||||
|
|
||||||
|
As a simple countermeasure, make functions converting between proto
|
||||||
|
number and name prefer the built-in list of "well-known" protocols. This
|
||||||
|
is not a perfect solution, repeated rules for protocol names libxtables
|
||||||
|
does not cache (e.g. igmp or dccp) will still be slow. Implementing
|
||||||
|
getprotoent() result caching could solve this.
|
||||||
|
|
||||||
|
As a side-effect, explicit check for pseudo-protocol "all" may be
|
||||||
|
dropped as it is contained in the built-in list and therefore immutable.
|
||||||
|
|
||||||
|
Also update xtables_chain_protos entries a bit to align with typical
|
||||||
|
/etc/protocols contents. The testsuite assumes those names, so the
|
||||||
|
preferred ones prior to this patch are indeed uncommon nowadays.
|
||||||
|
|
||||||
|
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
||||||
|
Acked-by: Florian Westphal <fw@strlen.de>
|
||||||
|
(cherry picked from commit b6196c7504d4d41827cea86c167926125cdbf1f3)
|
||||||
|
---
|
||||||
|
iptables/xshared.c | 8 ++++----
|
||||||
|
libxtables/xtables.c | 19 ++++++-------------
|
||||||
|
2 files changed, 10 insertions(+), 17 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/iptables/xshared.c b/iptables/xshared.c
|
||||||
|
index e3c8072b5ca96..dcc995a9cabe6 100644
|
||||||
|
--- a/iptables/xshared.c
|
||||||
|
+++ b/iptables/xshared.c
|
||||||
|
@@ -52,16 +52,16 @@ proto_to_name(uint8_t proto, int nolookup)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
+ for (i = 0; xtables_chain_protos[i].name != NULL; ++i)
|
||||||
|
+ if (xtables_chain_protos[i].num == proto)
|
||||||
|
+ return xtables_chain_protos[i].name;
|
||||||
|
+
|
||||||
|
if (proto && !nolookup) {
|
||||||
|
struct protoent *pent = getprotobynumber(proto);
|
||||||
|
if (pent)
|
||||||
|
return pent->p_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
- for (i = 0; xtables_chain_protos[i].name != NULL; ++i)
|
||||||
|
- if (xtables_chain_protos[i].num == proto)
|
||||||
|
- return xtables_chain_protos[i].name;
|
||||||
|
-
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/libxtables/xtables.c b/libxtables/xtables.c
|
||||||
|
index 28ffffedd8147..58dd69440253d 100644
|
||||||
|
--- a/libxtables/xtables.c
|
||||||
|
+++ b/libxtables/xtables.c
|
||||||
|
@@ -2021,10 +2021,11 @@ const struct xtables_pprot xtables_chain_protos[] = {
|
||||||
|
{"udp", IPPROTO_UDP},
|
||||||
|
{"udplite", IPPROTO_UDPLITE},
|
||||||
|
{"icmp", IPPROTO_ICMP},
|
||||||
|
- {"icmpv6", IPPROTO_ICMPV6},
|
||||||
|
{"ipv6-icmp", IPPROTO_ICMPV6},
|
||||||
|
+ {"icmpv6", IPPROTO_ICMPV6},
|
||||||
|
{"esp", IPPROTO_ESP},
|
||||||
|
{"ah", IPPROTO_AH},
|
||||||
|
+ {"mobility-header", IPPROTO_MH},
|
||||||
|
{"ipv6-mh", IPPROTO_MH},
|
||||||
|
{"mh", IPPROTO_MH},
|
||||||
|
{"all", 0},
|
||||||
|
@@ -2040,23 +2041,15 @@ xtables_parse_protocol(const char *s)
|
||||||
|
if (xtables_strtoui(s, NULL, &proto, 0, UINT8_MAX))
|
||||||
|
return proto;
|
||||||
|
|
||||||
|
- /* first deal with the special case of 'all' to prevent
|
||||||
|
- * people from being able to redefine 'all' in nsswitch
|
||||||
|
- * and/or provoke expensive [not working] ldap/nis/...
|
||||||
|
- * lookups */
|
||||||
|
- if (strcmp(s, "all") == 0)
|
||||||
|
- return 0;
|
||||||
|
+ for (i = 0; xtables_chain_protos[i].name != NULL; ++i) {
|
||||||
|
+ if (strcmp(s, xtables_chain_protos[i].name) == 0)
|
||||||
|
+ return xtables_chain_protos[i].num;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
pent = getprotobyname(s);
|
||||||
|
if (pent != NULL)
|
||||||
|
return pent->p_proto;
|
||||||
|
|
||||||
|
- for (i = 0; i < ARRAY_SIZE(xtables_chain_protos); ++i) {
|
||||||
|
- if (xtables_chain_protos[i].name == NULL)
|
||||||
|
- continue;
|
||||||
|
- if (strcmp(s, xtables_chain_protos[i].name) == 0)
|
||||||
|
- return xtables_chain_protos[i].num;
|
||||||
|
- }
|
||||||
|
xt_params->exit_err(PARAMETER_PROBLEM,
|
||||||
|
"unknown protocol \"%s\" specified", s);
|
||||||
|
return -1;
|
||||||
|
--
|
||||||
|
2.34.1
|
||||||
|
|
163
SOURCES/0066-xshared-Merge-and-share-parse_chain.patch
Normal file
163
SOURCES/0066-xshared-Merge-and-share-parse_chain.patch
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
From 767c668628296fb3236aeeea1699ce06e66e5270 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Phil Sutter <phil@nwl.cc>
|
||||||
|
Date: Fri, 5 Apr 2019 13:21:19 +0200
|
||||||
|
Subject: [PATCH] xshared: Merge and share parse_chain()
|
||||||
|
|
||||||
|
Have a common routine to perform chain name checks, combining all
|
||||||
|
variants' requirements.
|
||||||
|
|
||||||
|
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
||||||
|
(cherry picked from commit 1189d830ea4fd269da87761d400ebabca02e1ef3)
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
iptables/ip6tables.c
|
||||||
|
iptables/xshared.c
|
||||||
|
-> Context changes due to missing commit 9dc50b5b8e441
|
||||||
|
("xshared: Merge invflags handling code")
|
||||||
|
---
|
||||||
|
iptables/ip6tables.c | 26 --------------------------
|
||||||
|
iptables/iptables.c | 25 -------------------------
|
||||||
|
iptables/xshared.c | 24 ++++++++++++++++++++++++
|
||||||
|
iptables/xshared.h | 1 +
|
||||||
|
iptables/xtables.c | 9 +--------
|
||||||
|
5 files changed, 26 insertions(+), 59 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/iptables/ip6tables.c b/iptables/ip6tables.c
|
||||||
|
index 576c2cf8b0d9f..614d1e249c06d 100644
|
||||||
|
--- a/iptables/ip6tables.c
|
||||||
|
+++ b/iptables/ip6tables.c
|
||||||
|
@@ -327,32 +327,6 @@ static int is_exthdr(uint16_t proto)
|
||||||
|
proto == IPPROTO_DSTOPTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void
|
||||||
|
-parse_chain(const char *chainname)
|
||||||
|
-{
|
||||||
|
- const char *ptr;
|
||||||
|
-
|
||||||
|
- if (strlen(chainname) >= XT_EXTENSION_MAXNAMELEN)
|
||||||
|
- xtables_error(PARAMETER_PROBLEM,
|
||||||
|
- "chain name `%s' too long (must be under %u chars)",
|
||||||
|
- chainname, XT_EXTENSION_MAXNAMELEN);
|
||||||
|
-
|
||||||
|
- if (*chainname == '-' || *chainname == '!')
|
||||||
|
- xtables_error(PARAMETER_PROBLEM,
|
||||||
|
- "chain name not allowed to start "
|
||||||
|
- "with `%c'\n", *chainname);
|
||||||
|
-
|
||||||
|
- if (xtables_find_target(chainname, XTF_TRY_LOAD))
|
||||||
|
- xtables_error(PARAMETER_PROBLEM,
|
||||||
|
- "chain name may not clash "
|
||||||
|
- "with target name\n");
|
||||||
|
-
|
||||||
|
- for (ptr = chainname; *ptr; ptr++)
|
||||||
|
- if (isspace(*ptr))
|
||||||
|
- xtables_error(PARAMETER_PROBLEM,
|
||||||
|
- "Invalid chain name `%s'", chainname);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
static void
|
||||||
|
set_option(unsigned int *options, unsigned int option, uint8_t *invflg,
|
||||||
|
int invert)
|
||||||
|
diff --git a/iptables/iptables.c b/iptables/iptables.c
|
||||||
|
index 88ef6cf666d4b..3b395981cc8ea 100644
|
||||||
|
--- a/iptables/iptables.c
|
||||||
|
+++ b/iptables/iptables.c
|
||||||
|
@@ -319,31 +319,6 @@ opt2char(int option)
|
||||||
|
|
||||||
|
/* Christophe Burki wants `-p 6' to imply `-m tcp'. */
|
||||||
|
|
||||||
|
-static void
|
||||||
|
-parse_chain(const char *chainname)
|
||||||
|
-{
|
||||||
|
- const char *ptr;
|
||||||
|
-
|
||||||
|
- if (strlen(chainname) >= XT_EXTENSION_MAXNAMELEN)
|
||||||
|
- xtables_error(PARAMETER_PROBLEM,
|
||||||
|
- "chain name `%s' too long (must be under %u chars)",
|
||||||
|
- chainname, XT_EXTENSION_MAXNAMELEN);
|
||||||
|
-
|
||||||
|
- if (*chainname == '-' || *chainname == '!')
|
||||||
|
- xtables_error(PARAMETER_PROBLEM,
|
||||||
|
- "chain name not allowed to start "
|
||||||
|
- "with `%c'\n", *chainname);
|
||||||
|
-
|
||||||
|
- if (xtables_find_target(chainname, XTF_TRY_LOAD))
|
||||||
|
- xtables_error(PARAMETER_PROBLEM,
|
||||||
|
- "chain name may not clash "
|
||||||
|
- "with target name\n");
|
||||||
|
-
|
||||||
|
- for (ptr = chainname; *ptr; ptr++)
|
||||||
|
- if (isspace(*ptr))
|
||||||
|
- xtables_error(PARAMETER_PROBLEM,
|
||||||
|
- "Invalid chain name `%s'", chainname);
|
||||||
|
-}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_option(unsigned int *options, unsigned int option, uint8_t *invflg,
|
||||||
|
diff --git a/iptables/xshared.c b/iptables/xshared.c
|
||||||
|
index dcc995a9cabe6..de8326b6c7b05 100644
|
||||||
|
--- a/iptables/xshared.c
|
||||||
|
+++ b/iptables/xshared.c
|
||||||
|
@@ -775,3 +775,27 @@ int parse_rulenumber(const char *rule)
|
||||||
|
|
||||||
|
return rulenum;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+void parse_chain(const char *chainname)
|
||||||
|
+{
|
||||||
|
+ const char *ptr;
|
||||||
|
+
|
||||||
|
+ if (strlen(chainname) >= XT_EXTENSION_MAXNAMELEN)
|
||||||
|
+ xtables_error(PARAMETER_PROBLEM,
|
||||||
|
+ "chain name `%s' too long (must be under %u chars)",
|
||||||
|
+ chainname, XT_EXTENSION_MAXNAMELEN);
|
||||||
|
+
|
||||||
|
+ if (*chainname == '-' || *chainname == '!')
|
||||||
|
+ xtables_error(PARAMETER_PROBLEM,
|
||||||
|
+ "chain name not allowed to start with `%c'\n",
|
||||||
|
+ *chainname);
|
||||||
|
+
|
||||||
|
+ if (xtables_find_target(chainname, XTF_TRY_LOAD))
|
||||||
|
+ xtables_error(PARAMETER_PROBLEM,
|
||||||
|
+ "chain name may not clash with target name\n");
|
||||||
|
+
|
||||||
|
+ for (ptr = chainname; *ptr; ptr++)
|
||||||
|
+ if (isspace(*ptr))
|
||||||
|
+ xtables_error(PARAMETER_PROBLEM,
|
||||||
|
+ "Invalid chain name `%s'", chainname);
|
||||||
|
+}
|
||||||
|
diff --git a/iptables/xshared.h b/iptables/xshared.h
|
||||||
|
index e4015c00e2a35..f5d2f8d0a2bc5 100644
|
||||||
|
--- a/iptables/xshared.h
|
||||||
|
+++ b/iptables/xshared.h
|
||||||
|
@@ -217,5 +217,6 @@ char cmd2char(int option);
|
||||||
|
void add_command(unsigned int *cmd, const int newcmd,
|
||||||
|
const int othercmds, int invert);
|
||||||
|
int parse_rulenumber(const char *rule);
|
||||||
|
+void parse_chain(const char *chainname);
|
||||||
|
|
||||||
|
#endif /* IPTABLES_XSHARED_H */
|
||||||
|
diff --git a/iptables/xtables.c b/iptables/xtables.c
|
||||||
|
index 8c2d21d42b7d2..3ea293ee7c411 100644
|
||||||
|
--- a/iptables/xtables.c
|
||||||
|
+++ b/iptables/xtables.c
|
||||||
|
@@ -668,14 +668,7 @@ void do_parse(struct nft_handle *h, int argc, char *argv[],
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'N':
|
||||||
|
- if (optarg && (*optarg == '-' || *optarg == '!'))
|
||||||
|
- xtables_error(PARAMETER_PROBLEM,
|
||||||
|
- "chain name not allowed to start "
|
||||||
|
- "with `%c'\n", *optarg);
|
||||||
|
- if (xtables_find_target(optarg, XTF_TRY_LOAD))
|
||||||
|
- xtables_error(PARAMETER_PROBLEM,
|
||||||
|
- "chain name may not clash "
|
||||||
|
- "with target name\n");
|
||||||
|
+ parse_chain(optarg);
|
||||||
|
add_command(&p->command, CMD_NEW_CHAIN, CMD_NONE,
|
||||||
|
cs->invert);
|
||||||
|
p->chain = optarg;
|
||||||
|
--
|
||||||
|
2.34.1
|
||||||
|
|
@ -0,0 +1,112 @@
|
|||||||
|
From 257c18bf4fbcc7e5f4fb3c9cadab699986a9bd41 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Phil Sutter <phil@nwl.cc>
|
||||||
|
Date: Wed, 16 Mar 2022 17:14:07 +0100
|
||||||
|
Subject: [PATCH] nft: Reject standard targets as chain names when restoring
|
||||||
|
|
||||||
|
Reuse parse_chain() called from do_parse() for '-N' and rename it for a
|
||||||
|
better description of what it does.
|
||||||
|
|
||||||
|
Note that by itself, this patch will likely kill iptables-restore
|
||||||
|
performance for big rulesets due to the extra extension lookup for chain
|
||||||
|
lines. A following patch announcing those chains to libxtables will
|
||||||
|
alleviate that.
|
||||||
|
|
||||||
|
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
||||||
|
Reviewed-by: Florian Westphal <fw@strlen.de>
|
||||||
|
(cherry picked from commit b1aee6b2238794446feba41778f88703784560f7)
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
iptables/xshared.c
|
||||||
|
-> Parts manually applied due to unmerged do_parse() function.
|
||||||
|
---
|
||||||
|
iptables/ip6tables.c | 2 +-
|
||||||
|
iptables/iptables.c | 2 +-
|
||||||
|
iptables/xshared.c | 2 +-
|
||||||
|
iptables/xshared.h | 2 +-
|
||||||
|
iptables/xtables-restore.c | 5 +----
|
||||||
|
iptables/xtables.c | 2 +-
|
||||||
|
6 files changed, 6 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/iptables/ip6tables.c b/iptables/ip6tables.c
|
||||||
|
index 614d1e249c06d..b96dc033e7ebb 100644
|
||||||
|
--- a/iptables/ip6tables.c
|
||||||
|
+++ b/iptables/ip6tables.c
|
||||||
|
@@ -1247,7 +1247,7 @@ int do_command6(int argc, char *argv[], char **table,
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'N':
|
||||||
|
- parse_chain(optarg);
|
||||||
|
+ assert_valid_chain_name(optarg);
|
||||||
|
add_command(&command, CMD_NEW_CHAIN, CMD_NONE,
|
||||||
|
cs.invert);
|
||||||
|
chain = optarg;
|
||||||
|
diff --git a/iptables/iptables.c b/iptables/iptables.c
|
||||||
|
index 3b395981cc8ea..6e2946f5660de 100644
|
||||||
|
--- a/iptables/iptables.c
|
||||||
|
+++ b/iptables/iptables.c
|
||||||
|
@@ -1243,7 +1243,7 @@ int do_command4(int argc, char *argv[], char **table,
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'N':
|
||||||
|
- parse_chain(optarg);
|
||||||
|
+ assert_valid_chain_name(optarg);
|
||||||
|
add_command(&command, CMD_NEW_CHAIN, CMD_NONE,
|
||||||
|
cs.invert);
|
||||||
|
chain = optarg;
|
||||||
|
diff --git a/iptables/xshared.c b/iptables/xshared.c
|
||||||
|
index de8326b6c7b05..0c232ca2ae8d5 100644
|
||||||
|
--- a/iptables/xshared.c
|
||||||
|
+++ b/iptables/xshared.c
|
||||||
|
@@ -776,7 +776,7 @@ int parse_rulenumber(const char *rule)
|
||||||
|
return rulenum;
|
||||||
|
}
|
||||||
|
|
||||||
|
-void parse_chain(const char *chainname)
|
||||||
|
+void assert_valid_chain_name(const char *chainname)
|
||||||
|
{
|
||||||
|
const char *ptr;
|
||||||
|
|
||||||
|
diff --git a/iptables/xshared.h b/iptables/xshared.h
|
||||||
|
index f5d2f8d0a2bc5..095a574d85879 100644
|
||||||
|
--- a/iptables/xshared.h
|
||||||
|
+++ b/iptables/xshared.h
|
||||||
|
@@ -217,6 +217,6 @@ char cmd2char(int option);
|
||||||
|
void add_command(unsigned int *cmd, const int newcmd,
|
||||||
|
const int othercmds, int invert);
|
||||||
|
int parse_rulenumber(const char *rule);
|
||||||
|
-void parse_chain(const char *chainname);
|
||||||
|
+void assert_valid_chain_name(const char *chainname);
|
||||||
|
|
||||||
|
#endif /* IPTABLES_XSHARED_H */
|
||||||
|
diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c
|
||||||
|
index c472ac9bf651b..a078da32045dc 100644
|
||||||
|
--- a/iptables/xtables-restore.c
|
||||||
|
+++ b/iptables/xtables-restore.c
|
||||||
|
@@ -150,10 +150,7 @@ static void xtables_restore_parse_line(struct nft_handle *h,
|
||||||
|
"%s: line %u chain name invalid\n",
|
||||||
|
xt_params->program_name, line);
|
||||||
|
|
||||||
|
- if (strlen(chain) >= XT_EXTENSION_MAXNAMELEN)
|
||||||
|
- xtables_error(PARAMETER_PROBLEM,
|
||||||
|
- "Invalid chain name `%s' (%u chars max)",
|
||||||
|
- chain, XT_EXTENSION_MAXNAMELEN - 1);
|
||||||
|
+ assert_valid_chain_name(chain);
|
||||||
|
|
||||||
|
policy = strtok(NULL, " \t\n");
|
||||||
|
DEBUGP("line %u, policy '%s'\n", line, policy);
|
||||||
|
diff --git a/iptables/xtables.c b/iptables/xtables.c
|
||||||
|
index 3ea293ee7c411..9006962472c58 100644
|
||||||
|
--- a/iptables/xtables.c
|
||||||
|
+++ b/iptables/xtables.c
|
||||||
|
@@ -668,7 +668,7 @@ void do_parse(struct nft_handle *h, int argc, char *argv[],
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'N':
|
||||||
|
- parse_chain(optarg);
|
||||||
|
+ assert_valid_chain_name(optarg);
|
||||||
|
add_command(&p->command, CMD_NEW_CHAIN, CMD_NONE,
|
||||||
|
cs->invert);
|
||||||
|
p->chain = optarg;
|
||||||
|
--
|
||||||
|
2.34.1
|
||||||
|
|
142
SOURCES/0068-libxtables-Implement-notargets-hash-table.patch
Normal file
142
SOURCES/0068-libxtables-Implement-notargets-hash-table.patch
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
From 3e8e2f0a6590a3b1eeb989e364fe4b5638be108f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Phil Sutter <phil@nwl.cc>
|
||||||
|
Date: Tue, 15 Dec 2020 15:40:56 +0100
|
||||||
|
Subject: [PATCH] libxtables: Implement notargets hash table
|
||||||
|
|
||||||
|
Target lookup is relatively costly due to the filesystem access. Avoid
|
||||||
|
this overhead in huge rulesets which contain many chain jumps by caching
|
||||||
|
the failed lookups into a hashtable for later.
|
||||||
|
|
||||||
|
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
||||||
|
Acked-by: Florian Westphal <fw@strlen.de>
|
||||||
|
(cherry picked from commit f58b0d7406451afbb4b9b6c7888990c964fa7c79)
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
libxtables/xtables.c
|
||||||
|
-> Context changes and missing xtables_fini() due to missing commit
|
||||||
|
7db4333dc0b6c ("libxtables: Introduce xtables_fini()")
|
||||||
|
---
|
||||||
|
libxtables/xtables.c | 79 ++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 79 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/libxtables/xtables.c b/libxtables/xtables.c
|
||||||
|
index 58dd69440253d..1e1c218df7441 100644
|
||||||
|
--- a/libxtables/xtables.c
|
||||||
|
+++ b/libxtables/xtables.c
|
||||||
|
@@ -48,6 +48,7 @@
|
||||||
|
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||||
|
#include <linux/netfilter_ipv6/ip6_tables.h>
|
||||||
|
#include <libiptc/libxtc.h>
|
||||||
|
+#include <libiptc/linux_list.h>
|
||||||
|
|
||||||
|
#ifndef NO_SHARED_LIBS
|
||||||
|
#include <dlfcn.h>
|
||||||
|
@@ -208,6 +209,71 @@ static bool xtables_fully_register_pending_match(struct xtables_match *me,
|
||||||
|
static bool xtables_fully_register_pending_target(struct xtables_target *me,
|
||||||
|
struct xtables_target *prev);
|
||||||
|
|
||||||
|
+struct notarget {
|
||||||
|
+ struct hlist_node node;
|
||||||
|
+ char name[];
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+#define NOTARGET_HSIZE 512
|
||||||
|
+static struct hlist_head notargets[NOTARGET_HSIZE];
|
||||||
|
+
|
||||||
|
+static void notargets_hlist_init(void)
|
||||||
|
+{
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < NOTARGET_HSIZE; i++)
|
||||||
|
+ INIT_HLIST_HEAD(¬argets[i]);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void notargets_hlist_free(void)
|
||||||
|
+{
|
||||||
|
+ struct hlist_node *pos, *n;
|
||||||
|
+ struct notarget *cur;
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < NOTARGET_HSIZE; i++) {
|
||||||
|
+ hlist_for_each_entry_safe(cur, pos, n, ¬argets[i], node) {
|
||||||
|
+ hlist_del(&cur->node);
|
||||||
|
+ free(cur);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static uint32_t djb_hash(const char *key)
|
||||||
|
+{
|
||||||
|
+ uint32_t i, hash = 5381;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < strlen(key); i++)
|
||||||
|
+ hash = ((hash << 5) + hash) + key[i];
|
||||||
|
+
|
||||||
|
+ return hash;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static struct notarget *notargets_hlist_lookup(const char *name)
|
||||||
|
+{
|
||||||
|
+ uint32_t key = djb_hash(name) % NOTARGET_HSIZE;
|
||||||
|
+ struct hlist_node *node;
|
||||||
|
+ struct notarget *cur;
|
||||||
|
+
|
||||||
|
+ hlist_for_each_entry(cur, node, ¬argets[key], node) {
|
||||||
|
+ if (!strcmp(name, cur->name))
|
||||||
|
+ return cur;
|
||||||
|
+ }
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void notargets_hlist_insert(const char *name)
|
||||||
|
+{
|
||||||
|
+ struct notarget *cur;
|
||||||
|
+
|
||||||
|
+ if (!name)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ cur = xtables_malloc(sizeof(*cur) + strlen(name) + 1);
|
||||||
|
+ strcpy(cur->name, name);
|
||||||
|
+ hlist_add_head(&cur->node, ¬argets[djb_hash(name) % NOTARGET_HSIZE]);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void xtables_init(void)
|
||||||
|
{
|
||||||
|
xtables_libdir = getenv("XTABLES_LIBDIR");
|
||||||
|
@@ -233,6 +299,13 @@ void xtables_init(void)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
xtables_libdir = XTABLES_LIBDIR;
|
||||||
|
+
|
||||||
|
+ notargets_hlist_init();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void xtables_fini(void)
|
||||||
|
+{
|
||||||
|
+ notargets_hlist_free();
|
||||||
|
}
|
||||||
|
|
||||||
|
void xtables_set_nfproto(uint8_t nfproto)
|
||||||
|
@@ -750,6 +823,10 @@ xtables_find_target(const char *name, enum xtables_tryload tryload)
|
||||||
|
|| strcmp(name, XTC_LABEL_QUEUE) == 0
|
||||||
|
|| strcmp(name, XTC_LABEL_RETURN) == 0)
|
||||||
|
name = "standard";
|
||||||
|
+ /* known non-target? */
|
||||||
|
+ else if (notargets_hlist_lookup(name) &&
|
||||||
|
+ tryload != XTF_LOAD_MUST_SUCCEED)
|
||||||
|
+ return NULL;
|
||||||
|
|
||||||
|
/* Trigger delayed initialization */
|
||||||
|
for (dptr = &xtables_pending_targets; *dptr; ) {
|
||||||
|
@@ -813,6 +890,8 @@ xtables_find_target(const char *name, enum xtables_tryload tryload)
|
||||||
|
|
||||||
|
if (ptr)
|
||||||
|
ptr->used = 1;
|
||||||
|
+ else
|
||||||
|
+ notargets_hlist_insert(name);
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.34.1
|
||||||
|
|
@ -0,0 +1,86 @@
|
|||||||
|
From 86bf4207cb744c38807fb5c42c5921fc9964a2af Mon Sep 17 00:00:00 2001
|
||||||
|
From: Phil Sutter <phil@nwl.cc>
|
||||||
|
Date: Fri, 4 Mar 2022 12:50:01 +0100
|
||||||
|
Subject: [PATCH] libxtables: Boost rule target checks by announcing chain
|
||||||
|
names
|
||||||
|
|
||||||
|
When restoring a ruleset, feed libxtables with chain names from
|
||||||
|
respective lines to avoid an extension search.
|
||||||
|
|
||||||
|
While the user's intention is clear, this effectively disables the
|
||||||
|
sanity check for clashes with target extensions. But:
|
||||||
|
|
||||||
|
* The check yielded only a warning and the clashing chain was finally
|
||||||
|
accepted.
|
||||||
|
|
||||||
|
* Users crafting iptables dumps for feeding into iptables-restore likely
|
||||||
|
know what they're doing.
|
||||||
|
|
||||||
|
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
||||||
|
Acked-by: Florian Westphal <fw@strlen.de>
|
||||||
|
(cherry picked from commit ac4c84cc63d3cc021ca532692885a644fcde4518)
|
||||||
|
---
|
||||||
|
include/xtables.h | 3 +++
|
||||||
|
iptables/iptables-restore.c | 1 +
|
||||||
|
iptables/xtables-restore.c | 1 +
|
||||||
|
libxtables/xtables.c | 6 ++++++
|
||||||
|
4 files changed, 11 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/include/xtables.h b/include/xtables.h
|
||||||
|
index 4aa084a1a2a30..d77a73a4303a7 100644
|
||||||
|
--- a/include/xtables.h
|
||||||
|
+++ b/include/xtables.h
|
||||||
|
@@ -632,6 +632,9 @@ void xt_xlate_add_comment(struct xt_xlate *xl, const char *comment);
|
||||||
|
const char *xt_xlate_get_comment(struct xt_xlate *xl);
|
||||||
|
const char *xt_xlate_get(struct xt_xlate *xl);
|
||||||
|
|
||||||
|
+/* informed target lookups */
|
||||||
|
+void xtables_announce_chain(const char *name);
|
||||||
|
+
|
||||||
|
#ifdef XTABLES_INTERNAL
|
||||||
|
|
||||||
|
/* Shipped modules rely on this... */
|
||||||
|
diff --git a/iptables/iptables-restore.c b/iptables/iptables-restore.c
|
||||||
|
index b0a51d491c508..339abaa32a055 100644
|
||||||
|
--- a/iptables/iptables-restore.c
|
||||||
|
+++ b/iptables/iptables-restore.c
|
||||||
|
@@ -309,6 +309,7 @@ ip46tables_restore_main(const struct iptables_restore_cb *cb,
|
||||||
|
cb->ops->strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
+ xtables_announce_chain(chain);
|
||||||
|
ret = 1;
|
||||||
|
|
||||||
|
} else if (in_table) {
|
||||||
|
diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c
|
||||||
|
index a078da32045dc..41e7cb7661464 100644
|
||||||
|
--- a/iptables/xtables-restore.c
|
||||||
|
+++ b/iptables/xtables-restore.c
|
||||||
|
@@ -150,6 +150,7 @@ static void xtables_restore_parse_line(struct nft_handle *h,
|
||||||
|
"%s: line %u chain name invalid\n",
|
||||||
|
xt_params->program_name, line);
|
||||||
|
|
||||||
|
+ xtables_announce_chain(chain);
|
||||||
|
assert_valid_chain_name(chain);
|
||||||
|
|
||||||
|
policy = strtok(NULL, " \t\n");
|
||||||
|
diff --git a/libxtables/xtables.c b/libxtables/xtables.c
|
||||||
|
index 1e1c218df7441..4aee74acb6816 100644
|
||||||
|
--- a/libxtables/xtables.c
|
||||||
|
+++ b/libxtables/xtables.c
|
||||||
|
@@ -274,6 +274,12 @@ static void notargets_hlist_insert(const char *name)
|
||||||
|
hlist_add_head(&cur->node, ¬argets[djb_hash(name) % NOTARGET_HSIZE]);
|
||||||
|
}
|
||||||
|
|
||||||
|
+void xtables_announce_chain(const char *name)
|
||||||
|
+{
|
||||||
|
+ if (!notargets_hlist_lookup(name))
|
||||||
|
+ notargets_hlist_insert(name);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void xtables_init(void)
|
||||||
|
{
|
||||||
|
xtables_libdir = getenv("XTABLES_LIBDIR");
|
||||||
|
--
|
||||||
|
2.34.1
|
||||||
|
|
156
SOURCES/0070-Use-proto_to_name-from-xshared-in-more-places.patch
Normal file
156
SOURCES/0070-Use-proto_to_name-from-xshared-in-more-places.patch
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
From f8839b3651e0ffbb93b6ce4675809d60782a4396 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Phil Sutter <phil@nwl.cc>
|
||||||
|
Date: Tue, 17 Nov 2020 00:57:10 +0100
|
||||||
|
Subject: [PATCH] Use proto_to_name() from xshared in more places
|
||||||
|
|
||||||
|
Share the common proto name lookup code. While being at it, make proto
|
||||||
|
number variable 16bit, values may exceed 256.
|
||||||
|
|
||||||
|
This aligns iptables-nft '-p' argument printing with legacy iptables. In
|
||||||
|
practice, this should make a difference only in corner cases.
|
||||||
|
|
||||||
|
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
||||||
|
(cherry picked from commit 556f704458cdb509d395ddb7d2629987d60e762e)
|
||||||
|
---
|
||||||
|
include/xtables.h | 2 +-
|
||||||
|
iptables/ip6tables.c | 22 +++++-----------------
|
||||||
|
iptables/iptables.c | 20 +++++---------------
|
||||||
|
iptables/nft-shared.c | 6 +++---
|
||||||
|
iptables/xshared.c | 2 +-
|
||||||
|
iptables/xshared.h | 2 +-
|
||||||
|
6 files changed, 16 insertions(+), 38 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/include/xtables.h b/include/xtables.h
|
||||||
|
index d77a73a4303a7..06982e720cbb8 100644
|
||||||
|
--- a/include/xtables.h
|
||||||
|
+++ b/include/xtables.h
|
||||||
|
@@ -395,7 +395,7 @@ struct xtables_rule_match {
|
||||||
|
*/
|
||||||
|
struct xtables_pprot {
|
||||||
|
const char *name;
|
||||||
|
- uint8_t num;
|
||||||
|
+ uint16_t num;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum xtables_tryload {
|
||||||
|
diff --git a/iptables/ip6tables.c b/iptables/ip6tables.c
|
||||||
|
index b96dc033e7ebb..4860682001360 100644
|
||||||
|
--- a/iptables/ip6tables.c
|
||||||
|
+++ b/iptables/ip6tables.c
|
||||||
|
@@ -849,28 +849,16 @@ print_iface(char letter, const char *iface, const unsigned char *mask,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-/* The ip6tables looks up the /etc/protocols. */
|
||||||
|
static void print_proto(uint16_t proto, int invert)
|
||||||
|
{
|
||||||
|
if (proto) {
|
||||||
|
- unsigned int i;
|
||||||
|
+ const char *pname = proto_to_name(proto, 0);
|
||||||
|
const char *invertstr = invert ? " !" : "";
|
||||||
|
|
||||||
|
- const struct protoent *pent = getprotobynumber(proto);
|
||||||
|
- if (pent) {
|
||||||
|
- printf("%s -p %s",
|
||||||
|
- invertstr, pent->p_name);
|
||||||
|
- return;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- for (i = 0; xtables_chain_protos[i].name != NULL; ++i)
|
||||||
|
- if (xtables_chain_protos[i].num == proto) {
|
||||||
|
- printf("%s -p %s",
|
||||||
|
- invertstr, xtables_chain_protos[i].name);
|
||||||
|
- return;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- printf("%s -p %u", invertstr, proto);
|
||||||
|
+ if (pname)
|
||||||
|
+ printf("%s -p %s", invertstr, pname);
|
||||||
|
+ else
|
||||||
|
+ printf("%s -p %u", invertstr, proto);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/iptables/iptables.c b/iptables/iptables.c
|
||||||
|
index 6e2946f5660de..620429b5d4817 100644
|
||||||
|
--- a/iptables/iptables.c
|
||||||
|
+++ b/iptables/iptables.c
|
||||||
|
@@ -819,23 +819,13 @@ list_entries(const xt_chainlabel chain, int rulenum, int verbose, int numeric,
|
||||||
|
static void print_proto(uint16_t proto, int invert)
|
||||||
|
{
|
||||||
|
if (proto) {
|
||||||
|
- unsigned int i;
|
||||||
|
+ const char *pname = proto_to_name(proto, 0);
|
||||||
|
const char *invertstr = invert ? " !" : "";
|
||||||
|
|
||||||
|
- const struct protoent *pent = getprotobynumber(proto);
|
||||||
|
- if (pent) {
|
||||||
|
- printf("%s -p %s", invertstr, pent->p_name);
|
||||||
|
- return;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- for (i = 0; xtables_chain_protos[i].name != NULL; ++i)
|
||||||
|
- if (xtables_chain_protos[i].num == proto) {
|
||||||
|
- printf("%s -p %s",
|
||||||
|
- invertstr, xtables_chain_protos[i].name);
|
||||||
|
- return;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- printf("%s -p %u", invertstr, proto);
|
||||||
|
+ if (pname)
|
||||||
|
+ printf("%s -p %s", invertstr, pname);
|
||||||
|
+ else
|
||||||
|
+ printf("%s -p %u", invertstr, proto);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c
|
||||||
|
index d73d0b6159be6..e3ba4ac34146f 100644
|
||||||
|
--- a/iptables/nft-shared.c
|
||||||
|
+++ b/iptables/nft-shared.c
|
||||||
|
@@ -821,13 +821,13 @@ void save_rule_details(const struct iptables_command_state *cs,
|
||||||
|
}
|
||||||
|
|
||||||
|
if (proto > 0) {
|
||||||
|
- const struct protoent *pent = getprotobynumber(proto);
|
||||||
|
+ const char *pname = proto_to_name(proto, 0);
|
||||||
|
|
||||||
|
if (invflags & XT_INV_PROTO)
|
||||||
|
printf("! ");
|
||||||
|
|
||||||
|
- if (pent)
|
||||||
|
- printf("-p %s ", pent->p_name);
|
||||||
|
+ if (pname)
|
||||||
|
+ printf("-p %s ", pname);
|
||||||
|
else
|
||||||
|
printf("-p %u ", proto);
|
||||||
|
}
|
||||||
|
diff --git a/iptables/xshared.c b/iptables/xshared.c
|
||||||
|
index 0c232ca2ae8d5..7a55ed5d15715 100644
|
||||||
|
--- a/iptables/xshared.c
|
||||||
|
+++ b/iptables/xshared.c
|
||||||
|
@@ -48,7 +48,7 @@ void print_extension_helps(const struct xtables_target *t,
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
-proto_to_name(uint8_t proto, int nolookup)
|
||||||
|
+proto_to_name(uint16_t proto, int nolookup)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
diff --git a/iptables/xshared.h b/iptables/xshared.h
|
||||||
|
index 095a574d85879..f3c7f28806619 100644
|
||||||
|
--- a/iptables/xshared.h
|
||||||
|
+++ b/iptables/xshared.h
|
||||||
|
@@ -146,7 +146,7 @@ enum {
|
||||||
|
|
||||||
|
extern void print_extension_helps(const struct xtables_target *,
|
||||||
|
const struct xtables_rule_match *);
|
||||||
|
-extern const char *proto_to_name(uint8_t, int);
|
||||||
|
+extern const char *proto_to_name(uint16_t, int);
|
||||||
|
extern int command_default(struct iptables_command_state *,
|
||||||
|
struct xtables_globals *);
|
||||||
|
extern struct xtables_match *load_proto(struct iptables_command_state *);
|
||||||
|
--
|
||||||
|
2.34.1
|
||||||
|
|
@ -0,0 +1,64 @@
|
|||||||
|
From afcbce6924dfe05af4b41bf46b21794f4a4d8302 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Phil Sutter <phil@nwl.cc>
|
||||||
|
Date: Fri, 11 Feb 2022 17:39:24 +0100
|
||||||
|
Subject: [PATCH] libxtables: Register only the highest revision extension
|
||||||
|
|
||||||
|
When fully registering extensions, ignore all consecutive ones with same
|
||||||
|
name and family value. Since commit b3ac87038f4e4 ("libxtables: Make
|
||||||
|
sure extensions register in revision order"), one may safely assume the
|
||||||
|
list of pending extensions has highest revision numbers first. Since
|
||||||
|
iptables is only interested in the highest revision the kernel supports,
|
||||||
|
registration and compatibility checks may be skipped once the first
|
||||||
|
matching extension in pending list has validated.
|
||||||
|
|
||||||
|
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
||||||
|
(cherry picked from commit 2dbb49d15fb44ddd521a734eca3be3f940b7c1ba)
|
||||||
|
---
|
||||||
|
libxtables/xtables.c | 10 ++++++++--
|
||||||
|
1 file changed, 8 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libxtables/xtables.c b/libxtables/xtables.c
|
||||||
|
index 4aee74acb6816..57ad0330a454c 100644
|
||||||
|
--- a/libxtables/xtables.c
|
||||||
|
+++ b/libxtables/xtables.c
|
||||||
|
@@ -701,6 +701,7 @@ xtables_find_match(const char *name, enum xtables_tryload tryload,
|
||||||
|
struct xtables_match **dptr;
|
||||||
|
struct xtables_match *ptr;
|
||||||
|
const char *icmp6 = "icmp6";
|
||||||
|
+ bool found = false;
|
||||||
|
|
||||||
|
if (strlen(name) >= XT_EXTENSION_MAXNAMELEN)
|
||||||
|
xtables_error(PARAMETER_PROBLEM,
|
||||||
|
@@ -719,7 +720,9 @@ xtables_find_match(const char *name, enum xtables_tryload tryload,
|
||||||
|
if (extension_cmp(name, (*dptr)->name, (*dptr)->family)) {
|
||||||
|
ptr = *dptr;
|
||||||
|
*dptr = (*dptr)->next;
|
||||||
|
- if (xtables_fully_register_pending_match(ptr, prev)) {
|
||||||
|
+ if (!found &&
|
||||||
|
+ xtables_fully_register_pending_match(ptr, prev)) {
|
||||||
|
+ found = true;
|
||||||
|
prev = ptr;
|
||||||
|
continue;
|
||||||
|
} else if (prev) {
|
||||||
|
@@ -821,6 +824,7 @@ xtables_find_target(const char *name, enum xtables_tryload tryload)
|
||||||
|
struct xtables_target *prev = NULL;
|
||||||
|
struct xtables_target **dptr;
|
||||||
|
struct xtables_target *ptr;
|
||||||
|
+ bool found = false;
|
||||||
|
|
||||||
|
/* Standard target? */
|
||||||
|
if (strcmp(name, "") == 0
|
||||||
|
@@ -839,7 +843,9 @@ xtables_find_target(const char *name, enum xtables_tryload tryload)
|
||||||
|
if (extension_cmp(name, (*dptr)->name, (*dptr)->family)) {
|
||||||
|
ptr = *dptr;
|
||||||
|
*dptr = (*dptr)->next;
|
||||||
|
- if (xtables_fully_register_pending_target(ptr, prev)) {
|
||||||
|
+ if (!found &&
|
||||||
|
+ xtables_fully_register_pending_target(ptr, prev)) {
|
||||||
|
+ found = true;
|
||||||
|
prev = ptr;
|
||||||
|
continue;
|
||||||
|
} else if (prev) {
|
||||||
|
--
|
||||||
|
2.34.1
|
||||||
|
|
119
SOURCES/0072-xshared-Fix-response-to-unprivileged-users.patch
Normal file
119
SOURCES/0072-xshared-Fix-response-to-unprivileged-users.patch
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
From 6d1b02218a591ff95053b22c1ed802355e44878d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Phil Sutter <phil@nwl.cc>
|
||||||
|
Date: Tue, 18 Jan 2022 22:39:08 +0100
|
||||||
|
Subject: [PATCH] xshared: Fix response to unprivileged users
|
||||||
|
|
||||||
|
Expected behaviour in both variants is:
|
||||||
|
|
||||||
|
* Print help without error, append extension help if -m and/or -j
|
||||||
|
options are present
|
||||||
|
* Indicate lack of permissions in an error message for anything else
|
||||||
|
|
||||||
|
With iptables-nft, this was broken basically from day 1. Shared use of
|
||||||
|
do_parse() then somewhat broke legacy: it started complaining about
|
||||||
|
inability to create a lock file.
|
||||||
|
|
||||||
|
Fix this by making iptables-nft assume extension revision 0 is present
|
||||||
|
if permissions don't allow to verify. This is consistent with legacy.
|
||||||
|
|
||||||
|
Second part is to exit directly after printing help - this avoids having
|
||||||
|
to make the following code "nop-aware" to prevent privileged actions.
|
||||||
|
|
||||||
|
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
||||||
|
Reviewed-by: Florian Westphal <fw@strlen.de>
|
||||||
|
(cherry picked from commit 26ecdf53960658771c0fc582f72a4025e2887f75)
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
iptables/xshared.c
|
||||||
|
-> Some chunks not applied as not necessary in RHEL8.
|
||||||
|
---
|
||||||
|
iptables/nft.c | 5 ++
|
||||||
|
.../testcases/iptables/0008-unprivileged_0 | 60 +++++++++++++++++++
|
||||||
|
2 files changed, 65 insertions(+)
|
||||||
|
create mode 100755 iptables/tests/shell/testcases/iptables/0008-unprivileged_0
|
||||||
|
|
||||||
|
diff --git a/iptables/nft.c b/iptables/nft.c
|
||||||
|
index dc5490c085364..c5cc6f83bf573 100644
|
||||||
|
--- a/iptables/nft.c
|
||||||
|
+++ b/iptables/nft.c
|
||||||
|
@@ -3110,6 +3110,11 @@ int nft_compatible_revision(const char *name, uint8_t rev, int opt)
|
||||||
|
err:
|
||||||
|
mnl_socket_close(nl);
|
||||||
|
|
||||||
|
+ /* pretend revision 0 is valid if not permitted to check -
|
||||||
|
+ * this is required for printing extension help texts as user */
|
||||||
|
+ if (ret < 0 && errno == EPERM && rev == 0)
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
return ret < 0 ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/iptables/tests/shell/testcases/iptables/0008-unprivileged_0 b/iptables/tests/shell/testcases/iptables/0008-unprivileged_0
|
||||||
|
new file mode 100755
|
||||||
|
index 0000000000000..43e3bc8721dbd
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/iptables/tests/shell/testcases/iptables/0008-unprivileged_0
|
||||||
|
@@ -0,0 +1,60 @@
|
||||||
|
+#!/bin/bash
|
||||||
|
+
|
||||||
|
+# iptables may print match/target specific help texts
|
||||||
|
+# help output should work for unprivileged users
|
||||||
|
+
|
||||||
|
+run() {
|
||||||
|
+ echo "running: $*" >&2
|
||||||
|
+ runuser -u nobody -- "$@"
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+grep_or_rc() {
|
||||||
|
+ declare -g rc
|
||||||
|
+ grep -q "$*" && return 0
|
||||||
|
+ echo "missing in output: $*" >&2
|
||||||
|
+ return 1
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+out=$(run $XT_MULTI iptables --help)
|
||||||
|
+let "rc+=$?"
|
||||||
|
+grep_or_rc "iptables -h (print this help information)" <<< "$out"
|
||||||
|
+let "rc+=$?"
|
||||||
|
+
|
||||||
|
+out=$(run $XT_MULTI iptables -m limit --help)
|
||||||
|
+let "rc+=$?"
|
||||||
|
+grep_or_rc "limit match options:" <<< "$out"
|
||||||
|
+let "rc+=$?"
|
||||||
|
+
|
||||||
|
+out=$(run $XT_MULTI iptables -p tcp --help)
|
||||||
|
+let "rc+=$?"
|
||||||
|
+grep_or_rc "tcp match options:" <<< "$out"
|
||||||
|
+let "rc+=$?"
|
||||||
|
+
|
||||||
|
+out=$(run $XT_MULTI iptables -j DNAT --help)
|
||||||
|
+let "rc+=$?"
|
||||||
|
+grep_or_rc "DNAT target options:" <<< "$out"
|
||||||
|
+let "rc+=$?"
|
||||||
|
+
|
||||||
|
+out=$(run $XT_MULTI iptables -p tcp -j DNAT --help)
|
||||||
|
+let "rc+=$?"
|
||||||
|
+grep_or_rc "tcp match options:" <<< "$out"
|
||||||
|
+let "rc+=$?"
|
||||||
|
+out=$(run $XT_MULTI iptables -p tcp -j DNAT --help)
|
||||||
|
+let "rc+=$?"
|
||||||
|
+grep_or_rc "DNAT target options:" <<< "$out"
|
||||||
|
+let "rc+=$?"
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+run $XT_MULTI iptables -L 2>&1 | \
|
||||||
|
+ grep_or_rc "Permission denied"
|
||||||
|
+let "rc+=$?"
|
||||||
|
+
|
||||||
|
+run $XT_MULTI iptables -A FORWARD -p tcp --dport 123 2>&1 | \
|
||||||
|
+ grep_or_rc "Permission denied"
|
||||||
|
+let "rc+=$?"
|
||||||
|
+
|
||||||
|
+run $XT_MULTI iptables -A FORWARD -j DNAT --to-destination 1.2.3.4 2>&1 | \
|
||||||
|
+ grep_or_rc "Permission denied"
|
||||||
|
+let "rc+=$?"
|
||||||
|
+
|
||||||
|
+exit $rc
|
||||||
|
--
|
||||||
|
2.34.1
|
||||||
|
|
@ -0,0 +1,84 @@
|
|||||||
|
From 4243bd97f3c703a75e795fdc6dd2273a7c74e85c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Phil Sutter <phil@nwl.cc>
|
||||||
|
Date: Fri, 11 Feb 2022 17:47:22 +0100
|
||||||
|
Subject: [PATCH] Improve error messages for unsupported extensions
|
||||||
|
|
||||||
|
If a given extension was not supported by the kernel, iptables would
|
||||||
|
print a rather confusing error message if extension parameters were
|
||||||
|
given:
|
||||||
|
|
||||||
|
| # rm /lib/modules/$(uname -r)/kernel/net/netfilter/xt_LOG.ko
|
||||||
|
| # iptables -A FORWARD -j LOG --log-prefix foo
|
||||||
|
| iptables v1.8.7 (legacy): unknown option "--log-prefix"
|
||||||
|
|
||||||
|
Avoid this by pretending extension revision 0 is always supported. It is
|
||||||
|
the same hack as used to successfully print extension help texts as
|
||||||
|
unprivileged user, extended to all error codes to serve privileged ones
|
||||||
|
as well.
|
||||||
|
|
||||||
|
In addition, print a warning if kernel rejected revision 0 and it's not
|
||||||
|
a permissions problem. This helps users find out which extension in a
|
||||||
|
rule the kernel didn't like.
|
||||||
|
|
||||||
|
Finally, the above commands result in these messages:
|
||||||
|
|
||||||
|
| Warning: Extension LOG revision 0 not supported, missing kernel module?
|
||||||
|
| iptables: No chain/target/match by that name.
|
||||||
|
|
||||||
|
Or, for iptables-nft:
|
||||||
|
|
||||||
|
| Warning: Extension LOG revision 0 not supported, missing kernel module?
|
||||||
|
| iptables v1.8.7 (nf_tables): RULE_APPEND failed (No such file or directory): rule in chain FORWARD
|
||||||
|
|
||||||
|
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
||||||
|
(cherry picked from commit 17534cb18ed0a5052dc45c117401251359dba6aa)
|
||||||
|
---
|
||||||
|
iptables/nft.c | 12 +++++++++---
|
||||||
|
libxtables/xtables.c | 7 ++++++-
|
||||||
|
2 files changed, 15 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/iptables/nft.c b/iptables/nft.c
|
||||||
|
index c5cc6f83bf573..9643abf2d0085 100644
|
||||||
|
--- a/iptables/nft.c
|
||||||
|
+++ b/iptables/nft.c
|
||||||
|
@@ -3110,10 +3110,16 @@ int nft_compatible_revision(const char *name, uint8_t rev, int opt)
|
||||||
|
err:
|
||||||
|
mnl_socket_close(nl);
|
||||||
|
|
||||||
|
- /* pretend revision 0 is valid if not permitted to check -
|
||||||
|
- * this is required for printing extension help texts as user */
|
||||||
|
- if (ret < 0 && errno == EPERM && rev == 0)
|
||||||
|
+ /* pretend revision 0 is valid -
|
||||||
|
+ * this is required for printing extension help texts as user, also
|
||||||
|
+ * helps error messaging on unavailable kernel extension */
|
||||||
|
+ if (ret < 0 && rev == 0) {
|
||||||
|
+ if (errno != EPERM)
|
||||||
|
+ fprintf(stderr,
|
||||||
|
+ "Warning: Extension %s revision 0 not supported, missing kernel module?\n",
|
||||||
|
+ name);
|
||||||
|
return 1;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
return ret < 0 ? 0 : 1;
|
||||||
|
}
|
||||||
|
diff --git a/libxtables/xtables.c b/libxtables/xtables.c
|
||||||
|
index 57ad0330a454c..a5c8d7e2c17ef 100644
|
||||||
|
--- a/libxtables/xtables.c
|
||||||
|
+++ b/libxtables/xtables.c
|
||||||
|
@@ -968,7 +968,12 @@ int xtables_compatible_revision(const char *name, uint8_t revision, int opt)
|
||||||
|
/* Definitely don't support this? */
|
||||||
|
if (errno == ENOENT || errno == EPROTONOSUPPORT) {
|
||||||
|
close(sockfd);
|
||||||
|
- return 0;
|
||||||
|
+ /* Pretend revision 0 support for better error messaging */
|
||||||
|
+ if (revision == 0)
|
||||||
|
+ fprintf(stderr,
|
||||||
|
+ "Warning: Extension %s revision 0 not supported, missing kernel module?\n",
|
||||||
|
+ name);
|
||||||
|
+ return (revision == 0);
|
||||||
|
} else if (errno == ENOPROTOOPT) {
|
||||||
|
close(sockfd);
|
||||||
|
/* Assume only revision 0 support (old kernel) */
|
||||||
|
--
|
||||||
|
2.34.1
|
||||||
|
|
@ -0,0 +1,65 @@
|
|||||||
|
From 3696c4af80496a0dd5a3637e4be11754e2cdc99e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Phil Sutter <phil@nwl.cc>
|
||||||
|
Date: Wed, 4 May 2022 11:19:16 +0200
|
||||||
|
Subject: [PATCH] nft: Fix EPERM handling for extensions without rev 0
|
||||||
|
|
||||||
|
Treating revision 0 as compatible in EPERM case works fine as long as
|
||||||
|
there is a revision 0 of that extension defined in DSO. Fix the code for
|
||||||
|
others: Extend the EPERM handling to all revisions and keep the existing
|
||||||
|
warning for revision 0.
|
||||||
|
|
||||||
|
Fixes: 17534cb18ed0a ("Improve error messages for unsupported extensions")
|
||||||
|
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
||||||
|
(cherry picked from commit 8468fd4f7c85c21ab375402bc80d0188412b6cbf)
|
||||||
|
---
|
||||||
|
iptables/nft.c | 11 +++++++----
|
||||||
|
.../shell/testcases/iptables/0008-unprivileged_0 | 6 ++++++
|
||||||
|
2 files changed, 13 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/iptables/nft.c b/iptables/nft.c
|
||||||
|
index 9643abf2d0085..9839e8c683708 100644
|
||||||
|
--- a/iptables/nft.c
|
||||||
|
+++ b/iptables/nft.c
|
||||||
|
@@ -3110,15 +3110,18 @@ int nft_compatible_revision(const char *name, uint8_t rev, int opt)
|
||||||
|
err:
|
||||||
|
mnl_socket_close(nl);
|
||||||
|
|
||||||
|
- /* pretend revision 0 is valid -
|
||||||
|
+ /* ignore EPERM and errors for revision 0 -
|
||||||
|
* this is required for printing extension help texts as user, also
|
||||||
|
* helps error messaging on unavailable kernel extension */
|
||||||
|
- if (ret < 0 && rev == 0) {
|
||||||
|
- if (errno != EPERM)
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ if (errno == EPERM)
|
||||||
|
+ return 1;
|
||||||
|
+ if (rev == 0) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Warning: Extension %s revision 0 not supported, missing kernel module?\n",
|
||||||
|
name);
|
||||||
|
- return 1;
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret < 0 ? 0 : 1;
|
||||||
|
diff --git a/iptables/tests/shell/testcases/iptables/0008-unprivileged_0 b/iptables/tests/shell/testcases/iptables/0008-unprivileged_0
|
||||||
|
index 43e3bc8721dbd..983531fef4720 100755
|
||||||
|
--- a/iptables/tests/shell/testcases/iptables/0008-unprivileged_0
|
||||||
|
+++ b/iptables/tests/shell/testcases/iptables/0008-unprivileged_0
|
||||||
|
@@ -35,6 +35,12 @@ let "rc+=$?"
|
||||||
|
grep_or_rc "DNAT target options:" <<< "$out"
|
||||||
|
let "rc+=$?"
|
||||||
|
|
||||||
|
+# TEE has no revision 0
|
||||||
|
+out=$(run $XT_MULTI iptables -j TEE --help)
|
||||||
|
+let "rc+=$?"
|
||||||
|
+grep_or_rc "TEE target options:" <<< "$out"
|
||||||
|
+let "rc+=$?"
|
||||||
|
+
|
||||||
|
out=$(run $XT_MULTI iptables -p tcp -j DNAT --help)
|
||||||
|
let "rc+=$?"
|
||||||
|
grep_or_rc "tcp match options:" <<< "$out"
|
||||||
|
--
|
||||||
|
2.34.1
|
||||||
|
|
@ -0,0 +1,61 @@
|
|||||||
|
From 4d61a3ea7bc6cbef8d4ea021e4998137cfca1453 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Phil Sutter <phil@nwl.cc>
|
||||||
|
Date: Thu, 2 Jun 2022 13:44:45 +0200
|
||||||
|
Subject: [PATCH] tests: shell: Check overhead in iptables-save and -restore
|
||||||
|
|
||||||
|
Some repeated calls have been reduced recently, assert this in a test
|
||||||
|
evaluating strace output.
|
||||||
|
|
||||||
|
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
||||||
|
(cherry picked from commit 0416ae5dea134b33e22c97e68b64010d679debe1)
|
||||||
|
---
|
||||||
|
.../shell/testcases/ipt-save/0007-overhead_0 | 37 +++++++++++++++++++
|
||||||
|
1 file changed, 37 insertions(+)
|
||||||
|
create mode 100755 iptables/tests/shell/testcases/ipt-save/0007-overhead_0
|
||||||
|
|
||||||
|
diff --git a/iptables/tests/shell/testcases/ipt-save/0007-overhead_0 b/iptables/tests/shell/testcases/ipt-save/0007-overhead_0
|
||||||
|
new file mode 100755
|
||||||
|
index 0000000000000..b86d71f209471
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/iptables/tests/shell/testcases/ipt-save/0007-overhead_0
|
||||||
|
@@ -0,0 +1,37 @@
|
||||||
|
+#!/bin/bash
|
||||||
|
+
|
||||||
|
+# Test recent performance improvements in iptables-save due to reduced
|
||||||
|
+# overhead.
|
||||||
|
+
|
||||||
|
+strace --version >/dev/null || { echo "skip for missing strace"; exit 0; }
|
||||||
|
+
|
||||||
|
+RULESET=$(
|
||||||
|
+ echo "*filter"
|
||||||
|
+ for ((i = 0; i < 100; i++)); do
|
||||||
|
+ echo ":mychain$i -"
|
||||||
|
+ echo "-A FORWARD -p tcp --dport 22 -j mychain$i"
|
||||||
|
+ done
|
||||||
|
+ echo "COMMIT"
|
||||||
|
+)
|
||||||
|
+
|
||||||
|
+RESTORE_STRACE=$(strace $XT_MULTI iptables-restore <<< "$RULESET" 2>&1 >/dev/null)
|
||||||
|
+SAVE_STRACE=$(strace $XT_MULTI iptables-save 2>&1 >/dev/null)
|
||||||
|
+
|
||||||
|
+do_grep() { # (name, threshold, pattern)
|
||||||
|
+ local cnt=$(grep -c "$3")
|
||||||
|
+ [[ $cnt -le $2 ]] && return 0
|
||||||
|
+ echo "ERROR: Too many $3 lookups for $1: $cnt > $2"
|
||||||
|
+ exit 1
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+# iptables prefers hard-coded protocol names instead of looking them up first
|
||||||
|
+
|
||||||
|
+do_grep "$XT_MULTI iptables-restore" 0 /etc/protocols <<< "$RESTORE_STRACE"
|
||||||
|
+do_grep "$XT_MULTI iptables-save" 0 /etc/protocols <<< "$SAVE_STRACE"
|
||||||
|
+
|
||||||
|
+# iptables-nft-save pointlessly checked whether chain jumps are targets
|
||||||
|
+
|
||||||
|
+do_grep "$XT_MULTI iptables-restore" 10 libxt_ <<< "$RESTORE_STRACE"
|
||||||
|
+do_grep "$XT_MULTI iptables-save" 10 libxt_ <<< "$SAVE_STRACE"
|
||||||
|
+
|
||||||
|
+exit 0
|
||||||
|
--
|
||||||
|
2.34.1
|
||||||
|
|
@ -0,0 +1,91 @@
|
|||||||
|
From f70e667bbc14c1dbf96b8732704aea294e4dcaa7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Phil Sutter <phil@nwl.cc>
|
||||||
|
Date: Thu, 30 Jun 2022 18:04:39 +0200
|
||||||
|
Subject: [PATCH] libxtables: Fix unsupported extension warning corner case
|
||||||
|
|
||||||
|
Some extensions are not supported in revision 0 by user space anymore,
|
||||||
|
for those the warning in xtables_compatible_revision() does not print as
|
||||||
|
no revision 0 is tried.
|
||||||
|
|
||||||
|
To fix this, one has to track if none of the user space supported
|
||||||
|
revisions were accepted by the kernel. Therefore add respective logic to
|
||||||
|
xtables_find_{target,match}().
|
||||||
|
|
||||||
|
Note that this does not lead to duplicated warnings for unsupported
|
||||||
|
extensions that have a revision 0 because xtables_compatible_revision()
|
||||||
|
returns true for them to allow for extension's help output.
|
||||||
|
|
||||||
|
For the record, these ip6tables extensions are affected: set/SET,
|
||||||
|
socket, tos/TOS, TPROXY and SNAT. In addition to that, TEE is affected
|
||||||
|
for both families.
|
||||||
|
|
||||||
|
Fixes: 17534cb18ed0a ("Improve error messages for unsupported extensions")
|
||||||
|
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
||||||
|
(cherry picked from commit 552c4a2f9e5706fef5f7abb27d1492a78bbb2a37)
|
||||||
|
---
|
||||||
|
libxtables/xtables.c | 14 ++++++++++++++
|
||||||
|
1 file changed, 14 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/libxtables/xtables.c b/libxtables/xtables.c
|
||||||
|
index a5c8d7e2c17ef..89547fb3ab947 100644
|
||||||
|
--- a/libxtables/xtables.c
|
||||||
|
+++ b/libxtables/xtables.c
|
||||||
|
@@ -702,6 +702,7 @@ xtables_find_match(const char *name, enum xtables_tryload tryload,
|
||||||
|
struct xtables_match *ptr;
|
||||||
|
const char *icmp6 = "icmp6";
|
||||||
|
bool found = false;
|
||||||
|
+ bool seen = false;
|
||||||
|
|
||||||
|
if (strlen(name) >= XT_EXTENSION_MAXNAMELEN)
|
||||||
|
xtables_error(PARAMETER_PROBLEM,
|
||||||
|
@@ -720,6 +721,7 @@ xtables_find_match(const char *name, enum xtables_tryload tryload,
|
||||||
|
if (extension_cmp(name, (*dptr)->name, (*dptr)->family)) {
|
||||||
|
ptr = *dptr;
|
||||||
|
*dptr = (*dptr)->next;
|
||||||
|
+ seen = true;
|
||||||
|
if (!found &&
|
||||||
|
xtables_fully_register_pending_match(ptr, prev)) {
|
||||||
|
found = true;
|
||||||
|
@@ -733,6 +735,11 @@ xtables_find_match(const char *name, enum xtables_tryload tryload,
|
||||||
|
dptr = &((*dptr)->next);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (seen && !found)
|
||||||
|
+ fprintf(stderr,
|
||||||
|
+ "Warning: Extension %s is not supported, missing kernel module?\n",
|
||||||
|
+ name);
|
||||||
|
+
|
||||||
|
for (ptr = xtables_matches; ptr; ptr = ptr->next) {
|
||||||
|
if (extension_cmp(name, ptr->name, ptr->family)) {
|
||||||
|
struct xtables_match *clone;
|
||||||
|
@@ -825,6 +832,7 @@ xtables_find_target(const char *name, enum xtables_tryload tryload)
|
||||||
|
struct xtables_target **dptr;
|
||||||
|
struct xtables_target *ptr;
|
||||||
|
bool found = false;
|
||||||
|
+ bool seen = false;
|
||||||
|
|
||||||
|
/* Standard target? */
|
||||||
|
if (strcmp(name, "") == 0
|
||||||
|
@@ -843,6 +851,7 @@ xtables_find_target(const char *name, enum xtables_tryload tryload)
|
||||||
|
if (extension_cmp(name, (*dptr)->name, (*dptr)->family)) {
|
||||||
|
ptr = *dptr;
|
||||||
|
*dptr = (*dptr)->next;
|
||||||
|
+ seen = true;
|
||||||
|
if (!found &&
|
||||||
|
xtables_fully_register_pending_target(ptr, prev)) {
|
||||||
|
found = true;
|
||||||
|
@@ -856,6 +865,11 @@ xtables_find_target(const char *name, enum xtables_tryload tryload)
|
||||||
|
dptr = &((*dptr)->next);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (seen && !found)
|
||||||
|
+ fprintf(stderr,
|
||||||
|
+ "Warning: Extension %s is not supported, missing kernel module?\n",
|
||||||
|
+ name);
|
||||||
|
+
|
||||||
|
for (ptr = xtables_targets; ptr; ptr = ptr->next) {
|
||||||
|
if (extension_cmp(name, ptr->name, ptr->family)) {
|
||||||
|
struct xtables_target *clone;
|
||||||
|
--
|
||||||
|
2.34.1
|
||||||
|
|
@ -17,7 +17,7 @@ Name: iptables
|
|||||||
Summary: Tools for managing Linux kernel packet filtering capabilities
|
Summary: Tools for managing Linux kernel packet filtering capabilities
|
||||||
URL: http://www.netfilter.org/projects/iptables
|
URL: http://www.netfilter.org/projects/iptables
|
||||||
Version: 1.8.4
|
Version: 1.8.4
|
||||||
Release: 22%{?dist}
|
Release: 23%{?dist}
|
||||||
Source: %{url}/files/%{name}-%{version}.tar.bz2
|
Source: %{url}/files/%{name}-%{version}.tar.bz2
|
||||||
Source1: iptables.init
|
Source1: iptables.init
|
||||||
Source2: iptables-config
|
Source2: iptables-config
|
||||||
@ -96,6 +96,20 @@ Patch59: 0059-doc-ebtables-nft.8-Adjust-for-missing-atomic-options.patch
|
|||||||
Patch60: 0060-ebtables-Dump-atomic-waste.patch
|
Patch60: 0060-ebtables-Dump-atomic-waste.patch
|
||||||
Patch61: 0061-extensions-hashlimit-Fix-tests-with-HZ-100.patch
|
Patch61: 0061-extensions-hashlimit-Fix-tests-with-HZ-100.patch
|
||||||
Patch62: 0062-extensions-hashlimit-Fix-tests-with-HZ-1000.patch
|
Patch62: 0062-extensions-hashlimit-Fix-tests-with-HZ-1000.patch
|
||||||
|
Patch63: 0063-nft-Simplify-immediate-parsing.patch
|
||||||
|
Patch64: 0064-nft-Speed-up-immediate-parsing.patch
|
||||||
|
Patch65: 0065-xshared-Prefer-xtables_chain_protos-lookup-over-getp.patch
|
||||||
|
Patch66: 0066-xshared-Merge-and-share-parse_chain.patch
|
||||||
|
Patch67: 0067-nft-Reject-standard-targets-as-chain-names-when-rest.patch
|
||||||
|
Patch68: 0068-libxtables-Implement-notargets-hash-table.patch
|
||||||
|
Patch69: 0069-libxtables-Boost-rule-target-checks-by-announcing-ch.patch
|
||||||
|
Patch70: 0070-Use-proto_to_name-from-xshared-in-more-places.patch
|
||||||
|
Patch71: 0071-libxtables-Register-only-the-highest-revision-extens.patch
|
||||||
|
Patch72: 0072-xshared-Fix-response-to-unprivileged-users.patch
|
||||||
|
Patch73: 0073-Improve-error-messages-for-unsupported-extensions.patch
|
||||||
|
Patch74: 0074-nft-Fix-EPERM-handling-for-extensions-without-rev-0.patch
|
||||||
|
Patch75: 0075-tests-shell-Check-overhead-in-iptables-save-and-rest.patch
|
||||||
|
Patch76: 0076-libxtables-Fix-unsupported-extension-warning-corner-.patch
|
||||||
|
|
||||||
# pf.os: ISC license
|
# pf.os: ISC license
|
||||||
# iptables-apply: Artistic Licence 2.0
|
# iptables-apply: Artistic Licence 2.0
|
||||||
@ -504,6 +518,22 @@ done
|
|||||||
%doc %{_mandir}/man8/ebtables*.8*
|
%doc %{_mandir}/man8/ebtables*.8*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Fri Jul 01 2022 Phil Sutter <psutter@redhat.com> - 1.8.4-23
|
||||||
|
- libxtables: Fix unsupported extension warning corner case
|
||||||
|
- tests: shell: Check overhead in iptables-save and -restore
|
||||||
|
- nft: Fix EPERM handling for extensions without rev 0
|
||||||
|
- Improve error messages for unsupported extensions
|
||||||
|
- xshared: Fix response to unprivileged users
|
||||||
|
- libxtables: Register only the highest revision extension
|
||||||
|
- Use proto_to_name() from xshared in more places
|
||||||
|
- libxtables: Boost rule target checks by announcing chain names
|
||||||
|
- libxtables: Implement notargets hash table
|
||||||
|
- nft: Reject standard targets as chain names when restoring
|
||||||
|
- xshared: Merge and share parse_chain()
|
||||||
|
- xshared: Prefer xtables_chain_protos lookup over getprotoent
|
||||||
|
- nft: Speed up immediate parsing
|
||||||
|
- nft: Simplify immediate parsing
|
||||||
|
|
||||||
* Mon Nov 29 2021 Phil Sutter <psutter@redhat.com> - 1.8.4-22
|
* Mon Nov 29 2021 Phil Sutter <psutter@redhat.com> - 1.8.4-22
|
||||||
- extensions: hashlimit: Fix tests with HZ=1000
|
- extensions: hashlimit: Fix tests with HZ=1000
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user