12 #include <arpa/inet.h>
16 #include <linux/netfilter/nf_tables.h>
18 #include <libmnl/libmnl.h>
19 #include <libnftnl/object.h>
25 nftnl_obj_tunnel_set(
struct nftnl_obj *e, uint16_t type,
26 const void *data, uint32_t data_len)
28 struct nftnl_obj_tunnel *tun = nftnl_obj_data(e);
31 case NFTNL_OBJ_TUNNEL_ID:
32 memcpy(&tun->id, data, data_len);
34 case NFTNL_OBJ_TUNNEL_IPV4_SRC:
35 memcpy(&tun->src_v4, data, data_len);
37 case NFTNL_OBJ_TUNNEL_IPV4_DST:
38 memcpy(&tun->dst_v4, data, data_len);
40 case NFTNL_OBJ_TUNNEL_IPV6_SRC:
41 memcpy(&tun->src_v6, data, data_len);
43 case NFTNL_OBJ_TUNNEL_IPV6_DST:
44 memcpy(&tun->dst_v6, data, data_len);
46 case NFTNL_OBJ_TUNNEL_IPV6_FLOWLABEL:
47 memcpy(&tun->flowlabel, data, data_len);
49 case NFTNL_OBJ_TUNNEL_SPORT:
50 memcpy(&tun->sport, data, data_len);
52 case NFTNL_OBJ_TUNNEL_DPORT:
53 memcpy(&tun->dport, data, data_len);
55 case NFTNL_OBJ_TUNNEL_FLAGS:
56 memcpy(&tun->tun_flags, data, data_len);
58 case NFTNL_OBJ_TUNNEL_TOS:
59 memcpy(&tun->tun_tos, data, data_len);
61 case NFTNL_OBJ_TUNNEL_TTL:
62 memcpy(&tun->tun_ttl, data, data_len);
64 case NFTNL_OBJ_TUNNEL_VXLAN_GBP:
65 memcpy(&tun->u.tun_vxlan.gbp, data, data_len);
67 case NFTNL_OBJ_TUNNEL_ERSPAN_VERSION:
68 memcpy(&tun->u.tun_erspan.version, data, data_len);
70 case NFTNL_OBJ_TUNNEL_ERSPAN_V1_INDEX:
71 memcpy(&tun->u.tun_erspan.u.v1_index, data, data_len);
73 case NFTNL_OBJ_TUNNEL_ERSPAN_V2_HWID:
74 memcpy(&tun->u.tun_erspan.u.v2.hwid, data, data_len);
76 case NFTNL_OBJ_TUNNEL_ERSPAN_V2_DIR:
77 memcpy(&tun->u.tun_erspan.u.v2.dir, data, data_len);
84 nftnl_obj_tunnel_get(
const struct nftnl_obj *e, uint16_t type,
87 struct nftnl_obj_tunnel *tun = nftnl_obj_data(e);
90 case NFTNL_OBJ_TUNNEL_ID:
91 *data_len =
sizeof(tun->id);
93 case NFTNL_OBJ_TUNNEL_IPV4_SRC:
94 *data_len =
sizeof(tun->src_v4);
96 case NFTNL_OBJ_TUNNEL_IPV4_DST:
97 *data_len =
sizeof(tun->dst_v4);
99 case NFTNL_OBJ_TUNNEL_IPV6_SRC:
100 *data_len =
sizeof(tun->src_v6);
102 case NFTNL_OBJ_TUNNEL_IPV6_DST:
103 *data_len =
sizeof(tun->dst_v6);
105 case NFTNL_OBJ_TUNNEL_IPV6_FLOWLABEL:
106 *data_len =
sizeof(tun->flowlabel);
107 return &tun->flowlabel;
108 case NFTNL_OBJ_TUNNEL_SPORT:
109 *data_len =
sizeof(tun->sport);
111 case NFTNL_OBJ_TUNNEL_DPORT:
112 *data_len =
sizeof(tun->dport);
114 case NFTNL_OBJ_TUNNEL_FLAGS:
115 *data_len =
sizeof(tun->tun_flags);
116 return &tun->tun_flags;
117 case NFTNL_OBJ_TUNNEL_TOS:
118 *data_len =
sizeof(tun->tun_tos);
119 return &tun->tun_tos;
120 case NFTNL_OBJ_TUNNEL_TTL:
121 *data_len =
sizeof(tun->tun_ttl);
122 return &tun->tun_ttl;
123 case NFTNL_OBJ_TUNNEL_VXLAN_GBP:
124 *data_len =
sizeof(tun->u.tun_vxlan.gbp);
125 return &tun->u.tun_vxlan.gbp;
126 case NFTNL_OBJ_TUNNEL_ERSPAN_VERSION:
127 *data_len =
sizeof(tun->u.tun_erspan.version);
128 return &tun->u.tun_erspan.version;
129 case NFTNL_OBJ_TUNNEL_ERSPAN_V1_INDEX:
130 *data_len =
sizeof(tun->u.tun_erspan.u.v1_index);
131 return &tun->u.tun_erspan.u.v1_index;
132 case NFTNL_OBJ_TUNNEL_ERSPAN_V2_HWID:
133 *data_len =
sizeof(tun->u.tun_erspan.u.v2.hwid);
134 return &tun->u.tun_erspan.u.v2.hwid;
135 case NFTNL_OBJ_TUNNEL_ERSPAN_V2_DIR:
136 *data_len =
sizeof(tun->u.tun_erspan.u.v2.dir);
137 return &tun->u.tun_erspan.u.v2.dir;
142 static int nftnl_obj_tunnel_cb(
const struct nlattr *attr,
void *data)
144 const struct nlattr **tb = data;
145 int type = mnl_attr_get_type(attr);
147 if (mnl_attr_type_valid(attr, NFTA_TUNNEL_KEY_MAX) < 0)
151 case NFTA_TUNNEL_KEY_ID:
152 case NFTA_TUNNEL_KEY_FLAGS:
153 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
156 case NFTA_TUNNEL_KEY_IP:
157 case NFTA_TUNNEL_KEY_IP6:
158 case NFTA_TUNNEL_KEY_OPTS:
159 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
162 case NFTA_TUNNEL_KEY_SPORT:
163 case NFTA_TUNNEL_KEY_DPORT:
164 if (mnl_attr_validate(attr, MNL_TYPE_U16) < 0)
167 case NFTA_TUNNEL_KEY_TOS:
168 case NFTA_TUNNEL_KEY_TTL:
169 if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0)
179 nftnl_obj_tunnel_build(
struct nlmsghdr *nlh,
const struct nftnl_obj *e)
181 struct nftnl_obj_tunnel *tun = nftnl_obj_data(e);
184 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_ID))
185 mnl_attr_put_u32(nlh, NFTA_TUNNEL_KEY_ID, htonl(tun->id));
186 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_IPV4_SRC) ||
187 e->flags & (1 << NFTNL_OBJ_TUNNEL_IPV4_DST)) {
188 nest = mnl_attr_nest_start(nlh, NFTA_TUNNEL_KEY_IP);
189 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_IPV4_SRC))
190 mnl_attr_put_u32(nlh, NFTA_TUNNEL_KEY_IP_SRC, tun->src_v4);
191 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_IPV4_DST))
192 mnl_attr_put_u32(nlh, NFTA_TUNNEL_KEY_IP_DST, tun->dst_v4);
193 mnl_attr_nest_end(nlh, nest);
195 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_IPV6_SRC) ||
196 e->flags & (1 << NFTNL_OBJ_TUNNEL_IPV6_DST)) {
197 nest = mnl_attr_nest_start(nlh, NFTA_TUNNEL_KEY_IP6);
198 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_IPV6_SRC))
199 mnl_attr_put(nlh, NFTA_TUNNEL_KEY_IP6_SRC,
200 sizeof(tun->src_v6), &tun->src_v6);
201 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_IPV6_DST))
202 mnl_attr_put(nlh, NFTA_TUNNEL_KEY_IP6_DST,
203 sizeof(tun->dst_v6), &tun->dst_v6);
204 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_IPV6_FLOWLABEL))
205 mnl_attr_put_u32(nlh, NFTA_TUNNEL_KEY_IP6_FLOWLABEL,
206 htonl(tun->flowlabel));
207 mnl_attr_nest_end(nlh, nest);
209 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_SPORT))
210 mnl_attr_put_u16(nlh, NFTA_TUNNEL_KEY_SPORT, htons(tun->sport));
211 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_DPORT))
212 mnl_attr_put_u16(nlh, NFTA_TUNNEL_KEY_DPORT, htons(tun->dport));
213 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_TOS))
214 mnl_attr_put_u8(nlh, NFTA_TUNNEL_KEY_TOS, tun->tun_tos);
215 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_TTL))
216 mnl_attr_put_u8(nlh, NFTA_TUNNEL_KEY_TTL, tun->tun_ttl);
217 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_FLAGS))
218 mnl_attr_put_u32(nlh, NFTA_TUNNEL_KEY_FLAGS, htonl(tun->tun_flags));
219 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_VXLAN_GBP)) {
220 nest = mnl_attr_nest_start(nlh, NFTA_TUNNEL_KEY_OPTS);
221 mnl_attr_put_u32(nlh, NFTA_TUNNEL_KEY_VXLAN_GBP,
222 htonl(tun->u.tun_vxlan.gbp));
223 mnl_attr_nest_end(nlh, nest);
225 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_ERSPAN_VERSION) &&
226 (e->flags & (1 << NFTNL_OBJ_TUNNEL_ERSPAN_V1_INDEX) ||
227 (e->flags & (1 << NFTNL_OBJ_TUNNEL_ERSPAN_V2_HWID) &&
228 e->flags & (1u << NFTNL_OBJ_TUNNEL_ERSPAN_V2_DIR)))) {
229 struct nlattr *nest_inner;
231 nest = mnl_attr_nest_start(nlh, NFTA_TUNNEL_KEY_OPTS);
232 nest_inner = mnl_attr_nest_start(nlh, NFTA_TUNNEL_KEY_OPTS_ERSPAN);
233 mnl_attr_put_u32(nlh, NFTA_TUNNEL_KEY_ERSPAN_VERSION,
234 htonl(tun->u.tun_erspan.version));
235 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_ERSPAN_V1_INDEX))
236 mnl_attr_put_u32(nlh, NFTA_TUNNEL_KEY_ERSPAN_V1_INDEX,
237 htonl(tun->u.tun_erspan.u.v1_index));
238 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_ERSPAN_V2_HWID))
239 mnl_attr_put_u8(nlh, NFTA_TUNNEL_KEY_ERSPAN_V2_HWID,
240 tun->u.tun_erspan.u.v2.hwid);
241 if (e->flags & (1u << NFTNL_OBJ_TUNNEL_ERSPAN_V2_DIR))
242 mnl_attr_put_u8(nlh, NFTA_TUNNEL_KEY_ERSPAN_V2_DIR,
243 tun->u.tun_erspan.u.v2.dir);
244 mnl_attr_nest_end(nlh, nest_inner);
245 mnl_attr_nest_end(nlh, nest);
249 static int nftnl_obj_tunnel_ip_cb(
const struct nlattr *attr,
void *data)
251 const struct nlattr **tb = data;
252 int type = mnl_attr_get_type(attr);
254 if (mnl_attr_type_valid(attr, NFTA_TUNNEL_KEY_MAX) < 0)
258 case NFTA_TUNNEL_KEY_IP_SRC:
259 case NFTA_TUNNEL_KEY_IP_DST:
260 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
269 static int nftnl_obj_tunnel_parse_ip(
struct nftnl_obj *e,
struct nlattr *attr,
270 struct nftnl_obj_tunnel *tun)
272 struct nlattr *tb[NFTA_TUNNEL_KEY_IP_MAX + 1] = {};
274 if (mnl_attr_parse_nested(attr, nftnl_obj_tunnel_ip_cb, tb) < 0)
277 if (tb[NFTA_TUNNEL_KEY_IP_SRC]) {
278 tun->src_v4 = mnl_attr_get_u32(tb[NFTA_TUNNEL_KEY_IP_SRC]);
279 e->flags |= (1 << NFTNL_OBJ_TUNNEL_IPV4_SRC);
281 if (tb[NFTA_TUNNEL_KEY_IP_DST]) {
282 tun->dst_v4 = mnl_attr_get_u32(tb[NFTA_TUNNEL_KEY_IP_DST]);
283 e->flags |= (1 << NFTNL_OBJ_TUNNEL_IPV4_DST);
289 static int nftnl_obj_tunnel_ip6_cb(
const struct nlattr *attr,
void *data)
291 const struct nlattr **tb = data;
292 int type = mnl_attr_get_type(attr);
294 if (mnl_attr_type_valid(attr, NFTA_TUNNEL_KEY_MAX) < 0)
298 case NFTA_TUNNEL_KEY_IP6_SRC:
299 case NFTA_TUNNEL_KEY_IP6_DST:
300 if (mnl_attr_validate(attr, MNL_TYPE_BINARY) < 0)
303 case NFTA_TUNNEL_KEY_IP6_FLOWLABEL:
304 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
313 static int nftnl_obj_tunnel_parse_ip6(
struct nftnl_obj *e,
struct nlattr *attr,
314 struct nftnl_obj_tunnel *tun)
316 struct nlattr *tb[NFTA_TUNNEL_KEY_IP6_MAX + 1] = {};
318 if (mnl_attr_parse_nested(attr, nftnl_obj_tunnel_ip6_cb, tb) < 0)
321 if (tb[NFTA_TUNNEL_KEY_IP6_SRC]) {
323 mnl_attr_get_payload(tb[NFTA_TUNNEL_KEY_IP6_SRC]),
324 sizeof(
struct in6_addr));
325 e->flags |= (1 << NFTNL_OBJ_TUNNEL_IPV6_SRC);
327 if (tb[NFTA_TUNNEL_KEY_IP6_DST]) {
329 mnl_attr_get_payload(tb[NFTA_TUNNEL_KEY_IP6_DST]),
330 sizeof(
struct in6_addr));
331 e->flags |= (1 << NFTNL_OBJ_TUNNEL_IPV6_DST);
333 if (tb[NFTA_TUNNEL_KEY_IP6_FLOWLABEL]) {
335 ntohl(mnl_attr_get_u32(tb[NFTA_TUNNEL_KEY_IP6_FLOWLABEL]));
336 e->flags |= (1 << NFTNL_OBJ_TUNNEL_IPV6_FLOWLABEL);
342 static int nftnl_obj_tunnel_vxlan_cb(
const struct nlattr *attr,
void *data)
344 const struct nlattr **tb = data;
345 int type = mnl_attr_get_type(attr);
347 if (mnl_attr_type_valid(attr, NFTA_TUNNEL_KEY_VXLAN_MAX) < 0)
351 case NFTA_TUNNEL_KEY_VXLAN_GBP:
352 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
362 nftnl_obj_tunnel_parse_vxlan(
struct nftnl_obj *e,
struct nlattr *attr,
363 struct nftnl_obj_tunnel *tun)
365 struct nlattr *tb[NFTA_TUNNEL_KEY_VXLAN_MAX + 1] = {};
367 if (mnl_attr_parse_nested(attr, nftnl_obj_tunnel_vxlan_cb, tb) < 0)
370 if (tb[NFTA_TUNNEL_KEY_VXLAN_GBP]) {
371 tun->u.tun_vxlan.gbp =
372 ntohl(mnl_attr_get_u32(tb[NFTA_TUNNEL_KEY_VXLAN_GBP]));
373 e->flags |= (1 << NFTNL_OBJ_TUNNEL_VXLAN_GBP);
379 static int nftnl_obj_tunnel_erspan_cb(
const struct nlattr *attr,
void *data)
381 const struct nlattr **tb = data;
382 int type = mnl_attr_get_type(attr);
384 if (mnl_attr_type_valid(attr, NFTA_TUNNEL_KEY_ERSPAN_MAX) < 0)
388 case NFTA_TUNNEL_KEY_ERSPAN_VERSION:
389 case NFTA_TUNNEL_KEY_ERSPAN_V1_INDEX:
390 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
393 case NFTA_TUNNEL_KEY_ERSPAN_V2_HWID:
394 case NFTA_TUNNEL_KEY_ERSPAN_V2_DIR:
395 if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0)
405 nftnl_obj_tunnel_parse_erspan(
struct nftnl_obj *e,
struct nlattr *attr,
406 struct nftnl_obj_tunnel *tun)
408 struct nlattr *tb[NFTA_TUNNEL_KEY_ERSPAN_MAX + 1] = {};
410 if (mnl_attr_parse_nested(attr, nftnl_obj_tunnel_erspan_cb, tb) < 0)
413 if (tb[NFTA_TUNNEL_KEY_ERSPAN_VERSION]) {
414 tun->u.tun_erspan.version =
415 ntohl(mnl_attr_get_u32(tb[NFTA_TUNNEL_KEY_ERSPAN_VERSION]));
416 e->flags |= (1 << NFTNL_OBJ_TUNNEL_ERSPAN_VERSION);
418 if (tb[NFTA_TUNNEL_KEY_ERSPAN_V1_INDEX]) {
419 tun->u.tun_erspan.u.v1_index =
420 ntohl(mnl_attr_get_u32(tb[NFTA_TUNNEL_KEY_ERSPAN_V1_INDEX]));
421 e->flags |= (1 << NFTNL_OBJ_TUNNEL_ERSPAN_V1_INDEX);
423 if (tb[NFTA_TUNNEL_KEY_ERSPAN_V2_HWID]) {
424 tun->u.tun_erspan.u.v2.hwid =
425 mnl_attr_get_u8(tb[NFTA_TUNNEL_KEY_ERSPAN_V2_HWID]);
426 e->flags |= (1 << NFTNL_OBJ_TUNNEL_ERSPAN_V2_HWID);
428 if (tb[NFTA_TUNNEL_KEY_ERSPAN_V2_DIR]) {
429 tun->u.tun_erspan.u.v2.dir =
430 mnl_attr_get_u8(tb[NFTA_TUNNEL_KEY_ERSPAN_V2_DIR]);
431 e->flags |= (1u << NFTNL_OBJ_TUNNEL_ERSPAN_V2_DIR);
437 static int nftnl_obj_tunnel_opts_cb(
const struct nlattr *attr,
void *data)
439 const struct nlattr **tb = data;
440 int type = mnl_attr_get_type(attr);
442 if (mnl_attr_type_valid(attr, NFTA_TUNNEL_KEY_OPTS_MAX) < 0)
446 case NFTA_TUNNEL_KEY_OPTS_VXLAN:
447 case NFTA_TUNNEL_KEY_OPTS_ERSPAN:
448 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
458 nftnl_obj_tunnel_parse_opts(
struct nftnl_obj *e,
struct nlattr *attr,
459 struct nftnl_obj_tunnel *tun)
461 struct nlattr *tb[NFTA_TUNNEL_KEY_OPTS_MAX + 1] = {};
464 if (mnl_attr_parse_nested(attr, nftnl_obj_tunnel_opts_cb, tb) < 0)
467 if (tb[NFTA_TUNNEL_KEY_OPTS_VXLAN]) {
468 err = nftnl_obj_tunnel_parse_vxlan(e, tb[NFTA_TUNNEL_KEY_OPTS_VXLAN],
470 }
else if (tb[NFTA_TUNNEL_KEY_OPTS_ERSPAN]) {
471 err = nftnl_obj_tunnel_parse_erspan(e, tb[NFTA_TUNNEL_KEY_OPTS_ERSPAN],
479 nftnl_obj_tunnel_parse(
struct nftnl_obj *e,
struct nlattr *attr)
481 struct nftnl_obj_tunnel *tun = nftnl_obj_data(e);
482 struct nlattr *tb[NFTA_TUNNEL_KEY_MAX + 1] = {};
485 if (mnl_attr_parse_nested(attr, nftnl_obj_tunnel_cb, tb) < 0)
488 if (tb[NFTA_TUNNEL_KEY_ID]) {
489 tun->id = ntohl(mnl_attr_get_u32(tb[NFTA_TUNNEL_KEY_ID]));
490 e->flags |= (1 << NFTNL_OBJ_TUNNEL_ID);
492 if (tb[NFTA_TUNNEL_KEY_IP]) {
493 err = nftnl_obj_tunnel_parse_ip(e, tb[NFTA_TUNNEL_KEY_IP], tun);
496 }
else if (tb[NFTA_TUNNEL_KEY_IP6]) {
497 err = nftnl_obj_tunnel_parse_ip6(e, tb[NFTA_TUNNEL_KEY_IP6], tun);
502 if (tb[NFTA_TUNNEL_KEY_SPORT]) {
503 tun->sport = ntohs(mnl_attr_get_u16(tb[NFTA_TUNNEL_KEY_SPORT]));
504 e->flags |= (1 << NFTNL_OBJ_TUNNEL_SPORT);
506 if (tb[NFTA_TUNNEL_KEY_DPORT]) {
507 tun->dport = ntohs(mnl_attr_get_u16(tb[NFTA_TUNNEL_KEY_DPORT]));
508 e->flags |= (1 << NFTNL_OBJ_TUNNEL_DPORT);
510 if (tb[NFTA_TUNNEL_KEY_TOS]) {
511 tun->tun_tos = mnl_attr_get_u8(tb[NFTA_TUNNEL_KEY_TOS]);
512 e->flags |= (1 << NFTNL_OBJ_TUNNEL_TOS);
514 if (tb[NFTA_TUNNEL_KEY_TTL]) {
515 tun->tun_ttl = mnl_attr_get_u8(tb[NFTA_TUNNEL_KEY_TTL]);
516 e->flags |= (1 << NFTNL_OBJ_TUNNEL_TTL);
518 if (tb[NFTA_TUNNEL_KEY_FLAGS]) {
519 tun->tun_flags = mnl_attr_get_u8(tb[NFTA_TUNNEL_KEY_FLAGS]);
520 e->flags |= (1 << NFTNL_OBJ_TUNNEL_FLAGS);
522 if (tb[NFTA_TUNNEL_KEY_OPTS]) {
523 err = nftnl_obj_tunnel_parse_opts(e, tb[NFTA_TUNNEL_KEY_OPTS], tun);
531 static int nftnl_obj_tunnel_snprintf(
char *buf,
size_t len,
532 uint32_t flags,
const struct nftnl_obj *e)
534 struct nftnl_obj_tunnel *tun = nftnl_obj_data(e);
536 return snprintf(buf, len,
"id %u ", tun->id);
539 static struct attr_policy obj_tunnel_attr_policy[__NFTNL_OBJ_TUNNEL_MAX] = {
540 [NFTNL_OBJ_TUNNEL_ID] = { .maxlen =
sizeof(uint32_t) },
541 [NFTNL_OBJ_TUNNEL_IPV4_SRC] = { .maxlen =
sizeof(uint32_t) },
542 [NFTNL_OBJ_TUNNEL_IPV4_DST] = { .maxlen =
sizeof(uint32_t) },
543 [NFTNL_OBJ_TUNNEL_IPV6_SRC] = { .maxlen =
sizeof(
struct in6_addr) },
544 [NFTNL_OBJ_TUNNEL_IPV6_DST] = { .maxlen =
sizeof(
struct in6_addr) },
545 [NFTNL_OBJ_TUNNEL_IPV6_FLOWLABEL] = { .maxlen =
sizeof(uint32_t) },
546 [NFTNL_OBJ_TUNNEL_SPORT] = { .maxlen =
sizeof(uint16_t) },
547 [NFTNL_OBJ_TUNNEL_DPORT] = { .maxlen =
sizeof(uint16_t) },
548 [NFTNL_OBJ_TUNNEL_FLAGS] = { .maxlen =
sizeof(uint32_t) },
549 [NFTNL_OBJ_TUNNEL_TOS] = { .maxlen =
sizeof(uint8_t) },
550 [NFTNL_OBJ_TUNNEL_TTL] = { .maxlen =
sizeof(uint8_t) },
551 [NFTNL_OBJ_TUNNEL_VXLAN_GBP] = { .maxlen =
sizeof(uint32_t) },
552 [NFTNL_OBJ_TUNNEL_ERSPAN_VERSION] = { .maxlen =
sizeof(uint32_t) },
553 [NFTNL_OBJ_TUNNEL_ERSPAN_V1_INDEX] = { .maxlen =
sizeof(uint32_t) },
554 [NFTNL_OBJ_TUNNEL_ERSPAN_V2_HWID] = { .maxlen =
sizeof(uint8_t) },
555 [NFTNL_OBJ_TUNNEL_ERSPAN_V2_DIR] = { .maxlen =
sizeof(uint8_t) },
558 struct obj_ops obj_ops_tunnel = {
560 .type = NFT_OBJECT_TUNNEL,
561 .alloc_len =
sizeof(
struct nftnl_obj_tunnel),
562 .nftnl_max_attr = __NFTNL_OBJ_TUNNEL_MAX - 1,
563 .attr_policy = obj_tunnel_attr_policy,
564 .set = nftnl_obj_tunnel_set,
565 .get = nftnl_obj_tunnel_get,
566 .parse = nftnl_obj_tunnel_parse,
567 .build = nftnl_obj_tunnel_build,
568 .output = nftnl_obj_tunnel_snprintf,