3 * Copyright (C) 2018-2019 Cumulus Networks, Inc.
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 #include "lib/command.h"
24 #include "lib/ipaddr.h"
26 #include "lib/prefix.h"
27 #include "lib/termtable.h"
31 #include "vrrp_debug.h"
33 #ifndef VTYSH_EXTRACT_PL
34 #include "vrrpd/vrrp_vty_clippy.c"
38 #define VRRP_STR "Virtual Router Redundancy Protocol\n"
39 #define VRRP_VRID_STR "Virtual Router ID\n"
40 #define VRRP_PRIORITY_STR "Virtual Router Priority\n"
41 #define VRRP_ADVINT_STR "Virtual Router Advertisement Interval\n"
42 #define VRRP_IP_STR "Virtual Router IPv4 address\n"
43 #define VRRP_VERSION_STR "VRRP protocol version\n"
45 #define VROUTER_GET_VTY(_vty, _ifp, _vrid, _vr) \
47 _vr = vrrp_lookup(_ifp, _vrid); \
50 "%% Please configure VRRP instance %u\n", \
51 (unsigned int)_vrid); \
52 return CMD_WARNING_CONFIG_FAILED; \
56 /* clang-format off */
60 "[no] vrrp (1-255)$vrid [version (2-3)]",
67 VTY_DECLVAR_CONTEXT(interface
, ifp
);
69 struct vrrp_vrouter
*vr
= vrrp_lookup(ifp
, vrid
);
75 vrrp_vrouter_destroy(vr
);
77 vty_out(vty
, "%% VRRP instance %ld does not exist on %s\n",
80 vrrp_vrouter_create(ifp
, vrid
, version
);
82 vty_out(vty
, "%% VRRP instance %ld already exists on %s\n",
90 "[no] vrrp (1-255)$vrid shutdown",
94 "Force VRRP router into administrative shutdown\n")
96 VTY_DECLVAR_CONTEXT(interface
, ifp
);
98 struct vrrp_vrouter
*vr
;
100 VROUTER_GET_VTY(vty
, ifp
, vrid
, vr
);
103 if (vr
->v4
->fsm
.state
!= VRRP_STATE_INITIALIZE
)
104 vrrp_event(vr
->v4
, VRRP_EVENT_SHUTDOWN
);
105 if (vr
->v6
->fsm
.state
!= VRRP_STATE_INITIALIZE
)
106 vrrp_event(vr
->v6
, VRRP_EVENT_SHUTDOWN
);
109 vr
->shutdown
= false;
110 vrrp_check_start(vr
);
118 "[no] vrrp (1-255)$vrid priority (1-254)",
125 VTY_DECLVAR_CONTEXT(interface
, ifp
);
127 struct vrrp_vrouter
*vr
;
128 uint8_t newprio
= no
? vd
.priority
: priority
;
130 VROUTER_GET_VTY(vty
, ifp
, vrid
, vr
);
132 vrrp_set_priority(vr
, newprio
);
137 DEFPY(vrrp_advertisement_interval
,
138 vrrp_advertisement_interval_cmd
,
139 "[no] vrrp (1-255)$vrid advertisement-interval (10-40950)",
140 NO_STR VRRP_STR VRRP_VRID_STR VRRP_ADVINT_STR
141 "Advertisement interval in milliseconds; must be multiple of 10")
143 VTY_DECLVAR_CONTEXT(interface
, ifp
);
145 struct vrrp_vrouter
*vr
;
147 no
? vd
.advertisement_interval
* 10 : advertisement_interval
;
149 if (newadvint
% 10 != 0) {
150 vty_out(vty
, "%% Value must be a multiple of 10\n");
151 return CMD_WARNING_CONFIG_FAILED
;
154 /* all internal computations are in centiseconds */
157 VROUTER_GET_VTY(vty
, ifp
, vrid
, vr
);
158 vrrp_set_advertisement_interval(vr
, newadvint
);
165 "[no] vrrp (1-255)$vrid ip A.B.C.D",
172 VTY_DECLVAR_CONTEXT(interface
, ifp
);
174 struct vrrp_vrouter
*vr
;
175 bool deactivated
= false;
176 bool activated
= false;
178 int ret
= CMD_SUCCESS
;
181 VROUTER_GET_VTY(vty
, ifp
, vrid
, vr
);
183 bool will_activate
= (vr
->v4
->fsm
.state
== VRRP_STATE_INITIALIZE
);
186 oldstate
= vr
->v4
->fsm
.state
;
187 failed
= vrrp_del_ipv4(vr
, ip
);
188 vrrp_check_start(vr
);
189 deactivated
= (vr
->v4
->fsm
.state
== VRRP_STATE_INITIALIZE
190 && oldstate
!= VRRP_STATE_INITIALIZE
);
192 oldstate
= vr
->v4
->fsm
.state
;
193 failed
= vrrp_add_ipv4(vr
, ip
);
194 vrrp_check_start(vr
);
195 activated
= (vr
->v4
->fsm
.state
!= VRRP_STATE_INITIALIZE
196 && oldstate
== VRRP_STATE_INITIALIZE
);
200 vty_out(vty
, "%% Activated IPv4 Virtual Router %ld\n", vrid
);
202 vty_out(vty
, "%% Deactivated IPv4 Virtual Router %ld\n", vrid
);
204 vty_out(vty
, "%% Failed to %s virtual IP\n",
205 no
? "remove" : "add");
206 ret
= CMD_WARNING_CONFIG_FAILED
;
207 if (will_activate
&& !activated
) {
209 "%% Failed to activate IPv4 Virtual Router %ld\n",
219 "[no] vrrp (1-255)$vrid ipv6 X:X::X:X",
226 VTY_DECLVAR_CONTEXT(interface
, ifp
);
228 struct vrrp_vrouter
*vr
;
229 bool deactivated
= false;
230 bool activated
= false;
232 int ret
= CMD_SUCCESS
;
235 VROUTER_GET_VTY(vty
, ifp
, vrid
, vr
);
237 if (vr
->version
!= 3) {
239 "%% Cannot add IPv6 address to VRRPv2 virtual router\n");
240 return CMD_WARNING_CONFIG_FAILED
;
243 bool will_activate
= (vr
->v6
->fsm
.state
== VRRP_STATE_INITIALIZE
);
246 oldstate
= vr
->v6
->fsm
.state
;
247 failed
= vrrp_del_ipv6(vr
, ipv6
);
248 vrrp_check_start(vr
);
249 deactivated
= (vr
->v6
->fsm
.state
== VRRP_STATE_INITIALIZE
250 && oldstate
!= VRRP_STATE_INITIALIZE
);
252 oldstate
= vr
->v6
->fsm
.state
;
253 failed
= vrrp_add_ipv6(vr
, ipv6
);
254 vrrp_check_start(vr
);
255 activated
= (vr
->v6
->fsm
.state
!= VRRP_STATE_INITIALIZE
256 && oldstate
== VRRP_STATE_INITIALIZE
);
260 vty_out(vty
, "%% Activated IPv6 Virtual Router %ld\n", vrid
);
262 vty_out(vty
, "%% Deactivated IPv6 Virtual Router %ld\n", vrid
);
264 vty_out(vty
, "%% Failed to %s virtual IP\n",
265 no
? "remove" : "add");
266 ret
= CMD_WARNING_CONFIG_FAILED
;
267 if (will_activate
&& !activated
) {
269 "%% Failed to activate IPv6 Virtual Router %ld\n",
279 "[no] vrrp (1-255)$vrid preempt",
285 VTY_DECLVAR_CONTEXT(interface
, ifp
);
287 struct vrrp_vrouter
*vr
;
289 VROUTER_GET_VTY(vty
, ifp
, vrid
, vr
);
291 vr
->preempt_mode
= !no
;
296 DEFPY(vrrp_autoconfigure
,
297 vrrp_autoconfigure_cmd
,
298 "[no] vrrp autoconfigure [version (2-3)]",
301 "Automatically set up VRRP instances on VRRP-compatible interfaces\n"
302 "Version for automatically configured instances\n"
305 version
= version
? version
: 3;
308 vrrp_autoconfig_on(version
);
310 vrrp_autoconfig_off();
317 "[no] vrrp default <advertisement-interval$adv (10-40950)$advint|preempt$p|priority$prio (1-254)$prioval|shutdown$s>",
320 "Configure defaults for new VRRP instances\n"
322 "Advertisement interval in milliseconds\n"
326 "Force VRRP router into administrative shutdown\n")
329 if (advint
% 10 != 0) {
330 vty_out(vty
, "%% Value must be a multiple of 10\n");
331 return CMD_WARNING_CONFIG_FAILED
;
333 /* all internal computations are in centiseconds */
335 vd
.advertisement_interval
= no
? VRRP_DEFAULT_ADVINT
: advint
;
338 vd
.preempt_mode
= !no
;
340 vd
.priority
= no
? VRRP_DEFAULT_PRIORITY
: prioval
;
347 /* clang-format on */
350 * Build JSON representation of VRRP instance.
353 * VRRP router to build json object from
356 * JSON representation of VRRP instance. Must be freed by caller.
358 static struct json_object
*vrrp_build_json(struct vrrp_vrouter
*vr
)
360 char ethstr4
[ETHER_ADDR_STRLEN
];
361 char ethstr6
[ETHER_ADDR_STRLEN
];
362 char ipstr
[INET6_ADDRSTRLEN
];
363 const char *stastr4
= vrrp_state_names
[vr
->v4
->fsm
.state
];
364 const char *stastr6
= vrrp_state_names
[vr
->v6
->fsm
.state
];
365 char sipstr4
[INET6_ADDRSTRLEN
] = {};
366 char sipstr6
[INET6_ADDRSTRLEN
] = {};
369 struct json_object
*j
= json_object_new_object();
370 struct json_object
*v4
= json_object_new_object();
371 struct json_object
*v4_stats
= json_object_new_object();
372 struct json_object
*v4_addrs
= json_object_new_array();
373 struct json_object
*v6
= json_object_new_object();
374 struct json_object
*v6_stats
= json_object_new_object();
375 struct json_object
*v6_addrs
= json_object_new_array();
377 prefix_mac2str(&vr
->v4
->vmac
, ethstr4
, sizeof(ethstr4
));
378 prefix_mac2str(&vr
->v6
->vmac
, ethstr6
, sizeof(ethstr6
));
380 json_object_int_add(j
, "vrid", vr
->vrid
);
381 json_object_int_add(j
, "version", vr
->version
);
382 json_object_boolean_add(j
, "autoconfigured", vr
->autoconf
);
383 json_object_boolean_add(j
, "shutdown", vr
->shutdown
);
384 json_object_boolean_add(j
, "preemptMode", vr
->preempt_mode
);
385 json_object_boolean_add(j
, "acceptMode", vr
->accept_mode
);
386 json_object_string_add(j
, "interface", vr
->ifp
->name
);
387 json_object_int_add(j
, "advertisementInterval",
388 vr
->advertisement_interval
* CS2MS
);
390 json_object_string_add(v4
, "interface",
391 vr
->v4
->mvl_ifp
? vr
->v4
->mvl_ifp
->name
: "");
392 json_object_string_add(v4
, "vmac", ethstr4
);
393 ipaddr2str(&vr
->v4
->src
, sipstr4
, sizeof(sipstr4
));
394 json_object_string_add(v4
, "primaryAddress", sipstr4
);
395 json_object_string_add(v4
, "status", stastr4
);
396 json_object_int_add(v4
, "effectivePriority", vr
->v4
->priority
);
397 json_object_int_add(v4
, "masterAdverInterval",
398 vr
->v4
->master_adver_interval
* CS2MS
);
399 json_object_int_add(v4
, "skewTime", vr
->v4
->skew_time
* CS2MS
);
400 json_object_int_add(v4
, "masterDownInterval",
401 vr
->v4
->master_down_interval
* CS2MS
);
403 json_object_int_add(v4_stats
, "adverTx", vr
->v4
->stats
.adver_tx_cnt
);
404 json_object_int_add(v4_stats
, "adverRx", vr
->v4
->stats
.adver_rx_cnt
);
405 json_object_int_add(v4_stats
, "garpTx", vr
->v4
->stats
.garp_tx_cnt
);
406 json_object_int_add(v4_stats
, "transitions", vr
->v4
->stats
.trans_cnt
);
407 json_object_object_add(v4
, "stats", v4_stats
);
409 if (vr
->v4
->addrs
->count
) {
410 for (ALL_LIST_ELEMENTS_RO(vr
->v4
->addrs
, ln
, ip
)) {
411 inet_ntop(vr
->v4
->family
, &ip
->ipaddr_v4
, ipstr
,
413 json_object_array_add(v4_addrs
,
414 json_object_new_string(ipstr
));
417 json_object_object_add(v4
, "addresses", v4_addrs
);
418 json_object_object_add(j
, "v4", v4
);
421 json_object_string_add(v6
, "interface",
422 vr
->v6
->mvl_ifp
? vr
->v6
->mvl_ifp
->name
: "");
423 json_object_string_add(v6
, "vmac", ethstr6
);
424 ipaddr2str(&vr
->v6
->src
, sipstr6
, sizeof(sipstr6
));
425 if (strlen(sipstr6
) == 0 && vr
->v6
->src
.ip
.addr
== 0x00)
426 strlcat(sipstr6
, "::", sizeof(sipstr6
));
427 json_object_string_add(v6
, "primaryAddress", sipstr6
);
428 json_object_string_add(v6
, "status", stastr6
);
429 json_object_int_add(v6
, "effectivePriority", vr
->v6
->priority
);
430 json_object_int_add(v6
, "masterAdverInterval",
431 vr
->v6
->master_adver_interval
* CS2MS
);
432 json_object_int_add(v6
, "skewTime", vr
->v6
->skew_time
* CS2MS
);
433 json_object_int_add(v6
, "masterDownInterval",
434 vr
->v6
->master_down_interval
* CS2MS
);
436 json_object_int_add(v6_stats
, "adverTx", vr
->v6
->stats
.adver_tx_cnt
);
437 json_object_int_add(v6_stats
, "adverRx", vr
->v6
->stats
.adver_rx_cnt
);
438 json_object_int_add(v6_stats
, "neighborAdverTx",
439 vr
->v6
->stats
.una_tx_cnt
);
440 json_object_int_add(v6_stats
, "transitions", vr
->v6
->stats
.trans_cnt
);
441 json_object_object_add(v6
, "stats", v6_stats
);
443 if (vr
->v6
->addrs
->count
) {
444 for (ALL_LIST_ELEMENTS_RO(vr
->v6
->addrs
, ln
, ip
)) {
445 inet_ntop(vr
->v6
->family
, &ip
->ipaddr_v6
, ipstr
,
447 json_object_array_add(v6_addrs
,
448 json_object_new_string(ipstr
));
451 json_object_object_add(v6
, "addresses", v6_addrs
);
452 json_object_object_add(j
, "v6", v6
);
458 * Dump VRRP instance status to VTY.
464 * VRRP router to dump
466 static void vrrp_show(struct vty
*vty
, struct vrrp_vrouter
*vr
)
468 char ethstr4
[ETHER_ADDR_STRLEN
];
469 char ethstr6
[ETHER_ADDR_STRLEN
];
470 char ipstr
[INET6_ADDRSTRLEN
];
471 const char *stastr4
= vrrp_state_names
[vr
->v4
->fsm
.state
];
472 const char *stastr6
= vrrp_state_names
[vr
->v6
->fsm
.state
];
473 char sipstr4
[INET6_ADDRSTRLEN
] = {};
474 char sipstr6
[INET6_ADDRSTRLEN
] = {};
478 struct ttable
*tt
= ttable_new(&ttable_styles
[TTSTYLE_BLANK
]);
480 ttable_add_row(tt
, "%s|%" PRIu32
, "Virtual Router ID", vr
->vrid
);
481 ttable_add_row(tt
, "%s|%" PRIu8
, "Protocol Version", vr
->version
);
482 ttable_add_row(tt
, "%s|%s", "Autoconfigured",
483 vr
->autoconf
? "Yes" : "No");
484 ttable_add_row(tt
, "%s|%s", "Shutdown", vr
->shutdown
? "Yes" : "No");
485 ttable_add_row(tt
, "%s|%s", "Interface", vr
->ifp
->name
);
486 prefix_mac2str(&vr
->v4
->vmac
, ethstr4
, sizeof(ethstr4
));
487 prefix_mac2str(&vr
->v6
->vmac
, ethstr6
, sizeof(ethstr6
));
488 ttable_add_row(tt
, "%s|%s", "VRRP interface (v4)",
489 vr
->v4
->mvl_ifp
? vr
->v4
->mvl_ifp
->name
: "None");
490 ttable_add_row(tt
, "%s|%s", "VRRP interface (v6)",
491 vr
->v6
->mvl_ifp
? vr
->v6
->mvl_ifp
->name
: "None");
492 ipaddr2str(&vr
->v4
->src
, sipstr4
, sizeof(sipstr4
));
493 ipaddr2str(&vr
->v6
->src
, sipstr6
, sizeof(sipstr6
));
494 if (strlen(sipstr6
) == 0 && vr
->v6
->src
.ip
.addr
== 0x00)
495 strlcat(sipstr6
, "::", sizeof(sipstr6
));
496 ttable_add_row(tt
, "%s|%s", "Primary IP (v4)", sipstr4
);
497 ttable_add_row(tt
, "%s|%s", "Primary IP (v6)", sipstr6
);
498 ttable_add_row(tt
, "%s|%s", "Virtual MAC (v4)", ethstr4
);
499 ttable_add_row(tt
, "%s|%s", "Virtual MAC (v6)", ethstr6
);
500 ttable_add_row(tt
, "%s|%s", "Status (v4)", stastr4
);
501 ttable_add_row(tt
, "%s|%s", "Status (v6)", stastr6
);
502 ttable_add_row(tt
, "%s|%" PRIu8
, "Priority", vr
->priority
);
503 ttable_add_row(tt
, "%s|%" PRIu8
, "Effective Priority (v4)",
505 ttable_add_row(tt
, "%s|%" PRIu8
, "Effective Priority (v6)",
507 ttable_add_row(tt
, "%s|%s", "Preempt Mode",
508 vr
->preempt_mode
? "Yes" : "No");
509 ttable_add_row(tt
, "%s|%s", "Accept Mode",
510 vr
->accept_mode
? "Yes" : "No");
511 ttable_add_row(tt
, "%s|%d ms", "Advertisement Interval",
512 vr
->advertisement_interval
* CS2MS
);
513 ttable_add_row(tt
, "%s|%d ms",
514 "Master Advertisement Interval (v4)",
515 vr
->v4
->master_adver_interval
* CS2MS
);
516 ttable_add_row(tt
, "%s|%d ms",
517 "Master Advertisement Interval (v6)",
518 vr
->v6
->master_adver_interval
* CS2MS
);
519 ttable_add_row(tt
, "%s|%" PRIu32
, "Advertisements Tx (v4)",
520 vr
->v4
->stats
.adver_tx_cnt
);
521 ttable_add_row(tt
, "%s|%" PRIu32
, "Advertisements Tx (v6)",
522 vr
->v6
->stats
.adver_tx_cnt
);
523 ttable_add_row(tt
, "%s|%" PRIu32
, "Advertisements Rx (v4)",
524 vr
->v4
->stats
.adver_rx_cnt
);
525 ttable_add_row(tt
, "%s|%" PRIu32
, "Advertisements Rx (v6)",
526 vr
->v6
->stats
.adver_rx_cnt
);
527 ttable_add_row(tt
, "%s|%" PRIu32
, "Gratuitous ARP Tx (v4)",
528 vr
->v4
->stats
.garp_tx_cnt
);
529 ttable_add_row(tt
, "%s|%" PRIu32
, "Neigh. Adverts Tx (v6)",
530 vr
->v6
->stats
.una_tx_cnt
);
531 ttable_add_row(tt
, "%s|%" PRIu32
, "State transitions (v4)",
532 vr
->v4
->stats
.trans_cnt
);
533 ttable_add_row(tt
, "%s|%" PRIu32
, "State transitions (v6)",
534 vr
->v6
->stats
.trans_cnt
);
535 ttable_add_row(tt
, "%s|%d ms", "Skew Time (v4)",
536 vr
->v4
->skew_time
* CS2MS
);
537 ttable_add_row(tt
, "%s|%d ms", "Skew Time (v6)",
538 vr
->v6
->skew_time
* CS2MS
);
539 ttable_add_row(tt
, "%s|%d ms", "Master Down Interval (v4)",
540 vr
->v4
->master_down_interval
* CS2MS
);
541 ttable_add_row(tt
, "%s|%d ms", "Master Down Interval (v6)",
542 vr
->v6
->master_down_interval
* CS2MS
);
543 ttable_add_row(tt
, "%s|%u", "IPv4 Addresses", vr
->v4
->addrs
->count
);
547 memset(fill
, '.', sizeof(fill
));
548 fill
[sizeof(fill
) - 1] = 0x00;
549 if (vr
->v4
->addrs
->count
) {
550 for (ALL_LIST_ELEMENTS_RO(vr
->v4
->addrs
, ln
, ip
)) {
551 inet_ntop(vr
->v4
->family
, &ip
->ipaddr_v4
, ipstr
,
553 ttable_add_row(tt
, "%s|%s", fill
, ipstr
);
557 ttable_add_row(tt
, "%s|%u", "IPv6 Addresses", vr
->v6
->addrs
->count
);
559 if (vr
->v6
->addrs
->count
) {
560 for (ALL_LIST_ELEMENTS_RO(vr
->v6
->addrs
, ln
, ip
)) {
561 inet_ntop(vr
->v6
->family
, &ip
->ipaddr_v6
, ipstr
,
563 ttable_add_row(tt
, "%s|%s", fill
, ipstr
);
567 char *table
= ttable_dump(tt
, "\n");
569 vty_out(vty
, "\n%s\n", table
);
570 XFREE(MTYPE_TMP
, table
);
575 * Sort comparator, used when sorting VRRP instances for display purposes.
577 * Sorts by interface name first, then by VRID ascending.
579 static int vrrp_instance_display_sort_cmp(const void **d1
, const void **d2
)
581 const struct vrrp_vrouter
*vr1
= *d1
;
582 const struct vrrp_vrouter
*vr2
= *d2
;
585 result
= strcmp(vr1
->ifp
->name
, vr2
->ifp
->name
);
586 result
+= !result
* (vr1
->vrid
- vr2
->vrid
);
591 /* clang-format off */
593 DEFPY(vrrp_vrid_show
,
595 "show vrrp [interface INTERFACE$ifn] [(1-255)$vrid] [json$json]",
599 "Only show VRRP instances on this interface\n"
603 struct vrrp_vrouter
*vr
;
605 struct list
*ll
= hash_to_list(vrrp_vrouters_hash
);
606 struct json_object
*j
= json_object_new_array();
608 list_sort(ll
, vrrp_instance_display_sort_cmp
);
610 for (ALL_LIST_ELEMENTS_RO(ll
, ln
, vr
)) {
611 if (ifn
&& !strmatch(ifn
, vr
->ifp
->name
))
613 if (vrid
&& ((uint8_t) vrid
) != vr
->vrid
)
619 json_object_array_add(j
, vrrp_build_json(vr
));
624 json_object_to_json_string_ext(
625 j
, JSON_C_TO_STRING_PRETTY
));
634 DEFPY(vrrp_vrid_show_summary
,
635 vrrp_vrid_show_summary_cmd
,
636 "show vrrp [interface INTERFACE$ifn] [(1-255)$vrid] summary",
640 "Only show VRRP instances on this interface\n"
642 "Summarize all VRRP instances\n")
644 struct vrrp_vrouter
*vr
;
646 struct list
*ll
= hash_to_list(vrrp_vrouters_hash
);
648 list_sort(ll
, vrrp_instance_display_sort_cmp
);
650 struct ttable
*tt
= ttable_new(&ttable_styles
[TTSTYLE_BLANK
]);
653 tt
, "Interface|VRID|Priority|IPv4|IPv6|State (v4)|State (v6)");
654 ttable_rowseps(tt
, 0, BOTTOM
, true, '-');
656 for (ALL_LIST_ELEMENTS_RO(ll
, ln
, vr
)) {
657 if (ifn
&& !strmatch(ifn
, vr
->ifp
->name
))
659 if (vrid
&& ((uint8_t)vrid
) != vr
->vrid
)
663 tt
, "%s|%" PRIu8
"|%" PRIu8
"|%d|%d|%s|%s",
664 vr
->ifp
->name
, vr
->vrid
, vr
->priority
,
665 vr
->v4
->addrs
->count
, vr
->v6
->addrs
->count
,
666 vr
->v4
->fsm
.state
== VRRP_STATE_MASTER
? "Master"
668 vr
->v6
->fsm
.state
== VRRP_STATE_MASTER
? "Master"
672 char *table
= ttable_dump(tt
, "\n");
674 vty_out(vty
, "\n%s\n", table
);
675 XFREE(MTYPE_TMP
, table
);
686 "[no] debug vrrp [{protocol$proto|autoconfigure$ac|packets$pkt|sockets$sock|ndisc$ndisc|arp$arp|zebra$zebra}]",
690 "Debug protocol state\n"
691 "Debug autoconfiguration\n"
692 "Debug sent and received packets\n"
693 "Debug socket creation and configuration\n"
694 "Debug Neighbor Discovery\n"
696 "Debug Zebra events\n")
698 /* If no specific are given on/off them all */
699 if (strmatch(argv
[argc
- 1]->text
, "vrrp"))
700 vrrp_debug_set(NULL
, 0, vty
->node
, !no
, true, true, true, true,
703 vrrp_debug_set(NULL
, 0, vty
->node
, !no
, !!proto
, !!ac
, !!pkt
,
704 !!sock
, !!ndisc
, !!arp
, !!zebra
);
709 DEFUN_NOSH (show_debugging_vrrp
,
710 show_debugging_vrrp_cmd
,
711 "show debugging [vrrp]",
714 "VRRP information\n")
716 vty_out(vty
, "VRRP debugging status:\n");
718 vrrp_debug_status_write(vty
);
723 /* clang-format on */
725 static struct cmd_node interface_node
= {INTERFACE_NODE
, "%s(config-if)# ", 1};
726 static struct cmd_node debug_node
= {DEBUG_NODE
, "", 1};
727 static struct cmd_node vrrp_node
= {VRRP_NODE
, "", 1};
729 void vrrp_vty_init(void)
731 install_node(&debug_node
, vrrp_config_write_debug
);
732 install_node(&interface_node
, vrrp_config_write_interface
);
733 install_node(&vrrp_node
, vrrp_config_write_global
);
736 install_element(VIEW_NODE
, &vrrp_vrid_show_cmd
);
737 install_element(VIEW_NODE
, &vrrp_vrid_show_summary_cmd
);
738 install_element(VIEW_NODE
, &show_debugging_vrrp_cmd
);
739 install_element(VIEW_NODE
, &debug_vrrp_cmd
);
740 install_element(CONFIG_NODE
, &debug_vrrp_cmd
);
741 install_element(CONFIG_NODE
, &vrrp_autoconfigure_cmd
);
742 install_element(CONFIG_NODE
, &vrrp_default_cmd
);
743 install_element(INTERFACE_NODE
, &vrrp_vrid_cmd
);
744 install_element(INTERFACE_NODE
, &vrrp_shutdown_cmd
);
745 install_element(INTERFACE_NODE
, &vrrp_priority_cmd
);
746 install_element(INTERFACE_NODE
, &vrrp_advertisement_interval_cmd
);
747 install_element(INTERFACE_NODE
, &vrrp_ip_cmd
);
748 install_element(INTERFACE_NODE
, &vrrp_ip6_cmd
);
749 install_element(INTERFACE_NODE
, &vrrp_preempt_cmd
);