]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
src: flowtable: add support for delete command by handle
authorEric Jallot <ejallot@gmail.com>
Mon, 4 Nov 2019 20:23:59 +0000 (21:23 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Wed, 6 Nov 2019 11:38:24 +0000 (12:38 +0100)
Also, display handle when listing with '-a'.

Signed-off-by: Eric Jallot <ejallot@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
doc/libnftables-json.adoc
doc/nft.txt
src/json.c
src/mnl.c
src/netlink.c
src/parser_bison.y
src/parser_json.c
src/rule.c
tests/shell/testcases/flowtable/0010delete_handle_0 [new file with mode: 0755]

index 871480b95ceb607b7f3b535f7876c37a4fe9d0e8..858abbf73fbfc0a429d59647a21cdec18db10015 100644 (file)
@@ -409,6 +409,7 @@ ____
        "family":* 'STRING'*,
        "table":* 'STRING'*,
        "name":* 'STRING'*,
+       "handle":* 'NUMBER'*,
        "hook":* 'STRING'*,
        "prio":* 'NUMBER'*,
        "dev":* 'FT_INTERFACE'
@@ -426,6 +427,8 @@ This object represents a named flowtable.
        The table's name.
 *name*::
        The flow table's name.
+*handle*::
+       The flow table's handle. In input, it is used by the *delete* command only.
 *hook*::
        The flow table's hook.
 *prio*::
index ed2157638032a16398dc2d1565cce7600b694742..1521171b7babc66bd89804e00ebae7467e736235 100644 (file)
@@ -588,6 +588,7 @@ FLOWTABLES
 {*add* | *create*} *flowtable* ['family'] 'table' 'flowtable' *{ hook* 'hook' *priority* 'priority' *; devices = {* 'device'[*,* ...] *} ; }*
 *list flowtables* ['family']
 {*delete* | *list*} *flowtable* ['family'] 'table' 'flowtable'
+*delete* *flowtable* ['family'] 'table' *handle* 'handle'
 
 Flowtables allow you to accelerate packet forwarding in software. Flowtables
 entries are represented through a tuple that is composed of the input interface,
index d079da9ea9ebe00ddb1b2f640bedb7cc67798b15..f0a70117745411953e7bf752137ad3bcd1d15e43 100644 (file)
@@ -410,10 +410,11 @@ static json_t *flowtable_print_json(const struct flowtable *ftable)
 
        mpz_export_data(&priority, ftable->priority.expr->value,
                        BYTEORDER_HOST_ENDIAN, sizeof(int));
-       root = json_pack("{s:s, s:s, s:s, s:s, s:i}",
+       root = json_pack("{s:s, s:s, s:s, s:I, s:s, s:i}",
                        "family", family2str(ftable->handle.family),
                        "name", ftable->handle.flowtable.name,
                        "table", ftable->handle.table.name,
+                       "handle", ftable->handle.handle.id,
                        "hook", hooknum2str(NFPROTO_NETDEV, ftable->hooknum),
                        "prio", priority);
 
index 36ccda58c2688b4eedab421a37777d21f9d753fb..fdba0af839026603b73966ad413f086730468a56 100644 (file)
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -1474,8 +1474,12 @@ int mnl_nft_flowtable_del(struct netlink_ctx *ctx, const struct cmd *cmd)
                                cmd->handle.family);
        nftnl_flowtable_set_str(flo, NFTNL_FLOWTABLE_TABLE,
                                cmd->handle.table.name);
-       nftnl_flowtable_set_str(flo, NFTNL_FLOWTABLE_NAME,
-                               cmd->handle.flowtable.name);
+       if (cmd->handle.flowtable.name)
+               nftnl_flowtable_set_str(flo, NFTNL_FLOWTABLE_NAME,
+                                       cmd->handle.flowtable.name);
+       else if (cmd->handle.handle.id)
+               nftnl_flowtable_set_u64(flo, NFTNL_FLOWTABLE_HANDLE,
+                                       cmd->handle.handle.id);
 
        nlh = nftnl_nlmsg_build_hdr(nftnl_batch_buffer(ctx->batch),
                                    NFT_MSG_DELFLOWTABLE, cmd->handle.family,
index a727c7eb76b0e325c7a78dd07a968d0f36cedc7e..7306e358ca39d0f224872bb2f10e5a7ef18561d7 100644 (file)
@@ -1133,6 +1133,8 @@ netlink_delinearize_flowtable(struct netlink_ctx *ctx,
                xstrdup(nftnl_flowtable_get_str(nlo, NFTNL_FLOWTABLE_TABLE));
        flowtable->handle.flowtable.name =
                xstrdup(nftnl_flowtable_get_str(nlo, NFTNL_FLOWTABLE_NAME));
+       flowtable->handle.handle.id =
+               nftnl_flowtable_get_u64(nlo, NFTNL_FLOWTABLE_HANDLE);
        dev_array = nftnl_flowtable_get(nlo, NFTNL_FLOWTABLE_DEVICES);
        while (dev_array[len])
                len++;
index 94494f6f5005ea3513368c22dbf3b26707921ec1..6f525d5b85240f023afee6bf30362796315e8c3b 100644 (file)
@@ -559,8 +559,8 @@ int nft_lex(void *, void *, void *);
 
 %type <handle>                 table_spec tableid_spec chain_spec chainid_spec flowtable_spec chain_identifier ruleid_spec handle_spec position_spec rule_position ruleset_spec index_spec
 %destructor { handle_free(&$$); } table_spec tableid_spec chain_spec chainid_spec flowtable_spec chain_identifier ruleid_spec handle_spec position_spec rule_position ruleset_spec index_spec
-%type <handle>                 set_spec setid_spec set_identifier flowtable_identifier obj_spec objid_spec obj_identifier
-%destructor { handle_free(&$$); } set_spec setid_spec set_identifier obj_spec objid_spec obj_identifier
+%type <handle>                 set_spec setid_spec set_identifier flowtableid_spec flowtable_identifier obj_spec objid_spec obj_identifier
+%destructor { handle_free(&$$); } set_spec setid_spec set_identifier flowtableid_spec obj_spec objid_spec obj_identifier
 %type <val>                    family_spec family_spec_explicit
 %type <val32>                  int_num chain_policy
 %type <prio_spec>              extended_prio_spec prio_spec
@@ -1151,6 +1151,10 @@ delete_cmd               :       TABLE           table_spec
                        {
                                $$ = cmd_alloc(CMD_DELETE, CMD_OBJ_FLOWTABLE, &$2, &@$, NULL);
                        }
+                       |       FLOWTABLE       flowtableid_spec
+                       {
+                               $$ = cmd_alloc(CMD_DELETE, CMD_OBJ_FLOWTABLE, &$2, &@$, NULL);
+                       }
                        |       COUNTER         obj_spec
                        {
                                $$ = cmd_alloc(CMD_DELETE, CMD_OBJ_COUNTER, &$2, &@$, NULL);
@@ -2225,7 +2229,6 @@ set_identifier            :       identifier
                        }
                        ;
 
-
 flowtable_spec         :       table_spec      identifier
                        {
                                $$                      = $1;
@@ -2234,6 +2237,14 @@ flowtable_spec           :       table_spec      identifier
                        }
                        ;
 
+flowtableid_spec       :       table_spec      HANDLE NUM
+                       {
+                               $$                      = $1;
+                               $$.handle.location      = @$;
+                               $$.handle.id            = $3;
+                       }
+                       ;
+
 flowtable_identifier   :       identifier
                        {
                                memset(&$$, 0, sizeof($$));
index 3b86a0ae543f98f098c8a6d1bdce47de9a6e823b..031930e2d7088fb3d564578df09f9df0faab3e6e 100644 (file)
@@ -2964,20 +2964,30 @@ static struct cmd *json_parse_cmd_add_flowtable(struct json_ctx *ctx,
        json_t *devs;
        int prio;
 
-       if (json_unpack_err(ctx, root, "{s:s, s:s, s:s}",
+       if (json_unpack_err(ctx, root, "{s:s, s:s}",
                            "family", &family,
-                           "table", &h.table.name,
-                           "name", &h.flowtable.name))
+                           "table", &h.table.name))
+               return NULL;
+
+       if (op != CMD_DELETE &&
+           json_unpack_err(ctx, root, "{s:s}", "name", &h.flowtable.name)) {
+               return NULL;
+       } else if (op == CMD_DELETE &&
+                  json_unpack(root, "{s:s}", "name", &h.flowtable.name) &&
+                  json_unpack(root, "{s:I}", "handle", &h.handle.id)) {
+               json_error(ctx, "Either name or handle required to delete a flowtable.");
                return NULL;
+       }
 
        if (parse_family(family, &h.family)) {
                json_error(ctx, "Unknown family '%s'.", family);
                return NULL;
        }
        h.table.name = xstrdup(h.table.name);
-       h.flowtable.name = xstrdup(h.flowtable.name);
+       if (h.flowtable.name)
+               h.flowtable.name = xstrdup(h.flowtable.name);
 
-       if (op == CMD_DELETE)
+       if (op == CMD_DELETE || op == CMD_LIST)
                return cmd_alloc(op, cmd_obj, &h, int_loc, NULL);
 
        if (json_unpack_err(ctx, root, "{s:s, s:I, s:o}",
index a2811d18fa31b5c20cc13c731f28ec5513b2cdca..ff9e8e6c0e57c9ede43468af8fcfde023e668227 100644 (file)
@@ -2156,8 +2156,11 @@ static void flowtable_print_declaration(const struct flowtable *flowtable,
        if (opts->table != NULL)
                nft_print(octx, " %s", opts->table);
 
-       nft_print(octx, " %s {%s", flowtable->handle.flowtable.name, opts->nl);
+       nft_print(octx, " %s {", flowtable->handle.flowtable.name);
 
+       if (nft_output_handle(octx))
+               nft_print(octx, " # handle %" PRIu64, flowtable->handle.handle.id);
+       nft_print(octx, "%s", opts->nl);
        nft_print(octx, "%s%shook %s priority %s%s",
                  opts->tab, opts->tab,
                  hooknum2str(NFPROTO_NETDEV, flowtable->hooknum),
diff --git a/tests/shell/testcases/flowtable/0010delete_handle_0 b/tests/shell/testcases/flowtable/0010delete_handle_0
new file mode 100755 (executable)
index 0000000..303967d
--- /dev/null
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+# delete flowtable by handle
+
+set -e
+
+$NFT add table inet t
+$NFT add flowtable inet t f { hook ingress priority filter\; devices = { lo }\; }
+
+FH=$($NFT list ruleset -a | awk '/flowtable f/ { print $NF }')
+
+$NFT delete flowtable inet t handle $FH
+
+EXPECTED="table inet t {
+}"
+
+GET="$($NFT list ruleset)"
+if [ "$EXPECTED" != "$GET" ] ; then
+       DIFF="$(which diff)"
+       [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET")
+       exit 1
+fi