3 * Copyright (C) Cumulus Networks, Inc.
6 * This file is part of FRR.
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
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.
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
31 #include "nexthop_group.h"
33 #include "sharpd/sharp_globals.h"
34 #include "sharpd/sharp_zebra.h"
35 #include "sharpd/sharp_nht.h"
36 #include "sharpd/sharp_vty.h"
37 #ifndef VTYSH_EXTRACT_PL
38 #include "sharpd/sharp_vty_clippy.c"
41 DEFPY(watch_nexthop_v6
, watch_nexthop_v6_cmd
,
42 "sharp watch [vrf NAME$vrf_name] <nexthop$n X:X::X:X$nhop|import$import X:X::X:X/M$inhop> [connected$connected]",
43 "Sharp routing Protocol\n"
45 "The vrf we would like to watch if non-default\n"
46 "The NAME of the vrf\n"
47 "Watch for nexthop changes\n"
48 "The v6 nexthop to signal for watching\n"
49 "Watch for import check changes\n"
50 "The v6 prefix to signal for watching\n"
51 "Should the route be connected\n")
58 vrf_name
= VRF_DEFAULT_NAME
;
59 vrf
= vrf_lookup_by_name(vrf_name
);
61 vty_out(vty
, "The vrf NAME specified: %s does not exist\n",
66 memset(&p
, 0, sizeof(p
));
71 memcpy(&p
.u
.prefix6
, &nhop
, 16);
75 p
= *(const struct prefix
*)inhop
;
78 sharp_nh_tracker_get(&p
);
79 sharp_zebra_nexthop_watch(&p
, vrf
->vrf_id
, type_import
,
85 DEFPY(watch_nexthop_v4
, watch_nexthop_v4_cmd
,
86 "sharp watch [vrf NAME$vrf_name] <nexthop$n A.B.C.D$nhop|import$import A.B.C.D/M$inhop> [connected$connected]",
87 "Sharp routing Protocol\n"
89 "The vrf we would like to watch if non-default\n"
90 "The NAME of the vrf\n"
91 "Watch for nexthop changes\n"
92 "The v4 address to signal for watching\n"
93 "Watch for import check changes\n"
94 "The v4 prefix for import check to watch\n"
95 "Should the route be connected\n")
102 vrf_name
= VRF_DEFAULT_NAME
;
103 vrf
= vrf_lookup_by_name(vrf_name
);
105 vty_out(vty
, "The vrf NAME specified: %s does not exist\n",
110 memset(&p
, 0, sizeof(p
));
120 p
= *(const struct prefix
*)inhop
;
123 sharp_nh_tracker_get(&p
);
124 sharp_zebra_nexthop_watch(&p
, vrf
->vrf_id
, type_import
,
130 DEFPY(sharp_nht_data_dump
,
131 sharp_nht_data_dump_cmd
,
132 "sharp data nexthop",
133 "Sharp routing Protocol\n"
134 "Nexthop information\n"
137 sharp_nh_tracker_dump(vty
);
142 DEFPY (install_routes_data_dump
,
143 install_routes_data_dump_cmd
,
145 "Sharp routing Protocol\n"
146 "Data about what is going on\n"
147 "Route Install/Removal Information\n")
149 char buf
[PREFIX_STRLEN
];
152 timersub(&sg
.r
.t_end
, &sg
.r
.t_start
, &r
);
153 vty_out(vty
, "Prefix: %s Total: %u %u %u Time: %jd.%ld\n",
154 prefix2str(&sg
.r
.orig_prefix
, buf
, sizeof(buf
)),
156 sg
.r
.installed_routes
,
158 (intmax_t)r
.tv_sec
, (long)r
.tv_usec
);
163 DEFPY (install_routes
,
165 "sharp install routes [vrf NAME$vrf_name]\
166 <A.B.C.D$start4|X:X::X:X$start6>\
167 <nexthop <A.B.C.D$nexthop4|X:X::X:X$nexthop6>|\
168 nexthop-group NHGNAME$nexthop_group>\
169 [backup$backup <A.B.C.D$backup_nexthop4|X:X::X:X$backup_nexthop6>] \
170 (1-1000000)$routes [instance (0-255)$instance] [repeat (2-1000)$rpt]",
171 "Sharp routing Protocol\n"
172 "install some routes\n"
173 "Routes to install\n"
174 "The vrf we would like to install into if non-default\n"
175 "The NAME of the vrf\n"
176 "v4 Address to start /32 generation at\n"
177 "v6 Address to start /32 generation at\n"
178 "Nexthop to use(Can be an IPv4 or IPv6 address)\n"
179 "V4 Nexthop address to use\n"
180 "V6 Nexthop address to use\n"
181 "Nexthop-Group to use\n"
182 "The Name of the nexthop-group\n"
183 "Backup nexthop to use(Can be an IPv4 or IPv6 address)\n"
184 "Backup V4 Nexthop address to use\n"
185 "Backup V6 Nexthop address to use\n"
186 "How many to create\n"
189 "Should we repeat this command\n"
190 "How many times to repeat this command\n")
193 struct prefix prefix
;
196 sg
.r
.total_routes
= routes
;
197 sg
.r
.installed_routes
= 0;
200 sg
.r
.repeat
= rpt
* 2;
204 memset(&prefix
, 0, sizeof(prefix
));
205 memset(&sg
.r
.orig_prefix
, 0, sizeof(sg
.r
.orig_prefix
));
206 memset(&sg
.r
.nhop
, 0, sizeof(sg
.r
.nhop
));
207 memset(&sg
.r
.nhop_group
, 0, sizeof(sg
.r
.nhop_group
));
208 memset(&sg
.r
.backup_nhop
, 0, sizeof(sg
.r
.nhop
));
209 memset(&sg
.r
.backup_nhop_group
, 0, sizeof(sg
.r
.nhop_group
));
211 if (start4
.s_addr
!= 0) {
212 prefix
.family
= AF_INET
;
213 prefix
.prefixlen
= 32;
214 prefix
.u
.prefix4
= start4
;
216 prefix
.family
= AF_INET6
;
217 prefix
.prefixlen
= 128;
218 prefix
.u
.prefix6
= start6
;
220 sg
.r
.orig_prefix
= prefix
;
223 vrf_name
= VRF_DEFAULT_NAME
;
225 vrf
= vrf_lookup_by_name(vrf_name
);
227 vty_out(vty
, "The vrf NAME specified: %s does not exist\n",
232 /* Explicit backup not available with named nexthop-group */
233 if (backup
&& nexthop_group
) {
234 vty_out(vty
, "%% Invalid: cannot specify both nexthop-group and backup\n");
239 struct nexthop_group_cmd
*nhgc
= nhgc_find(nexthop_group
);
242 "Specified Nexthop Group: %s does not exist\n",
247 sg
.r
.nhop_group
.nexthop
= nhgc
->nhg
.nexthop
;
249 /* Use group's backup nexthop info if present */
250 if (nhgc
->backup_list_name
[0]) {
251 struct nexthop_group_cmd
*bnhgc
=
252 nhgc_find(nhgc
->backup_list_name
);
255 vty_out(vty
, "%% Backup group %s not found for group %s\n",
256 nhgc
->backup_list_name
,
261 sg
.r
.backup_nhop
.vrf_id
= vrf
->vrf_id
;
262 sg
.r
.backup_nhop_group
.nexthop
= bnhgc
->nhg
.nexthop
;
265 if (nexthop4
.s_addr
!= INADDR_ANY
) {
266 sg
.r
.nhop
.gate
.ipv4
= nexthop4
;
267 sg
.r
.nhop
.type
= NEXTHOP_TYPE_IPV4
;
269 sg
.r
.nhop
.gate
.ipv6
= nexthop6
;
270 sg
.r
.nhop
.type
= NEXTHOP_TYPE_IPV6
;
273 sg
.r
.nhop
.vrf_id
= vrf
->vrf_id
;
274 sg
.r
.nhop_group
.nexthop
= &sg
.r
.nhop
;
277 /* Use single backup nexthop if specified */
279 /* Set flag and index in primary nexthop */
280 SET_FLAG(sg
.r
.nhop
.flags
, NEXTHOP_FLAG_HAS_BACKUP
);
281 sg
.r
.nhop
.backup_idx
= 0;
283 if (backup_nexthop4
.s_addr
!= INADDR_ANY
) {
284 sg
.r
.backup_nhop
.gate
.ipv4
= backup_nexthop4
;
285 sg
.r
.backup_nhop
.type
= NEXTHOP_TYPE_IPV4
;
287 sg
.r
.backup_nhop
.gate
.ipv6
= backup_nexthop6
;
288 sg
.r
.backup_nhop
.type
= NEXTHOP_TYPE_IPV6
;
291 sg
.r
.backup_nhop
.vrf_id
= vrf
->vrf_id
;
292 sg
.r
.backup_nhop_group
.nexthop
= &sg
.r
.backup_nhop
;
295 sg
.r
.inst
= instance
;
296 sg
.r
.vrf_id
= vrf
->vrf_id
;
298 sharp_install_routes_helper(&prefix
, sg
.r
.vrf_id
, sg
.r
.inst
,
299 &sg
.r
.nhop_group
, &sg
.r
.backup_nhop_group
,
305 DEFPY(vrf_label
, vrf_label_cmd
,
306 "sharp label <ip$ipv4|ipv6$ipv6> vrf NAME$vrf_name label (0-100000)$label",
307 "Sharp Routing Protocol\n"
308 "Give a vrf a label\n"
309 "Pop and forward for IPv4\n"
310 "Pop and forward for IPv6\n"
312 "The label to use, 0 specifies remove the label installed from previous\n"
313 "Specified range to use\n")
316 afi_t afi
= (ipv4
) ? AFI_IP
: AFI_IP6
;
318 if (strcmp(vrf_name
, "default") == 0)
319 vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
321 vrf
= vrf_lookup_by_name(vrf_name
);
324 vty_out(vty
, "Unable to find vrf you silly head");
325 return CMD_WARNING_CONFIG_FAILED
;
329 label
= MPLS_LABEL_NONE
;
331 vrf_label_add(vrf
->vrf_id
, afi
, label
);
335 DEFPY (remove_routes
,
337 "sharp remove routes [vrf NAME$vrf_name] <A.B.C.D$start4|X:X::X:X$start6> (1-1000000)$routes [instance (0-255)$instance]",
338 "Sharp Routing Protocol\n"
339 "Remove some routes\n"
341 "The vrf we would like to remove from if non-default\n"
342 "The NAME of the vrf\n"
345 "Routes to uninstall\n"
347 "Value of instance\n")
350 struct prefix prefix
;
352 sg
.r
.total_routes
= routes
;
353 sg
.r
.removed_routes
= 0;
356 memset(&prefix
, 0, sizeof(prefix
));
358 if (start4
.s_addr
!= 0) {
359 prefix
.family
= AF_INET
;
360 prefix
.prefixlen
= 32;
361 prefix
.u
.prefix4
= start4
;
363 prefix
.family
= AF_INET6
;
364 prefix
.prefixlen
= 128;
365 prefix
.u
.prefix6
= start6
;
368 vrf
= vrf_lookup_by_name(vrf_name
? vrf_name
: VRF_DEFAULT_NAME
);
370 vty_out(vty
, "The vrf NAME specified: %s does not exist\n",
371 vrf_name
? vrf_name
: VRF_DEFAULT_NAME
);
375 sg
.r
.inst
= instance
;
376 sg
.r
.vrf_id
= vrf
->vrf_id
;
378 sharp_remove_routes_helper(&prefix
, sg
.r
.vrf_id
,
384 DEFUN_NOSH (show_debugging_sharpd
,
385 show_debugging_sharpd_cmd
,
386 "show debugging [sharp]",
389 "Sharp Information\n")
391 vty_out(vty
, "Sharp debugging status:\n");
396 DEFPY(sharp_lsp_prefix_v4
, sharp_lsp_prefix_v4_cmd
,
397 "sharp lsp (0-100000)$inlabel\
398 nexthop-group NHGNAME$nhgname\
399 [prefix A.B.C.D/M$pfx\
400 " FRR_IP_REDIST_STR_ZEBRA
"$type_str [instance (0-255)$instance]]",
401 "Sharp Routing Protocol\n"
403 "The ingress label to use\n"
404 "Use nexthops from a nexthop-group\n"
405 "The nexthop-group name\n"
407 "The v4 prefix to label\n"
408 FRR_IP_REDIST_HELP_STR_ZEBRA
412 struct nexthop_group_cmd
*nhgc
= NULL
;
413 struct prefix p
= {};
416 /* We're offered a v4 prefix */
417 if (pfx
->family
> 0 && type_str
) {
418 p
.family
= pfx
->family
;
419 p
.prefixlen
= pfx
->prefixlen
;
420 p
.u
.prefix4
= pfx
->prefix
;
422 type
= proto_redistnum(AFI_IP
, type_str
);
424 vty_out(vty
, "%% Unknown route type '%s'\n", type_str
);
427 } else if (pfx
->family
> 0 || type_str
) {
428 vty_out(vty
, "%% Must supply both prefix and type\n");
432 nhgc
= nhgc_find(nhgname
);
434 vty_out(vty
, "%% Nexthop-group '%s' does not exist\n",
439 if (nhgc
->nhg
.nexthop
== NULL
) {
440 vty_out(vty
, "%% Nexthop-group '%s' is empty\n", nhgname
);
444 if (sharp_install_lsps_helper(true, pfx
->family
> 0 ? &p
: NULL
,
445 type
, instance
, inlabel
,
449 vty_out(vty
, "%% LSP install failed!\n");
454 DEFPY(sharp_remove_lsp_prefix_v4
, sharp_remove_lsp_prefix_v4_cmd
,
457 nexthop-group NHGNAME$nhgname\
458 [prefix A.B.C.D/M$pfx\
459 " FRR_IP_REDIST_STR_SHARPD
"$type_str [instance (0-255)$instance]]",
460 "Sharp Routing Protocol\n"
463 "The ingress label\n"
464 "Use nexthops from a nexthop-group\n"
465 "The nexthop-group name\n"
466 "Specify a v4 prefix\n"
467 "The v4 prefix to label\n"
468 FRR_IP_REDIST_HELP_STR_SHARPD
472 struct nexthop_group_cmd
*nhgc
= NULL
;
473 struct prefix p
= {};
476 /* We're offered a v4 prefix */
477 if (pfx
->family
> 0 && type_str
) {
478 p
.family
= pfx
->family
;
479 p
.prefixlen
= pfx
->prefixlen
;
480 p
.u
.prefix4
= pfx
->prefix
;
482 type
= proto_redistnum(AFI_IP
, type_str
);
484 vty_out(vty
, "%% Unknown route type '%s'\n", type_str
);
487 } else if (pfx
->family
> 0 || type_str
) {
488 vty_out(vty
, "%% Must supply both prefix and type\n");
492 nhgc
= nhgc_find(nhgname
);
494 vty_out(vty
, "%% Nexthop-group '%s' does not exist\n",
499 if (nhgc
->nhg
.nexthop
== NULL
) {
500 vty_out(vty
, "%% Nexthop-group '%s' is empty\n", nhgname
);
504 if (sharp_install_lsps_helper(false, pfx
->family
> 0 ? &p
: NULL
,
505 type
, instance
, inlabel
,
509 vty_out(vty
, "%% LSP remove failed!\n");
516 "sharp logpump duration (1-60) frequency (1-1000000) burst (1-1000)",
517 "Sharp Routing Protocol\n"
518 "Generate bulk log messages for testing\n"
519 "Duration of run (s)\n"
520 "Duration of run (s)\n"
521 "Frequency of bursts (s^-1)\n"
522 "Frequency of bursts (s^-1)\n"
523 "Number of log messages per each burst\n"
524 "Number of log messages per each burst\n")
526 sharp_logpump_run(vty
, duration
, frequency
, burst
);
530 void sharp_vty_init(void)
532 install_element(ENABLE_NODE
, &install_routes_data_dump_cmd
);
533 install_element(ENABLE_NODE
, &install_routes_cmd
);
534 install_element(ENABLE_NODE
, &remove_routes_cmd
);
535 install_element(ENABLE_NODE
, &vrf_label_cmd
);
536 install_element(ENABLE_NODE
, &sharp_nht_data_dump_cmd
);
537 install_element(ENABLE_NODE
, &watch_nexthop_v6_cmd
);
538 install_element(ENABLE_NODE
, &watch_nexthop_v4_cmd
);
539 install_element(ENABLE_NODE
, &sharp_lsp_prefix_v4_cmd
);
540 install_element(ENABLE_NODE
, &sharp_remove_lsp_prefix_v4_cmd
);
541 install_element(ENABLE_NODE
, &logpump_cmd
);
543 install_element(VIEW_NODE
, &show_debugging_sharpd_cmd
);