* [nft PATCH 0/9] Support wildcard netdev hooks and events
@ 2024-10-02 19:38 Phil Sutter
2024-10-02 19:38 ` [nft PATCH 1/9] json: Support typeof in set and map types Phil Sutter
` (10 more replies)
0 siblings, 11 replies; 14+ messages in thread
From: Phil Sutter @ 2024-10-02 19:38 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
This series is the second (and last?) step of enabling support for
name-based and wildcard interface hooks in user space. It depends on the
previously sent series for libnftnl.
Patches 1-4 are fallout, fixing for deficits in different areas.
Patches 5 and 6 extend parser and serializer to accept and correctly
pass interface wildcards on to the kernel.
Patch 7 adjusts shell test cases to the different behaviour (removed
interfaces no longer disappearing from hook specs), mostly stored dump
adjustments.
Patches 8 and 9 extend nft monitor to print NEWDEV/DELDEV events and
extend the monitor testsuite to cover the code.
Phil Sutter (9):
json: Support typeof in set and map types
tests: py: Fix for storing payload into missing file
monitor: Recognize flowtable add/del events
tests: monitor: Run in own netns
mnl: Support simple wildcards in netdev hooks
parser_bison: Accept ASTERISK_STRING in flowtable_expr_member
tests: shell: Adjust to ifname-based flowtables
tests: monitor: Support running external commands
monitor: Support NFT_MSG_(NEW|DEL)DEV events
doc/libnftables-json.adoc | 7 +-
include/json.h | 20 +++
include/linux/netfilter/nf_tables.h | 10 ++
include/netlink.h | 1 +
include/rule.h | 1 +
src/json.c | 46 ++++++-
src/mnl.c | 19 ++-
src/monitor.c | 125 ++++++++++++++++++
src/parser_bison.y | 11 +-
src/parser_json.c | 15 +++
src/rule.c | 15 +++
tests/monitor/run-tests.sh | 72 +++++++++-
tests/monitor/testcases/chain-netdev.t | 66 +++++++++
tests/monitor/testcases/flowtable-simple.t | 66 +++++++++
tests/monitor/testcases/map-expr.t | 2 +-
tests/monitor/testcases/set-concat-interval.t | 3 +
tests/py/nft-test.py | 5 +-
.../chains/dumps/netdev_chain_0.json-nft | 17 +++
.../testcases/chains/dumps/netdev_chain_0.nft | 3 +
.../netdev_chain_dormant_autoremove.json-nft | 5 +-
.../dumps/netdev_chain_dormant_autoremove.nft | 2 +-
.../dumps/0012flowtable_variable_0.json-nft | 10 +-
.../dumps/0012flowtable_variable_0.nft | 4 +-
.../testcases/json/dumps/netdev.json-nft | 13 ++
tests/shell/testcases/json/dumps/netdev.nft | 3 +
.../listing/dumps/0020flowtable_0.json-nft | 6 +-
.../listing/dumps/0020flowtable_0.nft | 2 +
.../maps/dumps/0012map_concat_0.json-nft | 21 ++-
.../maps/dumps/0017_map_variable_0.json-nft | 18 ++-
.../maps/dumps/named_limits.json-nft | 55 ++++++--
.../dumps/typeof_maps_add_delete.json-nft | 9 +-
.../maps/dumps/typeof_maps_update_0.json-nft | 9 +-
.../maps/dumps/vmap_timeout.json-nft | 22 ++-
.../packetpath/dumps/set_lookups.json-nft | 42 ++++--
.../sets/dumps/0048set_counters_0.json-nft | 9 +-
.../testcases/sets/dumps/inner_0.json-nft | 34 ++++-
.../set_element_timeout_updates.json-nft | 9 +-
tests/shell/testcases/transactions/0050rule_1 | 19 ---
.../transactions/dumps/0050rule_1.json-nft | 11 --
.../transactions/dumps/0050rule_1.nft | 0
40 files changed, 706 insertions(+), 101 deletions(-)
create mode 100644 tests/monitor/testcases/chain-netdev.t
create mode 100644 tests/monitor/testcases/flowtable-simple.t
delete mode 100755 tests/shell/testcases/transactions/0050rule_1
delete mode 100644 tests/shell/testcases/transactions/dumps/0050rule_1.json-nft
delete mode 100644 tests/shell/testcases/transactions/dumps/0050rule_1.nft
--
2.43.0
^ permalink raw reply [flat|nested] 14+ messages in thread
* [nft PATCH 1/9] json: Support typeof in set and map types
2024-10-02 19:38 [nft PATCH 0/9] Support wildcard netdev hooks and events Phil Sutter
@ 2024-10-02 19:38 ` Phil Sutter
2024-10-02 19:38 ` [nft PATCH 2/9] tests: py: Fix for storing payload into missing file Phil Sutter
` (9 subsequent siblings)
10 siblings, 0 replies; 14+ messages in thread
From: Phil Sutter @ 2024-10-02 19:38 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
Implement this as a special "type" property value which is an object
with sole property "typeof". The latter's value is the JSON
representation of the expression in set->key, so for concatenated
typeofs it is a concat expression.
All this is a bit clumsy right now but it works and it should be
possible to tear it down a bit for more user-friendliness in a
compatible way by either replacing the concat expression by the array it
contains or even the whole "typeof" object - the parser would just
assume any object (or objects in an array) in the "type" property value
are expressions to extract a type from.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
doc/libnftables-json.adoc | 7 ++-
src/json.c | 13 ++++-
src/parser_json.c | 9 +++
tests/monitor/testcases/map-expr.t | 2 +-
tests/monitor/testcases/set-concat-interval.t | 3 +
.../maps/dumps/0012map_concat_0.json-nft | 21 +++++--
.../maps/dumps/0017_map_variable_0.json-nft | 18 +++++-
.../maps/dumps/named_limits.json-nft | 55 ++++++++++++++++---
.../dumps/typeof_maps_add_delete.json-nft | 9 ++-
.../maps/dumps/typeof_maps_update_0.json-nft | 9 ++-
.../maps/dumps/vmap_timeout.json-nft | 22 ++++++--
.../packetpath/dumps/set_lookups.json-nft | 42 +++++++++++---
.../sets/dumps/0048set_counters_0.json-nft | 9 ++-
.../testcases/sets/dumps/inner_0.json-nft | 34 ++++++++++--
.../set_element_timeout_updates.json-nft | 9 ++-
15 files changed, 222 insertions(+), 40 deletions(-)
diff --git a/doc/libnftables-json.adoc b/doc/libnftables-json.adoc
index a8a6165fde59d..593d407c924e9 100644
--- a/doc/libnftables-json.adoc
+++ b/doc/libnftables-json.adoc
@@ -341,7 +341,7 @@ ____
"auto-merge":* 'BOOLEAN'
*}}*
-'SET_TYPE' := 'STRING' | *[* 'SET_TYPE_LIST' *]*
+'SET_TYPE' := 'STRING' | *[* 'SET_TYPE_LIST' *]* | *{ "typeof":* 'EXPRESSION' *}*
'SET_TYPE_LIST' := 'STRING' [*,* 'SET_TYPE_LIST' ]
'SET_POLICY' := *"performance"* | *"memory"*
'SET_FLAG_LIST' := 'SET_FLAG' [*,* 'SET_FLAG_LIST' ]
@@ -381,8 +381,9 @@ that they translate a unique key to a value.
Automatic merging of adjacent/overlapping set elements in interval sets.
==== TYPE
-The set type might be a string, such as *"ipv4_addr"* or an array
-consisting of strings (for concatenated types).
+The set type might be a string, such as *"ipv4_addr"*, an array
+consisting of strings (for concatenated types) or a *typeof* object containing
+an expression to extract the type from.
==== ELEM
A single set element might be given as string, integer or boolean value for
diff --git a/src/json.c b/src/json.c
index b1531ff3f4c9e..1f609bf2b03e9 100644
--- a/src/json.c
+++ b/src/json.c
@@ -96,6 +96,17 @@ static json_t *set_dtype_json(const struct expr *key)
return root;
}
+static json_t *set_key_dtype_json(const struct set *set,
+ struct output_ctx *octx)
+{
+ bool use_typeof = set->key_typeof_valid;
+
+ if (!use_typeof)
+ return set_dtype_json(set->key);
+
+ return json_pack("{s:o}", "typeof", expr_print_json(set->key, octx));
+}
+
static json_t *stmt_print_json(const struct stmt *stmt, struct output_ctx *octx)
{
char buf[1024];
@@ -158,7 +169,7 @@ static json_t *set_print_json(struct output_ctx *octx, const struct set *set)
"family", family2str(set->handle.family),
"name", set->handle.set.name,
"table", set->handle.table.name,
- "type", set_dtype_json(set->key),
+ "type", set_key_dtype_json(set, octx),
"handle", set->handle.handle.id);
if (set->comment)
diff --git a/src/parser_json.c b/src/parser_json.c
index bbe3b1c59192c..f8200db1fe114 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -1729,7 +1729,16 @@ static struct expr *json_parse_dtype_expr(struct json_ctx *ctx, json_t *root)
compound_expr_add(expr, i);
}
return expr;
+ } else if (json_is_object(root)) {
+ const char *key;
+ json_t *val;
+
+ if (!json_unpack_stmt(ctx, root, &key, &val) &&
+ !strcmp(key, "typeof")) {
+ return json_parse_expr(ctx, val);
+ }
}
+
json_error(ctx, "Invalid set datatype.");
return NULL;
}
diff --git a/tests/monitor/testcases/map-expr.t b/tests/monitor/testcases/map-expr.t
index 8729c0b44ee2c..d11ad0ebc0d57 100644
--- a/tests/monitor/testcases/map-expr.t
+++ b/tests/monitor/testcases/map-expr.t
@@ -3,4 +3,4 @@ I add table ip t
I add map ip t m { typeof meta day . meta hour : verdict; flags interval; counter; }
O -
J {"add": {"table": {"family": "ip", "name": "t", "handle": 0}}}
-J {"add": {"map": {"family": "ip", "name": "m", "table": "t", "type": ["day", "hour"], "handle": 0, "map": "verdict", "flags": ["interval"], "stmt": [{"counter": null}]}}}
+J {"add": {"map": {"family": "ip", "name": "m", "table": "t", "type": {"typeof": {"concat": [{"meta": {"key": "day"}}, {"meta": {"key": "hour"}}]}}, "handle": 0, "map": "verdict", "flags": ["interval"], "stmt": [{"counter": null}]}}}
diff --git a/tests/monitor/testcases/set-concat-interval.t b/tests/monitor/testcases/set-concat-interval.t
index 763dc319f0d13..3542b8225ebd1 100644
--- a/tests/monitor/testcases/set-concat-interval.t
+++ b/tests/monitor/testcases/set-concat-interval.t
@@ -10,3 +10,6 @@ I add map ip t s { typeof udp length . @ih,32,32 : verdict; flags interval; elem
O add map ip t s { typeof udp length . @ih,32,32 : verdict; flags interval; }
O add element ip t s { 20-80 . 0x14 : accept }
O add element ip t s { 1-10 . 0xa : drop }
+J {"add": {"map": {"family": "ip", "name": "s", "table": "t", "type": {"typeof": {"concat": [{"payload": {"protocol": "udp", "field": "length"}}, {"payload": {"base": "ih", "offset": 32, "len": 32}}]}}, "handle": 0, "map": "verdict", "flags": ["interval"]}}}
+J {"add": {"element": {"family": "ip", "table": "t", "name": "s", "elem": {"set": [[{"concat": [{"range": [20, 80]}, 20]}, {"accept": null}]]}}}}
+J {"add": {"element": {"family": "ip", "table": "t", "name": "s", "elem": {"set": [[{"concat": [{"range": [1, 10]}, 10]}, {"drop": null}]]}}}}
diff --git a/tests/shell/testcases/maps/dumps/0012map_concat_0.json-nft b/tests/shell/testcases/maps/dumps/0012map_concat_0.json-nft
index 000522365df9f..88bf4984dbde7 100644
--- a/tests/shell/testcases/maps/dumps/0012map_concat_0.json-nft
+++ b/tests/shell/testcases/maps/dumps/0012map_concat_0.json-nft
@@ -31,10 +31,23 @@
"family": "ip",
"name": "w",
"table": "x",
- "type": [
- "ipv4_addr",
- "mark"
- ],
+ "type": {
+ "typeof": {
+ "concat": [
+ {
+ "payload": {
+ "protocol": "ip",
+ "field": "saddr"
+ }
+ },
+ {
+ "meta": {
+ "key": "mark"
+ }
+ }
+ ]
+ }
+ },
"handle": 0,
"map": "verdict",
"flags": [
diff --git a/tests/shell/testcases/maps/dumps/0017_map_variable_0.json-nft b/tests/shell/testcases/maps/dumps/0017_map_variable_0.json-nft
index 725498cdcbef8..8eacf612d12fb 100644
--- a/tests/shell/testcases/maps/dumps/0017_map_variable_0.json-nft
+++ b/tests/shell/testcases/maps/dumps/0017_map_variable_0.json-nft
@@ -19,7 +19,14 @@
"family": "ip",
"name": "y",
"table": "x",
- "type": "ipv4_addr",
+ "type": {
+ "typeof": {
+ "payload": {
+ "protocol": "ip",
+ "field": "saddr"
+ }
+ }
+ },
"handle": 0,
"map": "mark",
"elem": [
@@ -39,7 +46,14 @@
"family": "ip",
"name": "z",
"table": "x",
- "type": "ipv4_addr",
+ "type": {
+ "typeof": {
+ "payload": {
+ "protocol": "ip",
+ "field": "saddr"
+ }
+ }
+ },
"handle": 0,
"map": "mark",
"elem": [
diff --git a/tests/shell/testcases/maps/dumps/named_limits.json-nft b/tests/shell/testcases/maps/dumps/named_limits.json-nft
index 7fa1298103832..3c6845ac43b42 100644
--- a/tests/shell/testcases/maps/dumps/named_limits.json-nft
+++ b/tests/shell/testcases/maps/dumps/named_limits.json-nft
@@ -75,7 +75,14 @@
"family": "inet",
"name": "tarpit4",
"table": "filter",
- "type": "ipv4_addr",
+ "type": {
+ "typeof": {
+ "payload": {
+ "protocol": "ip",
+ "field": "saddr"
+ }
+ }
+ },
"handle": 0,
"size": 10000,
"flags": [
@@ -90,7 +97,14 @@
"family": "inet",
"name": "tarpit6",
"table": "filter",
- "type": "ipv6_addr",
+ "type": {
+ "typeof": {
+ "payload": {
+ "protocol": "ip6",
+ "field": "saddr"
+ }
+ }
+ },
"handle": 0,
"size": 10000,
"flags": [
@@ -105,11 +119,29 @@
"family": "inet",
"name": "addr4limit",
"table": "filter",
- "type": [
- "inet_proto",
- "ipv4_addr",
- "inet_service"
- ],
+ "type": {
+ "typeof": {
+ "concat": [
+ {
+ "meta": {
+ "key": "l4proto"
+ }
+ },
+ {
+ "payload": {
+ "protocol": "ip",
+ "field": "saddr"
+ }
+ },
+ {
+ "payload": {
+ "protocol": "tcp",
+ "field": "sport"
+ }
+ }
+ ]
+ }
+ },
"handle": 0,
"map": "limit",
"flags": [
@@ -244,7 +276,14 @@
"family": "inet",
"name": "saddr6limit",
"table": "filter",
- "type": "ipv6_addr",
+ "type": {
+ "typeof": {
+ "payload": {
+ "protocol": "ip6",
+ "field": "saddr"
+ }
+ }
+ },
"handle": 0,
"map": "limit",
"flags": [
diff --git a/tests/shell/testcases/maps/dumps/typeof_maps_add_delete.json-nft b/tests/shell/testcases/maps/dumps/typeof_maps_add_delete.json-nft
index b3204a283d0ad..effe02dcf8364 100644
--- a/tests/shell/testcases/maps/dumps/typeof_maps_add_delete.json-nft
+++ b/tests/shell/testcases/maps/dumps/typeof_maps_add_delete.json-nft
@@ -39,7 +39,14 @@
"family": "ip",
"name": "dynmark",
"table": "dynset",
- "type": "ipv4_addr",
+ "type": {
+ "typeof": {
+ "payload": {
+ "protocol": "ip",
+ "field": "daddr"
+ }
+ }
+ },
"handle": 0,
"map": "mark",
"size": 64,
diff --git a/tests/shell/testcases/maps/dumps/typeof_maps_update_0.json-nft b/tests/shell/testcases/maps/dumps/typeof_maps_update_0.json-nft
index 1d50477d783df..731514663b1aa 100644
--- a/tests/shell/testcases/maps/dumps/typeof_maps_update_0.json-nft
+++ b/tests/shell/testcases/maps/dumps/typeof_maps_update_0.json-nft
@@ -50,7 +50,14 @@
"family": "ip",
"name": "sticky-set-svc-153CN2XYVUHRQ7UB",
"table": "kube-nfproxy-v4",
- "type": "ipv4_addr",
+ "type": {
+ "typeof": {
+ "payload": {
+ "protocol": "ip",
+ "field": "daddr"
+ }
+ }
+ },
"handle": 0,
"map": "mark",
"size": 65535,
diff --git a/tests/shell/testcases/maps/dumps/vmap_timeout.json-nft b/tests/shell/testcases/maps/dumps/vmap_timeout.json-nft
index 1c3aa590f846e..71e9a9ee9f21b 100644
--- a/tests/shell/testcases/maps/dumps/vmap_timeout.json-nft
+++ b/tests/shell/testcases/maps/dumps/vmap_timeout.json-nft
@@ -87,10 +87,24 @@
"family": "inet",
"name": "portaddrmap",
"table": "filter",
- "type": [
- "ipv4_addr",
- "inet_service"
- ],
+ "type": {
+ "typeof": {
+ "concat": [
+ {
+ "payload": {
+ "protocol": "ip",
+ "field": "daddr"
+ }
+ },
+ {
+ "payload": {
+ "protocol": "th",
+ "field": "dport"
+ }
+ }
+ ]
+ }
+ },
"handle": 0,
"map": "verdict",
"flags": [
diff --git a/tests/shell/testcases/packetpath/dumps/set_lookups.json-nft b/tests/shell/testcases/packetpath/dumps/set_lookups.json-nft
index 24363f9071b22..bcf6914e95cb9 100644
--- a/tests/shell/testcases/packetpath/dumps/set_lookups.json-nft
+++ b/tests/shell/testcases/packetpath/dumps/set_lookups.json-nft
@@ -60,10 +60,23 @@
"family": "ip",
"name": "s2",
"table": "t",
- "type": [
- "ipv4_addr",
- "iface_index"
- ],
+ "type": {
+ "typeof": {
+ "concat": [
+ {
+ "payload": {
+ "protocol": "ip",
+ "field": "saddr"
+ }
+ },
+ {
+ "meta": {
+ "key": "iif"
+ }
+ }
+ ]
+ }
+ },
"handle": 0,
"elem": [
{
@@ -113,10 +126,23 @@
"family": "ip",
"name": "nomatch",
"table": "t",
- "type": [
- "ipv4_addr",
- "iface_index"
- ],
+ "type": {
+ "typeof": {
+ "concat": [
+ {
+ "payload": {
+ "protocol": "ip",
+ "field": "saddr"
+ }
+ },
+ {
+ "meta": {
+ "key": "iif"
+ }
+ }
+ ]
+ }
+ },
"handle": 0,
"elem": [
{
diff --git a/tests/shell/testcases/sets/dumps/0048set_counters_0.json-nft b/tests/shell/testcases/sets/dumps/0048set_counters_0.json-nft
index 62a6a177b7776..4be4112bf7935 100644
--- a/tests/shell/testcases/sets/dumps/0048set_counters_0.json-nft
+++ b/tests/shell/testcases/sets/dumps/0048set_counters_0.json-nft
@@ -31,7 +31,14 @@
"family": "ip",
"name": "y",
"table": "x",
- "type": "ipv4_addr",
+ "type": {
+ "typeof": {
+ "payload": {
+ "protocol": "ip",
+ "field": "saddr"
+ }
+ }
+ },
"handle": 0,
"elem": [
{
diff --git a/tests/shell/testcases/sets/dumps/inner_0.json-nft b/tests/shell/testcases/sets/dumps/inner_0.json-nft
index 8d84e1ccecb9f..e5dc198f436be 100644
--- a/tests/shell/testcases/sets/dumps/inner_0.json-nft
+++ b/tests/shell/testcases/sets/dumps/inner_0.json-nft
@@ -27,10 +27,26 @@
"family": "netdev",
"name": "x",
"table": "x",
- "type": [
- "ipv4_addr",
- "ipv4_addr"
- ],
+ "type": {
+ "typeof": {
+ "concat": [
+ {
+ "payload": {
+ "tunnel": "vxlan",
+ "protocol": "ip",
+ "field": "saddr"
+ }
+ },
+ {
+ "payload": {
+ "tunnel": "vxlan",
+ "protocol": "ip",
+ "field": "daddr"
+ }
+ }
+ ]
+ }
+ },
"handle": 0,
"elem": [
{
@@ -47,7 +63,15 @@
"family": "netdev",
"name": "y",
"table": "x",
- "type": "ipv4_addr",
+ "type": {
+ "typeof": {
+ "payload": {
+ "tunnel": "vxlan",
+ "protocol": "ip",
+ "field": "saddr"
+ }
+ }
+ },
"handle": 0,
"size": 65535,
"flags": [
diff --git a/tests/shell/testcases/sets/dumps/set_element_timeout_updates.json-nft b/tests/shell/testcases/sets/dumps/set_element_timeout_updates.json-nft
index aa908297e49ea..d92d8d7a54940 100644
--- a/tests/shell/testcases/sets/dumps/set_element_timeout_updates.json-nft
+++ b/tests/shell/testcases/sets/dumps/set_element_timeout_updates.json-nft
@@ -31,7 +31,14 @@
"family": "ip",
"name": "s",
"table": "t",
- "type": "ipv4_addr",
+ "type": {
+ "typeof": {
+ "payload": {
+ "protocol": "ip",
+ "field": "saddr"
+ }
+ }
+ },
"handle": 0,
"flags": [
"timeout"
--
2.43.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [nft PATCH 2/9] tests: py: Fix for storing payload into missing file
2024-10-02 19:38 [nft PATCH 0/9] Support wildcard netdev hooks and events Phil Sutter
2024-10-02 19:38 ` [nft PATCH 1/9] json: Support typeof in set and map types Phil Sutter
@ 2024-10-02 19:38 ` Phil Sutter
2024-10-02 19:38 ` [nft PATCH 3/9] monitor: Recognize flowtable add/del events Phil Sutter
` (8 subsequent siblings)
10 siblings, 0 replies; 14+ messages in thread
From: Phil Sutter @ 2024-10-02 19:38 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
When running a test for which no corresponding *.payload file exists,
the *.payload.got file name was incorrectly constructed due to
'payload_path' variable not being set.
Fixes: 2cfab7a3e10fc ("tests/py: Write dissenting payload into the right file")
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
tests/py/nft-test.py | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/tests/py/nft-test.py b/tests/py/nft-test.py
index 00799e281d566..7acdb77f2d0a2 100755
--- a/tests/py/nft-test.py
+++ b/tests/py/nft-test.py
@@ -769,10 +769,9 @@ def set_delete_elements(set_element, set_name, table, filename=None,
if rule[1].strip() == "ok":
payload_expected = None
- payload_path = None
+ payload_path = "%s.payload" % filename_path
try:
- payload_log = open("%s.payload" % filename_path)
- payload_path = payload_log.name
+ payload_log = open(payload_path)
payload_expected = payload_find_expected(payload_log, rule[0])
except:
payload_log = None
--
2.43.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [nft PATCH 3/9] monitor: Recognize flowtable add/del events
2024-10-02 19:38 [nft PATCH 0/9] Support wildcard netdev hooks and events Phil Sutter
2024-10-02 19:38 ` [nft PATCH 1/9] json: Support typeof in set and map types Phil Sutter
2024-10-02 19:38 ` [nft PATCH 2/9] tests: py: Fix for storing payload into missing file Phil Sutter
@ 2024-10-02 19:38 ` Phil Sutter
2024-10-02 19:38 ` [nft PATCH 4/9] tests: monitor: Run in own netns Phil Sutter
` (7 subsequent siblings)
10 siblings, 0 replies; 14+ messages in thread
From: Phil Sutter @ 2024-10-02 19:38 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
These were entirely ignored before, add the necessary code analogous to
e.g. objects.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
include/json.h | 10 ++++
include/netlink.h | 1 +
include/rule.h | 1 +
src/json.c | 6 +++
src/monitor.c | 61 ++++++++++++++++++++++
src/parser_json.c | 6 +++
src/rule.c | 15 ++++++
tests/monitor/testcases/flowtable-simple.t | 10 ++++
8 files changed, 110 insertions(+)
create mode 100644 tests/monitor/testcases/flowtable-simple.t
diff --git a/include/json.h b/include/json.h
index 39be8928e8ee0..0670b8714519b 100644
--- a/include/json.h
+++ b/include/json.h
@@ -11,6 +11,7 @@ struct nlmsghdr;
struct rule;
struct set;
struct obj;
+struct flowtable;
struct stmt;
struct symbol_table;
struct table;
@@ -113,6 +114,8 @@ void monitor_print_element_json(struct netlink_mon_handler *monh,
const char *cmd, struct set *s);
void monitor_print_obj_json(struct netlink_mon_handler *monh,
const char *cmd, struct obj *o);
+void monitor_print_flowtable_json(struct netlink_mon_handler *monh,
+ const char *cmd, struct flowtable *ft);
void monitor_print_rule_json(struct netlink_mon_handler *monh,
const char *cmd, struct rule *r);
@@ -254,6 +257,13 @@ static inline void monitor_print_obj_json(struct netlink_mon_handler *monh,
/* empty */
}
+static inline void
+monitor_print_flowtable_json(struct netlink_mon_handler *monh,
+ const char *cmd, struct flowtable *ft)
+{
+ /* empty */
+}
+
static inline void monitor_print_rule_json(struct netlink_mon_handler *monh,
const char *cmd, struct rule *r)
{
diff --git a/include/netlink.h b/include/netlink.h
index cf7ba3693885a..e9667a24b0d11 100644
--- a/include/netlink.h
+++ b/include/netlink.h
@@ -97,6 +97,7 @@ extern struct nftnl_table *netlink_table_alloc(const struct nlmsghdr *nlh);
extern struct nftnl_chain *netlink_chain_alloc(const struct nlmsghdr *nlh);
extern struct nftnl_set *netlink_set_alloc(const struct nlmsghdr *nlh);
extern struct nftnl_obj *netlink_obj_alloc(const struct nlmsghdr *nlh);
+extern struct nftnl_flowtable *netlink_flowtable_alloc(const struct nlmsghdr *nlh);
extern struct nftnl_rule *netlink_rule_alloc(const struct nlmsghdr *nlh);
struct nft_data_linearize {
diff --git a/include/rule.h b/include/rule.h
index 5b3e12b5d7dcf..75166b48446f5 100644
--- a/include/rule.h
+++ b/include/rule.h
@@ -551,6 +551,7 @@ extern struct flowtable *flowtable_lookup_fuzzy(const char *ft_name,
const struct table **table);
void flowtable_print(const struct flowtable *n, struct output_ctx *octx);
+void flowtable_print_plain(const struct flowtable *ft, struct output_ctx *octx);
/**
* enum cmd_ops - command operations
diff --git a/src/json.c b/src/json.c
index 1f609bf2b03e9..64a6888f9e0ac 100644
--- a/src/json.c
+++ b/src/json.c
@@ -2108,6 +2108,12 @@ void monitor_print_obj_json(struct netlink_mon_handler *monh,
monitor_print_json(monh, cmd, obj_print_json(o));
}
+void monitor_print_flowtable_json(struct netlink_mon_handler *monh,
+ const char *cmd, struct flowtable *ft)
+{
+ monitor_print_json(monh, cmd, flowtable_print_json(ft));
+}
+
void monitor_print_rule_json(struct netlink_mon_handler *monh,
const char *cmd, struct rule *r)
{
diff --git a/src/monitor.c b/src/monitor.c
index 2fc16d6776a28..a787db8cbf5a3 100644
--- a/src/monitor.c
+++ b/src/monitor.c
@@ -127,6 +127,19 @@ struct nftnl_obj *netlink_obj_alloc(const struct nlmsghdr *nlh)
return nlo;
}
+struct nftnl_flowtable *netlink_flowtable_alloc(const struct nlmsghdr *nlh)
+{
+ struct nftnl_flowtable *nlf;
+
+ nlf = nftnl_flowtable_alloc();
+ if (nlf == NULL)
+ memory_allocation_error();
+ if (nftnl_flowtable_nlmsg_parse(nlh, nlf) < 0)
+ netlink_abi_error();
+
+ return nlf;
+}
+
static uint32_t netlink_msg2nftnl_of(uint32_t type, uint16_t flags)
{
switch (type) {
@@ -542,6 +555,50 @@ static int netlink_events_obj_cb(const struct nlmsghdr *nlh, int type,
return MNL_CB_OK;
}
+static int netlink_events_flowtable_cb(const struct nlmsghdr *nlh, int type,
+ struct netlink_mon_handler *monh)
+{
+ const char *family, *cmd;
+ struct nftnl_flowtable *nlf;
+ struct flowtable *ft;
+
+ nlf = netlink_flowtable_alloc(nlh);
+
+ ft = netlink_delinearize_flowtable(monh->ctx, nlf);
+ if (!ft) {
+ nftnl_flowtable_free(nlf);
+ return MNL_CB_ERROR;
+ }
+ family = family2str(ft->handle.family);
+ cmd = netlink_msg2cmd(type, nlh->nlmsg_flags);
+
+ switch (monh->format) {
+ case NFTNL_OUTPUT_DEFAULT:
+ nft_mon_print(monh, "%s ", cmd);
+
+ switch (type) {
+ case NFT_MSG_NEWFLOWTABLE:
+ flowtable_print_plain(ft, &monh->ctx->nft->output);
+ break;
+ case NFT_MSG_DELFLOWTABLE:
+ nft_mon_print(monh, "flowtable %s %s %s", family,
+ ft->handle.table.name,
+ ft->handle.flowtable.name);
+ break;
+ }
+ nft_mon_print(monh, "\n");
+ break;
+ case NFTNL_OUTPUT_JSON:
+ monitor_print_flowtable_json(monh, cmd, ft);
+ if (!nft_output_echo(&monh->ctx->nft->output))
+ nft_mon_print(monh, "\n");
+ break;
+ }
+ flowtable_free(ft);
+ nftnl_flowtable_free(nlf);
+ return MNL_CB_OK;
+}
+
static void rule_map_decompose_cb(struct set *s, void *data)
{
if (!set_is_anonymous(s->flags))
@@ -962,6 +1019,10 @@ static int netlink_events_cb(const struct nlmsghdr *nlh, void *data)
case NFT_MSG_DELOBJ:
ret = netlink_events_obj_cb(nlh, type, monh);
break;
+ case NFT_MSG_NEWFLOWTABLE:
+ case NFT_MSG_DELFLOWTABLE:
+ ret = netlink_events_flowtable_cb(nlh, type, monh);
+ break;
case NFT_MSG_NEWGEN:
ret = netlink_events_newgen_cb(nlh, type, monh);
break;
diff --git a/src/parser_json.c b/src/parser_json.c
index f8200db1fe114..bcc216e12e51c 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -4421,6 +4421,7 @@ static int json_echo_error(struct netlink_mon_handler *monh,
static uint64_t handle_from_nlmsg(const struct nlmsghdr *nlh)
{
+ struct nftnl_flowtable *nlf;
struct nftnl_table *nlt;
struct nftnl_chain *nlc;
struct nftnl_rule *nlr;
@@ -4457,6 +4458,11 @@ static uint64_t handle_from_nlmsg(const struct nlmsghdr *nlh)
handle = nftnl_obj_get_u64(nlo, NFTNL_OBJ_HANDLE);
nftnl_obj_free(nlo);
break;
+ case NFT_MSG_NEWFLOWTABLE:
+ nlf = netlink_flowtable_alloc(nlh);
+ handle = nftnl_flowtable_get_u64(nlf, NFTNL_FLOWTABLE_HANDLE);
+ nftnl_flowtable_free(nlf);
+ break;
}
return handle;
}
diff --git a/src/rule.c b/src/rule.c
index 9bc160ec0d888..dc6b9d89fc967 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -2155,6 +2155,21 @@ void flowtable_print(const struct flowtable *s, struct output_ctx *octx)
do_flowtable_print(s, &opts, octx);
}
+void flowtable_print_plain(const struct flowtable *ft, struct output_ctx *octx)
+{
+ struct print_fmt_options opts = {
+ .tab = "",
+ .nl = " ",
+ .table = ft->handle.table.name,
+ .family = family2str(ft->handle.family),
+ .stmt_separator = "; ",
+ };
+
+ flowtable_print_declaration(ft, &opts, octx);
+ nft_print(octx, "}");
+}
+
+
struct flowtable *flowtable_lookup_fuzzy(const char *ft_name,
const struct nft_cache *cache,
const struct table **t)
diff --git a/tests/monitor/testcases/flowtable-simple.t b/tests/monitor/testcases/flowtable-simple.t
new file mode 100644
index 0000000000000..df8eccbd91e0a
--- /dev/null
+++ b/tests/monitor/testcases/flowtable-simple.t
@@ -0,0 +1,10 @@
+# setup first
+I add table ip t
+I add flowtable ip t ft { hook ingress priority 0; devices = { lo }; }
+O -
+J {"add": {"table": {"family": "ip", "name": "t", "handle": 0}}}
+J {"add": {"flowtable": {"family": "ip", "name": "ft", "table": "t", "handle": 0, "hook": "ingress", "prio": 0, "dev": "lo"}}}
+
+I delete flowtable ip t ft
+O -
+J {"delete": {"flowtable": {"family": "ip", "name": "ft", "table": "t", "handle": 0, "hook": "ingress", "prio": 0, "dev": "lo"}}}
--
2.43.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [nft PATCH 4/9] tests: monitor: Run in own netns
2024-10-02 19:38 [nft PATCH 0/9] Support wildcard netdev hooks and events Phil Sutter
` (2 preceding siblings ...)
2024-10-02 19:38 ` [nft PATCH 3/9] monitor: Recognize flowtable add/del events Phil Sutter
@ 2024-10-02 19:38 ` Phil Sutter
2024-10-02 19:38 ` [nft PATCH 5/9] mnl: Support simple wildcards in netdev hooks Phil Sutter
` (6 subsequent siblings)
10 siblings, 0 replies; 14+ messages in thread
From: Phil Sutter @ 2024-10-02 19:38 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
Have the script call itself prefixed by unshare. This won't prevent
clashing test case contents, but at least leave the host netns alone.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
tests/monitor/run-tests.sh | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/tests/monitor/run-tests.sh b/tests/monitor/run-tests.sh
index f1ac790acf80c..214512d269e8d 100755
--- a/tests/monitor/run-tests.sh
+++ b/tests/monitor/run-tests.sh
@@ -120,6 +120,14 @@ echo_run_test() {
return $rc
}
+netns=true
+for arg in "$@"; do
+ [[ "$arg" == "--no-netns" ]] && netns=false
+done
+if $netns; then
+ exec unshare -n $0 --no-netns "$@"
+fi
+
testcases=""
while [ -n "$1" ]; do
case "$1" in
@@ -131,6 +139,9 @@ while [ -n "$1" ]; do
test_json=true
shift
;;
+ --no-netns)
+ shift
+ ;;
-H|--host)
nft=nft
shift
--
2.43.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [nft PATCH 5/9] mnl: Support simple wildcards in netdev hooks
2024-10-02 19:38 [nft PATCH 0/9] Support wildcard netdev hooks and events Phil Sutter
` (3 preceding siblings ...)
2024-10-02 19:38 ` [nft PATCH 4/9] tests: monitor: Run in own netns Phil Sutter
@ 2024-10-02 19:38 ` Phil Sutter
2024-10-02 19:38 ` [nft PATCH 6/9] parser_bison: Accept ASTERISK_STRING in flowtable_expr_member Phil Sutter
` (5 subsequent siblings)
10 siblings, 0 replies; 14+ messages in thread
From: Phil Sutter @ 2024-10-02 19:38 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
When building NFTA_FLOWTABLE_HOOK_DEVS, NFTA_HOOK_DEV or NFTA_HOOK_DEVS
attributes, detect trailing asterisks in interface names and reduce
attribute length accordingly. Kernel will use strncmp(), effectively
performing a prefix search this way.
Deserialization (i.e., appending asterisk to interface names which don't
include a trailing nul-char) happens in libnftnl.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
src/mnl.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/src/mnl.c b/src/mnl.c
index db53a60b43cb9..4faf027ce1027 100644
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -787,18 +787,24 @@ static void mnl_nft_chain_devs_build(struct nlmsghdr *nlh, struct cmd *cmd)
{
const struct expr *dev_expr = cmd->chain->dev_expr;
const struct nft_dev *dev_array;
+ int i, len, num_devs = 0;
struct nlattr *nest_dev;
- int i, num_devs = 0;
dev_array = nft_dev_array(dev_expr, &num_devs);
if (num_devs == 1) {
cmd_add_loc(cmd, nlh->nlmsg_len, dev_array[0].location);
- mnl_attr_put_strz(nlh, NFTA_HOOK_DEV, dev_array[0].ifname);
+ len = strlen(dev_array[0].ifname) + 1;
+ if (dev_array[0].ifname[len - 2] == '*')
+ len -= 2;
+ mnl_attr_put(nlh, NFTA_HOOK_DEV, len, dev_array[0].ifname);
} else {
nest_dev = mnl_attr_nest_start(nlh, NFTA_HOOK_DEVS);
for (i = 0; i < num_devs; i++) {
cmd_add_loc(cmd, nlh->nlmsg_len, dev_array[i].location);
- mnl_attr_put_strz(nlh, NFTA_DEVICE_NAME, dev_array[i].ifname);
+ len = strlen(dev_array[i].ifname) + 1;
+ if (dev_array[i].ifname[len - 2] == '*')
+ len -= 2;
+ mnl_attr_put(nlh, NFTA_DEVICE_NAME, len, dev_array[i].ifname);
mnl_attr_nest_end(nlh, nest_dev);
}
}
@@ -1999,14 +2005,17 @@ static void mnl_nft_ft_devs_build(struct nlmsghdr *nlh, struct cmd *cmd)
{
const struct expr *dev_expr = cmd->flowtable->dev_expr;
const struct nft_dev *dev_array;
+ int i, len, num_devs = 0;
struct nlattr *nest_dev;
- int i, num_devs= 0;
dev_array = nft_dev_array(dev_expr, &num_devs);
nest_dev = mnl_attr_nest_start(nlh, NFTA_FLOWTABLE_HOOK_DEVS);
for (i = 0; i < num_devs; i++) {
cmd_add_loc(cmd, nlh->nlmsg_len, dev_array[i].location);
- mnl_attr_put_strz(nlh, NFTA_DEVICE_NAME, dev_array[i].ifname);
+ len = strlen(dev_array[i].ifname) + 1;
+ if (dev_array[i].ifname[len - 2] == '*')
+ len -= 2;
+ mnl_attr_put(nlh, NFTA_DEVICE_NAME, len, dev_array[i].ifname);
}
mnl_attr_nest_end(nlh, nest_dev);
--
2.43.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [nft PATCH 6/9] parser_bison: Accept ASTERISK_STRING in flowtable_expr_member
2024-10-02 19:38 [nft PATCH 0/9] Support wildcard netdev hooks and events Phil Sutter
` (4 preceding siblings ...)
2024-10-02 19:38 ` [nft PATCH 5/9] mnl: Support simple wildcards in netdev hooks Phil Sutter
@ 2024-10-02 19:38 ` Phil Sutter
2024-10-02 19:38 ` [nft PATCH 7/9] tests: shell: Adjust to ifname-based flowtables Phil Sutter
` (4 subsequent siblings)
10 siblings, 0 replies; 14+ messages in thread
From: Phil Sutter @ 2024-10-02 19:38 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
All clauses are identical, so instead of adding a third one for
ASTERISK_STRING, use a single one for 'string' (which combines all three
variants).
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
src/parser_bison.y | 11 +----------
1 file changed, 1 insertion(+), 10 deletions(-)
diff --git a/src/parser_bison.y b/src/parser_bison.y
index e2936d10efe4c..d9cf2cd25c2f0 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -2477,16 +2477,7 @@ flowtable_list_expr : flowtable_expr_member
| flowtable_list_expr COMMA opt_newline
;
-flowtable_expr_member : QUOTED_STRING
- {
- struct expr *expr = ifname_expr_alloc(&@$, state->msgs, $1);
-
- if (!expr)
- YYERROR;
-
- $$ = expr;
- }
- | STRING
+flowtable_expr_member : string
{
struct expr *expr = ifname_expr_alloc(&@$, state->msgs, $1);
--
2.43.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [nft PATCH 7/9] tests: shell: Adjust to ifname-based flowtables
2024-10-02 19:38 [nft PATCH 0/9] Support wildcard netdev hooks and events Phil Sutter
` (5 preceding siblings ...)
2024-10-02 19:38 ` [nft PATCH 6/9] parser_bison: Accept ASTERISK_STRING in flowtable_expr_member Phil Sutter
@ 2024-10-02 19:38 ` Phil Sutter
2024-10-02 19:38 ` [nft PATCH 8/9] tests: monitor: Support running external commands Phil Sutter
` (3 subsequent siblings)
10 siblings, 0 replies; 14+ messages in thread
From: Phil Sutter @ 2024-10-02 19:38 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
Removed interfaces will remain in place in dumps. Also drop
transactions/0050rule_1 test entirely: It won't fail anymore as the
flowtable is accepted despite the non-existent interfaces and thus the
test as a whole does not work anymore.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
.../chains/dumps/netdev_chain_0.json-nft | 17 +++++++++++++++++
.../testcases/chains/dumps/netdev_chain_0.nft | 3 +++
.../netdev_chain_dormant_autoremove.json-nft | 5 ++++-
.../dumps/netdev_chain_dormant_autoremove.nft | 2 +-
.../dumps/0012flowtable_variable_0.json-nft | 10 ++++++++--
.../dumps/0012flowtable_variable_0.nft | 4 ++--
.../testcases/json/dumps/netdev.json-nft | 13 +++++++++++++
tests/shell/testcases/json/dumps/netdev.nft | 3 +++
.../listing/dumps/0020flowtable_0.json-nft | 6 ++++--
.../listing/dumps/0020flowtable_0.nft | 2 ++
tests/shell/testcases/transactions/0050rule_1 | 19 -------------------
.../transactions/dumps/0050rule_1.json-nft | 11 -----------
.../transactions/dumps/0050rule_1.nft | 0
13 files changed, 57 insertions(+), 38 deletions(-)
delete mode 100755 tests/shell/testcases/transactions/0050rule_1
delete mode 100644 tests/shell/testcases/transactions/dumps/0050rule_1.json-nft
delete mode 100644 tests/shell/testcases/transactions/dumps/0050rule_1.nft
diff --git a/tests/shell/testcases/chains/dumps/netdev_chain_0.json-nft b/tests/shell/testcases/chains/dumps/netdev_chain_0.json-nft
index 7d78bd6757034..13e9f6bb016f7 100644
--- a/tests/shell/testcases/chains/dumps/netdev_chain_0.json-nft
+++ b/tests/shell/testcases/chains/dumps/netdev_chain_0.json-nft
@@ -13,6 +13,23 @@
"name": "x",
"handle": 0
}
+ },
+ {
+ "chain": {
+ "family": "netdev",
+ "table": "x",
+ "name": "y",
+ "handle": 0,
+ "dev": [
+ "d0",
+ "d1",
+ "d2"
+ ],
+ "type": "filter",
+ "hook": "ingress",
+ "prio": 0,
+ "policy": "accept"
+ }
}
]
}
diff --git a/tests/shell/testcases/chains/dumps/netdev_chain_0.nft b/tests/shell/testcases/chains/dumps/netdev_chain_0.nft
index aa571e00885fe..6606d5bc3f608 100644
--- a/tests/shell/testcases/chains/dumps/netdev_chain_0.nft
+++ b/tests/shell/testcases/chains/dumps/netdev_chain_0.nft
@@ -1,2 +1,5 @@
table netdev x {
+ chain y {
+ type filter hook ingress devices = { d0, d1, d2 } priority filter; policy accept;
+ }
}
diff --git a/tests/shell/testcases/chains/dumps/netdev_chain_dormant_autoremove.json-nft b/tests/shell/testcases/chains/dumps/netdev_chain_dormant_autoremove.json-nft
index 9151d42f17d91..88b8958f4d86e 100644
--- a/tests/shell/testcases/chains/dumps/netdev_chain_dormant_autoremove.json-nft
+++ b/tests/shell/testcases/chains/dumps/netdev_chain_dormant_autoremove.json-nft
@@ -21,7 +21,10 @@
"table": "test",
"name": "ingress",
"handle": 0,
- "dev": "dummy1",
+ "dev": [
+ "dummy0",
+ "dummy1"
+ ],
"type": "filter",
"hook": "ingress",
"prio": 0,
diff --git a/tests/shell/testcases/chains/dumps/netdev_chain_dormant_autoremove.nft b/tests/shell/testcases/chains/dumps/netdev_chain_dormant_autoremove.nft
index aad7cb6337734..f4bd9556b3e03 100644
--- a/tests/shell/testcases/chains/dumps/netdev_chain_dormant_autoremove.nft
+++ b/tests/shell/testcases/chains/dumps/netdev_chain_dormant_autoremove.nft
@@ -2,6 +2,6 @@ table netdev test {
flags dormant
chain ingress {
- type filter hook ingress device "dummy1" priority filter; policy drop;
+ type filter hook ingress devices = { dummy0, dummy1 } priority filter; policy drop;
}
}
diff --git a/tests/shell/testcases/flowtable/dumps/0012flowtable_variable_0.json-nft b/tests/shell/testcases/flowtable/dumps/0012flowtable_variable_0.json-nft
index 10f1df98874ab..20da08fb2fc29 100644
--- a/tests/shell/testcases/flowtable/dumps/0012flowtable_variable_0.json-nft
+++ b/tests/shell/testcases/flowtable/dumps/0012flowtable_variable_0.json-nft
@@ -22,7 +22,10 @@
"handle": 0,
"hook": "ingress",
"prio": 0,
- "dev": "lo"
+ "dev": [
+ "dummy1",
+ "lo"
+ ]
}
},
{
@@ -40,7 +43,10 @@
"handle": 0,
"hook": "ingress",
"prio": 0,
- "dev": "lo"
+ "dev": [
+ "dummy1",
+ "lo"
+ ]
}
}
]
diff --git a/tests/shell/testcases/flowtable/dumps/0012flowtable_variable_0.nft b/tests/shell/testcases/flowtable/dumps/0012flowtable_variable_0.nft
index df1c51a247033..1cbb2f1103f03 100644
--- a/tests/shell/testcases/flowtable/dumps/0012flowtable_variable_0.nft
+++ b/tests/shell/testcases/flowtable/dumps/0012flowtable_variable_0.nft
@@ -1,14 +1,14 @@
table ip filter1 {
flowtable Main_ft1 {
hook ingress priority filter
- devices = { lo }
+ devices = { dummy1, lo }
counter
}
}
table ip filter2 {
flowtable Main_ft2 {
hook ingress priority filter
- devices = { lo }
+ devices = { dummy1, lo }
counter
}
}
diff --git a/tests/shell/testcases/json/dumps/netdev.json-nft b/tests/shell/testcases/json/dumps/netdev.json-nft
index e0d2bfb4385b7..6eb19a17b31d9 100644
--- a/tests/shell/testcases/json/dumps/netdev.json-nft
+++ b/tests/shell/testcases/json/dumps/netdev.json-nft
@@ -13,6 +13,19 @@
"name": "test_table",
"handle": 0
}
+ },
+ {
+ "chain": {
+ "family": "netdev",
+ "table": "test_table",
+ "name": "test_chain",
+ "handle": 0,
+ "dev": "d0",
+ "type": "filter",
+ "hook": "ingress",
+ "prio": 0,
+ "policy": "accept"
+ }
}
]
}
diff --git a/tests/shell/testcases/json/dumps/netdev.nft b/tests/shell/testcases/json/dumps/netdev.nft
index 3c568ed3eb38d..373ea0a46d600 100644
--- a/tests/shell/testcases/json/dumps/netdev.nft
+++ b/tests/shell/testcases/json/dumps/netdev.nft
@@ -1,2 +1,5 @@
table netdev test_table {
+ chain test_chain {
+ type filter hook ingress device "d0" priority filter; policy accept;
+ }
}
diff --git a/tests/shell/testcases/listing/dumps/0020flowtable_0.json-nft b/tests/shell/testcases/listing/dumps/0020flowtable_0.json-nft
index d511739abd4b6..b1b3a5fba34a0 100644
--- a/tests/shell/testcases/listing/dumps/0020flowtable_0.json-nft
+++ b/tests/shell/testcases/listing/dumps/0020flowtable_0.json-nft
@@ -32,7 +32,8 @@
"table": "filter",
"handle": 0,
"hook": "ingress",
- "prio": 0
+ "prio": 0,
+ "dev": "d0"
}
},
{
@@ -60,7 +61,8 @@
"table": "filter",
"handle": 0,
"hook": "ingress",
- "prio": 0
+ "prio": 0,
+ "dev": "d0"
}
}
]
diff --git a/tests/shell/testcases/listing/dumps/0020flowtable_0.nft b/tests/shell/testcases/listing/dumps/0020flowtable_0.nft
index 4a64e531db840..59fcbec8e5130 100644
--- a/tests/shell/testcases/listing/dumps/0020flowtable_0.nft
+++ b/tests/shell/testcases/listing/dumps/0020flowtable_0.nft
@@ -6,6 +6,7 @@ table inet filter {
flowtable f2 {
hook ingress priority filter
+ devices = { d0 }
}
}
table ip filter {
@@ -16,5 +17,6 @@ table ip filter {
flowtable f2 {
hook ingress priority filter
+ devices = { d0 }
}
}
diff --git a/tests/shell/testcases/transactions/0050rule_1 b/tests/shell/testcases/transactions/0050rule_1
deleted file mode 100755
index 89e5f42fc9f4d..0000000000000
--- a/tests/shell/testcases/transactions/0050rule_1
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/bash
-
-set -e
-
-RULESET="table inet filter {
- flowtable ftable {
- hook ingress priority 0; devices = { eno1, eno0, x };
- }
-
-chain forward {
- type filter hook forward priority 0; policy drop;
-
- ip protocol { tcp, udp } ct mark and 1 == 1 counter flow add @ftable
- ip6 nexthdr { tcp, udp } ct mark and 2 == 2 counter flow add @ftable
- ct mark and 30 == 30 ct state established,related log prefix \"nftables accept: \" level info accept
- }
-}"
-
-$NFT -f - <<< "$RULESET" >/dev/null || exit 0
diff --git a/tests/shell/testcases/transactions/dumps/0050rule_1.json-nft b/tests/shell/testcases/transactions/dumps/0050rule_1.json-nft
deleted file mode 100644
index 546cc5977db61..0000000000000
--- a/tests/shell/testcases/transactions/dumps/0050rule_1.json-nft
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "nftables": [
- {
- "metainfo": {
- "version": "VERSION",
- "release_name": "RELEASE_NAME",
- "json_schema_version": 1
- }
- }
- ]
-}
diff --git a/tests/shell/testcases/transactions/dumps/0050rule_1.nft b/tests/shell/testcases/transactions/dumps/0050rule_1.nft
deleted file mode 100644
index e69de29bb2d1d..0000000000000
--
2.43.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [nft PATCH 8/9] tests: monitor: Support running external commands
2024-10-02 19:38 [nft PATCH 0/9] Support wildcard netdev hooks and events Phil Sutter
` (6 preceding siblings ...)
2024-10-02 19:38 ` [nft PATCH 7/9] tests: shell: Adjust to ifname-based flowtables Phil Sutter
@ 2024-10-02 19:38 ` Phil Sutter
2024-10-02 19:38 ` [nft PATCH 9/9] monitor: Support NFT_MSG_(NEW|DEL)DEV events Phil Sutter
` (2 subsequent siblings)
10 siblings, 0 replies; 14+ messages in thread
From: Phil Sutter @ 2024-10-02 19:38 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
Accept '@'-prefixed lines mixed in between 'I'-prefixed ones and apply
nft input and run commands in specified ordering.
To keep things simple, ignore such test cases when in echo mode for now.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
tests/monitor/run-tests.sh | 61 ++++++++++++++++++++++++++++++++++----
1 file changed, 56 insertions(+), 5 deletions(-)
diff --git a/tests/monitor/run-tests.sh b/tests/monitor/run-tests.sh
index 214512d269e8d..36fc800c10520 100755
--- a/tests/monitor/run-tests.sh
+++ b/tests/monitor/run-tests.sh
@@ -59,6 +59,44 @@ json_output_filter() { # (filename)
# unify handle values
sed -i -e 's/\("handle":\) [0-9][0-9]*/\1 0/g' "$1"
}
+apply_commands_from_file() { # (command_file)
+ grep -q '^# run: ' $1 || {
+ $nft -f - <$1 || {
+ err "nft command failed!"
+ return 1
+ }
+ return 0
+ }
+ local nft_cmd=""
+ local sep=""
+ local line=""
+ while read line; do
+ [[ $line =~ ^#\ run: ]] || {
+ nft_cmd+="$sep$line"
+ sep="; "
+ continue
+ }
+ [[ -n $nft_cmd ]] && {
+ $nft -f - <<<"$nft_cmd" || {
+ err "nft command failed!"
+ return 1
+ }
+ }
+ nft_cmd=""
+ sep=""
+ ${line#\# run: } || {
+ err "custom command failed!"
+ return 1
+ }
+ done <$1
+ [[ -n $nft_cmd ]] && {
+ $nft -f - <<<"$nft_cmd" || {
+ err "nft command failed!"
+ return 1
+ }
+ }
+ return 0
+}
monitor_run_test() {
monitor_output=$(mktemp -p $testdir)
monitor_args=""
@@ -74,10 +112,7 @@ monitor_run_test() {
echo "command file:"
cat $command_file
}
- $nft -f - <$command_file || {
- err "nft command failed!"
- rc=1
- }
+ apply_commands_from_file $command_file || rc=1
sleep 0.5
kill $monitor_pid
wait >/dev/null 2>&1
@@ -103,6 +138,17 @@ echo_run_test() {
echo "command file:"
cat $command_file
}
+ grep -q '^# run: ' $command_file && {
+ $debug && {
+ echo "skipping unsuitable test case in command file:"
+ cat $command_file
+ }
+ rm $command_file
+ rm $output_file
+ touch $command_file
+ touch $output_file
+ return 0
+ }
$nft -nn -e -f - <$command_file >$echo_output || {
err "nft command failed!"
rc=1
@@ -182,18 +228,23 @@ for variant in $variants; do
# O add table ip t
# I add chain ip t c
# O add chain ip t c
+ # I <nft input1>
+ # @ <command to run after nft input1>
+ # I <nft input2>
+ # O ...
$nft flush ruleset
input_complete=false
while read dir line; do
case $dir in
- I)
+ I|@)
$input_complete && {
$run_test
let "rc += $?"
}
input_complete=false
+ [[ $dir == '@' ]] && line="# run: $line"
cmd_append "$line"
;;
O)
--
2.43.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [nft PATCH 9/9] monitor: Support NFT_MSG_(NEW|DEL)DEV events
2024-10-02 19:38 [nft PATCH 0/9] Support wildcard netdev hooks and events Phil Sutter
` (7 preceding siblings ...)
2024-10-02 19:38 ` [nft PATCH 8/9] tests: monitor: Support running external commands Phil Sutter
@ 2024-10-02 19:38 ` Phil Sutter
2024-10-02 19:55 ` Phil Sutter
2024-10-31 22:08 ` [nft PATCH 0/9] Support wildcard netdev hooks and events Florian Westphal
2024-11-06 10:01 ` Phil Sutter
10 siblings, 1 reply; 14+ messages in thread
From: Phil Sutter @ 2024-10-02 19:38 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
Kernels with name-based netdev hooks emit these messages when a device
is added to or removed from an existing flowtable or netdev-family
base-chain.
This patch depends on respective support code in libnftnl.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
include/json.h | 10 ++++
include/linux/netfilter/nf_tables.h | 10 ++++
src/json.c | 27 +++++++++
src/monitor.c | 64 +++++++++++++++++++++
tests/monitor/testcases/chain-netdev.t | 66 ++++++++++++++++++++++
tests/monitor/testcases/flowtable-simple.t | 56 ++++++++++++++++++
6 files changed, 233 insertions(+)
create mode 100644 tests/monitor/testcases/chain-netdev.t
diff --git a/include/json.h b/include/json.h
index 0670b8714519b..10a75ba050a6c 100644
--- a/include/json.h
+++ b/include/json.h
@@ -20,6 +20,7 @@ struct nft_ctx;
struct location;
struct output_ctx;
struct list_head;
+struct nftnl_device;
#ifdef HAVE_LIBJANSSON
@@ -118,6 +119,8 @@ void monitor_print_flowtable_json(struct netlink_mon_handler *monh,
const char *cmd, struct flowtable *ft);
void monitor_print_rule_json(struct netlink_mon_handler *monh,
const char *cmd, struct rule *r);
+void monitor_print_device_json(struct netlink_mon_handler *monh,
+ const char *cmd, struct nftnl_device *nld);
int json_events_cb(const struct nlmsghdr *nlh,
struct netlink_mon_handler *monh);
@@ -270,6 +273,13 @@ static inline void monitor_print_rule_json(struct netlink_mon_handler *monh,
/* empty */
}
+static inline void
+monitor_print_device_json(struct netlink_mon_handler *monh,
+ const char *cmd, struct nftnl_device *nld)
+{
+ /* empty */
+}
+
static inline int json_events_cb(const struct nlmsghdr *nlh,
struct netlink_mon_handler *monh)
{
diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
index c62e6ac563988..206d90b190951 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -142,6 +142,8 @@ enum nf_tables_msg_types {
NFT_MSG_DESTROYOBJ,
NFT_MSG_DESTROYFLOWTABLE,
NFT_MSG_GETSETELEM_RESET,
+ NFT_MSG_NEWDEV,
+ NFT_MSG_DELDEV,
NFT_MSG_MAX,
};
@@ -1761,10 +1763,18 @@ enum nft_synproxy_attributes {
* enum nft_device_attributes - nf_tables device netlink attributes
*
* @NFTA_DEVICE_NAME: name of this device (NLA_STRING)
+ * @NFTA_DEVICE_TABLE: table containing the flowtable or chain hooking into the device (NLA_STRING)
+ * @NFTA_DEVICE_FLOWTABLE: flowtable hooking into the device (NLA_STRING)
+ * @NFTA_DEVICE_CHAIN: chain hooking into the device (NLA_STRING)
+ * @NFTA_DEVICE_SPEC: hook spec matching the device (NLA_STRING)
*/
enum nft_devices_attributes {
NFTA_DEVICE_UNSPEC,
NFTA_DEVICE_NAME,
+ NFTA_DEVICE_TABLE,
+ NFTA_DEVICE_FLOWTABLE,
+ NFTA_DEVICE_CHAIN,
+ NFTA_DEVICE_SPEC,
__NFTA_DEVICE_MAX
};
#define NFTA_DEVICE_MAX (__NFTA_DEVICE_MAX - 1)
diff --git a/src/json.c b/src/json.c
index 64a6888f9e0ac..02f21bb6b0d92 100644
--- a/src/json.c
+++ b/src/json.c
@@ -17,6 +17,8 @@
#include <rt.h>
#include "nftutils.h"
+#include <libnftnl/device.h>
+
#include <netdb.h>
#include <netinet/icmp6.h>
#include <netinet/in.h>
@@ -2122,6 +2124,31 @@ void monitor_print_rule_json(struct netlink_mon_handler *monh,
monitor_print_json(monh, cmd, rule_print_json(octx, r));
}
+void monitor_print_device_json(struct netlink_mon_handler *monh,
+ const char *cmd, struct nftnl_device *nld)
+{
+ int32_t family = nftnl_device_get_s32(nld, NFTNL_DEVICE_FAMILY);
+ const char *key, *val;
+ json_t *root;
+
+ if (nftnl_device_is_set(nld, NFTNL_DEVICE_CHAIN)) {
+ key = "chain";
+ val = nftnl_device_get_str(nld, NFTNL_DEVICE_CHAIN);
+ } else if (nftnl_device_is_set(nld, NFTNL_DEVICE_FLOWTABLE)) {
+ key = "flowtable";
+ val = nftnl_device_get_str(nld, NFTNL_DEVICE_FLOWTABLE);
+ } else {
+ return;
+ }
+ root = json_pack("{s:{s:s, s:s, s:s, s:s, s:s}}", "device",
+ "family", family2str(family),
+ "table", nftnl_device_get_str(nld, NFTNL_DEVICE_TABLE),
+ key, val,
+ "name", nftnl_device_get_str(nld, NFTNL_DEVICE_NAME),
+ "spec", nftnl_device_get_str(nld, NFTNL_DEVICE_SPEC));
+ monitor_print_json(monh, cmd, root);
+}
+
void json_alloc_echo(struct nft_ctx *nft)
{
nft->json_echo = json_array();
diff --git a/src/monitor.c b/src/monitor.c
index a787db8cbf5a3..3d53f62a61280 100644
--- a/src/monitor.c
+++ b/src/monitor.c
@@ -25,6 +25,7 @@
#include <libnftnl/udata.h>
#include <libnftnl/ruleset.h>
#include <libnftnl/common.h>
+#include <libnftnl/device.h>
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nf_tables.h>
#include <linux/netfilter.h>
@@ -154,6 +155,7 @@ static uint32_t netlink_msg2nftnl_of(uint32_t type, uint16_t flags)
case NFT_MSG_NEWSETELEM:
case NFT_MSG_NEWOBJ:
case NFT_MSG_NEWFLOWTABLE:
+ case NFT_MSG_NEWDEV:
if (flags & NLM_F_EXCL)
return NFT_OF_EVENT_CREATE;
else
@@ -165,6 +167,7 @@ static uint32_t netlink_msg2nftnl_of(uint32_t type, uint16_t flags)
case NFT_MSG_DELRULE:
case NFT_MSG_DELOBJ:
case NFT_MSG_DELFLOWTABLE:
+ case NFT_MSG_DELDEV:
return NFTNL_OF_EVENT_DEL;
}
@@ -599,6 +602,61 @@ static int netlink_events_flowtable_cb(const struct nlmsghdr *nlh, int type,
return MNL_CB_OK;
}
+static struct nftnl_device *netlink_device_alloc(const struct nlmsghdr *nlh)
+{
+ struct nftnl_device *nld;
+
+ nld = nftnl_device_alloc();
+ if (nld == NULL)
+ memory_allocation_error();
+ if (nftnl_device_nlmsg_parse(nlh, nld) < 0)
+ netlink_abi_error();
+
+ return nld;
+}
+
+static int netlink_events_dev_cb(const struct nlmsghdr *nlh, int type,
+ struct netlink_mon_handler *monh)
+{
+ struct nftnl_device *nld = netlink_device_alloc(nlh);
+ const char *cmd, *obj;
+ uint32_t objattr;
+ int32_t family;
+
+ if (nftnl_device_is_set(nld, NFTNL_DEVICE_CHAIN)) {
+ objattr = NFTNL_DEVICE_CHAIN;
+ obj = "chain";
+ } else if (nftnl_device_is_set(nld, NFTNL_DEVICE_FLOWTABLE)) {
+ objattr = NFTNL_DEVICE_FLOWTABLE;
+ obj = "flowtable";
+ } else {
+ return MNL_CB_ERROR;
+ }
+
+ cmd = netlink_msg2cmd(type, nlh->nlmsg_flags);
+ family = nftnl_device_get_s32(nld, NFTNL_DEVICE_FAMILY);
+
+ switch (monh->format) {
+ case NFTNL_OUTPUT_DEFAULT:
+ nft_mon_print(monh, "%s device %s %s %s %s hook %s { %s }",
+ cmd, obj, family2str(family),
+ nftnl_device_get_str(nld, NFTNL_DEVICE_TABLE),
+ nftnl_device_get_str(nld, objattr),
+ nftnl_device_get_str(nld, NFTNL_DEVICE_SPEC),
+ nftnl_device_get_str(nld, NFTNL_DEVICE_NAME));
+ nft_mon_print(monh, "\n");
+ break;
+ case NFTNL_OUTPUT_JSON:
+ monitor_print_device_json(monh, cmd, nld);
+ if (!nft_output_echo(&monh->ctx->nft->output))
+ nft_mon_print(monh, "\n");
+ break;
+ }
+
+ nftnl_device_free(nld);
+ return MNL_CB_OK;
+}
+
static void rule_map_decompose_cb(struct set *s, void *data)
{
if (!set_is_anonymous(s->flags))
@@ -921,6 +979,8 @@ static const char *const nftnl_msg_types[NFT_MSG_MAX] = {
[NFT_MSG_NEWGEN] = "NFT_MSG_NEWGEN",
[NFT_MSG_NEWOBJ] = "NFT_MSG_NEWOBJ",
[NFT_MSG_DELOBJ] = "NFT_MSG_DELOBJ",
+ [NFT_MSG_NEWDEV] = "NFT_MSG_NEWDEV",
+ [NFT_MSG_DELDEV] = "NFT_MSG_DELDEV",
};
static const char *nftnl_msgtype2str(uint16_t type)
@@ -1026,6 +1086,10 @@ static int netlink_events_cb(const struct nlmsghdr *nlh, void *data)
case NFT_MSG_NEWGEN:
ret = netlink_events_newgen_cb(nlh, type, monh);
break;
+ case NFT_MSG_NEWDEV:
+ case NFT_MSG_DELDEV:
+ ret = netlink_events_dev_cb(nlh, type, monh);
+ break;
}
return ret;
diff --git a/tests/monitor/testcases/chain-netdev.t b/tests/monitor/testcases/chain-netdev.t
new file mode 100644
index 0000000000000..3c004af0cd855
--- /dev/null
+++ b/tests/monitor/testcases/chain-netdev.t
@@ -0,0 +1,66 @@
+# setup first
+I add table netdev t
+I add chain netdev t c { type filter hook ingress devices = { lo } priority 0; policy accept; }
+O -
+J {"add": {"table": {"family": "netdev", "name": "t", "handle": 0}}}
+J {"add": {"chain": {"family": "netdev", "table": "t", "name": "c", "handle": 0, "dev": "lo", "type": "filter", "hook": "ingress", "prio": 0, "policy": "accept"}}}
+
+I delete chain netdev t c
+O delete chain netdev t c { type filter hook ingress devices = { lo } priority 0; policy accept; }
+J {"delete": {"chain": {"family": "netdev", "table": "t", "name": "c", "handle": 0, "dev": "lo", "type": "filter", "hook": "ingress", "prio": 0, "policy": "accept"}}}
+
+I add chain netdev t c { type filter hook ingress devices = { eth1337, lo } priority 0; policy accept; }
+O -
+J {"add": {"chain": {"family": "netdev", "table": "t", "name": "c", "handle": 0, "dev": ["eth1337", "lo"], "type": "filter", "hook": "ingress", "prio": 0, "policy": "accept"}}}
+
+@ ip link add eth1337 type dummy
+O add device chain netdev t c hook eth1337 { eth1337 }
+J {"add": {"device": {"family": "netdev", "table": "t", "chain": "c", "name": "eth1337", "spec": "eth1337"}}}
+
+@ ip link del eth1337
+O delete device chain netdev t c hook eth1337 { eth1337 }
+J {"delete": {"device": {"family": "netdev", "table": "t", "chain": "c", "name": "eth1337", "spec": "eth1337"}}}
+
+I delete chain netdev t c
+O delete chain netdev t c { type filter hook ingress devices = { eth1337, lo } priority 0; policy accept; }
+J {"delete": {"chain": {"family": "netdev", "table": "t", "name": "c", "handle": 0, "dev": ["eth1337", "lo"], "type": "filter", "hook": "ingress", "prio": 0, "policy": "accept"}}}
+
+I add chain netdev t c { type filter hook ingress devices = { wild* } priority 0; }
+@ ip link add wild23 type dummy
+@ ip link add wild42 type dummy
+@ ip link del wild23
+I delete chain netdev t c
+O add chain netdev t c { type filter hook ingress devices = { wild* } priority 0; policy accept; }
+O add device chain netdev t c hook wild* { wild23 }
+O add device chain netdev t c hook wild* { wild42 }
+O delete device chain netdev t c hook wild* { wild23 }
+O delete chain netdev t c { type filter hook ingress devices = { wild* } priority 0; policy accept; }
+J {"add": {"chain": {"family": "netdev", "table": "t", "name": "c", "handle": 0, "dev": "wild*", "type": "filter", "hook": "ingress", "prio": 0, "policy": "accept"}}}
+J {"add": {"device": {"family": "netdev", "table": "t", "chain": "c", "name": "wild23", "spec": "wild*"}}}
+J {"add": {"device": {"family": "netdev", "table": "t", "chain": "c", "name": "wild42", "spec": "wild*"}}}
+J {"delete": {"device": {"family": "netdev", "table": "t", "chain": "c", "name": "wild23", "spec": "wild*"}}}
+J {"delete": {"chain": {"family": "netdev", "table": "t", "name": "c", "handle": 0, "dev": "wild*", "type": "filter", "hook": "ingress", "prio": 0, "policy": "accept"}}}
+
+I add chain netdev t c { type filter hook ingress devices = { wild* } priority 0; }
+I add chain netdev t c2 { type filter hook ingress devices = { wald* } priority 0; }
+@ ip link add wild23 type dummy
+@ ip link set wild42 name wald42
+@ ip link del wild23
+I delete chain netdev t c
+I delete chain netdev t c2
+O add chain netdev t c { type filter hook ingress devices = { wild* } priority 0; policy accept; }
+O add chain netdev t c2 { type filter hook ingress devices = { wald* } priority 0; policy accept; }
+O add device chain netdev t c hook wild* { wild23 }
+O add device chain netdev t c2 hook wald* { wald42 }
+O delete device chain netdev t c hook wild* { wald42 }
+O delete device chain netdev t c hook wild* { wild23 }
+O delete chain netdev t c { type filter hook ingress devices = { wild* } priority 0; policy accept; }
+O delete chain netdev t c2 { type filter hook ingress devices = { wald* } priority 0; policy accept; }
+J {"add": {"chain": {"family": "netdev", "table": "t", "name": "c", "handle": 0, "dev": "wild*", "type": "filter", "hook": "ingress", "prio": 0, "policy": "accept"}}}
+J {"add": {"chain": {"family": "netdev", "table": "t", "name": "c2", "handle": 0, "dev": "wald*", "type": "filter", "hook": "ingress", "prio": 0, "policy": "accept"}}}
+J {"add": {"device": {"family": "netdev", "table": "t", "chain": "c", "name": "wild23", "spec": "wild*"}}}
+J {"add": {"device": {"family": "netdev", "table": "t", "chain": "c2", "name": "wald42", "spec": "wald*"}}}
+J {"delete": {"device": {"family": "netdev", "table": "t", "chain": "c", "name": "wald42", "spec": "wild*"}}}
+J {"delete": {"device": {"family": "netdev", "table": "t", "chain": "c", "name": "wild23", "spec": "wild*"}}}
+J {"delete": {"chain": {"family": "netdev", "table": "t", "name": "c", "handle": 0, "dev": "wild*", "type": "filter", "hook": "ingress", "prio": 0, "policy": "accept"}}}
+J {"delete": {"chain": {"family": "netdev", "table": "t", "name": "c2", "handle": 0, "dev": "wald*", "type": "filter", "hook": "ingress", "prio": 0, "policy": "accept"}}}
diff --git a/tests/monitor/testcases/flowtable-simple.t b/tests/monitor/testcases/flowtable-simple.t
index df8eccbd91e0a..113b15f20d1dc 100644
--- a/tests/monitor/testcases/flowtable-simple.t
+++ b/tests/monitor/testcases/flowtable-simple.t
@@ -8,3 +8,59 @@ J {"add": {"flowtable": {"family": "ip", "name": "ft", "table": "t", "handle": 0
I delete flowtable ip t ft
O -
J {"delete": {"flowtable": {"family": "ip", "name": "ft", "table": "t", "handle": 0, "hook": "ingress", "prio": 0, "dev": "lo"}}}
+
+I add flowtable ip t ft { hook ingress priority 0; devices = { eth1337, lo }; }
+O -
+J {"add": {"flowtable": {"family": "ip", "name": "ft", "table": "t", "handle": 0, "hook": "ingress", "prio": 0, "dev": ["eth1337", "lo"]}}}
+
+@ ip link add eth1337 type dummy
+O add device flowtable ip t ft hook eth1337 { eth1337 }
+J {"add": {"device": {"family": "ip", "table": "t", "flowtable": "ft", "name": "eth1337", "spec": "eth1337"}}}
+
+@ ip link del eth1337
+O delete device flowtable ip t ft hook eth1337 { eth1337 }
+J {"delete": {"device": {"family": "ip", "table": "t", "flowtable": "ft", "name": "eth1337", "spec": "eth1337"}}}
+
+I delete flowtable ip t ft
+O -
+J {"delete": {"flowtable": {"family": "ip", "name": "ft", "table": "t", "handle": 0, "hook": "ingress", "prio": 0, "dev": ["eth1337", "lo"]}}}
+
+I add flowtable ip t ft { hook ingress priority 0; devices = { wild* }; }
+@ ip link add wild23 type dummy
+@ ip link add wild42 type dummy
+@ ip link del wild23
+I delete flowtable ip t ft
+O add flowtable ip t ft { hook ingress priority 0; devices = { wild* }; }
+O add device flowtable ip t ft hook wild* { wild23 }
+O add device flowtable ip t ft hook wild* { wild42 }
+O delete device flowtable ip t ft hook wild* { wild23 }
+O delete flowtable ip t ft
+J {"add": {"flowtable": {"family": "ip", "name": "ft", "table": "t", "handle": 0, "hook": "ingress", "prio": 0, "dev": "wild*"}}}
+J {"add": {"device": {"family": "ip", "table": "t", "flowtable": "ft", "name": "wild23", "spec": "wild*"}}}
+J {"add": {"device": {"family": "ip", "table": "t", "flowtable": "ft", "name": "wild42", "spec": "wild*"}}}
+J {"delete": {"device": {"family": "ip", "table": "t", "flowtable": "ft", "name": "wild23", "spec": "wild*"}}}
+J {"delete": {"flowtable": {"family": "ip", "name": "ft", "table": "t", "handle": 0, "hook": "ingress", "prio": 0, "dev": "wild*"}}}
+
+I add flowtable ip t ft { hook ingress priority 0; devices = { wild* }; }
+I add flowtable ip t ft2 { hook ingress priority 0; devices = { wald* }; }
+@ ip link add wild23 type dummy
+@ ip link set wild42 name wald42
+@ ip link del wild23
+I delete flowtable ip t ft
+I delete flowtable ip t ft2
+O add flowtable ip t ft { hook ingress priority 0; devices = { wild* }; }
+O add flowtable ip t ft2 { hook ingress priority 0; devices = { wald* }; }
+O add device flowtable ip t ft hook wild* { wild23 }
+O add device flowtable ip t ft2 hook wald* { wald42 }
+O delete device flowtable ip t ft hook wild* { wald42 }
+O delete device flowtable ip t ft hook wild* { wild23 }
+O delete flowtable ip t ft
+O delete flowtable ip t ft2
+J {"add": {"flowtable": {"family": "ip", "name": "ft", "table": "t", "handle": 0, "hook": "ingress", "prio": 0, "dev": "wild*"}}}
+J {"add": {"flowtable": {"family": "ip", "name": "ft2", "table": "t", "handle": 0, "hook": "ingress", "prio": 0, "dev": "wald*"}}}
+J {"add": {"device": {"family": "ip", "table": "t", "flowtable": "ft", "name": "wild23", "spec": "wild*"}}}
+J {"add": {"device": {"family": "ip", "table": "t", "flowtable": "ft2", "name": "wald42", "spec": "wald*"}}}
+J {"delete": {"device": {"family": "ip", "table": "t", "flowtable": "ft", "name": "wald42", "spec": "wild*"}}}
+J {"delete": {"device": {"family": "ip", "table": "t", "flowtable": "ft", "name": "wild23", "spec": "wild*"}}}
+J {"delete": {"flowtable": {"family": "ip", "name": "ft", "table": "t", "handle": 0, "hook": "ingress", "prio": 0, "dev": "wild*"}}}
+J {"delete": {"flowtable": {"family": "ip", "name": "ft2", "table": "t", "handle": 0, "hook": "ingress", "prio": 0, "dev": "wald*"}}}
--
2.43.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [nft PATCH 9/9] monitor: Support NFT_MSG_(NEW|DEL)DEV events
2024-10-02 19:38 ` [nft PATCH 9/9] monitor: Support NFT_MSG_(NEW|DEL)DEV events Phil Sutter
@ 2024-10-02 19:55 ` Phil Sutter
0 siblings, 0 replies; 14+ messages in thread
From: Phil Sutter @ 2024-10-02 19:55 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
On Wed, Oct 02, 2024 at 09:38:53PM +0200, Phil Sutter wrote:
[...]
> tests/monitor/testcases/chain-netdev.t | 66 ++++++++++++++++++++++
> tests/monitor/testcases/flowtable-simple.t | 56 ++++++++++++++++++
And as foretold in patch 4, the new chain-netdev.t clashes with similar
content in flowtable-simple.t. To avoid this, both need a trivial
adjustment:
diff --git a/tests/monitor/testcases/chain-netdev.t b/tests/monitor/testcases/chain-netdev.t
index 3c004af0cd855..414040045dd20 100644
--- a/tests/monitor/testcases/chain-netdev.t
+++ b/tests/monitor/testcases/chain-netdev.t
@@ -48,6 +48,7 @@ I add chain netdev t c2 { type filter hook ingress devices = { wald* } priority
@ ip link del wild23
I delete chain netdev t c
I delete chain netdev t c2
+@ ip link del wald42
O add chain netdev t c { type filter hook ingress devices = { wild* } priority 0; policy accept; }
O add chain netdev t c2 { type filter hook ingress devices = { wald* } priority 0; policy accept; }
O add device chain netdev t c hook wild* { wild23 }
diff --git a/tests/monitor/testcases/flowtable-simple.t b/tests/monitor/testcases/flowtable-simple.t
index 113b15f20d1dc..2c82f4907ed93 100644
--- a/tests/monitor/testcases/flowtable-simple.t
+++ b/tests/monitor/testcases/flowtable-simple.t
@@ -48,6 +48,7 @@ I add flowtable ip t ft2 { hook ingress priority 0; devices = { wald* }; }
@ ip link del wild23
I delete flowtable ip t ft
I delete flowtable ip t ft2
+@ ip link del wald42
O add flowtable ip t ft { hook ingress priority 0; devices = { wild* }; }
O add flowtable ip t ft2 { hook ingress priority 0; devices = { wald* }; }
O add device flowtable ip t ft hook wild* { wild23 }
I'll wait for feedback before including this in a v2.
Sorry for the mess.
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [nft PATCH 0/9] Support wildcard netdev hooks and events
2024-10-02 19:38 [nft PATCH 0/9] Support wildcard netdev hooks and events Phil Sutter
` (8 preceding siblings ...)
2024-10-02 19:38 ` [nft PATCH 9/9] monitor: Support NFT_MSG_(NEW|DEL)DEV events Phil Sutter
@ 2024-10-31 22:08 ` Florian Westphal
2024-10-31 22:13 ` Pablo Neira Ayuso
2024-11-06 10:01 ` Phil Sutter
10 siblings, 1 reply; 14+ messages in thread
From: Florian Westphal @ 2024-10-31 22:08 UTC (permalink / raw)
To: Phil Sutter; +Cc: Pablo Neira Ayuso, netfilter-devel
Phil Sutter <phil@nwl.cc> wrote:
> This series is the second (and last?) step of enabling support for
> name-based and wildcard interface hooks in user space. It depends on the
> previously sent series for libnftnl.
>
> Patches 1-4 are fallout, fixing for deficits in different areas.
These look good, happy to see typeof support on json side, feel free to
push them out.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [nft PATCH 0/9] Support wildcard netdev hooks and events
2024-10-31 22:08 ` [nft PATCH 0/9] Support wildcard netdev hooks and events Florian Westphal
@ 2024-10-31 22:13 ` Pablo Neira Ayuso
0 siblings, 0 replies; 14+ messages in thread
From: Pablo Neira Ayuso @ 2024-10-31 22:13 UTC (permalink / raw)
To: Florian Westphal; +Cc: Phil Sutter, netfilter-devel
On Thu, Oct 31, 2024 at 11:08:23PM +0100, Florian Westphal wrote:
> Phil Sutter <phil@nwl.cc> wrote:
> > This series is the second (and last?) step of enabling support for
> > name-based and wildcard interface hooks in user space. It depends on the
> > previously sent series for libnftnl.
> >
> > Patches 1-4 are fallout, fixing for deficits in different areas.
>
> These look good, happy to see typeof support on json side, feel free to
> push them out.
Ack for 1-4 in this series, thanks.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [nft PATCH 0/9] Support wildcard netdev hooks and events
2024-10-02 19:38 [nft PATCH 0/9] Support wildcard netdev hooks and events Phil Sutter
` (9 preceding siblings ...)
2024-10-31 22:08 ` [nft PATCH 0/9] Support wildcard netdev hooks and events Florian Westphal
@ 2024-11-06 10:01 ` Phil Sutter
10 siblings, 0 replies; 14+ messages in thread
From: Phil Sutter @ 2024-11-06 10:01 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
On Wed, Oct 02, 2024 at 09:38:44PM +0200, Phil Sutter wrote:
> This series is the second (and last?) step of enabling support for
> name-based and wildcard interface hooks in user space. It depends on the
> previously sent series for libnftnl.
>
> Patches 1-4 are fallout, fixing for deficits in different areas.
Applied these four patches.
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2024-11-06 10:01 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-10-02 19:38 [nft PATCH 0/9] Support wildcard netdev hooks and events Phil Sutter
2024-10-02 19:38 ` [nft PATCH 1/9] json: Support typeof in set and map types Phil Sutter
2024-10-02 19:38 ` [nft PATCH 2/9] tests: py: Fix for storing payload into missing file Phil Sutter
2024-10-02 19:38 ` [nft PATCH 3/9] monitor: Recognize flowtable add/del events Phil Sutter
2024-10-02 19:38 ` [nft PATCH 4/9] tests: monitor: Run in own netns Phil Sutter
2024-10-02 19:38 ` [nft PATCH 5/9] mnl: Support simple wildcards in netdev hooks Phil Sutter
2024-10-02 19:38 ` [nft PATCH 6/9] parser_bison: Accept ASTERISK_STRING in flowtable_expr_member Phil Sutter
2024-10-02 19:38 ` [nft PATCH 7/9] tests: shell: Adjust to ifname-based flowtables Phil Sutter
2024-10-02 19:38 ` [nft PATCH 8/9] tests: monitor: Support running external commands Phil Sutter
2024-10-02 19:38 ` [nft PATCH 9/9] monitor: Support NFT_MSG_(NEW|DEL)DEV events Phil Sutter
2024-10-02 19:55 ` Phil Sutter
2024-10-31 22:08 ` [nft PATCH 0/9] Support wildcard netdev hooks and events Florian Westphal
2024-10-31 22:13 ` Pablo Neira Ayuso
2024-11-06 10:01 ` Phil Sutter
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).