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