2 * Zebra SRv6 VTY functions
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
33 #include "zebra/zserv.h"
34 #include "zebra/zebra_router.h"
35 #include "zebra/zebra_vrf.h"
36 #include "zebra/zebra_srv6.h"
37 #include "zebra/zebra_srv6_vty.h"
38 #include "zebra/zebra_rnh.h"
39 #include "zebra/redistribute.h"
40 #include "zebra/zebra_routemap.h"
41 #include "zebra/zebra_dplane.h"
43 #ifndef VTYSH_EXTRACT_PL
44 #include "zebra/zebra_srv6_vty_clippy.c"
47 static int zebra_sr_config(struct vty
*vty
);
49 static struct cmd_node sr_node
= {
51 .node
= SEGMENT_ROUTING_NODE
,
52 .parent_node
= CONFIG_NODE
,
53 .prompt
= "%s(config-sr)# ",
54 .config_write
= zebra_sr_config
,
57 static struct cmd_node srv6_node
= {
60 .parent_node
= SEGMENT_ROUTING_NODE
,
61 .prompt
= "%s(config-srv6)# ",
65 static struct cmd_node srv6_locs_node
= {
66 .name
= "srv6-locators",
67 .node
= SRV6_LOCS_NODE
,
68 .parent_node
= SRV6_NODE
,
69 .prompt
= "%s(config-srv6-locators)# ",
72 static struct cmd_node srv6_loc_node
= {
73 .name
= "srv6-locator",
74 .node
= SRV6_LOC_NODE
,
75 .parent_node
= SRV6_LOCS_NODE
,
76 .prompt
= "%s(config-srv6-locator)# "
79 DEFUN (show_srv6_locator
,
80 show_srv6_locator_cmd
,
81 "show segment-routing srv6 locator [json]",
84 "Segment Routing SRv6\n"
85 "Locator Information\n"
88 const bool uj
= use_json(argc
, argv
);
89 struct zebra_srv6
*srv6
= zebra_srv6_get_default();
90 struct srv6_locator
*locator
;
91 struct listnode
*node
;
94 json_object
*json
= NULL
;
95 json_object
*json_locators
= NULL
;
96 json_object
*json_locator
= NULL
;
99 json
= json_object_new_object();
100 json_locators
= json_object_new_array();
101 json_object_object_add(json
, "locators", json_locators
);
103 for (ALL_LIST_ELEMENTS_RO(srv6
->locators
, node
, locator
)) {
104 json_locator
= srv6_locator_json(locator
);
107 json_object_array_add(json_locators
, json_locator
);
113 vty_out(vty
, "Locator:\n");
114 vty_out(vty
, "Name ID Prefix Status\n");
115 vty_out(vty
, "-------------------- ------- ------------------------ -------\n");
118 for (ALL_LIST_ELEMENTS_RO(srv6
->locators
, node
, locator
)) {
119 prefix2str(&locator
->prefix
, str
, sizeof(str
));
120 vty_out(vty
, "%-20s %7d %-24s %s\n",
121 locator
->name
, id
, str
,
122 locator
->status_up
? "Up" : "Down");
131 DEFUN (show_srv6_locator_detail
,
132 show_srv6_locator_detail_cmd
,
133 "show segment-routing srv6 locator NAME detail [json]",
136 "Segment Routing SRv6\n"
137 "Locator Information\n"
139 "Detailed information\n"
142 const bool uj
= use_json(argc
, argv
);
143 struct zebra_srv6
*srv6
= zebra_srv6_get_default();
144 struct srv6_locator
*locator
;
145 struct listnode
*node
;
147 const char *locator_name
= argv
[4]->arg
;
148 json_object
*json_locator
= NULL
;
151 locator
= zebra_srv6_locator_lookup(locator_name
);
155 json_locator
= srv6_locator_detailed_json(locator
);
156 vty_json(vty
, json_locator
);
160 for (ALL_LIST_ELEMENTS_RO(srv6
->locators
, node
, locator
)) {
161 struct listnode
*node
;
162 struct srv6_locator_chunk
*chunk
;
164 if (strcmp(locator
->name
, locator_name
) != 0)
167 prefix2str(&locator
->prefix
, str
, sizeof(str
));
168 vty_out(vty
, "Name: %s\n", locator
->name
);
169 vty_out(vty
, "Prefix: %s\n", str
);
170 vty_out(vty
, "Function-Bit-Len: %u\n",
171 locator
->function_bits_length
);
173 vty_out(vty
, "Chunks:\n");
174 for (ALL_LIST_ELEMENTS_RO((struct list
*)locator
->chunks
, node
,
176 prefix2str(&chunk
->prefix
, str
, sizeof(str
));
177 vty_out(vty
, "- prefix: %s, owner: %s\n", str
,
178 zebra_route_string(chunk
->proto
));
186 DEFUN_NOSH (segment_routing
,
191 vty
->node
= SEGMENT_ROUTING_NODE
;
198 "Segment Routing SRv6\n")
200 vty
->node
= SRV6_NODE
;
208 "Segment Routing SRv6\n")
210 struct zebra_srv6
*srv6
= zebra_srv6_get_default();
211 struct srv6_locator
*locator
;
212 struct listnode
*node
, *nnode
;
214 for (ALL_LIST_ELEMENTS(srv6
->locators
, node
, nnode
, locator
))
215 zebra_srv6_locator_delete(locator
);
219 DEFUN_NOSH (srv6_locators
,
222 "Segment Routing SRv6 locators\n")
224 vty
->node
= SRV6_LOCS_NODE
;
228 DEFUN_NOSH (srv6_locator
,
231 "Segment Routing SRv6 locator\n"
232 "Specify locator-name\n")
234 struct srv6_locator
*locator
= NULL
;
236 locator
= zebra_srv6_locator_lookup(argv
[1]->arg
);
238 VTY_PUSH_CONTEXT(SRV6_LOC_NODE
, locator
);
239 locator
->status_up
= true;
243 locator
= srv6_locator_alloc(argv
[1]->arg
);
245 vty_out(vty
, "%% Alloc failed\n");
246 return CMD_WARNING_CONFIG_FAILED
;
248 locator
->status_up
= true;
250 VTY_PUSH_CONTEXT(SRV6_LOC_NODE
, locator
);
251 vty
->node
= SRV6_LOC_NODE
;
255 DEFUN (no_srv6_locator
,
259 "Segment Routing SRv6 locator\n"
260 "Specify locator-name\n")
262 struct srv6_locator
*locator
= zebra_srv6_locator_lookup(argv
[2]->arg
);
264 vty_out(vty
, "%% Can't find SRv6 locator\n");
265 return CMD_WARNING_CONFIG_FAILED
;
268 zebra_srv6_locator_delete(locator
);
272 DEFPY (locator_prefix
,
274 "prefix X:X::X:X/M$prefix [func-bits (16-64)$func_bit_len]",
275 "Configure SRv6 locator prefix\n"
276 "Specify SRv6 locator prefix\n"
277 "Configure SRv6 locator function length in bits\n"
278 "Specify SRv6 locator function length in bits\n")
280 VTY_DECLVAR_CONTEXT(srv6_locator
, locator
);
281 struct srv6_locator_chunk
*chunk
= NULL
;
282 struct listnode
*node
= NULL
;
284 locator
->prefix
= *prefix
;
287 * TODO(slankdev): please support variable node-bit-length.
288 * In draft-ietf-bess-srv6-services-05#section-3.2.1.
289 * Locator block length and Locator node length are defined.
290 * Which are defined as "locator-len == block-len + node-len".
291 * In current implementation, node bits length is hardcoded as 24.
292 * It should be supported various val.
294 * Cisco IOS-XR support only following pattern.
295 * (1) Teh locator length should be 64-bits long.
296 * (2) The SID block portion (MSBs) cannot exceed 40 bits.
297 * If this value is less than 40 bits,
298 * user should use a pattern of zeros as a filler.
299 * (3) The Node Id portion (LSBs) cannot exceed 24 bits.
301 locator
->block_bits_length
= prefix
->prefixlen
- 24;
302 locator
->node_bits_length
= 24;
303 locator
->function_bits_length
= func_bit_len
;
304 locator
->argument_bits_length
= 0;
306 if (list_isempty(locator
->chunks
)) {
307 chunk
= srv6_locator_chunk_alloc();
308 chunk
->prefix
= *prefix
;
310 listnode_add(locator
->chunks
, chunk
);
312 for (ALL_LIST_ELEMENTS_RO(locator
->chunks
, node
, chunk
)) {
313 uint8_t zero
[16] = {0};
315 if (memcmp(&chunk
->prefix
.prefix
, zero
, 16) == 0) {
316 struct zserv
*client
;
317 struct listnode
*client_node
;
319 chunk
->prefix
= *prefix
;
320 for (ALL_LIST_ELEMENTS_RO(zrouter
.client_list
,
323 struct srv6_locator
*tmp
;
325 if (client
->proto
!= chunk
->proto
)
328 srv6_manager_get_locator_chunk_call(
337 zebra_srv6_locator_add(locator
);
341 static int zebra_sr_config(struct vty
*vty
)
343 struct zebra_srv6
*srv6
= zebra_srv6_get_default();
344 struct listnode
*node
;
345 struct srv6_locator
*locator
;
349 if (zebra_srv6_is_enable()) {
350 vty_out(vty
, "segment-routing\n");
351 vty_out(vty
, " srv6\n");
352 vty_out(vty
, " locators\n");
353 for (ALL_LIST_ELEMENTS_RO(srv6
->locators
, node
, locator
)) {
354 inet_ntop(AF_INET6
, &locator
->prefix
.prefix
,
356 vty_out(vty
, " locator %s\n", locator
->name
);
357 vty_out(vty
, " prefix %s/%u\n", str
,
358 locator
->prefix
.prefixlen
);
359 vty_out(vty
, " exit\n");
360 vty_out(vty
, " !\n");
362 vty_out(vty
, " exit\n");
363 vty_out(vty
, " !\n");
364 vty_out(vty
, " exit\n");
365 vty_out(vty
, " !\n");
366 vty_out(vty
, "exit\n");
372 void zebra_srv6_vty_init(void)
374 /* Install nodes and its default commands */
375 install_node(&sr_node
);
376 install_node(&srv6_node
);
377 install_node(&srv6_locs_node
);
378 install_node(&srv6_loc_node
);
379 install_default(SEGMENT_ROUTING_NODE
);
380 install_default(SRV6_NODE
);
381 install_default(SRV6_LOCS_NODE
);
382 install_default(SRV6_LOC_NODE
);
384 /* Command for change node */
385 install_element(CONFIG_NODE
, &segment_routing_cmd
);
386 install_element(SEGMENT_ROUTING_NODE
, &srv6_cmd
);
387 install_element(SEGMENT_ROUTING_NODE
, &no_srv6_cmd
);
388 install_element(SRV6_NODE
, &srv6_locators_cmd
);
389 install_element(SRV6_LOCS_NODE
, &srv6_locator_cmd
);
390 install_element(SRV6_LOCS_NODE
, &no_srv6_locator_cmd
);
392 /* Command for configuration */
393 install_element(SRV6_LOC_NODE
, &locator_prefix_cmd
);
395 /* Command for operation */
396 install_element(VIEW_NODE
, &show_srv6_locator_cmd
);
397 install_element(VIEW_NODE
, &show_srv6_locator_detail_cmd
);