]> git.proxmox.com Git - mirror_frr.git/blame - sharpd/sharp_vty.c
sharpd: Add call to CSPF
[mirror_frr.git] / sharpd / sharp_vty.c
CommitLineData
8a71d93d
DS
1/*
2 * SHARP - vty code
3 * Copyright (C) Cumulus Networks, Inc.
4 * Donald Sharp
5 *
6 * This file is part of FRR.
7 *
8 * FRR is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2, or (at your option) any
11 * later version.
12 *
13 * FRR is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; see the file COPYING; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22#include <zebra.h>
23
24#include "vty.h"
25#include "command.h"
26#include "prefix.h"
27#include "nexthop.h"
28#include "log.h"
ab18a495
DS
29#include "vrf.h"
30#include "zclient.h"
694b242f 31#include "nexthop_group.h"
621fb5f3 32#include "linklist.h"
1888e243 33#include "link_state.h"
621fb5f3 34#include "cspf.h"
8a71d93d 35
547dc642 36#include "sharpd/sharp_globals.h"
8a71d93d 37#include "sharpd/sharp_zebra.h"
86da53ab 38#include "sharpd/sharp_nht.h"
8a71d93d 39#include "sharpd/sharp_vty.h"
2e4c2296 40#ifndef VTYSH_EXTRACT_PL
8a71d93d 41#include "sharpd/sharp_vty_clippy.c"
2e4c2296 42#endif
8a71d93d 43
ade3eebc
HS
44DEFINE_MTYPE_STATIC(SHARPD, SRV6_LOCATOR, "SRv6 Locator");
45
921af54d
DS
46DEFPY(watch_redistribute, watch_redistribute_cmd,
47 "sharp watch [vrf NAME$vrf_name] redistribute " FRR_REDIST_STR_SHARPD,
48 "Sharp routing Protocol\n"
49 "Watch for changes\n"
50 "The vrf we would like to watch if non-default\n"
51 "The NAME of the vrf\n"
52 "Redistribute into Sharp\n"
53 FRR_REDIST_HELP_STR_SHARPD)
54{
55 struct vrf *vrf;
56 int source;
57
58 if (!vrf_name)
59 vrf_name = VRF_DEFAULT_NAME;
60 vrf = vrf_lookup_by_name(vrf_name);
61 if (!vrf) {
62 vty_out(vty, "The vrf NAME specified: %s does not exist\n",
63 vrf_name);
64 return CMD_WARNING;
65 }
66
67 source = proto_redistnum(AFI_IP, argv[argc-1]->text);
68 sharp_redistribute_vrf(vrf, source);
69
70 return CMD_SUCCESS;
71}
72
0ae8130d 73DEFPY(watch_nexthop_v6, watch_nexthop_v6_cmd,
e429a2a0 74 "sharp watch [vrf NAME$vrf_name] <nexthop$n X:X::X:X$nhop|import$import X:X::X:X/M$inhop> [connected$connected]",
0ae8130d
DS
75 "Sharp routing Protocol\n"
76 "Watch for changes\n"
a3b6aa82
DS
77 "The vrf we would like to watch if non-default\n"
78 "The NAME of the vrf\n"
0ae8130d 79 "Watch for nexthop changes\n"
a60ffbc9 80 "The v6 nexthop to signal for watching\n"
1be0815d
DS
81 "Watch for import check changes\n"
82 "The v6 prefix to signal for watching\n"
a60ffbc9 83 "Should the route be connected\n")
0ae8130d 84{
a3b6aa82 85 struct vrf *vrf;
0ae8130d 86 struct prefix p;
80d5ff33
DS
87 bool type_import;
88
e429a2a0
IR
89 if (!vrf_name)
90 vrf_name = VRF_DEFAULT_NAME;
91 vrf = vrf_lookup_by_name(vrf_name);
a3b6aa82
DS
92 if (!vrf) {
93 vty_out(vty, "The vrf NAME specified: %s does not exist\n",
e429a2a0 94 vrf_name);
a3b6aa82
DS
95 return CMD_WARNING;
96 }
80d5ff33 97
0ae8130d
DS
98 memset(&p, 0, sizeof(p));
99
1be0815d
DS
100 if (n) {
101 type_import = false;
13ccce6e 102 p.prefixlen = IPV6_MAX_BITLEN;
8643c2e5 103 memcpy(&p.u.prefix6, &nhop, IPV6_MAX_BYTELEN);
1be0815d
DS
104 p.family = AF_INET6;
105 } else {
106 type_import = true;
107 p = *(const struct prefix *)inhop;
108 }
0ae8130d 109
86da53ab 110 sharp_nh_tracker_get(&p);
a3b6aa82 111 sharp_zebra_nexthop_watch(&p, vrf->vrf_id, type_import,
91529dc8 112 true, !!connected);
0ae8130d
DS
113
114 return CMD_SUCCESS;
115}
116
117DEFPY(watch_nexthop_v4, watch_nexthop_v4_cmd,
e429a2a0 118 "sharp watch [vrf NAME$vrf_name] <nexthop$n A.B.C.D$nhop|import$import A.B.C.D/M$inhop> [connected$connected]",
0ae8130d
DS
119 "Sharp routing Protocol\n"
120 "Watch for changes\n"
a3b6aa82
DS
121 "The vrf we would like to watch if non-default\n"
122 "The NAME of the vrf\n"
0ae8130d 123 "Watch for nexthop changes\n"
1be0815d 124 "The v4 address to signal for watching\n"
80d5ff33 125 "Watch for import check changes\n"
1be0815d 126 "The v4 prefix for import check to watch\n"
a60ffbc9 127 "Should the route be connected\n")
0ae8130d 128{
a3b6aa82 129 struct vrf *vrf;
0ae8130d 130 struct prefix p;
80d5ff33 131 bool type_import;
0ae8130d 132
e429a2a0
IR
133 if (!vrf_name)
134 vrf_name = VRF_DEFAULT_NAME;
135 vrf = vrf_lookup_by_name(vrf_name);
a3b6aa82
DS
136 if (!vrf) {
137 vty_out(vty, "The vrf NAME specified: %s does not exist\n",
e429a2a0 138 vrf_name);
a3b6aa82
DS
139 return CMD_WARNING;
140 }
141
0ae8130d
DS
142 memset(&p, 0, sizeof(p));
143
1be0815d 144 if (n) {
80d5ff33 145 type_import = false;
12256b84 146 p.prefixlen = IPV4_MAX_BITLEN;
1be0815d
DS
147 p.u.prefix4 = nhop;
148 p.family = AF_INET;
149 }
150 else {
80d5ff33 151 type_import = true;
1be0815d
DS
152 p = *(const struct prefix *)inhop;
153 }
0ae8130d 154
86da53ab 155 sharp_nh_tracker_get(&p);
a3b6aa82 156 sharp_zebra_nexthop_watch(&p, vrf->vrf_id, type_import,
91529dc8 157 true, !!connected);
0ae8130d
DS
158
159 return CMD_SUCCESS;
160}
161
86da53ab
DS
162DEFPY(sharp_nht_data_dump,
163 sharp_nht_data_dump_cmd,
164 "sharp data nexthop",
165 "Sharp routing Protocol\n"
bcc519dc
DS
166 "Data about what is going on\n"
167 "Nexthop information\n")
86da53ab
DS
168{
169 sharp_nh_tracker_dump(vty);
170
171 return CMD_SUCCESS;
172}
173
f59e6418
DS
174DEFPY (install_routes_data_dump,
175 install_routes_data_dump_cmd,
176 "sharp data route",
177 "Sharp routing Protocol\n"
178 "Data about what is going on\n"
179 "Route Install/Removal Information\n")
180{
f59e6418
DS
181 struct timeval r;
182
183 timersub(&sg.r.t_end, &sg.r.t_start, &r);
2dbe669b
DA
184 vty_out(vty, "Prefix: %pFX Total: %u %u %u Time: %jd.%ld\n",
185 &sg.r.orig_prefix, sg.r.total_routes, sg.r.installed_routes,
186 sg.r.removed_routes, (intmax_t)r.tv_sec, (long)r.tv_usec);
f59e6418
DS
187
188 return CMD_SUCCESS;
189}
190
8a71d93d
DS
191DEFPY (install_routes,
192 install_routes_cmd,
1df3b1dc
MS
193 "sharp install routes [vrf NAME$vrf_name]\
194 <A.B.C.D$start4|X:X::X:X$start6>\
195 <nexthop <A.B.C.D$nexthop4|X:X::X:X$nexthop6>|\
1cb131ee 196 nexthop-group NHGNAME$nexthop_group>\
1df3b1dc 197 [backup$backup <A.B.C.D$backup_nexthop4|X:X::X:X$backup_nexthop6>] \
cfa2a35d 198 (1-1000000)$routes [instance (0-255)$instance] [repeat (2-1000)$rpt] [opaque WORD]",
75239f4f 199 "Sharp routing Protocol\n"
8a71d93d
DS
200 "install some routes\n"
201 "Routes to install\n"
4a7d4737
DS
202 "The vrf we would like to install into if non-default\n"
203 "The NAME of the vrf\n"
dbc1bf46
DS
204 "v4 Address to start /32 generation at\n"
205 "v6 Address to start /32 generation at\n"
ba041bea
DS
206 "Nexthop to use(Can be an IPv4 or IPv6 address)\n"
207 "V4 Nexthop address to use\n"
208 "V6 Nexthop address to use\n"
d4101c0a
DS
209 "Nexthop-Group to use\n"
210 "The Name of the nexthop-group\n"
1df3b1dc
MS
211 "Backup nexthop to use(Can be an IPv4 or IPv6 address)\n"
212 "Backup V4 Nexthop address to use\n"
213 "Backup V6 Nexthop address to use\n"
ae252c02
DS
214 "How many to create\n"
215 "Instance to use\n"
b939f6ff
DS
216 "Instance\n"
217 "Should we repeat this command\n"
cfa2a35d
DS
218 "How many times to repeat this command\n"
219 "What opaque data to send down\n"
220 "The opaque data\n")
8a71d93d 221{
4a7d4737 222 struct vrf *vrf;
547dc642
DS
223 struct prefix prefix;
224 uint32_t rts;
569e87c0 225 uint32_t nhgid = 0;
547dc642
DS
226
227 sg.r.total_routes = routes;
228 sg.r.installed_routes = 0;
8a71d93d 229
b939f6ff 230 if (rpt >= 2)
547dc642 231 sg.r.repeat = rpt * 2;
b939f6ff 232 else
547dc642 233 sg.r.repeat = 0;
b939f6ff
DS
234
235 memset(&prefix, 0, sizeof(prefix));
547dc642
DS
236 memset(&sg.r.orig_prefix, 0, sizeof(sg.r.orig_prefix));
237 memset(&sg.r.nhop, 0, sizeof(sg.r.nhop));
238 memset(&sg.r.nhop_group, 0, sizeof(sg.r.nhop_group));
1df3b1dc
MS
239 memset(&sg.r.backup_nhop, 0, sizeof(sg.r.nhop));
240 memset(&sg.r.backup_nhop_group, 0, sizeof(sg.r.nhop_group));
8a71d93d 241
3a6290bd 242 if (start4.s_addr != INADDR_ANY) {
dbc1bf46 243 prefix.family = AF_INET;
12256b84 244 prefix.prefixlen = IPV4_MAX_BITLEN;
dbc1bf46
DS
245 prefix.u.prefix4 = start4;
246 } else {
247 prefix.family = AF_INET6;
13ccce6e 248 prefix.prefixlen = IPV6_MAX_BITLEN;
dbc1bf46
DS
249 prefix.u.prefix6 = start6;
250 }
547dc642 251 sg.r.orig_prefix = prefix;
8a71d93d 252
e429a2a0
IR
253 if (!vrf_name)
254 vrf_name = VRF_DEFAULT_NAME;
a3b6aa82 255
e429a2a0 256 vrf = vrf_lookup_by_name(vrf_name);
4a7d4737
DS
257 if (!vrf) {
258 vty_out(vty, "The vrf NAME specified: %s does not exist\n",
e429a2a0 259 vrf_name);
4a7d4737
DS
260 return CMD_WARNING;
261 }
262
1df3b1dc
MS
263 /* Explicit backup not available with named nexthop-group */
264 if (backup && nexthop_group) {
265 vty_out(vty, "%% Invalid: cannot specify both nexthop-group and backup\n");
266 return CMD_WARNING;
267 }
268
d4101c0a
DS
269 if (nexthop_group) {
270 struct nexthop_group_cmd *nhgc = nhgc_find(nexthop_group);
271 if (!nhgc) {
272 vty_out(vty,
273 "Specified Nexthop Group: %s does not exist\n",
274 nexthop_group);
275 return CMD_WARNING;
276 }
277
569e87c0
DS
278 nhgid = sharp_nhgroup_get_id(nexthop_group);
279 sg.r.nhgid = nhgid;
547dc642 280 sg.r.nhop_group.nexthop = nhgc->nhg.nexthop;
1df3b1dc
MS
281
282 /* Use group's backup nexthop info if present */
283 if (nhgc->backup_list_name[0]) {
284 struct nexthop_group_cmd *bnhgc =
285 nhgc_find(nhgc->backup_list_name);
286
287 if (!bnhgc) {
288 vty_out(vty, "%% Backup group %s not found for group %s\n",
289 nhgc->backup_list_name,
290 nhgc->name);
291 return CMD_WARNING;
292 }
293
294 sg.r.backup_nhop.vrf_id = vrf->vrf_id;
295 sg.r.backup_nhop_group.nexthop = bnhgc->nhg.nexthop;
296 }
ba041bea 297 } else {
d4101c0a 298 if (nexthop4.s_addr != INADDR_ANY) {
547dc642
DS
299 sg.r.nhop.gate.ipv4 = nexthop4;
300 sg.r.nhop.type = NEXTHOP_TYPE_IPV4;
d4101c0a 301 } else {
547dc642
DS
302 sg.r.nhop.gate.ipv6 = nexthop6;
303 sg.r.nhop.type = NEXTHOP_TYPE_IPV6;
d4101c0a
DS
304 }
305
4a7d4737 306 sg.r.nhop.vrf_id = vrf->vrf_id;
547dc642 307 sg.r.nhop_group.nexthop = &sg.r.nhop;
ba041bea 308 }
8a71d93d 309
1df3b1dc
MS
310 /* Use single backup nexthop if specified */
311 if (backup) {
312 /* Set flag and index in primary nexthop */
313 SET_FLAG(sg.r.nhop.flags, NEXTHOP_FLAG_HAS_BACKUP);
474aebd9
MS
314 sg.r.nhop.backup_num = 1;
315 sg.r.nhop.backup_idx[0] = 0;
1df3b1dc
MS
316
317 if (backup_nexthop4.s_addr != INADDR_ANY) {
318 sg.r.backup_nhop.gate.ipv4 = backup_nexthop4;
319 sg.r.backup_nhop.type = NEXTHOP_TYPE_IPV4;
320 } else {
321 sg.r.backup_nhop.gate.ipv6 = backup_nexthop6;
322 sg.r.backup_nhop.type = NEXTHOP_TYPE_IPV6;
323 }
324
325 sg.r.backup_nhop.vrf_id = vrf->vrf_id;
326 sg.r.backup_nhop_group.nexthop = &sg.r.backup_nhop;
327 }
328
cfa2a35d
DS
329 if (opaque)
330 strlcpy(sg.r.opaque, opaque, ZAPI_MESSAGE_OPAQUE_LENGTH);
331 else
332 sg.r.opaque[0] = '\0';
333
547dc642 334 sg.r.inst = instance;
4a7d4737 335 sg.r.vrf_id = vrf->vrf_id;
b939f6ff 336 rts = routes;
ff9aca4f
SW
337 sharp_install_routes_helper(&prefix, sg.r.vrf_id, sg.r.inst, nhgid,
338 &sg.r.nhop_group, &sg.r.backup_nhop_group,
1cb131ee
HS
339 rts, 0, sg.r.opaque);
340
341 return CMD_SUCCESS;
342}
343
344DEFPY (install_seg6_routes,
345 install_seg6_routes_cmd,
346 "sharp install seg6-routes [vrf NAME$vrf_name]\
347 <A.B.C.D$start4|X:X::X:X$start6>\
348 nexthop-seg6 X:X::X:X$seg6_nh6 encap X:X::X:X$seg6_seg\
349 (1-1000000)$routes [repeat (2-1000)$rpt]",
350 "Sharp routing Protocol\n"
351 "install some routes\n"
352 "Routes to install\n"
353 "The vrf we would like to install into if non-default\n"
354 "The NAME of the vrf\n"
355 "v4 Address to start /32 generation at\n"
356 "v6 Address to start /32 generation at\n"
357 "Nexthop-seg6 to use\n"
358 "V6 Nexthop address to use\n"
359 "Encap mode\n"
360 "Segment List to use\n"
361 "How many to create\n"
362 "Should we repeat this command\n"
363 "How many times to repeat this command\n")
364{
365 struct vrf *vrf;
366 struct prefix prefix;
367 uint32_t route_flags = 0;
368
369 sg.r.total_routes = routes;
370 sg.r.installed_routes = 0;
371
372 if (rpt >= 2)
373 sg.r.repeat = rpt * 2;
374 else
375 sg.r.repeat = 0;
376
377 memset(&prefix, 0, sizeof(prefix));
378 memset(&sg.r.orig_prefix, 0, sizeof(sg.r.orig_prefix));
379 memset(&sg.r.nhop, 0, sizeof(sg.r.nhop));
380 memset(&sg.r.nhop_group, 0, sizeof(sg.r.nhop_group));
381 memset(&sg.r.backup_nhop, 0, sizeof(sg.r.nhop));
382 memset(&sg.r.backup_nhop_group, 0, sizeof(sg.r.nhop_group));
383 sg.r.opaque[0] = '\0';
384 sg.r.inst = 0;
385
386 if (start4.s_addr != INADDR_ANY) {
387 prefix.family = AF_INET;
12256b84 388 prefix.prefixlen = IPV4_MAX_BITLEN;
1cb131ee
HS
389 prefix.u.prefix4 = start4;
390 } else {
391 prefix.family = AF_INET6;
13ccce6e 392 prefix.prefixlen = IPV6_MAX_BITLEN;
1cb131ee
HS
393 prefix.u.prefix6 = start6;
394 }
395 sg.r.orig_prefix = prefix;
396
397 if (!vrf_name)
398 vrf_name = VRF_DEFAULT_NAME;
399
400 vrf = vrf_lookup_by_name(vrf_name);
401 if (!vrf) {
402 vty_out(vty, "The vrf NAME specified: %s does not exist\n",
403 vrf_name);
404 return CMD_WARNING;
405 }
406
407 sg.r.nhop.type = NEXTHOP_TYPE_IPV6;
408 sg.r.nhop.gate.ipv6 = seg6_nh6;
409 sg.r.nhop.vrf_id = vrf->vrf_id;
410 sg.r.nhop_group.nexthop = &sg.r.nhop;
eab0f8f0 411 nexthop_add_srv6_seg6(&sg.r.nhop, &seg6_seg);
1cb131ee
HS
412
413 sg.r.vrf_id = vrf->vrf_id;
414 sharp_install_routes_helper(&prefix, sg.r.vrf_id, sg.r.inst, 0,
415 &sg.r.nhop_group, &sg.r.backup_nhop_group,
416 routes, route_flags, sg.r.opaque);
417
418 return CMD_SUCCESS;
419}
420
421DEFPY (install_seg6local_routes,
422 install_seg6local_routes_cmd,
423 "sharp install seg6local-routes [vrf NAME$vrf_name]\
424 X:X::X:X$start6\
425 nexthop-seg6local NAME$seg6l_oif\
426 <End$seg6l_end|\
427 End_X$seg6l_endx X:X::X:X$seg6l_endx_nh6|\
428 End_T$seg6l_endt (1-4294967295)$seg6l_endt_table|\
429 End_DX4$seg6l_enddx4 A.B.C.D$seg6l_enddx4_nh4|\
430 End_DT6$seg6l_enddt6 (1-4294967295)$seg6l_enddt6_table>\
431 (1-1000000)$routes [repeat (2-1000)$rpt]",
432 "Sharp routing Protocol\n"
433 "install some routes\n"
434 "Routes to install\n"
435 "The vrf we would like to install into if non-default\n"
436 "The NAME of the vrf\n"
437 "v6 Address to start /32 generation at\n"
438 "Nexthop-seg6local to use\n"
439 "Output device to use\n"
440 "SRv6 End function to use\n"
441 "SRv6 End.X function to use\n"
442 "V6 Nexthop address to use\n"
443 "SRv6 End.T function to use\n"
444 "Redirect table id to use\n"
445 "SRv6 End.DX4 function to use\n"
446 "V4 Nexthop address to use\n"
447 "SRv6 End.DT6 function to use\n"
448 "Redirect table id to use\n"
449 "How many to create\n"
450 "Should we repeat this command\n"
451 "How many times to repeat this command\n")
452{
453 struct vrf *vrf;
454 uint32_t route_flags = 0;
455 struct seg6local_context ctx = {};
456 enum seg6local_action_t action;
457
458 sg.r.total_routes = routes;
459 sg.r.installed_routes = 0;
460
461 if (rpt >= 2)
462 sg.r.repeat = rpt * 2;
463 else
464 sg.r.repeat = 0;
465
466 memset(&sg.r.orig_prefix, 0, sizeof(sg.r.orig_prefix));
467 memset(&sg.r.nhop, 0, sizeof(sg.r.nhop));
468 memset(&sg.r.nhop_group, 0, sizeof(sg.r.nhop_group));
469 memset(&sg.r.backup_nhop, 0, sizeof(sg.r.nhop));
470 memset(&sg.r.backup_nhop_group, 0, sizeof(sg.r.nhop_group));
471 sg.r.opaque[0] = '\0';
472 sg.r.inst = 0;
473 sg.r.orig_prefix.family = AF_INET6;
474 sg.r.orig_prefix.prefixlen = 128;
475 sg.r.orig_prefix.u.prefix6 = start6;
476
477 if (!vrf_name)
478 vrf_name = VRF_DEFAULT_NAME;
479
480 vrf = vrf_lookup_by_name(vrf_name);
481 if (!vrf) {
482 vty_out(vty, "The vrf NAME specified: %s does not exist\n",
483 vrf_name);
484 return CMD_WARNING;
485 }
486
487 if (seg6l_enddx4) {
488 action = ZEBRA_SEG6_LOCAL_ACTION_END_DX4;
489 ctx.nh4 = seg6l_enddx4_nh4;
490 } else if (seg6l_endx) {
491 action = ZEBRA_SEG6_LOCAL_ACTION_END_X;
492 ctx.nh6 = seg6l_endx_nh6;
493 } else if (seg6l_endt) {
494 action = ZEBRA_SEG6_LOCAL_ACTION_END_T;
495 ctx.table = seg6l_endt_table;
496 } else if (seg6l_enddt6) {
497 action = ZEBRA_SEG6_LOCAL_ACTION_END_DT6;
498 ctx.table = seg6l_enddt6_table;
499 } else {
500 action = ZEBRA_SEG6_LOCAL_ACTION_END;
501 }
502
503 sg.r.nhop.type = NEXTHOP_TYPE_IFINDEX;
504 sg.r.nhop.ifindex = ifname2ifindex(seg6l_oif, vrf->vrf_id);
505 sg.r.nhop.vrf_id = vrf->vrf_id;
506 sg.r.nhop_group.nexthop = &sg.r.nhop;
eab0f8f0 507 nexthop_add_srv6_seg6local(&sg.r.nhop, action, &ctx);
1cb131ee
HS
508
509 sg.r.vrf_id = vrf->vrf_id;
2ba6be5b
HS
510 sharp_install_routes_helper(&sg.r.orig_prefix, sg.r.vrf_id, sg.r.inst,
511 0, &sg.r.nhop_group,
512 &sg.r.backup_nhop_group, routes,
513 route_flags, sg.r.opaque);
8a71d93d
DS
514
515 return CMD_SUCCESS;
516}
517
42567e00 518DEFPY(vrf_label, vrf_label_cmd,
e429a2a0 519 "sharp label <ip$ipv4|ipv6$ipv6> vrf NAME$vrf_name label (0-100000)$label",
75239f4f 520 "Sharp Routing Protocol\n"
ab18a495 521 "Give a vrf a label\n"
7d061b3c
DS
522 "Pop and forward for IPv4\n"
523 "Pop and forward for IPv6\n"
ab18a495 524 VRF_CMD_HELP_STR
42567e00 525 "The label to use, 0 specifies remove the label installed from previous\n"
ab18a495
DS
526 "Specified range to use\n")
527{
528 struct vrf *vrf;
7d061b3c 529 afi_t afi = (ipv4) ? AFI_IP : AFI_IP6;
ab18a495 530
e429a2a0 531 if (strcmp(vrf_name, "default") == 0)
ab18a495
DS
532 vrf = vrf_lookup_by_id(VRF_DEFAULT);
533 else
e429a2a0 534 vrf = vrf_lookup_by_name(vrf_name);
ab18a495
DS
535
536 if (!vrf) {
537 vty_out(vty, "Unable to find vrf you silly head");
538 return CMD_WARNING_CONFIG_FAILED;
539 }
540
42567e00
DS
541 if (label == 0)
542 label = MPLS_LABEL_NONE;
543
7d061b3c 544 vrf_label_add(vrf->vrf_id, afi, label);
ab18a495
DS
545 return CMD_SUCCESS;
546}
547
8a71d93d
DS
548DEFPY (remove_routes,
549 remove_routes_cmd,
e429a2a0 550 "sharp remove routes [vrf NAME$vrf_name] <A.B.C.D$start4|X:X::X:X$start6> (1-1000000)$routes [instance (0-255)$instance]",
75239f4f 551 "Sharp Routing Protocol\n"
8a71d93d
DS
552 "Remove some routes\n"
553 "Routes to remove\n"
4a7d4737
DS
554 "The vrf we would like to remove from if non-default\n"
555 "The NAME of the vrf\n"
e310fc19
DS
556 "v4 Starting spot\n"
557 "v6 Starting spot\n"
558 "Routes to uninstall\n"
ae252c02
DS
559 "instance to use\n"
560 "Value of instance\n")
8a71d93d 561{
4a7d4737 562 struct vrf *vrf;
547dc642
DS
563 struct prefix prefix;
564
565 sg.r.total_routes = routes;
566 sg.r.removed_routes = 0;
567 uint32_t rts;
8a71d93d 568
b939f6ff 569 memset(&prefix, 0, sizeof(prefix));
8a71d93d 570
3a6290bd 571 if (start4.s_addr != INADDR_ANY) {
dbc1bf46 572 prefix.family = AF_INET;
12256b84 573 prefix.prefixlen = IPV4_MAX_BITLEN;
dbc1bf46
DS
574 prefix.u.prefix4 = start4;
575 } else {
576 prefix.family = AF_INET6;
13ccce6e 577 prefix.prefixlen = IPV6_MAX_BITLEN;
dbc1bf46
DS
578 prefix.u.prefix6 = start6;
579 }
8a71d93d 580
e429a2a0 581 vrf = vrf_lookup_by_name(vrf_name ? vrf_name : VRF_DEFAULT_NAME);
4a7d4737
DS
582 if (!vrf) {
583 vty_out(vty, "The vrf NAME specified: %s does not exist\n",
e429a2a0 584 vrf_name ? vrf_name : VRF_DEFAULT_NAME);
4a7d4737
DS
585 return CMD_WARNING;
586 }
587
547dc642 588 sg.r.inst = instance;
4a7d4737 589 sg.r.vrf_id = vrf->vrf_id;
b939f6ff 590 rts = routes;
0cf08685
DS
591 sharp_remove_routes_helper(&prefix, sg.r.vrf_id,
592 sg.r.inst, rts);
8a71d93d
DS
593
594 return CMD_SUCCESS;
595}
596
aaf8c96f
DS
597DEFUN_NOSH (show_debugging_sharpd,
598 show_debugging_sharpd_cmd,
599 "show debugging [sharp]",
600 SHOW_STR
601 DEBUG_STR
602 "Sharp Information\n")
603{
c9e5adba 604 vty_out(vty, "Sharp debugging status:\n");
aaf8c96f
DS
605
606 return CMD_SUCCESS;
607}
608
faa75dfa
MS
609DEFPY (sharp_lsp_prefix_v4, sharp_lsp_prefix_v4_cmd,
610 "sharp lsp [update]$update (0-100000)$inlabel\
c9e5adba
MS
611 nexthop-group NHGNAME$nhgname\
612 [prefix A.B.C.D/M$pfx\
4b0f6237 613 " FRR_IP_REDIST_STR_ZEBRA "$type_str [instance (0-255)$instance]]",
faa75dfa
MS
614 "Sharp Routing Protocol\n"
615 "Add an LSP\n"
616 "Update an LSP\n"
617 "The ingress label to use\n"
618 "Use nexthops from a nexthop-group\n"
619 "The nexthop-group name\n"
620 "Label a prefix\n"
621 "The v4 prefix to label\n"
622 FRR_IP_REDIST_HELP_STR_ZEBRA
623 "Instance to use\n"
624 "Instance\n")
c9e5adba
MS
625{
626 struct nexthop_group_cmd *nhgc = NULL;
665edffd
MS
627 struct nexthop_group_cmd *backup_nhgc = NULL;
628 struct nexthop_group *backup_nhg = NULL;
c9e5adba
MS
629 struct prefix p = {};
630 int type = 0;
faa75dfa
MS
631 bool update_p;
632
633 update_p = (update != NULL);
c9e5adba
MS
634
635 /* We're offered a v4 prefix */
636 if (pfx->family > 0 && type_str) {
637 p.family = pfx->family;
638 p.prefixlen = pfx->prefixlen;
639 p.u.prefix4 = pfx->prefix;
640
641 type = proto_redistnum(AFI_IP, type_str);
642 if (type < 0) {
643 vty_out(vty, "%% Unknown route type '%s'\n", type_str);
644 return CMD_WARNING;
645 }
646 } else if (pfx->family > 0 || type_str) {
647 vty_out(vty, "%% Must supply both prefix and type\n");
648 return CMD_WARNING;
649 }
650
651 nhgc = nhgc_find(nhgname);
652 if (!nhgc) {
653 vty_out(vty, "%% Nexthop-group '%s' does not exist\n",
654 nhgname);
655 return CMD_WARNING;
656 }
657
658 if (nhgc->nhg.nexthop == NULL) {
659 vty_out(vty, "%% Nexthop-group '%s' is empty\n", nhgname);
660 return CMD_WARNING;
661 }
662
665edffd
MS
663 /* Use group's backup nexthop info if present */
664 if (nhgc->backup_list_name[0]) {
665 backup_nhgc = nhgc_find(nhgc->backup_list_name);
666
667 if (!backup_nhgc) {
668 vty_out(vty,
669 "%% Backup group %s not found for group %s\n",
670 nhgc->backup_list_name,
671 nhgname);
672 return CMD_WARNING;
673 }
674 backup_nhg = &(backup_nhgc->nhg);
675 }
676
faa75dfa
MS
677 if (sharp_install_lsps_helper(true /*install*/, update_p,
678 pfx->family > 0 ? &p : NULL,
c9e5adba 679 type, instance, inlabel,
665edffd 680 &(nhgc->nhg), backup_nhg) == 0)
c9e5adba
MS
681 return CMD_SUCCESS;
682 else {
683 vty_out(vty, "%% LSP install failed!\n");
684 return CMD_WARNING;
685 }
686}
687
688DEFPY(sharp_remove_lsp_prefix_v4, sharp_remove_lsp_prefix_v4_cmd,
689 "sharp remove lsp \
690 (0-100000)$inlabel\
665edffd 691 [nexthop-group NHGNAME$nhgname] \
c9e5adba 692 [prefix A.B.C.D/M$pfx\
20c9e649 693 " FRR_IP_REDIST_STR_ZEBRA "$type_str [instance (0-255)$instance]]",
c9e5adba
MS
694 "Sharp Routing Protocol\n"
695 "Remove data\n"
696 "Remove an LSP\n"
697 "The ingress label\n"
698 "Use nexthops from a nexthop-group\n"
699 "The nexthop-group name\n"
700 "Specify a v4 prefix\n"
701 "The v4 prefix to label\n"
20c9e649 702 FRR_IP_REDIST_HELP_STR_ZEBRA
c9e5adba
MS
703 "Routing instance\n"
704 "Instance to use\n")
705{
706 struct nexthop_group_cmd *nhgc = NULL;
707 struct prefix p = {};
708 int type = 0;
665edffd 709 struct nexthop_group *nhg = NULL;
c9e5adba
MS
710
711 /* We're offered a v4 prefix */
712 if (pfx->family > 0 && type_str) {
713 p.family = pfx->family;
714 p.prefixlen = pfx->prefixlen;
715 p.u.prefix4 = pfx->prefix;
716
717 type = proto_redistnum(AFI_IP, type_str);
718 if (type < 0) {
719 vty_out(vty, "%% Unknown route type '%s'\n", type_str);
720 return CMD_WARNING;
721 }
722 } else if (pfx->family > 0 || type_str) {
723 vty_out(vty, "%% Must supply both prefix and type\n");
724 return CMD_WARNING;
725 }
726
665edffd
MS
727 if (nhgname) {
728 nhgc = nhgc_find(nhgname);
729 if (!nhgc) {
730 vty_out(vty, "%% Nexthop-group '%s' does not exist\n",
731 nhgname);
732 return CMD_WARNING;
733 }
c9e5adba 734
665edffd
MS
735 if (nhgc->nhg.nexthop == NULL) {
736 vty_out(vty, "%% Nexthop-group '%s' is empty\n",
737 nhgname);
738 return CMD_WARNING;
739 }
740 nhg = &(nhgc->nhg);
c9e5adba
MS
741 }
742
faa75dfa
MS
743 if (sharp_install_lsps_helper(false /*!install*/, false,
744 pfx->family > 0 ? &p : NULL,
665edffd 745 type, instance, inlabel, nhg, NULL) == 0)
c9e5adba
MS
746 return CMD_SUCCESS;
747 else {
748 vty_out(vty, "%% LSP remove failed!\n");
749 return CMD_WARNING;
750 }
751}
752
aef4a13f
DL
753DEFPY (logpump,
754 logpump_cmd,
755 "sharp logpump duration (1-60) frequency (1-1000000) burst (1-1000)",
756 "Sharp Routing Protocol\n"
757 "Generate bulk log messages for testing\n"
758 "Duration of run (s)\n"
759 "Duration of run (s)\n"
760 "Frequency of bursts (s^-1)\n"
761 "Frequency of bursts (s^-1)\n"
762 "Number of log messages per each burst\n"
763 "Number of log messages per each burst\n")
764{
765 sharp_logpump_run(vty, duration, frequency, burst);
766 return CMD_SUCCESS;
767}
768
2be4d61a
MS
769DEFPY (create_session,
770 create_session_cmd,
771 "sharp create session (1-1024)",
772 "Sharp Routing Protocol\n"
773 "Create data\n"
774 "Create a test session\n"
775 "Session ID\n")
776{
777 if (sharp_zclient_create(session) != 0) {
778 vty_out(vty, "%% Client session error\n");
779 return CMD_WARNING;
780 }
781
782 return CMD_SUCCESS;
783}
784
785DEFPY (remove_session,
786 remove_session_cmd,
787 "sharp remove session (1-1024)",
788 "Sharp Routing Protocol\n"
789 "Remove data\n"
790 "Remove a test session\n"
791 "Session ID\n")
792{
793 sharp_zclient_delete(session);
794 return CMD_SUCCESS;
795}
796
2ac6c90d
MS
797DEFPY (send_opaque,
798 send_opaque_cmd,
799 "sharp send opaque type (1-255) (1-1000)$count",
478ff17b 800 SHARP_STR
2ac6c90d
MS
801 "Send messages for testing\n"
802 "Send opaque messages\n"
803 "Type code to send\n"
804 "Type code to send\n"
805 "Number of messages to send\n")
806{
c8b27f2a
MS
807 sharp_opaque_send(type, 0, 0, 0, count);
808 return CMD_SUCCESS;
809}
810
811DEFPY (send_opaque_unicast,
812 send_opaque_unicast_cmd,
813 "sharp send opaque unicast type (1-255) \
814 " FRR_IP_REDIST_STR_ZEBRA "$proto_str \
815 [{instance (0-1000) | session (1-1000)}] (1-1000)$count",
816 SHARP_STR
817 "Send messages for testing\n"
818 "Send opaque messages\n"
819 "Send unicast messages\n"
820 "Type code to send\n"
821 "Type code to send\n"
822 FRR_IP_REDIST_HELP_STR_ZEBRA
823 "Daemon instance\n"
824 "Daemon instance\n"
825 "Session ID\n"
826 "Session ID\n"
827 "Number of messages to send\n")
828{
829 uint32_t proto;
830
831 proto = proto_redistnum(AFI_IP, proto_str);
832
833 sharp_opaque_send(type, proto, instance, session, count);
834
2ac6c90d
MS
835 return CMD_SUCCESS;
836}
837
939b2339
MS
838DEFPY (send_opaque_reg,
839 send_opaque_reg_cmd,
840 "sharp send opaque <reg$reg | unreg> \
841 " FRR_IP_REDIST_STR_ZEBRA "$proto_str \
842 [{instance (0-1000) | session (1-1000)}] type (1-1000)",
478ff17b 843 SHARP_STR
939b2339
MS
844 "Send messages for testing\n"
845 "Send opaque messages\n"
846 "Send opaque registration\n"
847 "Send opaque unregistration\n"
848 FRR_IP_REDIST_HELP_STR_ZEBRA
849 "Daemon instance\n"
850 "Daemon instance\n"
851 "Session ID\n"
852 "Session ID\n"
853 "Opaque sub-type code\n"
854 "Opaque sub-type code\n")
855{
856 int proto;
857
858 proto = proto_redistnum(AFI_IP, proto_str);
859
860 sharp_opaque_reg_send((reg != NULL), proto, instance, session, type);
861 return CMD_SUCCESS;
862}
863
da187b77
JU
864DEFPY (neigh_discover,
865 neigh_discover_cmd,
866 "sharp neigh discover [vrf NAME$vrf_name] <A.B.C.D$dst4|X:X::X:X$dst6> IFNAME$ifname",
867 SHARP_STR
868 "Discover neighbours\n"
869 "Send an ARP/NDP request\n"
870 VRF_CMD_HELP_STR
871 "v4 Destination address\n"
872 "v6 Destination address\n"
873 "Interface name\n")
874{
875 struct vrf *vrf;
876 struct interface *ifp;
877 struct prefix prefix;
878
879 memset(&prefix, 0, sizeof(prefix));
880
3a6290bd 881 if (dst4.s_addr != INADDR_ANY) {
da187b77 882 prefix.family = AF_INET;
12256b84 883 prefix.prefixlen = IPV4_MAX_BITLEN;
da187b77
JU
884 prefix.u.prefix4 = dst4;
885 } else {
886 prefix.family = AF_INET6;
887 prefix.prefixlen = 128;
888 prefix.u.prefix6 = dst6;
889 }
890
891 vrf = vrf_lookup_by_name(vrf_name ? vrf_name : VRF_DEFAULT_NAME);
892 if (!vrf) {
893 vty_out(vty, "The vrf NAME specified: %s does not exist\n",
894 vrf_name ? vrf_name : VRF_DEFAULT_NAME);
895 return CMD_WARNING;
896 }
897
898 ifp = if_lookup_by_name_vrf(ifname, vrf);
899 if (ifp == NULL) {
900 vty_out(vty, "%% Can't find interface %s\n", ifname);
901 return CMD_WARNING;
902 }
903
904 sharp_zebra_send_arp(ifp, &prefix);
905
906 return CMD_SUCCESS;
907}
908
1888e243
OD
909DEFPY (import_te,
910 import_te_cmd,
911 "sharp import-te",
912 SHARP_STR
913 "Import Traffic Engineering\n")
914{
915 sg.ted = ls_ted_new(1, "Sharp", 0);
916 sharp_zebra_register_te();
917
918 return CMD_SUCCESS;
919}
920
ade3eebc
HS
921DEFPY (sharp_srv6_manager_get_locator_chunk,
922 sharp_srv6_manager_get_locator_chunk_cmd,
923 "sharp srv6-manager get-locator-chunk NAME$locator_name",
924 SHARP_STR
925 "Segment-Routing IPv6\n"
926 "Get SRv6 locator-chunk\n"
927 "SRv6 Locator name\n")
928{
929 int ret;
930 struct listnode *node;
931 struct sharp_srv6_locator *loc;
932 struct sharp_srv6_locator *loc_found = NULL;
933
934 for (ALL_LIST_ELEMENTS_RO(sg.srv6_locators, node, loc)) {
935 if (strcmp(loc->name, locator_name))
936 continue;
937 loc_found = loc;
938 break;
939 }
940 if (!loc_found) {
941 loc = XCALLOC(MTYPE_SRV6_LOCATOR,
942 sizeof(struct sharp_srv6_locator));
943 loc->chunks = list_new();
944 snprintf(loc->name, SRV6_LOCNAME_SIZE, "%s", locator_name);
945 listnode_add(sg.srv6_locators, loc);
946 }
947
948 ret = sharp_zebra_srv6_manager_get_locator_chunk(locator_name);
949 if (ret < 0)
950 return CMD_WARNING_CONFIG_FAILED;
951
952 return CMD_SUCCESS;
953}
954
1888e243
OD
955DEFUN (show_sharp_ted,
956 show_sharp_ted_cmd,
957 "show sharp ted [<vertex [A.B.C.D]|edge [A.B.C.D]|subnet [A.B.C.D/M]>] [verbose|json]",
958 SHOW_STR
959 SHARP_STR
960 "Traffic Engineering Database\n"
961 "MPLS-TE Vertex\n"
962 "MPLS-TE router ID (as an IP address)\n"
963 "MPLS-TE Edge\n"
964 "MPLS-TE Edge ID (as an IP address)\n"
965 "MPLS-TE Subnet\n"
966 "MPLS-TE Subnet ID (as an IP prefix)\n"
967 "Verbose output\n"
968 JSON_STR)
969{
970 int idx = 0;
971 struct in_addr ip_addr;
972 struct prefix pref;
973 struct ls_vertex *vertex;
974 struct ls_edge *edge;
975 struct ls_subnet *subnet;
976 uint64_t key;
977 bool verbose = false;
978 bool uj = use_json(argc, argv);
979 json_object *json = NULL;
980
981 if (sg.ted == NULL) {
982 vty_out(vty, "MPLS-TE import is not enabled\n");
983 return CMD_WARNING;
984 }
985
986 if (uj)
987 json = json_object_new_object();
988
989 if (argv[argc - 1]->arg && strmatch(argv[argc - 1]->text, "verbose"))
990 verbose = true;
991
992 if (argv_find(argv, argc, "vertex", &idx)) {
993 /* Show Vertex */
994 if (argv_find(argv, argc, "A.B.C.D", &idx)) {
995 if (!inet_aton(argv[idx + 1]->arg, &ip_addr)) {
996 vty_out(vty,
997 "Specified Router ID %s is invalid\n",
998 argv[idx + 1]->arg);
999 return CMD_WARNING_CONFIG_FAILED;
1000 }
1001 /* Get the Vertex from the Link State Database */
1002 key = ((uint64_t)ip_addr.s_addr) & 0xffffffff;
1003 vertex = ls_find_vertex_by_key(sg.ted, key);
1004 if (!vertex) {
1005 vty_out(vty, "No vertex found for ID %pI4\n",
1006 &ip_addr);
1007 return CMD_WARNING;
1008 }
1009 } else
1010 vertex = NULL;
1011
1012 if (vertex)
1013 ls_show_vertex(vertex, vty, json, verbose);
1014 else
1015 ls_show_vertices(sg.ted, vty, json, verbose);
1016
1017 } else if (argv_find(argv, argc, "edge", &idx)) {
1018 /* Show Edge */
1019 if (argv_find(argv, argc, "A.B.C.D", &idx)) {
1020 if (!inet_aton(argv[idx]->arg, &ip_addr)) {
1021 vty_out(vty,
1022 "Specified Edge ID %s is invalid\n",
1023 argv[idx]->arg);
1024 return CMD_WARNING_CONFIG_FAILED;
1025 }
1026 /* Get the Edge from the Link State Database */
1027 key = ((uint64_t)ip_addr.s_addr) & 0xffffffff;
1028 edge = ls_find_edge_by_key(sg.ted, key);
1029 if (!edge) {
1030 vty_out(vty, "No edge found for ID %pI4\n",
1031 &ip_addr);
1032 return CMD_WARNING;
1033 }
1034 } else
1035 edge = NULL;
1036
1037 if (edge)
1038 ls_show_edge(edge, vty, json, verbose);
1039 else
1040 ls_show_edges(sg.ted, vty, json, verbose);
1041
1042 } else if (argv_find(argv, argc, "subnet", &idx)) {
1043 /* Show Subnet */
1044 if (argv_find(argv, argc, "A.B.C.D/M", &idx)) {
1045 if (!str2prefix(argv[idx]->arg, &pref)) {
1046 vty_out(vty, "Invalid prefix format %s\n",
1047 argv[idx]->arg);
1048 return CMD_WARNING_CONFIG_FAILED;
1049 }
1050 /* Get the Subnet from the Link State Database */
1051 subnet = ls_find_subnet(sg.ted, pref);
1052 if (!subnet) {
1053 vty_out(vty, "No subnet found for ID %pFX\n",
1054 &pref);
1055 return CMD_WARNING;
1056 }
1057 } else
1058 subnet = NULL;
1059
1060 if (subnet)
1061 ls_show_subnet(subnet, vty, json, verbose);
1062 else
1063 ls_show_subnets(sg.ted, vty, json, verbose);
1064
1065 } else {
1066 /* Show the complete TED */
1067 ls_show_ted(sg.ted, vty, json, verbose);
1068 }
1069
c48349e3 1070 if (uj)
7297350e 1071 vty_json(vty, json);
ade3eebc
HS
1072
1073 return CMD_SUCCESS;
1074}
1075
1076DEFPY (sharp_srv6_manager_release_locator_chunk,
1077 sharp_srv6_manager_release_locator_chunk_cmd,
1078 "sharp srv6-manager release-locator-chunk NAME$locator_name",
1079 SHARP_STR
1080 "Segment-Routing IPv6\n"
1081 "Release SRv6 locator-chunk\n"
1082 "SRv6 Locator name\n")
1083{
1084 int ret;
1085 struct listnode *loc_node;
1086 struct sharp_srv6_locator *loc;
1087
1088 for (ALL_LIST_ELEMENTS_RO(sg.srv6_locators, loc_node, loc)) {
1089 if (!strcmp(loc->name, locator_name)) {
1090 list_delete_all_node(loc->chunks);
1091 list_delete(&loc->chunks);
1092 listnode_delete(sg.srv6_locators, loc);
1093 break;
1094 }
1095 }
1096
1097 ret = sharp_zebra_srv6_manager_release_locator_chunk(locator_name);
1098 if (ret < 0)
1099 return CMD_WARNING_CONFIG_FAILED;
1100
1101 return CMD_SUCCESS;
1102}
1103
1104DEFPY (show_sharp_segment_routing_srv6,
1105 show_sharp_segment_routing_srv6_cmd,
a2df1e4f 1106 "show sharp segment-routing srv6 [json]",
ade3eebc
HS
1107 SHOW_STR
1108 SHARP_STR
1109 "Segment-Routing\n"
a2df1e4f
HS
1110 "Segment-Routing IPv6\n"
1111 JSON_STR)
ade3eebc
HS
1112{
1113 char str[256];
1114 struct listnode *loc_node;
1115 struct listnode *chunk_node;
1116 struct sharp_srv6_locator *loc;
1117 struct prefix_ipv6 *chunk;
a2df1e4f 1118 bool uj = use_json(argc, argv);
ade3eebc
HS
1119 json_object *jo_locs = NULL;
1120 json_object *jo_loc = NULL;
1121 json_object *jo_chunks = NULL;
1122
a2df1e4f
HS
1123 if (uj) {
1124 jo_locs = json_object_new_array();
1125 for (ALL_LIST_ELEMENTS_RO(sg.srv6_locators, loc_node, loc)) {
1126 jo_loc = json_object_new_object();
1127 json_object_array_add(jo_locs, jo_loc);
1128 json_object_string_add(jo_loc, "name", loc->name);
1129 jo_chunks = json_object_new_array();
1130 json_object_object_add(jo_loc, "chunks", jo_chunks);
1131 for (ALL_LIST_ELEMENTS_RO(loc->chunks, chunk_node,
1132 chunk)) {
1133 prefix2str(chunk, str, sizeof(str));
1134 json_array_string_add(jo_chunks, str);
1135 }
1136 }
1137
7297350e 1138 vty_json(vty, jo_locs);
a2df1e4f
HS
1139 } else {
1140 for (ALL_LIST_ELEMENTS_RO(sg.srv6_locators, loc_node, loc)) {
1141 vty_out(vty, "Locator %s has %d prefix chunks\n",
1142 loc->name, listcount(loc->chunks));
1143 for (ALL_LIST_ELEMENTS_RO(loc->chunks, chunk_node,
1144 chunk)) {
1145 prefix2str(chunk, str, sizeof(str));
1146 vty_out(vty, " %s\n", str);
1147 }
1148 vty_out(vty, "\n");
ade3eebc
HS
1149 }
1150 }
1151
1888e243
OD
1152 return CMD_SUCCESS;
1153}
1154
621fb5f3
OD
1155DEFPY (show_sharp_cspf,
1156 show_sharp_cspf_cmd,
1157 "show sharp cspf source <A.B.C.D$src4|X:X::X:X$src6> \
1158 destination <A.B.C.D$dst4|X:X::X:X$dst6> \
1159 <metric|te-metric|delay> (0-16777215)$cost \
1160 [rsv-bw (0-7)$cos BANDWIDTH$bw]",
1161 SHOW_STR
1162 SHARP_STR
1163 "Constraint Shortest Path First path computation\n"
1164 "Source of the path\n"
1165 "IPv4 Source address in dot decimal A.B.C.D\n"
1166 "IPv6 Source address as X:X:X:X\n"
1167 "Destination of the path\n"
1168 "IPv4 Destination address in dot decimal A.B.C.D\n"
1169 "IPv6 Destination address as X:X:X:X\n"
1170 "Maximum Metric\n"
1171 "Maximum TE Metric\n"
1172 "Maxim Delay\n"
1173 "Value of Maximum cost\n"
1174 "Reserved Bandwidth of this path\n"
1175 "Class of Service or Priority level\n"
1176 "Bytes/second (IEEE floating point format)\n")
1177{
1178
1179 struct cspf *algo;
1180 struct constraints csts;
1181 struct c_path *path;
1182 struct listnode *node;
1183 struct ls_edge *edge;
1184 int idx;
1185
1186 if (sg.ted == NULL) {
1187 vty_out(vty, "MPLS-TE import is not enabled\n");
1188 return CMD_WARNING;
1189 }
1190
1191 if ((src4.s_addr != INADDR_ANY && dst4.s_addr == INADDR_ANY) ||
1192 (src4.s_addr == INADDR_ANY && dst4.s_addr != INADDR_ANY)) {
1193 vty_out(vty, "Don't mix IPv4 and IPv6 addresses\n");
1194 return CMD_WARNING;
1195 }
1196
1197 idx = 6;
1198 memset(&csts, 0, sizeof(struct constraints));
1199 if (argv_find(argv, argc, "metric", &idx)) {
1200 csts.ctype = CSPF_METRIC;
1201 csts.cost = cost;
1202 }
1203 idx = 6;
1204 if (argv_find(argv, argc, "te-metric", &idx)) {
1205 csts.ctype = CSPF_TE_METRIC;
1206 csts.cost = cost;
1207 }
1208 idx = 6;
1209 if (argv_find(argv, argc, "delay", &idx)) {
1210 csts.ctype = CSPF_DELAY;
1211 csts.cost = cost;
1212 }
1213 if (argc > 9) {
1214 if (sscanf(bw, "%g", &csts.bw) != 1) {
1215 vty_out(vty, "Bandwidth constraints: fscanf: %s\n",
1216 safe_strerror(errno));
1217 return CMD_WARNING_CONFIG_FAILED;
1218 }
1219 csts.cos = cos;
1220 }
1221
1222 /* Initialize and call point-to-point Path computation */
1223 if (src4.s_addr != INADDR_ANY)
1224 algo = cspf_init_v4(NULL, sg.ted, src4, dst4, &csts);
1225 else
1226 algo = cspf_init_v6(NULL, sg.ted, src6, dst6, &csts);
1227 path = compute_p2p_path(algo, sg.ted);
1228 cspf_del(algo);
1229
1230 if (!path) {
1231 vty_out(vty, "Path computation failed without error\n");
1232 return CMD_SUCCESS;
1233 }
1234 if (path->status != SUCCESS) {
1235 vty_out(vty, "Path computation failed: %d\n", path->status);
1236 return CMD_SUCCESS;
1237 }
1238
1239 vty_out(vty, "Path computation success\n");
1240 vty_out(vty, "\tCost: %d\n", path->weight);
1241 vty_out(vty, "\tEdges:");
1242 for (ALL_LIST_ELEMENTS_RO(path->edges, node, edge)) {
1243 if (src4.s_addr != INADDR_ANY)
1244 vty_out(vty, " %pI4",
1245 &edge->attributes->standard.remote);
1246 else
1247 vty_out(vty, " %pI6",
1248 &edge->attributes->standard.remote6);
1249 }
1250 vty_out(vty, "\n");
1251
1252 return CMD_SUCCESS;
1253}
1254
8a71d93d
DS
1255void sharp_vty_init(void)
1256{
f59e6418 1257 install_element(ENABLE_NODE, &install_routes_data_dump_cmd);
8a71d93d 1258 install_element(ENABLE_NODE, &install_routes_cmd);
1cb131ee
HS
1259 install_element(ENABLE_NODE, &install_seg6_routes_cmd);
1260 install_element(ENABLE_NODE, &install_seg6local_routes_cmd);
8a71d93d 1261 install_element(ENABLE_NODE, &remove_routes_cmd);
ab18a495 1262 install_element(ENABLE_NODE, &vrf_label_cmd);
86da53ab 1263 install_element(ENABLE_NODE, &sharp_nht_data_dump_cmd);
921af54d 1264 install_element(ENABLE_NODE, &watch_redistribute_cmd);
0ae8130d
DS
1265 install_element(ENABLE_NODE, &watch_nexthop_v6_cmd);
1266 install_element(ENABLE_NODE, &watch_nexthop_v4_cmd);
c9e5adba
MS
1267 install_element(ENABLE_NODE, &sharp_lsp_prefix_v4_cmd);
1268 install_element(ENABLE_NODE, &sharp_remove_lsp_prefix_v4_cmd);
aef4a13f 1269 install_element(ENABLE_NODE, &logpump_cmd);
2be4d61a
MS
1270 install_element(ENABLE_NODE, &create_session_cmd);
1271 install_element(ENABLE_NODE, &remove_session_cmd);
2ac6c90d 1272 install_element(ENABLE_NODE, &send_opaque_cmd);
c8b27f2a 1273 install_element(ENABLE_NODE, &send_opaque_unicast_cmd);
939b2339 1274 install_element(ENABLE_NODE, &send_opaque_reg_cmd);
da187b77 1275 install_element(ENABLE_NODE, &neigh_discover_cmd);
1888e243 1276 install_element(ENABLE_NODE, &import_te_cmd);
aaf8c96f 1277
dd73744d 1278 install_element(ENABLE_NODE, &show_debugging_sharpd_cmd);
1888e243 1279 install_element(ENABLE_NODE, &show_sharp_ted_cmd);
621fb5f3 1280 install_element(ENABLE_NODE, &show_sharp_cspf_cmd);
aaf8c96f 1281
ade3eebc 1282 install_element(ENABLE_NODE, &sharp_srv6_manager_get_locator_chunk_cmd);
4df9d859
HS
1283 install_element(ENABLE_NODE,
1284 &sharp_srv6_manager_release_locator_chunk_cmd);
ade3eebc
HS
1285 install_element(ENABLE_NODE, &show_sharp_segment_routing_srv6_cmd);
1286
8a71d93d
DS
1287 return;
1288}