libnl  3.4.0
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  struct rtnl_link *parent;
222 
223  if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_LINK) {
224  nl_dump(p, " link ");
225 
226  name = NULL;
227  parent = link_lookup(link->ce_cache, ip6_tnl->link);
228  if (parent)
229  name = rtnl_link_get_name(parent);
230 
231  if (name)
232  nl_dump_line(p, "%s\n", name);
233  else
234  nl_dump_line(p, "%u\n", ip6_tnl->link);
235  }
236 
237  if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_LOCAL) {
238  nl_dump(p, " local ");
239 
240  if(inet_ntop(AF_INET6, &ip6_tnl->local, addr, INET6_ADDRSTRLEN))
241  nl_dump_line(p, "%s\n", addr);
242  else
243  nl_dump_line(p, "%#x\n", ip6_tnl->local);
244  }
245 
246  if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_REMOTE) {
247  nl_dump(p, " remote ");
248 
249  if(inet_ntop(AF_INET6, &ip6_tnl->remote, addr, INET6_ADDRSTRLEN))
250  nl_dump_line(p, "%s\n", addr);
251  else
252  nl_dump_line(p, "%#x\n", ip6_tnl->remote);
253  }
254 
255  if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_TTL) {
256  nl_dump(p, " ttl ");
257  nl_dump_line(p, "%d\n", ip6_tnl->ttl);
258  }
259 
260  if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_TOS) {
261  nl_dump(p, " tos ");
262  nl_dump_line(p, "%d\n", ip6_tnl->tos);
263  }
264 
265  if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_ENCAPLIMIT) {
266  nl_dump(p, " encaplimit ");
267  nl_dump_line(p, "%d\n", ip6_tnl->encap_limit);
268  }
269 
270  if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_FLAGS) {
271  nl_dump(p, " flags ");
272  nl_dump_line(p, " (%x)\n", ip6_tnl->flags);
273  }
274 
275  if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_FLOWINFO) {
276  nl_dump(p, " flowinfo ");
277  nl_dump_line(p, " (%x)\n", ip6_tnl->flowinfo);
278  }
279 
280  if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_PROTO) {
281  nl_dump(p, " proto ");
282  nl_dump_line(p, " (%x)\n", ip6_tnl->proto);
283  }
284 }
285 
286 static int ip6_tnl_clone(struct rtnl_link *dst, struct rtnl_link *src)
287 {
288  struct ip6_tnl_info *ip6_tnl_dst, *ip6_tnl_src = src->l_info;
289  int err;
290 
291  dst->l_info = NULL;
292 
293  err = rtnl_link_set_type(dst, "ip6tnl");
294  if (err < 0)
295  return err;
296 
297  ip6_tnl_dst = dst->l_info;
298 
299  if (!ip6_tnl_dst || !ip6_tnl_src)
300  BUG();
301 
302  memcpy(ip6_tnl_dst, ip6_tnl_src, sizeof(struct ip6_tnl_info));
303 
304  return 0;
305 }
306 
307 static struct rtnl_link_info_ops ip6_tnl_info_ops = {
308  .io_name = "ip6tnl",
309  .io_alloc = ip6_tnl_alloc,
310  .io_parse = ip6_tnl_parse,
311  .io_dump = {
312  [NL_DUMP_LINE] = ip6_tnl_dump_line,
313  [NL_DUMP_DETAILS] = ip6_tnl_dump_details,
314  },
315  .io_clone = ip6_tnl_clone,
316  .io_put_attrs = ip6_tnl_put_attrs,
317  .io_free = ip6_tnl_free,
318 };
319 
320 #define IS_IP6_TNL_LINK_ASSERT(link)\
321  if ((link)->l_info_ops != &ip6_tnl_info_ops) {\
322  APPBUG("Link is not a ip6_tnl link. set type \"ip6tnl\" first.");\
323  return -NLE_OPNOTSUPP;\
324  }
325 
326 struct rtnl_link *rtnl_link_ip6_tnl_alloc(void)
327 {
328  struct rtnl_link *link;
329  int err;
330 
331  link = rtnl_link_alloc();
332  if (!link)
333  return NULL;
334 
335  err = rtnl_link_set_type(link, "ip6tnl");
336  if (err < 0) {
337  rtnl_link_put(link);
338  return NULL;
339  }
340 
341  return link;
342 }
343 
344 /**
345  * Check if link is a IP6_TNL link
346  * @arg link Link object
347  *
348  * @return True if link is a IP6_TNL link, otherwise false is returned.
349  */
351 {
352  return link->l_info_ops && !strcmp(link->l_info_ops->io_name, "ip6tnl");
353 }
354 
355 /**
356  * Create a new ip6_tnl tunnel device
357  * @arg sock netlink socket
358  * @arg name name of the tunnel device
359  *
360  * Creates a new ip6_tnl tunnel device in the kernel
361  * @return 0 on success or a negative error code
362  */
363 int rtnl_link_ip6_tnl_add(struct nl_sock *sk, const char *name)
364 {
365  struct rtnl_link *link;
366  int err;
367 
368  link = rtnl_link_ip6_tnl_alloc();
369  if (!link)
370  return -NLE_NOMEM;
371 
372  if(name)
373  rtnl_link_set_name(link, name);
374 
375  err = rtnl_link_add(sk, link, NLM_F_CREATE);
376  rtnl_link_put(link);
377 
378  return err;
379 }
380 
381 /**
382  * Set IP6_TNL tunnel interface index
383  * @arg link Link object
384  * @arg index interface index
385  *
386  * @return 0 on success or a negative error code
387  */
388 int rtnl_link_ip6_tnl_set_link(struct rtnl_link *link, uint32_t index)
389 {
390  struct ip6_tnl_info *ip6_tnl = link->l_info;
391 
392  IS_IP6_TNL_LINK_ASSERT(link);
393 
394  ip6_tnl->link = index;
395  ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_LINK;
396 
397  return 0;
398 }
399 
400 /**
401  * Get IP6_TNL tunnel interface index
402  * @arg link Link object
403  *
404  * @return interface index value
405  */
406 uint32_t rtnl_link_ip6_tnl_get_link(struct rtnl_link *link)
407 {
408  struct ip6_tnl_info *ip6_tnl = link->l_info;
409 
410  IS_IP6_TNL_LINK_ASSERT(link);
411 
412  return ip6_tnl->link;
413 }
414 
415 /**
416  * Set IP6_TNL tunnel local address
417  * @arg link Link object
418  * @arg addr local address
419  *
420  * @return 0 on success or a negative error code
421  */
422 int rtnl_link_ip6_tnl_set_local(struct rtnl_link *link, struct in6_addr *addr)
423 {
424  struct ip6_tnl_info *ip6_tnl = link->l_info;
425 
426  IS_IP6_TNL_LINK_ASSERT(link);
427 
428  memcpy(&ip6_tnl->local, addr, sizeof(struct in6_addr));
429  ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_LOCAL;
430 
431  return 0;
432 }
433 
434 /**
435  * Get IP6_TNL tunnel local address
436  * @arg link Link object
437  *
438  * @return 0 on success or a negative error code
439  */
440 int rtnl_link_ip6_tnl_get_local(struct rtnl_link *link, struct in6_addr *addr)
441 {
442  struct ip6_tnl_info *ip6_tnl = link->l_info;
443 
444  IS_IP6_TNL_LINK_ASSERT(link);
445 
446  memcpy(addr, &ip6_tnl->local, sizeof(struct in6_addr));
447 
448  return 0;
449 }
450 
451 /**
452  * Set IP6_TNL tunnel remote address
453  * @arg link Link object
454  * @arg remote remote address
455  *
456  * @return 0 on success or a negative error code
457  */
458 int rtnl_link_ip6_tnl_set_remote(struct rtnl_link *link, struct in6_addr *addr)
459 {
460  struct ip6_tnl_info *ip6_tnl = link->l_info;
461 
462  IS_IP6_TNL_LINK_ASSERT(link);
463 
464  memcpy(&ip6_tnl->remote, addr, sizeof(struct in6_addr));
465  ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_REMOTE;
466 
467  return 0;
468 }
469 
470 /**
471  * Get IP6_TNL tunnel remote address
472  * @arg link Link object
473  *
474  * @return 0 on success or a negative error code
475  */
476 int rtnl_link_ip6_tnl_get_remote(struct rtnl_link *link, struct in6_addr *addr)
477 {
478  struct ip6_tnl_info *ip6_tnl = link->l_info;
479 
480  IS_IP6_TNL_LINK_ASSERT(link);
481 
482  memcpy(addr, &ip6_tnl->remote, sizeof(struct in6_addr));
483 
484  return 0;
485 }
486 
487 /**
488  * Set IP6_TNL tunnel ttl
489  * @arg link Link object
490  * @arg ttl tunnel ttl
491  *
492  * @return 0 on success or a negative error code
493  */
494 int rtnl_link_ip6_tnl_set_ttl(struct rtnl_link *link, uint8_t ttl)
495 {
496  struct ip6_tnl_info *ip6_tnl = link->l_info;
497 
498  IS_IP6_TNL_LINK_ASSERT(link);
499 
500  ip6_tnl->ttl = ttl;
501  ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_TTL;
502 
503  return 0;
504 }
505 
506 /**
507  * Get IP6_TNL tunnel ttl
508  * @arg link Link object
509  *
510  * @return ttl value
511  */
513 {
514  struct ip6_tnl_info *ip6_tnl = link->l_info;
515 
516  IS_IP6_TNL_LINK_ASSERT(link);
517 
518  return ip6_tnl->ttl;
519 }
520 
521 /**
522  * Set IP6_TNL tunnel tos
523  * @arg link Link object
524  * @arg tos tunnel tos
525  *
526  * @return 0 on success or a negative error code
527  */
528 int rtnl_link_ip6_tnl_set_tos(struct rtnl_link *link, uint8_t tos)
529 {
530  struct ip6_tnl_info *ip6_tnl = link->l_info;
531 
532  IS_IP6_TNL_LINK_ASSERT(link);
533 
534  ip6_tnl->tos = tos;
535  ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_TOS;
536 
537  return 0;
538 }
539 
540 /**
541  * Get IP6_TNL tunnel tos
542  * @arg link Link object
543  *
544  * @return tos value
545  */
547 {
548  struct ip6_tnl_info *ip6_tnl = link->l_info;
549 
550  IS_IP6_TNL_LINK_ASSERT(link);
551 
552  return ip6_tnl->tos;
553 }
554 
555 /**
556  * Set IP6_TNL tunnel encap limit
557  * @arg link Link object
558  * @arg encap_limit encaplimit value
559  *
560  * @return 0 on success or a negative error code
561  */
562 int rtnl_link_ip6_tnl_set_encaplimit(struct rtnl_link *link, uint8_t encap_limit)
563 {
564  struct ip6_tnl_info *ip6_tnl = link->l_info;
565 
566  IS_IP6_TNL_LINK_ASSERT(link);
567 
568  ip6_tnl->encap_limit = encap_limit;
569  ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_ENCAPLIMIT;
570 
571  return 0;
572 }
573 
574 /**
575  * Get IP6_TNL encaplimit
576  * @arg link Link object
577  *
578  * @return encaplimit value
579  */
581 {
582  struct ip6_tnl_info *ip6_tnl = link->l_info;
583 
584  IS_IP6_TNL_LINK_ASSERT(link);
585 
586  return ip6_tnl->encap_limit;
587 }
588 
589 /**
590  * Set IP6_TNL tunnel flowinfo
591  * @arg link Link object
592  * @arg flowinfo flowinfo value
593  *
594  * @return 0 on success or a negative error code
595  */
596 int rtnl_link_ip6_tnl_set_flowinfo(struct rtnl_link *link, uint32_t flowinfo)
597 {
598  struct ip6_tnl_info *ip6_tnl = link->l_info;
599 
600  IS_IP6_TNL_LINK_ASSERT(link);
601 
602  ip6_tnl->flowinfo = flowinfo;
603  ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_FLOWINFO;
604 
605  return 0;
606 }
607 
608 /**
609  * Get IP6_TNL flowinfo
610  * @arg link Link object
611  *
612  * @return flowinfo value
613  */
615 {
616  struct ip6_tnl_info *ip6_tnl = link->l_info;
617 
618  IS_IP6_TNL_LINK_ASSERT(link);
619 
620  return ip6_tnl->flowinfo;
621 }
622 
623 /**
624  * Set IP6_TNL tunnel flags
625  * @arg link Link object
626  * @arg flags tunnel flags
627  *
628  * @return 0 on success or a negative error code
629  */
630 int rtnl_link_ip6_tnl_set_flags(struct rtnl_link *link, uint32_t flags)
631 {
632  struct ip6_tnl_info *ip6_tnl = link->l_info;
633 
634  IS_IP6_TNL_LINK_ASSERT(link);
635 
636  ip6_tnl->flags = flags;
637  ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_FLAGS;
638 
639  return 0;
640 }
641 
642 /**
643  * Get IP6_TNL path flags
644  * @arg link Link object
645  *
646  * @return flags value
647  */
649 {
650  struct ip6_tnl_info *ip6_tnl = link->l_info;
651 
652  IS_IP6_TNL_LINK_ASSERT(link);
653 
654  return ip6_tnl->flags;
655 }
656 
657 /**
658  * Set IP6_TNL tunnel proto
659  * @arg link Link object
660  * @arg proto tunnel proto
661  *
662  * @return 0 on success or a negative error code
663  */
664 int rtnl_link_ip6_tnl_set_proto(struct rtnl_link *link, uint8_t proto)
665 {
666  struct ip6_tnl_info *ip6_tnl = link->l_info;
667 
668  IS_IP6_TNL_LINK_ASSERT(link);
669 
670  ip6_tnl->proto = proto;
671  ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_PROTO;
672 
673  return 0;
674 }
675 
676 /**
677  * Get IP6_TNL proto
678  * @arg link Link object
679  *
680  * @return proto value
681  */
683 {
684  struct ip6_tnl_info *ip6_tnl = link->l_info;
685 
686  IS_IP6_TNL_LINK_ASSERT(link);
687 
688  return ip6_tnl->proto;
689 }
690 
691 static void __init ip6_tnl_init(void)
692 {
693  rtnl_link_register_info(&ip6_tnl_info_ops);
694 }
695 
696 static void __exit ip6_tnl_exit(void)
697 {
698  rtnl_link_unregister_info(&ip6_tnl_info_ops);
699 }
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:512
8 bit integer
Definition: attr.h:41
uint8_t rtnl_link_ip6_tnl_get_tos(struct rtnl_link *link)
Get IP6_TNL tunnel tos.
Definition: ip6tnl.c:546
uint32_t rtnl_link_ip6_tnl_get_flowinfo(struct rtnl_link *link)
Get IP6_TNL flowinfo.
Definition: ip6tnl.c:614
int rtnl_link_ip6_tnl_add(struct nl_sock *sk, const char *name)
Create a new ip6_tnl tunnel device.
Definition: ip6tnl.c:363
Attribute validation policy.
Definition: attr.h:69
uint8_t nla_get_u8(const struct nlattr *nla)
Return value of 8 bit integer attribute.
Definition: attr.c:606
int rtnl_link_ip6_tnl_set_ttl(struct rtnl_link *link, uint8_t ttl)
Set IP6_TNL tunnel ttl.
Definition: ip6tnl.c:494
int rtnl_link_ip6_tnl_set_proto(struct rtnl_link *link, uint8_t proto)
Set IP6_TNL tunnel proto.
Definition: ip6tnl.c:664
int rtnl_link_ip6_tnl_set_flags(struct rtnl_link *link, uint32_t flags)
Set IP6_TNL tunnel flags.
Definition: ip6tnl.c:630
int rtnl_link_ip6_tnl_set_remote(struct rtnl_link *link, struct in6_addr *addr)
Set IP6_TNL tunnel remote address.
Definition: ip6tnl.c:458
uint32_t nla_get_u32(const struct nlattr *nla)
Return payload of 32 bit integer attribute.
Definition: attr.c:706
int rtnl_link_ip6_tnl_set_tos(struct rtnl_link *link, uint8_t tos)
Set IP6_TNL tunnel tos.
Definition: ip6tnl.c:528
#define NLA_PUT_U8(msg, attrtype, value)
Add 8 bit integer attribute to netlink message.
Definition: attr.h:199
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:422
int nla_nest_end(struct nl_msg *msg, struct nlattr *start)
Finalize nesting of attributes.
Definition: attr.c:924
uint8_t rtnl_link_ip6_tnl_get_encaplimit(struct rtnl_link *link)
Get IP6_TNL encaplimit.
Definition: ip6tnl.c:580
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:164
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:999
int rtnl_link_ip6_tnl_set_flowinfo(struct rtnl_link *link, uint32_t flowinfo)
Set IP6_TNL tunnel flowinfo.
Definition: ip6tnl.c:596
#define NLA_PUT_U32(msg, attrtype, value)
Add 32 bit integer attribute to netlink message.
Definition: attr.h:235
uint8_t rtnl_link_ip6_tnl_get_proto(struct rtnl_link *link)
Get IP6_TNL proto.
Definition: ip6tnl.c:682
int rtnl_link_ip6_tnl_set_encaplimit(struct rtnl_link *link, uint8_t encap_limit)
Set IP6_TNL tunnel encap limit.
Definition: ip6tnl.c:562
uint32_t rtnl_link_ip6_tnl_get_flags(struct rtnl_link *link)
Get IP6_TNL path flags.
Definition: ip6tnl.c:648
int rtnl_link_ip6_tnl_get_local(struct rtnl_link *link, struct in6_addr *addr)
Get IP6_TNL tunnel local address.
Definition: ip6tnl.c:440
uint16_t type
Type of attribute or NLA_UNSPEC.
Definition: attr.h:71
32 bit integer
Definition: attr.h:43
int rtnl_link_is_ip6_tnl(struct rtnl_link *link)
Check if link is a IP6_TNL link.
Definition: ip6tnl.c:350
uint32_t rtnl_link_ip6_tnl_get_link(struct rtnl_link *link)
Get IP6_TNL tunnel interface index.
Definition: ip6tnl.c:406
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:388
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
Definition: utils.c:961
int rtnl_link_ip6_tnl_get_remote(struct rtnl_link *link, struct in6_addr *addr)
Get IP6_TNL tunnel remote address.
Definition: ip6tnl.c:476
struct nlattr * nla_nest_start(struct nl_msg *msg, int attrtype)
Start a new level of nested attributes.
Definition: attr.c:902