import iptables-1.8.4-17.el8

This commit is contained in:
CentOS Sources 2021-01-28 16:10:49 +00:00 committed by Andrew Lukoshko
parent 083742164f
commit 51b720ce21
10 changed files with 1041 additions and 1 deletions

View File

@ -0,0 +1,128 @@
From e6eede725bbd395fb8b385aec4d0a32ce99e842c Mon Sep 17 00:00:00 2001
From: Phil Sutter <phil@nwl.cc>
Date: Mon, 21 Sep 2020 13:42:06 +0200
Subject: [PATCH] libxtables: Make sure extensions register in revision order
Insert extensions into pending lists in ordered fashion: Group by
extension name (and, for matches, family) and order groups by descending
revision number.
This allows to simplify the later full registration considerably. Since
that involves kernel compatibility checks, the extra cycles here pay off
eventually.
Signed-off-by: Phil Sutter <phil@nwl.cc>
(cherry picked from commit b3ac87038f4e45141831d9ab485a2f627daba3f1)
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
libxtables/xtables.c | 71 +++++++++++++++++++++++++++++++++++++++-----
1 file changed, 64 insertions(+), 7 deletions(-)
diff --git a/libxtables/xtables.c b/libxtables/xtables.c
index 777c2b08e9896..13139d7f8ad62 100644
--- a/libxtables/xtables.c
+++ b/libxtables/xtables.c
@@ -902,8 +902,14 @@ static void xtables_check_options(const char *name, const struct option *opt)
}
}
+static int xtables_match_prefer(const struct xtables_match *a,
+ const struct xtables_match *b);
+
void xtables_register_match(struct xtables_match *me)
{
+ struct xtables_match **pos;
+ bool seen_myself = false;
+
if (me->next) {
fprintf(stderr, "%s: match \"%s\" already registered\n",
xt_params->program_name, me->name);
@@ -955,10 +961,34 @@ void xtables_register_match(struct xtables_match *me)
if (me->extra_opts != NULL)
xtables_check_options(me->name, me->extra_opts);
-
- /* place on linked list of matches pending full registration */
- me->next = xtables_pending_matches;
- xtables_pending_matches = me;
+ /* order into linked list of matches pending full registration */
+ for (pos = &xtables_pending_matches; *pos; pos = &(*pos)->next) {
+ /* group by name and family */
+ if (strcmp(me->name, (*pos)->name) ||
+ me->family != (*pos)->family) {
+ if (seen_myself)
+ break; /* end of own group, append to it */
+ continue;
+ }
+ /* found own group */
+ seen_myself = true;
+ if (xtables_match_prefer(me, *pos) >= 0)
+ break; /* put preferred items first in group */
+ }
+ /* if own group was not found, prepend item */
+ if (!*pos && !seen_myself)
+ pos = &xtables_pending_matches;
+
+ me->next = *pos;
+ *pos = me;
+#ifdef DEBUG
+ printf("%s: inserted match %s (family %d, revision %d):\n",
+ __func__, me->name, me->family, me->revision);
+ for (pos = &xtables_pending_matches; *pos; pos = &(*pos)->next) {
+ printf("%s:\tmatch %s (family %d, revision %d)\n", __func__,
+ (*pos)->name, (*pos)->family, (*pos)->revision);
+ }
+#endif
}
/**
@@ -1097,6 +1127,9 @@ void xtables_register_matches(struct xtables_match *match, unsigned int n)
void xtables_register_target(struct xtables_target *me)
{
+ struct xtables_target **pos;
+ bool seen_myself = false;
+
if (me->next) {
fprintf(stderr, "%s: target \"%s\" already registered\n",
xt_params->program_name, me->name);
@@ -1152,9 +1185,33 @@ void xtables_register_target(struct xtables_target *me)
if (me->family != afinfo->family && me->family != AF_UNSPEC)
return;
- /* place on linked list of targets pending full registration */
- me->next = xtables_pending_targets;
- xtables_pending_targets = me;
+ /* order into linked list of targets pending full registration */
+ for (pos = &xtables_pending_targets; *pos; pos = &(*pos)->next) {
+ /* group by name */
+ if (!extension_cmp(me->name, (*pos)->name, (*pos)->family)) {
+ if (seen_myself)
+ break; /* end of own group, append to it */
+ continue;
+ }
+ /* found own group */
+ seen_myself = true;
+ if (xtables_target_prefer(me, *pos) >= 0)
+ break; /* put preferred items first in group */
+ }
+ /* if own group was not found, prepend item */
+ if (!*pos && !seen_myself)
+ pos = &xtables_pending_targets;
+
+ me->next = *pos;
+ *pos = me;
+#ifdef DEBUG
+ printf("%s: inserted target %s (family %d, revision %d):\n",
+ __func__, me->name, me->family, me->revision);
+ for (pos = &xtables_pending_targets; *pos; pos = &(*pos)->next) {
+ printf("%s:\ttarget %s (family %d, revision %d)\n", __func__,
+ (*pos)->name, (*pos)->family, (*pos)->revision);
+ }
+#endif
}
static bool xtables_fully_register_pending_target(struct xtables_target *me)
--
2.28.0

View File

@ -0,0 +1,241 @@
From 1a842fb1cfb3b36f3081aee37c5fdd4a897d77d5 Mon Sep 17 00:00:00 2001
From: Phil Sutter <phil@nwl.cc>
Date: Fri, 18 Sep 2020 18:48:14 +0200
Subject: [PATCH] libxtables: Simplify pending extension registration
Assuming that pending extensions are sorted by first name and family,
then descending revision, the decision where to insert a newly
registered extension may be simplified by memorizing the previous
registration (which obviously is of same name and family and higher
revision).
As a side-effect, fix for unsupported old extension revisions lingering
in pending extension list forever and being retried with every use of
the given extension. Any revision being rejected by the kernel may
safely be dropped iff a previous (read: higher) revision was accepted
already.
Yet another side-effect of this change is the removal of an unwanted
recursion by xtables_fully_register_pending_*() into itself via
xtables_find_*().
Signed-off-by: Phil Sutter <phil@nwl.cc>
(cherry picked from commit a1eaaceb0460b338294e40bdd5bc5186320a478c)
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
libxtables/xtables.c | 128 +++++++++++--------------------------------
1 file changed, 33 insertions(+), 95 deletions(-)
diff --git a/libxtables/xtables.c b/libxtables/xtables.c
index 13139d7f8ad62..409128333e0e6 100644
--- a/libxtables/xtables.c
+++ b/libxtables/xtables.c
@@ -203,8 +203,10 @@ struct xtables_match *xtables_matches;
struct xtables_target *xtables_targets;
/* Fully register a match/target which was previously partially registered. */
-static bool xtables_fully_register_pending_match(struct xtables_match *me);
-static bool xtables_fully_register_pending_target(struct xtables_target *me);
+static bool xtables_fully_register_pending_match(struct xtables_match *me,
+ struct xtables_match *prev);
+static bool xtables_fully_register_pending_target(struct xtables_target *me,
+ struct xtables_target *prev);
void xtables_init(void)
{
@@ -616,6 +618,7 @@ struct xtables_match *
xtables_find_match(const char *name, enum xtables_tryload tryload,
struct xtables_rule_match **matches)
{
+ struct xtables_match *prev = NULL;
struct xtables_match **dptr;
struct xtables_match *ptr;
const char *icmp6 = "icmp6";
@@ -637,8 +640,12 @@ 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))
+ if (xtables_fully_register_pending_match(ptr, prev)) {
+ prev = ptr;
continue;
+ } else if (prev) {
+ continue;
+ }
*dptr = ptr;
}
dptr = &((*dptr)->next);
@@ -732,6 +739,7 @@ xtables_find_match_revision(const char *name, enum xtables_tryload tryload,
struct xtables_target *
xtables_find_target(const char *name, enum xtables_tryload tryload)
{
+ struct xtables_target *prev = NULL;
struct xtables_target **dptr;
struct xtables_target *ptr;
@@ -748,8 +756,12 @@ 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))
+ if (xtables_fully_register_pending_target(ptr, prev)) {
+ prev = ptr;
continue;
+ } else if (prev) {
+ continue;
+ }
*dptr = ptr;
}
dptr = &((*dptr)->next);
@@ -1052,64 +1064,27 @@ static int xtables_target_prefer(const struct xtables_target *a,
b->revision, b->family);
}
-static bool xtables_fully_register_pending_match(struct xtables_match *me)
+static bool xtables_fully_register_pending_match(struct xtables_match *me,
+ struct xtables_match *prev)
{
- struct xtables_match **i, *old, *pos = NULL;
+ struct xtables_match **i;
const char *rn;
- int compare;
/* See if new match can be used. */
rn = (me->real_name != NULL) ? me->real_name : me->name;
if (!compatible_match_revision(rn, me->revision))
return false;
- old = xtables_find_match(me->name, XTF_DURING_LOAD, NULL);
- while (old) {
- compare = xtables_match_prefer(old, me);
- if (compare == 0) {
- fprintf(stderr,
- "%s: match `%s' already registered.\n",
- xt_params->program_name, me->name);
- exit(1);
- }
-
- /* Now we have two (or more) options, check compatibility. */
- rn = (old->real_name != NULL) ? old->real_name : old->name;
- if (compare > 0) {
- /* Kernel tells old isn't compatible anymore??? */
- if (!compatible_match_revision(rn, old->revision)) {
- /* Delete old one. */
- for (i = &xtables_matches; *i != old;)
- i = &(*i)->next;
- *i = old->next;
- }
- pos = old;
- old = old->next;
- if (!old)
- break;
- if (!extension_cmp(me->name, old->name, old->family))
- break;
- continue;
- }
-
- /* Found right old */
- pos = old;
- break;
- }
-
- if (!pos) {
+ if (!prev) {
/* Append to list. */
for (i = &xtables_matches; *i; i = &(*i)->next);
- } else if (compare < 0) {
- /* Prepend it */
- for (i = &xtables_matches; *i != pos; i = &(*i)->next);
- } else if (compare > 0) {
+ } else {
/* Append it */
- i = &pos->next;
- pos = pos->next;
+ i = &prev->next;
+ prev = prev->next;
}
- me->next = pos;
+ me->next = prev;
*i = me;
me->m = NULL;
@@ -1214,11 +1189,11 @@ void xtables_register_target(struct xtables_target *me)
#endif
}
-static bool xtables_fully_register_pending_target(struct xtables_target *me)
+static bool xtables_fully_register_pending_target(struct xtables_target *me,
+ struct xtables_target *prev)
{
- struct xtables_target **i, *old, *pos = NULL;
+ struct xtables_target **i;
const char *rn;
- int compare;
if (strcmp(me->name, "standard") != 0) {
/* See if new target can be used. */
@@ -1227,54 +1202,17 @@ static bool xtables_fully_register_pending_target(struct xtables_target *me)
return false;
}
- old = xtables_find_target(me->name, XTF_DURING_LOAD);
- while (old) {
- compare = xtables_target_prefer(old, me);
- if (compare == 0) {
- fprintf(stderr,
- "%s: target `%s' already registered.\n",
- xt_params->program_name, me->name);
- exit(1);
- }
-
- /* Now we have two (or more) options, check compatibility. */
- rn = (old->real_name != NULL) ? old->real_name : old->name;
- if (compare > 0) {
- /* Kernel tells old isn't compatible anymore??? */
- if (!compatible_target_revision(rn, old->revision)) {
- /* Delete old one. */
- for (i = &xtables_targets; *i != old;)
- i = &(*i)->next;
- *i = old->next;
- }
- pos = old;
- old = old->next;
- if (!old)
- break;
- if (!extension_cmp(me->name, old->name, old->family))
- break;
- continue;
- }
-
- /* Found right old */
- pos = old;
- break;
- }
-
- if (!pos) {
+ if (!prev) {
/* Prepend to list. */
i = &xtables_targets;
- pos = xtables_targets;
- } else if (compare < 0) {
- /* Prepend it */
- for (i = &xtables_targets; *i != pos; i = &(*i)->next);
- } else if (compare > 0) {
+ prev = xtables_targets;
+ } else {
/* Append it */
- i = &pos->next;
- pos = pos->next;
+ i = &prev->next;
+ prev = prev->next;
}
- me->next = pos;
+ me->next = prev;
*i = me;
me->t = NULL;
--
2.28.0

View File

@ -0,0 +1,52 @@
From cfcafd3638cdc06a8b4a1d267e58b5ad1e35922c Mon Sep 17 00:00:00 2001
From: Phil Sutter <phil@nwl.cc>
Date: Tue, 22 Sep 2020 20:01:15 +0200
Subject: [PATCH] libxtables: Register multiple extensions in ascending order
The newly introduced ordered insert algorithm in
xtables_register_{match,target}() works best if extensions of same name
are passed in ascending revisions. Since this is the case in about all
extensions' arrays, iterate over them from beginning to end.
Signed-off-by: Phil Sutter <phil@nwl.cc>
(cherry picked from commit b5f1a3beac1d1f2b96c8be8ebec450f5ea758090)
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
libxtables/xtables.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/libxtables/xtables.c b/libxtables/xtables.c
index 409128333e0e6..28ffffedd8147 100644
--- a/libxtables/xtables.c
+++ b/libxtables/xtables.c
@@ -1095,9 +1095,10 @@ static bool xtables_fully_register_pending_match(struct xtables_match *me,
void xtables_register_matches(struct xtables_match *match, unsigned int n)
{
- do {
- xtables_register_match(&match[--n]);
- } while (n > 0);
+ int i;
+
+ for (i = 0; i < n; i++)
+ xtables_register_match(&match[i]);
}
void xtables_register_target(struct xtables_target *me)
@@ -1223,9 +1224,10 @@ static bool xtables_fully_register_pending_target(struct xtables_target *me,
void xtables_register_targets(struct xtables_target *target, unsigned int n)
{
- do {
- xtables_register_target(&target[--n]);
- } while (n > 0);
+ int i;
+
+ for (i = 0; i < n; i++)
+ xtables_register_target(&target[i]);
}
/* receives a list of xtables_rule_match, release them */
--
2.28.0

View File

@ -0,0 +1,53 @@
From f5185f4efad409fc7ec4ae05267b642ee4103a6c Mon Sep 17 00:00:00 2001
From: Phil Sutter <phil@nwl.cc>
Date: Fri, 4 Dec 2020 17:44:51 +0100
Subject: [PATCH] tests/shell: Test for fixed extension registration
Use strace to look at iptables-restore behaviour with typically
problematic input (conntrack revision 0 is no longer supported by
current kernels) to make sure the fix in commit a1eaaceb0460b
("libxtables: Simplify pending extension registration") is still
effective.
Signed-off-by: Phil Sutter <phil@nwl.cc>
(cherry picked from commit 93d0c97e8b6713f51ba679e01a1338d4f9076e7c)
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
.../0017-pointless-compat-checks_0 | 25 +++++++++++++++++++
1 file changed, 25 insertions(+)
create mode 100755 iptables/tests/shell/testcases/ipt-restore/0017-pointless-compat-checks_0
diff --git a/iptables/tests/shell/testcases/ipt-restore/0017-pointless-compat-checks_0 b/iptables/tests/shell/testcases/ipt-restore/0017-pointless-compat-checks_0
new file mode 100755
index 0000000000000..cf73de32df409
--- /dev/null
+++ b/iptables/tests/shell/testcases/ipt-restore/0017-pointless-compat-checks_0
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+# A bug in extension registration would leave unsupported older extension
+# revisions in pending list and get compatibility checked again for each rule
+# using them. With SELinux enabled, the resulting socket() call per rule leads
+# to significant slowdown (~50% performance in worst cases).
+
+set -e
+
+strace --version >/dev/null || { echo "skip for missing strace"; exit 0; }
+
+RULESET="$(
+ echo "*filter"
+ for ((i = 0; i < 100; i++)); do
+ echo "-A FORWARD -m conntrack --ctstate NEW"
+ done
+ echo "COMMIT"
+)"
+
+cmd="$XT_MULTI iptables-restore"
+socketcount=$(strace -esocket $cmd <<< "$RULESET" 2>&1 | wc -l)
+
+# unpatched iptables-restore would open 111 sockets,
+# patched only 12 but keep a certain margin for future changes
+[[ $socketcount -lt 20 ]]
--
2.28.0

View File

@ -0,0 +1,52 @@
From 6adcdca2aaf8cba6ee452c88f41ad8695bebdcfc Mon Sep 17 00:00:00 2001
From: Phil Sutter <phil@nwl.cc>
Date: Tue, 6 Oct 2020 19:07:19 +0200
Subject: [PATCH] extensions: libipt_icmp: Fix translation of type 'any'
By itself, '-m icmp --icmp-type any' is a noop, it matches any icmp
types. Yet nft_ipv4_xlate() does not emit an 'ip protocol' match if
there's an extension with same name present in the rule. Luckily, legacy
iptables demands icmp match to be prepended by '-p icmp', so we can
assume this is present and just emit the 'ip protocol' match from icmp
xlate callback.
Fixes: aa158ca0fda65 ("extensions: libipt_icmp: Add translation to nft")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Reviewed-by: Florian Westphal <fw@strlen.de>
(cherry picked from commit ad4b17b98bbedf93d2182a4dc9a37e9cf3adfe1b)
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
extensions/libipt_icmp.c | 5 +++++
extensions/libipt_icmp.txlate | 3 +++
2 files changed, 8 insertions(+)
diff --git a/extensions/libipt_icmp.c b/extensions/libipt_icmp.c
index e76257c54708c..e5e236613f39f 100644
--- a/extensions/libipt_icmp.c
+++ b/extensions/libipt_icmp.c
@@ -256,6 +256,11 @@ static int icmp_xlate(struct xt_xlate *xl,
if (!type_xlate_print(xl, info->type, info->code[0],
info->code[1]))
return 0;
+ } else {
+ /* '-m icmp --icmp-type any' is a noop by itself,
+ * but it eats a (mandatory) previous '-p icmp' so
+ * emit it here */
+ xt_xlate_add(xl, "ip protocol icmp");
}
return 1;
}
diff --git a/extensions/libipt_icmp.txlate b/extensions/libipt_icmp.txlate
index 434f8cc4eb1ae..a2aec8e26df75 100644
--- a/extensions/libipt_icmp.txlate
+++ b/extensions/libipt_icmp.txlate
@@ -6,3 +6,6 @@ nft add rule ip filter INPUT icmp type destination-unreachable counter accept
iptables-translate -t filter -A INPUT -m icmp ! --icmp-type 3 -j ACCEPT
nft add rule ip filter INPUT icmp type != destination-unreachable counter accept
+
+iptables-translate -t filter -A INPUT -m icmp --icmp-type any -j ACCEPT
+nft add rule ip filter INPUT ip protocol icmp counter accept
--
2.28.0

View File

@ -0,0 +1,66 @@
From 1695f552d3947299e54978bcd5bc1cdc3a5c14f7 Mon Sep 17 00:00:00 2001
From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Wed, 15 Apr 2020 18:16:41 +0200
Subject: [PATCH] extensions: libxt_CT: add translation for NOTRACK
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
(cherry picked from commit f3d4a3ddbcfca15a00dd9758f481420038f6de10)
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
extensions/libxt_CT.c | 16 ++++++++++++++++
extensions/libxt_NOTRACK.txlate | 2 ++
2 files changed, 18 insertions(+)
create mode 100644 extensions/libxt_NOTRACK.txlate
diff --git a/extensions/libxt_CT.c b/extensions/libxt_CT.c
index 371b21766c56c..fbbbe2660e9fc 100644
--- a/extensions/libxt_CT.c
+++ b/extensions/libxt_CT.c
@@ -348,6 +348,20 @@ static void notrack_ct2_tg_init(struct xt_entry_target *target)
info->flags = XT_CT_NOTRACK | XT_CT_NOTRACK_ALIAS;
}
+static int xlate_ct1_tg(struct xt_xlate *xl,
+ const struct xt_xlate_tg_params *params)
+{
+ struct xt_ct_target_info_v1 *info =
+ (struct xt_ct_target_info_v1 *)params->target->data;
+
+ if (info->flags & XT_CT_NOTRACK)
+ xt_xlate_add(xl, "notrack");
+ else
+ return 0;
+
+ return 1;
+}
+
static struct xtables_target ct_target_reg[] = {
{
.family = NFPROTO_UNSPEC,
@@ -387,6 +401,7 @@ static struct xtables_target ct_target_reg[] = {
.alias = ct_print_name_alias,
.x6_parse = ct_parse_v1,
.x6_options = ct_opts_v1,
+ .xlate = xlate_ct1_tg,
},
{
.family = NFPROTO_UNSPEC,
@@ -418,6 +433,7 @@ static struct xtables_target ct_target_reg[] = {
.size = XT_ALIGN(sizeof(struct xt_ct_target_info_v1)),
.userspacesize = offsetof(struct xt_ct_target_info_v1, ct),
.init = notrack_ct2_tg_init,
+ .xlate = xlate_ct1_tg,
},
{
.family = NFPROTO_UNSPEC,
diff --git a/extensions/libxt_NOTRACK.txlate b/extensions/libxt_NOTRACK.txlate
new file mode 100644
index 0000000000000..9d35619d3dbdd
--- /dev/null
+++ b/extensions/libxt_NOTRACK.txlate
@@ -0,0 +1,2 @@
+iptables-translate -A PREROUTING -t raw -j NOTRACK
+nft add rule ip raw PREROUTING counter notrack
--
2.28.0

View File

@ -0,0 +1,45 @@
From 6d8a390bd13bac294ff9de225a49fe9e4de2d6e5 Mon Sep 17 00:00:00 2001
From: Phil Sutter <phil@nwl.cc>
Date: Fri, 7 Aug 2020 13:48:28 +0200
Subject: [PATCH] nft: Fix command name in ip6tables error message
Upon errors, ip6tables-nft would prefix its error messages with
'iptables:' instead of 'ip6tables:'. Turns out the command name was
hard-coded, use 'progname' variable instead.
While being at it, merge the two mostly identical fprintf() calls into
one.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
(cherry picked from commit 3be40dcfb5af1438b6abdbda45a1e3b59c104e13)
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
iptables/xtables-standalone.c | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/iptables/xtables-standalone.c b/iptables/xtables-standalone.c
index 022d5dd44abbf..b5b7ccaf4e660 100644
--- a/iptables/xtables-standalone.c
+++ b/iptables/xtables-standalone.c
@@ -74,14 +74,10 @@ xtables_main(int family, const char *progname, int argc, char *argv[])
nft_fini(&h);
if (!ret) {
- if (errno == EINVAL) {
- fprintf(stderr, "iptables: %s. "
- "Run `dmesg' for more information.\n",
- nft_strerror(errno));
- } else {
- fprintf(stderr, "iptables: %s.\n",
- nft_strerror(errno));
- }
+ fprintf(stderr, "%s: %s.%s\n", progname, nft_strerror(errno),
+ (errno == EINVAL ?
+ " Run `dmesg' for more information." : ""));
+
if (errno == EAGAIN)
exit(RESOURCE_PROBLEM);
}
--
2.28.0

View File

@ -0,0 +1,206 @@
From c5f07a7d718f812f916686926567adbac6c1b125 Mon Sep 17 00:00:00 2001
From: Phil Sutter <phil@nwl.cc>
Date: Thu, 6 Aug 2020 18:52:34 +0200
Subject: [PATCH] tests: shell: Merge and extend return codes test
Merge scripts for iptables and ip6tables, they were widely identical.
Also extend the test by one check (removing a non-existent rule with
valid chain and target) and quote the error messages where differences
are deliberately ignored.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
(cherry picked from commit cd3e83d1b04fd2683f0fb06e496ee5be08a96b4f)
Conflicts:
iptables/tests/shell/testcases/ip6tables/0004-return-codes_0
iptables/tests/shell/testcases/iptables/0004-return-codes_0
-> Missing upstream commit a7f1e208cdf9c ("nft: split parsing from
netlink commands") which added a few tests to both files.
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
.../testcases/ip6tables/0004-return-codes_0 | 38 -------
.../testcases/iptables/0004-return-codes_0 | 104 ++++++++++--------
2 files changed, 58 insertions(+), 84 deletions(-)
delete mode 100755 iptables/tests/shell/testcases/ip6tables/0004-return-codes_0
diff --git a/iptables/tests/shell/testcases/ip6tables/0004-return-codes_0 b/iptables/tests/shell/testcases/ip6tables/0004-return-codes_0
deleted file mode 100755
index f023b7915498e..0000000000000
--- a/iptables/tests/shell/testcases/ip6tables/0004-return-codes_0
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/sh
-
-# make sure error return codes are as expected useful cases
-# (e.g. commands to check ruleset state)
-
-global_rc=0
-
-cmd() { # (rc, cmd, [args ...])
- rc_exp=$1; shift
-
- $XT_MULTI "$@"
- rc=$?
-
- [ $rc -eq $rc_exp ] || {
- echo "---> expected $rc_exp, got $rc for command '$@'"
- global_rc=1
- }
-}
-
-# test chain creation
-cmd 0 ip6tables -N foo
-cmd 1 ip6tables -N foo
-# iptables-nft allows this - bug or feature?
-#cmd 2 ip6tables -N "invalid name"
-
-# test rule adding
-cmd 0 ip6tables -A INPUT -j ACCEPT
-cmd 1 ip6tables -A noexist -j ACCEPT
-
-# test rule checking
-cmd 0 ip6tables -C INPUT -j ACCEPT
-cmd 1 ip6tables -C FORWARD -j ACCEPT
-cmd 1 ip6tables -C nonexist -j ACCEPT
-cmd 2 ip6tables -C INPUT -j foobar
-cmd 2 ip6tables -C INPUT -m foobar -j ACCEPT
-cmd 3 ip6tables -t foobar -C INPUT -j ACCEPT
-
-exit $global_rc
diff --git a/iptables/tests/shell/testcases/iptables/0004-return-codes_0 b/iptables/tests/shell/testcases/iptables/0004-return-codes_0
index ce02e0bcb128b..67f1698945753 100755
--- a/iptables/tests/shell/testcases/iptables/0004-return-codes_0
+++ b/iptables/tests/shell/testcases/iptables/0004-return-codes_0
@@ -13,69 +13,81 @@ cmd() { # (rc, msg, cmd, [args ...])
msg_exp="$1"; shift
}
- msg="$($XT_MULTI "$@" 2>&1 >/dev/null)"
- rc=$?
+ for ipt in iptables ip6tables; do
+ msg="$($XT_MULTI $ipt "$@" 2>&1 >/dev/null)"
+ rc=$?
- [ $rc -eq $rc_exp ] || {
- echo "---> expected return code $rc_exp, got $rc for command '$@'"
- global_rc=1
- }
+ [ $rc -eq $rc_exp ] || {
+ echo "---> expected return code $rc_exp, got $rc for command '$ipt $@'"
+ global_rc=1
+ }
- [ -n "$msg_exp" ] || return
- grep -q "$msg_exp" <<< $msg || {
- echo "---> expected error message '$msg_exp', got '$msg' for command '$@'"
- global_rc=1
- }
+ [ -n "$msg_exp" ] || continue
+ msg_exp_full="${ipt}$msg_exp"
+ grep -q "$msg_exp_full" <<< $msg || {
+ echo "---> expected error message '$msg_exp_full', got '$msg' for command '$ipt $@'"
+ global_rc=1
+ }
+ done
}
-EEXIST_F="File exists."
-EEXIST="Chain already exists."
-ENOENT="No chain/target/match by that name."
-E2BIG_I="Index of insertion too big."
-E2BIG_D="Index of deletion too big."
-E2BIG_R="Index of replacement too big."
-EBADRULE="Bad rule (does a matching rule exist in that chain?)."
-ENOTGT="Couldn't load target \`foobar':No such file or directory"
-ENOMTH="Couldn't load match \`foobar':No such file or directory"
-ENOTBL="can't initialize iptables table \`foobar': Table does not exist"
+EEXIST_F=": File exists."
+EEXIST=": Chain already exists."
+ENOENT=": No chain/target/match by that name."
+E2BIG_I=": Index of insertion too big."
+E2BIG_D=": Index of deletion too big."
+E2BIG_R=": Index of replacement too big."
+EBADRULE=": Bad rule (does a matching rule exist in that chain?)."
+#ENOTGT=" v[0-9\.]* [^ ]*: Couldn't load target \`foobar':No such file or directory"
+ENOMTH=" v[0-9\.]* [^ ]*: Couldn't load match \`foobar':No such file or directory"
+ENOTBL=": can't initialize iptables table \`foobar': Table does not exist"
# test chain creation
-cmd 0 iptables -N foo
-cmd 1 "$EEXIST" iptables -N foo
+cmd 0 -N foo
+cmd 1 "$EEXIST" -N foo
# iptables-nft allows this - bug or feature?
-#cmd 2 iptables -N "invalid name"
+#cmd 2 -N "invalid name"
# test chain flushing/zeroing
-cmd 0 iptables -F foo
-cmd 0 iptables -Z foo
-cmd 1 "$ENOENT" iptables -F bar
-cmd 1 "$ENOENT" iptables -Z bar
+cmd 0 -F foo
+cmd 0 -Z foo
+cmd 1 "$ENOENT" -F bar
+cmd 1 "$ENOENT" -Z bar
# test chain rename
-cmd 0 iptables -E foo bar
-cmd 1 "$EEXIST_F" iptables -E foo bar
+cmd 0 -E foo bar
+cmd 1 "$EEXIST_F" -E foo bar
# test rule adding
-cmd 0 iptables -A INPUT -j ACCEPT
-cmd 1 "$ENOENT" iptables -A noexist -j ACCEPT
+cmd 0 -A INPUT -j ACCEPT
+cmd 1 "$ENOENT" -A noexist -j ACCEPT
+# next three differ:
+# legacy: Couldn't load target `foobar':No such file or directory
+# nft: Chain 'foobar' does not exist
+cmd 2 "" -I INPUT -j foobar
+cmd 2 "" -R INPUT 1 -j foobar
+cmd 2 "" -D INPUT -j foobar
+cmd 1 "$EBADRULE" -D INPUT -p tcp --dport 22 -j ACCEPT
# test rulenum commands
-cmd 1 "$E2BIG_I" iptables -I INPUT 23 -j ACCEPT
-cmd 1 "$E2BIG_D" iptables -D INPUT 23
-cmd 1 "$E2BIG_R" iptables -R INPUT 23 -j ACCEPT
-cmd 1 "$ENOENT" iptables -I nonexist 23 -j ACCEPT
-cmd 1 "$ENOENT" iptables -D nonexist 23
-cmd 1 "$ENOENT" iptables -R nonexist 23 -j ACCEPT
+cmd 1 "$E2BIG_I" -I INPUT 23 -j ACCEPT
+cmd 1 "$E2BIG_D" -D INPUT 23
+cmd 1 "$E2BIG_R" -R INPUT 23 -j ACCEPT
+cmd 1 "$ENOENT" -I nonexist 23 -j ACCEPT
+cmd 1 "$ENOENT" -D nonexist 23
+cmd 1 "$ENOENT" -R nonexist 23 -j ACCEPT
# test rule checking
-cmd 0 iptables -C INPUT -j ACCEPT
-cmd 1 "$EBADRULE" iptables -C FORWARD -j ACCEPT
-cmd 1 "$BADRULE" iptables -C nonexist -j ACCEPT
-cmd 2 "$ENOMTH" iptables -C INPUT -m foobar -j ACCEPT
+cmd 0 -C INPUT -j ACCEPT
+cmd 1 "$EBADRULE" -C FORWARD -j ACCEPT
+cmd 1 "$BADRULE" -C nonexist -j ACCEPT
+cmd 2 "$ENOMTH" -C INPUT -m foobar -j ACCEPT
# messages of those don't match, but iptables-nft ones are actually nicer.
-#cmd 2 "$ENOTGT" iptables -C INPUT -j foobar
-#cmd 3 "$ENOTBL" iptables -t foobar -C INPUT -j ACCEPT
-cmd 2 "" iptables -C INPUT -j foobar
-cmd 3 "" iptables -t foobar -C INPUT -j ACCEPT
+# legacy: Couldn't load target `foobar':No such file or directory
+# nft: Chain 'foobar' does not exist
+cmd 2 "" -C INPUT -j foobar
+# legacy: can't initialize ip6tables table `foobar': Table does not exist (do you need to insmod?)
+# nft: table 'foobar' does not exist
+cmd 3 "" -t foobar -C INPUT -j ACCEPT
exit $global_rc
--
2.28.0

View File

@ -0,0 +1,177 @@
From 98794894774a39927bc975921fc9e40f00db937b Mon Sep 17 00:00:00 2001
From: Phil Sutter <phil@nwl.cc>
Date: Wed, 2 Dec 2020 13:37:06 +0100
Subject: [PATCH] extensions: dccp: Fix for DCCP type 'INVALID'
Support for matching on invalid DCCP type field values was pretty
broken: While RFC4340 declares any type value from 10 to 15 invalid, the
extension's type name 'INVALID' mapped to type value 10 only. Fix this
by introduction of INVALID_OTHER_TYPE_MASK which has the remaining
invalid type's bits set and apply it if bit 10 is set after parsing the
type list. When printing, stop searching type names after printing
'INVALID' - unless numeric output was requested. The latter prints all
actual type values. Since parsing types in numeric form is not
supported, changing the output should not break existing scripts.
When translating into nftables syntax, the code returned prematurely if
'INVALID' was among the list of types - thereby emitting invalid syntax.
Instead print a real match for invalid types by use of a range
expression.
While being at it, fix syntax of translator output: If only
'--dccp-types' was translated, the output contained an extra 'dccp'. On
the other hand, if '--sport' and '--dport' was present, a required
'dccp' between the translations of both was missing.
Fixes: e40b11d7ef827 ("add support for new 'dccp' protocol match")
Fixes: c94a998724143 ("extensions: libxt_dccp: Add translation to nft")
Signed-off-by: Phil Sutter <phil@nwl.cc>
(cherry picked from commit 4bcbc8e11a2764f4537dc405962f83cd072cccfe)
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
extensions/libxt_dccp.c | 58 ++++++++++++++++++++++--------------
extensions/libxt_dccp.txlate | 12 ++++++--
2 files changed, 45 insertions(+), 25 deletions(-)
diff --git a/extensions/libxt_dccp.c b/extensions/libxt_dccp.c
index 5e67c264db2a9..aea3e20be4818 100644
--- a/extensions/libxt_dccp.c
+++ b/extensions/libxt_dccp.c
@@ -76,6 +76,9 @@ static const char *const dccp_pkt_types[] = {
[DCCP_PKT_INVALID] = "INVALID",
};
+/* Bits for type values 11-15 */
+#define INVALID_OTHER_TYPE_MASK 0xf800
+
static uint16_t
parse_dccp_types(const char *typestring)
{
@@ -95,6 +98,9 @@ parse_dccp_types(const char *typestring)
xtables_error(PARAMETER_PROBLEM,
"Unknown DCCP type `%s'", ptr);
}
+ if (typemask & (1 << DCCP_PKT_INVALID))
+ typemask |= INVALID_OTHER_TYPE_MASK;
+
free(buffer);
return typemask;
@@ -193,9 +199,13 @@ print_types(uint16_t types, int inverted, int numeric)
if (numeric)
printf("%u", i);
- else
+ else {
printf("%s", dccp_pkt_types[i]);
+ if (i == DCCP_PKT_INVALID)
+ break;
+ }
+
types &= ~(1 << i);
}
}
@@ -288,6 +298,7 @@ static const char *const dccp_pkt_types_xlate[] = {
[DCCP_PKT_RESET] = "reset",
[DCCP_PKT_SYNC] = "sync",
[DCCP_PKT_SYNCACK] = "syncack",
+ [DCCP_PKT_INVALID] = "10-15",
};
static int dccp_type_xlate(const struct xt_dccp_info *einfo,
@@ -296,10 +307,10 @@ static int dccp_type_xlate(const struct xt_dccp_info *einfo,
bool have_type = false, set_need = false;
uint16_t types = einfo->typemask;
- if (types & (1 << DCCP_PKT_INVALID))
- return 0;
-
- xt_xlate_add(xl, " dccp type%s ", einfo->invflags ? " !=" : "");
+ if (types & INVALID_OTHER_TYPE_MASK) {
+ types &= ~INVALID_OTHER_TYPE_MASK;
+ types |= 1 << DCCP_PKT_INVALID;
+ }
if ((types != 0) && !(types == (types & -types))) {
xt_xlate_add(xl, "{");
@@ -335,34 +346,37 @@ static int dccp_xlate(struct xt_xlate *xl,
char *space = "";
int ret = 1;
- xt_xlate_add(xl, "dccp ");
-
if (einfo->flags & XT_DCCP_SRC_PORTS) {
+ xt_xlate_add(xl, "dccp sport%s %u",
+ einfo->invflags & XT_DCCP_SRC_PORTS ? " !=" : "",
+ einfo->spts[0]);
+
if (einfo->spts[0] != einfo->spts[1])
- xt_xlate_add(xl, "sport%s %u-%u",
- einfo->invflags & XT_DCCP_SRC_PORTS ? " !=" : "",
- einfo->spts[0], einfo->spts[1]);
- else
- xt_xlate_add(xl, "sport%s %u",
- einfo->invflags & XT_DCCP_SRC_PORTS ? " !=" : "",
- einfo->spts[0]);
+ xt_xlate_add(xl, "-%u", einfo->spts[1]);
+
space = " ";
}
if (einfo->flags & XT_DCCP_DEST_PORTS) {
+ xt_xlate_add(xl, "%sdccp dport%s %u", space,
+ einfo->invflags & XT_DCCP_DEST_PORTS ? " !=" : "",
+ einfo->dpts[0]);
+
if (einfo->dpts[0] != einfo->dpts[1])
- xt_xlate_add(xl, "%sdport%s %u-%u", space,
- einfo->invflags & XT_DCCP_DEST_PORTS ? " !=" : "",
- einfo->dpts[0], einfo->dpts[1]);
- else
- xt_xlate_add(xl, "%sdport%s %u", space,
- einfo->invflags & XT_DCCP_DEST_PORTS ? " !=" : "",
- einfo->dpts[0]);
+ xt_xlate_add(xl, "-%u", einfo->dpts[1]);
+
+ space = " ";
}
- if (einfo->flags & XT_DCCP_TYPE)
+ if (einfo->flags & XT_DCCP_TYPE && einfo->typemask) {
+ xt_xlate_add(xl, "%sdccp type%s ", space,
+ einfo->invflags & XT_DCCP_TYPE ? " !=" : "");
ret = dccp_type_xlate(einfo, xl);
+ space = " ";
+ }
+
+ /* FIXME: no dccp option support in nftables yet */
if (einfo->flags & XT_DCCP_OPTION)
ret = 0;
diff --git a/extensions/libxt_dccp.txlate b/extensions/libxt_dccp.txlate
index b47dc65f5bc4f..ea853f6acf627 100644
--- a/extensions/libxt_dccp.txlate
+++ b/extensions/libxt_dccp.txlate
@@ -7,8 +7,14 @@ nft add rule ip filter INPUT dccp dport 100-200 counter
iptables-translate -A INPUT -p dccp -m dccp ! --dport 100
nft add rule ip filter INPUT dccp dport != 100 counter
-iptables-translate -A INPUT -p dccp -m dccp --dport 100 --dccp-types REQUEST,RESPONSE,DATA,ACK,DATAACK,CLOSEREQ,CLOSE,SYNC,SYNCACK
-nft add rule ip filter INPUT dccp dport 100 dccp type {request, response, data, ack, dataack, closereq, close, sync, syncack} counter
+iptables-translate -A INPUT -p dccp -m dccp --dccp-types CLOSE
+nft add rule ip filter INPUT dccp type close counter
+
+iptables-translate -A INPUT -p dccp -m dccp --dccp-types INVALID
+nft add rule ip filter INPUT dccp type 10-15 counter
+
+iptables-translate -A INPUT -p dccp -m dccp --dport 100 --dccp-types REQUEST,RESPONSE,DATA,ACK,DATAACK,CLOSEREQ,CLOSE,SYNC,SYNCACK,INVALID
+nft add rule ip filter INPUT dccp dport 100 dccp type {request, response, data, ack, dataack, closereq, close, sync, syncack, 10-15} counter
iptables-translate -A INPUT -p dccp -m dccp --sport 200 --dport 100
-nft add rule ip filter INPUT dccp sport 200 dport 100 counter
+nft add rule ip filter INPUT dccp sport 200 dccp dport 100 counter
--
2.28.0

View File

@ -17,7 +17,7 @@ Name: iptables
Summary: Tools for managing Linux kernel packet filtering capabilities
URL: http://www.netfilter.org/projects/iptables
Version: 1.8.4
Release: 16%{?dist}
Release: 17%{?dist}
Source: %{url}/files/%{name}-%{version}.tar.bz2
Source1: iptables.init
Source2: iptables-config
@ -68,6 +68,15 @@ Patch31: 0031-nft-Fix-for-broken-address-mask-match-detection.patch
Patch32: 0032-nft-Optimize-class-based-IP-prefix-matches.patch
Patch33: 0033-ebtables-Optimize-masked-MAC-address-matches.patch
Patch34: 0034-tests-shell-Add-test-for-bitwise-avoidance-fixes.patch
Patch35: 0035-libxtables-Make-sure-extensions-register-in-revision.patch
Patch36: 0036-libxtables-Simplify-pending-extension-registration.patch
Patch37: 0037-libxtables-Register-multiple-extensions-in-ascending.patch
Patch38: 0038-tests-shell-Test-for-fixed-extension-registration.patch
Patch39: 0039-extensions-libipt_icmp-Fix-translation-of-type-any.patch
Patch40: 0040-extensions-libxt_CT-add-translation-for-NOTRACK.patch
Patch41: 0041-nft-Fix-command-name-in-ip6tables-error-message.patch
Patch42: 0042-tests-shell-Merge-and-extend-return-codes-test.patch
Patch43: 0043-extensions-dccp-Fix-for-DCCP-type-INVALID.patch
# pf.os: ISC license
# iptables-apply: Artistic Licence 2.0
@ -476,6 +485,17 @@ done
%doc %{_mandir}/man8/ebtables*.8*
%changelog
* Thu Dec 10 2020 Phil Sutter <psutter@redhat.com> - 1.8.4-17
- extensions: dccp: Fix for DCCP type 'INVALID'
- tests: shell: Merge and extend return codes test
- nft: Fix command name in ip6tables error message
- extensions: libxt_CT: add translation for NOTRACK
- extensions: libipt_icmp: Fix translation of type 'any'
- tests/shell: Test for fixed extension registration
- libxtables: Register multiple extensions in ascending order
- libxtables: Simplify pending extension registration
- libxtables: Make sure extensions register in revision order
* Wed Oct 28 2020 Phil Sutter <psutter@redhat.com> - 1.8.4-16
- tests/shell: Add test for bitwise avoidance fixes
- ebtables: Optimize masked MAC address matches