1 // SPDX-License-Identifier: GPL-2.0-or-later
4 * Copyright (C) 2020 Hiroki Shirokura, LINE Corporation
12 DEFINE_QOBJ_TYPE(srv6_locator
);
13 DEFINE_MTYPE_STATIC(LIB
, SRV6_LOCATOR
, "SRV6 locator");
14 DEFINE_MTYPE_STATIC(LIB
, SRV6_LOCATOR_CHUNK
, "SRV6 locator chunk");
16 const char *seg6local_action2str(uint32_t action
)
19 case ZEBRA_SEG6_LOCAL_ACTION_END
:
21 case ZEBRA_SEG6_LOCAL_ACTION_END_X
:
23 case ZEBRA_SEG6_LOCAL_ACTION_END_T
:
25 case ZEBRA_SEG6_LOCAL_ACTION_END_DX2
:
27 case ZEBRA_SEG6_LOCAL_ACTION_END_DX6
:
29 case ZEBRA_SEG6_LOCAL_ACTION_END_DX4
:
31 case ZEBRA_SEG6_LOCAL_ACTION_END_DT6
:
33 case ZEBRA_SEG6_LOCAL_ACTION_END_DT4
:
35 case ZEBRA_SEG6_LOCAL_ACTION_END_B6
:
37 case ZEBRA_SEG6_LOCAL_ACTION_END_B6_ENCAP
:
38 return "End.B6.Encap";
39 case ZEBRA_SEG6_LOCAL_ACTION_END_BM
:
41 case ZEBRA_SEG6_LOCAL_ACTION_END_S
:
43 case ZEBRA_SEG6_LOCAL_ACTION_END_AS
:
45 case ZEBRA_SEG6_LOCAL_ACTION_END_AM
:
47 case ZEBRA_SEG6_LOCAL_ACTION_END_DT46
:
49 case ZEBRA_SEG6_LOCAL_ACTION_UNSPEC
:
56 int snprintf_seg6_segs(char *str
,
57 size_t size
, const struct seg6_segs
*segs
)
60 for (size_t i
= 0; i
< segs
->num_segs
; i
++) {
61 char addr
[INET6_ADDRSTRLEN
];
62 bool not_last
= (i
+ 1) < segs
->num_segs
;
64 inet_ntop(AF_INET6
, &segs
->segs
[i
], addr
, sizeof(addr
));
65 strlcat(str
, addr
, size
);
66 strlcat(str
, not_last
? "," : "", size
);
71 const char *seg6local_context2str(char *str
, size_t size
,
72 const struct seg6local_context
*ctx
,
77 case ZEBRA_SEG6_LOCAL_ACTION_END
:
78 snprintf(str
, size
, "USP");
81 case ZEBRA_SEG6_LOCAL_ACTION_END_X
:
82 case ZEBRA_SEG6_LOCAL_ACTION_END_DX6
:
83 snprintfrr(str
, size
, "nh6 %pI6", &ctx
->nh6
);
86 case ZEBRA_SEG6_LOCAL_ACTION_END_DX4
:
87 snprintfrr(str
, size
, "nh4 %pI4", &ctx
->nh4
);
90 case ZEBRA_SEG6_LOCAL_ACTION_END_T
:
91 case ZEBRA_SEG6_LOCAL_ACTION_END_DT6
:
92 case ZEBRA_SEG6_LOCAL_ACTION_END_DT4
:
93 case ZEBRA_SEG6_LOCAL_ACTION_END_DT46
:
94 snprintf(str
, size
, "table %u", ctx
->table
);
97 case ZEBRA_SEG6_LOCAL_ACTION_END_DX2
:
98 case ZEBRA_SEG6_LOCAL_ACTION_END_B6
:
99 case ZEBRA_SEG6_LOCAL_ACTION_END_B6_ENCAP
:
100 case ZEBRA_SEG6_LOCAL_ACTION_END_BM
:
101 case ZEBRA_SEG6_LOCAL_ACTION_END_S
:
102 case ZEBRA_SEG6_LOCAL_ACTION_END_AS
:
103 case ZEBRA_SEG6_LOCAL_ACTION_END_AM
:
104 case ZEBRA_SEG6_LOCAL_ACTION_UNSPEC
:
106 snprintf(str
, size
, "unknown(%s)", __func__
);
111 static void srv6_locator_chunk_list_free(void *data
)
113 struct srv6_locator_chunk
*chunk
= data
;
115 srv6_locator_chunk_free(&chunk
);
118 struct srv6_locator
*srv6_locator_alloc(const char *name
)
120 struct srv6_locator
*locator
= NULL
;
122 locator
= XCALLOC(MTYPE_SRV6_LOCATOR
, sizeof(struct srv6_locator
));
123 strlcpy(locator
->name
, name
, sizeof(locator
->name
));
124 locator
->chunks
= list_new();
125 locator
->chunks
->del
= srv6_locator_chunk_list_free
;
127 QOBJ_REG(locator
, srv6_locator
);
131 struct srv6_locator_chunk
*srv6_locator_chunk_alloc(void)
133 struct srv6_locator_chunk
*chunk
= NULL
;
135 chunk
= XCALLOC(MTYPE_SRV6_LOCATOR_CHUNK
,
136 sizeof(struct srv6_locator_chunk
));
140 void srv6_locator_free(struct srv6_locator
*locator
)
144 list_delete(&locator
->chunks
);
146 XFREE(MTYPE_SRV6_LOCATOR
, locator
);
150 void srv6_locator_chunk_free(struct srv6_locator_chunk
**chunk
)
152 XFREE(MTYPE_SRV6_LOCATOR_CHUNK
, *chunk
);
155 json_object
*srv6_locator_chunk_json(const struct srv6_locator_chunk
*chunk
)
157 json_object
*jo_root
= NULL
;
159 jo_root
= json_object_new_object();
160 json_object_string_addf(jo_root
, "prefix", "%pFX", &chunk
->prefix
);
161 json_object_string_add(jo_root
, "proto",
162 zebra_route_string(chunk
->proto
));
168 srv6_locator_chunk_detailed_json(const struct srv6_locator_chunk
*chunk
)
170 json_object
*jo_root
= NULL
;
172 jo_root
= json_object_new_object();
175 json_object_string_addf(jo_root
, "prefix", "%pFX", &chunk
->prefix
);
177 /* set block_bits_length */
178 json_object_int_add(jo_root
, "blockBitsLength",
179 chunk
->block_bits_length
);
181 /* set node_bits_length */
182 json_object_int_add(jo_root
, "nodeBitsLength", chunk
->node_bits_length
);
184 /* set function_bits_length */
185 json_object_int_add(jo_root
, "functionBitsLength",
186 chunk
->function_bits_length
);
188 /* set argument_bits_length */
189 json_object_int_add(jo_root
, "argumentBitsLength",
190 chunk
->argument_bits_length
);
193 json_object_int_add(jo_root
, "keep", chunk
->keep
);
196 json_object_string_add(jo_root
, "proto",
197 zebra_route_string(chunk
->proto
));
200 json_object_int_add(jo_root
, "instance", chunk
->instance
);
203 json_object_int_add(jo_root
, "sessionId", chunk
->session_id
);
208 json_object
*srv6_locator_json(const struct srv6_locator
*loc
)
210 struct listnode
*node
;
211 struct srv6_locator_chunk
*chunk
;
212 json_object
*jo_root
= NULL
;
213 json_object
*jo_chunk
= NULL
;
214 json_object
*jo_chunks
= NULL
;
216 jo_root
= json_object_new_object();
219 json_object_string_add(jo_root
, "name", loc
->name
);
222 json_object_string_addf(jo_root
, "prefix", "%pFX", &loc
->prefix
);
224 /* set block_bits_length */
225 json_object_int_add(jo_root
, "blockBitsLength", loc
->block_bits_length
);
227 /* set node_bits_length */
228 json_object_int_add(jo_root
, "nodeBitsLength", loc
->node_bits_length
);
230 /* set function_bits_length */
231 json_object_int_add(jo_root
, "functionBitsLength",
232 loc
->function_bits_length
);
234 /* set argument_bits_length */
235 json_object_int_add(jo_root
, "argumentBitsLength",
236 loc
->argument_bits_length
);
238 /* set true if the locator is a Micro-segment (uSID) locator */
239 if (CHECK_FLAG(loc
->flags
, SRV6_LOCATOR_USID
))
240 json_object_string_add(jo_root
, "behavior", "usid");
243 json_object_boolean_add(jo_root
, "statusUp",
247 jo_chunks
= json_object_new_array();
248 json_object_object_add(jo_root
, "chunks", jo_chunks
);
249 for (ALL_LIST_ELEMENTS_RO((struct list
*)loc
->chunks
, node
, chunk
)) {
250 jo_chunk
= srv6_locator_chunk_json(chunk
);
251 json_object_array_add(jo_chunks
, jo_chunk
);
257 json_object
*srv6_locator_detailed_json(const struct srv6_locator
*loc
)
259 struct listnode
*node
;
260 struct srv6_locator_chunk
*chunk
;
261 json_object
*jo_root
= NULL
;
262 json_object
*jo_chunk
= NULL
;
263 json_object
*jo_chunks
= NULL
;
265 jo_root
= json_object_new_object();
268 json_object_string_add(jo_root
, "name", loc
->name
);
271 json_object_string_addf(jo_root
, "prefix", "%pFX", &loc
->prefix
);
273 /* set block_bits_length */
274 json_object_int_add(jo_root
, "blockBitsLength", loc
->block_bits_length
);
276 /* set node_bits_length */
277 json_object_int_add(jo_root
, "nodeBitsLength", loc
->node_bits_length
);
279 /* set function_bits_length */
280 json_object_int_add(jo_root
, "functionBitsLength",
281 loc
->function_bits_length
);
283 /* set argument_bits_length */
284 json_object_int_add(jo_root
, "argumentBitsLength",
285 loc
->argument_bits_length
);
287 /* set true if the locator is a Micro-segment (uSID) locator */
288 if (CHECK_FLAG(loc
->flags
, SRV6_LOCATOR_USID
))
289 json_object_string_add(jo_root
, "behavior", "usid");
292 json_object_int_add(jo_root
, "algoNum", loc
->algonum
);
295 json_object_boolean_add(jo_root
, "statusUp", loc
->status_up
);
298 jo_chunks
= json_object_new_array();
299 json_object_object_add(jo_root
, "chunks", jo_chunks
);
300 for (ALL_LIST_ELEMENTS_RO((struct list
*)loc
->chunks
, node
, chunk
)) {
301 jo_chunk
= srv6_locator_chunk_detailed_json(chunk
);
302 json_object_array_add(jo_chunks
, jo_chunk
);