[PATCH 2/7 nft] tunnel: add erspan support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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





[Index of Archives]     [Netfitler Users]     [Berkeley Packet Filter]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux