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