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