]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zebra_srv6_vty.c
zebra: elliminate srv6 locator auto allocation by zlicnet request
[mirror_frr.git] / zebra / zebra_srv6_vty.c
CommitLineData
6c0a7c09
HS
1/*
2 * Zebra SRv6 VTY functions
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
20#include <zebra.h>
21
22#include "memory.h"
23#include "if.h"
24#include "prefix.h"
25#include "command.h"
26#include "table.h"
27#include "rib.h"
28#include "nexthop.h"
29#include "vrf.h"
30#include "srv6.h"
31#include "lib/json.h"
32
33#include "zebra/zserv.h"
00978977 34#include "zebra/zebra_router.h"
6c0a7c09 35#include "zebra/zebra_vrf.h"
00978977 36#include "zebra/zebra_srv6.h"
6c0a7c09
HS
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"
42
daedb8b3
HS
43#ifndef VTYSH_EXTRACT_PL
44#include "zebra/zebra_srv6_vty_clippy.c"
45#endif
46
6c0a7c09
HS
47static int zebra_sr_config(struct vty *vty);
48
49static struct cmd_node sr_node = {
50 .name = "sr",
51 .node = SEGMENT_ROUTING_NODE,
52 .parent_node = CONFIG_NODE,
53 .prompt = "%s(config-sr)# ",
54 .config_write = zebra_sr_config,
55};
56
57static struct cmd_node srv6_node = {
58 .name = "srv6",
59 .node = SRV6_NODE,
60 .parent_node = SEGMENT_ROUTING_NODE,
61 .prompt = "%s(config-srv6)# ",
62
63};
64
65static 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)# ",
70};
71
72static 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)# "
77};
78
00978977
HS
79DEFUN (show_srv6_locator,
80 show_srv6_locator_cmd,
81 "show segment-routing srv6 locator [json]",
82 SHOW_STR
83 "Segment Routing\n"
84 "Segment Routing SRv6\n"
85 "Locator Information\n"
86 JSON_STR)
87{
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;
92 char str[256];
93 int id;
94 json_object *json = NULL;
95 json_object *json_locators = NULL;
96 json_object *json_locator = NULL;
97
98 if (uj) {
99 json = json_object_new_object();
100 json_locators = json_object_new_array();
101 json_object_object_add(json, "locators", json_locators);
102
103 for (ALL_LIST_ELEMENTS_RO(srv6->locators, node, locator)) {
104 json_locator = srv6_locator_json(locator);
105 if (!json_locator)
106 continue;
107 json_object_array_add(json_locators, json_locator);
108
109 }
110
111 vty_out(vty, "%s\n", json_object_to_json_string_ext(json,
112 JSON_C_TO_STRING_PRETTY));
113 json_object_free(json);
114 } else {
115 vty_out(vty, "Locator:\n");
116 vty_out(vty, "Name ID Prefix Status\n");
117 vty_out(vty, "-------------------- ------- ------------------------ -------\n");
118
119 id = 1;
120 for (ALL_LIST_ELEMENTS_RO(srv6->locators, node, locator)) {
121 prefix2str(&locator->prefix, str, sizeof(str));
122 vty_out(vty, "%-20s %7d %-24s %s\n",
123 locator->name, id, str,
124 locator->status_up ? "Up" : "Down");
125 ++id;
126 }
127 vty_out(vty, "\n");
128 }
129
130 return CMD_SUCCESS;
131}
132
133DEFUN (show_srv6_locator_detail,
134 show_srv6_locator_detail_cmd,
135 "show segment-routing srv6 locator NAME detail [json]",
136 SHOW_STR
137 "Segment Routing\n"
138 "Segment Routing SRv6\n"
139 "Locator Information\n"
140 "Locator Name\n"
141 "Detailed information\n"
142 JSON_STR)
143{
144 const bool uj = use_json(argc, argv);
145 struct zebra_srv6 *srv6 = zebra_srv6_get_default();
146 struct srv6_locator *locator;
147 struct listnode *node;
148 char str[256];
149 const char *locator_name = argv[4]->arg;
150
151 if (uj) {
152 vty_out(vty, "JSON format isn't supported\n");
153 return CMD_WARNING;
4df9d859 154 }
00978977 155
4df9d859
HS
156 for (ALL_LIST_ELEMENTS_RO(srv6->locators, node, locator)) {
157 struct listnode *node;
158 struct srv6_locator_chunk *chunk;
159
160 if (strcmp(locator->name, locator_name) != 0)
161 continue;
162
163 prefix2str(&locator->prefix, str, sizeof(str));
164 vty_out(vty, "Name: %s\n", locator->name);
165 vty_out(vty, "Prefix: %s\n", str);
166 vty_out(vty, "Function-Bit-Len: %u\n",
167 locator->function_bits_length);
168
169 vty_out(vty, "Chunks:\n");
170 for (ALL_LIST_ELEMENTS_RO((struct list *)locator->chunks, node,
171 chunk)) {
172 prefix2str(&chunk->prefix, str, sizeof(str));
173 vty_out(vty, "- prefix: %s, owner: %s\n", str,
174 zebra_route_string(chunk->proto));
00978977 175 }
00978977
HS
176 }
177
4df9d859 178
00978977
HS
179 return CMD_SUCCESS;
180}
181
6c0a7c09
HS
182DEFUN_NOSH (segment_routing,
183 segment_routing_cmd,
184 "segment-routing",
185 "Segment Routing\n")
186{
187 vty->node = SEGMENT_ROUTING_NODE;
188 return CMD_SUCCESS;
189}
190
191DEFUN_NOSH (srv6,
192 srv6_cmd,
193 "srv6",
194 "Segment Routing SRv6\n")
195{
196 vty->node = SRV6_NODE;
197 return CMD_SUCCESS;
198}
199
200DEFUN_NOSH (srv6_locators,
201 srv6_locators_cmd,
202 "locators",
203 "Segment Routing SRv6 locators\n")
204{
205 vty->node = SRV6_LOCS_NODE;
206 return CMD_SUCCESS;
207}
208
209DEFUN_NOSH (srv6_locator,
210 srv6_locator_cmd,
211 "locator WORD",
212 "Segment Routing SRv6 locator\n"
213 "Specify locator-name\n")
214{
00978977
HS
215 struct srv6_locator *locator = NULL;
216
217 locator = zebra_srv6_locator_lookup(argv[1]->arg);
218 if (locator) {
219 VTY_PUSH_CONTEXT(SRV6_LOC_NODE, locator);
220 locator->status_up = true;
221 return CMD_SUCCESS;
222 }
223
224 locator = srv6_locator_alloc(argv[1]->arg);
225 if (!locator) {
226 vty_out(vty, "%% Alloc failed\n");
227 return CMD_WARNING_CONFIG_FAILED;
228 }
229 locator->status_up = true;
230
231 VTY_PUSH_CONTEXT(SRV6_LOC_NODE, locator);
6c0a7c09
HS
232 vty->node = SRV6_LOC_NODE;
233 return CMD_SUCCESS;
234}
235
daedb8b3 236DEFPY (locator_prefix,
00978977 237 locator_prefix_cmd,
daedb8b3 238 "prefix X:X::X:X/M$prefix [func-bits (16-64)$func_bit_len]",
00978977
HS
239 "Configure SRv6 locator prefix\n"
240 "Specify SRv6 locator prefix\n"
241 "Configure SRv6 locator function length in bits\n"
242 "Specify SRv6 locator function length in bits\n")
243{
244 VTY_DECLVAR_CONTEXT(srv6_locator, locator);
00978977
HS
245 struct srv6_locator_chunk *chunk = NULL;
246 struct listnode *node = NULL;
00978977 247
daedb8b3 248 locator->prefix = *prefix;
ac6a9479
HS
249
250 /*
251 * TODO(slankdev): please support variable node-bit-length.
252 * In draft-ietf-bess-srv6-services-05#section-3.2.1.
253 * Locator block length and Locator node length are defined.
254 * Which are defined as "locator-len == block-len + node-len".
255 * In current implementation, node bits length is hardcoded as 24.
256 * It should be supported various val.
257 *
258 * Cisco IOS-XR support only following pattern.
259 * (1) Teh locator length should be 64-bits long.
260 * (2) The SID block portion (MSBs) cannot exceed 40 bits.
261 * If this value is less than 40 bits,
262 * user should use a pattern of zeros as a filler.
263 * (3) The Node Id portion (LSBs) cannot exceed 24 bits.
264 */
265 locator->block_bits_length = prefix->prefixlen - 24;
266 locator->node_bits_length = 24;
daedb8b3 267 locator->function_bits_length = func_bit_len;
ac6a9479 268 locator->argument_bits_length = 0;
00978977
HS
269
270 if (list_isempty(locator->chunks)) {
271 chunk = srv6_locator_chunk_alloc();
daedb8b3 272 chunk->prefix = *prefix;
00978977
HS
273 chunk->proto = 0;
274 listnode_add(locator->chunks, chunk);
275 } else {
276 for (ALL_LIST_ELEMENTS_RO(locator->chunks, node, chunk)) {
277 uint8_t zero[16] = {0};
4df9d859 278
00978977
HS
279 if (memcmp(&chunk->prefix.prefix, zero, 16) == 0) {
280 struct zserv *client;
281 struct listnode *client_node;
4df9d859 282
daedb8b3 283 chunk->prefix = *prefix;
4df9d859
HS
284 for (ALL_LIST_ELEMENTS_RO(zrouter.client_list,
285 client_node,
286 client)) {
287 struct srv6_locator *tmp;
288
00978977
HS
289 if (client->proto != chunk->proto)
290 continue;
f29aed74 291
00978977 292 srv6_manager_get_locator_chunk_call(
4df9d859
HS
293 &tmp, client,
294 locator->name,
295 VRF_DEFAULT);
00978977
HS
296 }
297 }
298 }
299 }
300
301 zebra_srv6_locator_add(locator);
302 return CMD_SUCCESS;
303}
304
6c0a7c09
HS
305static int zebra_sr_config(struct vty *vty)
306{
00978977
HS
307 struct zebra_srv6 *srv6 = zebra_srv6_get_default();
308 struct listnode *node;
309 struct srv6_locator *locator;
310 char str[256];
311
312 vty_out(vty, "!\n");
313 if (zebra_srv6_is_enable()) {
314 vty_out(vty, "segment-routing\n");
315 vty_out(vty, " srv6\n");
316 vty_out(vty, " locators\n");
317 for (ALL_LIST_ELEMENTS_RO(srv6->locators, node, locator)) {
318 inet_ntop(AF_INET6, &locator->prefix.prefix,
319 str, sizeof(str));
320 vty_out(vty, " locator %s\n", locator->name);
321 vty_out(vty, " prefix %s/%u\n", str,
322 locator->prefix.prefixlen);
07679ad9 323 vty_out(vty, " exit\n");
00978977
HS
324 vty_out(vty, " !\n");
325 }
07679ad9 326 vty_out(vty, " exit\n");
00978977 327 vty_out(vty, " !\n");
07679ad9 328 vty_out(vty, " exit\n");
00978977 329 vty_out(vty, " !\n");
07679ad9 330 vty_out(vty, "exit\n");
00978977
HS
331 vty_out(vty, "!\n");
332 }
6c0a7c09
HS
333 return 0;
334}
335
336void zebra_srv6_vty_init(void)
337{
338 /* Install nodes and its default commands */
339 install_node(&sr_node);
340 install_node(&srv6_node);
341 install_node(&srv6_locs_node);
342 install_node(&srv6_loc_node);
343 install_default(SEGMENT_ROUTING_NODE);
344 install_default(SRV6_NODE);
345 install_default(SRV6_LOCS_NODE);
346 install_default(SRV6_LOC_NODE);
347
348 /* Command for change node */
349 install_element(CONFIG_NODE, &segment_routing_cmd);
350 install_element(SEGMENT_ROUTING_NODE, &srv6_cmd);
351 install_element(SRV6_NODE, &srv6_locators_cmd);
352 install_element(SRV6_LOCS_NODE, &srv6_locator_cmd);
00978977
HS
353
354 /* Command for configuration */
355 install_element(SRV6_LOC_NODE, &locator_prefix_cmd);
356
357 /* Command for operation */
358 install_element(VIEW_NODE, &show_srv6_locator_cmd);
359 install_element(VIEW_NODE, &show_srv6_locator_detail_cmd);
6c0a7c09 360}