netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Phil Sutter <phil@nwl.cc>
To: Pablo Neira Ayuso <pablo@netfilter.org>
Cc: netfilter-devel@vger.kernel.org
Subject: [nft PATCH 3/9] monitor: Recognize flowtable add/del events
Date: Wed,  2 Oct 2024 21:38:47 +0200	[thread overview]
Message-ID: <20241002193853.13818-4-phil@nwl.cc> (raw)
In-Reply-To: <20241002193853.13818-1-phil@nwl.cc>

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


  parent reply	other threads:[~2024-10-02 19:38 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20241002193853.13818-4-phil@nwl.cc \
    --to=phil@nwl.cc \
    --cc=netfilter-devel@vger.kernel.org \
    --cc=pablo@netfilter.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).