12 #include <linux/netfilter/nf_tables.h>
14 #include <libmnl/libmnl.h>
15 #include <libnftnl/object.h>
21 nftnl_obj_tunnel_set(
struct nftnl_obj *e, uint16_t type,
22 const void *data, uint32_t data_len)
24 struct nftnl_obj_tunnel *tun = nftnl_obj_data(e);
27 case NFTNL_OBJ_TUNNEL_ID:
28 memcpy(&tun->id, data, data_len);
30 case NFTNL_OBJ_TUNNEL_IPV4_SRC:
31 memcpy(&tun->src_v4, data, data_len);
33 case NFTNL_OBJ_TUNNEL_IPV4_DST:
34 memcpy(&tun->dst_v4, data, data_len);
36 case NFTNL_OBJ_TUNNEL_IPV6_SRC:
37 memcpy(&tun->src_v6, data, data_len);
39 case NFTNL_OBJ_TUNNEL_IPV6_DST:
40 memcpy(&tun->dst_v6, data, data_len);
42 case NFTNL_OBJ_TUNNEL_IPV6_FLOWLABEL:
43 memcpy(&tun->flowlabel, data, data_len);
45 case NFTNL_OBJ_TUNNEL_SPORT:
46 memcpy(&tun->sport, data, data_len);
48 case NFTNL_OBJ_TUNNEL_DPORT:
49 memcpy(&tun->dport, data, data_len);
51 case NFTNL_OBJ_TUNNEL_FLAGS:
52 memcpy(&tun->tun_flags, data, data_len);
54 case NFTNL_OBJ_TUNNEL_TOS:
55 memcpy(&tun->tun_tos, data, data_len);
57 case NFTNL_OBJ_TUNNEL_TTL:
58 memcpy(&tun->tun_ttl, data, data_len);
60 case NFTNL_OBJ_TUNNEL_VXLAN_GBP:
61 memcpy(&tun->u.tun_vxlan.gbp, data, data_len);
63 case NFTNL_OBJ_TUNNEL_ERSPAN_VERSION:
64 memcpy(&tun->u.tun_erspan.version, data, data_len);
66 case NFTNL_OBJ_TUNNEL_ERSPAN_V1_INDEX:
67 memcpy(&tun->u.tun_erspan.u.v1_index, data, data_len);
69 case NFTNL_OBJ_TUNNEL_ERSPAN_V2_HWID:
70 memcpy(&tun->u.tun_erspan.u.v2.hwid, data, data_len);
72 case NFTNL_OBJ_TUNNEL_ERSPAN_V2_DIR:
73 memcpy(&tun->u.tun_erspan.u.v2.dir, data, data_len);
80 nftnl_obj_tunnel_get(
const struct nftnl_obj *e, uint16_t type,
83 struct nftnl_obj_tunnel *tun = nftnl_obj_data(e);
86 case NFTNL_OBJ_TUNNEL_ID:
87 *data_len =
sizeof(tun->id);
89 case NFTNL_OBJ_TUNNEL_IPV4_SRC:
90 *data_len =
sizeof(tun->src_v4);
92 case NFTNL_OBJ_TUNNEL_IPV4_DST:
93 *data_len =
sizeof(tun->dst_v4);
95 case NFTNL_OBJ_TUNNEL_IPV6_SRC:
96 *data_len =
sizeof(tun->src_v6);
98 case NFTNL_OBJ_TUNNEL_IPV6_DST:
99 *data_len =
sizeof(tun->dst_v6);
101 case NFTNL_OBJ_TUNNEL_IPV6_FLOWLABEL:
102 *data_len =
sizeof(tun->flowlabel);
103 return &tun->flowlabel;
104 case NFTNL_OBJ_TUNNEL_SPORT:
105 *data_len =
sizeof(tun->sport);
107 case NFTNL_OBJ_TUNNEL_DPORT:
108 *data_len =
sizeof(tun->dport);
110 case NFTNL_OBJ_TUNNEL_FLAGS:
111 *data_len =
sizeof(tun->tun_flags);
112 return &tun->tun_flags;
113 case NFTNL_OBJ_TUNNEL_TOS:
114 *data_len =
sizeof(tun->tun_tos);
115 return &tun->tun_tos;
116 case NFTNL_OBJ_TUNNEL_TTL:
117 *data_len =
sizeof(tun->tun_ttl);
118 return &tun->tun_ttl;
119 case NFTNL_OBJ_TUNNEL_VXLAN_GBP:
120 *data_len =
sizeof(tun->u.tun_vxlan.gbp);
121 return &tun->u.tun_vxlan.gbp;
122 case NFTNL_OBJ_TUNNEL_ERSPAN_VERSION:
123 *data_len =
sizeof(tun->u.tun_erspan.version);
124 return &tun->u.tun_erspan.version;
125 case NFTNL_OBJ_TUNNEL_ERSPAN_V1_INDEX:
126 *data_len =
sizeof(tun->u.tun_erspan.u.v1_index);
127 return &tun->u.tun_erspan.u.v1_index;
128 case NFTNL_OBJ_TUNNEL_ERSPAN_V2_HWID:
129 *data_len =
sizeof(tun->u.tun_erspan.u.v2.hwid);
130 return &tun->u.tun_erspan.u.v2.hwid;
131 case NFTNL_OBJ_TUNNEL_ERSPAN_V2_DIR:
132 *data_len =
sizeof(tun->u.tun_erspan.u.v2.dir);
133 return &tun->u.tun_erspan.u.v2.dir;
138 static int nftnl_obj_tunnel_cb(
const struct nlattr *attr,
void *data)
140 const struct nlattr **tb = data;
141 int type = mnl_attr_get_type(attr);
143 if (mnl_attr_type_valid(attr, NFTA_TUNNEL_KEY_MAX) < 0)
147 case NFTA_TUNNEL_KEY_ID:
148 case NFTA_TUNNEL_KEY_FLAGS:
149 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
152 case NFTA_TUNNEL_KEY_IP:
153 case NFTA_TUNNEL_KEY_IP6:
154 case NFTA_TUNNEL_KEY_OPTS:
155 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
158 case NFTA_TUNNEL_KEY_SPORT:
159 case NFTA_TUNNEL_KEY_DPORT:
160 if (mnl_attr_validate(attr, MNL_TYPE_U16) < 0)
163 case NFTA_TUNNEL_KEY_TOS:
164 case NFTA_TUNNEL_KEY_TTL:
165 if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0)
175 nftnl_obj_tunnel_build(
struct nlmsghdr *nlh,
const struct nftnl_obj *e)
177 struct nftnl_obj_tunnel *tun = nftnl_obj_data(e);
178 struct nlattr *nest, *nest_inner;
180 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_ID))
181 mnl_attr_put_u32(nlh, NFTA_TUNNEL_KEY_ID, htonl(tun->id));
182 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_IPV4_SRC) ||
183 e->flags & (1 << NFTNL_OBJ_TUNNEL_IPV4_DST)) {
184 nest = mnl_attr_nest_start(nlh, NFTA_TUNNEL_KEY_IP);
185 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_IPV4_SRC))
186 mnl_attr_put_u32(nlh, NFTA_TUNNEL_KEY_IP_SRC, tun->src_v4);
187 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_IPV4_DST))
188 mnl_attr_put_u32(nlh, NFTA_TUNNEL_KEY_IP_DST, tun->dst_v4);
189 mnl_attr_nest_end(nlh, nest);
191 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_IPV6_SRC) ||
192 e->flags & (1 << NFTNL_OBJ_TUNNEL_IPV6_DST)) {
193 nest = mnl_attr_nest_start(nlh, NFTA_TUNNEL_KEY_IP6);
194 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_IPV6_SRC))
195 mnl_attr_put(nlh, NFTA_TUNNEL_KEY_IP6_SRC,
196 sizeof(tun->src_v6), &tun->src_v6);
197 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_IPV6_DST))
198 mnl_attr_put(nlh, NFTA_TUNNEL_KEY_IP6_DST,
199 sizeof(tun->dst_v6), &tun->dst_v6);
200 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_IPV6_FLOWLABEL))
201 mnl_attr_put_u32(nlh, NFTA_TUNNEL_KEY_IP6_FLOWLABEL,
202 htonl(tun->flowlabel));
203 mnl_attr_nest_end(nlh, nest);
205 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_SPORT))
206 mnl_attr_put_u16(nlh, NFTA_TUNNEL_KEY_SPORT, htons(tun->sport));
207 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_DPORT))
208 mnl_attr_put_u16(nlh, NFTA_TUNNEL_KEY_DPORT, htons(tun->dport));
209 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_TOS))
210 mnl_attr_put_u8(nlh, NFTA_TUNNEL_KEY_TOS, tun->tun_tos);
211 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_TTL))
212 mnl_attr_put_u8(nlh, NFTA_TUNNEL_KEY_TTL, tun->tun_ttl);
213 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_FLAGS))
214 mnl_attr_put_u32(nlh, NFTA_TUNNEL_KEY_FLAGS, htonl(tun->tun_flags));
215 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_VXLAN_GBP)) {
216 nest = mnl_attr_nest_start(nlh, NFTA_TUNNEL_KEY_OPTS);
217 nest_inner = mnl_attr_nest_start(nlh, NFTA_TUNNEL_KEY_OPTS_VXLAN);
218 mnl_attr_put_u32(nlh, NFTA_TUNNEL_KEY_VXLAN_GBP,
219 htonl(tun->u.tun_vxlan.gbp));
220 mnl_attr_nest_end(nlh, nest_inner);
221 mnl_attr_nest_end(nlh, nest);
223 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_ERSPAN_VERSION) &&
224 (e->flags & (1 << NFTNL_OBJ_TUNNEL_ERSPAN_V1_INDEX) ||
225 (e->flags & (1 << NFTNL_OBJ_TUNNEL_ERSPAN_V2_HWID) &&
226 e->flags & (1u << NFTNL_OBJ_TUNNEL_ERSPAN_V2_DIR)))) {
227 nest = mnl_attr_nest_start(nlh, NFTA_TUNNEL_KEY_OPTS);
228 nest_inner = mnl_attr_nest_start(nlh, NFTA_TUNNEL_KEY_OPTS_ERSPAN);
229 mnl_attr_put_u32(nlh, NFTA_TUNNEL_KEY_ERSPAN_VERSION,
230 htonl(tun->u.tun_erspan.version));
231 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_ERSPAN_V1_INDEX))
232 mnl_attr_put_u32(nlh, NFTA_TUNNEL_KEY_ERSPAN_V1_INDEX,
233 htonl(tun->u.tun_erspan.u.v1_index));
234 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_ERSPAN_V2_HWID))
235 mnl_attr_put_u8(nlh, NFTA_TUNNEL_KEY_ERSPAN_V2_HWID,
236 tun->u.tun_erspan.u.v2.hwid);
237 if (e->flags & (1u << NFTNL_OBJ_TUNNEL_ERSPAN_V2_DIR))
238 mnl_attr_put_u8(nlh, NFTA_TUNNEL_KEY_ERSPAN_V2_DIR,
239 tun->u.tun_erspan.u.v2.dir);
240 mnl_attr_nest_end(nlh, nest_inner);
241 mnl_attr_nest_end(nlh, nest);
245 static int nftnl_obj_tunnel_ip_cb(
const struct nlattr *attr,
void *data)
247 const struct nlattr **tb = data;
248 int type = mnl_attr_get_type(attr);
250 if (mnl_attr_type_valid(attr, NFTA_TUNNEL_KEY_MAX) < 0)
254 case NFTA_TUNNEL_KEY_IP_SRC:
255 case NFTA_TUNNEL_KEY_IP_DST:
256 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
265 static int nftnl_obj_tunnel_parse_ip(
struct nftnl_obj *e,
struct nlattr *attr,
266 struct nftnl_obj_tunnel *tun)
268 struct nlattr *tb[NFTA_TUNNEL_KEY_IP_MAX + 1] = {};
270 if (mnl_attr_parse_nested(attr, nftnl_obj_tunnel_ip_cb, tb) < 0)
273 if (tb[NFTA_TUNNEL_KEY_IP_SRC]) {
274 tun->src_v4 = mnl_attr_get_u32(tb[NFTA_TUNNEL_KEY_IP_SRC]);
275 e->flags |= (1 << NFTNL_OBJ_TUNNEL_IPV4_SRC);
277 if (tb[NFTA_TUNNEL_KEY_IP_DST]) {
278 tun->dst_v4 = mnl_attr_get_u32(tb[NFTA_TUNNEL_KEY_IP_DST]);
279 e->flags |= (1 << NFTNL_OBJ_TUNNEL_IPV4_DST);
285 static int nftnl_obj_tunnel_ip6_cb(
const struct nlattr *attr,
void *data)
287 const struct nlattr **tb = data;
288 int type = mnl_attr_get_type(attr);
290 if (mnl_attr_type_valid(attr, NFTA_TUNNEL_KEY_MAX) < 0)
294 case NFTA_TUNNEL_KEY_IP6_SRC:
295 case NFTA_TUNNEL_KEY_IP6_DST:
296 if (mnl_attr_validate(attr, MNL_TYPE_BINARY) < 0)
299 case NFTA_TUNNEL_KEY_IP6_FLOWLABEL:
300 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
309 static int nftnl_obj_tunnel_parse_ip6(
struct nftnl_obj *e,
struct nlattr *attr,
310 struct nftnl_obj_tunnel *tun)
312 struct nlattr *tb[NFTA_TUNNEL_KEY_IP6_MAX + 1] = {};
314 if (mnl_attr_parse_nested(attr, nftnl_obj_tunnel_ip6_cb, tb) < 0)
317 if (tb[NFTA_TUNNEL_KEY_IP6_SRC]) {
319 mnl_attr_get_payload(tb[NFTA_TUNNEL_KEY_IP6_SRC]),
320 sizeof(
struct in6_addr));
321 e->flags |= (1 << NFTNL_OBJ_TUNNEL_IPV6_SRC);
323 if (tb[NFTA_TUNNEL_KEY_IP6_DST]) {
325 mnl_attr_get_payload(tb[NFTA_TUNNEL_KEY_IP6_DST]),
326 sizeof(
struct in6_addr));
327 e->flags |= (1 << NFTNL_OBJ_TUNNEL_IPV6_DST);
329 if (tb[NFTA_TUNNEL_KEY_IP6_FLOWLABEL]) {
331 ntohl(mnl_attr_get_u32(tb[NFTA_TUNNEL_KEY_IP6_FLOWLABEL]));
332 e->flags |= (1 << NFTNL_OBJ_TUNNEL_IPV6_FLOWLABEL);
338 static int nftnl_obj_tunnel_vxlan_cb(
const struct nlattr *attr,
void *data)
340 const struct nlattr **tb = data;
341 int type = mnl_attr_get_type(attr);
343 if (mnl_attr_type_valid(attr, NFTA_TUNNEL_KEY_VXLAN_MAX) < 0)
347 case NFTA_TUNNEL_KEY_VXLAN_GBP:
348 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
358 nftnl_obj_tunnel_parse_vxlan(
struct nftnl_obj *e,
struct nlattr *attr,
359 struct nftnl_obj_tunnel *tun)
361 struct nlattr *tb[NFTA_TUNNEL_KEY_VXLAN_MAX + 1] = {};
363 if (mnl_attr_parse_nested(attr, nftnl_obj_tunnel_vxlan_cb, tb) < 0)
366 if (tb[NFTA_TUNNEL_KEY_VXLAN_GBP]) {
367 tun->u.tun_vxlan.gbp =
368 ntohl(mnl_attr_get_u32(tb[NFTA_TUNNEL_KEY_VXLAN_GBP]));
369 e->flags |= (1 << NFTNL_OBJ_TUNNEL_VXLAN_GBP);
375 static int nftnl_obj_tunnel_erspan_cb(
const struct nlattr *attr,
void *data)
377 const struct nlattr **tb = data;
378 int type = mnl_attr_get_type(attr);
380 if (mnl_attr_type_valid(attr, NFTA_TUNNEL_KEY_ERSPAN_MAX) < 0)
384 case NFTA_TUNNEL_KEY_ERSPAN_VERSION:
385 case NFTA_TUNNEL_KEY_ERSPAN_V1_INDEX:
386 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
389 case NFTA_TUNNEL_KEY_ERSPAN_V2_HWID:
390 case NFTA_TUNNEL_KEY_ERSPAN_V2_DIR:
391 if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0)
401 nftnl_obj_tunnel_parse_erspan(
struct nftnl_obj *e,
struct nlattr *attr,
402 struct nftnl_obj_tunnel *tun)
404 struct nlattr *tb[NFTA_TUNNEL_KEY_ERSPAN_MAX + 1] = {};
406 if (mnl_attr_parse_nested(attr, nftnl_obj_tunnel_erspan_cb, tb) < 0)
409 if (tb[NFTA_TUNNEL_KEY_ERSPAN_VERSION]) {
410 tun->u.tun_erspan.version =
411 ntohl(mnl_attr_get_u32(tb[NFTA_TUNNEL_KEY_ERSPAN_VERSION]));
412 e->flags |= (1 << NFTNL_OBJ_TUNNEL_ERSPAN_VERSION);
414 if (tb[NFTA_TUNNEL_KEY_ERSPAN_V1_INDEX]) {
415 tun->u.tun_erspan.u.v1_index =
416 ntohl(mnl_attr_get_u32(tb[NFTA_TUNNEL_KEY_ERSPAN_V1_INDEX]));
417 e->flags |= (1 << NFTNL_OBJ_TUNNEL_ERSPAN_V1_INDEX);
419 if (tb[NFTA_TUNNEL_KEY_ERSPAN_V2_HWID]) {
420 tun->u.tun_erspan.u.v2.hwid =
421 mnl_attr_get_u8(tb[NFTA_TUNNEL_KEY_ERSPAN_V2_HWID]);
422 e->flags |= (1 << NFTNL_OBJ_TUNNEL_ERSPAN_V2_HWID);
424 if (tb[NFTA_TUNNEL_KEY_ERSPAN_V2_DIR]) {
425 tun->u.tun_erspan.u.v2.dir =
426 mnl_attr_get_u8(tb[NFTA_TUNNEL_KEY_ERSPAN_V2_DIR]);
427 e->flags |= (1u << NFTNL_OBJ_TUNNEL_ERSPAN_V2_DIR);
433 static int nftnl_obj_tunnel_opts_cb(
const struct nlattr *attr,
void *data)
435 const struct nlattr **tb = data;
436 int type = mnl_attr_get_type(attr);
438 if (mnl_attr_type_valid(attr, NFTA_TUNNEL_KEY_OPTS_MAX) < 0)
442 case NFTA_TUNNEL_KEY_OPTS_VXLAN:
443 case NFTA_TUNNEL_KEY_OPTS_ERSPAN:
444 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
454 nftnl_obj_tunnel_parse_opts(
struct nftnl_obj *e,
struct nlattr *attr,
455 struct nftnl_obj_tunnel *tun)
457 struct nlattr *tb[NFTA_TUNNEL_KEY_OPTS_MAX + 1] = {};
460 if (mnl_attr_parse_nested(attr, nftnl_obj_tunnel_opts_cb, tb) < 0)
463 if (tb[NFTA_TUNNEL_KEY_OPTS_VXLAN]) {
464 err = nftnl_obj_tunnel_parse_vxlan(e, tb[NFTA_TUNNEL_KEY_OPTS_VXLAN],
466 }
else if (tb[NFTA_TUNNEL_KEY_OPTS_ERSPAN]) {
467 err = nftnl_obj_tunnel_parse_erspan(e, tb[NFTA_TUNNEL_KEY_OPTS_ERSPAN],
475 nftnl_obj_tunnel_parse(
struct nftnl_obj *e,
struct nlattr *attr)
477 struct nftnl_obj_tunnel *tun = nftnl_obj_data(e);
478 struct nlattr *tb[NFTA_TUNNEL_KEY_MAX + 1] = {};
481 if (mnl_attr_parse_nested(attr, nftnl_obj_tunnel_cb, tb) < 0)
484 if (tb[NFTA_TUNNEL_KEY_ID]) {
485 tun->id = ntohl(mnl_attr_get_u32(tb[NFTA_TUNNEL_KEY_ID]));
486 e->flags |= (1 << NFTNL_OBJ_TUNNEL_ID);
488 if (tb[NFTA_TUNNEL_KEY_IP]) {
489 err = nftnl_obj_tunnel_parse_ip(e, tb[NFTA_TUNNEL_KEY_IP], tun);
492 }
else if (tb[NFTA_TUNNEL_KEY_IP6]) {
493 err = nftnl_obj_tunnel_parse_ip6(e, tb[NFTA_TUNNEL_KEY_IP6], tun);
498 if (tb[NFTA_TUNNEL_KEY_SPORT]) {
499 tun->sport = ntohs(mnl_attr_get_u16(tb[NFTA_TUNNEL_KEY_SPORT]));
500 e->flags |= (1 << NFTNL_OBJ_TUNNEL_SPORT);
502 if (tb[NFTA_TUNNEL_KEY_DPORT]) {
503 tun->dport = ntohs(mnl_attr_get_u16(tb[NFTA_TUNNEL_KEY_DPORT]));
504 e->flags |= (1 << NFTNL_OBJ_TUNNEL_DPORT);
506 if (tb[NFTA_TUNNEL_KEY_TOS]) {
507 tun->tun_tos = mnl_attr_get_u8(tb[NFTA_TUNNEL_KEY_TOS]);
508 e->flags |= (1 << NFTNL_OBJ_TUNNEL_TOS);
510 if (tb[NFTA_TUNNEL_KEY_TTL]) {
511 tun->tun_ttl = mnl_attr_get_u8(tb[NFTA_TUNNEL_KEY_TTL]);
512 e->flags |= (1 << NFTNL_OBJ_TUNNEL_TTL);
514 if (tb[NFTA_TUNNEL_KEY_FLAGS]) {
515 tun->tun_flags = mnl_attr_get_u8(tb[NFTA_TUNNEL_KEY_FLAGS]);
516 e->flags |= (1 << NFTNL_OBJ_TUNNEL_FLAGS);
518 if (tb[NFTA_TUNNEL_KEY_OPTS]) {
519 err = nftnl_obj_tunnel_parse_opts(e, tb[NFTA_TUNNEL_KEY_OPTS], tun);
527 static int nftnl_obj_tunnel_snprintf(
char *buf,
size_t len,
528 uint32_t flags,
const struct nftnl_obj *e)
530 struct nftnl_obj_tunnel *tun = nftnl_obj_data(e);
532 return snprintf(buf, len,
"id %u ", tun->id);
535 static struct attr_policy obj_tunnel_attr_policy[__NFTNL_OBJ_TUNNEL_MAX] = {
536 [NFTNL_OBJ_TUNNEL_ID] = { .maxlen =
sizeof(uint32_t) },
537 [NFTNL_OBJ_TUNNEL_IPV4_SRC] = { .maxlen =
sizeof(uint32_t) },
538 [NFTNL_OBJ_TUNNEL_IPV4_DST] = { .maxlen =
sizeof(uint32_t) },
539 [NFTNL_OBJ_TUNNEL_IPV6_SRC] = { .maxlen =
sizeof(
struct in6_addr) },
540 [NFTNL_OBJ_TUNNEL_IPV6_DST] = { .maxlen =
sizeof(
struct in6_addr) },
541 [NFTNL_OBJ_TUNNEL_IPV6_FLOWLABEL] = { .maxlen =
sizeof(uint32_t) },
542 [NFTNL_OBJ_TUNNEL_SPORT] = { .maxlen =
sizeof(uint16_t) },
543 [NFTNL_OBJ_TUNNEL_DPORT] = { .maxlen =
sizeof(uint16_t) },
544 [NFTNL_OBJ_TUNNEL_FLAGS] = { .maxlen =
sizeof(uint32_t) },
545 [NFTNL_OBJ_TUNNEL_TOS] = { .maxlen =
sizeof(uint8_t) },
546 [NFTNL_OBJ_TUNNEL_TTL] = { .maxlen =
sizeof(uint8_t) },
547 [NFTNL_OBJ_TUNNEL_VXLAN_GBP] = { .maxlen =
sizeof(uint32_t) },
548 [NFTNL_OBJ_TUNNEL_ERSPAN_VERSION] = { .maxlen =
sizeof(uint32_t) },
549 [NFTNL_OBJ_TUNNEL_ERSPAN_V1_INDEX] = { .maxlen =
sizeof(uint32_t) },
550 [NFTNL_OBJ_TUNNEL_ERSPAN_V2_HWID] = { .maxlen =
sizeof(uint8_t) },
551 [NFTNL_OBJ_TUNNEL_ERSPAN_V2_DIR] = { .maxlen =
sizeof(uint8_t) },
554 struct obj_ops obj_ops_tunnel = {
556 .type = NFT_OBJECT_TUNNEL,
557 .alloc_len =
sizeof(
struct nftnl_obj_tunnel),
558 .nftnl_max_attr = __NFTNL_OBJ_TUNNEL_MAX - 1,
559 .attr_policy = obj_tunnel_attr_policy,
560 .set = nftnl_obj_tunnel_set,
561 .get = nftnl_obj_tunnel_get,
562 .parse = nftnl_obj_tunnel_parse,
563 .build = nftnl_obj_tunnel_build,
564 .output = nftnl_obj_tunnel_snprintf,