3 * Copyright (C) 2020 Hiroki Shirokura, LINE Corporation
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)
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
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
25 DEFINE_QOBJ_TYPE(srv6_locator
);
26 DEFINE_MTYPE_STATIC(LIB
, SRV6_LOCATOR
, "SRV6 locator");
27 DEFINE_MTYPE_STATIC(LIB
, SRV6_LOCATOR_CHUNK
, "SRV6 locator chunk");
29 const char *seg6local_action2str(uint32_t action
)
32 case ZEBRA_SEG6_LOCAL_ACTION_END
:
34 case ZEBRA_SEG6_LOCAL_ACTION_END_X
:
36 case ZEBRA_SEG6_LOCAL_ACTION_END_T
:
38 case ZEBRA_SEG6_LOCAL_ACTION_END_DX2
:
40 case ZEBRA_SEG6_LOCAL_ACTION_END_DX6
:
42 case ZEBRA_SEG6_LOCAL_ACTION_END_DX4
:
44 case ZEBRA_SEG6_LOCAL_ACTION_END_DT6
:
46 case ZEBRA_SEG6_LOCAL_ACTION_END_DT4
:
48 case ZEBRA_SEG6_LOCAL_ACTION_END_B6
:
50 case ZEBRA_SEG6_LOCAL_ACTION_END_B6_ENCAP
:
51 return "End.B6.Encap";
52 case ZEBRA_SEG6_LOCAL_ACTION_END_BM
:
54 case ZEBRA_SEG6_LOCAL_ACTION_END_S
:
56 case ZEBRA_SEG6_LOCAL_ACTION_END_AS
:
58 case ZEBRA_SEG6_LOCAL_ACTION_END_AM
:
60 case ZEBRA_SEG6_LOCAL_ACTION_END_DT46
:
62 case ZEBRA_SEG6_LOCAL_ACTION_UNSPEC
:
69 int snprintf_seg6_segs(char *str
,
70 size_t size
, const struct seg6_segs
*segs
)
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
;
77 inet_ntop(AF_INET6
, &segs
->segs
[i
], addr
, sizeof(addr
));
78 strlcat(str
, addr
, size
);
79 strlcat(str
, not_last
? "," : "", size
);
84 const char *seg6local_context2str(char *str
, size_t size
,
85 const struct seg6local_context
*ctx
,
90 case ZEBRA_SEG6_LOCAL_ACTION_END
:
91 snprintf(str
, size
, "USP");
94 case ZEBRA_SEG6_LOCAL_ACTION_END_X
:
95 case ZEBRA_SEG6_LOCAL_ACTION_END_DX6
:
96 snprintfrr(str
, size
, "nh6 %pI6", &ctx
->nh6
);
99 case ZEBRA_SEG6_LOCAL_ACTION_END_DX4
:
100 snprintfrr(str
, size
, "nh4 %pI4", &ctx
->nh4
);
103 case ZEBRA_SEG6_LOCAL_ACTION_END_T
:
104 case ZEBRA_SEG6_LOCAL_ACTION_END_DT6
:
105 case ZEBRA_SEG6_LOCAL_ACTION_END_DT4
:
106 case ZEBRA_SEG6_LOCAL_ACTION_END_DT46
:
107 snprintf(str
, size
, "table %u", ctx
->table
);
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
:
119 snprintf(str
, size
, "unknown(%s)", __func__
);
124 struct srv6_locator
*srv6_locator_alloc(const char *name
)
126 struct srv6_locator
*locator
= NULL
;
128 locator
= XCALLOC(MTYPE_SRV6_LOCATOR
, sizeof(struct srv6_locator
));
129 strlcpy(locator
->name
, name
, sizeof(locator
->name
));
130 locator
->chunks
= list_new();
131 locator
->chunks
->del
= (void (*)(void *))srv6_locator_chunk_free
;
133 QOBJ_REG(locator
, srv6_locator
);
137 struct srv6_locator_chunk
*srv6_locator_chunk_alloc(void)
139 struct srv6_locator_chunk
*chunk
= NULL
;
141 chunk
= XCALLOC(MTYPE_SRV6_LOCATOR_CHUNK
,
142 sizeof(struct srv6_locator_chunk
));
146 void srv6_locator_free(struct srv6_locator
*locator
)
150 list_delete(&locator
->chunks
);
152 XFREE(MTYPE_SRV6_LOCATOR
, locator
);
156 void srv6_locator_chunk_free(struct srv6_locator_chunk
**chunk
)
158 XFREE(MTYPE_SRV6_LOCATOR_CHUNK
, *chunk
);
161 json_object
*srv6_locator_chunk_json(const struct srv6_locator_chunk
*chunk
)
163 json_object
*jo_root
= NULL
;
165 jo_root
= json_object_new_object();
166 json_object_string_addf(jo_root
, "prefix", "%pFX", &chunk
->prefix
);
167 json_object_string_add(jo_root
, "proto",
168 zebra_route_string(chunk
->proto
));
174 srv6_locator_chunk_detailed_json(const struct srv6_locator_chunk
*chunk
)
176 json_object
*jo_root
= NULL
;
178 jo_root
= json_object_new_object();
181 json_object_string_addf(jo_root
, "prefix", "%pFX", &chunk
->prefix
);
183 /* set block_bits_length */
184 json_object_int_add(jo_root
, "blockBitsLength",
185 chunk
->block_bits_length
);
187 /* set node_bits_length */
188 json_object_int_add(jo_root
, "nodeBitsLength", chunk
->node_bits_length
);
190 /* set function_bits_length */
191 json_object_int_add(jo_root
, "functionBitsLength",
192 chunk
->function_bits_length
);
194 /* set argument_bits_length */
195 json_object_int_add(jo_root
, "argumentBitsLength",
196 chunk
->argument_bits_length
);
199 json_object_int_add(jo_root
, "keep", chunk
->keep
);
202 json_object_string_add(jo_root
, "proto",
203 zebra_route_string(chunk
->proto
));
206 json_object_int_add(jo_root
, "instance", chunk
->instance
);
209 json_object_int_add(jo_root
, "sessionId", chunk
->session_id
);
214 json_object
*srv6_locator_json(const struct srv6_locator
*loc
)
216 struct listnode
*node
;
217 struct srv6_locator_chunk
*chunk
;
218 json_object
*jo_root
= NULL
;
219 json_object
*jo_chunk
= NULL
;
220 json_object
*jo_chunks
= NULL
;
222 jo_root
= json_object_new_object();
225 json_object_string_add(jo_root
, "name", loc
->name
);
228 json_object_string_addf(jo_root
, "prefix", "%pFX", &loc
->prefix
);
230 /* set block_bits_length */
231 json_object_int_add(jo_root
, "blockBitsLength", loc
->block_bits_length
);
233 /* set node_bits_length */
234 json_object_int_add(jo_root
, "nodeBitsLength", loc
->node_bits_length
);
236 /* set function_bits_length */
237 json_object_int_add(jo_root
, "functionBitsLength",
238 loc
->function_bits_length
);
240 /* set argument_bits_length */
241 json_object_int_add(jo_root
, "argumentBitsLength",
242 loc
->argument_bits_length
);
244 /* set true if the locator is a Micro-segment (uSID) locator */
245 if (CHECK_FLAG(loc
->flags
, SRV6_LOCATOR_USID
))
246 json_object_string_add(jo_root
, "behavior", "usid");
249 json_object_boolean_add(jo_root
, "statusUp",
253 jo_chunks
= json_object_new_array();
254 json_object_object_add(jo_root
, "chunks", jo_chunks
);
255 for (ALL_LIST_ELEMENTS_RO((struct list
*)loc
->chunks
, node
, chunk
)) {
256 jo_chunk
= srv6_locator_chunk_json(chunk
);
257 json_object_array_add(jo_chunks
, jo_chunk
);
263 json_object
*srv6_locator_detailed_json(const struct srv6_locator
*loc
)
265 struct listnode
*node
;
266 struct srv6_locator_chunk
*chunk
;
267 json_object
*jo_root
= NULL
;
268 json_object
*jo_chunk
= NULL
;
269 json_object
*jo_chunks
= NULL
;
271 jo_root
= json_object_new_object();
274 json_object_string_add(jo_root
, "name", loc
->name
);
277 json_object_string_addf(jo_root
, "prefix", "%pFX", &loc
->prefix
);
279 /* set block_bits_length */
280 json_object_int_add(jo_root
, "blockBitsLength", loc
->block_bits_length
);
282 /* set node_bits_length */
283 json_object_int_add(jo_root
, "nodeBitsLength", loc
->node_bits_length
);
285 /* set function_bits_length */
286 json_object_int_add(jo_root
, "functionBitsLength",
287 loc
->function_bits_length
);
289 /* set argument_bits_length */
290 json_object_int_add(jo_root
, "argumentBitsLength",
291 loc
->argument_bits_length
);
293 /* set true if the locator is a Micro-segment (uSID) locator */
294 if (CHECK_FLAG(loc
->flags
, SRV6_LOCATOR_USID
))
295 json_object_string_add(jo_root
, "behavior", "usid");
298 json_object_int_add(jo_root
, "algoNum", loc
->algonum
);
301 json_object_boolean_add(jo_root
, "statusUp", loc
->status_up
);
304 jo_chunks
= json_object_new_array();
305 json_object_object_add(jo_root
, "chunks", jo_chunks
);
306 for (ALL_LIST_ELEMENTS_RO((struct list
*)loc
->chunks
, node
, chunk
)) {
307 jo_chunk
= srv6_locator_chunk_detailed_json(chunk
);
308 json_object_array_add(jo_chunks
, jo_chunk
);