summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/libnftables-json.adoc3
-rw-r--r--doc/nft.txt1
-rw-r--r--src/json.c3
-rw-r--r--src/mnl.c8
-rw-r--r--src/netlink.c2
-rw-r--r--src/parser_bison.y17
-rw-r--r--src/parser_json.c20
-rw-r--r--src/rule.c5
-rwxr-xr-xtests/shell/testcases/flowtable/0010delete_handle_022
9 files changed, 69 insertions, 12 deletions
diff --git a/doc/libnftables-json.adoc b/doc/libnftables-json.adoc
index 871480b9..858abbf7 100644
--- a/doc/libnftables-json.adoc
+++ b/doc/libnftables-json.adoc
@@ -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*::
diff --git a/doc/nft.txt b/doc/nft.txt
index ed215763..1521171b 100644
--- a/doc/nft.txt
+++ b/doc/nft.txt
@@ -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,
diff --git a/src/json.c b/src/json.c
index d079da9e..f0a70117 100644
--- a/src/json.c
+++ b/src/json.c
@@ -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);
diff --git a/src/mnl.c b/src/mnl.c
index 36ccda58..fdba0af8 100644
--- 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,
diff --git a/src/netlink.c b/src/netlink.c
index a727c7eb..7306e358 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -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++;
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 94494f6f..6f525d5b 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -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($$));
diff --git a/src/parser_json.c b/src/parser_json.c
index 3b86a0ae..031930e2 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -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}",
diff --git a/src/rule.c b/src/rule.c
index a2811d18..ff9e8e6c 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -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
index 00000000..303967dd
--- /dev/null
+++ b/tests/shell/testcases/flowtable/0010delete_handle_0
@@ -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