[PATCH 2/2 libnftnl] tunnel: add support to geneve

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

 



Signed-off-by: Fernando Fernandez Mancera <ffmancera@xxxxxxxxxx>
---
 include/libnftnl/object.h |   5 ++
 include/obj.h             |   6 +++
 src/obj/tunnel.c          | 103 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 114 insertions(+)

diff --git a/include/libnftnl/object.h b/include/libnftnl/object.h
index 9930355..0c695ea 100644
--- a/include/libnftnl/object.h
+++ b/include/libnftnl/object.h
@@ -117,9 +117,14 @@ enum {
 	NFTNL_OBJ_TUNNEL_ERSPAN_V1_INDEX,
 	NFTNL_OBJ_TUNNEL_ERSPAN_V2_HWID,
 	NFTNL_OBJ_TUNNEL_ERSPAN_V2_DIR,
+	NFTNL_OBJ_TUNNEL_GENEVE_CLASS,
+	NFTNL_OBJ_TUNNEL_GENEVE_TYPE,
+	NFTNL_OBJ_TUNNEL_GENEVE_DATA,
 	__NFTNL_OBJ_TUNNEL_MAX,
 };
 
+#define NFTNL_TUNNEL_GENEVE_DATA_MAXLEN	126
+
 enum {
 	NFTNL_OBJ_SECMARK_CTX	= NFTNL_OBJ_BASE,
 	__NFTNL_OBJ_SECMARK_MAX,
diff --git a/include/obj.h b/include/obj.h
index fc78e2a..e6c1cbf 100644
--- a/include/obj.h
+++ b/include/obj.h
@@ -92,6 +92,12 @@ struct nftnl_obj {
 						} v2;
 					} u;
 				} tun_erspan;
+				struct {
+					uint16_t	geneve_class;
+					uint8_t		type;
+					uint8_t		data[NFTNL_TUNNEL_GENEVE_DATA_MAXLEN];
+					uint32_t	data_len;
+				} tun_geneve;
 			} u;
 		} tunnel;
 		struct nftnl_obj_secmark {
diff --git a/src/obj/tunnel.c b/src/obj/tunnel.c
index 8941e39..27a6acd 100644
--- a/src/obj/tunnel.c
+++ b/src/obj/tunnel.c
@@ -72,6 +72,16 @@ nftnl_obj_tunnel_set(struct nftnl_obj *e, uint16_t type,
 	case NFTNL_OBJ_TUNNEL_ERSPAN_V2_DIR:
 		memcpy(&tun->u.tun_erspan.u.v2.dir, data, data_len);
 		break;
+	case NFTNL_OBJ_TUNNEL_GENEVE_CLASS:
+		memcpy(&tun->u.tun_geneve.geneve_class, data, data_len);
+		break;
+	case NFTNL_OBJ_TUNNEL_GENEVE_TYPE:
+		memcpy(&tun->u.tun_geneve.type, data, data_len);
+		break;
+	case NFTNL_OBJ_TUNNEL_GENEVE_DATA:
+		memcpy(&tun->u.tun_geneve.data, data, data_len);
+		tun->u.tun_geneve.data_len = data_len;
+		break;
 	}
 	return 0;
 }
@@ -131,6 +141,15 @@ nftnl_obj_tunnel_get(const struct nftnl_obj *e, uint16_t type,
 	case NFTNL_OBJ_TUNNEL_ERSPAN_V2_DIR:
 		*data_len = sizeof(tun->u.tun_erspan.u.v2.dir);
 		return &tun->u.tun_erspan.u.v2.dir;
+	case NFTNL_OBJ_TUNNEL_GENEVE_CLASS:
+		*data_len = sizeof(tun->u.tun_geneve.geneve_class);
+		return &tun->u.tun_geneve.geneve_class;
+	case NFTNL_OBJ_TUNNEL_GENEVE_TYPE:
+		*data_len = sizeof(tun->u.tun_geneve.type);
+		return &tun->u.tun_geneve.type;
+	case NFTNL_OBJ_TUNNEL_GENEVE_DATA:
+		*data_len = tun->u.tun_geneve.data_len;
+		return &tun->u.tun_geneve.data;
 	}
 	return NULL;
 }
@@ -240,6 +259,21 @@ nftnl_obj_tunnel_build(struct nlmsghdr *nlh, const struct nftnl_obj *e)
 		mnl_attr_nest_end(nlh, nest_inner);
 		mnl_attr_nest_end(nlh, nest);
 	}
+	if (e->flags & (1ULL << NFTNL_OBJ_TUNNEL_GENEVE_CLASS) &&
+	    e->flags & (1ULL << NFTNL_OBJ_TUNNEL_GENEVE_TYPE) &&
+	    e->flags & (1ULL << NFTNL_OBJ_TUNNEL_GENEVE_DATA)) {
+		nest = mnl_attr_nest_start(nlh, NFTA_TUNNEL_KEY_OPTS);
+		nest_inner = mnl_attr_nest_start(nlh, NFTA_TUNNEL_KEY_OPTS_GENEVE);
+		mnl_attr_put_u16(nlh, NFTA_TUNNEL_KEY_GENEVE_CLASS,
+				 htons(tun->u.tun_geneve.geneve_class));
+		mnl_attr_put_u8(nlh, NFTA_TUNNEL_KEY_GENEVE_TYPE,
+				tun->u.tun_geneve.type);
+		mnl_attr_put(nlh, NFTA_TUNNEL_KEY_GENEVE_DATA,
+			     tun->u.tun_geneve.data_len,
+			     tun->u.tun_geneve.data);
+		mnl_attr_nest_end(nlh, nest_inner);
+		mnl_attr_nest_end(nlh, nest);
+	}
 }
 
 static int nftnl_obj_tunnel_ip_cb(const struct nlattr *attr, void *data)
@@ -335,6 +369,68 @@ static int nftnl_obj_tunnel_parse_ip6(struct nftnl_obj *e, struct nlattr *attr,
 	return 0;
 }
 
+static int nftnl_obj_tunnel_geneve_cb(const struct nlattr *attr, void *data)
+{
+	const struct nlattr **tb = data;
+	int type = mnl_attr_get_type(attr);
+
+	if (mnl_attr_type_valid(attr, NFTA_TUNNEL_KEY_GENEVE_MAX) < 0)
+		return MNL_CB_OK;
+
+	switch (type) {
+	case NFTA_TUNNEL_KEY_GENEVE_CLASS:
+		if (mnl_attr_validate(attr, MNL_TYPE_U16) < 0)
+			abi_breakage();
+		break;
+	case NFTA_TUNNEL_KEY_GENEVE_TYPE:
+		if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0)
+			abi_breakage();
+		break;
+	case NFTA_TUNNEL_KEY_GENEVE_DATA:
+		if (mnl_attr_validate(attr, MNL_TYPE_BINARY) < 0)
+			abi_breakage();
+		break;
+	}
+
+	tb[type] = attr;
+	return MNL_CB_OK;
+}
+
+static int
+nftnl_obj_tunnel_parse_geneve(struct nftnl_obj *e, struct nlattr *attr,
+			      struct nftnl_obj_tunnel *tun)
+{
+	struct nlattr *tb[NFTA_TUNNEL_KEY_GENEVE_MAX + 1] = {};
+
+	if (mnl_attr_parse_nested(attr, nftnl_obj_tunnel_geneve_cb, tb) < 0)
+		return -1;
+
+	if (tb[NFTA_TUNNEL_KEY_GENEVE_CLASS]) {
+		tun->u.tun_geneve.geneve_class =
+			ntohs(mnl_attr_get_u16(tb[NFTA_TUNNEL_KEY_GENEVE_CLASS]));
+		e->flags |= (1ULL << NFTNL_OBJ_TUNNEL_GENEVE_CLASS);
+	}
+
+	if (tb[NFTA_TUNNEL_KEY_GENEVE_TYPE]) {
+		tun->u.tun_geneve.type =
+			mnl_attr_get_u8(tb[NFTA_TUNNEL_KEY_GENEVE_TYPE]);
+		e->flags |= (1ULL << NFTNL_OBJ_TUNNEL_GENEVE_TYPE);
+	}
+
+	if (tb[NFTA_TUNNEL_KEY_GENEVE_DATA]) {
+		uint32_t len = mnl_attr_get_payload_len(tb[NFTA_TUNNEL_KEY_GENEVE_DATA]);
+
+		memcpy(tun->u.tun_geneve.data,
+		       mnl_attr_get_payload(tb[NFTA_TUNNEL_KEY_GENEVE_DATA]),
+		       len);
+		tun->u.tun_geneve.data_len = len;
+
+		e->flags |= (1ULL << NFTNL_OBJ_TUNNEL_GENEVE_DATA);
+	}
+
+	return 0;
+}
+
 static int nftnl_obj_tunnel_vxlan_cb(const struct nlattr *attr, void *data)
 {
 	const struct nlattr **tb = data;
@@ -441,6 +537,7 @@ static int nftnl_obj_tunnel_opts_cb(const struct nlattr *attr, void *data)
 	switch (type) {
 	case NFTA_TUNNEL_KEY_OPTS_VXLAN:
 	case NFTA_TUNNEL_KEY_OPTS_ERSPAN:
+	case NFTA_TUNNEL_KEY_OPTS_GENEVE:
 		if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
 			abi_breakage();
 		break;
@@ -466,6 +563,9 @@ nftnl_obj_tunnel_parse_opts(struct nftnl_obj *e, struct nlattr *attr,
 	} else if (tb[NFTA_TUNNEL_KEY_OPTS_ERSPAN]) {
 		err = nftnl_obj_tunnel_parse_erspan(e, tb[NFTA_TUNNEL_KEY_OPTS_ERSPAN],
 						    tun);
+	} else if (tb[NFTA_TUNNEL_KEY_OPTS_GENEVE]) {
+		err = nftnl_obj_tunnel_parse_geneve(e, tb[NFTA_TUNNEL_KEY_OPTS_GENEVE],
+						    tun);
 	}
 
 	return err;
@@ -549,6 +649,9 @@ static struct attr_policy obj_tunnel_attr_policy[__NFTNL_OBJ_TUNNEL_MAX] = {
 	[NFTNL_OBJ_TUNNEL_ERSPAN_V1_INDEX] = { .maxlen = sizeof(uint32_t) },
 	[NFTNL_OBJ_TUNNEL_ERSPAN_V2_HWID] = { .maxlen = sizeof(uint8_t) },
 	[NFTNL_OBJ_TUNNEL_ERSPAN_V2_DIR] = { .maxlen = sizeof(uint8_t) },
+	[NFTNL_OBJ_TUNNEL_GENEVE_CLASS]	= { .maxlen = sizeof(uint16_t) },
+	[NFTNL_OBJ_TUNNEL_GENEVE_TYPE]	= { .maxlen = sizeof(uint8_t) },
+	[NFTNL_OBJ_TUNNEL_GENEVE_DATA]	= { .maxlen = NFTNL_TUNNEL_GENEVE_DATA_MAXLEN},
 };
 
 struct obj_ops obj_ops_tunnel = {
-- 
2.49.0





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

  Powered by Linux