import nftables-0.9.3-25.el8

This commit is contained in:
CentOS Sources 2022-02-27 05:25:59 +00:00 committed by Stepan Oksanichenko
parent 222a01544b
commit e02fa8686b
7 changed files with 778 additions and 3 deletions

View File

@ -0,0 +1,134 @@
From cf85778a263a34aa2aeee565f3e046693164a097 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 13 Jan 2022 20:37:56 +0100
Subject: [PATCH] netlink: remove unused parameter from
netlink_gen_stmt_stateful()
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2039594
Upstream Status: nftables commit 3f3e897f42965
commit 3f3e897f429659ff6c8387245d0d4115952a6c31
Author: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Wed Mar 11 13:02:26 2020 +0100
netlink: remove unused parameter from netlink_gen_stmt_stateful()
Remove context from netlink_gen_stmt_stateful().
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
src/netlink_linearize.c | 36 +++++++++++++-----------------------
1 file changed, 13 insertions(+), 23 deletions(-)
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index 28b0e6a..f5c6116 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -780,9 +780,7 @@ static void netlink_gen_objref_stmt(struct netlink_linearize_ctx *ctx,
nftnl_rule_add_expr(ctx->nlr, nle);
}
-static struct nftnl_expr *
-netlink_gen_connlimit_stmt(struct netlink_linearize_ctx *ctx,
- const struct stmt *stmt)
+static struct nftnl_expr *netlink_gen_connlimit_stmt(const struct stmt *stmt)
{
struct nftnl_expr *nle;
@@ -795,9 +793,7 @@ netlink_gen_connlimit_stmt(struct netlink_linearize_ctx *ctx,
return nle;
}
-static struct nftnl_expr *
-netlink_gen_counter_stmt(struct netlink_linearize_ctx *ctx,
- const struct stmt *stmt)
+static struct nftnl_expr *netlink_gen_counter_stmt(const struct stmt *stmt)
{
struct nftnl_expr *nle;
@@ -814,9 +810,7 @@ netlink_gen_counter_stmt(struct netlink_linearize_ctx *ctx,
return nle;
}
-static struct nftnl_expr *
-netlink_gen_limit_stmt(struct netlink_linearize_ctx *ctx,
- const struct stmt *stmt)
+static struct nftnl_expr *netlink_gen_limit_stmt(const struct stmt *stmt)
{
struct nftnl_expr *nle;
@@ -832,9 +826,7 @@ netlink_gen_limit_stmt(struct netlink_linearize_ctx *ctx,
return nle;
}
-static struct nftnl_expr *
-netlink_gen_quota_stmt(struct netlink_linearize_ctx *ctx,
- const struct stmt *stmt)
+static struct nftnl_expr *netlink_gen_quota_stmt(const struct stmt *stmt)
{
struct nftnl_expr *nle;
@@ -846,19 +838,17 @@ netlink_gen_quota_stmt(struct netlink_linearize_ctx *ctx,
return nle;
}
-static struct nftnl_expr *
-netlink_gen_stmt_stateful(struct netlink_linearize_ctx *ctx,
- const struct stmt *stmt)
+static struct nftnl_expr *netlink_gen_stmt_stateful(const struct stmt *stmt)
{
switch (stmt->ops->type) {
case STMT_CONNLIMIT:
- return netlink_gen_connlimit_stmt(ctx, stmt);
+ return netlink_gen_connlimit_stmt(stmt);
case STMT_COUNTER:
- return netlink_gen_counter_stmt(ctx, stmt);
+ return netlink_gen_counter_stmt(stmt);
case STMT_LIMIT:
- return netlink_gen_limit_stmt(ctx, stmt);
+ return netlink_gen_limit_stmt(stmt);
case STMT_QUOTA:
- return netlink_gen_quota_stmt(ctx, stmt);
+ return netlink_gen_quota_stmt(stmt);
default:
BUG("unknown stateful statement type %s\n", stmt->ops->name);
}
@@ -1307,7 +1297,7 @@ static void netlink_gen_set_stmt(struct netlink_linearize_ctx *ctx,
if (stmt->set.stmt)
nftnl_expr_set(nle, NFTNL_EXPR_DYNSET_EXPR,
- netlink_gen_stmt_stateful(ctx, stmt->set.stmt), 0);
+ netlink_gen_stmt_stateful(stmt->set.stmt), 0);
}
static void netlink_gen_map_stmt(struct netlink_linearize_ctx *ctx,
@@ -1337,7 +1327,7 @@ static void netlink_gen_map_stmt(struct netlink_linearize_ctx *ctx,
if (stmt->map.stmt)
nftnl_expr_set(nle, NFTNL_EXPR_DYNSET_EXPR,
- netlink_gen_stmt_stateful(ctx, stmt->map.stmt), 0);
+ netlink_gen_stmt_stateful(stmt->map.stmt), 0);
nftnl_rule_add_expr(ctx->nlr, nle);
}
@@ -1369,7 +1359,7 @@ static void netlink_gen_meter_stmt(struct netlink_linearize_ctx *ctx,
nftnl_expr_set_str(nle, NFTNL_EXPR_DYNSET_SET_NAME, set->handle.set.name);
nftnl_expr_set_u32(nle, NFTNL_EXPR_DYNSET_SET_ID, set->handle.set_id);
nftnl_expr_set(nle, NFTNL_EXPR_DYNSET_EXPR,
- netlink_gen_stmt_stateful(ctx, stmt->meter.stmt), 0);
+ netlink_gen_stmt_stateful(stmt->meter.stmt), 0);
nftnl_rule_add_expr(ctx->nlr, nle);
}
@@ -1415,7 +1405,7 @@ static void netlink_gen_stmt(struct netlink_linearize_ctx *ctx,
case STMT_COUNTER:
case STMT_LIMIT:
case STMT_QUOTA:
- nle = netlink_gen_stmt_stateful(ctx, stmt);
+ nle = netlink_gen_stmt_stateful(stmt);
nftnl_rule_add_expr(ctx->nlr, nle);
break;
case STMT_NOTRACK:
--
2.31.1

View File

@ -0,0 +1,150 @@
From 0db42cc2d2647ec61441e29445c9f6e0f8946613 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 13 Jan 2022 20:37:56 +0100
Subject: [PATCH] src: support for restoring element counters
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2039594
Upstream Status: nftables commit 1fe6089ddd87e
commit 1fe6089ddd87ee7869d24c0f8849951220cc9b85
Author: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Wed Mar 11 13:00:01 2020 +0100
src: support for restoring element counters
This patch allows you to restore counters in dynamic sets:
table ip test {
set test {
type ipv4_addr
size 65535
flags dynamic,timeout
timeout 30d
gc-interval 1d
elements = { 192.168.10.13 expires 19d23h52m27s576ms counter packets 51 bytes 17265 }
}
chain output {
type filter hook output priority 0;
update @test { ip saddr }
}
}
You can also add counters to elements from the control place, ie.
table ip test {
set test {
type ipv4_addr
size 65535
elements = { 192.168.2.1 counter packets 75 bytes 19043 }
}
chain output {
type filter hook output priority filter; policy accept;
ip daddr @test
}
}
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/netlink.h | 1 +
src/netlink.c | 3 +++
src/netlink_linearize.c | 2 +-
src/parser_bison.y | 36 +++++++++++++++++++++++++++++++++++-
4 files changed, 40 insertions(+), 2 deletions(-)
diff --git a/include/netlink.h b/include/netlink.h
index 88d12ba..059092e 100644
--- a/include/netlink.h
+++ b/include/netlink.h
@@ -97,6 +97,7 @@ extern void netlink_gen_data(const struct expr *expr,
extern void netlink_gen_raw_data(const mpz_t value, enum byteorder byteorder,
unsigned int len,
struct nft_data_linearize *data);
+extern struct nftnl_expr *netlink_gen_stmt_stateful(const struct stmt *stmt);
extern struct expr *netlink_alloc_value(const struct location *loc,
const struct nft_data_delinearize *nld);
diff --git a/src/netlink.c b/src/netlink.c
index 64e51e5..825c2cc 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -136,6 +136,9 @@ static struct nftnl_set_elem *alloc_nftnl_setelem(const struct expr *set,
if (elem->expiration)
nftnl_set_elem_set_u64(nlse, NFTNL_SET_ELEM_EXPIRATION,
elem->expiration);
+ if (elem->stmt)
+ nftnl_set_elem_set(nlse, NFTNL_SET_ELEM_EXPR,
+ netlink_gen_stmt_stateful(elem->stmt), 0);
if (elem->comment || expr->elem_flags) {
udbuf = nftnl_udata_buf_alloc(NFT_USERDATA_MAXLEN);
if (!udbuf)
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index f5c6116..3fa1339 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -838,7 +838,7 @@ static struct nftnl_expr *netlink_gen_quota_stmt(const struct stmt *stmt)
return nle;
}
-static struct nftnl_expr *netlink_gen_stmt_stateful(const struct stmt *stmt)
+struct nftnl_expr *netlink_gen_stmt_stateful(const struct stmt *stmt)
{
switch (stmt->ops->type) {
case STMT_CONNLIMIT:
diff --git a/src/parser_bison.y b/src/parser_bison.y
index d38ec30..2cdf8ec 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -3654,7 +3654,7 @@ meter_key_expr_alloc : concat_expr
;
set_elem_expr : set_elem_expr_alloc
- | set_elem_expr_alloc set_elem_options
+ | set_elem_expr_alloc set_elem_expr_options
;
set_elem_expr_alloc : set_lhs_expr
@@ -3684,6 +3684,40 @@ set_elem_option : TIMEOUT time_spec
}
;
+set_elem_expr_options : set_elem_expr_option
+ {
+ $<expr>$ = $<expr>0;
+ }
+ | set_elem_expr_options set_elem_expr_option
+ ;
+
+set_elem_expr_option : TIMEOUT time_spec
+ {
+ $<expr>0->timeout = $2;
+ }
+ | EXPIRES time_spec
+ {
+ $<expr>0->expiration = $2;
+ }
+ | COUNTER
+ {
+ $<expr>0->stmt = counter_stmt_alloc(&@$);
+ }
+ | COUNTER PACKETS NUM BYTES NUM
+ {
+ struct stmt *stmt;
+
+ stmt = counter_stmt_alloc(&@$);
+ stmt->counter.packets = $3;
+ stmt->counter.bytes = $5;
+ $<expr>0->stmt = stmt;
+ }
+ | comment_spec
+ {
+ $<expr>0->comment = $1;
+ }
+ ;
+
set_lhs_expr : concat_rhs_expr
| wildcard_expr
;
--
2.31.1

View File

@ -0,0 +1,127 @@
From 48021b277a1ab92480c43e1fa7573b00e33f5212 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Fri, 14 Jan 2022 11:39:17 +0100
Subject: [PATCH] evaluate: attempt to set_eval flag if dynamic updates
requested
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2039594
Upstream Status: nftables commit 8d443adfcc8c1
Conflicts:
* Context change due to missing commit 242965f452e64
("src: add support for multi-statement in dynamic sets and maps")
* Adjusted test-case: Due to missing kernel commit 7b1394892de8d
("netfilter: nft_dynset: relax superfluous check on set updates"),
'update' statement is allowed only if timeout flag is present
commit 8d443adfcc8c19effd6be9a9c903ee96e374f2e8
Author: Florian Westphal <fw@strlen.de>
Date: Tue Jan 11 12:08:59 2022 +0100
evaluate: attempt to set_eval flag if dynamic updates requested
When passing no upper size limit, the dynset expression forces
an internal 64k upperlimit.
In some cases, this can result in 'nft -f' to restore the ruleset.
Avoid this by always setting the EVAL flag on a set definition when
we encounter packet-path update attempt in the batch.
Reported-by: Yi Chen <yiche@redhat.com>
Suggested-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
---
src/evaluate.c | 11 +++++++
.../testcases/sets/dumps/dynset_missing.nft | 12 +++++++
tests/shell/testcases/sets/dynset_missing | 32 +++++++++++++++++++
3 files changed, 55 insertions(+)
create mode 100644 tests/shell/testcases/sets/dumps/dynset_missing.nft
create mode 100755 tests/shell/testcases/sets/dynset_missing
diff --git a/src/evaluate.c b/src/evaluate.c
index 00ec20b..9381f23 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -3076,6 +3076,8 @@ static int stmt_evaluate_log(struct eval_ctx *ctx, struct stmt *stmt)
static int stmt_evaluate_set(struct eval_ctx *ctx, struct stmt *stmt)
{
+ struct set *this_set;
+
expr_set_context(&ctx->ectx, NULL, 0);
if (expr_evaluate(ctx, &stmt->set.set) < 0)
return -1;
@@ -3103,6 +3105,15 @@ static int stmt_evaluate_set(struct eval_ctx *ctx, struct stmt *stmt)
"meter statement must be stateful");
}
+ this_set = stmt->set.set->set;
+
+ /* Make sure EVAL flag is set on set definition so that kernel
+ * picks a set that allows updates from the packet path.
+ *
+ * Alternatively we could error out in case 'flags dynamic' was
+ * not given, but we can repair this here.
+ */
+ this_set->flags |= NFT_SET_EVAL;
return 0;
}
diff --git a/tests/shell/testcases/sets/dumps/dynset_missing.nft b/tests/shell/testcases/sets/dumps/dynset_missing.nft
new file mode 100644
index 0000000..fdb1b97
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/dynset_missing.nft
@@ -0,0 +1,12 @@
+table ip test {
+ set dlist {
+ type ipv4_addr
+ size 65535
+ flags dynamic,timeout
+ }
+
+ chain output {
+ type filter hook output priority filter; policy accept;
+ udp dport 1234 update @dlist { ip daddr } counter packets 0 bytes 0
+ }
+}
diff --git a/tests/shell/testcases/sets/dynset_missing b/tests/shell/testcases/sets/dynset_missing
new file mode 100755
index 0000000..89afcd5
--- /dev/null
+++ b/tests/shell/testcases/sets/dynset_missing
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+set -e
+
+$NFT -f /dev/stdin <<EOF
+table ip test {
+ chain output { type filter hook output priority 0;
+ }
+}
+EOF
+
+# misses 'flags dynamic'
+$NFT 'add set ip test dlist {type ipv4_addr; flags timeout; }'
+
+# picks rhash backend because 'size' was also missing.
+$NFT 'add rule ip test output udp dport 1234 update @dlist { ip daddr } counter'
+
+tmpfile=$(mktemp)
+
+trap "rm -rf $tmpfile" EXIT
+
+# kernel has forced an 64k upper size, i.e. this restore file
+# has 'size 65536' but no 'flags dynamic'.
+$NFT list ruleset > $tmpfile
+
+# this restore works, because set is still the rhash backend.
+$NFT -f $tmpfile # success
+$NFT flush ruleset
+
+# fails without commit 'attempt to set_eval flag if dynamic updates requested',
+# because set in $tmpfile has 'size x' but no 'flags dynamic'.
+$NFT -f $tmpfile
--
2.31.1

View File

@ -0,0 +1,49 @@
From 1fe92af5a03608b94e8e1e2ff26e24adfe2ea09a Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Fri, 21 Jan 2022 12:35:39 +0100
Subject: [PATCH] evaluate: fix inet nat with no layer 3 info
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2030773
Upstream Status: nftables commit 9a36033ce5063
commit 9a36033ce50638a403d1421935cdd1287ee5de6b
Author: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Tue Jul 20 18:59:44 2021 +0200
evaluate: fix inet nat with no layer 3 info
nft currently reports:
Error: Could not process rule: Protocol error
add rule inet x y meta l4proto tcp dnat to :80
^^^^
default to NFPROTO_INET family, otherwise kernel bails out EPROTO when
trying to load the conntrack helper.
Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1428
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
src/evaluate.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/evaluate.c b/src/evaluate.c
index 9381f23..e495faf 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -2757,9 +2757,10 @@ static int nat_evaluate_family(struct eval_ctx *ctx, struct stmt *stmt)
stmt->nat.family = ctx->pctx.family;
return 0;
case NFPROTO_INET:
- if (!stmt->nat.addr)
+ if (!stmt->nat.addr) {
+ stmt->nat.family = NFPROTO_INET;
return 0;
-
+ }
if (stmt->nat.family != NFPROTO_UNSPEC)
return 0;
--
2.31.1

View File

@ -0,0 +1,86 @@
From eeba2cd956485d3059dabf86a7ad8dd59ee682dd Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Fri, 4 Feb 2022 14:18:44 +0100
Subject: [PATCH] tests: py: add dnat to port without defining destination
address
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2030773
Upstream Status: nftables commit 0f27e258b37a5
Conflicts: Context changes due to missing commit ae1d822630e6d
("src: context tracking for multiple transport protocols")
commit 0f27e258b37a592233d6ad5381cd1fae65e57514
Author: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Thu Jul 22 17:43:56 2021 +0200
tests: py: add dnat to port without defining destination address
Add a test to cover dnat to port without destination address.
Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1428
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
tests/py/inet/dnat.t | 1 +
tests/py/inet/dnat.t.json | 20 ++++++++++++++++++++
tests/py/inet/dnat.t.payload | 8 ++++++++
3 files changed, 29 insertions(+)
diff --git a/tests/py/inet/dnat.t b/tests/py/inet/dnat.t
index fcdf943..6beceda 100644
--- a/tests/py/inet/dnat.t
+++ b/tests/py/inet/dnat.t
@@ -6,6 +6,7 @@ iifname "foo" tcp dport 80 redirect to :8080;ok
iifname "eth0" tcp dport 443 dnat ip to 192.168.3.2;ok
iifname "eth0" tcp dport 443 dnat ip6 to [dead::beef]:4443;ok
+meta l4proto tcp dnat to :80;ok;meta l4proto 6 dnat to :80
dnat ip to ct mark map { 0x00000014 : 1.2.3.4};ok
dnat ip to ct mark . ip daddr map { 0x00000014 . 1.1.1.1 : 1.2.3.4};ok
diff --git a/tests/py/inet/dnat.t.json b/tests/py/inet/dnat.t.json
index ac6dac6..f88e9cf 100644
--- a/tests/py/inet/dnat.t.json
+++ b/tests/py/inet/dnat.t.json
@@ -164,3 +164,23 @@
}
]
+# meta l4proto tcp dnat to :80
+[
+ {
+ "match": {
+ "left": {
+ "meta": {
+ "key": "l4proto"
+ }
+ },
+ "op": "==",
+ "right": 6
+ }
+ },
+ {
+ "dnat": {
+ "port": 80
+ }
+ }
+]
+
diff --git a/tests/py/inet/dnat.t.payload b/tests/py/inet/dnat.t.payload
index b81caf7..6d8569d 100644
--- a/tests/py/inet/dnat.t.payload
+++ b/tests/py/inet/dnat.t.payload
@@ -52,3 +52,11 @@ inet test-inet prerouting
[ payload load 4b @ network header + 16 => reg 9 ]
[ lookup reg 1 set __map%d dreg 1 ]
[ nat dnat ip addr_min reg 1 addr_max reg 0 ]
+
+# meta l4proto tcp dnat to :80
+inet
+ [ meta load l4proto => reg 1 ]
+ [ cmp eq reg 1 0x00000006 ]
+ [ immediate reg 1 0x00005000 ]
+ [ nat dnat inet proto_min reg 1 flags 0x2 ]
+
--
2.31.1

View File

@ -0,0 +1,214 @@
From bd940a4efd2b5897f8a8e58ec7733417b3710e1e Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Wed, 8 Dec 2021 13:28:49 +0100
Subject: [PATCH] mnl: do not build nftnl_set element list
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2047821
Upstream Status: nftables commit b4b234f5a29e8
Conflicts: Context change due to missing commit 66746e7dedeb0
("src: support for nat with interval concatenation").
commit b4b234f5a29e819045679acd95820a7457d4d7de
Author: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Thu Nov 4 12:53:11 2021 +0100
mnl: do not build nftnl_set element list
Do not call alloc_setelem_cache() to build the set element list in
nftnl_set. Instead, translate one single set element expression to
nftnl_set_elem object at a time and use this object to build the netlink
header.
Using a huge test set containing 1.1 million element blocklist, this
patch is reducing userspace memory consumption by 40%.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/netlink.h | 2 +
src/mnl.c | 112 ++++++++++++++++++++++++++++++++++++----------
src/netlink.c | 4 +-
3 files changed, 93 insertions(+), 25 deletions(-)
diff --git a/include/netlink.h b/include/netlink.h
index 059092e..3443582 100644
--- a/include/netlink.h
+++ b/include/netlink.h
@@ -56,6 +56,8 @@ struct netlink_ctx {
extern struct nftnl_expr *alloc_nft_expr(const char *name);
extern void alloc_setelem_cache(const struct expr *set, struct nftnl_set *nls);
+struct nftnl_set_elem *alloc_nftnl_setelem(const struct expr *set,
+ const struct expr *expr);
extern struct nftnl_table *netlink_table_alloc(const struct nlmsghdr *nlh);
extern struct nftnl_chain *netlink_chain_alloc(const struct nlmsghdr *nlh);
diff --git a/src/mnl.c b/src/mnl.c
index 23341e6..44cf1a4 100644
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -1201,33 +1201,102 @@ static int set_elem_cb(const struct nlmsghdr *nlh, void *data)
return MNL_CB_OK;
}
-static int mnl_nft_setelem_batch(struct nftnl_set *nls,
+static bool mnl_nft_attr_nest_overflow(struct nlmsghdr *nlh,
+ const struct nlattr *from,
+ const struct nlattr *to)
+{
+ int len = (void *)to + to->nla_len - (void *)from;
+
+ /* The attribute length field is 16 bits long, thus the maximum payload
+ * that an attribute can convey is UINT16_MAX. In case of overflow,
+ * discard the last attribute that did not fit into the nest.
+ */
+ if (len > UINT16_MAX) {
+ nlh->nlmsg_len -= to->nla_len;
+ return true;
+ }
+ return false;
+}
+
+static void netlink_dump_setelem(const struct nftnl_set_elem *nlse,
+ struct netlink_ctx *ctx)
+{
+ FILE *fp = ctx->nft->output.output_fp;
+ char buf[4096];
+
+ if (!(ctx->nft->debug_mask & NFT_DEBUG_NETLINK) || !fp)
+ return;
+
+ nftnl_set_elem_snprintf(buf, sizeof(buf), nlse, NFTNL_OUTPUT_DEFAULT, 0);
+ fprintf(fp, "\t%s", buf);
+}
+
+static void netlink_dump_setelem_done(struct netlink_ctx *ctx)
+{
+ FILE *fp = ctx->nft->output.output_fp;
+
+ if (!(ctx->nft->debug_mask & NFT_DEBUG_NETLINK) || !fp)
+ return;
+
+ fprintf(fp, "\n");
+}
+
+static int mnl_nft_setelem_batch(const struct nftnl_set *nls,
struct nftnl_batch *batch,
enum nf_tables_msg_types cmd,
- unsigned int flags, uint32_t seqnum)
+ unsigned int flags, uint32_t seqnum,
+ const struct expr *set,
+ struct netlink_ctx *ctx)
{
+ struct nlattr *nest1, *nest2;
+ struct nftnl_set_elem *nlse;
struct nlmsghdr *nlh;
- struct nftnl_set_elems_iter *iter;
- int ret;
-
- iter = nftnl_set_elems_iter_create(nls);
- if (iter == NULL)
- memory_allocation_error();
+ struct expr *expr = NULL;
+ int i = 0;
if (cmd == NFT_MSG_NEWSETELEM)
flags |= NLM_F_CREATE;
- while (nftnl_set_elems_iter_cur(iter)) {
- nlh = nftnl_nlmsg_build_hdr(nftnl_batch_buffer(batch), cmd,
- nftnl_set_get_u32(nls, NFTNL_SET_FAMILY),
- flags, seqnum);
- ret = nftnl_set_elems_nlmsg_build_payload_iter(nlh, iter);
- mnl_nft_batch_continue(batch);
- if (ret <= 0)
- break;
+ if (set)
+ expr = list_first_entry(&set->expressions, struct expr, list);
+
+next:
+ nlh = nftnl_nlmsg_build_hdr(nftnl_batch_buffer(batch), cmd,
+ nftnl_set_get_u32(nls, NFTNL_SET_FAMILY),
+ flags, seqnum);
+
+ if (nftnl_set_is_set(nls, NFTNL_SET_TABLE)) {
+ mnl_attr_put_strz(nlh, NFTA_SET_ELEM_LIST_TABLE,
+ nftnl_set_get_str(nls, NFTNL_SET_TABLE));
+ }
+ if (nftnl_set_is_set(nls, NFTNL_SET_NAME)) {
+ mnl_attr_put_strz(nlh, NFTA_SET_ELEM_LIST_SET,
+ nftnl_set_get_str(nls, NFTNL_SET_NAME));
}
+ if (nftnl_set_is_set(nls, NFTNL_SET_ID)) {
+ mnl_attr_put_u32(nlh, NFTA_SET_ELEM_LIST_SET_ID,
+ htonl(nftnl_set_get_u32(nls, NFTNL_SET_ID)));
+ }
+
+ if (!set || list_empty(&set->expressions))
+ return 0;
- nftnl_set_elems_iter_destroy(iter);
+ assert(expr);
+ nest1 = mnl_attr_nest_start(nlh, NFTA_SET_ELEM_LIST_ELEMENTS);
+ list_for_each_entry_from(expr, &set->expressions, list) {
+ nlse = alloc_nftnl_setelem(set, expr);
+ nest2 = nftnl_set_elem_nlmsg_build(nlh, nlse, ++i);
+ netlink_dump_setelem(nlse, ctx);
+ nftnl_set_elem_free(nlse);
+ if (mnl_nft_attr_nest_overflow(nlh, nest1, nest2)) {
+ mnl_attr_nest_end(nlh, nest1);
+ mnl_nft_batch_continue(batch);
+ goto next;
+ }
+ }
+ mnl_attr_nest_end(nlh, nest1);
+ mnl_nft_batch_continue(batch);
+ netlink_dump_setelem_done(ctx);
return 0;
}
@@ -1249,11 +1318,10 @@ int mnl_nft_setelem_add(struct netlink_ctx *ctx, const struct set *set,
if (h->set_id)
nftnl_set_set_u32(nls, NFTNL_SET_ID, h->set_id);
- alloc_setelem_cache(expr, nls);
netlink_dump_set(nls, ctx);
- err = mnl_nft_setelem_batch(nls, ctx->batch, NFT_MSG_NEWSETELEM, flags,
- ctx->seqnum);
+ err = mnl_nft_setelem_batch(nls, ctx->batch, NFT_MSG_NEWSETELEM,
+ flags, ctx->seqnum, expr, ctx);
nftnl_set_free(nls);
return err;
@@ -1306,12 +1374,10 @@ int mnl_nft_setelem_del(struct netlink_ctx *ctx, const struct cmd *cmd)
else if (h->handle.id)
nftnl_set_set_u64(nls, NFTNL_SET_HANDLE, h->handle.id);
- if (cmd->expr)
- alloc_setelem_cache(cmd->expr, nls);
netlink_dump_set(nls, ctx);
err = mnl_nft_setelem_batch(nls, ctx->batch, NFT_MSG_DELSETELEM, 0,
- ctx->seqnum);
+ ctx->seqnum, cmd->expr, ctx);
nftnl_set_free(nls);
return err;
diff --git a/src/netlink.c b/src/netlink.c
index 825c2cc..f8c97d0 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -95,8 +95,8 @@ struct nftnl_expr *alloc_nft_expr(const char *name)
return nle;
}
-static struct nftnl_set_elem *alloc_nftnl_setelem(const struct expr *set,
- const struct expr *expr)
+struct nftnl_set_elem *alloc_nftnl_setelem(const struct expr *set,
+ const struct expr *expr)
{
const struct expr *elem, *data;
struct nftnl_set_elem *nlse;
--
2.31.1

View File

@ -1,5 +1,6 @@
%define rpmversion 0.9.3
%define specrelease 24
%define specrelease 25
%define libnftnl_ver 1.1.5-5
Name: nftables
Version: %{rpmversion}
@ -87,6 +88,12 @@ Patch67: 0067-segtree-Fix-segfault-when-restoring-a-huge-interval-.pa
Patch68: 0068-tests-cover-baecd1cf2685-segtree-Fix-segfault-when-r.patch
Patch69: 0069-tests-shell-NFT-needs-to-be-invoked-unquoted.patch
Patch70: 0070-tests-shell-better-parameters-for-the-interval-stack.patch
Patch71: 0071-netlink-remove-unused-parameter-from-netlink_gen_stm.patch
Patch72: 0072-src-support-for-restoring-element-counters.patch
Patch73: 0073-evaluate-attempt-to-set_eval-flag-if-dynamic-updates.patch
Patch74: 0074-evaluate-fix-inet-nat-with-no-layer-3-info.patch
Patch75: 0075-tests-py-add-dnat-to-port-without-defining-destinati.patch
Patch76: 0076-mnl-do-not-build-nftnl_set-element-list.patch
BuildRequires: autogen
BuildRequires: autoconf
@ -98,14 +105,14 @@ BuildRequires: bison
BuildRequires: libmnl-devel
BuildRequires: gmp-devel
BuildRequires: readline-devel
BuildRequires: pkgconfig(libnftnl) >= 1.1.5-3
BuildRequires: pkgconfig(libnftnl) >= %{libnftnl_ver}
BuildRequires: systemd
BuildRequires: asciidoc
BuildRequires: iptables-devel
BuildRequires: jansson-devel
BuildRequires: python3-devel
Requires: libnftnl >= 1.1.5-3
Requires: libnftnl >= %{libnftnl_ver}
%description
Netfilter Tables userspace utilities.
@ -203,6 +210,14 @@ touch -r %{SOURCE2} $RPM_BUILD_ROOT/%{python3_sitelib}/nftables/nftables.py
%{python3_sitelib}/nftables/
%changelog
* Fri Feb 04 2022 Phil Sutter <psutter@redhat.com> [0.9.3-25.el8]
- mnl: do not build nftnl_set element list (Phil Sutter) [2047821]
- tests: py: add dnat to port without defining destination address (Phil Sutter) [2030773]
- evaluate: fix inet nat with no layer 3 info (Phil Sutter) [2030773]
- evaluate: attempt to set_eval flag if dynamic updates requested (Phil Sutter) [2039594]
- src: support for restoring element counters (Phil Sutter) [2039594]
- netlink: remove unused parameter from netlink_gen_stmt_stateful() (Phil Sutter) [2039594]
* Wed Dec 08 2021 Phil Sutter <psutter@redhat.com> [0.9.3-24.el8]
- tests: shell: better parameters for the interval stack overflow test (Phil Sutter) [1908127]
- tests: shell: $NFT needs to be invoked unquoted (Phil Sutter) [1908127]