libnl 3.12.0
nh_encap_ila.c
1/* SPDX-License-Identifier: LGPL-2.1-only */
2
3#include "nl-default.h"
4
5#include <linux/ila.h>
6#include <linux/lwtunnel.h>
7
8#include <netlink/route/nexthop.h>
9
10#include "nexthop-encap.h"
11#include "nl-aux-route/nl-route.h"
12#include "nl-route.h"
13
15 uint64_t locator;
16 uint8_t csum_mode;
17 uint8_t ident_type;
18 uint8_t hook_type;
19 bool has_csum_mode : 1;
20 bool has_ident_type : 1;
21 bool has_hook_type : 1;
22};
23
24static void ila_encap_dump(void *priv, struct nl_dump_params *dp)
25{
26 struct ila_tunnel_encap *ila_encap = priv;
27
28 nl_dump(dp, " locator 0x%llx ", (unsigned long long)ila_encap->locator);
29
30 if (ila_encap->has_csum_mode)
31 nl_dump(dp, " csum-mode %u ", ila_encap->csum_mode);
32
33 if (ila_encap->has_ident_type)
34 nl_dump(dp, " ident-type %u ", ila_encap->ident_type);
35
36 if (ila_encap->has_hook_type)
37 nl_dump(dp, " hook-type %u ", ila_encap->hook_type);
38}
39
40static int ila_encap_build_msg(struct nl_msg *msg, void *priv)
41{
42 struct ila_tunnel_encap *ila_encap = priv;
43
44 NLA_PUT_U64(msg, ILA_ATTR_LOCATOR, ila_encap->locator);
45
46 if (ila_encap->has_csum_mode)
47 NLA_PUT_U8(msg, ILA_ATTR_CSUM_MODE, ila_encap->csum_mode);
48
49 if (ila_encap->has_ident_type)
50 NLA_PUT_U8(msg, ILA_ATTR_IDENT_TYPE, ila_encap->ident_type);
51
52 if (ila_encap->has_hook_type)
53 NLA_PUT_U8(msg, ILA_ATTR_HOOK_TYPE, ila_encap->hook_type);
54
55 return 0;
56
57nla_put_failure:
58 return -NLE_MSGSIZE;
59}
60
61static void *ila_encap_clone(void *priv)
62{
63 return priv ? _nl_memdup(priv, sizeof(struct ila_tunnel_encap)) : NULL;
64}
65
66static int ila_encap_compare(void *_a, void *_b)
67{
68 struct ila_tunnel_encap *a = _a;
69 struct ila_tunnel_encap *b = _b;
70
71 if (!a || !b)
72 return a != b;
73
74 if (a->locator != b->locator)
75 return 1;
76
77 if (a->has_csum_mode != b->has_csum_mode)
78 return 1;
79
80 if (a->has_csum_mode && a->csum_mode != b->csum_mode)
81 return 1;
82
83 if (a->has_ident_type != b->has_ident_type)
84 return 1;
85
86 if (a->has_ident_type && a->ident_type != b->ident_type)
87 return 1;
88
89 if (a->has_hook_type != b->has_hook_type)
90 return 1;
91
92 if (a->has_hook_type && a->hook_type != b->hook_type)
93 return 1;
94
95 return 0;
96}
97
98static struct nla_policy ila_encap_policy[ILA_ATTR_MAX + 1] = {
99 [ILA_ATTR_LOCATOR] = { .type = NLA_U64 },
100 [ILA_ATTR_CSUM_MODE] = { .type = NLA_U8 },
101 [ILA_ATTR_IDENT_TYPE] = { .type = NLA_U8 },
102 [ILA_ATTR_HOOK_TYPE] = { .type = NLA_U8 },
103};
104
105static int ila_encap_parse_msg(struct nlattr *nla,
106 struct rtnl_nh_encap **encap_out)
107{
108 _nl_auto_rtnl_nh_encap struct rtnl_nh_encap *nh_encap = NULL;
109 struct nlattr *tb[ILA_ATTR_MAX + 1];
110 uint64_t locator;
111 int err;
112
113 err = nla_parse_nested(tb, ILA_ATTR_MAX, nla, ila_encap_policy);
114 if (err < 0)
115 return err;
116
117 if (!tb[ILA_ATTR_LOCATOR])
118 return -NLE_INVAL;
119
120 locator = nla_get_u64(tb[ILA_ATTR_LOCATOR]);
121
122 nh_encap = rtnl_nh_encap_alloc();
123 if (!nh_encap)
124 return -NLE_NOMEM;
125
126 err = rtnl_nh_encap_ila(nh_encap, locator);
127 if (err < 0)
128 return err;
129
130 if (tb[ILA_ATTR_CSUM_MODE]) {
131 err = rtnl_nh_set_encap_ila_csum_mode(
132 nh_encap, nla_get_u8(tb[ILA_ATTR_CSUM_MODE]));
133 if (err < 0)
134 return err;
135 }
136
137 if (tb[ILA_ATTR_IDENT_TYPE]) {
138 err = rtnl_nh_set_encap_ila_ident_type(
139 nh_encap, nla_get_u8(tb[ILA_ATTR_IDENT_TYPE]));
140 if (err < 0)
141 return err;
142 }
143
144 if (tb[ILA_ATTR_HOOK_TYPE]) {
145 err = rtnl_nh_set_encap_ila_hook_type(
146 nh_encap, nla_get_u8(tb[ILA_ATTR_HOOK_TYPE]));
147 if (err < 0)
148 return err;
149 }
150
151 *encap_out = _nl_steal_pointer(&nh_encap);
152
153 return 0;
154}
155
156const struct nh_encap_ops ila_encap_ops = {
157 .encap_type = LWTUNNEL_ENCAP_ILA,
158 .build_msg = ila_encap_build_msg,
159 .parse_msg = ila_encap_parse_msg,
160 .compare = ila_encap_compare,
161 .clone = ila_encap_clone,
162 .dump = ila_encap_dump,
163};
164
165static struct ila_tunnel_encap *nh_encap_get_ila(struct rtnl_nh_encap *nh_encap)
166{
167 return nh_encap_check_and_get_priv(nh_encap, LWTUNNEL_ENCAP_ILA);
168}
169
170int rtnl_nh_encap_ila(struct rtnl_nh_encap *nh_encap, uint64_t locator)
171{
172 struct ila_tunnel_encap *ila_encap;
173
174 if (!nh_encap)
175 return -NLE_INVAL;
176
177 ila_encap = calloc(1, sizeof(*ila_encap));
178 if (!ila_encap)
179 return -NLE_NOMEM;
180
181 ila_encap->locator = locator;
182
183 nh_encap->priv = ila_encap;
184 nh_encap->ops = &ila_encap_ops;
185
186 return 0;
187}
188
189int rtnl_nh_get_encap_ila_locator(struct rtnl_nh_encap *nh_encap,
190 uint64_t *locator)
191{
192 struct ila_tunnel_encap *ila_encap;
193
194 if (!locator)
195 return -NLE_INVAL;
196
197 ila_encap = nh_encap_get_ila(nh_encap);
198 if (!ila_encap)
199 return -NLE_INVAL;
200
201 *locator = ila_encap->locator;
202
203 return 0;
204}
205
206int rtnl_nh_set_encap_ila_csum_mode(struct rtnl_nh_encap *nh_encap,
207 uint8_t csum_mode)
208{
209 struct ila_tunnel_encap *ila_encap;
210
211 ila_encap = nh_encap_get_ila(nh_encap);
212 if (!ila_encap)
213 return -NLE_INVAL;
214
215 ila_encap->csum_mode = csum_mode;
216 ila_encap->has_csum_mode = true;
217
218 return 0;
219}
220
221int rtnl_nh_clear_encap_ila_csum_mode(struct rtnl_nh_encap *nh_encap)
222{
223 struct ila_tunnel_encap *ila_encap;
224
225 ila_encap = nh_encap_get_ila(nh_encap);
226 if (!ila_encap)
227 return -NLE_INVAL;
228
229 ila_encap->has_csum_mode = false;
230 ila_encap->csum_mode = 0;
231
232 return 0;
233}
234
235int rtnl_nh_get_encap_ila_csum_mode(struct rtnl_nh_encap *nh_encap)
236{
237 struct ila_tunnel_encap *ila_encap;
238
239 ila_encap = nh_encap_get_ila(nh_encap);
240 if (!ila_encap)
241 return -NLE_INVAL;
242
243 if (!ila_encap->has_csum_mode)
244 return -NLE_MISSING_ATTR;
245
246 return ila_encap->csum_mode;
247}
248
249int rtnl_nh_set_encap_ila_ident_type(struct rtnl_nh_encap *nh_encap,
250 uint8_t ident_type)
251{
252 struct ila_tunnel_encap *ila_encap;
253
254 ila_encap = nh_encap_get_ila(nh_encap);
255 if (!ila_encap)
256 return -NLE_INVAL;
257
258 ila_encap->ident_type = ident_type;
259 ila_encap->has_ident_type = true;
260
261 return 0;
262}
263
264int rtnl_nh_clear_encap_ila_ident_type(struct rtnl_nh_encap *nh_encap)
265{
266 struct ila_tunnel_encap *ila_encap;
267
268 ila_encap = nh_encap_get_ila(nh_encap);
269 if (!ila_encap)
270 return -NLE_INVAL;
271
272 ila_encap->has_ident_type = false;
273 ila_encap->ident_type = 0;
274
275 return 0;
276}
277
278int rtnl_nh_get_encap_ila_ident_type(struct rtnl_nh_encap *nh_encap)
279{
280 struct ila_tunnel_encap *ila_encap;
281
282 ila_encap = nh_encap_get_ila(nh_encap);
283 if (!ila_encap)
284 return -NLE_INVAL;
285
286 if (!ila_encap->has_ident_type)
287 return -NLE_MISSING_ATTR;
288
289 return ila_encap->ident_type;
290}
291
292int rtnl_nh_set_encap_ila_hook_type(struct rtnl_nh_encap *nh_encap,
293 uint8_t hook_type)
294{
295 struct ila_tunnel_encap *ila_encap;
296
297 ila_encap = nh_encap_get_ila(nh_encap);
298 if (!ila_encap)
299 return -NLE_INVAL;
300
301 ila_encap->hook_type = hook_type;
302 ila_encap->has_hook_type = true;
303
304 return 0;
305}
306
307int rtnl_nh_clear_encap_ila_hook_type(struct rtnl_nh_encap *nh_encap)
308{
309 struct ila_tunnel_encap *ila_encap;
310
311 ila_encap = nh_encap_get_ila(nh_encap);
312 if (!ila_encap)
313 return -NLE_INVAL;
314
315 ila_encap->has_hook_type = false;
316 ila_encap->hook_type = 0;
317
318 return 0;
319}
320
321int rtnl_nh_get_encap_ila_hook_type(struct rtnl_nh_encap *nh_encap)
322{
323 struct ila_tunnel_encap *ila_encap;
324
325 ila_encap = nh_encap_get_ila(nh_encap);
326 if (!ila_encap)
327 return -NLE_INVAL;
328
329 if (!ila_encap->has_hook_type)
330 return -NLE_MISSING_ATTR;
331
332 return ila_encap->hook_type;
333}
#define NLA_PUT_U8(msg, attrtype, value)
Add 8 bit integer attribute to netlink message.
Definition attr.h:201
uint64_t nla_get_u64(const struct nlattr *nla)
Return payload of u64 attribute.
Definition attr.c:769
uint8_t nla_get_u8(const struct nlattr *nla)
Return value of 8 bit integer attribute.
Definition attr.c:614
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:1101
#define NLA_PUT_U64(msg, attrtype, value)
Add 64 bit integer attribute to netlink message.
Definition attr.h:255
@ NLA_U64
64 bit integer
Definition attr.h:38
@ NLA_U8
8 bit integer
Definition attr.h:35
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
Definition utils.c:1015
Dumping parameters.
Definition types.h:32
Attribute validation policy.
Definition attr.h:66