libnl  3.3.0
sit.c
1 /*
2  * lib/route/link/sit.c SIT 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 sit SIT
15  * sit link module
16  *
17  * @details
18  * \b Link Type Name: "sit"
19  *
20  * @route_doc{link_sit, SIT 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/sit.h>
32 #include <netlink-private/route/link/api.h>
33 #include <linux/if_tunnel.h>
34 
35 #define SIT_ATTR_LINK (1 << 0)
36 #define SIT_ATTR_LOCAL (1 << 1)
37 #define SIT_ATTR_REMOTE (1 << 2)
38 #define SIT_ATTR_TTL (1 << 3)
39 #define SIT_ATTR_TOS (1 << 4)
40 #define SIT_ATTR_PMTUDISC (1 << 5)
41 #define SIT_ATTR_FLAGS (1 << 6)
42 #define SIT_ATTR_PROTO (1 << 7)
43 #define SIT_ATTR_6RD_PREFIX (1 << 8)
44 #define SIT_ATTR_6RD_RELAY_PREFIX (1 << 9)
45 #define SIT_ATTR_6RD_PREFIXLEN (1 << 10)
46 #define SIT_ATTR_6RD_RELAY_PREFIXLEN (1 << 11)
47 
48 struct sit_info
49 {
50  uint8_t ttl;
51  uint8_t tos;
52  uint8_t pmtudisc;
53  uint8_t proto;
54  uint16_t flags;
55  uint32_t link;
56  uint32_t local;
57  uint32_t remote;
58  struct in6_addr ip6rd_prefix;
59  uint32_t ip6rd_relay_prefix;
60  uint16_t ip6rd_prefixlen;
61  uint16_t ip6rd_relay_prefixlen;
62  uint32_t sit_mask;
63 };
64 
65 static struct nla_policy sit_policy[IFLA_IPTUN_MAX + 1] = {
66  [IFLA_IPTUN_LINK] = { .type = NLA_U32 },
67  [IFLA_IPTUN_LOCAL] = { .type = NLA_U32 },
68  [IFLA_IPTUN_REMOTE] = { .type = NLA_U32 },
69  [IFLA_IPTUN_TTL] = { .type = NLA_U8 },
70  [IFLA_IPTUN_TOS] = { .type = NLA_U8 },
71  [IFLA_IPTUN_PMTUDISC] = { .type = NLA_U8 },
72  [IFLA_IPTUN_FLAGS] = { .type = NLA_U16 },
73  [IFLA_IPTUN_PROTO] = { .type = NLA_U8 },
74  [IFLA_IPTUN_6RD_PREFIX] = { .minlen = sizeof(struct in6_addr) },
75  [IFLA_IPTUN_6RD_RELAY_PREFIX] = { .type = NLA_U32 },
76  [IFLA_IPTUN_6RD_PREFIXLEN] = { .type = NLA_U16 },
77  [IFLA_IPTUN_6RD_RELAY_PREFIXLEN] = { .type = NLA_U16 },
78 };
79 
80 static int sit_alloc(struct rtnl_link *link)
81 {
82  struct sit_info *sit;
83 
84  if (link->l_info)
85  memset(link->l_info, 0, sizeof(*sit));
86  else {
87  sit = calloc(1, sizeof(*sit));
88  if (!sit)
89  return -NLE_NOMEM;
90 
91  link->l_info = sit;
92  }
93 
94  return 0;
95 }
96 
97 static int sit_parse(struct rtnl_link *link, struct nlattr *data,
98  struct nlattr *xstats)
99 {
100  struct nlattr *tb[IFLA_IPTUN_MAX + 1];
101  struct sit_info *sit;
102  int err;
103 
104  NL_DBG(3, "Parsing SIT link info\n");
105 
106  err = nla_parse_nested(tb, IFLA_IPTUN_MAX, data, sit_policy);
107  if (err < 0)
108  goto errout;
109 
110  err = sit_alloc(link);
111  if (err < 0)
112  goto errout;
113 
114  sit = link->l_info;
115 
116  if (tb[IFLA_IPTUN_LINK]) {
117  sit->link = nla_get_u32(tb[IFLA_IPTUN_LINK]);
118  sit->sit_mask |= SIT_ATTR_LINK;
119  }
120 
121  if (tb[IFLA_IPTUN_LOCAL]) {
122  sit->local = nla_get_u32(tb[IFLA_IPTUN_LOCAL]);
123  sit->sit_mask |= SIT_ATTR_LOCAL;
124  }
125 
126  if (tb[IFLA_IPTUN_REMOTE]) {
127  sit->remote = nla_get_u32(tb[IFLA_IPTUN_REMOTE]);
128  sit->sit_mask |= SIT_ATTR_REMOTE;
129  }
130 
131  if (tb[IFLA_IPTUN_TTL]) {
132  sit->ttl = nla_get_u8(tb[IFLA_IPTUN_TTL]);
133  sit->sit_mask |= SIT_ATTR_TTL;
134  }
135 
136  if (tb[IFLA_IPTUN_TOS]) {
137  sit->tos = nla_get_u8(tb[IFLA_IPTUN_TOS]);
138  sit->sit_mask |= SIT_ATTR_TOS;
139  }
140 
141  if (tb[IFLA_IPTUN_PMTUDISC]) {
142  sit->pmtudisc = nla_get_u8(tb[IFLA_IPTUN_PMTUDISC]);
143  sit->sit_mask |= SIT_ATTR_PMTUDISC;
144  }
145 
146  if (tb[IFLA_IPTUN_FLAGS]) {
147  sit->flags = nla_get_u16(tb[IFLA_IPTUN_FLAGS]);
148  sit->sit_mask |= SIT_ATTR_FLAGS;
149  }
150 
151  if (tb[IFLA_IPTUN_PROTO]) {
152  sit->proto = nla_get_u8(tb[IFLA_IPTUN_PROTO]);
153  sit->sit_mask |= SIT_ATTR_PROTO;
154  }
155 
156  if (tb[IFLA_IPTUN_6RD_PREFIX]) {
157  nla_memcpy(&sit->ip6rd_prefix, tb[IFLA_IPTUN_6RD_PREFIX],
158  sizeof(struct in6_addr));
159  sit->sit_mask |= SIT_ATTR_6RD_PREFIX;
160  }
161 
162  if (tb[IFLA_IPTUN_6RD_RELAY_PREFIX]) {
163  sit->ip6rd_relay_prefix = nla_get_u32(tb[IFLA_IPTUN_6RD_RELAY_PREFIX]);
164  sit->sit_mask |= SIT_ATTR_6RD_RELAY_PREFIX;
165  }
166 
167  if (tb[IFLA_IPTUN_6RD_PREFIXLEN]) {
168  sit->ip6rd_prefixlen = nla_get_u16(tb[IFLA_IPTUN_6RD_PREFIXLEN]);
169  sit->sit_mask |= SIT_ATTR_6RD_PREFIXLEN;
170  }
171 
172  if (tb[IFLA_IPTUN_6RD_RELAY_PREFIXLEN]) {
173  sit->ip6rd_relay_prefixlen = nla_get_u16(tb[IFLA_IPTUN_6RD_RELAY_PREFIXLEN]);
174  sit->sit_mask |= SIT_ATTR_6RD_RELAY_PREFIXLEN;
175  }
176 
177  err = 0;
178 
179 errout:
180  return err;
181 }
182 
183 static int sit_put_attrs(struct nl_msg *msg, struct rtnl_link *link)
184 {
185  struct sit_info *sit = link->l_info;
186  struct nlattr *data;
187 
188  data = nla_nest_start(msg, IFLA_INFO_DATA);
189  if (!data)
190  return -NLE_MSGSIZE;
191 
192  if (sit->sit_mask & SIT_ATTR_LINK)
193  NLA_PUT_U32(msg, IFLA_IPTUN_LINK, sit->link);
194 
195  if (sit->sit_mask & SIT_ATTR_LOCAL)
196  NLA_PUT_U32(msg, IFLA_IPTUN_LOCAL, sit->local);
197 
198  if (sit->sit_mask & SIT_ATTR_REMOTE)
199  NLA_PUT_U32(msg, IFLA_IPTUN_REMOTE, sit->remote);
200 
201  if (sit->sit_mask & SIT_ATTR_TTL)
202  NLA_PUT_U8(msg, IFLA_IPTUN_TTL, sit->ttl);
203 
204  if (sit->sit_mask & SIT_ATTR_TOS)
205  NLA_PUT_U8(msg, IFLA_IPTUN_TOS, sit->tos);
206 
207  if (sit->sit_mask & SIT_ATTR_PMTUDISC)
208  NLA_PUT_U8(msg, IFLA_IPTUN_PMTUDISC, sit->pmtudisc);
209 
210  if (sit->sit_mask & SIT_ATTR_FLAGS)
211  NLA_PUT_U16(msg, IFLA_IPTUN_FLAGS, sit->flags);
212 
213  if (sit->sit_mask & SIT_ATTR_PROTO)
214  NLA_PUT_U8(msg, IFLA_IPTUN_PROTO, sit->proto);
215 
216  if (sit->sit_mask & SIT_ATTR_6RD_PREFIX)
217  NLA_PUT(msg, IFLA_IPTUN_6RD_PREFIX, sizeof(struct in6_addr), &sit->ip6rd_prefix);
218 
219  if (sit->sit_mask & SIT_ATTR_6RD_RELAY_PREFIX)
220  NLA_PUT_U32(msg, IFLA_IPTUN_6RD_RELAY_PREFIX, sit->ip6rd_relay_prefix);
221 
222  if (sit->sit_mask & SIT_ATTR_6RD_PREFIXLEN)
223  NLA_PUT_U16(msg, IFLA_IPTUN_6RD_PREFIXLEN, sit->ip6rd_prefixlen);
224 
225  if (sit->sit_mask & SIT_ATTR_6RD_RELAY_PREFIXLEN)
226  NLA_PUT_U16(msg, IFLA_IPTUN_6RD_RELAY_PREFIXLEN, sit->ip6rd_relay_prefixlen);
227 
228  nla_nest_end(msg, data);
229 
230 nla_put_failure:
231 
232  return 0;
233 }
234 
235 static void sit_free(struct rtnl_link *link)
236 {
237  struct sit_info *sit = link->l_info;
238 
239  free(sit);
240  link->l_info = NULL;
241 }
242 
243 static void sit_dump_line(struct rtnl_link *link, struct nl_dump_params *p)
244 {
245  nl_dump(p, "sit : %s", link->l_name);
246 }
247 
248 static void sit_dump_details(struct rtnl_link *link, struct nl_dump_params *p)
249 {
250  struct sit_info *sit = link->l_info;
251  char *name, addr[INET_ADDRSTRLEN], addr6[INET6_ADDRSTRLEN];
252  struct rtnl_link *parent;
253 
254  if (sit->sit_mask & SIT_ATTR_LINK) {
255  nl_dump(p, " link ");
256 
257  name = NULL;
258  parent = link_lookup(link->ce_cache, sit->link);
259  if (parent)
260  name = rtnl_link_get_name(parent);
261 
262  if (name)
263  nl_dump_line(p, "%s\n", name);
264  else
265  nl_dump_line(p, "%u\n", sit->link);
266  }
267 
268  if (sit->sit_mask & SIT_ATTR_LOCAL) {
269  nl_dump(p, " local ");
270  if(inet_ntop(AF_INET, &sit->local, addr, sizeof(addr)))
271  nl_dump_line(p, "%s\n", addr);
272  else
273  nl_dump_line(p, "%#x\n", ntohs(sit->local));
274  }
275 
276  if (sit->sit_mask & SIT_ATTR_REMOTE) {
277  nl_dump(p, " remote ");
278  if(inet_ntop(AF_INET, &sit->remote, addr, sizeof(addr)))
279  nl_dump_line(p, "%s\n", addr);
280  else
281  nl_dump_line(p, "%#x\n", ntohs(sit->remote));
282  }
283 
284  if (sit->sit_mask & SIT_ATTR_TTL) {
285  nl_dump(p, " ttl ");
286  nl_dump_line(p, "%u\n", sit->ttl);
287  }
288 
289  if (sit->sit_mask & SIT_ATTR_TOS) {
290  nl_dump(p, " tos ");
291  nl_dump_line(p, "%u\n", sit->tos);
292  }
293 
294  if (sit->sit_mask & SIT_ATTR_FLAGS) {
295  nl_dump(p, " flags ");
296  nl_dump_line(p, " (%x)\n", sit->flags);
297  }
298 
299  if (sit->sit_mask & SIT_ATTR_PROTO) {
300  nl_dump(p, " proto ");
301  nl_dump_line(p, " (%x)\n", sit->proto);
302  }
303 
304  if (sit->sit_mask & SIT_ATTR_6RD_PREFIX) {
305  nl_dump(p, " 6rd_prefix ");
306  if(inet_ntop(AF_INET6, &sit->ip6rd_prefix, addr6, INET6_ADDRSTRLEN))
307  nl_dump_line(p, "%s\n", addr6);
308  else
309  nl_dump_line(p, "[unknown]\n");
310  }
311 
312  if (sit->sit_mask & SIT_ATTR_6RD_RELAY_PREFIX) {
313  nl_dump(p, " 6rd_relay_prefix ");
314  if(inet_ntop(AF_INET, &sit->ip6rd_relay_prefix, addr, sizeof(addr)))
315  nl_dump_line(p, "%s\n", addr);
316  else
317  nl_dump_line(p, "[unknown]\n");
318  }
319 
320  if (sit->sit_mask & SIT_ATTR_6RD_PREFIXLEN) {
321  nl_dump(p, " 6rd_prefixlen ");
322  nl_dump_line(p, "%d\n", sit->ip6rd_prefixlen);
323  }
324 
325  if (sit->sit_mask & SIT_ATTR_6RD_RELAY_PREFIXLEN) {
326  nl_dump(p, " 6rd_relay_prefixlen ");
327  nl_dump_line(p, "%d\n", sit->ip6rd_relay_prefixlen);
328  }
329 }
330 
331 static int sit_clone(struct rtnl_link *dst, struct rtnl_link *src)
332 {
333  struct sit_info *sit_dst, *sit_src = src->l_info;
334  int err;
335 
336  dst->l_info = NULL;
337 
338  err = rtnl_link_set_type(dst, "sit");
339  if (err < 0)
340  return err;
341 
342  sit_dst = dst->l_info;
343 
344  if (!sit_dst || !sit_src)
345  return -NLE_NOMEM;
346 
347  memcpy(sit_dst, sit_src, sizeof(struct sit_info));
348 
349  return 0;
350 }
351 
352 static struct rtnl_link_info_ops sit_info_ops = {
353  .io_name = "sit",
354  .io_alloc = sit_alloc,
355  .io_parse = sit_parse,
356  .io_dump = {
357  [NL_DUMP_LINE] = sit_dump_line,
358  [NL_DUMP_DETAILS] = sit_dump_details,
359  },
360  .io_clone = sit_clone,
361  .io_put_attrs = sit_put_attrs,
362  .io_free = sit_free,
363 };
364 
365 #define IS_SIT_LINK_ASSERT(link, sit) \
366  struct sit_info *sit; \
367  do { \
368  const struct rtnl_link *_link = (link); \
369  if (!_link || _link->l_info_ops != &sit_info_ops) { \
370  APPBUG("Link is not a sit link. set type \"sit\" first."); \
371  return -NLE_OPNOTSUPP; \
372  } \
373  (sit) = _link->l_info; \
374  } while (0)
375 
376 struct rtnl_link *rtnl_link_sit_alloc(void)
377 {
378  struct rtnl_link *link;
379  int err;
380 
381  link = rtnl_link_alloc();
382  if (!link)
383  return NULL;
384 
385  err = rtnl_link_set_type(link, "sit");
386  if (err < 0) {
387  rtnl_link_put(link);
388  return NULL;
389  }
390 
391  return link;
392 }
393 
394 /**
395  * Check if link is a SIT link
396  * @arg link Link object
397  *
398  * @return True if link is a SIT link, otherwise false is returned.
399  */
400 int rtnl_link_is_sit(struct rtnl_link *link)
401 {
402  return link->l_info_ops && !strcmp(link->l_info_ops->io_name, "sit");
403 }
404 
405 /**
406  * Create a new sit tunnel device
407  * @arg sock netlink socket
408  * @arg name name of the tunnel device
409  *
410  * Creates a new sit tunnel device in the kernel
411  * @return 0 on success or a negative error code
412  */
413 int rtnl_link_sit_add(struct nl_sock *sk, const char *name)
414 {
415  struct rtnl_link *link;
416  int err;
417 
418  link = rtnl_link_sit_alloc();
419  if (!link)
420  return -NLE_NOMEM;
421 
422  if(name)
423  rtnl_link_set_name(link, name);
424 
425  err = rtnl_link_add(sk, link, NLM_F_CREATE);
426  rtnl_link_put(link);
427 
428  return err;
429 }
430 
431 /**
432  * Set SIT tunnel interface index
433  * @arg link Link object
434  * @arg index interface index
435  *
436  * @return 0 on success or a negative error code
437  */
438 int rtnl_link_sit_set_link(struct rtnl_link *link, uint32_t index)
439 {
440  IS_SIT_LINK_ASSERT(link, sit);
441 
442  sit->link = index;
443  sit->sit_mask |= SIT_ATTR_LINK;
444 
445  return 0;
446 }
447 
448 /**
449  * Get SIT tunnel interface index
450  * @arg link Link object
451  *
452  * @return interface index value
453  */
454 uint32_t rtnl_link_sit_get_link(struct rtnl_link *link)
455 {
456  IS_SIT_LINK_ASSERT(link, sit);
457 
458  return sit->link;
459 }
460 
461 /**
462  * Set SIT tunnel local address
463  * @arg link Link object
464  * @arg addr local address
465  *
466  * @return 0 on success or a negative error code
467  */
468 int rtnl_link_sit_set_local(struct rtnl_link *link, uint32_t addr)
469 {
470  IS_SIT_LINK_ASSERT(link, sit);
471 
472  sit->local = addr;
473  sit->sit_mask |= SIT_ATTR_LOCAL;
474 
475  return 0;
476 }
477 
478 /**
479  * Get SIT tunnel local address
480  * @arg link Link object
481  *
482  * @return local address value
483  */
484 uint32_t rtnl_link_sit_get_local(struct rtnl_link *link)
485 {
486  IS_SIT_LINK_ASSERT(link, sit);
487 
488  return sit->local;
489 }
490 
491 /**
492  * Set SIT tunnel remote address
493  * @arg link Link object
494  * @arg remote remote address
495  *
496  * @return 0 on success or a negative error code
497  */
498 int rtnl_link_sit_set_remote(struct rtnl_link *link, uint32_t addr)
499 {
500  IS_SIT_LINK_ASSERT(link, sit);
501 
502  sit->remote = addr;
503  sit->sit_mask |= SIT_ATTR_REMOTE;
504 
505  return 0;
506 }
507 
508 /**
509  * Get SIT tunnel remote address
510  * @arg link Link object
511  *
512  * @return remote address
513  */
514 uint32_t rtnl_link_sit_get_remote(struct rtnl_link *link)
515 {
516  IS_SIT_LINK_ASSERT(link, sit);
517 
518  return sit->remote;
519 }
520 
521 /**
522  * Set SIT tunnel ttl
523  * @arg link Link object
524  * @arg ttl tunnel ttl
525  *
526  * @return 0 on success or a negative error code
527  */
528 int rtnl_link_sit_set_ttl(struct rtnl_link *link, uint8_t ttl)
529 {
530  IS_SIT_LINK_ASSERT(link, sit);
531 
532  sit->ttl = ttl;
533  sit->sit_mask |= SIT_ATTR_TTL;
534 
535  return 0;
536 }
537 
538 /**
539  * Get SIT tunnel ttl
540  * @arg link Link object
541  *
542  * @return ttl value
543  */
544 uint8_t rtnl_link_sit_get_ttl(struct rtnl_link *link)
545 {
546  IS_SIT_LINK_ASSERT(link, sit);
547 
548  return sit->ttl;
549 }
550 
551 /**
552  * Set SIT tunnel tos
553  * @arg link Link object
554  * @arg tos tunnel tos
555  *
556  * @return 0 on success or a negative error code
557  */
558 int rtnl_link_sit_set_tos(struct rtnl_link *link, uint8_t tos)
559 {
560  IS_SIT_LINK_ASSERT(link, sit);
561 
562  sit->tos = tos;
563  sit->sit_mask |= SIT_ATTR_TOS;
564 
565  return 0;
566 }
567 
568 /**
569  * Get SIT tunnel tos
570  * @arg link Link object
571  *
572  * @return tos value
573  */
574 uint8_t rtnl_link_sit_get_tos(struct rtnl_link *link)
575 {
576  IS_SIT_LINK_ASSERT(link, sit);
577 
578  return sit->tos;
579 }
580 
581 /**
582  * Set SIT tunnel path MTU discovery
583  * @arg link Link object
584  * @arg pmtudisc path MTU discovery
585  *
586  * @return 0 on success or a negative error code
587  */
588 int rtnl_link_sit_set_pmtudisc(struct rtnl_link *link, uint8_t pmtudisc)
589 {
590  IS_SIT_LINK_ASSERT(link, sit);
591 
592  sit->pmtudisc = pmtudisc;
593  sit->sit_mask |= SIT_ATTR_PMTUDISC;
594 
595  return 0;
596 }
597 
598 /**
599  * Get SIT path MTU discovery
600  * @arg link Link object
601  *
602  * @return pmtudisc value
603  */
605 {
606  IS_SIT_LINK_ASSERT(link, sit);
607 
608  return sit->pmtudisc;
609 }
610 
611 /**
612  * Set SIT tunnel flags
613  * @arg link Link object
614  * @arg flags tunnel flags
615  *
616  * @return 0 on success or a negative error code
617  */
618 int rtnl_link_sit_set_flags(struct rtnl_link *link, uint16_t flags)
619 {
620  IS_SIT_LINK_ASSERT(link, sit);
621 
622  sit->flags = flags;
623  sit->sit_mask |= SIT_ATTR_FLAGS;
624 
625  return 0;
626 }
627 
628 /**
629  * Get SIT path flags
630  * @arg link Link object
631  *
632  * @return flags value
633  */
634 uint16_t rtnl_link_sit_get_flags(struct rtnl_link *link)
635 {
636  IS_SIT_LINK_ASSERT(link, sit);
637 
638  return sit->flags;
639 }
640 
641 /**
642  * Set SIT tunnel proto
643  * @arg link Link object
644  * @arg proto tunnel proto
645  *
646  * @return 0 on success or a negative error code
647  */
648 int rtnl_link_sit_set_proto(struct rtnl_link *link, uint8_t proto)
649 {
650  IS_SIT_LINK_ASSERT(link, sit);
651 
652  sit->proto = proto;
653  sit->sit_mask |= SIT_ATTR_PROTO;
654 
655  return 0;
656 }
657 
658 /**
659  * Get SIT proto
660  * @arg link Link object
661  *
662  * @return proto value
663  */
664 uint8_t rtnl_link_sit_get_proto(struct rtnl_link *link)
665 {
666  IS_SIT_LINK_ASSERT(link, sit);
667 
668  return sit->proto;
669 }
670 
671 /**
672  * Set ip6rd prefix
673  * @arg link Link object
674  * @arg prefix The IPv6 prefix
675  *
676  * @return 0 on success or an error code.
677  */
678 int rtnl_link_sit_set_ip6rd_prefix(struct rtnl_link *link, const struct in6_addr *prefix)
679 {
680  IS_SIT_LINK_ASSERT(link, sit);
681 
682  sit->ip6rd_prefix = *prefix;
683  sit->sit_mask |= SIT_ATTR_6RD_PREFIX;
684  return 0;
685 }
686 
687 /**
688  * Get ip6rd prefix
689  * @arg link Link object
690  * @arg prefix The output IPv6 prefix
691  *
692  * @return 0 on success or an error code. If the property is unset,
693  * this call fails too.
694  */
695 int rtnl_link_sit_get_ip6rd_prefix(const struct rtnl_link *link, struct in6_addr *prefix)
696 {
697  IS_SIT_LINK_ASSERT(link, sit);
698 
699  if (!(sit->sit_mask & SIT_ATTR_6RD_PREFIX))
700  return -NLE_NOATTR;
701 
702  if (prefix)
703  *prefix = sit->ip6rd_prefix;
704  return 0;
705 }
706 
707 /**
708  * Set ip6rd prefix length
709  * @arg link Link object
710  * @arg prefixlen The IPv6 prefix length
711  *
712  * @return 0 on success or an error code.
713  */
714 int rtnl_link_sit_set_ip6rd_prefixlen(struct rtnl_link *link, uint16_t prefixlen)
715 {
716  IS_SIT_LINK_ASSERT(link, sit);
717 
718  sit->sit_mask |= SIT_ATTR_6RD_PREFIXLEN;
719  sit->ip6rd_prefixlen = prefixlen;
720  return 0;
721 }
722 
723 /**
724  * Get ip6rd prefix length
725  * @arg link Link object
726  * @arg prefixlen Output pointer for the prefix length
727  *
728  * @return 0 on success or an error code. If the property is unset,
729  * this call fails.
730  */
731 int rtnl_link_sit_get_ip6rd_prefixlen(struct rtnl_link *link, uint16_t *prefixlen)
732 {
733  IS_SIT_LINK_ASSERT(link, sit);
734 
735  if (!(sit->sit_mask & SIT_ATTR_6RD_PREFIXLEN))
736  return -NLE_NOATTR;
737 
738  if (prefixlen)
739  *prefixlen = sit->ip6rd_prefixlen;
740  return 0;
741 }
742 
743 /**
744  * Set ip6rd relay prefix
745  * @arg link Link object
746  * @arg prefix The IPv6 prefix length
747  *
748  * @return 0 on success or an error code.
749  */
750 int rtnl_link_sit_set_ip6rd_relay_prefix(struct rtnl_link *link, uint32_t prefix)
751 {
752  IS_SIT_LINK_ASSERT(link, sit);
753 
754  sit->sit_mask |= SIT_ATTR_6RD_RELAY_PREFIX;
755  sit->ip6rd_relay_prefix = prefix;
756  return 0;
757 }
758 
759 /**
760  * Get ip6rd prefix length
761  * @arg link Link object
762  * @arg prefixlen Output pointer for the prefix length
763  *
764  * @return 0 on success or an error code. If the property is unset,
765  * this call fails.
766  */
767 int rtnl_link_sit_get_ip6rd_relay_prefix(const struct rtnl_link *link, uint32_t *prefix)
768 {
769  IS_SIT_LINK_ASSERT(link, sit);
770 
771  if (!(sit->sit_mask & SIT_ATTR_6RD_RELAY_PREFIX))
772  return -NLE_NOATTR;
773 
774  if (prefix)
775  *prefix = sit->ip6rd_relay_prefix;
776  return 0;
777 }
778 
779 /**
780  * Set ip6rd relay prefix length
781  * @arg link Link object
782  * @arg prefixlen The IPv6 prefix length
783  *
784  * @return 0 on success or an error code.
785  */
786 int rtnl_link_sit_set_ip6rd_relay_prefixlen(struct rtnl_link *link, uint16_t prefixlen)
787 {
788  IS_SIT_LINK_ASSERT(link, sit);
789 
790  sit->sit_mask |= SIT_ATTR_6RD_RELAY_PREFIXLEN;
791  sit->ip6rd_relay_prefixlen = prefixlen;
792  return 0;
793 }
794 
795 /**
796  * Get ip6rd relay prefix length
797  * @arg link Link object
798  * @arg prefixlen Output pointer for the prefix length
799  *
800  * @return 0 on success or an error code. If the property is unset,
801  * this call fails.
802  */
803 int rtnl_link_sit_get_ip6rd_relay_prefixlen(struct rtnl_link *link, uint16_t *prefixlen)
804 {
805  IS_SIT_LINK_ASSERT(link, sit);
806 
807  if (!(sit->sit_mask & SIT_ATTR_6RD_RELAY_PREFIX))
808  return -NLE_NOATTR;
809 
810  if (prefixlen)
811  *prefixlen = sit->ip6rd_relay_prefixlen;
812  return 0;
813 }
814 
815 static void __init sit_init(void)
816 {
817  rtnl_link_register_info(&sit_info_ops);
818 }
819 
820 static void __exit sit_exit(void)
821 {
822  rtnl_link_unregister_info(&sit_info_ops);
823 }
Definition: sit.c:48
Dump object briefly on one line.
Definition: types.h:22
8 bit integer
Definition: attr.h:41
int rtnl_link_sit_set_pmtudisc(struct rtnl_link *link, uint8_t pmtudisc)
Set SIT tunnel path MTU discovery.
Definition: sit.c:588
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
uint16_t rtnl_link_sit_get_flags(struct rtnl_link *link)
Get SIT path flags.
Definition: sit.c:634
uint32_t nla_get_u32(const struct nlattr *nla)
Return payload of 32 bit integer attribute.
Definition: attr.c:706
int rtnl_link_sit_set_ip6rd_prefixlen(struct rtnl_link *link, uint16_t prefixlen)
Set ip6rd prefix length.
Definition: sit.c:714
int rtnl_link_sit_get_ip6rd_prefixlen(struct rtnl_link *link, uint16_t *prefixlen)
Get ip6rd prefix length.
Definition: sit.c:731
int rtnl_link_sit_set_proto(struct rtnl_link *link, uint8_t proto)
Set SIT tunnel proto.
Definition: sit.c:648
#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 nla_nest_end(struct nl_msg *msg, struct nlattr *start)
Finalize nesting of attributes.
Definition: attr.c:924
int rtnl_link_sit_set_remote(struct rtnl_link *link, uint32_t addr)
Set SIT tunnel remote address.
Definition: sit.c:498
uint32_t rtnl_link_sit_get_remote(struct rtnl_link *link)
Get SIT tunnel remote address.
Definition: sit.c:514
int rtnl_link_sit_set_ttl(struct rtnl_link *link, uint8_t ttl)
Set SIT tunnel ttl.
Definition: sit.c:528
int nla_memcpy(void *dest, const struct nlattr *src, int count)
Copy attribute payload to another memory area.
Definition: attr.c:353
uint8_t rtnl_link_sit_get_ttl(struct rtnl_link *link)
Get SIT tunnel ttl.
Definition: sit.c:544
#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_sit_get_ip6rd_relay_prefixlen(struct rtnl_link *link, uint16_t *prefixlen)
Get ip6rd relay prefix length.
Definition: sit.c:803
16 bit integer
Definition: attr.h:42
uint8_t rtnl_link_sit_get_proto(struct rtnl_link *link)
Get SIT proto.
Definition: sit.c:664
int rtnl_link_sit_set_ip6rd_prefix(struct rtnl_link *link, const struct in6_addr *prefix)
Set ip6rd prefix.
Definition: sit.c:678
int rtnl_link_sit_get_ip6rd_relay_prefix(const struct rtnl_link *link, uint32_t *prefix)
Get ip6rd prefix length.
Definition: sit.c:767
int rtnl_link_sit_add(struct nl_sock *sk, const char *name)
Create a new sit tunnel device.
Definition: sit.c:413
#define NLA_PUT_U32(msg, attrtype, value)
Add 32 bit integer attribute to netlink message.
Definition: attr.h:235
int rtnl_link_sit_get_ip6rd_prefix(const struct rtnl_link *link, struct in6_addr *prefix)
Get ip6rd prefix.
Definition: sit.c:695
uint32_t rtnl_link_sit_get_local(struct rtnl_link *link)
Get SIT tunnel local address.
Definition: sit.c:484
int rtnl_link_sit_set_link(struct rtnl_link *link, uint32_t index)
Set SIT tunnel interface index.
Definition: sit.c:438
uint8_t rtnl_link_sit_get_pmtudisc(struct rtnl_link *link)
Get SIT path MTU discovery.
Definition: sit.c:604
uint8_t rtnl_link_sit_get_tos(struct rtnl_link *link)
Get SIT tunnel tos.
Definition: sit.c:574
uint16_t type
Type of attribute or NLA_UNSPEC.
Definition: attr.h:71
uint16_t nla_get_u16(const struct nlattr *nla)
Return payload of 16 bit integer attribute.
Definition: attr.c:656
32 bit integer
Definition: attr.h:43
int rtnl_link_sit_set_ip6rd_relay_prefixlen(struct rtnl_link *link, uint16_t prefixlen)
Set ip6rd relay prefix length.
Definition: sit.c:786
Dumping parameters.
Definition: types.h:33
#define NLA_PUT_U16(msg, attrtype, value)
Add 16 bit integer attribute to netlink message.
Definition: attr.h:217
int rtnl_link_sit_set_tos(struct rtnl_link *link, uint8_t tos)
Set SIT tunnel tos.
Definition: sit.c:558
uint32_t rtnl_link_sit_get_link(struct rtnl_link *link)
Get SIT tunnel interface index.
Definition: sit.c:454
int rtnl_link_sit_set_ip6rd_relay_prefix(struct rtnl_link *link, uint32_t prefix)
Set ip6rd relay prefix.
Definition: sit.c:750
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
Definition: utils.c:961
int rtnl_link_sit_set_local(struct rtnl_link *link, uint32_t addr)
Set SIT tunnel local address.
Definition: sit.c:468
int rtnl_link_is_sit(struct rtnl_link *link)
Check if link is a SIT link.
Definition: sit.c:400
struct nlattr * nla_nest_start(struct nl_msg *msg, int attrtype)
Start a new level of nested attributes.
Definition: attr.c:902
int rtnl_link_sit_set_flags(struct rtnl_link *link, uint16_t flags)
Set SIT tunnel flags.
Definition: sit.c:618