]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
monitor: Recognize flowtable add/del events
authorPhil Sutter <phil@nwl.cc>
Wed, 15 May 2024 14:01:20 +0000 (16:01 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Wed, 13 Aug 2025 17:54:46 +0000 (19:54 +0200)
commit 73a8adfc2432ec8337288cc90e7c9f4509139846 upstream.

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
include/netlink.h
include/rule.h
src/json.c
src/monitor.c
src/parser_json.c
src/rule.c
tests/monitor/testcases/flowtable-simple.t [new file with mode: 0644]

index 1047c88d233ac6c7967a2599e261167af02fadc1..c8eca4d891c51c0b5a59c7a938a09d1fdde9f860 100644 (file)
@@ -11,6 +11,7 @@ struct nlmsghdr;
 struct rule;
 struct set;
 struct obj;
+struct flowtable;
 struct stmt;
 struct symbol_table;
 struct table;
@@ -112,6 +113,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);
 
@@ -252,6 +255,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)
 {
index 2777963457aa8eb7a13d86750d0272c48322382a..e7d36ac6fe287c4d6411198454c581ad63799f81 100644 (file)
@@ -89,6 +89,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 {
index 4fae9eec25b23a93d7e579ee3e6f236aaeae87f5..15bdce4770d27a2243d23484b7418b0846fb7114 100644 (file)
@@ -546,6 +546,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
index bae3fd5f4f6edc276c8e1533330b34f0fe0de8f6..70f754807b5a0ca1e4f926424369128cf767963d 100644 (file)
@@ -2122,6 +2122,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)
 {
index d5b8ac838d2cd40aae4d8833a397515f3e660321..8bca166bee96abb71c47557ab57bc09cdbf2ef6c 100644 (file)
@@ -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) {
@@ -539,6 +552,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))
@@ -958,6 +1015,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;
index 65a52a10d87eb4363b646a688c88a7c5cacc36a3..a4481aed4600d8c32aebfcd6ac515dfe424f9e50 100644 (file)
@@ -4293,6 +4293,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;
@@ -4329,6 +4330,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;
 }
index e24f7f274ddd2fd6a172a8a68a099a122e405cb9..1734f07b46cfb0087c1f5b1625e1372c4bbfd90c 100644 (file)
@@ -2317,6 +2317,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 (file)
index 0000000..df8eccb
--- /dev/null
@@ -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"}}}