]> git.proxmox.com Git - mirror_frr.git/blob - sharpd/sharp_vty.c
Merge pull request #7245 from donaldsharp/ospf_coverity
[mirror_frr.git] / sharpd / sharp_vty.c
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"
29 #include "vrf.h"
30 #include "zclient.h"
31 #include "nexthop_group.h"
32
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"
39 #endif
40
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"
44 "Watch for changes\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")
52 {
53 struct vrf *vrf;
54 struct prefix p;
55 bool type_import;
56
57 if (!vrf_name)
58 vrf_name = VRF_DEFAULT_NAME;
59 vrf = vrf_lookup_by_name(vrf_name);
60 if (!vrf) {
61 vty_out(vty, "The vrf NAME specified: %s does not exist\n",
62 vrf_name);
63 return CMD_WARNING;
64 }
65
66 memset(&p, 0, sizeof(p));
67
68 if (n) {
69 type_import = false;
70 p.prefixlen = 128;
71 memcpy(&p.u.prefix6, &nhop, 16);
72 p.family = AF_INET6;
73 } else {
74 type_import = true;
75 p = *(const struct prefix *)inhop;
76 }
77
78 sharp_nh_tracker_get(&p);
79 sharp_zebra_nexthop_watch(&p, vrf->vrf_id, type_import,
80 true, !!connected);
81
82 return CMD_SUCCESS;
83 }
84
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"
88 "Watch for changes\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")
96 {
97 struct vrf *vrf;
98 struct prefix p;
99 bool type_import;
100
101 if (!vrf_name)
102 vrf_name = VRF_DEFAULT_NAME;
103 vrf = vrf_lookup_by_name(vrf_name);
104 if (!vrf) {
105 vty_out(vty, "The vrf NAME specified: %s does not exist\n",
106 vrf_name);
107 return CMD_WARNING;
108 }
109
110 memset(&p, 0, sizeof(p));
111
112 if (n) {
113 type_import = false;
114 p.prefixlen = 32;
115 p.u.prefix4 = nhop;
116 p.family = AF_INET;
117 }
118 else {
119 type_import = true;
120 p = *(const struct prefix *)inhop;
121 }
122
123 sharp_nh_tracker_get(&p);
124 sharp_zebra_nexthop_watch(&p, vrf->vrf_id, type_import,
125 true, !!connected);
126
127 return CMD_SUCCESS;
128 }
129
130 DEFPY(sharp_nht_data_dump,
131 sharp_nht_data_dump_cmd,
132 "sharp data nexthop",
133 "Sharp routing Protocol\n"
134 "Data about what is going on\n"
135 "Nexthop information\n")
136 {
137 sharp_nh_tracker_dump(vty);
138
139 return CMD_SUCCESS;
140 }
141
142 DEFPY (install_routes_data_dump,
143 install_routes_data_dump_cmd,
144 "sharp data route",
145 "Sharp routing Protocol\n"
146 "Data about what is going on\n"
147 "Route Install/Removal Information\n")
148 {
149 char buf[PREFIX_STRLEN];
150 struct timeval r;
151
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)),
155 sg.r.total_routes,
156 sg.r.installed_routes,
157 sg.r.removed_routes,
158 (intmax_t)r.tv_sec, (long)r.tv_usec);
159
160 return CMD_SUCCESS;
161 }
162
163 DEFPY (install_routes,
164 install_routes_cmd,
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"
187 "Instance to use\n"
188 "Instance\n"
189 "Should we repeat this command\n"
190 "How many times to repeat this command\n")
191 {
192 struct vrf *vrf;
193 struct prefix prefix;
194 uint32_t rts;
195 uint32_t nhgid = 0;
196
197 sg.r.total_routes = routes;
198 sg.r.installed_routes = 0;
199
200 if (rpt >= 2)
201 sg.r.repeat = rpt * 2;
202 else
203 sg.r.repeat = 0;
204
205 memset(&prefix, 0, sizeof(prefix));
206 memset(&sg.r.orig_prefix, 0, sizeof(sg.r.orig_prefix));
207 memset(&sg.r.nhop, 0, sizeof(sg.r.nhop));
208 memset(&sg.r.nhop_group, 0, sizeof(sg.r.nhop_group));
209 memset(&sg.r.backup_nhop, 0, sizeof(sg.r.nhop));
210 memset(&sg.r.backup_nhop_group, 0, sizeof(sg.r.nhop_group));
211
212 if (start4.s_addr != 0) {
213 prefix.family = AF_INET;
214 prefix.prefixlen = 32;
215 prefix.u.prefix4 = start4;
216 } else {
217 prefix.family = AF_INET6;
218 prefix.prefixlen = 128;
219 prefix.u.prefix6 = start6;
220 }
221 sg.r.orig_prefix = prefix;
222
223 if (!vrf_name)
224 vrf_name = VRF_DEFAULT_NAME;
225
226 vrf = vrf_lookup_by_name(vrf_name);
227 if (!vrf) {
228 vty_out(vty, "The vrf NAME specified: %s does not exist\n",
229 vrf_name);
230 return CMD_WARNING;
231 }
232
233 /* Explicit backup not available with named nexthop-group */
234 if (backup && nexthop_group) {
235 vty_out(vty, "%% Invalid: cannot specify both nexthop-group and backup\n");
236 return CMD_WARNING;
237 }
238
239 if (nexthop_group) {
240 struct nexthop_group_cmd *nhgc = nhgc_find(nexthop_group);
241 if (!nhgc) {
242 vty_out(vty,
243 "Specified Nexthop Group: %s does not exist\n",
244 nexthop_group);
245 return CMD_WARNING;
246 }
247
248 nhgid = sharp_nhgroup_get_id(nexthop_group);
249 sg.r.nhgid = nhgid;
250 sg.r.nhop_group.nexthop = nhgc->nhg.nexthop;
251
252 /* Use group's backup nexthop info if present */
253 if (nhgc->backup_list_name[0]) {
254 struct nexthop_group_cmd *bnhgc =
255 nhgc_find(nhgc->backup_list_name);
256
257 if (!bnhgc) {
258 vty_out(vty, "%% Backup group %s not found for group %s\n",
259 nhgc->backup_list_name,
260 nhgc->name);
261 return CMD_WARNING;
262 }
263
264 sg.r.backup_nhop.vrf_id = vrf->vrf_id;
265 sg.r.backup_nhop_group.nexthop = bnhgc->nhg.nexthop;
266 }
267 } else {
268 if (nexthop4.s_addr != INADDR_ANY) {
269 sg.r.nhop.gate.ipv4 = nexthop4;
270 sg.r.nhop.type = NEXTHOP_TYPE_IPV4;
271 } else {
272 sg.r.nhop.gate.ipv6 = nexthop6;
273 sg.r.nhop.type = NEXTHOP_TYPE_IPV6;
274 }
275
276 sg.r.nhop.vrf_id = vrf->vrf_id;
277 sg.r.nhop_group.nexthop = &sg.r.nhop;
278 }
279
280 /* Use single backup nexthop if specified */
281 if (backup) {
282 /* Set flag and index in primary nexthop */
283 SET_FLAG(sg.r.nhop.flags, NEXTHOP_FLAG_HAS_BACKUP);
284 sg.r.nhop.backup_num = 1;
285 sg.r.nhop.backup_idx[0] = 0;
286
287 if (backup_nexthop4.s_addr != INADDR_ANY) {
288 sg.r.backup_nhop.gate.ipv4 = backup_nexthop4;
289 sg.r.backup_nhop.type = NEXTHOP_TYPE_IPV4;
290 } else {
291 sg.r.backup_nhop.gate.ipv6 = backup_nexthop6;
292 sg.r.backup_nhop.type = NEXTHOP_TYPE_IPV6;
293 }
294
295 sg.r.backup_nhop.vrf_id = vrf->vrf_id;
296 sg.r.backup_nhop_group.nexthop = &sg.r.backup_nhop;
297 }
298
299 sg.r.inst = instance;
300 sg.r.vrf_id = vrf->vrf_id;
301 rts = routes;
302 sharp_install_routes_helper(&prefix, sg.r.vrf_id, sg.r.inst, nhgid,
303 &sg.r.nhop_group, &sg.r.backup_nhop_group,
304 rts);
305
306 return CMD_SUCCESS;
307 }
308
309 DEFPY(vrf_label, vrf_label_cmd,
310 "sharp label <ip$ipv4|ipv6$ipv6> vrf NAME$vrf_name label (0-100000)$label",
311 "Sharp Routing Protocol\n"
312 "Give a vrf a label\n"
313 "Pop and forward for IPv4\n"
314 "Pop and forward for IPv6\n"
315 VRF_CMD_HELP_STR
316 "The label to use, 0 specifies remove the label installed from previous\n"
317 "Specified range to use\n")
318 {
319 struct vrf *vrf;
320 afi_t afi = (ipv4) ? AFI_IP : AFI_IP6;
321
322 if (strcmp(vrf_name, "default") == 0)
323 vrf = vrf_lookup_by_id(VRF_DEFAULT);
324 else
325 vrf = vrf_lookup_by_name(vrf_name);
326
327 if (!vrf) {
328 vty_out(vty, "Unable to find vrf you silly head");
329 return CMD_WARNING_CONFIG_FAILED;
330 }
331
332 if (label == 0)
333 label = MPLS_LABEL_NONE;
334
335 vrf_label_add(vrf->vrf_id, afi, label);
336 return CMD_SUCCESS;
337 }
338
339 DEFPY (remove_routes,
340 remove_routes_cmd,
341 "sharp remove routes [vrf NAME$vrf_name] <A.B.C.D$start4|X:X::X:X$start6> (1-1000000)$routes [instance (0-255)$instance]",
342 "Sharp Routing Protocol\n"
343 "Remove some routes\n"
344 "Routes to remove\n"
345 "The vrf we would like to remove from if non-default\n"
346 "The NAME of the vrf\n"
347 "v4 Starting spot\n"
348 "v6 Starting spot\n"
349 "Routes to uninstall\n"
350 "instance to use\n"
351 "Value of instance\n")
352 {
353 struct vrf *vrf;
354 struct prefix prefix;
355
356 sg.r.total_routes = routes;
357 sg.r.removed_routes = 0;
358 uint32_t rts;
359
360 memset(&prefix, 0, sizeof(prefix));
361
362 if (start4.s_addr != 0) {
363 prefix.family = AF_INET;
364 prefix.prefixlen = 32;
365 prefix.u.prefix4 = start4;
366 } else {
367 prefix.family = AF_INET6;
368 prefix.prefixlen = 128;
369 prefix.u.prefix6 = start6;
370 }
371
372 vrf = vrf_lookup_by_name(vrf_name ? vrf_name : VRF_DEFAULT_NAME);
373 if (!vrf) {
374 vty_out(vty, "The vrf NAME specified: %s does not exist\n",
375 vrf_name ? vrf_name : VRF_DEFAULT_NAME);
376 return CMD_WARNING;
377 }
378
379 sg.r.inst = instance;
380 sg.r.vrf_id = vrf->vrf_id;
381 rts = routes;
382 sharp_remove_routes_helper(&prefix, sg.r.vrf_id,
383 sg.r.inst, rts);
384
385 return CMD_SUCCESS;
386 }
387
388 DEFUN_NOSH (show_debugging_sharpd,
389 show_debugging_sharpd_cmd,
390 "show debugging [sharp]",
391 SHOW_STR
392 DEBUG_STR
393 "Sharp Information\n")
394 {
395 vty_out(vty, "Sharp debugging status:\n");
396
397 return CMD_SUCCESS;
398 }
399
400 DEFPY (sharp_lsp_prefix_v4, sharp_lsp_prefix_v4_cmd,
401 "sharp lsp [update]$update (0-100000)$inlabel\
402 nexthop-group NHGNAME$nhgname\
403 [prefix A.B.C.D/M$pfx\
404 " FRR_IP_REDIST_STR_ZEBRA "$type_str [instance (0-255)$instance]]",
405 "Sharp Routing Protocol\n"
406 "Add an LSP\n"
407 "Update an LSP\n"
408 "The ingress label to use\n"
409 "Use nexthops from a nexthop-group\n"
410 "The nexthop-group name\n"
411 "Label a prefix\n"
412 "The v4 prefix to label\n"
413 FRR_IP_REDIST_HELP_STR_ZEBRA
414 "Instance to use\n"
415 "Instance\n")
416 {
417 struct nexthop_group_cmd *nhgc = NULL;
418 struct nexthop_group_cmd *backup_nhgc = NULL;
419 struct nexthop_group *backup_nhg = NULL;
420 struct prefix p = {};
421 int type = 0;
422 bool update_p;
423
424 update_p = (update != NULL);
425
426 /* We're offered a v4 prefix */
427 if (pfx->family > 0 && type_str) {
428 p.family = pfx->family;
429 p.prefixlen = pfx->prefixlen;
430 p.u.prefix4 = pfx->prefix;
431
432 type = proto_redistnum(AFI_IP, type_str);
433 if (type < 0) {
434 vty_out(vty, "%% Unknown route type '%s'\n", type_str);
435 return CMD_WARNING;
436 }
437 } else if (pfx->family > 0 || type_str) {
438 vty_out(vty, "%% Must supply both prefix and type\n");
439 return CMD_WARNING;
440 }
441
442 nhgc = nhgc_find(nhgname);
443 if (!nhgc) {
444 vty_out(vty, "%% Nexthop-group '%s' does not exist\n",
445 nhgname);
446 return CMD_WARNING;
447 }
448
449 if (nhgc->nhg.nexthop == NULL) {
450 vty_out(vty, "%% Nexthop-group '%s' is empty\n", nhgname);
451 return CMD_WARNING;
452 }
453
454 /* Use group's backup nexthop info if present */
455 if (nhgc->backup_list_name[0]) {
456 backup_nhgc = nhgc_find(nhgc->backup_list_name);
457
458 if (!backup_nhgc) {
459 vty_out(vty,
460 "%% Backup group %s not found for group %s\n",
461 nhgc->backup_list_name,
462 nhgname);
463 return CMD_WARNING;
464 }
465 backup_nhg = &(backup_nhgc->nhg);
466 }
467
468 if (sharp_install_lsps_helper(true /*install*/, update_p,
469 pfx->family > 0 ? &p : NULL,
470 type, instance, inlabel,
471 &(nhgc->nhg), backup_nhg) == 0)
472 return CMD_SUCCESS;
473 else {
474 vty_out(vty, "%% LSP install failed!\n");
475 return CMD_WARNING;
476 }
477 }
478
479 DEFPY(sharp_remove_lsp_prefix_v4, sharp_remove_lsp_prefix_v4_cmd,
480 "sharp remove lsp \
481 (0-100000)$inlabel\
482 [nexthop-group NHGNAME$nhgname] \
483 [prefix A.B.C.D/M$pfx\
484 " FRR_IP_REDIST_STR_SHARPD "$type_str [instance (0-255)$instance]]",
485 "Sharp Routing Protocol\n"
486 "Remove data\n"
487 "Remove an LSP\n"
488 "The ingress label\n"
489 "Use nexthops from a nexthop-group\n"
490 "The nexthop-group name\n"
491 "Specify a v4 prefix\n"
492 "The v4 prefix to label\n"
493 FRR_IP_REDIST_HELP_STR_SHARPD
494 "Routing instance\n"
495 "Instance to use\n")
496 {
497 struct nexthop_group_cmd *nhgc = NULL;
498 struct prefix p = {};
499 int type = 0;
500 struct nexthop_group *nhg = NULL;
501
502 /* We're offered a v4 prefix */
503 if (pfx->family > 0 && type_str) {
504 p.family = pfx->family;
505 p.prefixlen = pfx->prefixlen;
506 p.u.prefix4 = pfx->prefix;
507
508 type = proto_redistnum(AFI_IP, type_str);
509 if (type < 0) {
510 vty_out(vty, "%% Unknown route type '%s'\n", type_str);
511 return CMD_WARNING;
512 }
513 } else if (pfx->family > 0 || type_str) {
514 vty_out(vty, "%% Must supply both prefix and type\n");
515 return CMD_WARNING;
516 }
517
518 if (nhgname) {
519 nhgc = nhgc_find(nhgname);
520 if (!nhgc) {
521 vty_out(vty, "%% Nexthop-group '%s' does not exist\n",
522 nhgname);
523 return CMD_WARNING;
524 }
525
526 if (nhgc->nhg.nexthop == NULL) {
527 vty_out(vty, "%% Nexthop-group '%s' is empty\n",
528 nhgname);
529 return CMD_WARNING;
530 }
531 nhg = &(nhgc->nhg);
532 }
533
534 if (sharp_install_lsps_helper(false /*!install*/, false,
535 pfx->family > 0 ? &p : NULL,
536 type, instance, inlabel, nhg, NULL) == 0)
537 return CMD_SUCCESS;
538 else {
539 vty_out(vty, "%% LSP remove failed!\n");
540 return CMD_WARNING;
541 }
542 }
543
544 DEFPY (logpump,
545 logpump_cmd,
546 "sharp logpump duration (1-60) frequency (1-1000000) burst (1-1000)",
547 "Sharp Routing Protocol\n"
548 "Generate bulk log messages for testing\n"
549 "Duration of run (s)\n"
550 "Duration of run (s)\n"
551 "Frequency of bursts (s^-1)\n"
552 "Frequency of bursts (s^-1)\n"
553 "Number of log messages per each burst\n"
554 "Number of log messages per each burst\n")
555 {
556 sharp_logpump_run(vty, duration, frequency, burst);
557 return CMD_SUCCESS;
558 }
559
560 DEFPY (create_session,
561 create_session_cmd,
562 "sharp create session (1-1024)",
563 "Sharp Routing Protocol\n"
564 "Create data\n"
565 "Create a test session\n"
566 "Session ID\n")
567 {
568 if (sharp_zclient_create(session) != 0) {
569 vty_out(vty, "%% Client session error\n");
570 return CMD_WARNING;
571 }
572
573 return CMD_SUCCESS;
574 }
575
576 DEFPY (remove_session,
577 remove_session_cmd,
578 "sharp remove session (1-1024)",
579 "Sharp Routing Protocol\n"
580 "Remove data\n"
581 "Remove a test session\n"
582 "Session ID\n")
583 {
584 sharp_zclient_delete(session);
585 return CMD_SUCCESS;
586 }
587
588 DEFPY (send_opaque,
589 send_opaque_cmd,
590 "sharp send opaque type (1-255) (1-1000)$count",
591 SHARP_STR
592 "Send messages for testing\n"
593 "Send opaque messages\n"
594 "Type code to send\n"
595 "Type code to send\n"
596 "Number of messages to send\n")
597 {
598 sharp_opaque_send(type, 0, 0, 0, count);
599 return CMD_SUCCESS;
600 }
601
602 DEFPY (send_opaque_unicast,
603 send_opaque_unicast_cmd,
604 "sharp send opaque unicast type (1-255) \
605 " FRR_IP_REDIST_STR_ZEBRA "$proto_str \
606 [{instance (0-1000) | session (1-1000)}] (1-1000)$count",
607 SHARP_STR
608 "Send messages for testing\n"
609 "Send opaque messages\n"
610 "Send unicast messages\n"
611 "Type code to send\n"
612 "Type code to send\n"
613 FRR_IP_REDIST_HELP_STR_ZEBRA
614 "Daemon instance\n"
615 "Daemon instance\n"
616 "Session ID\n"
617 "Session ID\n"
618 "Number of messages to send\n")
619 {
620 uint32_t proto;
621
622 proto = proto_redistnum(AFI_IP, proto_str);
623
624 sharp_opaque_send(type, proto, instance, session, count);
625
626 return CMD_SUCCESS;
627 }
628
629 DEFPY (send_opaque_reg,
630 send_opaque_reg_cmd,
631 "sharp send opaque <reg$reg | unreg> \
632 " FRR_IP_REDIST_STR_ZEBRA "$proto_str \
633 [{instance (0-1000) | session (1-1000)}] type (1-1000)",
634 SHARP_STR
635 "Send messages for testing\n"
636 "Send opaque messages\n"
637 "Send opaque registration\n"
638 "Send opaque unregistration\n"
639 FRR_IP_REDIST_HELP_STR_ZEBRA
640 "Daemon instance\n"
641 "Daemon instance\n"
642 "Session ID\n"
643 "Session ID\n"
644 "Opaque sub-type code\n"
645 "Opaque sub-type code\n")
646 {
647 int proto;
648
649 proto = proto_redistnum(AFI_IP, proto_str);
650
651 sharp_opaque_reg_send((reg != NULL), proto, instance, session, type);
652 return CMD_SUCCESS;
653 }
654
655 DEFPY (neigh_discover,
656 neigh_discover_cmd,
657 "sharp neigh discover [vrf NAME$vrf_name] <A.B.C.D$dst4|X:X::X:X$dst6> IFNAME$ifname",
658 SHARP_STR
659 "Discover neighbours\n"
660 "Send an ARP/NDP request\n"
661 VRF_CMD_HELP_STR
662 "v4 Destination address\n"
663 "v6 Destination address\n"
664 "Interface name\n")
665 {
666 struct vrf *vrf;
667 struct interface *ifp;
668 struct prefix prefix;
669
670 memset(&prefix, 0, sizeof(prefix));
671
672 if (dst4.s_addr != 0) {
673 prefix.family = AF_INET;
674 prefix.prefixlen = 32;
675 prefix.u.prefix4 = dst4;
676 } else {
677 prefix.family = AF_INET6;
678 prefix.prefixlen = 128;
679 prefix.u.prefix6 = dst6;
680 }
681
682 vrf = vrf_lookup_by_name(vrf_name ? vrf_name : VRF_DEFAULT_NAME);
683 if (!vrf) {
684 vty_out(vty, "The vrf NAME specified: %s does not exist\n",
685 vrf_name ? vrf_name : VRF_DEFAULT_NAME);
686 return CMD_WARNING;
687 }
688
689 ifp = if_lookup_by_name_vrf(ifname, vrf);
690 if (ifp == NULL) {
691 vty_out(vty, "%% Can't find interface %s\n", ifname);
692 return CMD_WARNING;
693 }
694
695 sharp_zebra_send_arp(ifp, &prefix);
696
697 return CMD_SUCCESS;
698 }
699
700 void sharp_vty_init(void)
701 {
702 install_element(ENABLE_NODE, &install_routes_data_dump_cmd);
703 install_element(ENABLE_NODE, &install_routes_cmd);
704 install_element(ENABLE_NODE, &remove_routes_cmd);
705 install_element(ENABLE_NODE, &vrf_label_cmd);
706 install_element(ENABLE_NODE, &sharp_nht_data_dump_cmd);
707 install_element(ENABLE_NODE, &watch_nexthop_v6_cmd);
708 install_element(ENABLE_NODE, &watch_nexthop_v4_cmd);
709 install_element(ENABLE_NODE, &sharp_lsp_prefix_v4_cmd);
710 install_element(ENABLE_NODE, &sharp_remove_lsp_prefix_v4_cmd);
711 install_element(ENABLE_NODE, &logpump_cmd);
712 install_element(ENABLE_NODE, &create_session_cmd);
713 install_element(ENABLE_NODE, &remove_session_cmd);
714 install_element(ENABLE_NODE, &send_opaque_cmd);
715 install_element(ENABLE_NODE, &send_opaque_unicast_cmd);
716 install_element(ENABLE_NODE, &send_opaque_reg_cmd);
717 install_element(ENABLE_NODE, &neigh_discover_cmd);
718
719 install_element(ENABLE_NODE, &show_debugging_sharpd_cmd);
720
721 return;
722 }