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