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