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