summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2024-04-02 00:28:24 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2024-04-04 11:50:11 +0200
commit5fecd2a6ef614eca7b0829e684449ee25982c233 (patch)
treea764d30af9cbe2bfced55ea773313e7288a7178d /src
parent3f776e8b37d8022d4492ed8be136e99f5a88ab9e (diff)
src: disentangle ICMP code types
Currently, ICMP{v4,v6,inet} code datatypes only describe those that are supported by the reject statement, but they can also be used for icmp code matching. Moreover, ICMP code types go hand-to-hand with ICMP types, that is, ICMP code symbols depend on the ICMP type. Thus, the output of: nft describe icmp_code look confusing because that only displays the values that are supported by the reject statement. Disentangle this by adding internal datatypes for the reject statement to handle the ICMP code symbol conversion to value as well as ruleset listing. The existing icmp_code, icmpv6_code and icmpx_code remain in place. For backward compatibility, a parser function is defined in case an existing ruleset relies on these symbols. As for the manpage, move existing ICMP code tables from the DATA TYPES section to the REJECT STATEMENT section, where this really belongs to. But the icmp_code and icmpv6_code table stubs remain in the DATA TYPES section because that describe that this is an 8-bit integer field. After this patch: # nft describe icmp_code datatype icmp_code (icmp code) (basetype integer), 8 bits # nft describe icmpv6_code datatype icmpv6_code (icmpv6 code) (basetype integer), 8 bits # nft describe icmpx_code datatype icmpx_code (icmpx code) (basetype integer), 8 bits do not display the symbol table of the reject statement anymore. icmpx_code_type is not used anymore, but keep it in place for backward compatibility reasons. And update tests/shell accordingly. Fixes: 5fdd0b6a0600 ("nft: complete reject support") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src')
-rw-r--r--src/datatype.c71
-rw-r--r--src/netlink_delinearize.c10
-rw-r--r--src/parser_bison.y12
-rw-r--r--src/parser_json.c6
4 files changed, 78 insertions, 21 deletions
diff --git a/src/datatype.c b/src/datatype.c
index b368ea91..d398a9c8 100644
--- a/src/datatype.c
+++ b/src/datatype.c
@@ -1017,6 +1017,7 @@ const struct datatype mark_type = {
.parse = mark_type_parse,
};
+/* symbol table for private datatypes for reject statement. */
static const struct symbol_table icmp_code_tbl = {
.base = BASE_DECIMAL,
.symbols = {
@@ -1032,16 +1033,17 @@ static const struct symbol_table icmp_code_tbl = {
},
};
-const struct datatype icmp_code_type = {
- .type = TYPE_ICMP_CODE,
+/* private datatype for reject statement. */
+const struct datatype reject_icmp_code_type = {
.name = "icmp_code",
- .desc = "icmp code",
+ .desc = "reject icmp code",
.size = BITS_PER_BYTE,
.byteorder = BYTEORDER_BIG_ENDIAN,
.basetype = &integer_type,
.sym_tbl = &icmp_code_tbl,
};
+/* symbol table for private datatypes for reject statement. */
static const struct symbol_table icmpv6_code_tbl = {
.base = BASE_DECIMAL,
.symbols = {
@@ -1055,16 +1057,17 @@ static const struct symbol_table icmpv6_code_tbl = {
},
};
-const struct datatype icmpv6_code_type = {
- .type = TYPE_ICMPV6_CODE,
+/* private datatype for reject statement. */
+const struct datatype reject_icmpv6_code_type = {
.name = "icmpv6_code",
- .desc = "icmpv6 code",
+ .desc = "reject icmpv6 code",
.size = BITS_PER_BYTE,
.byteorder = BYTEORDER_BIG_ENDIAN,
.basetype = &integer_type,
.sym_tbl = &icmpv6_code_tbl,
};
+/* symbol table for private datatypes for reject statement. */
static const struct symbol_table icmpx_code_tbl = {
.base = BASE_DECIMAL,
.symbols = {
@@ -1076,6 +1079,60 @@ static const struct symbol_table icmpx_code_tbl = {
},
};
+/* private datatype for reject statement. */
+const struct datatype reject_icmpx_code_type = {
+ .name = "icmpx_code",
+ .desc = "reject icmpx code",
+ .size = BITS_PER_BYTE,
+ .byteorder = BYTEORDER_BIG_ENDIAN,
+ .basetype = &integer_type,
+ .sym_tbl = &icmpx_code_tbl,
+};
+
+/* Backward compatible parser for the reject statement. */
+static struct error_record *icmp_code_parse(struct parse_ctx *ctx,
+ const struct expr *sym,
+ struct expr **res)
+{
+ return symbolic_constant_parse(ctx, sym, &icmp_code_tbl, res);
+}
+
+const struct datatype icmp_code_type = {
+ .type = TYPE_ICMP_CODE,
+ .name = "icmp_code",
+ .desc = "icmp code",
+ .size = BITS_PER_BYTE,
+ .byteorder = BYTEORDER_BIG_ENDIAN,
+ .basetype = &integer_type,
+ .parse = icmp_code_parse,
+};
+
+/* Backward compatible parser for the reject statement. */
+static struct error_record *icmpv6_code_parse(struct parse_ctx *ctx,
+ const struct expr *sym,
+ struct expr **res)
+{
+ return symbolic_constant_parse(ctx, sym, &icmpv6_code_tbl, res);
+}
+
+const struct datatype icmpv6_code_type = {
+ .type = TYPE_ICMPV6_CODE,
+ .name = "icmpv6_code",
+ .desc = "icmpv6 code",
+ .size = BITS_PER_BYTE,
+ .byteorder = BYTEORDER_BIG_ENDIAN,
+ .basetype = &integer_type,
+ .parse = icmpv6_code_parse,
+};
+
+/* Backward compatible parser for the reject statement. */
+static struct error_record *icmpx_code_parse(struct parse_ctx *ctx,
+ const struct expr *sym,
+ struct expr **res)
+{
+ return symbolic_constant_parse(ctx, sym, &icmpx_code_tbl, res);
+}
+
const struct datatype icmpx_code_type = {
.type = TYPE_ICMPX_CODE,
.name = "icmpx_code",
@@ -1083,7 +1140,7 @@ const struct datatype icmpx_code_type = {
.size = BITS_PER_BYTE,
.byteorder = BYTEORDER_BIG_ENDIAN,
.basetype = &integer_type,
- .sym_tbl = &icmpx_code_tbl,
+ .parse = icmpx_code_parse,
};
void time_print(uint64_t ms, struct output_ctx *octx)
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index 24dfb311..da9f7a91 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -2948,7 +2948,7 @@ static void stmt_reject_postprocess(struct rule_pp_ctx *rctx)
switch (dl->pctx.family) {
case NFPROTO_IPV4:
stmt->reject.family = dl->pctx.family;
- datatype_set(stmt->reject.expr, &icmp_code_type);
+ datatype_set(stmt->reject.expr, &reject_icmp_code_type);
if (stmt->reject.type == NFT_REJECT_TCP_RST &&
payload_dependency_exists(&dl->pdctx,
PROTO_BASE_TRANSPORT_HDR))
@@ -2957,7 +2957,7 @@ static void stmt_reject_postprocess(struct rule_pp_ctx *rctx)
break;
case NFPROTO_IPV6:
stmt->reject.family = dl->pctx.family;
- datatype_set(stmt->reject.expr, &icmpv6_code_type);
+ datatype_set(stmt->reject.expr, &reject_icmpv6_code_type);
if (stmt->reject.type == NFT_REJECT_TCP_RST &&
payload_dependency_exists(&dl->pdctx,
PROTO_BASE_TRANSPORT_HDR))
@@ -2968,7 +2968,7 @@ static void stmt_reject_postprocess(struct rule_pp_ctx *rctx)
case NFPROTO_BRIDGE:
case NFPROTO_NETDEV:
if (stmt->reject.type == NFT_REJECT_ICMPX_UNREACH) {
- datatype_set(stmt->reject.expr, &icmpx_code_type);
+ datatype_set(stmt->reject.expr, &reject_icmpx_code_type);
break;
}
@@ -2984,12 +2984,12 @@ static void stmt_reject_postprocess(struct rule_pp_ctx *rctx)
case NFPROTO_IPV4: /* INET */
case __constant_htons(ETH_P_IP): /* BRIDGE, NETDEV */
stmt->reject.family = NFPROTO_IPV4;
- datatype_set(stmt->reject.expr, &icmp_code_type);
+ datatype_set(stmt->reject.expr, &reject_icmp_code_type);
break;
case NFPROTO_IPV6: /* INET */
case __constant_htons(ETH_P_IPV6): /* BRIDGE, NETDEV */
stmt->reject.family = NFPROTO_IPV6;
- datatype_set(stmt->reject.expr, &icmpv6_code_type);
+ datatype_set(stmt->reject.expr, &reject_icmpv6_code_type);
break;
default:
break;
diff --git a/src/parser_bison.y b/src/parser_bison.y
index bdb73911..61bed761 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -3740,40 +3740,40 @@ reject_opts : /* empty */
$<stmt>0->reject.family = NFPROTO_IPV4;
$<stmt>0->reject.type = NFT_REJECT_ICMP_UNREACH;
$<stmt>0->reject.expr = $4;
- datatype_set($<stmt>0->reject.expr, &icmp_code_type);
+ datatype_set($<stmt>0->reject.expr, &reject_icmp_code_type);
}
| WITH ICMP reject_with_expr
{
$<stmt>0->reject.family = NFPROTO_IPV4;
$<stmt>0->reject.type = NFT_REJECT_ICMP_UNREACH;
$<stmt>0->reject.expr = $3;
- datatype_set($<stmt>0->reject.expr, &icmp_code_type);
+ datatype_set($<stmt>0->reject.expr, &reject_icmp_code_type);
}
| WITH ICMP6 TYPE reject_with_expr close_scope_type close_scope_icmp
{
$<stmt>0->reject.family = NFPROTO_IPV6;
$<stmt>0->reject.type = NFT_REJECT_ICMP_UNREACH;
$<stmt>0->reject.expr = $4;
- datatype_set($<stmt>0->reject.expr, &icmpv6_code_type);
+ datatype_set($<stmt>0->reject.expr, &reject_icmpv6_code_type);
}
| WITH ICMP6 reject_with_expr
{
$<stmt>0->reject.family = NFPROTO_IPV6;
$<stmt>0->reject.type = NFT_REJECT_ICMP_UNREACH;
$<stmt>0->reject.expr = $3;
- datatype_set($<stmt>0->reject.expr, &icmpv6_code_type);
+ datatype_set($<stmt>0->reject.expr, &reject_icmpv6_code_type);
}
| WITH ICMPX TYPE reject_with_expr close_scope_type
{
$<stmt>0->reject.type = NFT_REJECT_ICMPX_UNREACH;
$<stmt>0->reject.expr = $4;
- datatype_set($<stmt>0->reject.expr, &icmpx_code_type);
+ datatype_set($<stmt>0->reject.expr, &reject_icmpx_code_type);
}
| WITH ICMPX reject_with_expr
{
$<stmt>0->reject.type = NFT_REJECT_ICMPX_UNREACH;
$<stmt>0->reject.expr = $3;
- datatype_set($<stmt>0->reject.expr, &icmpx_code_type);
+ datatype_set($<stmt>0->reject.expr, &reject_icmpx_code_type);
}
| WITH TCP close_scope_tcp RESET close_scope_reset
{
diff --git a/src/parser_json.c b/src/parser_json.c
index 4fc0479c..efe49494 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -2331,17 +2331,17 @@ static struct stmt *json_parse_reject_stmt(struct json_ctx *ctx,
stmt->reject.icmp_code = 0;
} else if (!strcmp(type, "icmpx")) {
stmt->reject.type = NFT_REJECT_ICMPX_UNREACH;
- dtype = &icmpx_code_type;
+ dtype = &reject_icmpx_code_type;
stmt->reject.icmp_code = 0;
} else if (!strcmp(type, "icmp")) {
stmt->reject.type = NFT_REJECT_ICMP_UNREACH;
stmt->reject.family = NFPROTO_IPV4;
- dtype = &icmp_code_type;
+ dtype = &reject_icmp_code_type;
stmt->reject.icmp_code = 0;
} else if (!strcmp(type, "icmpv6")) {
stmt->reject.type = NFT_REJECT_ICMP_UNREACH;
stmt->reject.family = NFPROTO_IPV6;
- dtype = &icmpv6_code_type;
+ dtype = &reject_icmpv6_code_type;
stmt->reject.icmp_code = 0;
}
}