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

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