* [PATCH nft 01/10] exthdr: remove unused proto_key member from struct
2020-12-09 17:49 [PATCH nft 0/10] nft: add automatic icmp/icmpv6 dependencies Florian Westphal
@ 2020-12-09 17:49 ` Florian Westphal
2020-12-09 17:49 ` [PATCH nft 02/10] proto: reduce size of proto_desc structure Florian Westphal
` (9 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Florian Westphal @ 2020-12-09 17:49 UTC (permalink / raw)
To: netfilter-devel; +Cc: Florian Westphal
also, no need for this struct to be in the parser.
Signed-off-by: Florian Westphal <fw@strlen.de>
---
include/exthdr.h | 1 -
src/exthdr.c | 4 ----
src/parser_bison.y | 1 -
3 files changed, 6 deletions(-)
diff --git a/include/exthdr.h b/include/exthdr.h
index c9a3c211b8c4..1bc756f93649 100644
--- a/include/exthdr.h
+++ b/include/exthdr.h
@@ -30,7 +30,6 @@ struct exthdr_desc {
const char *name;
enum exthdr_desc_id id;
uint8_t type;
- int proto_key;
struct proto_hdr_template templates[10];
};
diff --git a/src/exthdr.c b/src/exthdr.c
index 5eb66529b5d7..b0243adad1da 100644
--- a/src/exthdr.c
+++ b/src/exthdr.c
@@ -409,7 +409,6 @@ const struct exthdr_desc exthdr_rt2 = {
.name = "rt2",
.id = EXTHDR_DESC_RT2,
.type = IPPROTO_ROUTING,
- .proto_key = 2,
.templates = {
[RT2HDR_RESERVED] = {},
[RT2HDR_ADDR] = {},
@@ -423,7 +422,6 @@ const struct exthdr_desc exthdr_rt0 = {
.name = "rt0",
.id = EXTHDR_DESC_RT0,
.type = IPPROTO_ROUTING,
- .proto_key = 0,
.templates = {
[RT0HDR_RESERVED] = RT0_FIELD("reserved", ip6r0_reserved, &integer_type),
[RT0HDR_ADDR_1] = RT0_FIELD("addr[1]", ip6r0_addr[0], &ip6addr_type),
@@ -439,7 +437,6 @@ const struct exthdr_desc exthdr_rt4 = {
.name = "srh",
.id = EXTHDR_DESC_SRH,
.type = IPPROTO_ROUTING,
- .proto_key = 4,
.templates = {
[RT4HDR_LASTENT] = RT4_FIELD("last-entry", ip6r4_last_entry, &integer_type),
[RT4HDR_FLAGS] = RT4_FIELD("flags", ip6r4_flags, &integer_type),
@@ -458,7 +455,6 @@ const struct exthdr_desc exthdr_rt = {
.name = "rt",
.id = EXTHDR_DESC_RT,
.type = IPPROTO_ROUTING,
- .proto_key = -1,
#if 0
.protocol_key = RTHDR_TYPE,
.protocols = {
diff --git a/src/parser_bison.y b/src/parser_bison.y
index e8aa5bb8eb3d..08aadaa32a86 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -184,7 +184,6 @@ int nft_lex(void *, void *, void *);
struct handle_spec handle_spec;
struct position_spec position_spec;
struct prio_spec prio_spec;
- const struct exthdr_desc *exthdr_desc;
}
%token TOKEN_EOF 0 "end of file"
--
2.26.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH nft 02/10] proto: reduce size of proto_desc structure
2020-12-09 17:49 [PATCH nft 0/10] nft: add automatic icmp/icmpv6 dependencies Florian Westphal
2020-12-09 17:49 ` [PATCH nft 01/10] exthdr: remove unused proto_key member from struct Florian Westphal
@ 2020-12-09 17:49 ` Florian Westphal
2020-12-09 17:49 ` [PATCH nft 03/10] src: add auto-dependencies for ipv4 icmp Florian Westphal
` (8 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Florian Westphal @ 2020-12-09 17:49 UTC (permalink / raw)
To: netfilter-devel; +Cc: Florian Westphal
This will need an additional field. We can compress state
here to avoid further size increase.
Signed-off-by: Florian Westphal <fw@strlen.de>
---
include/proto.h | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/include/proto.h b/include/proto.h
index 6ef332c3966f..667650d67c97 100644
--- a/include/proto.h
+++ b/include/proto.h
@@ -39,8 +39,8 @@ struct proto_hdr_template {
const struct datatype *dtype;
uint16_t offset;
uint16_t len;
- enum byteorder byteorder;
- enum nft_meta_keys meta_key;
+ enum byteorder byteorder:8;
+ enum nft_meta_keys meta_key:8;
};
#define PROTO_HDR_TEMPLATE(__token, __dtype, __byteorder, __offset, __len)\
@@ -101,11 +101,11 @@ enum proto_desc_id {
*/
struct proto_desc {
const char *name;
- enum proto_desc_id id;
- enum proto_bases base;
- enum nft_payload_csum_types checksum_type;
- unsigned int checksum_key;
- unsigned int protocol_key;
+ enum proto_desc_id id:8;
+ enum proto_bases base:8;
+ enum nft_payload_csum_types checksum_type:8;
+ uint16_t checksum_key;
+ uint16_t protocol_key;
unsigned int length;
struct {
unsigned int num;
--
2.26.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH nft 03/10] src: add auto-dependencies for ipv4 icmp
2020-12-09 17:49 [PATCH nft 0/10] nft: add automatic icmp/icmpv6 dependencies Florian Westphal
2020-12-09 17:49 ` [PATCH nft 01/10] exthdr: remove unused proto_key member from struct Florian Westphal
2020-12-09 17:49 ` [PATCH nft 02/10] proto: reduce size of proto_desc structure Florian Westphal
@ 2020-12-09 17:49 ` Florian Westphal
2020-12-09 17:49 ` [PATCH nft 04/10] tests: fix exepcted payload of icmp expressions Florian Westphal
` (7 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Florian Westphal @ 2020-12-09 17:49 UTC (permalink / raw)
To: netfilter-devel; +Cc: Florian Westphal
The ICMP header has field values that are only exist
for certain types.
Mark the icmp proto 'type' field as a nextheader field
and add a new th description to store the icmp type
dependency. This can later be re-used for other protocol
dependend definitions such as mptcp options -- which are all share the
same tcp option number and have a special 4 bit marker inside the
mptcp option space that tells how the remaining option looks like.
Signed-off-by: Florian Westphal <fw@strlen.de>
---
include/payload.h | 3 ++
include/proto.h | 16 +++++-
src/evaluate.c | 20 ++++++-
src/payload.c | 129 +++++++++++++++++++++++++++++++++++++++++++++-
src/proto.c | 25 ++++++---
5 files changed, 182 insertions(+), 11 deletions(-)
diff --git a/include/payload.h b/include/payload.h
index a914d23930e9..7bbb19b936a9 100644
--- a/include/payload.h
+++ b/include/payload.h
@@ -15,6 +15,9 @@ struct eval_ctx;
struct stmt;
extern int payload_gen_dependency(struct eval_ctx *ctx, const struct expr *expr,
struct stmt **res);
+extern int payload_gen_icmp_dependency(struct eval_ctx *ctx,
+ const struct expr *expr,
+ struct stmt **res);
extern int exthdr_gen_dependency(struct eval_ctx *ctx, const struct expr *expr,
const struct proto_desc *dependency,
enum proto_bases pb, struct stmt **res);
diff --git a/include/proto.h b/include/proto.h
index 667650d67c97..f383291b5a79 100644
--- a/include/proto.h
+++ b/include/proto.h
@@ -25,6 +25,13 @@ enum proto_bases {
extern const char *proto_base_names[];
extern const char *proto_base_tokens[];
+enum icmp_hdr_field_type {
+ PROTO_ICMP_ANY = 0,
+ PROTO_ICMP_ECHO, /* echo and reply */
+ PROTO_ICMP_MTU, /* destination unreachable */
+ PROTO_ICMP_ADDRESS, /* redirect */
+};
+
/**
* struct proto_hdr_template - protocol header field description
*
@@ -33,6 +40,7 @@ extern const char *proto_base_tokens[];
* @offset: offset of the header field from base
* @len: length of header field
* @meta_key: special case: meta expression key
+ * @icmp_dep: special case: icmp header dependency
*/
struct proto_hdr_template {
const char *token;
@@ -41,6 +49,7 @@ struct proto_hdr_template {
uint16_t len;
enum byteorder byteorder:8;
enum nft_meta_keys meta_key:8;
+ enum icmp_hdr_field_type icmp_dep:8;
};
#define PROTO_HDR_TEMPLATE(__token, __dtype, __byteorder, __offset, __len)\
@@ -170,7 +179,12 @@ extern const struct proto_desc *proto_dev_desc(uint16_t type);
*/
struct proto_ctx {
unsigned int debug_mask;
- unsigned int family;
+ uint8_t family;
+ union {
+ struct {
+ uint8_t type;
+ } icmp;
+ } th_dep;
struct {
struct location location;
const struct proto_desc *desc;
diff --git a/src/evaluate.c b/src/evaluate.c
index 76b25b408d55..3eb8e1bfc2c5 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -706,7 +706,8 @@ static int __expr_evaluate_payload(struct eval_ctx *ctx, struct expr *expr)
return -1;
rule_stmt_insert_at(ctx->rule, nstmt, ctx->stmt);
- return 0;
+ desc = ctx->pctx.protocol[base].desc;
+ goto check_icmp;
}
if (payload->payload.base == desc->base &&
@@ -724,7 +725,24 @@ static int __expr_evaluate_payload(struct eval_ctx *ctx, struct expr *expr)
* if needed.
*/
if (desc == payload->payload.desc) {
+ const struct proto_hdr_template *tmpl;
+
payload->payload.offset += ctx->pctx.protocol[base].offset;
+check_icmp:
+ if (desc != &proto_icmp)
+ return 0;
+
+ tmpl = expr->payload.tmpl;
+
+ if (!tmpl || !tmpl->icmp_dep)
+ return 0;
+
+ if (payload_gen_icmp_dependency(ctx, expr, &nstmt) < 0)
+ return -1;
+
+ if (nstmt)
+ rule_stmt_insert_at(ctx->rule, nstmt, ctx->stmt);
+
return 0;
}
/* If we already have context and this payload is on the same
diff --git a/src/payload.c b/src/payload.c
index e51c5797c589..54b08f051dc0 100644
--- a/src/payload.c
+++ b/src/payload.c
@@ -19,6 +19,7 @@
#include <arpa/inet.h>
#include <linux/netfilter.h>
#include <linux/if_ether.h>
+#include <netinet/ip_icmp.h>
#include <rule.h>
#include <expression.h>
@@ -95,8 +96,16 @@ static void payload_expr_pctx_update(struct proto_ctx *ctx,
base = ctx->protocol[left->payload.base].desc;
desc = proto_find_upper(base, proto);
- if (!desc)
+ if (!desc) {
+ if (base == &proto_icmp) {
+ /* proto 0 is ECHOREPLY, just pretend its ECHO.
+ * Not doing this would need an additional marker
+ * bit to tell when icmp.type was set.
+ */
+ ctx->th_dep.icmp.type = proto ? proto : ICMP_ECHO;
+ }
return;
+ }
assert(desc->base <= PROTO_BASE_MAX);
if (desc->base == base->base) {
@@ -662,6 +671,19 @@ void exthdr_dependency_kill(struct payload_dep_ctx *ctx, struct expr *expr,
}
}
+static uint8_t icmp_dep_to_type(enum icmp_hdr_field_type t)
+{
+ switch (t) {
+ case PROTO_ICMP_ANY:
+ BUG("Invalid map for simple dependency");
+ case PROTO_ICMP_ECHO: return ICMP_ECHO;
+ case PROTO_ICMP_MTU: return ICMP_DEST_UNREACH;
+ case PROTO_ICMP_ADDRESS: return ICMP_REDIRECT;
+ }
+
+ BUG("Missing icmp type mapping");
+}
+
/**
* payload_expr_complete - fill in type information of a raw payload expr
*
@@ -913,3 +935,108 @@ struct expr *payload_expr_join(const struct expr *e1, const struct expr *e2)
expr->len = e1->len + e2->len;
return expr;
}
+
+static struct stmt *
+__payload_gen_icmp_simple_dependency(struct eval_ctx *ctx, const struct expr *expr,
+ const struct datatype *icmp_type,
+ const struct proto_desc *desc,
+ uint8_t type)
+{
+ struct expr *left, *right, *dep;
+
+ left = payload_expr_alloc(&expr->location, desc, desc->protocol_key);
+ right = constant_expr_alloc(&expr->location, icmp_type,
+ BYTEORDER_BIG_ENDIAN, BITS_PER_BYTE,
+ constant_data_ptr(type, BITS_PER_BYTE));
+
+ dep = relational_expr_alloc(&expr->location, OP_EQ, left, right);
+ return expr_stmt_alloc(&dep->location, dep);
+}
+
+static struct stmt *
+__payload_gen_icmp_echo_dependency(struct eval_ctx *ctx, const struct expr *expr,
+ uint8_t echo, uint8_t reply,
+ const struct datatype *icmp_type,
+ const struct proto_desc *desc)
+{
+ struct expr *left, *right, *dep, *set;
+
+ left = payload_expr_alloc(&expr->location, desc, desc->protocol_key);
+
+ set = set_expr_alloc(&expr->location, NULL);
+
+ right = constant_expr_alloc(&expr->location, icmp_type,
+ BYTEORDER_BIG_ENDIAN, BITS_PER_BYTE,
+ constant_data_ptr(echo, BITS_PER_BYTE));
+ right = set_elem_expr_alloc(&expr->location, right);
+ compound_expr_add(set, right);
+
+ right = constant_expr_alloc(&expr->location, icmp_type,
+ BYTEORDER_BIG_ENDIAN, BITS_PER_BYTE,
+ constant_data_ptr(reply, BITS_PER_BYTE));
+ right = set_elem_expr_alloc(&expr->location, right);
+ compound_expr_add(set, right);
+
+ dep = relational_expr_alloc(&expr->location, OP_IMPLICIT, left, set);
+ return expr_stmt_alloc(&dep->location, dep);
+}
+
+int payload_gen_icmp_dependency(struct eval_ctx *ctx, const struct expr *expr,
+ struct stmt **res)
+{
+ const struct proto_hdr_template *tmpl;
+ const struct proto_desc *desc;
+ struct stmt *stmt = NULL;
+ uint8_t type;
+
+ assert(expr->etype == EXPR_PAYLOAD);
+
+ tmpl = expr->payload.tmpl;
+ desc = expr->payload.desc;
+
+ switch (tmpl->icmp_dep) {
+ case PROTO_ICMP_ANY:
+ BUG("No dependency needed");
+ break;
+ case PROTO_ICMP_ECHO:
+ /* do not test ICMP_ECHOREPLY here: its 0 */
+ if (ctx->pctx.th_dep.icmp.type == ICMP_ECHO)
+ goto done;
+
+ type = ICMP_ECHO;
+ if (ctx->pctx.th_dep.icmp.type)
+ goto bad_proto;
+
+ stmt = __payload_gen_icmp_echo_dependency(ctx, expr,
+ ICMP_ECHO, ICMP_ECHOREPLY,
+ &icmp_type_type,
+ desc);
+ break;
+ case PROTO_ICMP_MTU:
+ case PROTO_ICMP_ADDRESS:
+ type = icmp_dep_to_type(tmpl->icmp_dep);
+ if (ctx->pctx.th_dep.icmp.type == type)
+ goto done;
+ if (ctx->pctx.th_dep.icmp.type)
+ goto bad_proto;
+ stmt = __payload_gen_icmp_simple_dependency(ctx, expr,
+ &icmp_type_type,
+ desc, type);
+ break;
+ default:
+ BUG("Unhandled icmp dependency code");
+ }
+
+ ctx->pctx.th_dep.icmp.type = type;
+
+ if (stmt_evaluate(ctx, stmt) < 0)
+ return expr_error(ctx->msgs, expr,
+ "icmp dependency statement is invalid");
+done:
+ *res = stmt;
+ return 0;
+
+bad_proto:
+ return expr_error(ctx->msgs, expr, "incompatible icmp match: rule has %d, need %u",
+ ctx->pctx.th_dep.icmp.type, type);
+}
diff --git a/src/proto.c b/src/proto.c
index c42e8f517bae..d3371ac65975 100644
--- a/src/proto.c
+++ b/src/proto.c
@@ -396,25 +396,34 @@ const struct datatype icmp_type_type = {
.sym_tbl = &icmp_type_tbl,
};
-#define ICMPHDR_FIELD(__name, __member) \
- HDR_FIELD(__name, struct icmphdr, __member)
+#define ICMPHDR_FIELD(__token, __member, __dep) \
+ { \
+ .token = (__token), \
+ .dtype = &integer_type, \
+ .byteorder = BYTEORDER_BIG_ENDIAN, \
+ .offset = offsetof(struct icmphdr, __member) * 8, \
+ .len = field_sizeof(struct icmphdr, __member) * 8, \
+ .icmp_dep = (__dep), \
+ }
+
#define ICMPHDR_TYPE(__name, __type, __member) \
- HDR_TYPE(__name, __type, struct icmphdr, __member)
+ HDR_TYPE(__name, __type, struct icmphdr, __member)
const struct proto_desc proto_icmp = {
.name = "icmp",
.id = PROTO_DESC_ICMP,
.base = PROTO_BASE_TRANSPORT_HDR,
+ .protocol_key = ICMPHDR_TYPE,
.checksum_key = ICMPHDR_CHECKSUM,
.checksum_type = NFT_PAYLOAD_CSUM_INET,
.templates = {
[ICMPHDR_TYPE] = ICMPHDR_TYPE("type", &icmp_type_type, type),
[ICMPHDR_CODE] = ICMPHDR_TYPE("code", &icmp_code_type, code),
- [ICMPHDR_CHECKSUM] = ICMPHDR_FIELD("checksum", checksum),
- [ICMPHDR_ID] = ICMPHDR_FIELD("id", un.echo.id),
- [ICMPHDR_SEQ] = ICMPHDR_FIELD("sequence", un.echo.sequence),
- [ICMPHDR_GATEWAY] = ICMPHDR_FIELD("gateway", un.gateway),
- [ICMPHDR_MTU] = ICMPHDR_FIELD("mtu", un.frag.mtu),
+ [ICMPHDR_CHECKSUM] = ICMPHDR_FIELD("checksum", checksum, PROTO_ICMP_ANY),
+ [ICMPHDR_ID] = ICMPHDR_FIELD("id", un.echo.id, PROTO_ICMP_ECHO),
+ [ICMPHDR_SEQ] = ICMPHDR_FIELD("sequence", un.echo.sequence, PROTO_ICMP_ECHO),
+ [ICMPHDR_GATEWAY] = ICMPHDR_FIELD("gateway", un.gateway, PROTO_ICMP_ADDRESS),
+ [ICMPHDR_MTU] = ICMPHDR_FIELD("mtu", un.frag.mtu, PROTO_ICMP_MTU),
},
};
--
2.26.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH nft 04/10] tests: fix exepcted payload of icmp expressions
2020-12-09 17:49 [PATCH nft 0/10] nft: add automatic icmp/icmpv6 dependencies Florian Westphal
` (2 preceding siblings ...)
2020-12-09 17:49 ` [PATCH nft 03/10] src: add auto-dependencies for ipv4 icmp Florian Westphal
@ 2020-12-09 17:49 ` Florian Westphal
2020-12-09 17:49 ` [PATCH nft 05/10] src: add auto-dependencies for ipv6 icmp6 Florian Westphal
` (6 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Florian Westphal @ 2020-12-09 17:49 UTC (permalink / raw)
To: netfilter-devel; +Cc: Florian Westphal
after previous change nft will insert explicit icmp type match.
Signed-off-by: Florian Westphal <fw@strlen.de>
---
tests/py/ip/icmp.t.payload.ip | 131 +++++++++++++++++++++++++++++++++-
1 file changed, 130 insertions(+), 1 deletion(-)
diff --git a/tests/py/ip/icmp.t.payload.ip b/tests/py/ip/icmp.t.payload.ip
index 2185feb81021..6ed4dff86d10 100644
--- a/tests/py/ip/icmp.t.payload.ip
+++ b/tests/py/ip/icmp.t.payload.ip
@@ -272,148 +272,233 @@ ip test-ip4 input
[ immediate reg 0 accept ]
# icmp id 1245 log
+__set%d test-ip4 3
+__set%d test-ip4 0
+ element 00000008 : 0 [end] element 00000000 : 0 [end]
ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ lookup reg 1 set __set%d ]
[ payload load 2b @ transport header + 4 => reg 1 ]
[ cmp eq reg 1 0x0000dd04 ]
[ log ]
# icmp id 22
+__set%d test-ip4 3
+__set%d test-ip4 0
+ element 00000008 : 0 [end] element 00000000 : 0 [end]
ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ lookup reg 1 set __set%d ]
[ payload load 2b @ transport header + 4 => reg 1 ]
[ cmp eq reg 1 0x00001600 ]
# icmp id != 233
+__set%d test-ip4 3
+__set%d test-ip4 0
+ element 00000008 : 0 [end] element 00000000 : 0 [end]
ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ lookup reg 1 set __set%d ]
[ payload load 2b @ transport header + 4 => reg 1 ]
[ cmp neq reg 1 0x0000e900 ]
# icmp id 33-45
+__set%d test-ip4 3
+__set%d test-ip4 input
+ element 00000008 : 0 [end] element 00000000 : 0 [end]
ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ lookup reg 1 set __set%d ]
[ payload load 2b @ transport header + 4 => reg 1 ]
[ cmp gte reg 1 0x00002100 ]
[ cmp lte reg 1 0x00002d00 ]
# icmp id != 33-45
+__set%d test-ip4 3
+__set%d test-ip4 0
+ element 00000008 : 0 [end] element 00000000 : 0 [end]
ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ lookup reg 1 set __set%d ]
[ payload load 2b @ transport header + 4 => reg 1 ]
[ range neq reg 1 0x00002100 0x00002d00 ]
# icmp id { 33-55}
+__set%d test-ip4 3
+__set%d test-ip4 0
+ element 00000008 : 0 [end] element 00000000 : 0 [end]
__set%d test-ip4 7
__set%d test-ip4 0
element 00000000 : 1 [end] element 00002100 : 0 [end] element 00003800 : 1 [end]
ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ lookup reg 1 set __set%d ]
[ payload load 2b @ transport header + 4 => reg 1 ]
[ lookup reg 1 set __set%d ]
# icmp id != { 33-55}
+__set%d test-ip4 3
+__set%d test-ip4 0
+ element 00000008 : 0 [end] element 00000000 : 0 [end]
__set%d test-ip4 7
__set%d test-ip4 0
element 00000000 : 1 [end] element 00002100 : 0 [end] element 00003800 : 1 [end]
ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ lookup reg 1 set __set%d ]
[ payload load 2b @ transport header + 4 => reg 1 ]
[ lookup reg 1 set __set%d 0x1 ]
# icmp id { 22, 34, 333}
__set%d test-ip4 3
+__set%d test-ip4 0
+ element 00000008 : 0 [end] element 00000000 : 0 [end]
+__set%d test-ip4 3
__set%d test-ip4 0
element 00001600 : 0 [end] element 00002200 : 0 [end] element 00004d01 : 0 [end]
ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ lookup reg 1 set __set%d ]
[ payload load 2b @ transport header + 4 => reg 1 ]
[ lookup reg 1 set __set%d ]
# icmp id != { 22, 34, 333}
__set%d test-ip4 3
+__set%d test-ip4 0
+ element 00000008 : 0 [end] element 00000000 : 0 [end]
+__set%d test-ip4 3
__set%d test-ip4 0
element 00001600 : 0 [end] element 00002200 : 0 [end] element 00004d01 : 0 [end]
ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ lookup reg 1 set __set%d ]
[ payload load 2b @ transport header + 4 => reg 1 ]
[ lookup reg 1 set __set%d 0x1 ]
# icmp sequence 22
-ip test-ip4 input
+__set%d test-ip4 3
+__set%d test-ip4 0
+ element 00000008 : 0 [end] element 00000000 : 0 [end]
+ip
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ lookup reg 1 set __set%d ]
[ payload load 2b @ transport header + 6 => reg 1 ]
[ cmp eq reg 1 0x00001600 ]
# icmp sequence != 233
+__set%d test-ip4 3
+__set%d test-ip4 0
+ element 00000008 : 0 [end] element 00000000 : 0 [end]
ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ lookup reg 1 set __set%d ]
[ payload load 2b @ transport header + 6 => reg 1 ]
[ cmp neq reg 1 0x0000e900 ]
# icmp sequence 33-45
+__set%d test-ip4 3
+__set%d test-ip4 0
+ element 00000008 : 0 [end] element 00000000 : 0 [end]
ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ lookup reg 1 set __set%d ]
[ payload load 2b @ transport header + 6 => reg 1 ]
[ cmp gte reg 1 0x00002100 ]
[ cmp lte reg 1 0x00002d00 ]
# icmp sequence != 33-45
+__set%d test-ip4 3
+__set%d test-ip4 0
+ element 00000008 : 0 [end] element 00000000 : 0 [end]
ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ lookup reg 1 set __set%d ]
[ payload load 2b @ transport header + 6 => reg 1 ]
[ range neq reg 1 0x00002100 0x00002d00 ]
# icmp sequence { 33, 55, 67, 88}
__set%d test-ip4 3
+__set%d test-ip4 0
+ element 00000008 : 0 [end] element 00000000 : 0 [end]
+__set%d test-ip4 3
__set%d test-ip4 0
element 00002100 : 0 [end] element 00003700 : 0 [end] element 00004300 : 0 [end] element 00005800 : 0 [end]
ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ lookup reg 1 set __set%d ]
[ payload load 2b @ transport header + 6 => reg 1 ]
[ lookup reg 1 set __set%d ]
# icmp sequence != { 33, 55, 67, 88}
__set%d test-ip4 3
+__set%d test-ip4 0
+ element 00000008 : 0 [end] element 00000000 : 0 [end]
+__set%d test-ip4 3
__set%d test-ip4 0
element 00002100 : 0 [end] element 00003700 : 0 [end] element 00004300 : 0 [end] element 00005800 : 0 [end]
ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ lookup reg 1 set __set%d ]
[ payload load 2b @ transport header + 6 => reg 1 ]
[ lookup reg 1 set __set%d 0x1 ]
# icmp sequence { 33-55}
+__set%d test-ip4 3
+__set%d test-ip4 0
+ element 00000008 : 0 [end] element 00000000 : 0 [end]
__set%d test-ip4 7
__set%d test-ip4 0
element 00000000 : 1 [end] element 00002100 : 0 [end] element 00003800 : 1 [end]
ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ lookup reg 1 set __set%d ]
[ payload load 2b @ transport header + 6 => reg 1 ]
[ lookup reg 1 set __set%d ]
# icmp sequence != { 33-55}
+__set%d test-ip4 3
+__set%d test-ip4 0
+ element 00000008 : 0 [end] element 00000000 : 0 [end]
__set%d test-ip4 7
__set%d test-ip4 0
element 00000000 : 1 [end] element 00002100 : 0 [end] element 00003800 : 1 [end]
ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ lookup reg 1 set __set%d ]
[ payload load 2b @ transport header + 6 => reg 1 ]
[ lookup reg 1 set __set%d 0x1 ]
@@ -421,6 +506,8 @@ ip test-ip4 input
ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ cmp eq reg 1 0x00000003 ]
[ payload load 2b @ transport header + 6 => reg 1 ]
[ cmp eq reg 1 0x00002100 ]
@@ -428,6 +515,8 @@ ip test-ip4 input
ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ cmp eq reg 1 0x00000003 ]
[ payload load 2b @ transport header + 6 => reg 1 ]
[ cmp gte reg 1 0x00001600 ]
[ cmp lte reg 1 0x00002100 ]
@@ -439,6 +528,8 @@ __set%d test-ip4 0
ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ cmp eq reg 1 0x00000003 ]
[ payload load 2b @ transport header + 6 => reg 1 ]
[ lookup reg 1 set __set%d ]
@@ -449,6 +540,8 @@ __set%d test-ip4 0
ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ cmp eq reg 1 0x00000003 ]
[ payload load 2b @ transport header + 6 => reg 1 ]
[ lookup reg 1 set __set%d 0x1 ]
@@ -456,6 +549,8 @@ ip test-ip4 input
ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ cmp eq reg 1 0x00000003 ]
[ payload load 2b @ transport header + 6 => reg 1 ]
[ cmp eq reg 1 0x00001600 ]
@@ -463,6 +558,8 @@ ip test-ip4 input
ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ cmp eq reg 1 0x00000003 ]
[ payload load 2b @ transport header + 6 => reg 1 ]
[ cmp neq reg 1 0x0000e900 ]
@@ -470,6 +567,8 @@ ip test-ip4 input
ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ cmp eq reg 1 0x00000003 ]
[ payload load 2b @ transport header + 6 => reg 1 ]
[ cmp gte reg 1 0x00002100 ]
[ cmp lte reg 1 0x00002d00 ]
@@ -478,6 +577,8 @@ ip test-ip4 input
ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ cmp eq reg 1 0x00000003 ]
[ payload load 2b @ transport header + 6 => reg 1 ]
[ range neq reg 1 0x00002100 0x00002d00 ]
@@ -488,6 +589,8 @@ __set%d test-ip4 0
ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ cmp eq reg 1 0x00000003 ]
[ payload load 2b @ transport header + 6 => reg 1 ]
[ lookup reg 1 set __set%d ]
@@ -498,6 +601,8 @@ __set%d test-ip4 0
ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ cmp eq reg 1 0x00000003 ]
[ payload load 2b @ transport header + 6 => reg 1 ]
[ lookup reg 1 set __set%d 0x1 ]
@@ -508,6 +613,8 @@ __set%d test-ip4 0
ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ cmp eq reg 1 0x00000003 ]
[ payload load 2b @ transport header + 6 => reg 1 ]
[ lookup reg 1 set __set%d ]
@@ -518,6 +625,8 @@ __set%d test-ip4 0
ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ cmp eq reg 1 0x00000003 ]
[ payload load 2b @ transport header + 6 => reg 1 ]
[ lookup reg 1 set __set%d 0x1 ]
@@ -525,6 +634,8 @@ ip test-ip4 input
ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ cmp eq reg 1 0x00000005 ]
[ payload load 4b @ transport header + 4 => reg 1 ]
[ cmp eq reg 1 0x16000000 ]
@@ -532,6 +643,8 @@ ip test-ip4 input
ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ cmp eq reg 1 0x00000005 ]
[ payload load 4b @ transport header + 4 => reg 1 ]
[ cmp neq reg 1 0xe9000000 ]
@@ -539,6 +652,8 @@ ip test-ip4 input
ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ cmp eq reg 1 0x00000005 ]
[ payload load 4b @ transport header + 4 => reg 1 ]
[ cmp gte reg 1 0x21000000 ]
[ cmp lte reg 1 0x2d000000 ]
@@ -547,6 +662,8 @@ ip test-ip4 input
ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ cmp eq reg 1 0x00000005 ]
[ payload load 4b @ transport header + 4 => reg 1 ]
[ range neq reg 1 0x21000000 0x2d000000 ]
@@ -557,6 +674,8 @@ __set%d test-ip4 0
ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ cmp eq reg 1 0x00000005 ]
[ payload load 4b @ transport header + 4 => reg 1 ]
[ lookup reg 1 set __set%d ]
@@ -567,6 +686,8 @@ __set%d test-ip4 0
ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ cmp eq reg 1 0x00000005 ]
[ payload load 4b @ transport header + 4 => reg 1 ]
[ lookup reg 1 set __set%d 0x1 ]
@@ -577,6 +698,8 @@ __set%d test-ip4 0
ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ cmp eq reg 1 0x00000005 ]
[ payload load 4b @ transport header + 4 => reg 1 ]
[ lookup reg 1 set __set%d ]
@@ -587,6 +710,8 @@ __set%d test-ip4 0
ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ cmp eq reg 1 0x00000005 ]
[ payload load 4b @ transport header + 4 => reg 1 ]
[ lookup reg 1 set __set%d 0x1 ]
@@ -594,6 +719,8 @@ ip test-ip4 input
ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ cmp eq reg 1 0x00000005 ]
[ payload load 4b @ transport header + 4 => reg 1 ]
[ cmp neq reg 1 0x22000000 ]
@@ -604,6 +731,8 @@ __set%d test-ip4 0
ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ cmp eq reg 1 0x00000005 ]
[ payload load 4b @ transport header + 4 => reg 1 ]
[ lookup reg 1 set __set%d 0x1 ]
--
2.26.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH nft 05/10] src: add auto-dependencies for ipv6 icmp6
2020-12-09 17:49 [PATCH nft 0/10] nft: add automatic icmp/icmpv6 dependencies Florian Westphal
` (3 preceding siblings ...)
2020-12-09 17:49 ` [PATCH nft 04/10] tests: fix exepcted payload of icmp expressions Florian Westphal
@ 2020-12-09 17:49 ` Florian Westphal
2020-12-09 17:49 ` [PATCH nft 06/10] tests: fix exepcted payload of icmpv6 expressions Florian Westphal
` (5 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Florian Westphal @ 2020-12-09 17:49 UTC (permalink / raw)
To: netfilter-devel; +Cc: Florian Westphal
Extend the earlier commit to also cover icmpv6.
Signed-off-by: Florian Westphal <fw@strlen.de>
---
include/proto.h | 4 ++++
src/evaluate.c | 2 +-
src/payload.c | 33 +++++++++++++++++++++++++++++++++
src/proto.c | 26 +++++++++++++++-----------
4 files changed, 53 insertions(+), 12 deletions(-)
diff --git a/include/proto.h b/include/proto.h
index f383291b5a79..b9217588f3e3 100644
--- a/include/proto.h
+++ b/include/proto.h
@@ -30,6 +30,10 @@ enum icmp_hdr_field_type {
PROTO_ICMP_ECHO, /* echo and reply */
PROTO_ICMP_MTU, /* destination unreachable */
PROTO_ICMP_ADDRESS, /* redirect */
+ PROTO_ICMP6_MTU,
+ PROTO_ICMP6_PPTR,
+ PROTO_ICMP6_ECHO,
+ PROTO_ICMP6_MGMQ,
};
/**
diff --git a/src/evaluate.c b/src/evaluate.c
index 3eb8e1bfc2c5..e776cd018051 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -729,7 +729,7 @@ static int __expr_evaluate_payload(struct eval_ctx *ctx, struct expr *expr)
payload->payload.offset += ctx->pctx.protocol[base].offset;
check_icmp:
- if (desc != &proto_icmp)
+ if (desc != &proto_icmp && desc != &proto_icmp6)
return 0;
tmpl = expr->payload.tmpl;
diff --git a/src/payload.c b/src/payload.c
index 54b08f051dc0..7cfa530c06c6 100644
--- a/src/payload.c
+++ b/src/payload.c
@@ -20,6 +20,7 @@
#include <linux/netfilter.h>
#include <linux/if_ether.h>
#include <netinet/ip_icmp.h>
+#include <netinet/icmp6.h>
#include <rule.h>
#include <expression.h>
@@ -677,8 +678,12 @@ static uint8_t icmp_dep_to_type(enum icmp_hdr_field_type t)
case PROTO_ICMP_ANY:
BUG("Invalid map for simple dependency");
case PROTO_ICMP_ECHO: return ICMP_ECHO;
+ case PROTO_ICMP6_ECHO: return ICMP6_ECHO_REQUEST;
case PROTO_ICMP_MTU: return ICMP_DEST_UNREACH;
case PROTO_ICMP_ADDRESS: return ICMP_REDIRECT;
+ case PROTO_ICMP6_MTU: return ICMP6_PACKET_TOO_BIG;
+ case PROTO_ICMP6_MGMQ: return MLD_LISTENER_QUERY;
+ case PROTO_ICMP6_PPTR: return ICMP6_PARAM_PROB;
}
BUG("Missing icmp type mapping");
@@ -1023,6 +1028,34 @@ int payload_gen_icmp_dependency(struct eval_ctx *ctx, const struct expr *expr,
&icmp_type_type,
desc, type);
break;
+ case PROTO_ICMP6_ECHO:
+ if (ctx->pctx.th_dep.icmp.type == ICMP6_ECHO_REQUEST ||
+ ctx->pctx.th_dep.icmp.type == ICMP6_ECHO_REPLY)
+ goto done;
+
+ type = ICMP6_ECHO_REQUEST;
+ if (ctx->pctx.th_dep.icmp.type)
+ goto bad_proto;
+
+ stmt = __payload_gen_icmp_echo_dependency(ctx, expr,
+ ICMP6_ECHO_REQUEST,
+ ICMP6_ECHO_REPLY,
+ &icmp6_type_type,
+ desc);
+ break;
+ case PROTO_ICMP6_MTU:
+ case PROTO_ICMP6_MGMQ:
+ case PROTO_ICMP6_PPTR:
+ type = icmp_dep_to_type(tmpl->icmp_dep);
+ if (ctx->pctx.th_dep.icmp.type == type)
+ goto done;
+ if (ctx->pctx.th_dep.icmp.type)
+ goto bad_proto;
+ stmt = __payload_gen_icmp_simple_dependency(ctx, expr,
+ &icmp6_type_type,
+ desc, type);
+ break;
+ break;
default:
BUG("Unhandled icmp dependency code");
}
diff --git a/src/proto.c b/src/proto.c
index d3371ac65975..b75626df2861 100644
--- a/src/proto.c
+++ b/src/proto.c
@@ -396,16 +396,19 @@ const struct datatype icmp_type_type = {
.sym_tbl = &icmp_type_tbl,
};
-#define ICMPHDR_FIELD(__token, __member, __dep) \
+#define ICMP46HDR_FIELD(__token, __struct, __member, __dep) \
{ \
.token = (__token), \
.dtype = &integer_type, \
.byteorder = BYTEORDER_BIG_ENDIAN, \
- .offset = offsetof(struct icmphdr, __member) * 8, \
- .len = field_sizeof(struct icmphdr, __member) * 8, \
+ .offset = offsetof(__struct, __member) * 8, \
+ .len = field_sizeof(__struct, __member) * 8, \
.icmp_dep = (__dep), \
}
+#define ICMPHDR_FIELD(__token, __member, __dep) \
+ ICMP46HDR_FIELD(__token, struct icmphdr, __member, __dep)
+
#define ICMPHDR_TYPE(__name, __type, __member) \
HDR_TYPE(__name, __type, struct icmphdr, __member)
@@ -822,8 +825,8 @@ const struct datatype icmp6_type_type = {
.sym_tbl = &icmp6_type_tbl,
};
-#define ICMP6HDR_FIELD(__name, __member) \
- HDR_FIELD(__name, struct icmp6_hdr, __member)
+#define ICMP6HDR_FIELD(__token, __member, __dep) \
+ ICMP46HDR_FIELD(__token, struct icmp6_hdr, __member, __dep)
#define ICMP6HDR_TYPE(__name, __type, __member) \
HDR_TYPE(__name, __type, struct icmp6_hdr, __member)
@@ -831,17 +834,18 @@ const struct proto_desc proto_icmp6 = {
.name = "icmpv6",
.id = PROTO_DESC_ICMPV6,
.base = PROTO_BASE_TRANSPORT_HDR,
+ .protocol_key = ICMP6HDR_TYPE,
.checksum_key = ICMP6HDR_CHECKSUM,
.checksum_type = NFT_PAYLOAD_CSUM_INET,
.templates = {
[ICMP6HDR_TYPE] = ICMP6HDR_TYPE("type", &icmp6_type_type, icmp6_type),
[ICMP6HDR_CODE] = ICMP6HDR_TYPE("code", &icmpv6_code_type, icmp6_code),
- [ICMP6HDR_CHECKSUM] = ICMP6HDR_FIELD("checksum", icmp6_cksum),
- [ICMP6HDR_PPTR] = ICMP6HDR_FIELD("parameter-problem", icmp6_pptr),
- [ICMP6HDR_MTU] = ICMP6HDR_FIELD("mtu", icmp6_mtu),
- [ICMP6HDR_ID] = ICMP6HDR_FIELD("id", icmp6_id),
- [ICMP6HDR_SEQ] = ICMP6HDR_FIELD("sequence", icmp6_seq),
- [ICMP6HDR_MAXDELAY] = ICMP6HDR_FIELD("max-delay", icmp6_maxdelay),
+ [ICMP6HDR_CHECKSUM] = ICMP6HDR_FIELD("checksum", icmp6_cksum, PROTO_ICMP_ANY),
+ [ICMP6HDR_PPTR] = ICMP6HDR_FIELD("parameter-problem", icmp6_pptr, PROTO_ICMP6_PPTR),
+ [ICMP6HDR_MTU] = ICMP6HDR_FIELD("mtu", icmp6_mtu, PROTO_ICMP6_MTU),
+ [ICMP6HDR_ID] = ICMP6HDR_FIELD("id", icmp6_id, PROTO_ICMP6_ECHO),
+ [ICMP6HDR_SEQ] = ICMP6HDR_FIELD("sequence", icmp6_seq, PROTO_ICMP6_ECHO),
+ [ICMP6HDR_MAXDELAY] = ICMP6HDR_FIELD("max-delay", icmp6_maxdelay, PROTO_ICMP6_MGMQ),
},
};
--
2.26.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH nft 06/10] tests: fix exepcted payload of icmpv6 expressions
2020-12-09 17:49 [PATCH nft 0/10] nft: add automatic icmp/icmpv6 dependencies Florian Westphal
` (4 preceding siblings ...)
2020-12-09 17:49 ` [PATCH nft 05/10] src: add auto-dependencies for ipv6 icmp6 Florian Westphal
@ 2020-12-09 17:49 ` Florian Westphal
2020-12-09 17:49 ` [PATCH nft 07/10] payload: auto-remove simple icmp/icmpv6 dependency expressions Florian Westphal
` (4 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Florian Westphal @ 2020-12-09 17:49 UTC (permalink / raw)
To: netfilter-devel; +Cc: Florian Westphal
nft will now auto-insert a icmpv6 type match.
Signed-off-by: Florian Westphal <fw@strlen.de>
---
tests/py/ip6/icmpv6.t.payload.ip6 | 107 +++++++++++++++++++++++++++---
1 file changed, 97 insertions(+), 10 deletions(-)
diff --git a/tests/py/ip6/icmpv6.t.payload.ip6 b/tests/py/ip6/icmpv6.t.payload.ip6
index 51d71f4149b5..406bdd6dab93 100644
--- a/tests/py/ip6/icmpv6.t.payload.ip6
+++ b/tests/py/ip6/icmpv6.t.payload.ip6
@@ -327,6 +327,8 @@ ip6 test-ip6 input
ip6 test-ip6 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x0000003a ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ cmp eq reg 1 0x00000002 ]
[ payload load 4b @ transport header + 4 => reg 1 ]
[ cmp eq reg 1 0x16000000 ]
@@ -334,6 +336,8 @@ ip6 test-ip6 input
ip6 test-ip6 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x0000003a ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ cmp eq reg 1 0x00000002 ]
[ payload load 4b @ transport header + 4 => reg 1 ]
[ cmp neq reg 1 0xe9000000 ]
@@ -341,6 +345,8 @@ ip6 test-ip6 input
ip6 test-ip6 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x0000003a ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ cmp eq reg 1 0x00000002 ]
[ payload load 4b @ transport header + 4 => reg 1 ]
[ cmp gte reg 1 0x21000000 ]
[ cmp lte reg 1 0x2d000000 ]
@@ -349,6 +355,8 @@ ip6 test-ip6 input
ip6 test-ip6 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x0000003a ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ cmp eq reg 1 0x00000002 ]
[ payload load 4b @ transport header + 4 => reg 1 ]
[ range neq reg 1 0x21000000 0x2d000000 ]
@@ -359,6 +367,8 @@ __set%d test-ip6 0
ip6 test-ip6 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x0000003a ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ cmp eq reg 1 0x00000002 ]
[ payload load 4b @ transport header + 4 => reg 1 ]
[ lookup reg 1 set __set%d ]
@@ -369,6 +379,8 @@ __set%d test-ip6 0
ip6 test-ip6 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x0000003a ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ cmp eq reg 1 0x00000002 ]
[ payload load 4b @ transport header + 4 => reg 1 ]
[ lookup reg 1 set __set%d 0x1 ]
@@ -379,6 +391,8 @@ __set%d test-ip6 0
ip6 test-ip6 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x0000003a ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ cmp eq reg 1 0x00000002 ]
[ payload load 4b @ transport header + 4 => reg 1 ]
[ lookup reg 1 set __set%d ]
@@ -389,145 +403,206 @@ __set%d test-ip6 0
ip6 test-ip6 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x0000003a ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ cmp eq reg 1 0x00000002 ]
[ payload load 4b @ transport header + 4 => reg 1 ]
[ lookup reg 1 set __set%d 0x1 ]
# icmpv6 id 33-45
+__set%d test-ip6 3
+__set%d test-ip6 0
+ element 00000080 : 0 [end] element 00000081 : 0 [end]
ip6 test-ip6 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x0000003a ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ lookup reg 1 set __set%d ]
[ payload load 2b @ transport header + 4 => reg 1 ]
[ cmp gte reg 1 0x00002100 ]
[ cmp lte reg 1 0x00002d00 ]
# icmpv6 id != 33-45
+__set%d test-ip6 3
+__set%d test-ip6 0
+ element 00000080 : 0 [end] element 00000081 : 0 [end]
ip6 test-ip6 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x0000003a ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ lookup reg 1 set __set%d ]
[ payload load 2b @ transport header + 4 => reg 1 ]
[ range neq reg 1 0x00002100 0x00002d00 ]
# icmpv6 id {33, 55, 67, 88}
__set%d test-ip6 3
+__set%d test-ip6 0
+ element 00000080 : 0 [end] element 00000081 : 0 [end]
+__set%d test-ip6 3
__set%d test-ip6 0
element 00002100 : 0 [end] element 00003700 : 0 [end] element 00004300 : 0 [end] element 00005800 : 0 [end]
ip6 test-ip6 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x0000003a ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ lookup reg 1 set __set%d ]
[ payload load 2b @ transport header + 4 => reg 1 ]
[ lookup reg 1 set __set%d ]
# icmpv6 id != {33, 55, 67, 88}
__set%d test-ip6 3
+__set%d test-ip6 0
+ element 00000080 : 0 [end] element 00000081 : 0 [end]
+__set%d test-ip6 3
__set%d test-ip6 0
element 00002100 : 0 [end] element 00003700 : 0 [end] element 00004300 : 0 [end] element 00005800 : 0 [end]
ip6 test-ip6 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x0000003a ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ lookup reg 1 set __set%d ]
[ payload load 2b @ transport header + 4 => reg 1 ]
[ lookup reg 1 set __set%d 0x1 ]
# icmpv6 id {33-55}
+__set%d test-ip6 3
+__set%d test-ip6 0
+ element 00000080 : 0 [end] element 00000081 : 0 [end]
__set%d test-ip6 7
__set%d test-ip6 0
element 00000000 : 1 [end] element 00002100 : 0 [end] element 00003800 : 1 [end]
ip6 test-ip6 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x0000003a ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ lookup reg 1 set __set%d ]
[ payload load 2b @ transport header + 4 => reg 1 ]
[ lookup reg 1 set __set%d ]
# icmpv6 id != {33-55}
+__set%d test-ip6 3
+__set%d test-ip6 0
+ element 00000080 : 0 [end] element 00000081 : 0 [end]
__set%d test-ip6 7
__set%d test-ip6 0
element 00000000 : 1 [end] element 00002100 : 0 [end] element 00003800 : 1 [end]
ip6 test-ip6 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x0000003a ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ lookup reg 1 set __set%d ]
[ payload load 2b @ transport header + 4 => reg 1 ]
[ lookup reg 1 set __set%d 0x1 ]
# icmpv6 sequence 2
+__set%d test-ip6 3
+__set%d test-ip6 0
+ element 00000080 : 0 [end] element 00000081 : 0 [end]
ip6 test-ip6 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x0000003a ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ lookup reg 1 set __set%d ]
[ payload load 2b @ transport header + 6 => reg 1 ]
[ cmp eq reg 1 0x00000200 ]
# icmpv6 sequence {3, 4, 5, 6, 7} accept
__set%d test-ip6 3
__set%d test-ip6 0
- element 00000300 : 0 [end] element 00000400 : 0 [end] element 00000500 : 0 [end] element 00000600 : 0 [end] element 00000700 : 0 [end]
-ip6 test-ip6 input
- [ meta load l4proto => reg 1 ]
- [ cmp eq reg 1 0x0000003a ]
- [ payload load 2b @ transport header + 6 => reg 1 ]
- [ lookup reg 1 set __set%d ]
- [ immediate reg 0 accept ]
-
-# icmpv6 sequence != {3, 4, 5, 6, 7} accept
+ element 00000080 : 0 [end] element 00000081 : 0 [end]
__set%d test-ip6 3
__set%d test-ip6 0
element 00000300 : 0 [end] element 00000400 : 0 [end] element 00000500 : 0 [end] element 00000600 : 0 [end] element 00000700 : 0 [end]
ip6 test-ip6 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x0000003a ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ lookup reg 1 set __set%d ]
[ payload load 2b @ transport header + 6 => reg 1 ]
- [ lookup reg 1 set __set%d 0x1 ]
+ [ lookup reg 1 set __set%d ]
[ immediate reg 0 accept ]
# icmpv6 sequence {2, 4}
__set%d test-ip6 3
+__set%d test-ip6 0
+ element 00000080 : 0 [end] element 00000081 : 0 [end]
+__set%d test-ip6 3
__set%d test-ip6 0
element 00000200 : 0 [end] element 00000400 : 0 [end]
ip6 test-ip6 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x0000003a ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ lookup reg 1 set __set%d ]
[ payload load 2b @ transport header + 6 => reg 1 ]
[ lookup reg 1 set __set%d ]
# icmpv6 sequence != {2, 4}
__set%d test-ip6 3
+__set%d test-ip6 0
+ element 00000080 : 0 [end] element 00000081 : 0 [end]
+__set%d test-ip6 3
__set%d test-ip6 0
element 00000200 : 0 [end] element 00000400 : 0 [end]
ip6 test-ip6 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x0000003a ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ lookup reg 1 set __set%d ]
[ payload load 2b @ transport header + 6 => reg 1 ]
[ lookup reg 1 set __set%d 0x1 ]
# icmpv6 sequence 2-4
+__set%d test-ip6 3
+__set%d test-ip6 0
+ element 00000080 : 0 [end] element 00000081 : 0 [end]
ip6 test-ip6 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x0000003a ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ lookup reg 1 set __set%d ]
[ payload load 2b @ transport header + 6 => reg 1 ]
[ cmp gte reg 1 0x00000200 ]
[ cmp lte reg 1 0x00000400 ]
# icmpv6 sequence != 2-4
+__set%d test-ip6 3
+__set%d test-ip6 0
+ element 00000080 : 0 [end] element 00000081 : 0 [end]
ip6 test-ip6 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x0000003a ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ lookup reg 1 set __set%d ]
[ payload load 2b @ transport header + 6 => reg 1 ]
[ range neq reg 1 0x00000200 0x00000400 ]
# icmpv6 sequence { 2-4}
+__set%d test-ip6 3
+__set%d test-ip6 0
+ element 00000080 : 0 [end] element 00000081 : 0 [end]
__set%d test-ip6 7
__set%d test-ip6 0
element 00000000 : 1 [end] element 00000200 : 0 [end] element 00000500 : 1 [end]
ip6 test-ip6 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x0000003a ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ lookup reg 1 set __set%d ]
[ payload load 2b @ transport header + 6 => reg 1 ]
[ lookup reg 1 set __set%d ]
# icmpv6 sequence != { 2-4}
+__set%d test-ip6 3
+__set%d test-ip6 0
+ element 00000080 : 0 [end] element 00000081 : 0 [end]
__set%d test-ip6 7
__set%d test-ip6 0
element 00000000 : 1 [end] element 00000200 : 0 [end] element 00000500 : 1 [end]
ip6 test-ip6 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x0000003a ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ lookup reg 1 set __set%d ]
[ payload load 2b @ transport header + 6 => reg 1 ]
[ lookup reg 1 set __set%d 0x1 ]
@@ -535,6 +610,8 @@ ip6 test-ip6 input
ip6 test-ip6 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x0000003a ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ cmp eq reg 1 0x00000082 ]
[ payload load 2b @ transport header + 4 => reg 1 ]
[ cmp gte reg 1 0x00002100 ]
[ cmp lte reg 1 0x00002d00 ]
@@ -543,6 +620,8 @@ ip6 test-ip6 input
ip6 test-ip6 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x0000003a ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ cmp eq reg 1 0x00000082 ]
[ payload load 2b @ transport header + 4 => reg 1 ]
[ range neq reg 1 0x00002100 0x00002d00 ]
@@ -553,6 +632,8 @@ __set%d test-ip6 0
ip6 test-ip6 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x0000003a ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ cmp eq reg 1 0x00000082 ]
[ payload load 2b @ transport header + 4 => reg 1 ]
[ lookup reg 1 set __set%d ]
@@ -563,6 +644,8 @@ __set%d test-ip6 0
ip6 test-ip6 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x0000003a ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ cmp eq reg 1 0x00000082 ]
[ payload load 2b @ transport header + 4 => reg 1 ]
[ lookup reg 1 set __set%d 0x1 ]
@@ -573,6 +656,8 @@ __set%d test-ip6 0
ip6 test-ip6 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x0000003a ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ cmp eq reg 1 0x00000082 ]
[ payload load 2b @ transport header + 4 => reg 1 ]
[ lookup reg 1 set __set%d ]
@@ -583,6 +668,8 @@ __set%d test-ip6 0
ip6 test-ip6 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x0000003a ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ cmp eq reg 1 0x00000082 ]
[ payload load 2b @ transport header + 4 => reg 1 ]
[ lookup reg 1 set __set%d 0x1 ]
--
2.26.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH nft 07/10] payload: auto-remove simple icmp/icmpv6 dependency expressions
2020-12-09 17:49 [PATCH nft 0/10] nft: add automatic icmp/icmpv6 dependencies Florian Westphal
` (5 preceding siblings ...)
2020-12-09 17:49 ` [PATCH nft 06/10] tests: fix exepcted payload of icmpv6 expressions Florian Westphal
@ 2020-12-09 17:49 ` Florian Westphal
2020-12-09 17:49 ` [PATCH nft 08/10] tests: icmp, icmpv6: avoid remaining warnings Florian Westphal
` (3 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Florian Westphal @ 2020-12-09 17:49 UTC (permalink / raw)
To: netfilter-devel; +Cc: Florian Westphal
Instead of:
icmpv6 type packet-too-big icmpv6 mtu 1280
display just
icmpv6 mtu 1280
The dependency added for id/sequence is still kept, its handled
by a anon set instead to cover both the echo 'request' and 'reply' cases.
Signed-off-by: Florian Westphal <fw@strlen.de>
---
include/payload.h | 4 +++-
src/netlink_delinearize.c | 3 +++
src/payload.c | 50 ++++++++++++++++++++++++++++++++++++---
3 files changed, 53 insertions(+), 4 deletions(-)
diff --git a/include/payload.h b/include/payload.h
index 7bbb19b936a9..8bc3fb9a8a54 100644
--- a/include/payload.h
+++ b/include/payload.h
@@ -26,11 +26,13 @@ extern int exthdr_gen_dependency(struct eval_ctx *ctx, const struct expr *expr,
* struct payload_dep_ctx - payload protocol dependency tracking
*
* @pbase: protocol base of last dependency match
+ * @icmp_type: extra info for icmp(6) decoding
* @pdep: last dependency match
* @prev: previous statement
*/
struct payload_dep_ctx {
- enum proto_bases pbase;
+ enum proto_bases pbase:8;
+ uint8_t icmp_type;
struct stmt *pdep;
struct stmt *prev;
};
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index 9faddde63974..8b06c4c0985f 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -1771,6 +1771,9 @@ static void payload_match_expand(struct rule_pp_ctx *ctx,
enum proto_bases base = left->payload.base;
bool stacked;
+ if (ctx->pdctx.icmp_type)
+ ctx->pctx.th_dep.icmp.type = ctx->pdctx.icmp_type;
+
payload_expr_expand(&list, left, &ctx->pctx);
list_for_each_entry(left, &list, list) {
diff --git a/src/payload.c b/src/payload.c
index 7cfa530c06c6..48529bcf5c51 100644
--- a/src/payload.c
+++ b/src/payload.c
@@ -98,7 +98,7 @@ static void payload_expr_pctx_update(struct proto_ctx *ctx,
desc = proto_find_upper(base, proto);
if (!desc) {
- if (base == &proto_icmp) {
+ if (base == &proto_icmp || base == &proto_icmp6) {
/* proto 0 is ECHOREPLY, just pretend its ECHO.
* Not doing this would need an additional marker
* bit to tell when icmp.type was set.
@@ -554,6 +554,35 @@ void payload_dependency_reset(struct payload_dep_ctx *ctx)
memset(ctx, 0, sizeof(*ctx));
}
+static uint8_t icmp_get_type(const struct proto_desc *desc, uint8_t value)
+{
+ if (desc == &proto_icmp && value == 0)
+ return ICMP_ECHO;
+
+ return value;
+}
+
+static uint8_t icmp_get_dep_type(const struct proto_desc *desc, struct expr *right)
+{
+ if (right->etype == EXPR_VALUE && right->len == BITS_PER_BYTE)
+ return icmp_get_type(desc, mpz_get_uint8(right->value));
+
+ return 0;
+}
+
+static void payload_dependency_store_icmp_type(struct payload_dep_ctx *ctx)
+{
+ struct expr *dep = ctx->pdep->expr;
+ const struct proto_desc *desc;
+
+ if (dep->left->etype != EXPR_PAYLOAD)
+ return;
+
+ desc = dep->left->payload.desc;
+ if (desc == &proto_icmp || desc == &proto_icmp6)
+ ctx->icmp_type = icmp_get_dep_type(dep->left->payload.desc, dep->right);
+}
+
/**
* payload_dependency_store - store a possibly redundant protocol match
*
@@ -566,6 +595,8 @@ void payload_dependency_store(struct payload_dep_ctx *ctx,
{
ctx->pbase = base + 1;
ctx->pdep = stmt;
+
+ payload_dependency_store_icmp_type(ctx);
}
/**
@@ -581,8 +612,8 @@ bool payload_dependency_exists(const struct payload_dep_ctx *ctx,
enum proto_bases base)
{
return ctx->pbase != PROTO_BASE_INVALID &&
- ctx->pbase == base &&
- ctx->pdep != NULL;
+ ctx->pdep != NULL &&
+ (ctx->pbase == base || (base == PROTO_BASE_TRANSPORT_HDR && ctx->pbase == base + 1));
}
void payload_dependency_release(struct payload_dep_ctx *ctx)
@@ -649,6 +680,10 @@ void payload_dependency_kill(struct payload_dep_ctx *ctx, struct expr *expr,
if (payload_dependency_exists(ctx, expr->payload.base) &&
payload_may_dependency_kill(ctx, family, expr))
payload_dependency_release(ctx);
+ else if (ctx->icmp_type && ctx->pdep) {
+ fprintf(stderr, "Did not kill \n");
+ payload_dependency_release(ctx);
+ }
}
void exthdr_dependency_kill(struct payload_dep_ctx *ctx, struct expr *expr,
@@ -716,6 +751,11 @@ void payload_expr_complete(struct expr *expr, const struct proto_ctx *ctx)
if (tmpl->offset != expr->payload.offset ||
tmpl->len != expr->len)
continue;
+
+ if (tmpl->icmp_dep && ctx->th_dep.icmp.type &&
+ ctx->th_dep.icmp.type != icmp_dep_to_type(tmpl->icmp_dep))
+ continue;
+
expr->dtype = tmpl->dtype;
expr->payload.desc = desc;
expr->payload.tmpl = tmpl;
@@ -842,6 +882,10 @@ void payload_expr_expand(struct list_head *list, struct expr *expr,
if (tmpl->offset != expr->payload.offset)
continue;
+ if (tmpl->icmp_dep && ctx->th_dep.icmp.type &&
+ ctx->th_dep.icmp.type != icmp_dep_to_type(tmpl->icmp_dep))
+ continue;
+
if (tmpl->len <= expr->len) {
new = payload_expr_alloc(&expr->location, desc, i);
list_add_tail(&new->list, list);
--
2.26.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH nft 08/10] tests: icmp, icmpv6: avoid remaining warnings
2020-12-09 17:49 [PATCH nft 0/10] nft: add automatic icmp/icmpv6 dependencies Florian Westphal
` (6 preceding siblings ...)
2020-12-09 17:49 ` [PATCH nft 07/10] payload: auto-remove simple icmp/icmpv6 dependency expressions Florian Westphal
@ 2020-12-09 17:49 ` Florian Westphal
2020-12-09 17:49 ` [PATCH nft 09/10] tests: ip: add one test case to cover both id and sequence Florian Westphal
` (2 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Florian Westphal @ 2020-12-09 17:49 UTC (permalink / raw)
To: netfilter-devel; +Cc: Florian Westphal
In case of id/sequence, both 'reply' and 'request' are valid types.
nft currently does not remove dependencies that don't have
a fixed rhs constant.
Signed-off-by: Florian Westphal <fw@strlen.de>
---
tests/py/ip/icmp.t | 35 ++++++++++++++++++-----------------
tests/py/ip6/icmpv6.t | 41 ++++++++++++++++-------------------------
2 files changed, 34 insertions(+), 42 deletions(-)
diff --git a/tests/py/ip/icmp.t b/tests/py/ip/icmp.t
index cb3b3e356964..e81aeca76088 100644
--- a/tests/py/ip/icmp.t
+++ b/tests/py/ip/icmp.t
@@ -40,24 +40,25 @@ icmp checksum != { 11-343} accept;ok
icmp checksum { 1111, 222, 343} accept;ok
icmp checksum != { 1111, 222, 343} accept;ok
-icmp id 1245 log;ok
-icmp id 22;ok
-icmp id != 233;ok
-icmp id 33-45;ok
-icmp id != 33-45;ok
-icmp id { 33-55};ok
-icmp id != { 33-55};ok
-icmp id { 22, 34, 333};ok
-icmp id != { 22, 34, 333};ok
+icmp id 1245 log;ok;icmp type { echo-reply, echo-request} icmp id 1245 log
+icmp id 22;ok;icmp type { echo-reply, echo-request} icmp id 22
+icmp id != 233;ok;icmp type { echo-reply, echo-request} icmp id != 233
+icmp id 33-45;ok;icmp type { echo-reply, echo-request} icmp id 33-45
+icmp id != 33-45;ok;icmp type { echo-reply, echo-request} icmp id != 33-45
+icmp id { 33-55};ok;icmp type { echo-reply, echo-request} icmp id { 33-55}
+icmp id != { 33-55};ok;icmp type { echo-reply, echo-request} icmp id != { 33-55}
-icmp sequence 22;ok
-icmp sequence != 233;ok
-icmp sequence 33-45;ok
-icmp sequence != 33-45;ok
-icmp sequence { 33, 55, 67, 88};ok
-icmp sequence != { 33, 55, 67, 88};ok
-icmp sequence { 33-55};ok
-icmp sequence != { 33-55};ok
+icmp id { 22, 34, 333};ok;icmp type { echo-request, echo-reply} icmp id { 22, 34, 333}
+icmp id != { 22, 34, 333};ok;icmp type { echo-request, echo-reply} icmp id != { 22, 34, 333}
+
+icmp sequence 22;ok;icmp type { echo-reply, echo-request} icmp sequence 22
+icmp sequence != 233;ok;icmp type { echo-reply, echo-request} icmp sequence != 233
+icmp sequence 33-45;ok;icmp type { echo-reply, echo-request} icmp sequence 33-45
+icmp sequence != 33-45;ok;icmp type { echo-reply, echo-request} icmp sequence != 33-45
+icmp sequence { 33, 55, 67, 88};ok;icmp type { echo-request, echo-reply} icmp sequence { 33, 55, 67, 88}
+icmp sequence != { 33, 55, 67, 88};ok;icmp type { echo-request, echo-reply} icmp sequence != { 33, 55, 67, 88}
+icmp sequence { 33-55};ok;icmp type { echo-request, echo-reply} icmp sequence { 33-55}
+icmp sequence != { 33-55};ok;icmp type { echo-request, echo-reply} icmp sequence != { 33-55}
icmp mtu 33;ok
icmp mtu 22-33;ok
diff --git a/tests/py/ip6/icmpv6.t b/tests/py/ip6/icmpv6.t
index 8d794115d51e..67fa6ca8490f 100644
--- a/tests/py/ip6/icmpv6.t
+++ b/tests/py/ip6/icmpv6.t
@@ -44,9 +44,8 @@ icmpv6 checksum != { 222, 226};ok
icmpv6 checksum { 222-226};ok
icmpv6 checksum != { 222-226};ok
-# BUG: icmpv6 parameter-problem, pptr, mtu, packet-too-big
+# BUG: icmpv6 parameter-problem, pptr
# [ICMP6HDR_PPTR] = ICMP6HDR_FIELD("parameter-problem", icmp6_pptr),
-# [ICMP6HDR_MTU] = ICMP6HDR_FIELD("packet-too-big", icmp6_mtu),
# $ sudo nft add rule ip6 test6 input icmpv6 parameter-problem 35
# <cmdline>:1:53-53: Error: syntax error, unexpected end of file
# add rule ip6 test6 input icmpv6 parameter-problem 35
@@ -59,11 +58,6 @@ icmpv6 checksum != { 222-226};ok
# <cmdline>:1:54-54: Error: syntax error, unexpected end of file
# add rule ip6 test6 input icmpv6 parameter-problem 2-4
-# BUG: packet-too-big
-# $ sudo nft add rule ip6 test6 input icmpv6 packet-too-big 34
-# <cmdline>:1:50-50: Error: syntax error, unexpected end of file
-# add rule ip6 test6 input icmpv6 packet-too-big 34
-
icmpv6 mtu 22;ok
icmpv6 mtu != 233;ok
icmpv6 mtu 33-45;ok
@@ -73,27 +67,24 @@ icmpv6 mtu != {33, 55, 67, 88};ok
icmpv6 mtu {33-55};ok
icmpv6 mtu != {33-55};ok
-- icmpv6 id 2;ok
-- icmpv6 id != 233;ok
-icmpv6 id 33-45;ok
-icmpv6 id != 33-45;ok
-icmpv6 id {33, 55, 67, 88};ok
-icmpv6 id != {33, 55, 67, 88};ok
-icmpv6 id {33-55};ok
-icmpv6 id != {33-55};ok
+icmpv6 id 33-45;ok;icmpv6 type { echo-request, echo-reply} icmpv6 id 33-45
+icmpv6 id != 33-45;ok;icmpv6 type { echo-request, echo-reply} icmpv6 id != 33-45
+icmpv6 id {33, 55, 67, 88};ok;icmpv6 type { echo-request, echo-reply} icmpv6 id { 33, 55, 67, 88}
+icmpv6 id != {33, 55, 67, 88};ok;icmpv6 type { echo-request, echo-reply} icmpv6 id != { 33, 55, 67, 88}
+icmpv6 id {33-55};ok;icmpv6 type { echo-request, echo-reply} icmpv6 id { 33-55}
+icmpv6 id != {33-55};ok;icmpv6 type { echo-request, echo-reply} icmpv6 id != { 33-55}
+
+icmpv6 sequence 2;ok;icmpv6 type { echo-request, echo-reply} icmpv6 sequence 2
+icmpv6 sequence {3, 4, 5, 6, 7} accept;ok;icmpv6 type { echo-request, echo-reply} icmpv6 sequence { 3, 4, 5, 6, 7} accept
-icmpv6 sequence 2;ok
-icmpv6 sequence {3, 4, 5, 6, 7} accept;ok
-icmpv6 sequence {2, 4};ok
-icmpv6 sequence != {2, 4};ok
-icmpv6 sequence 2-4;ok
-icmpv6 sequence != 2-4;ok
-icmpv6 sequence { 2-4};ok
-icmpv6 sequence != { 2-4};ok
+icmpv6 sequence {2, 4};ok;icmpv6 type { echo-request, echo-reply} icmpv6 sequence { 2, 4}
+icmpv6 sequence != {2, 4};ok;icmpv6 type { echo-request, echo-reply} icmpv6 sequence != { 2, 4}
+icmpv6 sequence 2-4;ok;icmpv6 type { echo-request, echo-reply} icmpv6 sequence 2-4
+icmpv6 sequence != 2-4;ok;icmpv6 type { echo-request, echo-reply} icmpv6 sequence != 2-4
+icmpv6 sequence { 2-4};ok;icmpv6 type { echo-request, echo-reply} icmpv6 sequence { 2-4}
+icmpv6 sequence != { 2-4};ok;icmpv6 type { echo-request, echo-reply} icmpv6 sequence != { 2-4}
-- icmpv6 max-delay 22;ok
-- icmpv6 max-delay != 233;ok
icmpv6 max-delay 33-45;ok
icmpv6 max-delay != 33-45;ok
icmpv6 max-delay {33, 55, 67, 88};ok
--
2.26.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH nft 09/10] tests: ip: add one test case to cover both id and sequence
2020-12-09 17:49 [PATCH nft 0/10] nft: add automatic icmp/icmpv6 dependencies Florian Westphal
` (7 preceding siblings ...)
2020-12-09 17:49 ` [PATCH nft 08/10] tests: icmp, icmpv6: avoid remaining warnings Florian Westphal
@ 2020-12-09 17:49 ` Florian Westphal
2020-12-09 17:49 ` [PATCH nft 10/10] tests: icmp, icmpv6: check we don't add second dependency Florian Westphal
2020-12-11 14:30 ` [PATCH nft 0/10] nft: add automatic icmp/icmpv6 dependencies Phil Sutter
10 siblings, 0 replies; 12+ messages in thread
From: Florian Westphal @ 2020-12-09 17:49 UTC (permalink / raw)
To: netfilter-devel; +Cc: Florian Westphal
These are two 2-byte matches, so nft will merge the accesses to
a single 4-byte load+compare.
Check this is properly demangled.
Signed-off-by: Florian Westphal <fw@strlen.de>
---
tests/py/ip/icmp.t | 2 ++
tests/py/ip/icmp.t.payload.ip | 12 ++++++++++++
2 files changed, 14 insertions(+)
diff --git a/tests/py/ip/icmp.t b/tests/py/ip/icmp.t
index e81aeca76088..996e1fc321e4 100644
--- a/tests/py/ip/icmp.t
+++ b/tests/py/ip/icmp.t
@@ -59,6 +59,7 @@ icmp sequence { 33, 55, 67, 88};ok;icmp type { echo-request, echo-reply} icmp se
icmp sequence != { 33, 55, 67, 88};ok;icmp type { echo-request, echo-reply} icmp sequence != { 33, 55, 67, 88}
icmp sequence { 33-55};ok;icmp type { echo-request, echo-reply} icmp sequence { 33-55}
icmp sequence != { 33-55};ok;icmp type { echo-request, echo-reply} icmp sequence != { 33-55}
+icmp id 1 icmp sequence 2;ok;icmp type { echo-reply, echo-request} icmp id 1 icmp sequence 2
icmp mtu 33;ok
icmp mtu 22-33;ok
@@ -83,3 +84,4 @@ icmp gateway { 33-55};ok
icmp gateway != { 33-55};ok
icmp gateway != 34;ok
icmp gateway != { 333, 334};ok
+
diff --git a/tests/py/ip/icmp.t.payload.ip b/tests/py/ip/icmp.t.payload.ip
index 6ed4dff86d10..e238c4bb142c 100644
--- a/tests/py/ip/icmp.t.payload.ip
+++ b/tests/py/ip/icmp.t.payload.ip
@@ -502,6 +502,18 @@ ip test-ip4 input
[ payload load 2b @ transport header + 6 => reg 1 ]
[ lookup reg 1 set __set%d 0x1 ]
+# icmp id 1 icmp sequence 2
+__set%d test-ip4 3
+__set%d test-ip4 0
+ element 00000008 : 0 [end] element 00000000 : 0 [end]
+ip
+ [ meta load l4proto => reg 1 ]
+ [ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ lookup reg 1 set __set%d ]
+ [ payload load 4b @ transport header + 4 => reg 1 ]
+ [ cmp eq reg 1 0x02000100 ]
+
# icmp mtu 33
ip test-ip4 input
[ meta load l4proto => reg 1 ]
--
2.26.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH nft 10/10] tests: icmp, icmpv6: check we don't add second dependency
2020-12-09 17:49 [PATCH nft 0/10] nft: add automatic icmp/icmpv6 dependencies Florian Westphal
` (8 preceding siblings ...)
2020-12-09 17:49 ` [PATCH nft 09/10] tests: ip: add one test case to cover both id and sequence Florian Westphal
@ 2020-12-09 17:49 ` Florian Westphal
2020-12-11 14:30 ` [PATCH nft 0/10] nft: add automatic icmp/icmpv6 dependencies Phil Sutter
10 siblings, 0 replies; 12+ messages in thread
From: Florian Westphal @ 2020-12-09 17:49 UTC (permalink / raw)
To: netfilter-devel; +Cc: Florian Westphal
If dependency is already fulfilled, do not add another one.
Signed-off-by: Florian Westphal <fw@strlen.de>
---
tests/py/ip/icmp.t | 1 +
tests/py/ip/icmp.t.payload.ip | 12 ++++++++++++
tests/py/ip6/icmpv6.t | 1 +
tests/py/ip6/icmpv6.t.payload.ip6 | 9 +++++++++
4 files changed, 23 insertions(+)
diff --git a/tests/py/ip/icmp.t b/tests/py/ip/icmp.t
index 996e1fc321e4..c22b55eb1e3f 100644
--- a/tests/py/ip/icmp.t
+++ b/tests/py/ip/icmp.t
@@ -60,6 +60,7 @@ icmp sequence != { 33, 55, 67, 88};ok;icmp type { echo-request, echo-reply} icmp
icmp sequence { 33-55};ok;icmp type { echo-request, echo-reply} icmp sequence { 33-55}
icmp sequence != { 33-55};ok;icmp type { echo-request, echo-reply} icmp sequence != { 33-55}
icmp id 1 icmp sequence 2;ok;icmp type { echo-reply, echo-request} icmp id 1 icmp sequence 2
+icmp type { echo-reply, echo-request} icmp id 1 icmp sequence 2;ok
icmp mtu 33;ok
icmp mtu 22-33;ok
diff --git a/tests/py/ip/icmp.t.payload.ip b/tests/py/ip/icmp.t.payload.ip
index e238c4bb142c..d75d12a06125 100644
--- a/tests/py/ip/icmp.t.payload.ip
+++ b/tests/py/ip/icmp.t.payload.ip
@@ -514,6 +514,18 @@ ip
[ payload load 4b @ transport header + 4 => reg 1 ]
[ cmp eq reg 1 0x02000100 ]
+# icmp type { echo-reply, echo-request} icmp id 1 icmp sequence 2
+__set%d test-ip4 3
+__set%d test-ip4 0
+ element 00000000 : 0 [end] element 00000008 : 0 [end]
+ip
+ [ meta load l4proto => reg 1 ]
+ [ cmp eq reg 1 0x00000001 ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ lookup reg 1 set __set%d ]
+ [ payload load 4b @ transport header + 4 => reg 1 ]
+ [ cmp eq reg 1 0x02000100 ]
+
# icmp mtu 33
ip test-ip4 input
[ meta load l4proto => reg 1 ]
diff --git a/tests/py/ip6/icmpv6.t b/tests/py/ip6/icmpv6.t
index 67fa6ca8490f..8b411a8bf439 100644
--- a/tests/py/ip6/icmpv6.t
+++ b/tests/py/ip6/icmpv6.t
@@ -66,6 +66,7 @@ icmpv6 mtu {33, 55, 67, 88};ok
icmpv6 mtu != {33, 55, 67, 88};ok
icmpv6 mtu {33-55};ok
icmpv6 mtu != {33-55};ok
+icmpv6 type packet-too-big icmpv6 mtu 1280;ok;icmpv6 mtu 1280
icmpv6 id 33-45;ok;icmpv6 type { echo-request, echo-reply} icmpv6 id 33-45
icmpv6 id != 33-45;ok;icmpv6 type { echo-request, echo-reply} icmpv6 id != 33-45
diff --git a/tests/py/ip6/icmpv6.t.payload.ip6 b/tests/py/ip6/icmpv6.t.payload.ip6
index 406bdd6dab93..171b7eade6d3 100644
--- a/tests/py/ip6/icmpv6.t.payload.ip6
+++ b/tests/py/ip6/icmpv6.t.payload.ip6
@@ -408,6 +408,15 @@ ip6 test-ip6 input
[ payload load 4b @ transport header + 4 => reg 1 ]
[ lookup reg 1 set __set%d 0x1 ]
+# icmpv6 type packet-too-big icmpv6 mtu 1280
+ip6
+ [ meta load l4proto => reg 1 ]
+ [ cmp eq reg 1 0x0000003a ]
+ [ payload load 1b @ transport header + 0 => reg 1 ]
+ [ cmp eq reg 1 0x00000002 ]
+ [ payload load 4b @ transport header + 4 => reg 1 ]
+ [ cmp eq reg 1 0x00050000 ]
+
# icmpv6 id 33-45
__set%d test-ip6 3
__set%d test-ip6 0
--
2.26.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH nft 0/10] nft: add automatic icmp/icmpv6 dependencies
2020-12-09 17:49 [PATCH nft 0/10] nft: add automatic icmp/icmpv6 dependencies Florian Westphal
` (9 preceding siblings ...)
2020-12-09 17:49 ` [PATCH nft 10/10] tests: icmp, icmpv6: check we don't add second dependency Florian Westphal
@ 2020-12-11 14:30 ` Phil Sutter
10 siblings, 0 replies; 12+ messages in thread
From: Phil Sutter @ 2020-12-11 14:30 UTC (permalink / raw)
To: Florian Westphal; +Cc: netfilter-devel
Hi Florian,
On Wed, Dec 09, 2020 at 06:49:14PM +0100, Florian Westphal wrote:
> This series allows nft to automatically add the dependency so that
> the type-dependant field is not evaluated for any type.
Great work, thanks for taking care of this long-standing issue!
Thanks, Phil
^ permalink raw reply [flat|nested] 12+ messages in thread