summaryrefslogtreecommitdiffstats
path: root/src/meta.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2023-01-02 15:36:25 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2023-01-02 15:36:25 +0100
commit772892a018b4431361a226020b0f7615ab2b304f (patch)
tree1c88e423b3c7db8b03f520fd8bf89b36fbd65b39 /src/meta.c
parent5e7304e12518ecb38ff45746650b5362f975500d (diff)
src: add vxlan matching support
This patch adds the initial infrastructure to support for inner header tunnel matching and its first user: vxlan. A new struct proto_desc field for payload and meta expression to specify that the expression refers to inner header matching is used. The existing codebase to generate bytecode is fully reused, allowing for reusing existing supported layer 2, 3 and 4 protocols. Syntax requires to specify vxlan before the inner protocol field: ... vxlan ip protocol udp ... vxlan ip saddr 1.2.3.0/24 This also works with concatenations and anonymous sets, eg. ... vxlan ip saddr . vxlan ip daddr { 1.2.3.4 . 4.3.2.1 } You have to restrict vxlan matching to udp traffic, otherwise it complains on missing transport protocol dependency, e.g. ... udp dport 4789 vxlan ip daddr 1.2.3.4 The bytecode that is generated uses the new inner expression: # nft --debug=netlink add rule netdev x y udp dport 4789 vxlan ip saddr 1.2.3.4 netdev x y [ meta load l4proto => reg 1 ] [ cmp eq reg 1 0x00000011 ] [ payload load 2b @ transport header + 2 => reg 1 ] [ cmp eq reg 1 0x0000b512 ] [ inner type 1 hdrsize 8 flags f [ meta load protocol => reg 1 ] ] [ cmp eq reg 1 0x00000008 ] [ inner type 1 hdrsize 8 flags f [ payload load 4b @ network header + 12 => reg 1 ] ] [ cmp eq reg 1 0x04030201 ] JSON support is not included in this patch. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/meta.c')
-rw-r--r--src/meta.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/src/meta.c b/src/meta.c
index 257bbc9f..bd8a41ba 100644
--- a/src/meta.c
+++ b/src/meta.c
@@ -734,6 +734,7 @@ static void meta_expr_clone(struct expr *new, const struct expr *expr)
{
new->meta.key = expr->meta.key;
new->meta.base = expr->meta.base;
+ new->meta.inner_desc = expr->meta.inner_desc;
}
/**
@@ -807,13 +808,19 @@ static void meta_expr_pctx_update(struct proto_ctx *ctx,
}
#define NFTNL_UDATA_META_KEY 0
-#define NFTNL_UDATA_META_MAX 1
+#define NFTNL_UDATA_META_INNER_DESC 1
+#define NFTNL_UDATA_META_MAX 2
static int meta_expr_build_udata(struct nftnl_udata_buf *udbuf,
const struct expr *expr)
{
nftnl_udata_put_u32(udbuf, NFTNL_UDATA_META_KEY, expr->meta.key);
+ if (expr->meta.inner_desc) {
+ nftnl_udata_put_u32(udbuf, NFTNL_UDATA_META_INNER_DESC,
+ expr->meta.inner_desc->id);
+ }
+
return 0;
}
@@ -825,6 +832,7 @@ static int meta_parse_udata(const struct nftnl_udata *attr, void *data)
switch (type) {
case NFTNL_UDATA_META_KEY:
+ case NFTNL_UDATA_META_INNER_DESC:
if (len != sizeof(uint32_t))
return -1;
break;
@@ -839,6 +847,8 @@ static int meta_parse_udata(const struct nftnl_udata *attr, void *data)
static struct expr *meta_expr_parse_udata(const struct nftnl_udata *attr)
{
const struct nftnl_udata *ud[NFTNL_UDATA_META_MAX + 1] = {};
+ const struct proto_desc *desc;
+ struct expr *expr;
uint32_t key;
int err;
@@ -852,7 +862,14 @@ static struct expr *meta_expr_parse_udata(const struct nftnl_udata *attr)
key = nftnl_udata_get_u32(ud[NFTNL_UDATA_META_KEY]);
- return meta_expr_alloc(&internal_location, key);
+ expr = meta_expr_alloc(&internal_location, key);
+
+ if (ud[NFTNL_UDATA_META_INNER_DESC]) {
+ desc = find_proto_desc(ud[NFTNL_UDATA_META_INNER_DESC]);
+ expr->meta.inner_desc = desc;
+ }
+
+ return expr;
}
const struct expr_ops meta_expr_ops = {