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