libnl  3.2.25
ip6tnl.c
1 /*
2  * lib/route/link/ip6tnl.c IP6TNL Link Info
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation version 2.1
7  * of the License.
8  *
9  * Copyright (c) 2014 Susant Sahani <susant@redhat.com>
10  */
11 
12 /**
13  * @ingroup link
14  * @defgroup ip6tnl IP6TNL
15  * ip6tnl link module
16  *
17  * @details
18  * \b Link Type Name: "ip6tnl"
19  *
20  * @route_doc{link_ip6tnl, IP6TNL Documentation}
21  *
22  * @{
23  */
24 
25 #include <netlink-private/netlink.h>
26 #include <netlink/netlink.h>
27 #include <netlink/attr.h>
28 #include <netlink/utils.h>
29 #include <netlink/object.h>
30 #include <netlink/route/rtnl.h>
31 #include <netlink-private/route/link/api.h>
32 #include <linux/if_tunnel.h>
33 #include <netinet/in.h>
34 
35 #define IP6_TNL_ATTR_LINK (1 << 0)
36 #define IP6_TNL_ATTR_LOCAL (1 << 1)
37 #define IP6_TNL_ATTR_REMOTE (1 << 2)
38 #define IP6_TNL_ATTR_TTL (1 << 3)
39 #define IP6_TNL_ATTR_TOS (1 << 4)
40 #define IP6_TNL_ATTR_ENCAPLIMIT (1 << 5)
41 #define IP6_TNL_ATTR_FLAGS (1 << 6)
42 #define IP6_TNL_ATTR_PROTO (1 << 7)
43 #define IP6_TNL_ATTR_FLOWINFO (1 << 8)
44 
46 {
47  uint8_t ttl;
48  uint8_t tos;
49  uint8_t encap_limit;
50  uint8_t proto;
51  uint32_t flags;
52  uint32_t link;
53  uint32_t flowinfo;
54  struct in6_addr local;
55  struct in6_addr remote;
56  uint32_t ip6_tnl_mask;
57 };
58 
59 static struct nla_policy ip6_tnl_policy[IFLA_IPTUN_MAX + 1] = {
60  [IFLA_IPTUN_LINK] = { .type = NLA_U32 },
61  [IFLA_IPTUN_LOCAL] = { .minlen = sizeof(struct in6_addr) },
62  [IFLA_IPTUN_REMOTE] = { .minlen = sizeof(struct in6_addr) },
63  [IFLA_IPTUN_TTL] = { .type = NLA_U8 },
64  [IFLA_IPTUN_TOS] = { .type = NLA_U8 },
65  [IFLA_IPTUN_ENCAP_LIMIT] = { .type = NLA_U8 },
66  [IFLA_IPTUN_FLOWINFO] = { .type = NLA_U32 },
67  [IFLA_IPTUN_FLAGS] = { .type = NLA_U32 },
68  [IFLA_IPTUN_PROTO] = { .type = NLA_U8 },
69 };
70 
71 static int ip6_tnl_alloc(struct rtnl_link *link)
72 {
73  struct ip6_tnl_info *ip6_tnl;
74 
75  ip6_tnl = calloc(1, sizeof(*ip6_tnl));
76  if (!ip6_tnl)
77  return -NLE_NOMEM;
78 
79  link->l_info = ip6_tnl;
80 
81  return 0;
82 }
83 
84 static int ip6_tnl_parse(struct rtnl_link *link, struct nlattr *data,
85  struct nlattr *xstats)
86 {
87  struct nlattr *tb[IFLA_IPTUN_MAX + 1];
88  struct ip6_tnl_info *ip6_tnl;
89  int err;
90 
91  NL_DBG(3, "Parsing IP6_TNL link info");
92 
93  err = nla_parse_nested(tb, IFLA_IPTUN_MAX, data, ip6_tnl_policy);
94  if (err < 0)
95  goto errout;
96 
97  err = ip6_tnl_alloc(link);
98  if (err < 0)
99  goto errout;
100 
101  ip6_tnl = link->l_info;
102 
103  if (tb[IFLA_IPTUN_LINK]) {
104  ip6_tnl->link = nla_get_u32(tb[IFLA_IPTUN_LINK]);
105  ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_LINK;
106  }
107 
108  if (tb[IFLA_IPTUN_LOCAL]) {
109  nla_memcpy(&ip6_tnl->local, tb[IFLA_IPTUN_LOCAL], sizeof(struct in6_addr));
110  ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_LOCAL;
111  }
112 
113  if (tb[IFLA_IPTUN_REMOTE]) {
114  nla_memcpy(&ip6_tnl->remote, tb[IFLA_IPTUN_REMOTE], sizeof(struct in6_addr));
115  ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_REMOTE;
116  }
117 
118  if (tb[IFLA_IPTUN_TTL]) {
119  ip6_tnl->ttl = nla_get_u8(tb[IFLA_IPTUN_TTL]);
120  ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_TTL;
121  }
122 
123  if (tb[IFLA_IPTUN_TOS]) {
124  ip6_tnl->tos = nla_get_u8(tb[IFLA_IPTUN_TOS]);
125  ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_TOS;
126  }
127 
128  if (tb[IFLA_IPTUN_ENCAP_LIMIT]) {
129  ip6_tnl->encap_limit = nla_get_u8(tb[IFLA_IPTUN_ENCAP_LIMIT]);
130  ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_ENCAPLIMIT;
131  }
132 
133  if (tb[IFLA_IPTUN_FLAGS]) {
134  ip6_tnl->flags = nla_get_u32(tb[IFLA_IPTUN_FLAGS]);
135  ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_FLAGS;
136  }
137 
138  if (tb[IFLA_IPTUN_FLOWINFO]) {
139  ip6_tnl->flowinfo = nla_get_u32(tb[IFLA_IPTUN_FLOWINFO]);
140  ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_FLOWINFO;
141  }
142 
143  if (tb[IFLA_IPTUN_PROTO]) {
144  ip6_tnl->proto = nla_get_u8(tb[IFLA_IPTUN_PROTO]);
145  ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_PROTO;
146  }
147 
148  err = 0;
149 
150 errout:
151  return err;
152 }
153 
154 static int ip6_tnl_put_attrs(struct nl_msg *msg, struct rtnl_link *link)
155 {
156  struct ip6_tnl_info *ip6_tnl = link->l_info;
157  struct nlattr *data;
158 
159  data = nla_nest_start(msg, IFLA_INFO_DATA);
160  if (!data)
161  return -NLE_MSGSIZE;
162 
163  if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_LINK)
164  NLA_PUT_U32(msg, IFLA_IPTUN_LINK, ip6_tnl->link);
165 
166  if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_LOCAL)
167  NLA_PUT(msg, IFLA_IPTUN_LOCAL, sizeof(struct in6_addr), &ip6_tnl->local);
168 
169  if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_REMOTE)
170  NLA_PUT(msg, IFLA_IPTUN_REMOTE, sizeof(struct in6_addr), &ip6_tnl->remote);
171 
172  if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_TTL)
173  NLA_PUT_U8(msg, IFLA_IPTUN_TTL, ip6_tnl->ttl);
174 
175  if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_TOS)
176  NLA_PUT_U8(msg, IFLA_IPTUN_TOS, ip6_tnl->tos);
177 
178  if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_ENCAPLIMIT)
179  NLA_PUT_U8(msg, IFLA_IPTUN_ENCAP_LIMIT, ip6_tnl->encap_limit);
180 
181  if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_FLAGS)
182  NLA_PUT_U32(msg, IFLA_IPTUN_FLAGS, ip6_tnl->flags);
183 
184  if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_FLOWINFO)
185  NLA_PUT_U32(msg, IFLA_IPTUN_FLOWINFO, ip6_tnl->flowinfo);
186 
187  /* kernel crashes if this attribure is missing temporary fix */
188  if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_PROTO)
189  NLA_PUT_U8(msg, IFLA_IPTUN_PROTO, ip6_tnl->proto);
190  else
191  NLA_PUT_U8(msg, IFLA_IPTUN_PROTO, 0);
192 
193  nla_nest_end(msg, data);
194 
195 nla_put_failure:
196  return 0;
197 }
198 
199 static void ip6_tnl_free(struct rtnl_link *link)
200 {
201  struct ip6_tnl_info *ip6_tnl = link->l_info;
202 
203  free(ip6_tnl);
204  link->l_info = NULL;
205 }
206 
207 static void ip6_tnl_dump_line(struct rtnl_link *link, struct nl_dump_params *p)
208 {
209  nl_dump(p, "ip6_tnl : %s", link->l_name);
210 }
211 
212 static void ip6_tnl_dump_details(struct rtnl_link *link, struct nl_dump_params *p)
213 {
214  struct ip6_tnl_info *ip6_tnl = link->l_info;
215  char *name, addr[INET6_ADDRSTRLEN];
216 
217  if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_LINK) {
218  nl_dump(p, " link ");
219  name = rtnl_link_get_name(link);
220  if (name)
221  nl_dump_line(p, "%s\n", name);
222  else
223  nl_dump_line(p, "%u\n", ip6_tnl->link);
224  }
225 
226  if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_LOCAL) {
227  nl_dump(p, " local ");
228 
229  if(inet_ntop(AF_INET6, &ip6_tnl->local, addr, INET6_ADDRSTRLEN))
230  nl_dump_line(p, "%s\n", addr);
231  else
232  nl_dump_line(p, "%#x\n", ip6_tnl->local);
233  }
234 
235  if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_REMOTE) {
236  nl_dump(p, " remote ");
237 
238  if(inet_ntop(AF_INET6, &ip6_tnl->remote, addr, INET6_ADDRSTRLEN))
239  nl_dump_line(p, "%s\n", addr);
240  else
241  nl_dump_line(p, "%#x\n", ip6_tnl->remote);
242  }
243 
244  if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_TTL) {
245  nl_dump(p, " ttl ");
246  nl_dump_line(p, "%d\n", ip6_tnl->ttl);
247  }
248 
249  if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_TOS) {
250  nl_dump(p, " tos ");
251  nl_dump_line(p, "%d\n", ip6_tnl->tos);
252  }
253 
254  if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_ENCAPLIMIT) {
255  nl_dump(p, " encaplimit ");
256  nl_dump_line(p, "%d\n", ip6_tnl->encap_limit);
257  }
258 
259  if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_FLAGS) {
260  nl_dump(p, " flags ");
261  nl_dump_line(p, " (%x)\n", ip6_tnl->flags);
262  }
263 
264  if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_FLOWINFO) {
265  nl_dump(p, " flowinfo ");
266  nl_dump_line(p, " (%x)\n", ip6_tnl->flowinfo);
267  }
268 
269  if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_PROTO) {
270  nl_dump(p, " proto ");
271  nl_dump_line(p, " (%x)\n", ip6_tnl->proto);
272  }
273 }
274 
275 static int ip6_tnl_clone(struct rtnl_link *dst, struct rtnl_link *src)
276 {
277  struct ip6_tnl_info *ip6_tnl_dst, *ip6_tnl_src = src->l_info;
278  int err;
279 
280  dst->l_info = NULL;
281 
282  err = rtnl_link_set_type(dst, "ip6tnl");
283  if (err < 0)
284  return err;
285 
286  ip6_tnl_dst = dst->l_info;
287 
288  if (!ip6_tnl_dst || !ip6_tnl_src)
289  BUG();
290 
291  memcpy(ip6_tnl_dst, ip6_tnl_src, sizeof(struct ip6_tnl_info));
292 
293  return 0;
294 }
295 
296 static struct rtnl_link_info_ops ip6_tnl_info_ops = {
297  .io_name = "ip6tnl",
298  .io_alloc = ip6_tnl_alloc,
299  .io_parse = ip6_tnl_parse,
300  .io_dump = {
301  [NL_DUMP_LINE] = ip6_tnl_dump_line,
302  [NL_DUMP_DETAILS] = ip6_tnl_dump_details,
303  },
304  .io_clone = ip6_tnl_clone,
305  .io_put_attrs = ip6_tnl_put_attrs,
306  .io_free = ip6_tnl_free,
307 };
308 
309 #define IS_IP6_TNL_LINK_ASSERT(link)\
310  if ((link)->l_info_ops != &ip6_tnl_info_ops) {\
311  APPBUG("Link is not a ip6_tnl link. set type \"ip6tnl\" first.");\
312  return -NLE_OPNOTSUPP;\
313  }
314 
315 struct rtnl_link *rtnl_link_ip6_tnl_alloc(void)
316 {
317  struct rtnl_link *link;
318  int err;
319 
320  link = rtnl_link_alloc();
321  if (!link)
322  return NULL;
323 
324  err = rtnl_link_set_type(link, "ip6tnl");
325  if (err < 0) {
326  rtnl_link_put(link);
327  return NULL;
328  }
329 
330  return link;
331 }
332 
333 /**
334  * Check if link is a IP6_TNL link
335  * @arg link Link object
336  *
337  * @return True if link is a IP6_TNL link, otherwise false is returned.
338  */
340 {
341  return link->l_info_ops && !strcmp(link->l_info_ops->io_name, "ip6tnl");
342 }
343 
344 /**
345  * Create a new ip6_tnl tunnel device
346  * @arg sock netlink socket
347  * @arg name name of the tunnel device
348  *
349  * Creates a new ip6_tnl tunnel device in the kernel
350  * @return 0 on success or a negative error code
351  */
352 int rtnl_link_ip6_tnl_add(struct nl_sock *sk, const char *name)
353 {
354  struct rtnl_link *link;
355  int err;
356 
357  link = rtnl_link_ip6_tnl_alloc();
358  if (!link)
359  return -NLE_NOMEM;
360 
361  if(name)
362  rtnl_link_set_name(link, name);
363 
364  err = rtnl_link_add(sk, link, NLM_F_CREATE);
365  rtnl_link_put(link);
366 
367  return err;
368 }
369 
370 /**
371  * Set IP6_TNL tunnel interface index
372  * @arg link Link object
373  * @arg index interface index
374  *
375  * @return 0 on success or a negative error code
376  */
377 int rtnl_link_ip6_tnl_set_link(struct rtnl_link *link, uint32_t index)
378 {
379  struct ip6_tnl_info *ip6_tnl = link->l_info;
380 
381  IS_IP6_TNL_LINK_ASSERT(link);
382 
383  ip6_tnl->link = index;
384  ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_LINK;
385 
386  return 0;
387 }
388 
389 /**
390  * Get IP6_TNL tunnel interface index
391  * @arg link Link object
392  *
393  * @return interface index value
394  */
395 uint32_t rtnl_link_ip6_tnl_get_link(struct rtnl_link *link)
396 {
397  struct ip6_tnl_info *ip6_tnl = link->l_info;
398 
399  IS_IP6_TNL_LINK_ASSERT(link);
400 
401  return ip6_tnl->link;
402 }
403 
404 /**
405  * Set IP6_TNL tunnel local address
406  * @arg link Link object
407  * @arg addr local address
408  *
409  * @return 0 on success or a negative error code
410  */
411 int rtnl_link_ip6_tnl_set_local(struct rtnl_link *link, struct in6_addr *addr)
412 {
413  struct ip6_tnl_info *ip6_tnl = link->l_info;
414 
415  IS_IP6_TNL_LINK_ASSERT(link);
416 
417  memcpy(&ip6_tnl->local, addr, sizeof(struct in6_addr));
418  ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_LOCAL;
419 
420  return 0;
421 }
422 
423 /**
424  * Get IP6_TNL tunnel local address
425  * @arg link Link object
426  *
427  * @return 0 on success or a negative error code
428  */
429 int rtnl_link_ip6_tnl_get_local(struct rtnl_link *link, struct in6_addr *addr)
430 {
431  struct ip6_tnl_info *ip6_tnl = link->l_info;
432 
433  IS_IP6_TNL_LINK_ASSERT(link);
434 
435  memcpy(addr, &ip6_tnl->local, sizeof(struct in6_addr));
436 
437  return 0;
438 }
439 
440 /**
441  * Set IP6_TNL tunnel remote address
442  * @arg link Link object
443  * @arg remote remote address
444  *
445  * @return 0 on success or a negative error code
446  */
447 int rtnl_link_ip6_tnl_set_remote(struct rtnl_link *link, struct in6_addr *addr)
448 {
449  struct ip6_tnl_info *ip6_tnl = link->l_info;
450 
451  IS_IP6_TNL_LINK_ASSERT(link);
452 
453  memcpy(&ip6_tnl->remote, addr, sizeof(struct in6_addr));
454  ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_REMOTE;
455 
456  return 0;
457 }
458 
459 /**
460  * Get IP6_TNL tunnel remote address
461  * @arg link Link object
462  *
463  * @return 0 on success or a negative error code
464  */
465 int rtnl_link_ip6_tnl_get_remote(struct rtnl_link *link, struct in6_addr *addr)
466 {
467  struct ip6_tnl_info *ip6_tnl = link->l_info;
468 
469  IS_IP6_TNL_LINK_ASSERT(link);
470 
471  memcpy(addr, &ip6_tnl->remote, sizeof(struct in6_addr));
472 
473  return 0;
474 }
475 
476 /**
477  * Set IP6_TNL tunnel ttl
478  * @arg link Link object
479  * @arg ttl tunnel ttl
480  *
481  * @return 0 on success or a negative error code
482  */
483 int rtnl_link_ip6_tnl_set_ttl(struct rtnl_link *link, uint8_t ttl)
484 {
485  struct ip6_tnl_info *ip6_tnl = link->l_info;
486 
487  IS_IP6_TNL_LINK_ASSERT(link);
488 
489  ip6_tnl->ttl = ttl;
490  ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_TTL;
491 
492  return 0;
493 }
494 
495 /**
496  * Get IP6_TNL tunnel ttl
497  * @arg link Link object
498  *
499  * @return ttl value
500  */
502 {
503  struct ip6_tnl_info *ip6_tnl = link->l_info;
504 
505  IS_IP6_TNL_LINK_ASSERT(link);
506 
507  return ip6_tnl->ttl;
508 }
509 
510 /**
511  * Set IP6_TNL tunnel tos
512  * @arg link Link object
513  * @arg tos tunnel tos
514  *
515  * @return 0 on success or a negative error code
516  */
517 int rtnl_link_ip6_tnl_set_tos(struct rtnl_link *link, uint8_t tos)
518 {
519  struct ip6_tnl_info *ip6_tnl = link->l_info;
520 
521  IS_IP6_TNL_LINK_ASSERT(link);
522 
523  ip6_tnl->tos = tos;
524  ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_TOS;
525 
526  return 0;
527 }
528 
529 /**
530  * Get IP6_TNL tunnel tos
531  * @arg link Link object
532  *
533  * @return tos value
534  */
536 {
537  struct ip6_tnl_info *ip6_tnl = link->l_info;
538 
539  IS_IP6_TNL_LINK_ASSERT(link);
540 
541  return ip6_tnl->tos;
542 }
543 
544 /**
545  * Set IP6_TNL tunnel encap limit
546  * @arg link Link object
547  * @arg encap_limit encaplimit value
548  *
549  * @return 0 on success or a negative error code
550  */
551 int rtnl_link_ip6_tnl_set_encaplimit(struct rtnl_link *link, uint8_t encap_limit)
552 {
553  struct ip6_tnl_info *ip6_tnl = link->l_info;
554 
555  IS_IP6_TNL_LINK_ASSERT(link);
556 
557  ip6_tnl->encap_limit = encap_limit;
558  ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_ENCAPLIMIT;
559 
560  return 0;
561 }
562 
563 /**
564  * Get IP6_TNL encaplimit
565  * @arg link Link object
566  *
567  * @return encaplimit value
568  */
570 {
571  struct ip6_tnl_info *ip6_tnl = link->l_info;
572 
573  IS_IP6_TNL_LINK_ASSERT(link);
574 
575  return ip6_tnl->encap_limit;
576 }
577 
578 /**
579  * Set IP6_TNL tunnel flowinfo
580  * @arg link Link object
581  * @arg flowinfo flowinfo value
582  *
583  * @return 0 on success or a negative error code
584  */
585 int rtnl_link_ip6_tnl_set_flowinfo(struct rtnl_link *link, uint32_t flowinfo)
586 {
587  struct ip6_tnl_info *ip6_tnl = link->l_info;
588 
589  IS_IP6_TNL_LINK_ASSERT(link);
590 
591  ip6_tnl->flowinfo = flowinfo;
592  ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_FLOWINFO;
593 
594  return 0;
595 }
596 
597 /**
598  * Get IP6_TNL flowinfo
599  * @arg link Link object
600  *
601  * @return flowinfo value
602  */
604 {
605  struct ip6_tnl_info *ip6_tnl = link->l_info;
606 
607  IS_IP6_TNL_LINK_ASSERT(link);
608 
609  return ip6_tnl->flowinfo;
610 }
611 
612 /**
613  * Set IP6_TNL tunnel flags
614  * @arg link Link object
615  * @arg flags tunnel flags
616  *
617  * @return 0 on success or a negative error code
618  */
619 int rtnl_link_ip6_tnl_set_flags(struct rtnl_link *link, uint32_t flags)
620 {
621  struct ip6_tnl_info *ip6_tnl = link->l_info;
622 
623  IS_IP6_TNL_LINK_ASSERT(link);
624 
625  ip6_tnl->flags = flags;
626  ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_FLAGS;
627 
628  return 0;
629 }
630 
631 /**
632  * Get IP6_TNL path flags
633  * @arg link Link object
634  *
635  * @return flags value
636  */
638 {
639  struct ip6_tnl_info *ip6_tnl = link->l_info;
640 
641  IS_IP6_TNL_LINK_ASSERT(link);
642 
643  return ip6_tnl->flags;
644 }
645 
646 /**
647  * Set IP6_TNL tunnel proto
648  * @arg link Link object
649  * @arg proto tunnel proto
650  *
651  * @return 0 on success or a negative error code
652  */
653 int rtnl_link_ip6_tnl_set_proto(struct rtnl_link *link, uint8_t proto)
654 {
655  struct ip6_tnl_info *ip6_tnl = link->l_info;
656 
657  IS_IP6_TNL_LINK_ASSERT(link);
658 
659  ip6_tnl->proto = proto;
660  ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_PROTO;
661 
662  return 0;
663 }
664 
665 /**
666  * Get IP6_TNL proto
667  * @arg link Link object
668  *
669  * @return proto value
670  */
672 {
673  struct ip6_tnl_info *ip6_tnl = link->l_info;
674 
675  IS_IP6_TNL_LINK_ASSERT(link);
676 
677  return ip6_tnl->proto;
678 }
679 
680 static void __init ip6_tnl_init(void)
681 {
682  rtnl_link_register_info(&ip6_tnl_info_ops);
683 }
684 
685 static void __exit ip6_tnl_exit(void)
686 {
687  rtnl_link_unregister_info(&ip6_tnl_info_ops);
688 }
Dump object briefly on one line.
Definition: types.h:22
uint8_t rtnl_link_ip6_tnl_get_ttl(struct rtnl_link *link)
Get IP6_TNL tunnel ttl.
Definition: ip6tnl.c:501
8 bit integer
Definition: attr.h:39
uint8_t rtnl_link_ip6_tnl_get_tos(struct rtnl_link *link)
Get IP6_TNL tunnel tos.
Definition: ip6tnl.c:535
uint32_t rtnl_link_ip6_tnl_get_flowinfo(struct rtnl_link *link)
Get IP6_TNL flowinfo.
Definition: ip6tnl.c:603
int rtnl_link_ip6_tnl_add(struct nl_sock *sk, const char *name)
Create a new ip6_tnl tunnel device.
Definition: ip6tnl.c:352
Attribute validation policy.
Definition: attr.h:60
int rtnl_link_ip6_tnl_set_ttl(struct rtnl_link *link, uint8_t ttl)
Set IP6_TNL tunnel ttl.
Definition: ip6tnl.c:483
int rtnl_link_ip6_tnl_set_proto(struct rtnl_link *link, uint8_t proto)
Set IP6_TNL tunnel proto.
Definition: ip6tnl.c:653
int rtnl_link_ip6_tnl_set_flags(struct rtnl_link *link, uint32_t flags)
Set IP6_TNL tunnel flags.
Definition: ip6tnl.c:619
int rtnl_link_ip6_tnl_set_remote(struct rtnl_link *link, struct in6_addr *addr)
Set IP6_TNL tunnel remote address.
Definition: ip6tnl.c:447
int rtnl_link_ip6_tnl_set_tos(struct rtnl_link *link, uint8_t tos)
Set IP6_TNL tunnel tos.
Definition: ip6tnl.c:517
#define NLA_PUT_U8(msg, attrtype, value)
Add 8 bit integer attribute to netlink message.
Definition: attr.h:171
Dump all attributes but no statistics.
Definition: types.h:23
int nla_memcpy(void *dest, struct nlattr *src, int count)
Copy attribute payload to another memory area.
Definition: attr.c:353
int rtnl_link_ip6_tnl_set_local(struct rtnl_link *link, struct in6_addr *addr)
Set IP6_TNL tunnel local address.
Definition: ip6tnl.c:411
int nla_nest_end(struct nl_msg *msg, struct nlattr *start)
Finalize nesting of attributes.
Definition: attr.c:811
uint8_t rtnl_link_ip6_tnl_get_encaplimit(struct rtnl_link *link)
Get IP6_TNL encaplimit.
Definition: ip6tnl.c:569
#define NLA_PUT(msg, attrtype, attrlen, data)
Add unspecific attribute to netlink message.
Definition: attr.h:145
int nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla, struct nla_policy *policy)
Create attribute index based on nested attribute.
Definition: attr.c:885
uint8_t nla_get_u8(struct nlattr *nla)
Return value of 8 bit integer attribute.
Definition: attr.c:574
int rtnl_link_ip6_tnl_set_flowinfo(struct rtnl_link *link, uint32_t flowinfo)
Set IP6_TNL tunnel flowinfo.
Definition: ip6tnl.c:585
#define NLA_PUT_U32(msg, attrtype, value)
Add 32 bit integer attribute to netlink message.
Definition: attr.h:189
uint8_t rtnl_link_ip6_tnl_get_proto(struct rtnl_link *link)
Get IP6_TNL proto.
Definition: ip6tnl.c:671
int rtnl_link_ip6_tnl_set_encaplimit(struct rtnl_link *link, uint8_t encap_limit)
Set IP6_TNL tunnel encap limit.
Definition: ip6tnl.c:551
uint32_t rtnl_link_ip6_tnl_get_flags(struct rtnl_link *link)
Get IP6_TNL path flags.
Definition: ip6tnl.c:637
int rtnl_link_ip6_tnl_get_local(struct rtnl_link *link, struct in6_addr *addr)
Get IP6_TNL tunnel local address.
Definition: ip6tnl.c:429
uint16_t type
Type of attribute or NLA_UNSPEC.
Definition: attr.h:62
32 bit integer
Definition: attr.h:41
int rtnl_link_is_ip6_tnl(struct rtnl_link *link)
Check if link is a IP6_TNL link.
Definition: ip6tnl.c:339
uint32_t rtnl_link_ip6_tnl_get_link(struct rtnl_link *link)
Get IP6_TNL tunnel interface index.
Definition: ip6tnl.c:395
Dumping parameters.
Definition: types.h:33
int rtnl_link_ip6_tnl_set_link(struct rtnl_link *link, uint32_t index)
Set IP6_TNL tunnel interface index.
Definition: ip6tnl.c:377
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
Definition: utils.c:915
uint32_t nla_get_u32(struct nlattr *nla)
Return payload of 32 bit integer attribute.
Definition: attr.c:624
int rtnl_link_ip6_tnl_get_remote(struct rtnl_link *link, struct in6_addr *addr)
Get IP6_TNL tunnel remote address.
Definition: ip6tnl.c:465
struct nlattr * nla_nest_start(struct nl_msg *msg, int attrtype)
Start a new level of nested attributes.
Definition: attr.c:789