libnl 3.12.0
ip6gre.c
1/* SPDX-License-Identifier: LGPL-2.1-only */
2
3/**
4 * @ingroup link
5 * @defgroup ip6gre IP6GRE
6 * ip6gre link module
7 *
8 * @details
9 * \b Link Type Name: "ip6gre"
10 *
11 * @route_doc{link_ip6gre, IP6GRE Documentation}
12 *
13 * @{
14 */
15
16#include "nl-default.h"
17
18#include <linux/if_tunnel.h>
19
20#include <netlink/netlink.h>
21#include <netlink/attr.h>
22#include <netlink/utils.h>
23#include <netlink/object.h>
24#include <netlink/route/rtnl.h>
25#include <netlink/route/link/ip6gre.h>
26
27#include "nl-route.h"
28#include "link-api.h"
29#include "nl-aux-route/nl-route.h"
30
31#define IP6GRE_ATTR_LINK (1 << 0)
32#define IP6GRE_ATTR_IFLAGS (1 << 1)
33#define IP6GRE_ATTR_OFLAGS (1 << 2)
34#define IP6GRE_ATTR_IKEY (1 << 3)
35#define IP6GRE_ATTR_OKEY (1 << 4)
36#define IP6GRE_ATTR_LOCAL (1 << 5)
37#define IP6GRE_ATTR_REMOTE (1 << 6)
38#define IP6GRE_ATTR_TTL (1 << 7)
39#define IP6GRE_ATTR_ENCAPLIMIT (1 << 8)
40#define IP6GRE_ATTR_FLOWINFO (1 << 9)
41#define IP6GRE_ATTR_FLAGS (1 << 10)
42#define IP6GRE_ATTR_FWMARK (1 << 11)
43
45{
46 uint8_t ttl;
47 uint8_t encaplimit;
48 uint16_t iflags;
49 uint16_t oflags;
50 uint32_t ikey;
51 uint32_t okey;
52 uint32_t link;
53 uint32_t flowinfo;
54 uint32_t flags;
55 struct in6_addr local;
56 struct in6_addr remote;
57 uint32_t fwmark;
58 uint32_t ip6gre_mask;
59};
60
61static struct nla_policy ip6gre_policy[IFLA_GRE_MAX + 1] = {
62 [IFLA_GRE_LINK] = { .type = NLA_U32 },
63 [IFLA_GRE_IFLAGS] = { .type = NLA_U16 },
64 [IFLA_GRE_OFLAGS] = { .type = NLA_U16 },
65 [IFLA_GRE_IKEY] = { .type = NLA_U32 },
66 [IFLA_GRE_OKEY] = { .type = NLA_U32 },
67 [IFLA_GRE_LOCAL] = { .minlen = sizeof(struct in6_addr) },
68 [IFLA_GRE_REMOTE] = { .minlen = sizeof(struct in6_addr) },
69 [IFLA_GRE_TTL] = { .type = NLA_U8 },
70 [IFLA_GRE_ENCAP_LIMIT] = { .type = NLA_U8 },
71 [IFLA_GRE_FLOWINFO] = { .type = NLA_U32 },
72 [IFLA_GRE_FLAGS] = { .type = NLA_U32 },
73 [IFLA_GRE_FWMARK] = { .type = NLA_U32 },
74};
75
76static int ip6gre_alloc(struct rtnl_link *link)
77{
78 struct ip6gre_info *ip6gre;
79
80 if (link->l_info)
81 memset(link->l_info, 0, sizeof(*ip6gre));
82 else {
83 ip6gre = calloc(1, sizeof(*ip6gre));
84 if (!ip6gre)
85 return -NLE_NOMEM;
86
87 link->l_info = ip6gre;
88 }
89
90 return 0;
91}
92
93static int ip6gre_parse(struct rtnl_link *link, struct nlattr *data,
94 struct nlattr *xstats)
95{
96 struct nlattr *tb[IFLA_GRE_MAX + 1];
97 struct ip6gre_info *ip6gre;
98 int err;
99
100 NL_DBG(3, "Parsing IP6GRE link info\n");
101
102 err = nla_parse_nested(tb, IFLA_GRE_MAX, data, ip6gre_policy);
103 if (err < 0)
104 goto errout;
105
106 err = ip6gre_alloc(link);
107 if (err < 0)
108 goto errout;
109
110 ip6gre = link->l_info;
111
112 if (tb[IFLA_GRE_LINK]) {
113 ip6gre->link = nla_get_u32(tb[IFLA_GRE_LINK]);
114 ip6gre->ip6gre_mask |= IP6GRE_ATTR_LINK;
115 }
116
117 if (tb[IFLA_GRE_IFLAGS]) {
118 ip6gre->iflags = nla_get_u16(tb[IFLA_GRE_IFLAGS]);
119 ip6gre->ip6gre_mask |= IP6GRE_ATTR_IFLAGS;
120 }
121
122 if (tb[IFLA_GRE_OFLAGS]) {
123 ip6gre->oflags = nla_get_u16(tb[IFLA_GRE_OFLAGS]);
124 ip6gre->ip6gre_mask |= IP6GRE_ATTR_OFLAGS;
125 }
126
127 if (tb[IFLA_GRE_IKEY]) {
128 ip6gre->ikey = nla_get_u32(tb[IFLA_GRE_IKEY]);
129 ip6gre->ip6gre_mask |= IP6GRE_ATTR_IKEY;
130 }
131
132 if (tb[IFLA_GRE_OKEY]) {
133 ip6gre->okey = nla_get_u32(tb[IFLA_GRE_OKEY]);
134 ip6gre->ip6gre_mask |= IP6GRE_ATTR_OKEY;
135 }
136
137 if (tb[IFLA_GRE_LOCAL]) {
138 nla_memcpy(&ip6gre->local, tb[IFLA_GRE_LOCAL], sizeof(struct in6_addr));
139 ip6gre->ip6gre_mask |= IP6GRE_ATTR_LOCAL;
140 }
141
142 if (tb[IFLA_GRE_REMOTE]) {
143 nla_memcpy(&ip6gre->remote, tb[IFLA_GRE_REMOTE], sizeof(struct in6_addr));
144 ip6gre->ip6gre_mask |= IP6GRE_ATTR_REMOTE;
145 }
146
147 if (tb[IFLA_GRE_TTL]) {
148 ip6gre->ttl = nla_get_u8(tb[IFLA_GRE_TTL]);
149 ip6gre->ip6gre_mask |= IP6GRE_ATTR_TTL;
150 }
151
152 if (tb[IFLA_GRE_ENCAP_LIMIT]) {
153 ip6gre->encaplimit = nla_get_u8(tb[IFLA_GRE_ENCAP_LIMIT]);
154 ip6gre->ip6gre_mask |= IP6GRE_ATTR_ENCAPLIMIT;
155 }
156
157 if (tb[IFLA_GRE_FLOWINFO]) {
158 ip6gre->flowinfo = nla_get_u32(tb[IFLA_GRE_FLOWINFO]);
159 ip6gre->ip6gre_mask |= IP6GRE_ATTR_FLOWINFO;
160 }
161
162 if (tb[IFLA_GRE_FLAGS]) {
163 ip6gre->flags = nla_get_u32(tb[IFLA_GRE_FLAGS]);
164 ip6gre->ip6gre_mask |= IP6GRE_ATTR_FLAGS;
165 }
166
167 if (tb[IFLA_GRE_FWMARK]) {
168 ip6gre->fwmark = nla_get_u32(tb[IFLA_GRE_FWMARK]);
169 ip6gre->ip6gre_mask |= IP6GRE_ATTR_FWMARK;
170 }
171
172 err = 0;
173
174 errout:
175 return err;
176}
177
178static int ip6gre_put_attrs(struct nl_msg *msg, struct rtnl_link *link)
179{
180 struct ip6gre_info *ip6gre = link->l_info;
181 struct nlattr *data;
182
183 data = nla_nest_start(msg, IFLA_INFO_DATA);
184 if (!data)
185 return -NLE_MSGSIZE;
186
187 if (ip6gre->ip6gre_mask & IP6GRE_ATTR_LINK)
188 NLA_PUT_U32(msg, IFLA_GRE_LINK, ip6gre->link);
189
190 if (ip6gre->ip6gre_mask & IP6GRE_ATTR_IFLAGS)
191 NLA_PUT_U16(msg, IFLA_GRE_IFLAGS, ip6gre->iflags);
192
193 if (ip6gre->ip6gre_mask & IP6GRE_ATTR_OFLAGS)
194 NLA_PUT_U16(msg, IFLA_GRE_OFLAGS, ip6gre->oflags);
195
196 if (ip6gre->ip6gre_mask & IP6GRE_ATTR_IKEY)
197 NLA_PUT_U32(msg, IFLA_GRE_IKEY, ip6gre->ikey);
198
199 if (ip6gre->ip6gre_mask & IP6GRE_ATTR_OKEY)
200 NLA_PUT_U32(msg, IFLA_GRE_OKEY, ip6gre->okey);
201
202 if (ip6gre->ip6gre_mask & IP6GRE_ATTR_LOCAL)
203 NLA_PUT(msg, IFLA_GRE_LOCAL, sizeof(struct in6_addr), &ip6gre->local);
204
205 if (ip6gre->ip6gre_mask & IP6GRE_ATTR_REMOTE)
206 NLA_PUT(msg, IFLA_GRE_REMOTE, sizeof(struct in6_addr), &ip6gre->remote);
207
208 if (ip6gre->ip6gre_mask & IP6GRE_ATTR_TTL)
209 NLA_PUT_U8(msg, IFLA_GRE_TTL, ip6gre->ttl);
210
211 if (ip6gre->ip6gre_mask & IP6GRE_ATTR_ENCAPLIMIT)
212 NLA_PUT_U8(msg, IFLA_GRE_ENCAP_LIMIT, ip6gre->encaplimit);
213
214 if (ip6gre->ip6gre_mask & IP6GRE_ATTR_FLOWINFO)
215 NLA_PUT_U32(msg, IFLA_GRE_FLOWINFO, ip6gre->flowinfo);
216
217 if (ip6gre->ip6gre_mask & IP6GRE_ATTR_FLAGS)
218 NLA_PUT_U32(msg, IFLA_GRE_FLAGS, ip6gre->flags);
219
220 if (ip6gre->ip6gre_mask & IP6GRE_ATTR_FWMARK)
221 NLA_PUT_U32(msg, IFLA_GRE_FWMARK, ip6gre->fwmark);
222
223 nla_nest_end(msg, data);
224
225 nla_put_failure:
226
227 return 0;
228}
229
230static void ip6gre_free(struct rtnl_link *link)
231{
232 struct ip6gre_info *ip6gre = link->l_info;
233
234 free(ip6gre);
235 link->l_info = NULL;
236}
237
238static void ip6gre_dump_line(struct rtnl_link *link, struct nl_dump_params *p)
239{
240 nl_dump(p, "ip6gre : %s", link->l_name);
241}
242
243static void ip6gre_dump_details(struct rtnl_link *link, struct nl_dump_params *p)
244{
245 struct ip6gre_info *ip6gre = link->l_info;
246 char addr[INET6_ADDRSTRLEN];
247
248 if (ip6gre->ip6gre_mask & IP6GRE_ATTR_LINK) {
249 _nl_auto_rtnl_link struct rtnl_link *parent = NULL;
250 char *name;
251
252 nl_dump(p, " link ");
253
254 name = NULL;
255 parent = link_lookup(link->ce_cache, ip6gre->link);
256 if (parent)
257 name = rtnl_link_get_name(parent);
258
259 if (name)
260 nl_dump_line(p, "%s\n", name);
261 else
262 nl_dump_line(p, "%u\n", ip6gre->link);
263 }
264
265 if (ip6gre->ip6gre_mask & IP6GRE_ATTR_IFLAGS) {
266 nl_dump(p, " iflags ");
267 nl_dump_line(p, "%x\n", ip6gre->iflags);
268 }
269
270 if (ip6gre->ip6gre_mask & IP6GRE_ATTR_OFLAGS) {
271 nl_dump(p, " oflags ");
272 nl_dump_line(p, "%x\n", ip6gre->oflags);
273 }
274
275 if (ip6gre->ip6gre_mask & IP6GRE_ATTR_IKEY) {
276 nl_dump(p, " ikey ");
277 nl_dump_line(p, "%x\n",ip6gre->ikey);
278 }
279
280 if (ip6gre->ip6gre_mask & IP6GRE_ATTR_OKEY) {
281 nl_dump(p, " okey ");
282 nl_dump_line(p, "%x\n", ip6gre->okey);
283 }
284
285 if (ip6gre->ip6gre_mask & IP6GRE_ATTR_LOCAL) {
286 nl_dump(p, " local ");
287 nl_dump_line(p, "%s\n",
288 _nl_inet_ntop(AF_INET6, &ip6gre->local, addr));
289 }
290
291 if (ip6gre->ip6gre_mask & IP6GRE_ATTR_REMOTE) {
292 nl_dump(p, " remote ");
293 nl_dump_line(p, "%s\n",
294 _nl_inet_ntop(AF_INET6, &ip6gre->remote, addr));
295 }
296
297 if (ip6gre->ip6gre_mask & IP6GRE_ATTR_TTL) {
298 nl_dump(p, " ttl ");
299 nl_dump_line(p, "%u\n", ip6gre->ttl);
300 }
301
302 if (ip6gre->ip6gre_mask & IP6GRE_ATTR_ENCAPLIMIT) {
303 nl_dump(p, " encaplimit ");
304 nl_dump_line(p, "%u\n", ip6gre->encaplimit);
305 }
306
307 if (ip6gre->ip6gre_mask & IP6GRE_ATTR_FLOWINFO) {
308 nl_dump(p, " flowinfo ");
309 nl_dump_line(p, "%x\n", ip6gre->flowinfo);
310 }
311
312 if (ip6gre->ip6gre_mask & IP6GRE_ATTR_FLAGS) {
313 nl_dump(p, " flags ");
314 nl_dump_line(p, "%x\n", ip6gre->flags);
315 }
316
317 if (ip6gre->ip6gre_mask & IP6GRE_ATTR_FWMARK) {
318 nl_dump(p, " fwmark ");
319 nl_dump_line(p, "%x\n", ip6gre->fwmark);
320 }
321}
322
323static int ip6gre_clone(struct rtnl_link *dst, struct rtnl_link *src)
324{
325 struct ip6gre_info *ip6gre_dst, *ip6gre_src = src->l_info;
326 int err;
327
328 dst->l_info = NULL;
329
330 err = rtnl_link_set_type(dst, "ip6gre");
331 if (err < 0)
332 return err;
333
334 ip6gre_dst = dst->l_info;
335
336 if (!ip6gre_dst || !ip6gre_src)
337 BUG();
338
339 memcpy(ip6gre_dst, ip6gre_src, sizeof(struct ip6gre_info));
340
341 return 0;
342}
343
344static struct rtnl_link_info_ops ip6gre_info_ops = {
345 .io_name = "ip6gre",
346 .io_alloc = ip6gre_alloc,
347 .io_parse = ip6gre_parse,
348 .io_dump = {
349 [NL_DUMP_LINE] = ip6gre_dump_line,
350 [NL_DUMP_DETAILS] = ip6gre_dump_details,
351 },
352 .io_clone = ip6gre_clone,
353 .io_put_attrs = ip6gre_put_attrs,
354 .io_free = ip6gre_free,
355};
356
357#define IS_IP6GRE_LINK_ASSERT(link) \
358 if ((link)->l_info_ops != &ip6gre_info_ops) { \
359 APPBUG("Link is not a ip6gre link. set type \"ip6gre\" first.");\
360 return -NLE_OPNOTSUPP; \
361 }
362
363#define HAS_IP6GRE_ATTR_ASSERT(link,attr) \
364 if (!((link)->ip6gre_mask & (attr))) \
365 return -NLE_NOATTR;
366
367struct rtnl_link *rtnl_link_ip6gre_alloc(void)
368{
369 struct rtnl_link *link;
370 int err;
371
372 link = rtnl_link_alloc();
373 if (!link)
374 return NULL;
375
376 err = rtnl_link_set_type(link, "ip6gre");
377 if (err < 0) {
378 rtnl_link_put(link);
379 return NULL;
380 }
381
382 return link;
383}
384
385/**
386 * Check if link is a IP6GRE link
387 * @arg link Link object
388 *
389 * @return True if link is a IP6GRE link, otherwise 0 is returned.
390 */
392{
393 return link->l_info_ops && !strcmp(link->l_info_ops->io_name, "ip6gre");
394}
395
396/**
397 * Create a new IP6GRE tunnel device
398 * @arg sock netlink socket
399 * @arg name name of the tunnel deviceL
400 *
401 * Creates a new ip6gre tunnel device in the kernel
402 * @return 0 on success or a negative error code
403 */
404int rtnl_link_ip6gre_add(struct nl_sock *sk, const char *name)
405{
406 struct rtnl_link *link;
407 int err;
408
409 link = rtnl_link_ip6gre_alloc();
410 if (!link)
411 return -NLE_NOMEM;
412
413 if(name)
414 rtnl_link_set_name(link, name);
415
416 err = rtnl_link_add(sk, link, NLM_F_CREATE);
417 rtnl_link_put(link);
418
419 return err;
420}
421
422/**
423 * Set IP6GRE tunnel interface index
424 * @arg link Link object
425 * @arg index interface index
426 *
427 * @return 0 on success or a negative error code
428 */
429int rtnl_link_ip6gre_set_link(struct rtnl_link *link, uint32_t index)
430{
431 struct ip6gre_info *ip6gre = link->l_info;
432
433 IS_IP6GRE_LINK_ASSERT(link);
434
435 ip6gre->link = index;
436 ip6gre->ip6gre_mask |= IP6GRE_ATTR_LINK;
437
438 return 0;
439}
440
441/**
442 * Get IP6GRE tunnel interface index
443 * @arg link Link object
444 * @arg index addr to fill in with the interface index
445 *
446 * @return 0 on success or a negative error code
447 */
448int rtnl_link_ip6gre_get_link(struct rtnl_link *link, uint32_t *index)
449{
450 struct ip6gre_info *ip6gre = link->l_info;
451
452 IS_IP6GRE_LINK_ASSERT(link);
453
454 HAS_IP6GRE_ATTR_ASSERT(ip6gre, IP6GRE_ATTR_LINK);
455
456 *index = ip6gre->link;
457
458 return 0;
459}
460
461/**
462 * Set IP6GRE tunnel set iflags
463 * @arg link Link object
464 * @arg iflags ip6gre iflags
465 *
466 * @return 0 on success or a negative error code
467 */
468int rtnl_link_ip6gre_set_iflags(struct rtnl_link *link, uint16_t iflags)
469{
470 struct ip6gre_info *ip6gre = link->l_info;
471
472 IS_IP6GRE_LINK_ASSERT(link);
473
474 ip6gre->iflags = iflags;
475 ip6gre->ip6gre_mask |= IP6GRE_ATTR_IFLAGS;
476
477 return 0;
478}
479
480/**
481 * Get IP6GRE tunnel iflags
482 * @arg link Link object
483 * @arg iflags addr to fill in with the iflags
484 *
485 * @return 0 on success or a negative error code
486 */
487int rtnl_link_ip6gre_get_iflags(struct rtnl_link *link, uint16_t *iflags)
488{
489 struct ip6gre_info *ip6gre = link->l_info;
490
491 IS_IP6GRE_LINK_ASSERT(link);
492
493 HAS_IP6GRE_ATTR_ASSERT(ip6gre, IP6GRE_ATTR_IFLAGS);
494
495 *iflags = ip6gre->iflags;
496
497 return 0;
498}
499
500/**
501 * Set IP6GRE tunnel set oflags
502 * @arg link Link object
503 * @arg oflags ip6gre oflags
504 *
505 * @return 0 on success or a negative error code
506 */
507int rtnl_link_ip6gre_set_oflags(struct rtnl_link *link, uint16_t oflags)
508{
509 struct ip6gre_info *ip6gre = link->l_info;
510
511 IS_IP6GRE_LINK_ASSERT(link);
512
513 ip6gre->oflags = oflags;
514 ip6gre->ip6gre_mask |= IP6GRE_ATTR_OFLAGS;
515
516 return 0;
517}
518
519/**
520 * Get IP6GRE tunnel oflags
521 * @arg link Link object
522 * @arg oflags addr to fill in with the oflags
523 *
524 * @return 0 on success or a negative error code
525 */
526int rtnl_link_ip6gre_get_oflags(struct rtnl_link *link, uint16_t *oflags)
527{
528 struct ip6gre_info *ip6gre = link->l_info;
529
530 IS_IP6GRE_LINK_ASSERT(link);
531
532 HAS_IP6GRE_ATTR_ASSERT(ip6gre, IP6GRE_ATTR_OFLAGS);
533
534 *oflags = ip6gre->oflags;
535
536 return 0;
537}
538
539/**
540 * Set IP6GRE tunnel set ikey
541 * @arg link Link object
542 * @arg ikey ip6gre ikey
543 *
544 * @return 0 on success or a negative error code
545 */
546int rtnl_link_ip6gre_set_ikey(struct rtnl_link *link, uint32_t ikey)
547{
548 struct ip6gre_info *ip6gre = link->l_info;
549
550 IS_IP6GRE_LINK_ASSERT(link);
551
552 ip6gre->ikey = ikey;
553 ip6gre->ip6gre_mask |= IP6GRE_ATTR_IKEY;
554
555 return 0;
556}
557
558/**
559 * Get IP6GRE tunnel ikey
560 * @arg link Link object
561 * @arg ikey addr to fill in with the ikey
562 *
563 * @return 0 on success or a negative error code
564 */
565int rtnl_link_ip6gre_get_ikey(struct rtnl_link *link, uint32_t *ikey)
566{
567 struct ip6gre_info *ip6gre = link->l_info;
568
569 IS_IP6GRE_LINK_ASSERT(link);
570
571 HAS_IP6GRE_ATTR_ASSERT(ip6gre, IP6GRE_ATTR_IKEY);
572
573 *ikey = ip6gre->ikey;
574
575 return 0;
576}
577
578/**
579 * Set IP6GRE tunnel set okey
580 * @arg link Link object
581 * @arg okey ip6gre okey
582 *
583 * @return 0 on success or a negative error code
584 */
585int rtnl_link_ip6gre_set_okey(struct rtnl_link *link, uint32_t okey)
586{
587 struct ip6gre_info *ip6gre = link->l_info;
588
589 IS_IP6GRE_LINK_ASSERT(link);
590
591 ip6gre->okey = okey;
592 ip6gre->ip6gre_mask |= IP6GRE_ATTR_OKEY;
593
594 return 0;
595}
596
597/**
598 * Get IP6GRE tunnel okey
599 * @arg link Link object
600 * @arg okey addr to fill in with the okey
601 *
602 * @return okey value
603 */
604int rtnl_link_ip6gre_get_okey(struct rtnl_link *link, uint32_t *okey)
605{
606 struct ip6gre_info *ip6gre = link->l_info;
607
608 IS_IP6GRE_LINK_ASSERT(link);
609
610 HAS_IP6GRE_ATTR_ASSERT(ip6gre, IP6GRE_ATTR_OKEY);
611
612 *okey = ip6gre->okey;
613
614 return 0;
615}
616
617/**
618 * Set IP6GRE tunnel local address
619 * @arg link Link object
620 * @arg local local address
621 *
622 * @return 0 on success or a negative error code
623 */
624int rtnl_link_ip6gre_set_local(struct rtnl_link *link, struct in6_addr *local)
625{
626 struct ip6gre_info *ip6gre = link->l_info;
627
628 IS_IP6GRE_LINK_ASSERT(link);
629
630 memcpy(&ip6gre->local, local, sizeof(struct in6_addr));
631 ip6gre->ip6gre_mask |= IP6GRE_ATTR_LOCAL;
632
633 return 0;
634}
635
636/**
637 * Get IP6GRE tunnel local address
638 * @arg link Link object
639 * @arg local addr to fill in with local address
640 *
641 * @return 0 on success or a negative error code
642 */
643int rtnl_link_ip6gre_get_local(struct rtnl_link *link, struct in6_addr *local)
644{
645 struct ip6gre_info *ip6gre = link->l_info;
646
647 IS_IP6GRE_LINK_ASSERT(link);
648
649 HAS_IP6GRE_ATTR_ASSERT(ip6gre, IP6GRE_ATTR_LOCAL);
650
651 memcpy(local, &ip6gre->local, sizeof(struct in6_addr));
652
653 return 0;
654}
655
656/**
657 * Set IP6GRE tunnel remote address
658 * @arg link Link object
659 * @arg remote remote address
660 *
661 * @return 0 on success or a negative error code
662 */
663int rtnl_link_ip6gre_set_remote(struct rtnl_link *link, struct in6_addr *remote)
664{
665 struct ip6gre_info *ip6gre = link->l_info;
666
667 IS_IP6GRE_LINK_ASSERT(link);
668
669 memcpy(&ip6gre->remote, remote, sizeof(struct in6_addr));
670 ip6gre->ip6gre_mask |= IP6GRE_ATTR_REMOTE;
671
672 return 0;
673}
674
675/**
676 * Get IP6GRE tunnel remote address
677 * @arg link Link object
678 * @arg remote addr to fill in with remote address
679 *
680 * @return 0 on success or a negative error code
681 */
682int rtnl_link_ip6gre_get_remote(struct rtnl_link *link, struct in6_addr *remote)
683{
684 struct ip6gre_info *ip6gre = link->l_info;
685
686 IS_IP6GRE_LINK_ASSERT(link);
687
688 HAS_IP6GRE_ATTR_ASSERT(ip6gre, IP6GRE_ATTR_REMOTE);
689
690 memcpy(remote, &ip6gre->remote, sizeof(struct in6_addr));
691
692 return 0;
693}
694
695/**
696 * Set IP6GRE tunnel ttl
697 * @arg link Link object
698 * @arg ttl tunnel ttl
699 *
700 * @return 0 on success or a negative error code
701 */
702int rtnl_link_ip6gre_set_ttl(struct rtnl_link *link, uint8_t ttl)
703{
704 struct ip6gre_info *ip6gre = link->l_info;
705
706 IS_IP6GRE_LINK_ASSERT(link);
707
708 ip6gre->ttl = ttl;
709 ip6gre->ip6gre_mask |= IP6GRE_ATTR_TTL;
710
711 return 0;
712}
713
714/**
715 * Set IP6GRE tunnel ttl
716 * @arg link Link object
717 * @arg ttl addr to fill in with the ttl
718 *
719 * @return 0 on success or a negative error code
720 */
721int rtnl_link_ip6gre_get_ttl(struct rtnl_link *link, uint8_t *ttl)
722{
723 struct ip6gre_info *ip6gre = link->l_info;
724
725 IS_IP6GRE_LINK_ASSERT(link);
726
727 HAS_IP6GRE_ATTR_ASSERT(ip6gre, IP6GRE_ATTR_TTL);
728
729 *ttl = ip6gre->ttl;
730
731 return 0;
732}
733
734/**
735 * Set IP6GRE tunnel encap limit
736 * @arg link Link object
737 * @arg encaplimit tunnel encap limit value
738 *
739 * @return 0 on success or a negative error code
740 */
741int rtnl_link_ip6gre_set_encaplimit(struct rtnl_link *link, uint8_t encaplimit)
742{
743 struct ip6gre_info *ip6gre = link->l_info;
744
745 IS_IP6GRE_LINK_ASSERT(link);
746
747 ip6gre->encaplimit = encaplimit;
748 ip6gre->ip6gre_mask |= IP6GRE_ATTR_ENCAPLIMIT;
749
750 return 0;
751}
752
753/**
754 * Get IP6GRE tunnel encap limit
755 * @arg link Link object
756 * @arg encaplimit addr to fill in with the encaplimit
757 *
758 * @return 0 on success or a negative error code
759 */
760int rtnl_link_ip6gre_get_encaplimit(struct rtnl_link *link, uint8_t *encaplimit)
761{
762 struct ip6gre_info *ip6gre = link->l_info;
763
764 IS_IP6GRE_LINK_ASSERT(link);
765
766 HAS_IP6GRE_ATTR_ASSERT(ip6gre, IP6GRE_ATTR_ENCAPLIMIT);
767
768 *encaplimit = ip6gre->encaplimit;
769
770 return 0;
771}
772
773/**
774 * Set IP6GRE tunnel flowinfo
775 * @arg link Link object
776 * @arg flowinfo flowinfo value
777 *
778 * @return 0 on success or a negative error code
779 */
780int rtnl_link_ip6gre_set_flowinfo(struct rtnl_link *link, uint32_t flowinfo)
781{
782 struct ip6gre_info *ip6gre = link->l_info;
783
784 IS_IP6GRE_LINK_ASSERT(link);
785
786 ip6gre->flowinfo = flowinfo;
787 ip6gre->ip6gre_mask |= IP6GRE_ATTR_FLOWINFO;
788
789 return 0;
790}
791
792/**
793 * Get IP6GRE flowinfo
794 * @arg link Link object
795 * @arg flowinfo addr to fill in with the flowinfo
796 *
797 * @return 0 on success or a negative error code
798 */
799int rtnl_link_ip6gre_get_flowinfo(struct rtnl_link *link, uint32_t *flowinfo)
800{
801 struct ip6gre_info *ip6gre = link->l_info;
802
803 IS_IP6GRE_LINK_ASSERT(link);
804
805 HAS_IP6GRE_ATTR_ASSERT(ip6gre, IP6GRE_ATTR_FLOWINFO);
806
807 *flowinfo = ip6gre->flowinfo;
808
809 return 0;
810}
811
812/**
813 * Set IP6GRE tunnel flags
814 * @arg link Link object
815 * @arg flags tunnel flags
816 *
817 * @return 0 on success or a negative error code
818 */
819int rtnl_link_ip6gre_set_flags(struct rtnl_link *link, uint32_t flags)
820{
821 struct ip6gre_info *ip6gre = link->l_info;
822
823 IS_IP6GRE_LINK_ASSERT(link);
824
825 ip6gre->flags = flags;
826 ip6gre->ip6gre_mask |= IP6GRE_ATTR_FLAGS;
827
828 return 0;
829}
830
831/**
832 * Get IP6GRE flags
833 * @arg link Link object
834 * @arg flags addr to fill in with the tunnel flags
835 *
836 * @return 0 on success or a negative error code
837 */
838int rtnl_link_ip6gre_get_flags(struct rtnl_link *link, uint32_t *flags)
839{
840 struct ip6gre_info *ip6gre = link->l_info;
841
842 IS_IP6GRE_LINK_ASSERT(link);
843
844 HAS_IP6GRE_ATTR_ASSERT(ip6gre, IP6GRE_ATTR_FLAGS);
845
846 *flags = ip6gre->flags;
847
848 return 0;
849}
850
851/**
852 * Set IP6GRE tunnel fwmark
853 * @arg link Link object
854 * @arg fwmark fwmark
855 *
856 * @return 0 on success or a negative error code
857 */
858int rtnl_link_ip6gre_set_fwmark(struct rtnl_link *link, uint32_t fwmark)
859{
860 struct ip6gre_info *ip6gre = link->l_info;
861
862 IS_IP6GRE_LINK_ASSERT(link);
863
864 ip6gre->fwmark = fwmark;
865 ip6gre->ip6gre_mask |= IP6GRE_ATTR_FWMARK;
866
867 return 0;
868}
869
870/**
871 * Get IP6GRE tunnel fwmark
872 * @arg link Link object
873 * @arg fwmark addr to fill in with the fwmark
874 *
875 * @return 0 on success or a negative error code
876 */
877int rtnl_link_ip6gre_get_fwmark(struct rtnl_link *link, uint32_t *fwmark)
878{
879 struct ip6gre_info *ip6gre = link->l_info;
880
881 IS_IP6GRE_LINK_ASSERT(link);
882
883 HAS_IP6GRE_ATTR_ASSERT(ip6gre, IP6GRE_ATTR_FWMARK);
884
885 *fwmark = ip6gre->fwmark;
886
887 return 0;
888}
889
890static void _nl_init ip6gre_init(void)
891{
892 rtnl_link_register_info(&ip6gre_info_ops);
893}
894
895static void _nl_exit ip6gre_exit(void)
896{
897 rtnl_link_unregister_info(&ip6gre_info_ops);
898}
uint32_t nla_get_u32(const struct nlattr *nla)
Return payload of 32 bit integer attribute.
Definition attr.c:714
uint16_t nla_get_u16(const struct nlattr *nla)
Return payload of 16 bit integer attribute.
Definition attr.c:664
#define NLA_PUT_U16(msg, attrtype, value)
Add 16 bit integer attribute to netlink message.
Definition attr.h:219
#define NLA_PUT_U8(msg, attrtype, value)
Add 8 bit integer attribute to netlink message.
Definition attr.h:201
#define NLA_PUT(msg, attrtype, attrlen, data)
Add unspecific attribute to netlink message.
Definition attr.h:166
#define NLA_PUT_U32(msg, attrtype, value)
Add 32 bit integer attribute to netlink message.
Definition attr.h:237
uint8_t nla_get_u8(const struct nlattr *nla)
Return value of 8 bit integer attribute.
Definition attr.c:614
int nla_memcpy(void *dest, const struct nlattr *src, int count)
Copy attribute payload to another memory area.
Definition attr.c:355
struct nlattr * nla_nest_start(struct nl_msg *msg, int attrtype)
Start a new level of nested attributes.
Definition attr.c:974
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:1101
int nla_nest_end(struct nl_msg *msg, struct nlattr *start)
Finalize nesting of attributes.
Definition attr.c:1037
@ NLA_U8
8 bit integer
Definition attr.h:35
@ NLA_U16
16 bit integer
Definition attr.h:36
@ NLA_U32
32 bit integer
Definition attr.h:37
int rtnl_link_ip6gre_set_fwmark(struct rtnl_link *link, uint32_t fwmark)
Set IP6GRE tunnel fwmark.
Definition ip6gre.c:858
int rtnl_link_ip6gre_set_flags(struct rtnl_link *link, uint32_t flags)
Set IP6GRE tunnel flags.
Definition ip6gre.c:819
int rtnl_link_ip6gre_set_remote(struct rtnl_link *link, struct in6_addr *remote)
Set IP6GRE tunnel remote address.
Definition ip6gre.c:663
int rtnl_link_ip6gre_set_ttl(struct rtnl_link *link, uint8_t ttl)
Set IP6GRE tunnel ttl.
Definition ip6gre.c:702
int rtnl_link_ip6gre_get_oflags(struct rtnl_link *link, uint16_t *oflags)
Get IP6GRE tunnel oflags.
Definition ip6gre.c:526
int rtnl_link_ip6gre_set_okey(struct rtnl_link *link, uint32_t okey)
Set IP6GRE tunnel set okey.
Definition ip6gre.c:585
int rtnl_link_ip6gre_get_ttl(struct rtnl_link *link, uint8_t *ttl)
Set IP6GRE tunnel ttl.
Definition ip6gre.c:721
int rtnl_link_ip6gre_set_iflags(struct rtnl_link *link, uint16_t iflags)
Set IP6GRE tunnel set iflags.
Definition ip6gre.c:468
int rtnl_link_ip6gre_get_fwmark(struct rtnl_link *link, uint32_t *fwmark)
Get IP6GRE tunnel fwmark.
Definition ip6gre.c:877
int rtnl_link_ip6gre_set_link(struct rtnl_link *link, uint32_t index)
Set IP6GRE tunnel interface index.
Definition ip6gre.c:429
int rtnl_link_ip6gre_get_ikey(struct rtnl_link *link, uint32_t *ikey)
Get IP6GRE tunnel ikey.
Definition ip6gre.c:565
int rtnl_link_ip6gre_get_iflags(struct rtnl_link *link, uint16_t *iflags)
Get IP6GRE tunnel iflags.
Definition ip6gre.c:487
int rtnl_link_ip6gre_get_flowinfo(struct rtnl_link *link, uint32_t *flowinfo)
Get IP6GRE flowinfo.
Definition ip6gre.c:799
int rtnl_link_ip6gre_set_flowinfo(struct rtnl_link *link, uint32_t flowinfo)
Set IP6GRE tunnel flowinfo.
Definition ip6gre.c:780
int rtnl_link_ip6gre_set_encaplimit(struct rtnl_link *link, uint8_t encaplimit)
Set IP6GRE tunnel encap limit.
Definition ip6gre.c:741
int rtnl_link_ip6gre_get_flags(struct rtnl_link *link, uint32_t *flags)
Get IP6GRE flags.
Definition ip6gre.c:838
int rtnl_link_ip6gre_set_ikey(struct rtnl_link *link, uint32_t ikey)
Set IP6GRE tunnel set ikey.
Definition ip6gre.c:546
int rtnl_link_ip6gre_set_local(struct rtnl_link *link, struct in6_addr *local)
Set IP6GRE tunnel local address.
Definition ip6gre.c:624
int rtnl_link_ip6gre_get_link(struct rtnl_link *link, uint32_t *index)
Get IP6GRE tunnel interface index.
Definition ip6gre.c:448
int rtnl_link_ip6gre_add(struct nl_sock *sk, const char *name)
Create a new IP6GRE tunnel device.
Definition ip6gre.c:404
int rtnl_link_ip6gre_get_local(struct rtnl_link *link, struct in6_addr *local)
Get IP6GRE tunnel local address.
Definition ip6gre.c:643
int rtnl_link_ip6gre_get_okey(struct rtnl_link *link, uint32_t *okey)
Get IP6GRE tunnel okey.
Definition ip6gre.c:604
int rtnl_link_ip6gre_set_oflags(struct rtnl_link *link, uint16_t oflags)
Set IP6GRE tunnel set oflags.
Definition ip6gre.c:507
int rtnl_link_ip6gre_get_encaplimit(struct rtnl_link *link, uint8_t *encaplimit)
Get IP6GRE tunnel encap limit.
Definition ip6gre.c:760
int rtnl_link_is_ip6gre(struct rtnl_link *link)
Check if link is a IP6GRE link.
Definition ip6gre.c:391
int rtnl_link_ip6gre_get_remote(struct rtnl_link *link, struct in6_addr *remote)
Get IP6GRE tunnel remote address.
Definition ip6gre.c:682
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
Definition utils.c:1015
@ NL_DUMP_LINE
Dump object briefly on one line.
Definition types.h:20
@ NL_DUMP_DETAILS
Dump all attributes but no statistics.
Definition types.h:21
Dumping parameters.
Definition types.h:32
Attribute validation policy.
Definition attr.h:66