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
40struct 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
58static 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
72static 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
87static 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
165static 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
173static 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
180static 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
245static 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
266static 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
311nla_put_failure:
312
313 return 0;
314}
315
316static 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 */
381int 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 */
403int 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 */
427int 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 */
458int 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 */
484int 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 */
521int 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
559int 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 */
578int 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 */
602int 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 */
621int 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 */
644int 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 */
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 */
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 */
756int 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 */
780int 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/** @} */
791static void __init geneve_init(void)
792{
793 rtnl_link_register_info(&geneve_info_ops);
794}
795
796static void __exit geneve_exit(void)
797{
798 rtnl_link_unregister_info(&geneve_info_ops);
799}
800
801/** @} */
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
void * nl_addr_get_binary_addr(const struct nl_addr *addr)
Get binary address of abstract address object.
Definition: addr.c:940
int nl_addr_get_family(const struct nl_addr *addr)
Return address family.
Definition: addr.c:892
unsigned int nl_addr_get_len(const struct nl_addr *addr)
Get length of binary address of abstract address object.
Definition: addr.c:952
uint32_t nla_get_u32(const struct nlattr *nla)
Return payload of 32 bit integer attribute.
Definition: attr.c:702
uint16_t nla_get_u16(const struct nlattr *nla)
Return payload of 16 bit integer attribute.
Definition: attr.c:652
#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:602
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:898
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:1016
int nla_nest_end(struct nl_msg *msg, struct nlattr *start)
Finalize nesting of attributes.
Definition: attr.c:961
@ 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
struct rtnl_link * rtnl_link_geneve_alloc(void)
Allocate link object of type Geneve.
Definition: geneve.c:348
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
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