]> git.proxmox.com Git - mirror_frr.git/blame - lib/srv6.c
*: manual SPDX License ID conversions
[mirror_frr.git] / lib / srv6.c
CommitLineData
e496b420
HS
1/*
2 * SRv6 definitions
3 * Copyright (C) 2020 Hiroki Shirokura, LINE Corporation
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the Free
7 * Software Foundation; either version 2 of the License, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; see the file COPYING; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
7309092b
DL
20#include "zebra.h"
21
e496b420
HS
22#include "srv6.h"
23#include "log.h"
24
f2867068
HS
25DEFINE_QOBJ_TYPE(srv6_locator);
26DEFINE_MTYPE_STATIC(LIB, SRV6_LOCATOR, "SRV6 locator");
27DEFINE_MTYPE_STATIC(LIB, SRV6_LOCATOR_CHUNK, "SRV6 locator chunk");
28
e496b420
HS
29const char *seg6local_action2str(uint32_t action)
30{
31 switch (action) {
32 case ZEBRA_SEG6_LOCAL_ACTION_END:
33 return "End";
34 case ZEBRA_SEG6_LOCAL_ACTION_END_X:
35 return "End.X";
36 case ZEBRA_SEG6_LOCAL_ACTION_END_T:
37 return "End.T";
38 case ZEBRA_SEG6_LOCAL_ACTION_END_DX2:
39 return "End.DX2";
40 case ZEBRA_SEG6_LOCAL_ACTION_END_DX6:
41 return "End.DX6";
42 case ZEBRA_SEG6_LOCAL_ACTION_END_DX4:
43 return "End.DX4";
44 case ZEBRA_SEG6_LOCAL_ACTION_END_DT6:
45 return "End.DT6";
46 case ZEBRA_SEG6_LOCAL_ACTION_END_DT4:
47 return "End.DT4";
48 case ZEBRA_SEG6_LOCAL_ACTION_END_B6:
49 return "End.B6";
50 case ZEBRA_SEG6_LOCAL_ACTION_END_B6_ENCAP:
51 return "End.B6.Encap";
52 case ZEBRA_SEG6_LOCAL_ACTION_END_BM:
53 return "End.BM";
54 case ZEBRA_SEG6_LOCAL_ACTION_END_S:
55 return "End.S";
56 case ZEBRA_SEG6_LOCAL_ACTION_END_AS:
57 return "End.AS";
58 case ZEBRA_SEG6_LOCAL_ACTION_END_AM:
59 return "End.AM";
8bea07e4
CS
60 case ZEBRA_SEG6_LOCAL_ACTION_END_DT46:
61 return "End.DT46";
e496b420
HS
62 case ZEBRA_SEG6_LOCAL_ACTION_UNSPEC:
63 return "unspec";
64 default:
65 return "unknown";
66 }
67}
68
69int snprintf_seg6_segs(char *str,
70 size_t size, const struct seg6_segs *segs)
71{
72 str[0] = '\0';
73 for (size_t i = 0; i < segs->num_segs; i++) {
74 char addr[INET6_ADDRSTRLEN];
75 bool not_last = (i + 1) < segs->num_segs;
76
77 inet_ntop(AF_INET6, &segs->segs[i], addr, sizeof(addr));
78 strlcat(str, addr, size);
79 strlcat(str, not_last ? "," : "", size);
80 }
81 return strlen(str);
82}
83
84const char *seg6local_context2str(char *str, size_t size,
7a4b49bd
HS
85 const struct seg6local_context *ctx,
86 uint32_t action)
e496b420 87{
e496b420
HS
88 switch (action) {
89
90 case ZEBRA_SEG6_LOCAL_ACTION_END:
91 snprintf(str, size, "USP");
92 return str;
93
94 case ZEBRA_SEG6_LOCAL_ACTION_END_X:
95 case ZEBRA_SEG6_LOCAL_ACTION_END_DX6:
84410eb0 96 snprintfrr(str, size, "nh6 %pI6", &ctx->nh6);
e496b420
HS
97 return str;
98
99 case ZEBRA_SEG6_LOCAL_ACTION_END_DX4:
84410eb0 100 snprintfrr(str, size, "nh4 %pI4", &ctx->nh4);
e496b420
HS
101 return str;
102
103 case ZEBRA_SEG6_LOCAL_ACTION_END_T:
104 case ZEBRA_SEG6_LOCAL_ACTION_END_DT6:
105 case ZEBRA_SEG6_LOCAL_ACTION_END_DT4:
8bea07e4 106 case ZEBRA_SEG6_LOCAL_ACTION_END_DT46:
e496b420
HS
107 snprintf(str, size, "table %u", ctx->table);
108 return str;
109
110 case ZEBRA_SEG6_LOCAL_ACTION_END_DX2:
111 case ZEBRA_SEG6_LOCAL_ACTION_END_B6:
112 case ZEBRA_SEG6_LOCAL_ACTION_END_B6_ENCAP:
113 case ZEBRA_SEG6_LOCAL_ACTION_END_BM:
114 case ZEBRA_SEG6_LOCAL_ACTION_END_S:
115 case ZEBRA_SEG6_LOCAL_ACTION_END_AS:
116 case ZEBRA_SEG6_LOCAL_ACTION_END_AM:
117 case ZEBRA_SEG6_LOCAL_ACTION_UNSPEC:
118 default:
119 snprintf(str, size, "unknown(%s)", __func__);
120 return str;
121 }
122}
f2867068 123
1fec35c3
DS
124static void srv6_locator_chunk_list_free(void *data)
125{
126 struct srv6_locator_chunk *chunk = data;
127
128 srv6_locator_chunk_free(&chunk);
129}
130
f2867068
HS
131struct srv6_locator *srv6_locator_alloc(const char *name)
132{
133 struct srv6_locator *locator = NULL;
134
135 locator = XCALLOC(MTYPE_SRV6_LOCATOR, sizeof(struct srv6_locator));
136 strlcpy(locator->name, name, sizeof(locator->name));
137 locator->chunks = list_new();
1fec35c3 138 locator->chunks->del = srv6_locator_chunk_list_free;
4b220ad0 139
f2867068
HS
140 QOBJ_REG(locator, srv6_locator);
141 return locator;
142}
143
144struct srv6_locator_chunk *srv6_locator_chunk_alloc(void)
145{
146 struct srv6_locator_chunk *chunk = NULL;
147
148 chunk = XCALLOC(MTYPE_SRV6_LOCATOR_CHUNK,
149 sizeof(struct srv6_locator_chunk));
150 return chunk;
151}
152
153void srv6_locator_free(struct srv6_locator *locator)
154{
4b220ad0
MS
155 if (locator) {
156 QOBJ_UNREG(locator);
157 list_delete(&locator->chunks);
158
159 XFREE(MTYPE_SRV6_LOCATOR, locator);
160 }
f2867068
HS
161}
162
69467313 163void srv6_locator_chunk_free(struct srv6_locator_chunk **chunk)
f2867068 164{
69467313 165 XFREE(MTYPE_SRV6_LOCATOR_CHUNK, *chunk);
f2867068
HS
166}
167
168json_object *srv6_locator_chunk_json(const struct srv6_locator_chunk *chunk)
169{
f2867068
HS
170 json_object *jo_root = NULL;
171
172 jo_root = json_object_new_object();
a6c86424 173 json_object_string_addf(jo_root, "prefix", "%pFX", &chunk->prefix);
f2867068
HS
174 json_object_string_add(jo_root, "proto",
175 zebra_route_string(chunk->proto));
176
177 return jo_root;
178}
179
559f4b2f
YS
180json_object *
181srv6_locator_chunk_detailed_json(const struct srv6_locator_chunk *chunk)
182{
183 json_object *jo_root = NULL;
184
185 jo_root = json_object_new_object();
186
187 /* set prefix */
188 json_object_string_addf(jo_root, "prefix", "%pFX", &chunk->prefix);
189
190 /* set block_bits_length */
191 json_object_int_add(jo_root, "blockBitsLength",
192 chunk->block_bits_length);
193
194 /* set node_bits_length */
195 json_object_int_add(jo_root, "nodeBitsLength", chunk->node_bits_length);
196
197 /* set function_bits_length */
198 json_object_int_add(jo_root, "functionBitsLength",
199 chunk->function_bits_length);
200
201 /* set argument_bits_length */
202 json_object_int_add(jo_root, "argumentBitsLength",
203 chunk->argument_bits_length);
204
205 /* set keep */
206 json_object_int_add(jo_root, "keep", chunk->keep);
207
208 /* set proto */
209 json_object_string_add(jo_root, "proto",
210 zebra_route_string(chunk->proto));
211
212 /* set instance */
213 json_object_int_add(jo_root, "instance", chunk->instance);
214
215 /* set session_id */
216 json_object_int_add(jo_root, "sessionId", chunk->session_id);
217
218 return jo_root;
219}
220
f2867068
HS
221json_object *srv6_locator_json(const struct srv6_locator *loc)
222{
f2867068
HS
223 struct listnode *node;
224 struct srv6_locator_chunk *chunk;
225 json_object *jo_root = NULL;
226 json_object *jo_chunk = NULL;
227 json_object *jo_chunks = NULL;
228
229 jo_root = json_object_new_object();
230
231 /* set name */
232 json_object_string_add(jo_root, "name", loc->name);
233
234 /* set prefix */
a6c86424 235 json_object_string_addf(jo_root, "prefix", "%pFX", &loc->prefix);
f2867068 236
696f4370
CS
237 /* set block_bits_length */
238 json_object_int_add(jo_root, "blockBitsLength", loc->block_bits_length);
239
240 /* set node_bits_length */
241 json_object_int_add(jo_root, "nodeBitsLength", loc->node_bits_length);
242
f2867068 243 /* set function_bits_length */
326591dc 244 json_object_int_add(jo_root, "functionBitsLength",
f2867068
HS
245 loc->function_bits_length);
246
696f4370
CS
247 /* set argument_bits_length */
248 json_object_int_add(jo_root, "argumentBitsLength",
249 loc->argument_bits_length);
250
a3ff3dff
CS
251 /* set true if the locator is a Micro-segment (uSID) locator */
252 if (CHECK_FLAG(loc->flags, SRV6_LOCATOR_USID))
253 json_object_string_add(jo_root, "behavior", "usid");
254
f2867068 255 /* set status_up */
326591dc 256 json_object_boolean_add(jo_root, "statusUp",
f2867068
HS
257 loc->status_up);
258
259 /* set chunks */
260 jo_chunks = json_object_new_array();
261 json_object_object_add(jo_root, "chunks", jo_chunks);
262 for (ALL_LIST_ELEMENTS_RO((struct list *)loc->chunks, node, chunk)) {
263 jo_chunk = srv6_locator_chunk_json(chunk);
264 json_object_array_add(jo_chunks, jo_chunk);
265 }
266
267 return jo_root;
268}
559f4b2f
YS
269
270json_object *srv6_locator_detailed_json(const struct srv6_locator *loc)
271{
272 struct listnode *node;
273 struct srv6_locator_chunk *chunk;
274 json_object *jo_root = NULL;
275 json_object *jo_chunk = NULL;
276 json_object *jo_chunks = NULL;
277
278 jo_root = json_object_new_object();
279
280 /* set name */
281 json_object_string_add(jo_root, "name", loc->name);
282
283 /* set prefix */
284 json_object_string_addf(jo_root, "prefix", "%pFX", &loc->prefix);
285
286 /* set block_bits_length */
287 json_object_int_add(jo_root, "blockBitsLength", loc->block_bits_length);
288
289 /* set node_bits_length */
290 json_object_int_add(jo_root, "nodeBitsLength", loc->node_bits_length);
291
292 /* set function_bits_length */
293 json_object_int_add(jo_root, "functionBitsLength",
294 loc->function_bits_length);
295
296 /* set argument_bits_length */
297 json_object_int_add(jo_root, "argumentBitsLength",
298 loc->argument_bits_length);
299
a3ff3dff
CS
300 /* set true if the locator is a Micro-segment (uSID) locator */
301 if (CHECK_FLAG(loc->flags, SRV6_LOCATOR_USID))
302 json_object_string_add(jo_root, "behavior", "usid");
303
559f4b2f
YS
304 /* set algonum */
305 json_object_int_add(jo_root, "algoNum", loc->algonum);
306
307 /* set status_up */
308 json_object_boolean_add(jo_root, "statusUp", loc->status_up);
309
310 /* set chunks */
311 jo_chunks = json_object_new_array();
312 json_object_object_add(jo_root, "chunks", jo_chunks);
313 for (ALL_LIST_ELEMENTS_RO((struct list *)loc->chunks, node, chunk)) {
314 jo_chunk = srv6_locator_chunk_detailed_json(chunk);
315 json_object_array_add(jo_chunks, jo_chunk);
316 }
317
318 return jo_root;
319}