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

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

 





On 4/15/25 7:56 PM, Fernando Fernandez Mancera wrote:
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
+

I just noticed this should be 127.. anyway, it doesn't matter much as any length not divisible by 4 will be an invalid argument on kernel side so 127 won't make a difference. Maybe 124 is better?

  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 = {





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

  Powered by Linux