16#include <linux/netfilter/nf_tables.h>
18#include <libmnl/libmnl.h>
19#include <libnftnl/object.h>
25nftnl_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,
sizeof(tun->id));
34 case NFTNL_OBJ_TUNNEL_IPV4_SRC:
35 memcpy(&tun->src_v4, data,
sizeof(tun->src_v4));
37 case NFTNL_OBJ_TUNNEL_IPV4_DST:
38 memcpy(&tun->dst_v4, data,
sizeof(tun->dst_v4));
40 case NFTNL_OBJ_TUNNEL_IPV6_SRC:
41 memcpy(&tun->src_v6, data,
sizeof(
struct in6_addr));
43 case NFTNL_OBJ_TUNNEL_IPV6_DST:
44 memcpy(&tun->dst_v6, data,
sizeof(
struct in6_addr));
46 case NFTNL_OBJ_TUNNEL_IPV6_FLOWLABEL:
47 memcpy(&tun->flowlabel, data,
sizeof(tun->flowlabel));
49 case NFTNL_OBJ_TUNNEL_SPORT:
50 memcpy(&tun->sport, data,
sizeof(tun->sport));
52 case NFTNL_OBJ_TUNNEL_DPORT:
53 memcpy(&tun->dport, data,
sizeof(tun->dport));
55 case NFTNL_OBJ_TUNNEL_FLAGS:
56 memcpy(&tun->tun_flags, data,
sizeof(tun->tun_flags));
58 case NFTNL_OBJ_TUNNEL_TOS:
59 memcpy(&tun->tun_tos, data,
sizeof(tun->tun_tos));
61 case NFTNL_OBJ_TUNNEL_TTL:
62 memcpy(&tun->tun_ttl, data,
sizeof(tun->tun_ttl));
64 case NFTNL_OBJ_TUNNEL_VXLAN_GBP:
65 memcpy(&tun->u.tun_vxlan.gbp, data,
sizeof(tun->u.tun_vxlan.gbp));
67 case NFTNL_OBJ_TUNNEL_ERSPAN_VERSION:
68 memcpy(&tun->u.tun_erspan.version, data,
sizeof(tun->u.tun_erspan.version));
70 case NFTNL_OBJ_TUNNEL_ERSPAN_V1_INDEX:
71 memcpy(&tun->u.tun_erspan.u.v1_index, data,
sizeof(tun->u.tun_erspan.u.v1_index));
73 case NFTNL_OBJ_TUNNEL_ERSPAN_V2_HWID:
74 memcpy(&tun->u.tun_erspan.u.v2.hwid, data,
sizeof(tun->u.tun_erspan.u.v2.hwid));
76 case NFTNL_OBJ_TUNNEL_ERSPAN_V2_DIR:
77 memcpy(&tun->u.tun_erspan.u.v2.dir, data,
sizeof(tun->u.tun_erspan.u.v2.dir));
86nftnl_obj_tunnel_get(
const struct nftnl_obj *e, uint16_t type,
89 struct nftnl_obj_tunnel *tun = nftnl_obj_data(e);
92 case NFTNL_OBJ_TUNNEL_ID:
93 *data_len =
sizeof(tun->id);
95 case NFTNL_OBJ_TUNNEL_IPV4_SRC:
96 *data_len =
sizeof(tun->src_v4);
98 case NFTNL_OBJ_TUNNEL_IPV4_DST:
99 *data_len =
sizeof(tun->dst_v4);
101 case NFTNL_OBJ_TUNNEL_IPV6_SRC:
102 *data_len =
sizeof(tun->src_v6);
104 case NFTNL_OBJ_TUNNEL_IPV6_DST:
105 *data_len =
sizeof(tun->dst_v6);
107 case NFTNL_OBJ_TUNNEL_IPV6_FLOWLABEL:
108 *data_len =
sizeof(tun->flowlabel);
109 return &tun->flowlabel;
110 case NFTNL_OBJ_TUNNEL_SPORT:
111 *data_len =
sizeof(tun->sport);
113 case NFTNL_OBJ_TUNNEL_DPORT:
114 *data_len =
sizeof(tun->dport);
116 case NFTNL_OBJ_TUNNEL_FLAGS:
117 *data_len =
sizeof(tun->tun_flags);
118 return &tun->tun_flags;
119 case NFTNL_OBJ_TUNNEL_TOS:
120 *data_len =
sizeof(tun->tun_tos);
121 return &tun->tun_tos;
122 case NFTNL_OBJ_TUNNEL_TTL:
123 *data_len =
sizeof(tun->tun_ttl);
124 return &tun->tun_ttl;
125 case NFTNL_OBJ_TUNNEL_VXLAN_GBP:
126 *data_len =
sizeof(tun->u.tun_vxlan.gbp);
127 return &tun->u.tun_vxlan.gbp;
128 case NFTNL_OBJ_TUNNEL_ERSPAN_VERSION:
129 *data_len =
sizeof(tun->u.tun_erspan.version);
130 return &tun->u.tun_erspan.version;
131 case NFTNL_OBJ_TUNNEL_ERSPAN_V1_INDEX:
132 *data_len =
sizeof(tun->u.tun_erspan.u.v1_index);
133 return &tun->u.tun_erspan.u.v1_index;
134 case NFTNL_OBJ_TUNNEL_ERSPAN_V2_HWID:
135 *data_len =
sizeof(tun->u.tun_erspan.u.v2.hwid);
136 return &tun->u.tun_erspan.u.v2.hwid;
137 case NFTNL_OBJ_TUNNEL_ERSPAN_V2_DIR:
138 *data_len =
sizeof(tun->u.tun_erspan.u.v2.dir);
139 return &tun->u.tun_erspan.u.v2.dir;
144static int nftnl_obj_tunnel_cb(
const struct nlattr *attr,
void *data)
146 const struct nlattr **tb = data;
147 int type = mnl_attr_get_type(attr);
149 if (mnl_attr_type_valid(attr, NFTA_TUNNEL_KEY_MAX) < 0)
153 case NFTA_TUNNEL_KEY_ID:
154 case NFTA_TUNNEL_KEY_FLAGS:
155 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
158 case NFTA_TUNNEL_KEY_IP:
159 case NFTA_TUNNEL_KEY_IP6:
160 case NFTA_TUNNEL_KEY_OPTS:
161 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
164 case NFTA_TUNNEL_KEY_SPORT:
165 case NFTA_TUNNEL_KEY_DPORT:
166 if (mnl_attr_validate(attr, MNL_TYPE_U16) < 0)
169 case NFTA_TUNNEL_KEY_TOS:
170 case NFTA_TUNNEL_KEY_TTL:
171 if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0)
181nftnl_obj_tunnel_build(
struct nlmsghdr *nlh,
const struct nftnl_obj *e)
183 struct nftnl_obj_tunnel *tun = nftnl_obj_data(e);
186 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_ID))
187 mnl_attr_put_u32(nlh, NFTA_TUNNEL_KEY_ID, htonl(tun->id));
188 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_IPV4_SRC) ||
189 e->flags & (1 << NFTNL_OBJ_TUNNEL_IPV4_DST)) {
190 nest = mnl_attr_nest_start(nlh, NFTA_TUNNEL_KEY_IP);
191 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_IPV4_SRC))
192 mnl_attr_put_u32(nlh, NFTA_TUNNEL_KEY_IP_SRC, tun->src_v4);
193 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_IPV4_DST))
194 mnl_attr_put_u32(nlh, NFTA_TUNNEL_KEY_IP_DST, tun->dst_v4);
195 mnl_attr_nest_end(nlh, nest);
197 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_IPV6_SRC) ||
198 e->flags & (1 << NFTNL_OBJ_TUNNEL_IPV6_DST)) {
199 nest = mnl_attr_nest_start(nlh, NFTA_TUNNEL_KEY_IP6);
200 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_IPV6_SRC))
201 mnl_attr_put(nlh, NFTA_TUNNEL_KEY_IP6_SRC,
202 sizeof(tun->src_v6), &tun->src_v6);
203 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_IPV6_DST))
204 mnl_attr_put(nlh, NFTA_TUNNEL_KEY_IP6_DST,
205 sizeof(tun->dst_v6), &tun->dst_v6);
206 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_IPV6_FLOWLABEL))
207 mnl_attr_put_u32(nlh, NFTA_TUNNEL_KEY_IP6_FLOWLABEL,
208 htonl(tun->flowlabel));
209 mnl_attr_nest_end(nlh, nest);
211 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_SPORT))
212 mnl_attr_put_u16(nlh, NFTA_TUNNEL_KEY_SPORT, htons(tun->sport));
213 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_DPORT))
214 mnl_attr_put_u16(nlh, NFTA_TUNNEL_KEY_DPORT, htons(tun->dport));
215 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_TOS))
216 mnl_attr_put_u8(nlh, NFTA_TUNNEL_KEY_TOS, tun->tun_tos);
217 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_TTL))
218 mnl_attr_put_u8(nlh, NFTA_TUNNEL_KEY_TTL, tun->tun_ttl);
219 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_FLAGS))
220 mnl_attr_put_u32(nlh, NFTA_TUNNEL_KEY_FLAGS, htonl(tun->tun_flags));
221 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_VXLAN_GBP)) {
222 nest = mnl_attr_nest_start(nlh, NFTA_TUNNEL_KEY_OPTS);
223 mnl_attr_put_u32(nlh, NFTA_TUNNEL_KEY_VXLAN_GBP,
224 htonl(tun->u.tun_vxlan.gbp));
225 mnl_attr_nest_end(nlh, nest);
227 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_ERSPAN_VERSION) &&
228 (e->flags & (1 << NFTNL_OBJ_TUNNEL_ERSPAN_V1_INDEX) ||
229 (e->flags & (1 << NFTNL_OBJ_TUNNEL_ERSPAN_V2_HWID) &&
230 e->flags & (1u << NFTNL_OBJ_TUNNEL_ERSPAN_V2_DIR)))) {
231 struct nlattr *nest_inner;
233 nest = mnl_attr_nest_start(nlh, NFTA_TUNNEL_KEY_OPTS);
234 nest_inner = mnl_attr_nest_start(nlh, NFTA_TUNNEL_KEY_OPTS_ERSPAN);
235 mnl_attr_put_u32(nlh, NFTA_TUNNEL_KEY_ERSPAN_VERSION,
236 htonl(tun->u.tun_erspan.version));
237 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_ERSPAN_V1_INDEX))
238 mnl_attr_put_u32(nlh, NFTA_TUNNEL_KEY_ERSPAN_V1_INDEX,
239 htonl(tun->u.tun_erspan.u.v1_index));
240 if (e->flags & (1 << NFTNL_OBJ_TUNNEL_ERSPAN_V2_HWID))
241 mnl_attr_put_u8(nlh, NFTA_TUNNEL_KEY_ERSPAN_V2_HWID,
242 tun->u.tun_erspan.u.v2.hwid);
243 if (e->flags & (1u << NFTNL_OBJ_TUNNEL_ERSPAN_V2_DIR))
244 mnl_attr_put_u8(nlh, NFTA_TUNNEL_KEY_ERSPAN_V2_DIR,
245 tun->u.tun_erspan.u.v2.dir);
246 mnl_attr_nest_end(nlh, nest_inner);
247 mnl_attr_nest_end(nlh, nest);
251static int nftnl_obj_tunnel_ip_cb(
const struct nlattr *attr,
void *data)
253 const struct nlattr **tb = data;
254 int type = mnl_attr_get_type(attr);
256 if (mnl_attr_type_valid(attr, NFTA_TUNNEL_KEY_MAX) < 0)
260 case NFTA_TUNNEL_KEY_IP_SRC:
261 case NFTA_TUNNEL_KEY_IP_DST:
262 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
271static int nftnl_obj_tunnel_parse_ip(
struct nftnl_obj *e,
struct nlattr *attr,
272 struct nftnl_obj_tunnel *tun)
274 struct nlattr *tb[NFTA_TUNNEL_KEY_IP_MAX + 1] = {};
276 if (mnl_attr_parse_nested(attr, nftnl_obj_tunnel_ip_cb, tb) < 0)
279 if (tb[NFTA_TUNNEL_KEY_IP_SRC]) {
280 tun->src_v4 = mnl_attr_get_u32(tb[NFTA_TUNNEL_KEY_IP_SRC]);
281 e->flags |= (1 << NFTNL_OBJ_TUNNEL_IPV4_SRC);
283 if (tb[NFTA_TUNNEL_KEY_IP_DST]) {
284 tun->dst_v4 = mnl_attr_get_u32(tb[NFTA_TUNNEL_KEY_IP_DST]);
285 e->flags |= (1 << NFTNL_OBJ_TUNNEL_IPV4_DST);
291static int nftnl_obj_tunnel_ip6_cb(
const struct nlattr *attr,
void *data)
293 const struct nlattr **tb = data;
294 int type = mnl_attr_get_type(attr);
296 if (mnl_attr_type_valid(attr, NFTA_TUNNEL_KEY_MAX) < 0)
300 case NFTA_TUNNEL_KEY_IP6_SRC:
301 case NFTA_TUNNEL_KEY_IP6_DST:
302 if (mnl_attr_validate(attr, MNL_TYPE_BINARY) < 0)
305 case NFTA_TUNNEL_KEY_IP6_FLOWLABEL:
306 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
315static int nftnl_obj_tunnel_parse_ip6(
struct nftnl_obj *e,
struct nlattr *attr,
316 struct nftnl_obj_tunnel *tun)
318 struct nlattr *tb[NFTA_TUNNEL_KEY_IP6_MAX + 1] = {};
320 if (mnl_attr_parse_nested(attr, nftnl_obj_tunnel_ip6_cb, tb) < 0)
323 if (tb[NFTA_TUNNEL_KEY_IP6_SRC]) {
325 mnl_attr_get_payload(tb[NFTA_TUNNEL_KEY_IP6_SRC]),
326 sizeof(
struct in6_addr));
327 e->flags |= (1 << NFTNL_OBJ_TUNNEL_IPV6_SRC);
329 if (tb[NFTA_TUNNEL_KEY_IP6_DST]) {
331 mnl_attr_get_payload(tb[NFTA_TUNNEL_KEY_IP6_DST]),
332 sizeof(
struct in6_addr));
333 e->flags |= (1 << NFTNL_OBJ_TUNNEL_IPV6_DST);
335 if (tb[NFTA_TUNNEL_KEY_IP6_FLOWLABEL]) {
337 ntohl(mnl_attr_get_u32(tb[NFTA_TUNNEL_KEY_IP6_FLOWLABEL]));
338 e->flags |= (1 << NFTNL_OBJ_TUNNEL_IPV6_FLOWLABEL);
344static int nftnl_obj_tunnel_vxlan_cb(
const struct nlattr *attr,
void *data)
346 const struct nlattr **tb = data;
347 int type = mnl_attr_get_type(attr);
349 if (mnl_attr_type_valid(attr, NFTA_TUNNEL_KEY_VXLAN_MAX) < 0)
353 case NFTA_TUNNEL_KEY_VXLAN_GBP:
354 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
364nftnl_obj_tunnel_parse_vxlan(
struct nftnl_obj *e,
struct nlattr *attr,
365 struct nftnl_obj_tunnel *tun)
367 struct nlattr *tb[NFTA_TUNNEL_KEY_VXLAN_MAX + 1] = {};
369 if (mnl_attr_parse_nested(attr, nftnl_obj_tunnel_vxlan_cb, tb) < 0)
372 if (tb[NFTA_TUNNEL_KEY_VXLAN_GBP]) {
373 tun->u.tun_vxlan.gbp =
374 ntohl(mnl_attr_get_u32(tb[NFTA_TUNNEL_KEY_VXLAN_GBP]));
375 e->flags |= (1 << NFTNL_OBJ_TUNNEL_VXLAN_GBP);
381static int nftnl_obj_tunnel_erspan_cb(
const struct nlattr *attr,
void *data)
383 const struct nlattr **tb = data;
384 int type = mnl_attr_get_type(attr);
386 if (mnl_attr_type_valid(attr, NFTA_TUNNEL_KEY_ERSPAN_MAX) < 0)
390 case NFTA_TUNNEL_KEY_ERSPAN_VERSION:
391 case NFTA_TUNNEL_KEY_ERSPAN_V1_INDEX:
392 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
395 case NFTA_TUNNEL_KEY_ERSPAN_V2_HWID:
396 case NFTA_TUNNEL_KEY_ERSPAN_V2_DIR:
397 if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0)
407nftnl_obj_tunnel_parse_erspan(
struct nftnl_obj *e,
struct nlattr *attr,
408 struct nftnl_obj_tunnel *tun)
410 struct nlattr *tb[NFTA_TUNNEL_KEY_ERSPAN_MAX + 1] = {};
412 if (mnl_attr_parse_nested(attr, nftnl_obj_tunnel_erspan_cb, tb) < 0)
415 if (tb[NFTA_TUNNEL_KEY_ERSPAN_VERSION]) {
416 tun->u.tun_erspan.version =
417 ntohl(mnl_attr_get_u32(tb[NFTA_TUNNEL_KEY_ERSPAN_VERSION]));
418 e->flags |= (1 << NFTNL_OBJ_TUNNEL_ERSPAN_VERSION);
420 if (tb[NFTA_TUNNEL_KEY_ERSPAN_V1_INDEX]) {
421 tun->u.tun_erspan.u.v1_index =
422 ntohl(mnl_attr_get_u32(tb[NFTA_TUNNEL_KEY_ERSPAN_V1_INDEX]));
423 e->flags |= (1 << NFTNL_OBJ_TUNNEL_ERSPAN_V1_INDEX);
425 if (tb[NFTA_TUNNEL_KEY_ERSPAN_V2_HWID]) {
426 tun->u.tun_erspan.u.v2.hwid =
427 mnl_attr_get_u8(tb[NFTA_TUNNEL_KEY_ERSPAN_V2_HWID]);
428 e->flags |= (1 << NFTNL_OBJ_TUNNEL_ERSPAN_V2_HWID);
430 if (tb[NFTA_TUNNEL_KEY_ERSPAN_V2_DIR]) {
431 tun->u.tun_erspan.u.v2.dir =
432 mnl_attr_get_u8(tb[NFTA_TUNNEL_KEY_ERSPAN_V2_DIR]);
433 e->flags |= (1u << NFTNL_OBJ_TUNNEL_ERSPAN_V2_DIR);
439static int nftnl_obj_tunnel_opts_cb(
const struct nlattr *attr,
void *data)
441 const struct nlattr **tb = data;
442 int type = mnl_attr_get_type(attr);
444 if (mnl_attr_type_valid(attr, NFTA_TUNNEL_KEY_OPTS_MAX) < 0)
448 case NFTA_TUNNEL_KEY_OPTS_VXLAN:
449 case NFTA_TUNNEL_KEY_OPTS_ERSPAN:
450 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
460nftnl_obj_tunnel_parse_opts(
struct nftnl_obj *e,
struct nlattr *attr,
461 struct nftnl_obj_tunnel *tun)
463 struct nlattr *tb[NFTA_TUNNEL_KEY_OPTS_MAX + 1] = {};
466 if (mnl_attr_parse_nested(attr, nftnl_obj_tunnel_opts_cb, tb) < 0)
469 if (tb[NFTA_TUNNEL_KEY_OPTS_VXLAN]) {
470 err = nftnl_obj_tunnel_parse_vxlan(e, tb[NFTA_TUNNEL_KEY_OPTS_VXLAN],
472 }
else if (tb[NFTA_TUNNEL_KEY_OPTS_ERSPAN]) {
473 err = nftnl_obj_tunnel_parse_erspan(e, tb[NFTA_TUNNEL_KEY_OPTS_ERSPAN],
481nftnl_obj_tunnel_parse(
struct nftnl_obj *e,
struct nlattr *attr)
483 struct nftnl_obj_tunnel *tun = nftnl_obj_data(e);
484 struct nlattr *tb[NFTA_TUNNEL_KEY_MAX + 1] = {};
487 if (mnl_attr_parse_nested(attr, nftnl_obj_tunnel_cb, tb) < 0)
490 if (tb[NFTA_TUNNEL_KEY_ID]) {
491 tun->id = ntohl(mnl_attr_get_u32(tb[NFTA_TUNNEL_KEY_ID]));
492 e->flags |= (1 << NFTNL_OBJ_TUNNEL_ID);
494 if (tb[NFTA_TUNNEL_KEY_IP]) {
495 err = nftnl_obj_tunnel_parse_ip(e, tb[NFTA_TUNNEL_KEY_IP], tun);
498 }
else if (tb[NFTA_TUNNEL_KEY_IP6]) {
499 err = nftnl_obj_tunnel_parse_ip6(e, tb[NFTA_TUNNEL_KEY_IP6], tun);
504 if (tb[NFTA_TUNNEL_KEY_SPORT]) {
505 tun->sport = ntohs(mnl_attr_get_u16(tb[NFTA_TUNNEL_KEY_SPORT]));
506 e->flags |= (1 << NFTNL_OBJ_TUNNEL_SPORT);
508 if (tb[NFTA_TUNNEL_KEY_DPORT]) {
509 tun->dport = ntohs(mnl_attr_get_u16(tb[NFTA_TUNNEL_KEY_DPORT]));
510 e->flags |= (1 << NFTNL_OBJ_TUNNEL_DPORT);
512 if (tb[NFTA_TUNNEL_KEY_TOS]) {
513 tun->tun_tos = mnl_attr_get_u8(tb[NFTA_TUNNEL_KEY_TOS]);
514 e->flags |= (1 << NFTNL_OBJ_TUNNEL_TOS);
516 if (tb[NFTA_TUNNEL_KEY_TTL]) {
517 tun->tun_ttl = mnl_attr_get_u8(tb[NFTA_TUNNEL_KEY_TTL]);
518 e->flags |= (1 << NFTNL_OBJ_TUNNEL_TTL);
520 if (tb[NFTA_TUNNEL_KEY_FLAGS]) {
521 tun->tun_flags = mnl_attr_get_u8(tb[NFTA_TUNNEL_KEY_FLAGS]);
522 e->flags |= (1 << NFTNL_OBJ_TUNNEL_FLAGS);
524 if (tb[NFTA_TUNNEL_KEY_OPTS]) {
525 err = nftnl_obj_tunnel_parse_opts(e, tb[NFTA_TUNNEL_KEY_OPTS], tun);
533static int nftnl_obj_tunnel_snprintf(
char *buf,
size_t len,
534 uint32_t flags,
const struct nftnl_obj *e)
536 struct nftnl_obj_tunnel *tun = nftnl_obj_data(e);
538 return snprintf(buf, len,
"id %u ", tun->id);
541struct obj_ops obj_ops_tunnel = {
543 .type = NFT_OBJECT_TUNNEL,
544 .alloc_len =
sizeof(
struct nftnl_obj_tunnel),
545 .max_attr = NFTA_TUNNEL_KEY_MAX,
546 .set = nftnl_obj_tunnel_set,
547 .get = nftnl_obj_tunnel_get,
548 .parse = nftnl_obj_tunnel_parse,
549 .build = nftnl_obj_tunnel_build,
550 .output = nftnl_obj_tunnel_snprintf,