From: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx> This patch extends the tunnel metadata object to define erspan tunnel specific configurations: table netdev x { tunnel y { id 10 ip saddr 192.168.2.10 ip daddr 192.168.2.11 sport 10 dport 20 ttl 10 erspan { version 1 index 2 } } } Joint work with Fernando. Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx> --- include/rule.h | 18 ++++++++++++++++++ src/mnl.c | 24 ++++++++++++++++++++++++ src/netlink.c | 16 ++++++++++++++++ src/parser_bison.y | 46 +++++++++++++++++++++++++++++++++++++++++++++- src/rule.c | 26 ++++++++++++++++++++++++++ src/scanner.l | 5 +++++ 6 files changed, 134 insertions(+), 1 deletion(-) diff --git a/include/rule.h b/include/rule.h index c10db949..2723af38 100644 --- a/include/rule.h +++ b/include/rule.h @@ -490,6 +490,11 @@ struct secmark { char ctx[NFT_SECMARK_CTX_MAXLEN]; }; +enum tunnel_type { + TUNNEL_UNSPEC = 0, + TUNNEL_ERSPAN, +}; + struct tunnel { uint32_t id; struct expr *src; @@ -498,6 +503,19 @@ struct tunnel { uint16_t dport; uint8_t tos; uint8_t ttl; + enum tunnel_type type; + union { + struct { + uint32_t version; + struct { + uint32_t index; + } v1; + struct { + uint8_t direction; + uint8_t hwid; + } v2; + } erspan; + }; }; /** diff --git a/src/mnl.c b/src/mnl.c index ee46892e..34d919ea 100644 --- a/src/mnl.c +++ b/src/mnl.c @@ -1580,6 +1580,30 @@ int mnl_nft_obj_add(struct netlink_ctx *ctx, struct cmd *cmd, nld.value, nld.len); } } + switch (obj->tunnel.type) { + case TUNNEL_ERSPAN: + nftnl_obj_set_u32(nlo, + NFTNL_OBJ_TUNNEL_ERSPAN_VERSION, + obj->tunnel.erspan.version); + switch (obj->tunnel.erspan.version) { + case 1: + nftnl_obj_set_u32(nlo, + NFTNL_OBJ_TUNNEL_ERSPAN_V1_INDEX, + obj->tunnel.erspan.v1.index); + break; + case 2: + nftnl_obj_set_u8(nlo, + NFTNL_OBJ_TUNNEL_ERSPAN_V2_DIR, + obj->tunnel.erspan.v2.direction); + nftnl_obj_set_u8(nlo, + NFTNL_OBJ_TUNNEL_ERSPAN_V2_HWID, + obj->tunnel.erspan.v2.hwid); + break; + } + break; + case TUNNEL_UNSPEC: + break; + } break; default: BUG("Unknown type %d\n", obj->type); diff --git a/src/netlink.c b/src/netlink.c index ccf43580..086846ce 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -1885,6 +1885,22 @@ struct obj *netlink_delinearize_obj(struct netlink_ctx *ctx, obj->tunnel.dst = netlink_obj_tunnel_parse_addr(nlo, NFTNL_OBJ_TUNNEL_IPV6_DST); } + if (nftnl_obj_is_set(nlo, NFTNL_OBJ_TUNNEL_ERSPAN_VERSION)) { + obj->tunnel.type = TUNNEL_ERSPAN; + obj->tunnel.erspan.version = nftnl_obj_get_u32(nlo, NFTNL_OBJ_TUNNEL_ERSPAN_VERSION); + } + if (nftnl_obj_is_set(nlo, NFTNL_OBJ_TUNNEL_ERSPAN_V1_INDEX)) { + obj->tunnel.type = TUNNEL_ERSPAN; + obj->tunnel.erspan.v1.index = nftnl_obj_get_u8(nlo, NFTNL_OBJ_TUNNEL_ERSPAN_V1_INDEX); + } + if (nftnl_obj_is_set(nlo, NFTNL_OBJ_TUNNEL_ERSPAN_V2_DIR)) { + obj->tunnel.type = TUNNEL_ERSPAN; + obj->tunnel.erspan.v2.direction = nftnl_obj_get_u8(nlo, NFTNL_OBJ_TUNNEL_ERSPAN_V2_DIR); + } + if (nftnl_obj_is_set(nlo, NFTNL_OBJ_TUNNEL_ERSPAN_V2_HWID)) { + obj->tunnel.type = TUNNEL_ERSPAN; + obj->tunnel.erspan.v2.hwid = nftnl_obj_get_u8(nlo, NFTNL_OBJ_TUNNEL_ERSPAN_V2_HWID); + } break; default: netlink_io_error(ctx, NULL, "Unknown object type %u", type); diff --git a/src/parser_bison.y b/src/parser_bison.y index c4694c77..9ba6e8f2 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -606,6 +606,9 @@ int nft_lex(void *, void *, void *); %token NEVER "never" %token TUNNEL "tunnel" +%token ERSPAN "erspan" +%token EGRESS "egress" +%token INGRESS "ingress" %token COUNTERS "counters" %token QUOTAS "quotas" @@ -764,7 +767,7 @@ int nft_lex(void *, void *, void *); %type <flowtable> flowtable_block_alloc flowtable_block %destructor { flowtable_free($$); } flowtable_block_alloc -%type <obj> obj_block_alloc counter_block quota_block ct_helper_block ct_timeout_block ct_expect_block limit_block secmark_block synproxy_block tunnel_block +%type <obj> obj_block_alloc counter_block quota_block ct_helper_block ct_timeout_block ct_expect_block limit_block secmark_block synproxy_block tunnel_block erspan_block erspan_block_alloc %destructor { obj_free($$); } obj_block_alloc %type <list> stmt_list stateful_stmt_list set_elem_stmt_list @@ -4948,6 +4951,43 @@ limit_obj : /* empty */ } ; +erspan_block : /* empty */ { $$ = $<obj>-1; } + | erspan_block common_block + | erspan_block stmt_separator + | erspan_block erspan_config stmt_separator + { + $$ = $1; + } + ; + +erspan_block_alloc : /* empty */ + { + $$ = $<obj>-1; + } + ; + +erspan_config : HDRVERSION NUM + { + $<obj>0->tunnel.erspan.version = $2; + } + | INDEX NUM + { + $<obj>0->tunnel.erspan.v1.index = $2; + } + | DIRECTION INGRESS + { + $<obj>0->tunnel.erspan.v2.direction = 0; + } + | DIRECTION EGRESS + { + $<obj>0->tunnel.erspan.v2.direction = 1; + } + | ID NUM + { + $<obj>0->tunnel.erspan.v2.hwid = $2; + } + ; + tunnel_config : ID NUM { $<obj>0->tunnel.id = $2; @@ -4976,6 +5016,10 @@ tunnel_config : ID NUM { $<obj>0->tunnel.tos = $2; } + | ERSPAN erspan_block_alloc '{' erspan_block '}' + { + $<obj>0->tunnel.type = TUNNEL_ERSPAN; + } ; tunnel_block : /* empty */ { $$ = $<obj>-1; } diff --git a/src/rule.c b/src/rule.c index 1cea0d48..8acb6346 100644 --- a/src/rule.c +++ b/src/rule.c @@ -2005,6 +2005,32 @@ static void obj_print_data(const struct obj *obj, opts->nl, opts->tab, opts->tab, obj->tunnel.ttl); } + switch (obj->tunnel.type) { + case TUNNEL_ERSPAN: + nft_print(octx, "%s%s%serspan {", + opts->nl, opts->tab, opts->tab); + nft_print(octx, "%s%s%s%sversion %u", + opts->nl, opts->tab, opts->tab, opts->tab, + obj->tunnel.erspan.version); + if (obj->tunnel.erspan.version == 1) { + nft_print(octx, "%s%s%s%sindex %u", + opts->nl, opts->tab, opts->tab, opts->tab, + obj->tunnel.erspan.v1.index); + } else { + nft_print(octx, "%s%s%s%sdirection %s", + opts->nl, opts->tab, opts->tab, opts->tab, + obj->tunnel.erspan.v2.direction ? "egress" + : "ingress"); + nft_print(octx, "%s%s%s%sid %u", + opts->nl, opts->tab, opts->tab, opts->tab, + obj->tunnel.erspan.v2.hwid); + } + nft_print(octx, "%s%s%s}", + opts->nl, opts->tab, opts->tab); + default: + break; + } + nft_print(octx, "%s", opts->stmt_separator); break; default: diff --git a/src/scanner.l b/src/scanner.l index 232bce67..c5c394b7 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -817,6 +817,11 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr}) "dport" { return DPORT; } "ttl" { return TTL; } "tos" { return TOS; } + "version" { return HDRVERSION; } + "direction" { return DIRECTION; } + "erspan" { return ERSPAN; } + "egress" { return EGRESS; } + "ingress" { return INGRESS; } } "notrack" { return NOTRACK; } -- 2.49.0