libnl  3.5.0
geneve.c
1 /*
2  * lib/route/link/geneve.c Geneve Link Info
3  * This library is free software; you can redistribute it and/or
4  * modify it under the terms of the GNU Lesser General Public
5  * License as published by the Free Software Foundation version 2.1
6  * of the License.
7  *
8  * Copyright (c) 2018 Wang Jian <jianjian.wang1@gmail.com>
9  */
10 /**
11  * @ingroup link
12  * @defgroup geneve Geneve
13  * Generic Network Virtualization Encapsulation
14  *
15  * @details
16  * \b Link Type Name: "geneve"
17  *
18  * @route_doc{link_geneve, Geneve Documentation}
19  *
20  * @{
21  */
22 #include <netlink-private/netlink.h>
23 #include <netlink/netlink.h>
24 #include <netlink/utils.h>
25 #include <netlink/object.h>
26 #include <netlink/route/rtnl.h>
27 #include <netlink-private/route/link/api.h>
28 #include <netlink/route/link/geneve.h>
29 
30 
31 /** @cond SKIP */
32 #define GENEVE_ATTR_ID (1<<0)
33 #define GENEVE_ATTR_REMOTE (1<<1)
34 #define GENEVE_ATTR_REMOTE6 (1<<2)
35 #define GENEVE_ATTR_TTL (1<<3)
36 #define GENEVE_ATTR_TOS (1<<4)
37 #define GENEVE_ATTR_LABEL (1<<5)
38 #define GENEVE_ATTR_PORT (1<<6)
39 #define GENEVE_ATTR_FLAGS (1<<7)
40 #define GENEVE_ATTR_UDP_CSUM (1<<8)
41 #define GENEVE_ATTR_UDP_ZERO_CSUM6_TX (1<<9)
42 #define GENEVE_ATTR_UDP_ZERO_CSUM6_RX (1<<10)
43 
44 struct geneve_info
45 {
46  uint32_t id;
47  uint32_t remote;
48  struct in6_addr remote6;
49  uint8_t ttl;
50  uint8_t tos;
51  uint32_t label;
52  uint16_t port;
53  uint8_t flags;
54  uint8_t udp_csum;
55  uint8_t udp_zero_csum6_tx;
56  uint8_t udp_zero_csum6_rx;
57  uint32_t mask;
58 };
59 
60 /** @endcond */
61 
62 static struct nla_policy geneve_policy[IFLA_GENEVE_MAX + 1] = {
63  [IFLA_GENEVE_ID] = { .type = NLA_U32 },
64  [IFLA_GENEVE_REMOTE] = { .minlen = sizeof(uint32_t) },
65  [IFLA_GENEVE_REMOTE6] = { .minlen = sizeof(struct in6_addr) },
66  [IFLA_GENEVE_TTL] = { .type = NLA_U8 },
67  [IFLA_GENEVE_TOS] = { .type = NLA_U8 },
68  [IFLA_GENEVE_LABEL] = { .type = NLA_U32 },
69  [IFLA_GENEVE_PORT] = { .type = NLA_U16 },
70  [IFLA_GENEVE_COLLECT_METADATA] = { .type = NLA_FLAG },
71  [IFLA_GENEVE_UDP_CSUM] = { .type = NLA_U8 },
72  [IFLA_GENEVE_UDP_ZERO_CSUM6_TX] = { .type = NLA_U8 },
73  [IFLA_GENEVE_UDP_ZERO_CSUM6_RX] = { .type = NLA_U8 },
74 };
75 
76 static int geneve_alloc(struct rtnl_link *link)
77 {
78  struct geneve_info *geneve;
79 
80  if (link->l_info)
81  memset(link->l_info, 0, sizeof(*geneve));
82  else {
83  if ((geneve = calloc(1, sizeof(*geneve))) == NULL)
84  return -NLE_NOMEM;
85  link->l_info = geneve;
86  }
87 
88  return 0;
89 }
90 
91 static int geneve_parse(struct rtnl_link *link, struct nlattr *data,
92  struct nlattr *xstats)
93 {
94  struct nlattr *tb[IFLA_GENEVE_MAX + 1];
95  struct geneve_info *geneve;
96  int err = 0;
97 
98  NL_DBG(3, "Parsing Geneve link info\n");
99 
100  err = nla_parse_nested(tb, IFLA_GENEVE_MAX, data, geneve_policy);
101  if (err < 0)
102  return err;
103 
104  err = geneve_alloc(link);
105  if (err < 0)
106  return err;
107 
108  geneve = link->l_info;
109 
110  if (tb[IFLA_GENEVE_ID]) {
111  geneve->id = nla_get_u32(tb[IFLA_GENEVE_ID]);
112  geneve->mask |= GENEVE_ATTR_ID;
113  }
114 
115  if (tb[IFLA_GENEVE_REMOTE]) {
116  nla_memcpy(&geneve->remote, tb[IFLA_GENEVE_REMOTE],
117  sizeof(geneve->remote));
118  geneve->mask |= GENEVE_ATTR_REMOTE;
119  geneve->mask &= ~GENEVE_ATTR_REMOTE6;
120  }
121  if (tb[IFLA_GENEVE_REMOTE6]) {
122  nla_memcpy(&geneve->remote6, tb[IFLA_GENEVE_REMOTE6],
123  sizeof(geneve->remote6));
124  geneve->mask |= GENEVE_ATTR_REMOTE6;
125  geneve->mask &= ~GENEVE_ATTR_REMOTE;
126  }
127 
128  if (tb[IFLA_GENEVE_TTL]) {
129  geneve->ttl = nla_get_u8(tb[IFLA_GENEVE_TTL]);
130  geneve->mask |= GENEVE_ATTR_TTL;
131  }
132 
133  if (tb[IFLA_GENEVE_TOS]) {
134  geneve->tos = nla_get_u8(tb[IFLA_GENEVE_TOS]);
135  geneve->mask |= GENEVE_ATTR_TOS;
136  }
137 
138  if (tb[IFLA_GENEVE_LABEL]) {
139  geneve->label = nla_get_u32(tb[IFLA_GENEVE_LABEL]);
140  geneve->mask |= GENEVE_ATTR_LABEL;
141  }
142 
143  if (tb[IFLA_GENEVE_PORT]) {
144  geneve->port = nla_get_u16(tb[IFLA_GENEVE_PORT]);
145  geneve->mask |= GENEVE_ATTR_PORT;
146  }
147 
148  if (tb[IFLA_GENEVE_COLLECT_METADATA])
149  geneve->flags |= RTNL_LINK_GENEVE_F_COLLECT_METADATA;
150 
151  if (tb[IFLA_GENEVE_UDP_CSUM]) {
152  geneve->udp_csum = nla_get_u8(tb[IFLA_GENEVE_UDP_CSUM]);
153  geneve->mask |= GENEVE_ATTR_UDP_CSUM;
154  }
155 
156  if (tb[IFLA_GENEVE_UDP_ZERO_CSUM6_TX]) {
157  geneve->udp_zero_csum6_tx = nla_get_u8(tb[IFLA_GENEVE_UDP_ZERO_CSUM6_TX]);
158  geneve->mask |= GENEVE_ATTR_UDP_ZERO_CSUM6_TX;
159  }
160 
161  if (tb[IFLA_GENEVE_UDP_ZERO_CSUM6_RX]) {
162  geneve->udp_zero_csum6_rx = nla_get_u8(tb[IFLA_GENEVE_UDP_ZERO_CSUM6_RX]);
163  geneve->mask |= GENEVE_ATTR_UDP_ZERO_CSUM6_RX;
164  }
165 
166  return err;
167 }
168 
169 static void geneve_free(struct rtnl_link *link)
170 {
171  struct geneve_info *geneve = link->l_info;
172 
173  free(geneve);
174  link->l_info = NULL;
175 }
176 
177 static void geneve_dump_line(struct rtnl_link *link, struct nl_dump_params *p)
178 {
179  struct geneve_info *geneve = link->l_info;
180 
181  nl_dump(p, "geneve-id %u", geneve->id);
182 }
183 
184 static void geneve_dump_details(struct rtnl_link *link, struct nl_dump_params *p)
185 {
186  struct geneve_info *geneve = link->l_info;
187  char addr[INET6_ADDRSTRLEN];
188 
189  nl_dump_line(p, " geneve-id %u\n", geneve->id);
190 
191  if (geneve->mask & GENEVE_ATTR_REMOTE) {
192  nl_dump(p, " remote ");
193  if (inet_ntop(AF_INET, &geneve->remote, addr, sizeof(addr)))
194  nl_dump_line(p, "%s\n", addr);
195  else
196  nl_dump_line(p, "%#x\n", ntohs(geneve->remote));
197  } else if (geneve->mask & GENEVE_ATTR_REMOTE6) {
198  nl_dump(p, " remote ");
199  if (inet_ntop(AF_INET6, &geneve->remote6, addr, sizeof(addr)))
200  nl_dump_line(p, "%s\n", addr);
201  else
202  nl_dump_line(p, "%#x\n", geneve->remote6);
203  }
204 
205  if (geneve->mask & GENEVE_ATTR_TTL) {
206  nl_dump(p, " ttl ");
207  nl_dump_line(p, "%u\n", geneve->ttl);
208  }
209 
210  if (geneve->mask & GENEVE_ATTR_TOS) {
211  nl_dump(p, " tos ");
212  nl_dump_line(p, "%u\n", geneve->tos);
213  }
214 
215  if (geneve->mask & GENEVE_ATTR_PORT) {
216  nl_dump(p, " port ");
217  nl_dump_line(p, "%u\n", ntohs(geneve->port));
218  }
219 
220  if (geneve->mask & GENEVE_ATTR_LABEL) {
221  nl_dump(p, " label ");
222  nl_dump_line(p, "%u\n", ntohl(geneve->label));
223  }
224 
225  if (geneve->mask & GENEVE_ATTR_UDP_CSUM) {
226  nl_dump(p, " UDP checksum ");
227  if (geneve->udp_csum)
228  nl_dump_line(p, "enabled (%#x)\n", geneve->udp_csum);
229  else
230  nl_dump_line(p, "disabled\n");
231  }
232 
233  if (geneve->mask & GENEVE_ATTR_UDP_ZERO_CSUM6_TX) {
234  nl_dump(p, " udp-zero-csum6-tx ");
235  if (geneve->udp_zero_csum6_tx)
236  nl_dump_line(p, "enabled (%#x)\n", geneve->udp_zero_csum6_tx);
237  else
238  nl_dump_line(p, "disabled\n");
239  }
240 
241  if (geneve->mask & GENEVE_ATTR_UDP_ZERO_CSUM6_RX) {
242  nl_dump(p, " udp-zero-csum6-rx ");
243  if (geneve->udp_zero_csum6_tx)
244  nl_dump_line(p, "enabled (%#x)\n", geneve->udp_zero_csum6_rx);
245  else
246  nl_dump_line(p, "disabled\n");
247  }
248 
249  if (geneve->flags & RTNL_LINK_GENEVE_F_COLLECT_METADATA)
250  nl_dump(p, " collect-metadata\n");
251 }
252 
253 static int geneve_clone(struct rtnl_link *dst, struct rtnl_link *src)
254 {
255  struct geneve_info *gdst, *gsrc;
256  int err;
257 
258  gsrc = src->l_info;
259  dst->l_info = NULL;
260  err = rtnl_link_set_type(dst, "geneve");
261  if (err < 0)
262  return err;
263 
264  gdst = dst->l_info;
265 
266  if (!gsrc || !gdst)
267  return -NLE_NOMEM;
268 
269  memcpy(gdst, gsrc, sizeof(struct geneve_info));
270 
271  return 0;
272 }
273 
274 static int geneve_put_attrs(struct nl_msg *msg, struct rtnl_link *link)
275 {
276  struct geneve_info *geneve = link->l_info;
277  struct nlattr *data;
278 
279  if (!(data = nla_nest_start(msg, IFLA_INFO_DATA)))
280  return -NLE_MSGSIZE;
281 
282  if (geneve->mask & GENEVE_ATTR_ID)
283  NLA_PUT_U32(msg, IFLA_GENEVE_ID, geneve->id);
284 
285  if (geneve->mask & GENEVE_ATTR_REMOTE)
286  NLA_PUT(msg, IFLA_GENEVE_REMOTE,
287  sizeof(geneve->remote), &geneve->remote);
288 
289  if (geneve->mask & GENEVE_ATTR_REMOTE6)
290  NLA_PUT(msg, IFLA_GENEVE_REMOTE6,
291  sizeof(geneve->remote6), &geneve->remote6);
292 
293  if (geneve->mask & GENEVE_ATTR_TTL)
294  NLA_PUT_U8(msg, IFLA_GENEVE_TTL, geneve->ttl);
295 
296  if (geneve->mask & GENEVE_ATTR_TOS)
297  NLA_PUT_U8(msg, IFLA_GENEVE_TOS, geneve->tos);
298 
299  if (geneve->mask & GENEVE_ATTR_LABEL)
300  NLA_PUT_U32(msg, IFLA_GENEVE_LABEL, geneve->label);
301 
302  if (geneve->mask & GENEVE_ATTR_PORT)
303  NLA_PUT_U32(msg, IFLA_GENEVE_PORT, geneve->port);
304 
305  if (geneve->mask & GENEVE_ATTR_UDP_CSUM)
306  NLA_PUT_U8(msg, IFLA_GENEVE_UDP_CSUM, geneve->udp_csum);
307 
308  if (geneve->mask & GENEVE_ATTR_UDP_ZERO_CSUM6_TX)
309  NLA_PUT_U8(msg, IFLA_GENEVE_UDP_ZERO_CSUM6_TX, geneve->udp_zero_csum6_tx);
310 
311  if (geneve->mask & GENEVE_ATTR_UDP_ZERO_CSUM6_RX)
312  NLA_PUT_U8(msg, IFLA_GENEVE_UDP_ZERO_CSUM6_RX, geneve->udp_zero_csum6_rx);
313 
314  if (geneve->flags & RTNL_LINK_GENEVE_F_COLLECT_METADATA)
315  NLA_PUT_FLAG(msg, IFLA_GENEVE_COLLECT_METADATA);
316 
317  nla_nest_end(msg, data);
318 
319 nla_put_failure:
320 
321  return 0;
322 }
323 
324 static struct rtnl_link_info_ops geneve_info_ops = {
325  .io_name = "geneve",
326  .io_alloc = geneve_alloc,
327  .io_parse = geneve_parse,
328  .io_dump = {
329  [NL_DUMP_LINE] = geneve_dump_line,
330  [NL_DUMP_DETAILS] = geneve_dump_details,
331  },
332  .io_clone = geneve_clone,
333  .io_put_attrs = geneve_put_attrs,
334  .io_free = geneve_free,
335 };
336 
337 
338 /** @cond SKIP */
339 #define IS_GENEVE_LINK_ASSERT(link) \
340  if ((link)->l_info_ops != &geneve_info_ops) { \
341  APPBUG("Link is not a geneve link. set type \"geneve\" first."); \
342  return -NLE_OPNOTSUPP; \
343  }
344 /** @endcond */
345 
346 /**
347  * @name Geneve Object
348  * @{
349  */
350 
351 /**
352  * Allocate link object of type Geneve
353  *
354  * @return Allocated link object or NULL.
355  */
357 {
358  struct rtnl_link *link;
359  int err;
360 
361  if (!(link = rtnl_link_alloc()))
362  return NULL;
363 
364  if ((err = rtnl_link_set_type(link, "geneve")) < 0) {
365  rtnl_link_put(link);
366  return NULL;
367  }
368 
369  return link;
370 }
371 
372 /**
373  * Check if link is a Geneve link
374  * @arg link Link object
375  *
376  * @return True if link is a Geneve link, otherwisee false is returned.
377  */
379 {
380  return link->l_info_ops && !strcmp(link->l_info_ops->io_name, "geneve");
381 }
382 
383 /**
384  * Set Geneve Network Indentifier
385  * @arg link Link object
386  * @arg id Geneve network identifier
387  *
388  * @return 0 on success or a negative error code
389  */
390 int rtnl_link_geneve_set_id(struct rtnl_link *link, uint32_t id)
391 {
392  struct geneve_info *geneve = link->l_info;
393 
394  IS_GENEVE_LINK_ASSERT(link);
395 
396  if (id > RTNL_GENEVE_ID_MAX)
397  return -NLE_INVAL;
398 
399  geneve->id = id;
400  geneve->mask |= GENEVE_ATTR_ID;
401 
402  return 0;
403 }
404 
405 /**
406  * Get Geneve Network Identifier
407  * @arg link Link object
408  * @arg id Pointer to store network identifier
409  *
410  * @return 0 on success or a negative error code
411  */
412 int rtnl_link_geneve_get_id(struct rtnl_link *link, uint32_t *id)
413 {
414  struct geneve_info *geneve = link->l_info;
415 
416  IS_GENEVE_LINK_ASSERT(link);
417 
418  if (!id)
419  return -NLE_INVAL;
420 
421  if (geneve->mask & GENEVE_ATTR_ID)
422  *id = geneve->id;
423  else
424  return -NLE_AGAIN;
425 
426  return 0;
427 }
428 
429 /**
430  * Set Geneve unicast destination IP address
431  * @arg link Link object
432  * @arg addr The unicast destination IP address
433  *
434  * @return 0 on success or a negative error code
435  */
436 int rtnl_link_geneve_set_remote(struct rtnl_link *link, struct nl_addr *addr)
437 {
438  struct geneve_info *geneve = link->l_info;
439 
440  IS_GENEVE_LINK_ASSERT(link);
441 
442  if ((nl_addr_get_family(addr) == AF_INET) &&
443  (nl_addr_get_len(addr) == sizeof(geneve->remote))) {
444  memcpy(&geneve->remote, nl_addr_get_binary_addr(addr),
445  sizeof(geneve->remote));
446  geneve->mask |= GENEVE_ATTR_REMOTE;
447  geneve->mask &= ~GENEVE_ATTR_REMOTE6;
448  } else if ((nl_addr_get_family(addr) == AF_INET6) &&
449  (nl_addr_get_len(addr) == sizeof(geneve->remote6))) {
450  memcpy(&geneve->remote6, nl_addr_get_binary_addr(addr),
451  sizeof(geneve->remote6));
452  geneve->mask |= GENEVE_ATTR_REMOTE6;
453  geneve->mask &= ~GENEVE_ATTR_REMOTE;
454  } else
455  return -NLE_INVAL;
456 
457  return 0;
458 }
459 
460 /**
461  * Get Geneve unicast destination IP address
462  * @arg link Link object
463  * @arg addr Pointer to store unicast destination IP addree
464  *
465  * @return 0 on success or a a negative error code
466  */
467 int rtnl_link_geneve_get_remote(struct rtnl_link *link, struct nl_addr **addr)
468 {
469  struct geneve_info *geneve = link->l_info;
470 
471  IS_GENEVE_LINK_ASSERT(link);
472 
473  if (!addr)
474  return -NLE_INVAL;
475 
476  if (geneve->mask & GENEVE_ATTR_REMOTE)
477  *addr = nl_addr_build(AF_INET, &geneve->remote, sizeof(geneve->remote));
478  else if (geneve->mask & GENEVE_ATTR_REMOTE6)
479  *addr = nl_addr_build(AF_INET6, &geneve->remote6, sizeof(geneve->remote6));
480  else
481  return -NLE_AGAIN;
482 
483  return 0;
484 }
485 
486 /**
487  * Set IP TTL value to use for Geneve
488  * @arg link Link object
489  * @arg ttl TTL value
490  *
491  * @return 0 on success or a negative error code
492  */
493 int rtnl_link_geneve_set_ttl(struct rtnl_link *link, uint8_t ttl)
494 {
495  struct geneve_info *geneve = link->l_info;
496 
497  IS_GENEVE_LINK_ASSERT(link);
498 
499  geneve->ttl = ttl;
500  geneve->mask |= GENEVE_ATTR_TTL;
501 
502  return 0;
503 }
504 
505 /**
506  * Get IP TTL value to use for Geneve
507  * @arg link Link object
508  *
509  * @return TTL value on success or a negative error code
510  */
512 {
513  struct geneve_info *geneve = link->l_info;
514 
515  IS_GENEVE_LINK_ASSERT(link);
516 
517  if (!(geneve->mask & GENEVE_ATTR_TTL))
518  return -NLE_AGAIN;
519 
520  return geneve->ttl;
521 }
522 
523 /**
524  * Set IP ToS value to use for Geneve
525  * @arg link Link object
526  * @arg tos ToS value
527  *
528  * @return 0 on success or a negative error code
529  */
530 int rtnl_link_geneve_set_tos(struct rtnl_link *link, uint8_t tos)
531 {
532  struct geneve_info *geneve = link->l_info;
533 
534  IS_GENEVE_LINK_ASSERT(link);
535 
536  geneve->tos = tos;
537  geneve->mask |= GENEVE_ATTR_TOS;
538 
539  return 0;
540 }
541 
542 /**
543  * Get IP ToS value to use for Geneve
544  * @arg link Link object
545  *
546  * @return ToS value on success or a negative error code
547  */
549 {
550  struct geneve_info *geneve = link->l_info;
551 
552  IS_GENEVE_LINK_ASSERT(link);
553 
554  if (!(geneve->mask & GENEVE_ATTR_TOS))
555  return -NLE_AGAIN;
556 
557  return geneve->tos;
558 }
559 
560 /**
561  * Set UDP destination port to use for Geneve
562  * @arg link Link object
563  * @arg port Destination port
564  *
565  * @return 0 on success or a negative error code
566  */
567 
568 int rtnl_link_geneve_set_port(struct rtnl_link *link, uint32_t port)
569 {
570  struct geneve_info *geneve = link->l_info;
571 
572  IS_GENEVE_LINK_ASSERT(link);
573 
574  geneve->port = htons(port);
575  geneve->mask |= GENEVE_ATTR_PORT;
576 
577  return 0;
578 }
579 
580 /**
581  * Get UDP destination port to use for Geneve
582  * @arg link Link object
583  * @arg port Pointer to store destination port
584  *
585  * @return 0 on success or a negative error code
586  */
587 int rtnl_link_geneve_get_port(struct rtnl_link *link, uint32_t *port)
588 {
589  struct geneve_info *geneve = link->l_info;
590 
591  IS_GENEVE_LINK_ASSERT(link);
592 
593  if (!port)
594  return -NLE_INVAL;
595 
596  if (!(geneve->mask & GENEVE_ATTR_PORT))
597  return -NLE_NOATTR;
598 
599  *port = ntohs(geneve->port);
600 
601  return 0;
602 }
603 
604 /**
605  * Set flow label to use for Geneve
606  * @arg link Link object
607  * @arg label Destination label
608  *
609  * @return 0 on success or a negative error code
610  */
611 int rtnl_link_geneve_set_label(struct rtnl_link *link, uint32_t label)
612 {
613  struct geneve_info *geneve = link->l_info;
614 
615  IS_GENEVE_LINK_ASSERT(link);
616 
617  geneve->label = htonl(label);
618  geneve->mask |= GENEVE_ATTR_LABEL;
619 
620  return 0;
621 }
622 
623 /**
624  * Get flow label to use for Geneve
625  * @arg link Link object
626  * @arg label Pointer to store destination label
627  *
628  * @return 0 on success or a negative error code
629  */
630 int rtnl_link_geneve_get_label(struct rtnl_link *link, uint32_t *label)
631 {
632  struct geneve_info *geneve = link->l_info;
633 
634  IS_GENEVE_LINK_ASSERT(link);
635 
636  if (!label)
637  return -NLE_INVAL;
638  if (!(geneve->mask & GENEVE_ATTR_LABEL))
639  return -NLE_NOATTR;
640 
641  *label = ntohl(geneve->label);
642 
643  return 0;
644 }
645 
646 /**
647  * Set UDP checksum status to use for Geneve
648  * @arg link Link object
649  * @arg csum Status value
650  *
651  * @return 0 on success or a negative error code
652  */
653 int rtnl_link_geneve_set_udp_csum(struct rtnl_link *link, uint8_t csum)
654 {
655  struct geneve_info *geneve = link->l_info;
656 
657  IS_GENEVE_LINK_ASSERT(link);
658 
659  geneve->udp_csum = csum;
660  geneve->mask |= GENEVE_ATTR_UDP_CSUM;
661 
662  return 0;
663 }
664 
665 /**
666  * Get UDP checksum status to use for Geneve
667  * @arg link Link object
668  *
669  * @return status value on success or a negative error code
670  */
672 {
673  struct geneve_info *geneve = link->l_info;
674 
675  IS_GENEVE_LINK_ASSERT(link);
676 
677  if (!(geneve->mask & GENEVE_ATTR_UDP_CSUM))
678  return -NLE_NOATTR;
679 
680  return geneve->udp_csum;
681 }
682 
683 /**
684  * Set skip UDP checksum transmitted over IPv6 status to use for Geneve
685  * @arg link Link object
686  * @arg csum Status value
687  *
688  * @return 0 on success or a negative error code
689  */
690 int rtnl_link_geneve_set_udp_zero_csum6_tx(struct rtnl_link *link, uint8_t csum)
691 {
692  struct geneve_info *geneve = link->l_info;
693 
694  IS_GENEVE_LINK_ASSERT(link);
695 
696  geneve->udp_zero_csum6_tx = csum;
697  geneve->mask |= GENEVE_ATTR_UDP_ZERO_CSUM6_TX;
698 
699  return 0;
700 }
701 
702 /**
703  * Get skip UDP checksum transmitted over IPv6 status to use for Geneve
704  * @arg link Link object
705  *
706  * @return Status value on success or a negative error code
707  */
709 {
710  struct geneve_info *geneve = link->l_info;
711 
712  IS_GENEVE_LINK_ASSERT(link);
713 
714  if (!(geneve->mask & GENEVE_ATTR_UDP_ZERO_CSUM6_TX))
715  return -NLE_NOATTR;
716 
717  return geneve->udp_zero_csum6_tx;
718 }
719 
720 /**
721  * Set skip UDP checksum received over IPv6 status to use for Geneve
722  * @arg link Link object
723  * @arg csum Status value
724  *
725  * @return 0 on success or a negative error code
726  */
727 int rtnl_link_geneve_set_udp_zero_csum6_rx(struct rtnl_link *link, uint8_t csum)
728 {
729  struct geneve_info *geneve = link->l_info;
730 
731  IS_GENEVE_LINK_ASSERT(link);
732 
733  geneve->udp_zero_csum6_rx = csum;
734  geneve->mask |= GENEVE_ATTR_UDP_ZERO_CSUM6_RX;
735 
736  return 0;
737 }
738 
739 /**
740  * Get skip UDP checksum received over IPv6 status to use for Geneve
741  * @arg link Link object
742  *
743  * @return Status value on success or a negative error code
744  */
746 {
747  struct geneve_info *geneve = link->l_info;
748 
749  IS_GENEVE_LINK_ASSERT(link);
750 
751  if (!(geneve->mask & GENEVE_ATTR_UDP_ZERO_CSUM6_RX))
752  return -NLE_NOATTR;
753 
754  return geneve->udp_zero_csum6_rx;
755 }
756 
757 /**
758  * Set Geneve flags
759  * @arg link Link object
760  * @arg flags Which flags to set
761  * @arg enable Boolean enabling or disabling flag
762  *
763  * @return 0 on success or a negative error code
764  */
765 int rtnl_link_geneve_set_flags(struct rtnl_link *link, uint8_t flags, int enable)
766 {
767  struct geneve_info *geneve = link->l_info;
768 
769  IS_GENEVE_LINK_ASSERT(link);
770 
771  if (flags & ~RTNL_LINK_GENEVE_F_COLLECT_METADATA)
772  return -NLE_INVAL;
773 
774  if (enable)
775  geneve->flags = flags;
776  else
777  geneve->flags &= ~flags;
778 
779  return 0;
780 }
781 
782 /**
783  * Get Geneve flags
784  * @arg link Link object
785  * @arg flags Pointer to store flags
786  *
787  * @return 0 on success or a negative error code
788  */
789 int rtnl_link_geneve_get_flags(struct rtnl_link *link, uint8_t *flags)
790 {
791  struct geneve_info *geneve = link->l_info;
792 
793  IS_GENEVE_LINK_ASSERT(link);
794 
795  *flags = geneve->flags;
796  return 0;
797 }
798 
799 /** @} */
800 static void __init geneve_init(void)
801 {
802  rtnl_link_register_info(&geneve_info_ops);
803 }
804 
805 static void __exit geneve_exit(void)
806 {
807  rtnl_link_unregister_info(&geneve_info_ops);
808 }
809 
810 /** @} */
Dump object briefly on one line.
Definition: types.h:22
8 bit integer
Definition: attr.h:41
int rtnl_link_geneve_set_port(struct rtnl_link *link, uint32_t port)
Set UDP destination port to use for Geneve.
Definition: geneve.c:568
int rtnl_link_geneve_set_flags(struct rtnl_link *link, uint8_t flags, int enable)
Set Geneve flags.
Definition: geneve.c:765
int rtnl_link_geneve_get_udp_zero_csum6_rx(struct rtnl_link *link)
Get skip UDP checksum received over IPv6 status to use for Geneve.
Definition: geneve.c:745
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:607
int rtnl_link_geneve_set_tos(struct rtnl_link *link, uint8_t tos)
Set IP ToS value to use for Geneve.
Definition: geneve.c:530
struct nl_addr * nl_addr_build(int family, const void *buf, size_t size)
Allocate abstract address based on a binary address.
Definition: addr.c:218
uint32_t nla_get_u32(const struct nlattr *nla)
Return payload of 32 bit integer attribute.
Definition: attr.c:707
int rtnl_link_geneve_set_udp_zero_csum6_rx(struct rtnl_link *link, uint8_t csum)
Set skip UDP checksum received over IPv6 status to use for Geneve.
Definition: geneve.c:727
int rtnl_link_geneve_get_id(struct rtnl_link *link, uint32_t *id)
Get Geneve Network Identifier.
Definition: geneve.c:412
int rtnl_link_geneve_get_ttl(struct rtnl_link *link)
Get IP TTL value to use for Geneve.
Definition: geneve.c:511
int rtnl_link_geneve_get_port(struct rtnl_link *link, uint32_t *port)
Get UDP destination port to use for Geneve.
Definition: geneve.c:587
#define NLA_PUT_U8(msg, attrtype, value)
Add 8 bit integer attribute to netlink message.
Definition: attr.h:200
int rtnl_link_geneve_get_label(struct rtnl_link *link, uint32_t *label)
Get flow label to use for Geneve.
Definition: geneve.c:630
Dump all attributes but no statistics.
Definition: types.h:23
struct rtnl_link * rtnl_link_geneve_alloc(void)
Allocate link object of type Geneve.
Definition: geneve.c:356
int rtnl_link_geneve_set_id(struct rtnl_link *link, uint32_t id)
Set Geneve Network Indentifier.
Definition: geneve.c:390
int nla_nest_end(struct nl_msg *msg, struct nlattr *start)
Finalize nesting of attributes.
Definition: attr.c:966
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:1021
#define NLA_PUT_FLAG(msg, attrtype)
Add flag attribute to netlink message.
Definition: attr.h:271
int nla_memcpy(void *dest, const struct nlattr *src, int count)
Copy attribute payload to another memory area.
Definition: attr.c:354
int rtnl_link_geneve_get_remote(struct rtnl_link *link, struct nl_addr **addr)
Get Geneve unicast destination IP address.
Definition: geneve.c:467
#define NLA_PUT(msg, attrtype, attrlen, data)
Add unspecific attribute to netlink message.
Definition: attr.h:165
16 bit integer
Definition: attr.h:42
int rtnl_link_geneve_set_udp_zero_csum6_tx(struct rtnl_link *link, uint8_t csum)
Set skip UDP checksum transmitted over IPv6 status to use for Geneve.
Definition: geneve.c:690
#define NLA_PUT_U32(msg, attrtype, value)
Add 32 bit integer attribute to netlink message.
Definition: attr.h:236
int rtnl_link_geneve_get_udp_csum(struct rtnl_link *link)
Get UDP checksum status to use for Geneve.
Definition: geneve.c:671
int rtnl_link_geneve_get_udp_zero_csum6_tx(struct rtnl_link *link)
Get skip UDP checksum transmitted over IPv6 status to use for Geneve.
Definition: geneve.c:708
uint16_t type
Type of attribute or NLA_UNSPEC.
Definition: attr.h:71
int rtnl_link_geneve_get_tos(struct rtnl_link *link)
Get IP ToS value to use for Geneve.
Definition: geneve.c:548
uint16_t nla_get_u16(const struct nlattr *nla)
Return payload of 16 bit integer attribute.
Definition: attr.c:657
32 bit integer
Definition: attr.h:43
Flag.
Definition: attr.h:46
Dumping parameters.
Definition: types.h:33
int rtnl_link_geneve_set_label(struct rtnl_link *link, uint32_t label)
Set flow label to use for Geneve.
Definition: geneve.c:611
int rtnl_link_is_geneve(struct rtnl_link *link)
Check if link is a Geneve link.
Definition: geneve.c:378
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
Definition: utils.c:962
int rtnl_link_geneve_set_udp_csum(struct rtnl_link *link, uint8_t csum)
Set UDP checksum status to use for Geneve.
Definition: geneve.c:653
int rtnl_link_geneve_get_flags(struct rtnl_link *link, uint8_t *flags)
Get Geneve flags.
Definition: geneve.c:789
unsigned int nl_addr_get_len(const struct nl_addr *addr)
Get length of binary address of abstract address object.
Definition: addr.c:954
void * nl_addr_get_binary_addr(const struct nl_addr *addr)
Get binary address of abstract address object.
Definition: addr.c:942
int rtnl_link_geneve_set_ttl(struct rtnl_link *link, uint8_t ttl)
Set IP TTL value to use for Geneve.
Definition: geneve.c:493
int rtnl_link_geneve_set_remote(struct rtnl_link *link, struct nl_addr *addr)
Set Geneve unicast destination IP address.
Definition: geneve.c:436
struct nlattr * nla_nest_start(struct nl_msg *msg, int attrtype)
Start a new level of nested attributes.
Definition: attr.c:903
int nl_addr_get_family(const struct nl_addr *addr)
Return address family.
Definition: addr.c:894