libnl: /data/src/libnl3/lib/route/link/ip6vti.c Source File

libnl 3.7.0

ip6vti.c
1 /* SPDX-License-Identifier: LGPL-2.1-only */
2
3 /**
4 * @ingroup link
5 * @defgroup ip6vti IP6VTI
6 * ip6vti link module
7 *
8 * @details
9 * \b Link Type Name: "vti6"
10 *
11 * @route_doc{link_ip6vti, IP6VTI Documentation}
12 *
13 * @{
14 */
15
16 #include <netlink-private/netlink.h>
17 #include <netlink/netlink.h>
18 #include <netlink/attr.h>
19 #include <netlink/utils.h>
20 #include <netlink/object.h>
21 #include <netlink/route/rtnl.h>
22 #include <netlink/route/link/ip6vti.h>
23 #include <netlink-private/route/link/api.h>
24 #include <linux/if_tunnel.h>
25
26 #define IP6VTI_ATTR_LINK (1 << 0)
27 #define IP6VTI_ATTR_IKEY (1 << 1)
28 #define IP6VTI_ATTR_OKEY (1 << 2)
29 #define IP6VTI_ATTR_LOCAL (1 << 3)
30 #define IP6VTI_ATTR_REMOTE (1 << 4)
31 #define IP6VTI_ATTR_FWMARK (1 << 5)
32
33 struct ip6vti_info
34 {
35 uint32_t link;
36 uint32_t ikey;
37 uint32_t okey;
38 struct in6_addr local;
39 struct in6_addr remote;
40 uint32_t fwmark;
41 uint32_t ip6vti_mask;
42 };
43
44 static struct nla_policy ip6vti_policy[IFLA_VTI_MAX + 1] = {
45 [IFLA_VTI_LINK] = { .type = NLA_U32 },
46 [IFLA_VTI_IKEY] = { .type = NLA_U32 },
47 [IFLA_VTI_OKEY] = { .type = NLA_U32 },
48 [IFLA_VTI_LOCAL] = { .minlen = sizeof(struct in6_addr) },
49 [IFLA_VTI_REMOTE] = { .minlen = sizeof(struct in6_addr) },
50 [IFLA_VTI_FWMARK] = { .type = NLA_U32 },
51 };
52
53 static int ip6vti_alloc(struct rtnl_link *link)
54 {
55 struct ip6vti_info *ip6vti;
56
57 if (link->l_info)
58 memset(link->l_info, 0, sizeof(*ip6vti));
59 else {
60 ip6vti = calloc(1, sizeof(*ip6vti));
61 if (!ip6vti)
62 return -NLE_NOMEM;
63
64 link->l_info = ip6vti;
65 }
66
67 return 0;
68 }
69
70 static int ip6vti_parse(struct rtnl_link *link, struct nlattr *data,
71 struct nlattr *xstats)
72 {
73 struct nlattr *tb[IFLA_VTI_MAX + 1];
74 struct ip6vti_info *ip6vti;
75 int err;
76
77 NL_DBG(3, "Parsing IP6VTI link info\n");
78
79 err = nla_parse_nested(tb, IFLA_VTI_MAX, data, ip6vti_policy);
80 if (err < 0)
81 goto errout;
82
83 err = ip6vti_alloc(link);
84 if (err < 0)
85 goto errout;
86
87 ip6vti = link->l_info;
88
89 if (tb[IFLA_VTI_LINK]) {
90 ip6vti->link = nla_get_u32(tb[IFLA_VTI_LINK]);
91 ip6vti->ip6vti_mask |= IP6VTI_ATTR_LINK;
92 }
93
94 if (tb[IFLA_VTI_IKEY]) {
95 ip6vti->ikey = nla_get_u32(tb[IFLA_VTI_IKEY]);
96 ip6vti->ip6vti_mask |= IP6VTI_ATTR_IKEY;
97 }
98
99 if (tb[IFLA_VTI_OKEY]) {
100 ip6vti->okey = nla_get_u32(tb[IFLA_VTI_OKEY]);
101 ip6vti->ip6vti_mask |= IP6VTI_ATTR_OKEY;
102 }
103
104 if (tb[IFLA_VTI_LOCAL]) {
105 nla_memcpy(&ip6vti->local, tb[IFLA_VTI_LOCAL], sizeof(struct in6_addr));
106 ip6vti->ip6vti_mask |= IP6VTI_ATTR_LOCAL;
107 }
108
109 if (tb[IFLA_VTI_REMOTE]) {
110 nla_memcpy(&ip6vti->remote, tb[IFLA_VTI_REMOTE], sizeof(struct in6_addr));
111 ip6vti->ip6vti_mask |= IP6VTI_ATTR_REMOTE;
112 }
113
114 if (tb[IFLA_VTI_FWMARK]) {
115 ip6vti->fwmark = nla_get_u32(tb[IFLA_VTI_FWMARK]);
116 ip6vti->ip6vti_mask |= IP6VTI_ATTR_FWMARK;
117 }
118
119 err = 0;
120
121 errout:
122 return err;
123 }
124
125 static int ip6vti_put_attrs(struct nl_msg *msg, struct rtnl_link *link)
126 {
127 struct ip6vti_info *ip6vti = link->l_info;
128 struct nlattr *data;
129
130 data = nla_nest_start(msg, IFLA_INFO_DATA);
131 if (!data)
132 return -NLE_MSGSIZE;
133
134 if (ip6vti->ip6vti_mask & IP6VTI_ATTR_LINK)
135 NLA_PUT_U32(msg, IFLA_VTI_LINK, ip6vti->link);
136
137 if (ip6vti->ip6vti_mask & IP6VTI_ATTR_IKEY)
138 NLA_PUT_U32(msg, IFLA_VTI_IKEY, ip6vti->ikey);
139
140 if (ip6vti->ip6vti_mask & IP6VTI_ATTR_OKEY)
141 NLA_PUT_U32(msg, IFLA_VTI_OKEY, ip6vti->okey);
142
143 if (ip6vti->ip6vti_mask & IP6VTI_ATTR_LOCAL)
144 NLA_PUT(msg, IFLA_VTI_LOCAL, sizeof(struct in6_addr), &ip6vti->local);
145
146 if (ip6vti->ip6vti_mask & IP6VTI_ATTR_REMOTE)
147 NLA_PUT(msg, IFLA_VTI_REMOTE, sizeof(struct in6_addr), &ip6vti->remote);
148
149 if (ip6vti->ip6vti_mask & IP6VTI_ATTR_FWMARK)
150 NLA_PUT_U32(msg, IFLA_VTI_FWMARK, ip6vti->fwmark);
151
152 nla_nest_end(msg, data);
153
154 nla_put_failure:
155
156 return 0;
157 }
158
159 static void ip6vti_free(struct rtnl_link *link)
160 {
161 struct ip6vti_info *ip6vti = link->l_info;
162
163 free(ip6vti);
164 link->l_info = NULL;
165 }
166
167 static void ip6vti_dump_line(struct rtnl_link *link, struct nl_dump_params *p)
168 {
169 nl_dump(p, "ip6vti : %s", link->l_name);
170 }
171
172 static void ip6vti_dump_details(struct rtnl_link *link, struct nl_dump_params *p)
173 {
174 struct ip6vti_info *ip6vti = link->l_info;
175 char *name;
176 char addr[INET6_ADDRSTRLEN];
177
178 if (ip6vti->ip6vti_mask & IP6VTI_ATTR_LINK) {
179 nl_dump(p, " link ");
180 name = rtnl_link_get_name(link);
181 if (name)
182 nl_dump_line(p, "%s\n", name);
183 else
184 nl_dump_line(p, "%u\n", ip6vti->link);
185 }
186
187 if (ip6vti->ip6vti_mask & IP6VTI_ATTR_IKEY) {
188 nl_dump(p, " ikey ");
189 nl_dump_line(p, "%x\n",ip6vti->ikey);
190 }
191
192 if (ip6vti->ip6vti_mask & IP6VTI_ATTR_OKEY) {
193 nl_dump(p, " okey ");
194 nl_dump_line(p, "%x\n", ip6vti->okey);
195 }
196
197 if (ip6vti->ip6vti_mask & IP6VTI_ATTR_LOCAL) {
198 nl_dump(p, " local ");
199 nl_dump_line(p, "%s\n",
200 _nl_inet_ntop(AF_INET6, &ip6vti->local, addr));
201 }
202
203 if (ip6vti->ip6vti_mask & IP6VTI_ATTR_REMOTE) {
204 nl_dump(p, " remote ");
205 nl_dump_line(p, "%s\n",
206 _nl_inet_ntop(AF_INET6, &ip6vti->remote, addr));
207 }
208
209 if (ip6vti->ip6vti_mask & IP6VTI_ATTR_FWMARK) {
210 nl_dump(p, " fwmark ");
211 nl_dump_line(p, "%x\n", ip6vti->fwmark);
212 }
213 }
214
215 static int ip6vti_clone(struct rtnl_link *dst, struct rtnl_link *src)
216 {
217 struct ip6vti_info *ip6vti_dst, *ip6vti_src = src->l_info;
218 int err;
219
220 dst->l_info = NULL;
221
222 err = rtnl_link_set_type(dst, "vti6");
223 if (err < 0)
224 return err;
225
226 ip6vti_dst = dst->l_info;
227
228 if (!ip6vti_dst || !ip6vti_src)
229 BUG();
230
231 memcpy(ip6vti_dst, ip6vti_src, sizeof(struct ip6vti_info));
232
233 return 0;
234 }
235
236 static struct rtnl_link_info_ops ip6vti_info_ops = {
237 .io_name = "vti6",
238 .io_alloc = ip6vti_alloc,
239 .io_parse = ip6vti_parse,
240 .io_dump = {
241 [NL_DUMP_LINE] = ip6vti_dump_line,
242 [NL_DUMP_DETAILS] = ip6vti_dump_details,
243 },
244 .io_clone = ip6vti_clone,
245 .io_put_attrs = ip6vti_put_attrs,
246 .io_free = ip6vti_free,
247 };
248
249 #define IS_IP6VTI_LINK_ASSERT(link) \
250 if ((link)->l_info_ops != &ip6vti_info_ops) { \
251 APPBUG("Link is not a ip6vti link. set type \"vti6\" first."); \
252 return -NLE_OPNOTSUPP; \
253 }
254
255 #define HAS_IP6VTI_ATTR_ASSERT(ip6vti,attr) \
256 if (!((ip6vti)->ip6vti_mask & (attr))) \
257 return -NLE_NOATTR;
258
259 struct rtnl_link *rtnl_link_ip6vti_alloc(void)
260 {
261 struct rtnl_link *link;
262 int err;
263
264 link = rtnl_link_alloc();
265 if (!link)
266 return NULL;
267
268 err = rtnl_link_set_type(link, "vti6");
269 if (err < 0) {
270 rtnl_link_put(link);
271 return NULL;
272 }
273
274 return link;
275 }
276
277 /**
278 * Check if link is a IP6VTI link
279 * @arg link Link object
280 *
281 * @return True if link is a IP6VTI link, otherwise 0 is returned.
282 */
283 int rtnl_link_is_ip6vti(struct rtnl_link *link)
284 {
285 return link->l_info_ops && !strcmp(link->l_info_ops->io_name, "vti6");
286 }
287 /**
288 * Create a new vti6 tunnel device
289 * @arg sock netlink socket
290 * @arg name name of the tunnel deviceL
291 *
292 * Creates a new vti6 tunnel device in the kernel
293 * @return 0 on success or a negative error code
294 */
295 int rtnl_link_ip6vti_add(struct nl_sock *sk, const char *name)
296 {
297 struct rtnl_link *link;
298 int err;
299
300 link = rtnl_link_ip6vti_alloc();
301 if (!link)
302 return -NLE_NOMEM;
303
304 if(name)
305 rtnl_link_set_name(link, name);
306
307 err = rtnl_link_add(sk, link, NLM_F_CREATE);
308 rtnl_link_put(link);
309
310 return err;
311 }
312 /**
313 * Set IP6VTI tunnel interface index
314 * @arg link Link object
315 * @arg index interface index
316 *
317 * @return 0 on success or a negative error code
318 */
319 int rtnl_link_ip6vti_set_link(struct rtnl_link *link, uint32_t index)
320 {
321 struct ip6vti_info *ip6vti = link->l_info;
322
323 IS_IP6VTI_LINK_ASSERT(link);
324
325 ip6vti->link = index;
326 ip6vti->ip6vti_mask |= IP6VTI_ATTR_LINK;
327
328 return 0;
329 }
330
331 /**
332 * Get IP6VTI tunnel interface index
333 * @arg link Link object
334 * @arg index addr to fill in with the interface index
335 *
336 * @return 0 on success or a negative error code
337 */
338 int rtnl_link_ip6vti_get_link(struct rtnl_link *link, uint32_t *index)
339 {
340 struct ip6vti_info *ip6vti = link->l_info;
341
342 IS_IP6VTI_LINK_ASSERT(link);
343
344 HAS_IP6VTI_ATTR_ASSERT(ip6vti, IP6VTI_ATTR_LINK);
345
346 *index = ip6vti->link;
347
348 return 0;
349 }
350
351 /**
352 * Set IP6VTI tunnel set ikey
353 * @arg link Link object
354 * @arg ikey gre ikey
355 *
356 * @return 0 on success or a negative error code
357 */
358 int rtnl_link_ip6vti_set_ikey(struct rtnl_link *link, uint32_t ikey)
359 {
360 struct ip6vti_info *ip6vti = link->l_info;
361
362 IS_IP6VTI_LINK_ASSERT(link);
363
364 ip6vti->ikey = ikey;
365 ip6vti->ip6vti_mask |= IP6VTI_ATTR_IKEY;
366
367 return 0;
368 }
369
370 /**
371 * Get IP6VTI tunnel ikey
372 * @arg link Link object
373 * @arg ikey addr to fill in with the ikey
374 *
375 * @return 0 on success or a negative error code
376 */
377 int rtnl_link_ip6vti_get_ikey(struct rtnl_link *link, uint32_t *ikey)
378 {
379 struct ip6vti_info *ip6vti = link->l_info;
380
381 IS_IP6VTI_LINK_ASSERT(link);
382
383 HAS_IP6VTI_ATTR_ASSERT(ip6vti, IP6VTI_ATTR_IKEY);
384
385 *ikey = ip6vti->ikey;
386
387 return 0;
388 }
389
390 /**
391 * Set IP6VTI tunnel set okey
392 * @arg link Link object
393 * @arg okey gre okey
394 *
395 * @return 0 on success or a negative error code
396 */
397 int rtnl_link_ip6vti_set_okey(struct rtnl_link *link, uint32_t okey)
398 {
399 struct ip6vti_info *ip6vti = link->l_info;
400
401 IS_IP6VTI_LINK_ASSERT(link);
402
403 ip6vti->okey = okey;
404 ip6vti->ip6vti_mask |= IP6VTI_ATTR_OKEY;
405
406 return 0;
407 }
408
409 /**
410 * Get IP6VTI tunnel okey
411 * @arg link Link object
412 * @arg okey addr to fill in with the okey
413 *
414 * @return 0 on success or a negative error code
415 */
416 int rtnl_link_ip6vti_get_okey(struct rtnl_link *link, uint32_t *okey)
417 {
418 struct ip6vti_info *ip6vti = link->l_info;
419
420 IS_IP6VTI_LINK_ASSERT(link);
421
422 HAS_IP6VTI_ATTR_ASSERT(ip6vti, IP6VTI_ATTR_OKEY);
423
424 *okey = ip6vti->okey;
425
426 return 0;
427 }
428
429 /**
430 * Set IP6VTI tunnel local address
431 * @arg link Link object
432 * @arg local local address
433 *
434 * @return 0 on success or a negative error code
435 */
436 int rtnl_link_ip6vti_set_local(struct rtnl_link *link, struct in6_addr *local)
437 {
438 struct ip6vti_info *ip6vti = link->l_info;
439
440 IS_IP6VTI_LINK_ASSERT(link);
441
442 memcpy(&ip6vti->local, local, sizeof(struct in6_addr));
443 ip6vti->ip6vti_mask |= IP6VTI_ATTR_LOCAL;
444
445 return 0;
446 }
447
448 /**
449 * Get IP6VTI tunnel local address
450 * @arg link Link object
451 * @arg local addr to fill in with remote address
452 *
453 * @return 0 on success or a negative error code
454 */
455 int rtnl_link_ip6vti_get_local(struct rtnl_link *link, struct in6_addr *local)
456 {
457 struct ip6vti_info *ip6vti = link->l_info;
458
459 IS_IP6VTI_LINK_ASSERT(link);
460
461 HAS_IP6VTI_ATTR_ASSERT(ip6vti, IP6VTI_ATTR_LOCAL);
462
463 memcpy(local, &ip6vti->local, sizeof(struct in6_addr));
464
465 return 0;
466 }
467
468 /**
469 * Set IP6VTI tunnel remote address
470 * @arg link Link object
471 * @arg remote remote address
472 *
473 * @return 0 on success or a negative error code
474 */
475 int rtnl_link_ip6vti_set_remote(struct rtnl_link *link, struct in6_addr *remote)
476 {
477 struct ip6vti_info *ip6vti = link->l_info;
478
479 IS_IP6VTI_LINK_ASSERT(link);
480
481 memcpy(&ip6vti->remote, remote, sizeof(struct in6_addr));
482 ip6vti->ip6vti_mask |= IP6VTI_ATTR_REMOTE;
483
484 return 0;
485 }
486
487 /**
488 * Get IP6VTI tunnel remote address
489 * @arg link Link object
490 * @arg remote addr to fill in with remote address
491 *
492 * @return 0 on success or a negative error code
493 */
494 int rtnl_link_ip6vti_get_remote(struct rtnl_link *link, struct in6_addr *remote)
495 {
496 struct ip6vti_info *ip6vti = link->l_info;
497
498 IS_IP6VTI_LINK_ASSERT(link);
499
500 HAS_IP6VTI_ATTR_ASSERT(ip6vti, IP6VTI_ATTR_REMOTE);
501
502 memcpy(remote, &ip6vti->remote, sizeof(struct in6_addr));
503
504 return 0;
505 }
506
507 /**
508 * Set IP6VTI tunnel fwmark
509 * @arg link Link object
510 * @arg fwmark fwmark
511 *
512 * @return 0 on success or a negative error code
513 */
514 int rtnl_link_ip6vti_set_fwmark(struct rtnl_link *link, uint32_t fwmark)
515 {
516 struct ip6vti_info *ip6vti = link->l_info;
517
518 IS_IP6VTI_LINK_ASSERT(link);
519
520 ip6vti->fwmark = fwmark;
521 ip6vti->ip6vti_mask |= IP6VTI_ATTR_FWMARK;
522
523 return 0;
524 }
525
526 /**
527 * Get IP6VTI tunnel fwmark
528 * @arg link Link object
529 * @arg fwmark addr to fill in with the fwmark
530 *
531 * @return 0 on success or a negative error code
532 */
533 int rtnl_link_ip6vti_get_fwmark(struct rtnl_link *link, uint32_t *fwmark)
534 {
535 struct ip6vti_info *ip6vti = link->l_info;
536
537 IS_IP6VTI_LINK_ASSERT(link);
538
539 HAS_IP6VTI_ATTR_ASSERT(ip6vti, IP6VTI_ATTR_FWMARK);
540
541 *fwmark = ip6vti->fwmark;
542
543 return 0;
544 }
545
546 static void __init ip6vti_init(void)
547 {
548 rtnl_link_register_info(&ip6vti_info_ops);
549 }
550
551 static void __exit ip6vti_exit(void)
552 {
553 rtnl_link_unregister_info(&ip6vti_info_ops);
554 }
nla_get_u32
uint32_t nla_get_u32(const struct nlattr *nla)
Return payload of 32 bit integer attribute.
Definition: attr.c:699
NLA_PUT
#define NLA_PUT(msg, attrtype, attrlen, data)
Add unspecific attribute to netlink message.
Definition: attr.h:159
NLA_PUT_U32
#define NLA_PUT_U32(msg, attrtype, value)
Add 32 bit integer attribute to netlink message.
Definition: attr.h:230
nla_memcpy
int nla_memcpy(void *dest, const struct nlattr *src, int count)
Copy attribute payload to another memory area.
Definition: attr.c:346
nla_nest_start
struct nlattr * nla_nest_start(struct nl_msg *msg, int attrtype)
Start a new level of nested attributes.
Definition: attr.c:895
nla_parse_nested
int nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla, const struct nla_policy *policy)
Create attribute index based on nested attribute.
Definition: attr.c:1013
nla_nest_end
int nla_nest_end(struct nl_msg *msg, struct nlattr *start)
Finalize nesting of attributes.
Definition: attr.c:958
NLA_U32
@ NLA_U32
32 bit integer
Definition: attr.h:37
rtnl_link_ip6vti_add
int rtnl_link_ip6vti_add(struct nl_sock *sk, const char *name)
Create a new vti6 tunnel device.
Definition: ip6vti.c:295
rtnl_link_ip6vti_get_link
int rtnl_link_ip6vti_get_link(struct rtnl_link *link, uint32_t *index)
Get IP6VTI tunnel interface index.
Definition: ip6vti.c:338
rtnl_link_ip6vti_get_local
int rtnl_link_ip6vti_get_local(struct rtnl_link *link, struct in6_addr *local)
Get IP6VTI tunnel local address.
Definition: ip6vti.c:455
rtnl_link_ip6vti_set_link
int rtnl_link_ip6vti_set_link(struct rtnl_link *link, uint32_t index)
Set IP6VTI tunnel interface index.
Definition: ip6vti.c:319
rtnl_link_ip6vti_get_fwmark
int rtnl_link_ip6vti_get_fwmark(struct rtnl_link *link, uint32_t *fwmark)
Get IP6VTI tunnel fwmark.
Definition: ip6vti.c:533
rtnl_link_ip6vti_set_remote
int rtnl_link_ip6vti_set_remote(struct rtnl_link *link, struct in6_addr *remote)
Set IP6VTI tunnel remote address.
Definition: ip6vti.c:475
rtnl_link_ip6vti_set_fwmark
int rtnl_link_ip6vti_set_fwmark(struct rtnl_link *link, uint32_t fwmark)
Set IP6VTI tunnel fwmark.
Definition: ip6vti.c:514
rtnl_link_is_ip6vti
int rtnl_link_is_ip6vti(struct rtnl_link *link)
Check if link is a IP6VTI link.
Definition: ip6vti.c:283
rtnl_link_ip6vti_set_local
int rtnl_link_ip6vti_set_local(struct rtnl_link *link, struct in6_addr *local)
Set IP6VTI tunnel local address.
Definition: ip6vti.c:436
rtnl_link_ip6vti_set_okey
int rtnl_link_ip6vti_set_okey(struct rtnl_link *link, uint32_t okey)
Set IP6VTI tunnel set okey.
Definition: ip6vti.c:397
rtnl_link_ip6vti_get_remote
int rtnl_link_ip6vti_get_remote(struct rtnl_link *link, struct in6_addr *remote)
Get IP6VTI tunnel remote address.
Definition: ip6vti.c:494
rtnl_link_ip6vti_get_okey
int rtnl_link_ip6vti_get_okey(struct rtnl_link *link, uint32_t *okey)
Get IP6VTI tunnel okey.
Definition: ip6vti.c:416
rtnl_link_ip6vti_set_ikey
int rtnl_link_ip6vti_set_ikey(struct rtnl_link *link, uint32_t ikey)
Set IP6VTI tunnel set ikey.
Definition: ip6vti.c:358
rtnl_link_ip6vti_get_ikey
int rtnl_link_ip6vti_get_ikey(struct rtnl_link *link, uint32_t *ikey)
Get IP6VTI tunnel ikey.
Definition: ip6vti.c:377
rtnl_link_register_info
int rtnl_link_register_info(struct rtnl_link_info_ops *ops)
Register operations for a link info type.
Definition: api.c:124
rtnl_link_unregister_info
int rtnl_link_unregister_info(struct rtnl_link_info_ops *ops)
Unregister operations for a link info type.
Definition: api.c:159
rtnl_link_add
int rtnl_link_add(struct nl_sock *sk, struct rtnl_link *link, int flags)
Add virtual link.
Definition: link.c:1684
rtnl_link_get_name
char * rtnl_link_get_name(struct rtnl_link *link)
Return name of link object.
Definition: link.c:1952
rtnl_link_set_name
void rtnl_link_set_name(struct rtnl_link *link, const char *name)
Set name of link object.
Definition: link.c:1938
rtnl_link_put
void rtnl_link_put(struct rtnl_link *link)
Return a link object reference.
Definition: link.c:1919
rtnl_link_set_type
int rtnl_link_set_type(struct rtnl_link *link, const char *type)
Set type of link object.
Definition: link.c:2548
rtnl_link_alloc
struct rtnl_link * rtnl_link_alloc(void)
Allocate link object.
Definition: link.c:1910
nl_dump
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
Definition: utils.c:955
NL_DUMP_LINE
@ NL_DUMP_LINE
Dump object briefly on one line.
Definition: types.h:16
NL_DUMP_DETAILS
@ NL_DUMP_DETAILS
Dump all attributes but no statistics.
Definition: types.h:17
ip6vti_info
Definition: ip6vti.c:34
nl_dump_params
Dumping parameters.
Definition: types.h:28
nla_policy
Attribute validation policy.
Definition: attr.h:63
nla_policy::type
uint16_t type
Type of attribute or NLA_UNSPEC.
Definition: attr.h:65
rtnl_link
Link object.