]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
xt: Rewrite unsupported compat expression dumping
authorPhil Sutter <phil@nwl.cc>
Thu, 24 Nov 2022 13:17:17 +0000 (14:17 +0100)
committerPhil Sutter <phil@nwl.cc>
Tue, 13 Dec 2022 13:59:55 +0000 (14:59 +0100)
Choose a format which provides more information and is easily parseable.
Then teach parsers about it and make it explicitly reject the ruleset
giving a meaningful explanation. Also update the man pages with some
more details.

Signed-off-by: Phil Sutter <phil@nwl.cc>
doc/libnftables-json.adoc
doc/statements.txt
include/json.h
include/parser.h
src/json.c
src/parser_bison.y
src/parser_json.c
src/scanner.l
src/statement.c
src/xt.c

index bb59945fc510d25584c418b734073fb5068d6dba..d985149a0af357680ae9ce5835768974a9dadcb1 100644 (file)
@@ -1059,10 +1059,22 @@ Assign connection tracking expectation.
 
 === XT
 [verse]
-*{ "xt": null }*
+____
+*{ "xt": {
+       "type":* 'TYPENAME'*,
+       "name":* 'STRING'
+*}}*
+
+'TYPENAME' := *match* | *target* | *watcher*
+____
+
+This represents an xt statement from xtables compat interface. It is a
+fallback if translation is not available or not complete.
+
+Seeing this means the ruleset (or parts of it) were created by *iptables-nft*
+and one should use that to manage it.
 
-This represents an xt statement from xtables compat interface. Sadly, at this
-point, it is not possible to provide any further information about its content.
+*BEWARE:* nftables won't restore these statements.
 
 == EXPRESSIONS
 Expressions are the building blocks of (most) statements. In their most basic
index bda63bb3bc38eb2db5bf081b662540a765b6d43c..9e0dd5a034c16bac76efa9409595c7663c1606e0 100644 (file)
@@ -800,3 +800,20 @@ ____
 # jump to different chains depending on layer 4 protocol type:
 nft add rule ip filter input ip protocol vmap { tcp : jump tcp-chain, udp : jump udp-chain , icmp : jump icmp-chain }
 ------------------------
+
+XT STATEMENT
+~~~~~~~~~~~~
+This represents an xt statement from xtables compat interface. It is a
+fallback if translation is not available or not complete.
+
+[verse]
+____
+*xt* 'TYPE' 'NAME'
+
+'TYPE' := *match* | *target* | *watcher*
+____
+
+Seeing this means the ruleset (or parts of it) were created by *iptables-nft*
+and one should use that to manage it.
+
+*BEWARE:* nftables won't restore these statements.
index b0d78eb84987e0791d5aecb42da42bf0a307d784..f691678d4d726798fb113bb86cbc98c2a4c13787 100644 (file)
@@ -92,6 +92,7 @@ json_t *connlimit_stmt_json(const struct stmt *stmt, struct output_ctx *octx);
 json_t *tproxy_stmt_json(const struct stmt *stmt, struct output_ctx *octx);
 json_t *synproxy_stmt_json(const struct stmt *stmt, struct output_ctx *octx);
 json_t *optstrip_stmt_json(const struct stmt *stmt, struct output_ctx *octx);
+json_t *xt_stmt_json(const struct stmt *stmt, struct output_ctx *octx);
 
 int do_command_list_json(struct netlink_ctx *ctx, struct cmd *cmd);
 
@@ -194,6 +195,7 @@ STMT_PRINT_STUB(connlimit)
 STMT_PRINT_STUB(tproxy)
 STMT_PRINT_STUB(synproxy)
 STMT_PRINT_STUB(optstrip)
+STMT_PRINT_STUB(xt)
 
 #undef STMT_PRINT_STUB
 #undef EXPR_PRINT_STUB
index f55da0fd47bf27b5737f6390909cdbff0583e31e..977fbb94fbd625a1e2bcaff7f27ccbc0a7090f44 100644 (file)
@@ -50,6 +50,7 @@ enum startcond_type {
        PARSER_SC_TCP,
        PARSER_SC_TYPE,
        PARSER_SC_VLAN,
+       PARSER_SC_XT,
        PARSER_SC_CMD_EXPORT,
        PARSER_SC_CMD_IMPORT,
        PARSER_SC_CMD_LIST,
index 6662f8087736a182153854a21381983c2e6dedbd..89ff8a344c2e446547d096d9f502e0477b8b3260 100644 (file)
@@ -82,12 +82,6 @@ static json_t *stmt_print_json(const struct stmt *stmt, struct output_ctx *octx)
        char buf[1024];
        FILE *fp;
 
-       /* XXX: Can't be supported at this point:
-        * xt_stmt_xlate() ignores output_fp.
-        */
-       if (stmt->ops->type == STMT_XT)
-               return json_pack("{s:n}", "xt");
-
        if (stmt->ops->json)
                return stmt->ops->json(stmt, octx);
 
@@ -1624,6 +1618,19 @@ json_t *optstrip_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
                         expr_print_json(stmt->optstrip.expr, octx));
 }
 
+json_t *xt_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
+{
+       static const char *xt_typename[NFT_XT_MAX] = {
+               [NFT_XT_MATCH]          = "match",
+               [NFT_XT_TARGET]         = "target",
+               [NFT_XT_WATCHER]        = "watcher",
+       };
+
+       return json_pack("{s:{s:s, s:s}}", "xt",
+                        "type", xt_typename[stmt->xt.type],
+                        "name", stmt->xt.name);
+}
+
 static json_t *table_print_json_full(struct netlink_ctx *ctx,
                                     struct table *table)
 {
index 760c23cf33223340b56ae1d29e44bd6ce5ba4f92..d7cf8bc5fb1ee8bf4cd376984577457156c18d1e 100644 (file)
@@ -626,6 +626,8 @@ int nft_lex(void *, void *, void *);
 %token IN                      "in"
 %token OUT                     "out"
 
+%token XT              "xt"
+
 %type <limit_rate>             limit_rate_pkts
 %type <limit_rate>             limit_rate_bytes
 
@@ -900,6 +902,9 @@ int nft_lex(void *, void *, void *);
 %type <stmt>                   optstrip_stmt
 %destructor { stmt_free($$); } optstrip_stmt
 
+%type <stmt>                   xt_stmt
+%destructor { stmt_free($$); } xt_stmt
+
 %type <expr>                   boolean_expr
 %destructor { expr_free($$); } boolean_expr
 %type <val8>                   boolean_keys
@@ -991,6 +996,7 @@ close_scope_udplite : { scanner_pop_start_cond(nft->scanner, PARSER_SC_EXPR_UDPL
 
 close_scope_log                : { scanner_pop_start_cond(nft->scanner, PARSER_SC_STMT_LOG); }
 close_scope_synproxy   : { scanner_pop_start_cond(nft->scanner, PARSER_SC_STMT_SYNPROXY); }
+close_scope_xt         : { scanner_pop_start_cond(nft->scanner, PARSER_SC_XT); }
 
 common_block           :       INCLUDE         QUOTED_STRING   stmt_separator
                        {
@@ -2879,6 +2885,18 @@ stmt                     :       verdict_stmt
                        |       synproxy_stmt   close_scope_synproxy
                        |       chain_stmt
                        |       optstrip_stmt
+                       |       xt_stmt         close_scope_xt
+                       ;
+
+xt_stmt                        :       XT      STRING  STRING
+                       {
+                               $$ = NULL;
+                               xfree($2);
+                               xfree($3);
+                               erec_queue(error(&@$, "unsupported xtables compat expression, use iptables-nft with this ruleset"),
+                                          state->msgs);
+                               YYERROR;
+                       }
                        ;
 
 chain_stmt_type                :       JUMP    { $$ = NFT_JUMP; }
index aa00e9ecd65ca736f123496c0079623a2371b994..762e779de4b08f7f805988894560faa0b73b8952 100644 (file)
@@ -2764,6 +2764,11 @@ static struct stmt *json_parse_stmt(struct json_ctx *ctx, json_t *root)
                return verdict_stmt_alloc(int_loc, expr);
        }
 
+       if (!strcmp(type, "xt")) {
+               json_error(ctx, "unsupported xtables compat expression, use iptables-nft with this ruleset");
+               return NULL;
+       }
+
        for (i = 0; i < array_size(stmt_parser_tbl); i++) {
                if (!strcmp(type, stmt_parser_tbl[i].key))
                        return stmt_parser_tbl[i].cb(ctx, stmt_parser_tbl[i].key, tmp);
index 7e8748f51c274a503b2b793a52943534978f0423..583c251171fd7551af9625cba661e9e5fe5fe75d 100644 (file)
@@ -215,6 +215,7 @@ addrstring  ({macaddr}|{ip4addr}|{ip6addr})
 %s SCANSTATE_TCP
 %s SCANSTATE_TYPE
 %s SCANSTATE_VLAN
+%s SCANSTATE_XT
 %s SCANSTATE_CMD_EXPORT
 %s SCANSTATE_CMD_IMPORT
 %s SCANSTATE_CMD_LIST
@@ -800,6 +801,8 @@ addrstring  ({macaddr}|{ip4addr}|{ip6addr})
 
 "secmark"              { scanner_push_start_cond(yyscanner, SCANSTATE_SECMARK); return SECMARK; }
 
+"xt"                   { scanner_push_start_cond(yyscanner, SCANSTATE_XT); return XT; }
+
 {addrstring}           {
                                yylval->string = xstrdup(yytext);
                                return STRING;
index 327d00f99200a8c5aa3335a8e5be627998218425..eafc51c484de9f611363d0662b245fc259863870 100644 (file)
@@ -997,6 +997,7 @@ static const struct stmt_ops xt_stmt_ops = {
        .name           = "xt",
        .print          = xt_stmt_print,
        .destroy        = xt_stmt_destroy,
+       .json           = xt_stmt_json,
 };
 
 struct stmt *xt_stmt_alloc(const struct location *loc)
index 300416a1e8d922de8b86deb59129dbf5cbdcbeae..12b52aa33bc300550b3ee0a9af8719d98f75ea34 100644 (file)
--- a/src/xt.c
+++ b/src/xt.c
@@ -115,7 +115,13 @@ void xt_stmt_xlate(const struct stmt *stmt, struct output_ctx *octx)
        xt_xlate_free(xl);
        xfree(entry);
 #else
-       nft_print(octx, "# xt_%s", stmt->xt.name);
+       static const char *typename[NFT_XT_MAX] = {
+               [NFT_XT_MATCH]          = "match",
+               [NFT_XT_TARGET]         = "target",
+               [NFT_XT_WATCHER]        = "watcher",
+       };
+
+       nft_print(octx, "xt %s %s", typename[stmt->xt.type], stmt->xt.name);
 #endif
 }