summaryrefslogtreecommitdiffstats
path: root/include
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 /include
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 'include')
-rw-r--r--include/expression.h2
-rw-r--r--include/linux/netfilter/nf_tables.h27
-rw-r--r--include/netlink.h5
-rw-r--r--include/payload.h2
-rw-r--r--include/proto.h23
-rw-r--r--include/rule.h3
6 files changed, 59 insertions, 3 deletions
diff --git a/include/expression.h b/include/expression.h
index 3f06a38a..1f58a68c 100644
--- a/include/expression.h
+++ b/include/expression.h
@@ -316,6 +316,7 @@ struct expr {
/* EXPR_PAYLOAD */
const struct proto_desc *desc;
const struct proto_hdr_template *tmpl;
+ const struct proto_desc *inner_desc;
enum proto_bases base;
unsigned int offset;
bool is_raw;
@@ -334,6 +335,7 @@ struct expr {
/* EXPR_META */
enum nft_meta_keys key;
enum proto_bases base;
+ const struct proto_desc *inner_desc;
} meta;
struct {
/* SOCKET */
diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
index 466fd3f4..e4b739d5 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -760,6 +760,7 @@ enum nft_payload_bases {
NFT_PAYLOAD_NETWORK_HEADER,
NFT_PAYLOAD_TRANSPORT_HEADER,
NFT_PAYLOAD_INNER_HEADER,
+ NFT_PAYLOAD_TUN_HEADER,
};
/**
@@ -779,6 +780,32 @@ enum nft_payload_csum_flags {
NFT_PAYLOAD_L4CSUM_PSEUDOHDR = (1 << 0),
};
+enum nft_inner_type {
+ NFT_INNER_UNSPEC = 0,
+ NFT_INNER_VXLAN,
+ NFT_INNER_GENEVE,
+};
+
+enum nft_inner_flags {
+ NFT_INNER_HDRSIZE = (1 << 0),
+ NFT_INNER_LL = (1 << 1),
+ NFT_INNER_NH = (1 << 2),
+ NFT_INNER_TH = (1 << 3),
+};
+#define NFT_INNER_MASK (NFT_INNER_HDRSIZE | NFT_INNER_LL | \
+ NFT_INNER_NH | NFT_INNER_TH)
+
+enum nft_inner_attributes {
+ NFTA_INNER_UNSPEC,
+ NFTA_INNER_NUM,
+ NFTA_INNER_TYPE,
+ NFTA_INNER_FLAGS,
+ NFTA_INNER_HDRSIZE,
+ NFTA_INNER_EXPR,
+ __NFTA_INNER_MAX
+};
+#define NFTA_INNER_MAX (__NFTA_INNER_MAX - 1)
+
/**
* enum nft_payload_attributes - nf_tables payload expression netlink attributes
*
diff --git a/include/netlink.h b/include/netlink.h
index 4823f1e6..5a7f6a1e 100644
--- a/include/netlink.h
+++ b/include/netlink.h
@@ -40,6 +40,8 @@ struct netlink_parse_ctx {
struct expr *registers[MAX_REGS + 1];
unsigned int debug_mask;
struct netlink_ctx *nlctx;
+ bool inner;
+ uint8_t inner_reg;
};
@@ -55,7 +57,8 @@ struct dl_proto_ctx {
};
struct rule_pp_ctx {
- struct dl_proto_ctx _dl;
+ struct dl_proto_ctx _dl[2];
+ struct dl_proto_ctx *dl;
struct stmt *stmt;
unsigned int flags;
};
diff --git a/include/payload.h b/include/payload.h
index 37869928..aac553ee 100644
--- a/include/payload.h
+++ b/include/payload.h
@@ -67,4 +67,6 @@ extern void payload_expr_complete(struct expr *expr,
bool payload_expr_cmp(const struct expr *e1, const struct expr *e2);
+const struct proto_desc *find_proto_desc(const struct nftnl_udata *ud);
+
#endif /* NFTABLES_PAYLOAD_H */
diff --git a/include/proto.h b/include/proto.h
index 6a9289b1..5bb7562d 100644
--- a/include/proto.h
+++ b/include/proto.h
@@ -96,6 +96,7 @@ enum proto_desc_id {
PROTO_DESC_ARP,
PROTO_DESC_VLAN,
PROTO_DESC_ETHER,
+ PROTO_DESC_VXLAN,
__PROTO_DESC_MAX
};
#define PROTO_DESC_MAX (__PROTO_DESC_MAX - 1)
@@ -131,7 +132,11 @@ struct proto_desc {
uint32_t filter;
} format;
unsigned int pseudohdr[PROTO_HDRS_MAX];
-
+ struct {
+ uint32_t hdrsize;
+ uint32_t flags;
+ enum nft_inner_type type;
+ } inner;
};
#define PROTO_LINK(__num, __desc) { .num = (__num), .desc = (__desc), }
@@ -216,6 +221,8 @@ extern const struct proto_desc *proto_find_upper(const struct proto_desc *base,
unsigned int num);
extern int proto_find_num(const struct proto_desc *base,
const struct proto_desc *desc);
+const struct proto_desc *proto_find_inner(uint32_t type, uint32_t hdrsize,
+ uint32_t flags);
extern const struct proto_desc *proto_find_desc(enum proto_desc_id desc_id);
@@ -263,6 +270,7 @@ enum ip_hdr_fields {
IPHDR_SADDR,
IPHDR_DADDR,
};
+#define IPHDR_MAX IPHDR_DADDR
enum icmp_hdr_fields {
ICMPHDR_INVALID,
@@ -376,6 +384,19 @@ enum th_hdr_fields {
THDR_DPORT,
};
+struct vxlanhdr {
+ uint32_t vx_flags;
+ uint32_t vx_vni;
+};
+
+enum vxlan_hdr_fields {
+ VXLANHDR_INVALID,
+ VXLANHDR_VNI,
+ VXLANHDR_FLAGS,
+};
+
+extern const struct proto_desc proto_vxlan;
+
extern const struct proto_desc proto_icmp;
extern const struct proto_desc proto_igmp;
extern const struct proto_desc proto_ah;
diff --git a/include/rule.h b/include/rule.h
index c1b46414..d829f484 100644
--- a/include/rule.h
+++ b/include/rule.h
@@ -769,7 +769,8 @@ struct eval_ctx {
struct set *set;
struct stmt *stmt;
struct expr_ctx ectx;
- struct proto_ctx _pctx;
+ struct proto_ctx _pctx[2];
+ const struct proto_desc *inner_desc;
};
extern int cmd_evaluate(struct eval_ctx *ctx, struct cmd *cmd);