summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/proto.h2
-rw-r--r--src/netlink_delinearize.c3
-rw-r--r--src/parser_bison.y13
-rw-r--r--src/proto.c19
-rw-r--r--src/scanner.l1
5 files changed, 35 insertions, 3 deletions
diff --git a/include/proto.h b/include/proto.h
index c2c973f3..3a20ff8c 100644
--- a/include/proto.h
+++ b/include/proto.h
@@ -99,6 +99,7 @@ enum proto_desc_id {
PROTO_DESC_VXLAN,
PROTO_DESC_GENEVE,
PROTO_DESC_GRE,
+ PROTO_DESC_GRETAP,
__PROTO_DESC_MAX
};
#define PROTO_DESC_MAX (__PROTO_DESC_MAX - 1)
@@ -424,6 +425,7 @@ enum gre_hdr_fields {
extern const struct proto_desc proto_vxlan;
extern const struct proto_desc proto_geneve;
extern const struct proto_desc proto_gre;
+extern const struct proto_desc proto_gretap;
extern const struct proto_desc proto_icmp;
extern const struct proto_desc proto_igmp;
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index 4f99dabb..4cd6cc3a 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -1985,7 +1985,8 @@ static bool meta_outer_may_dependency_kill(struct rule_pp_ctx *ctx,
switch (l4proto) {
case IPPROTO_GRE:
- if (expr->payload.inner_desc == &proto_gre)
+ if (expr->payload.inner_desc == &proto_gre ||
+ expr->payload.inner_desc == &proto_gretap)
return true;
break;
default:
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 10270f12..ccf07a30 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -443,6 +443,7 @@ int nft_lex(void *, void *, void *);
%token VNI "vni"
%token GRE "gre"
+%token GRETAP "gretap"
%token GENEVE "geneve"
@@ -909,8 +910,8 @@ int nft_lex(void *, void *, void *);
%type <expr> inner_eth_expr inner_inet_expr inner_expr
%destructor { expr_free($$); } inner_eth_expr inner_inet_expr inner_expr
-%type <expr> vxlan_hdr_expr geneve_hdr_expr gre_hdr_expr
-%destructor { expr_free($$); } vxlan_hdr_expr geneve_hdr_expr gre_hdr_expr
+%type <expr> vxlan_hdr_expr geneve_hdr_expr gre_hdr_expr gretap_hdr_expr
+%destructor { expr_free($$); } vxlan_hdr_expr geneve_hdr_expr gre_hdr_expr gretap_hdr_expr
%type <val> vxlan_hdr_field geneve_hdr_field gre_hdr_field
%type <stmt> optstrip_stmt
@@ -5354,6 +5355,7 @@ payload_expr : payload_raw_expr
| vxlan_hdr_expr
| geneve_hdr_expr
| gre_hdr_expr
+ | gretap_hdr_expr
;
payload_raw_expr : AT payload_base_spec COMMA NUM COMMA NUM close_scope_at
@@ -5686,6 +5688,13 @@ gre_hdr_field : HDRVERSION { $$ = GREHDR_VERSION; }
| PROTOCOL { $$ = GREHDR_PROTOCOL; }
;
+gretap_hdr_expr : GRETAP close_scope_gre inner_expr
+ {
+ $$ = $3;
+ $$->payload.inner_desc = &proto_gretap;
+ }
+ ;
+
optstrip_stmt : RESET TCP OPTION tcp_hdr_option_type close_scope_tcp
{
$$ = optstrip_stmt_alloc(&@$, tcpopt_expr_alloc(&@$,
diff --git a/src/proto.c b/src/proto.c
index 0986a380..edf99e84 100644
--- a/src/proto.c
+++ b/src/proto.c
@@ -92,6 +92,7 @@ static const struct proto_desc *inner_protocols[] = {
&proto_vxlan,
&proto_geneve,
&proto_gre,
+ &proto_gretap,
};
const struct proto_desc *proto_find_inner(uint32_t type, uint32_t hdrsize,
@@ -796,6 +797,20 @@ const struct proto_desc proto_gre = {
},
};
+const struct proto_desc proto_gretap = {
+ .name = "gretap",
+ .id = PROTO_DESC_GRETAP,
+ .base = PROTO_BASE_TRANSPORT_HDR,
+ .templates = {
+ [0] = PROTO_META_TEMPLATE("l4proto", &inet_protocol_type, NFT_META_L4PROTO, 8),
+ },
+ .inner = {
+ .hdrsize = sizeof(struct grehdr),
+ .flags = NFT_INNER_LL | NFT_INNER_NH | NFT_INNER_TH,
+ .type = NFT_INNER_GENEVE + 2,
+ },
+};
+
#define IPHDR_FIELD(__name, __member) \
HDR_FIELD(__name, struct iphdr, __member)
#define IPHDR_ADDR(__name, __member) \
@@ -820,6 +835,7 @@ const struct proto_desc proto_ip = {
PROTO_LINK(IPPROTO_DCCP, &proto_dccp),
PROTO_LINK(IPPROTO_SCTP, &proto_sctp),
PROTO_LINK(IPPROTO_GRE, &proto_gre),
+ PROTO_LINK(IPPROTO_GRE, &proto_gretap),
},
.templates = {
[0] = PROTO_META_TEMPLATE("l4proto", &inet_protocol_type, NFT_META_L4PROTO, 8),
@@ -947,6 +963,7 @@ const struct proto_desc proto_ip6 = {
PROTO_LINK(IPPROTO_IGMP, &proto_igmp),
PROTO_LINK(IPPROTO_ICMPV6, &proto_icmp6),
PROTO_LINK(IPPROTO_GRE, &proto_gre),
+ PROTO_LINK(IPPROTO_GRE, &proto_gretap),
},
.templates = {
[0] = PROTO_META_TEMPLATE("l4proto", &inet_protocol_type, NFT_META_L4PROTO, 8),
@@ -1013,6 +1030,7 @@ const struct proto_desc proto_inet_service = {
PROTO_LINK(IPPROTO_IGMP, &proto_igmp),
PROTO_LINK(IPPROTO_ICMPV6, &proto_icmp6),
PROTO_LINK(IPPROTO_GRE, &proto_gre),
+ PROTO_LINK(IPPROTO_GRE, &proto_gretap),
},
.templates = {
[0] = PROTO_META_TEMPLATE("l4proto", &inet_protocol_type, NFT_META_L4PROTO, 8),
@@ -1281,6 +1299,7 @@ static const struct proto_desc *proto_definitions[PROTO_DESC_MAX + 1] = {
[PROTO_DESC_ETHER] = &proto_eth,
[PROTO_DESC_VXLAN] = &proto_vxlan,
[PROTO_DESC_GRE] = &proto_gre,
+ [PROTO_DESC_GRETAP] = &proto_gretap,
};
const struct proto_desc *proto_find_desc(enum proto_desc_id desc_id)
diff --git a/src/scanner.l b/src/scanner.l
index 1ac46d1a..9c85ee37 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -628,6 +628,7 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr})
"geneve" { return GENEVE; }
"gre" { scanner_push_start_cond(yyscanner, SCANSTATE_GRE); return GRE; }
+"gretap" { scanner_push_start_cond(yyscanner, SCANSTATE_GRE); return GRETAP; }
"tcp" { scanner_push_start_cond(yyscanner, SCANSTATE_TCP); return TCP; }