1 // SPDX-License-Identifier: GPL-2.0-or-later
4 * Copyright (C) 2018-2019 Cumulus Networks, Inc.
9 #include "lib/command.h"
11 #include "lib/ipaddr.h"
13 #include "lib/northbound_cli.h"
14 #include "lib/prefix.h"
15 #include "lib/termtable.h"
20 #include "vrrp_debug.h"
22 #include "vrrp_zebra.h"
23 #include "vrrpd/vrrp_vty_clippy.c"
26 #define VRRP_STR "Virtual Router Redundancy Protocol\n"
27 #define VRRP_VRID_STR "Virtual Router ID\n"
28 #define VRRP_PRIORITY_STR "Virtual Router Priority\n"
29 #define VRRP_ADVINT_STR "Virtual Router Advertisement Interval\n"
30 #define VRRP_IP_STR "Virtual Router IP address\n"
31 #define VRRP_VERSION_STR "VRRP protocol version\n"
33 #define VRRP_XPATH_ENTRY VRRP_XPATH "[virtual-router-id='%ld']"
35 /* clang-format off */
38 * XPath: /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group
42 "[no] vrrp (1-255)$vrid [version (2-3)]",
51 snprintf(valbuf
, sizeof(valbuf
), "%ld", version
? version
: vd
.version
);
54 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
56 nb_cli_enqueue_change(vty
, ".", NB_OP_CREATE
, NULL
);
57 nb_cli_enqueue_change(vty
, "./version", NB_OP_MODIFY
, valbuf
);
60 return nb_cli_apply_changes(vty
, VRRP_XPATH_ENTRY
, vrid
);
63 void cli_show_vrrp(struct vty
*vty
, const struct lyd_node
*dnode
, bool show_defaults
)
65 const char *vrid
= yang_dnode_get_string(dnode
, "./virtual-router-id");
66 const char *ver
= yang_dnode_get_string(dnode
, "./version");
68 vty_out(vty
, " vrrp %s", vrid
);
69 if (show_defaults
|| !yang_dnode_is_default(dnode
, "./version"))
70 vty_out(vty
, " version %s", ver
);
75 * XPath: /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/shutdown
77 DEFPY_YANG(vrrp_shutdown
,
79 "[no] vrrp (1-255)$vrid shutdown",
83 "Force VRRP router into administrative shutdown\n")
85 nb_cli_enqueue_change(vty
, "./shutdown", NB_OP_MODIFY
,
86 no
? "false" : "true");
88 return nb_cli_apply_changes(vty
, VRRP_XPATH_ENTRY
, vrid
);
91 void cli_show_shutdown(struct vty
*vty
, const struct lyd_node
*dnode
,
94 const char *vrid
= yang_dnode_get_string(dnode
, "../virtual-router-id");
95 const bool shut
= yang_dnode_get_bool(dnode
, NULL
);
97 vty_out(vty
, " %svrrp %s shutdown\n", shut
? "" : "no ", vrid
);
101 * XPath: /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/priority
103 DEFPY_YANG(vrrp_priority
,
105 "vrrp (1-255)$vrid priority (1-254)",
111 nb_cli_enqueue_change(vty
, "./priority", NB_OP_MODIFY
, priority_str
);
113 return nb_cli_apply_changes(vty
, VRRP_XPATH_ENTRY
, vrid
);
117 * XPath: /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/priority
119 DEFPY_YANG(no_vrrp_priority
,
120 no_vrrp_priority_cmd
,
121 "no vrrp (1-255)$vrid priority [(1-254)]",
128 nb_cli_enqueue_change(vty
, "./priority", NB_OP_MODIFY
, NULL
);
130 return nb_cli_apply_changes(vty
, VRRP_XPATH_ENTRY
, vrid
);
133 void cli_show_priority(struct vty
*vty
, const struct lyd_node
*dnode
,
136 const char *vrid
= yang_dnode_get_string(dnode
, "../virtual-router-id");
137 const char *prio
= yang_dnode_get_string(dnode
, NULL
);
139 vty_out(vty
, " vrrp %s priority %s\n", vrid
, prio
);
144 * /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/advertisement-interval
146 DEFPY_YANG(vrrp_advertisement_interval
,
147 vrrp_advertisement_interval_cmd
,
148 "vrrp (1-255)$vrid advertisement-interval (10-40950)",
149 VRRP_STR VRRP_VRID_STR VRRP_ADVINT_STR
150 "Advertisement interval in milliseconds; must be multiple of 10\n")
154 /* all internal computations are in centiseconds */
155 advertisement_interval
/= CS2MS
;
156 snprintf(val
, sizeof(val
), "%ld", advertisement_interval
);
157 nb_cli_enqueue_change(vty
, "./advertisement-interval", NB_OP_MODIFY
,
160 return nb_cli_apply_changes(vty
, VRRP_XPATH_ENTRY
, vrid
);
165 * /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/advertisement-interval
167 DEFPY_YANG(no_vrrp_advertisement_interval
,
168 no_vrrp_advertisement_interval_cmd
,
169 "no vrrp (1-255)$vrid advertisement-interval [(10-40950)]",
170 NO_STR VRRP_STR VRRP_VRID_STR VRRP_ADVINT_STR
171 "Advertisement interval in milliseconds; must be multiple of 10\n")
173 nb_cli_enqueue_change(vty
, "./advertisement-interval", NB_OP_MODIFY
,
176 return nb_cli_apply_changes(vty
, VRRP_XPATH_ENTRY
, vrid
);
179 void cli_show_advertisement_interval(struct vty
*vty
, const struct lyd_node
*dnode
,
182 const char *vrid
= yang_dnode_get_string(dnode
, "../virtual-router-id");
183 uint16_t advint
= yang_dnode_get_uint16(dnode
, NULL
);
185 vty_out(vty
, " vrrp %s advertisement-interval %u\n", vrid
,
191 * /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v4/virtual-address
195 "[no] vrrp (1-255)$vrid ip A.B.C.D",
202 int op
= no
? NB_OP_DESTROY
: NB_OP_CREATE
;
203 nb_cli_enqueue_change(vty
, "./v4/virtual-address", op
, ip_str
);
205 return nb_cli_apply_changes(vty
, VRRP_XPATH_ENTRY
, vrid
);
208 void cli_show_ip(struct vty
*vty
, const struct lyd_node
*dnode
, bool show_defaults
)
211 yang_dnode_get_string(dnode
, "../../virtual-router-id");
212 const char *ipv4
= yang_dnode_get_string(dnode
, NULL
);
214 vty_out(vty
, " vrrp %s ip %s\n", vrid
, ipv4
);
219 * /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v6/virtual-address
223 "[no] vrrp (1-255)$vrid ipv6 X:X::X:X",
230 int op
= no
? NB_OP_DESTROY
: NB_OP_CREATE
;
231 nb_cli_enqueue_change(vty
, "./v6/virtual-address", op
, ipv6_str
);
233 return nb_cli_apply_changes(vty
, VRRP_XPATH_ENTRY
, vrid
);
236 void cli_show_ipv6(struct vty
*vty
, const struct lyd_node
*dnode
, bool show_defaults
)
239 yang_dnode_get_string(dnode
, "../../virtual-router-id");
240 const char *ipv6
= yang_dnode_get_string(dnode
, NULL
);
242 vty_out(vty
, " vrrp %s ipv6 %s\n", vrid
, ipv6
);
246 * XPath: /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/preempt
248 DEFPY_YANG(vrrp_preempt
,
250 "[no] vrrp (1-255)$vrid preempt",
256 nb_cli_enqueue_change(vty
, "./preempt", NB_OP_MODIFY
,
257 no
? "false" : "true");
259 return nb_cli_apply_changes(vty
, VRRP_XPATH_ENTRY
, vrid
);
262 void cli_show_preempt(struct vty
*vty
, const struct lyd_node
*dnode
,
265 const char *vrid
= yang_dnode_get_string(dnode
, "../virtual-router-id");
266 const bool pre
= yang_dnode_get_bool(dnode
, NULL
);
268 vty_out(vty
, " %svrrp %s preempt\n", pre
? "" : "no ", vrid
);
272 * XPath: /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/checksum-with-
275 DEFPY_YANG(vrrp_checksum_with_ipv4_pseudoheader
,
276 vrrp_checksum_with_ipv4_pseudoheader_cmd
,
277 "[no] vrrp (1-255)$vrid checksum-with-ipv4-pseudoheader",
281 "Checksum mode in VRRPv3\n")
283 nb_cli_enqueue_change(vty
, "./checksum-with-ipv4-pseudoheader",
284 NB_OP_MODIFY
, no
? "false" : "true");
286 return nb_cli_apply_changes(vty
, VRRP_XPATH_ENTRY
, vrid
);
289 void cli_show_checksum_with_ipv4_pseudoheader(struct vty
*vty
,
290 const struct lyd_node
*dnode
,
293 const char *vrid
= yang_dnode_get_string(dnode
, "../virtual-router-id");
294 const bool pre
= yang_dnode_get_bool(dnode
, NULL
);
296 vty_out(vty
, " %svrrp %s checksum-with-ipv4-pseudoheader\n",
297 pre
? "" : "no ", vrid
);
300 /* XXX: yang conversion */
301 DEFPY_YANG(vrrp_autoconfigure
,
302 vrrp_autoconfigure_cmd
,
303 "[no] vrrp autoconfigure [version (2-3)]",
306 "Automatically set up VRRP instances on VRRP-compatible interfaces\n"
307 "Version for automatically configured instances\n"
310 version
= version
? version
: 3;
313 vrrp_autoconfig_on(version
);
315 vrrp_autoconfig_off();
320 /* XXX: yang conversion */
321 DEFPY_YANG(vrrp_default
,
323 "[no] vrrp default <advertisement-interval$adv (10-40950)$advint|preempt$p|priority$prio (1-254)$prioval|checksum-with-ipv4-pseudoheader$ipv4ph|shutdown$s>",
326 "Configure defaults for new VRRP instances\n"
328 "Advertisement interval in milliseconds\n"
332 "Checksum mode in VRRPv3\n"
333 "Force VRRP router into administrative shutdown\n")
336 if (advint
% CS2MS
!= 0) {
337 vty_out(vty
, "%% Value must be a multiple of %u\n",
338 (unsigned int)CS2MS
);
339 return CMD_WARNING_CONFIG_FAILED
;
341 /* all internal computations are in centiseconds */
343 vd
.advertisement_interval
= no
? VRRP_DEFAULT_ADVINT
: advint
;
346 vd
.preempt_mode
= !no
;
348 vd
.priority
= no
? VRRP_DEFAULT_PRIORITY
: prioval
;
350 vd
.checksum_with_ipv4_pseudoheader
= !no
;
357 /* clang-format on */
360 * Build JSON representation of VRRP instance.
363 * VRRP router to build json object from
366 * JSON representation of VRRP instance. Must be freed by caller.
368 static struct json_object
*vrrp_build_json(struct vrrp_vrouter
*vr
)
370 char ethstr4
[ETHER_ADDR_STRLEN
];
371 char ethstr6
[ETHER_ADDR_STRLEN
];
372 char ipstr
[INET6_ADDRSTRLEN
];
373 const char *stastr4
= vrrp_state_names
[vr
->v4
->fsm
.state
];
374 const char *stastr6
= vrrp_state_names
[vr
->v6
->fsm
.state
];
375 char sipstr4
[INET6_ADDRSTRLEN
] = {};
376 char sipstr6
[INET6_ADDRSTRLEN
] = {};
379 struct json_object
*j
= json_object_new_object();
380 struct json_object
*v4
= json_object_new_object();
381 struct json_object
*v4_stats
= json_object_new_object();
382 struct json_object
*v4_addrs
= json_object_new_array();
383 struct json_object
*v6
= json_object_new_object();
384 struct json_object
*v6_stats
= json_object_new_object();
385 struct json_object
*v6_addrs
= json_object_new_array();
387 prefix_mac2str(&vr
->v4
->vmac
, ethstr4
, sizeof(ethstr4
));
388 prefix_mac2str(&vr
->v6
->vmac
, ethstr6
, sizeof(ethstr6
));
390 json_object_int_add(j
, "vrid", vr
->vrid
);
391 json_object_int_add(j
, "version", vr
->version
);
392 json_object_boolean_add(j
, "autoconfigured", vr
->autoconf
);
393 json_object_boolean_add(j
, "shutdown", vr
->shutdown
);
394 json_object_boolean_add(j
, "preemptMode", vr
->preempt_mode
);
395 json_object_boolean_add(j
, "acceptMode", vr
->accept_mode
);
396 json_object_boolean_add(j
, "checksumWithIpv4Pseudoheader",
397 vr
->checksum_with_ipv4_pseudoheader
);
398 json_object_string_add(j
, "interface", vr
->ifp
->name
);
399 json_object_int_add(j
, "advertisementInterval",
400 vr
->advertisement_interval
* CS2MS
);
402 json_object_string_add(v4
, "interface",
403 vr
->v4
->mvl_ifp
? vr
->v4
->mvl_ifp
->name
: "");
404 json_object_string_add(v4
, "vmac", ethstr4
);
405 ipaddr2str(&vr
->v4
->src
, sipstr4
, sizeof(sipstr4
));
406 json_object_string_add(v4
, "primaryAddress", sipstr4
);
407 json_object_string_add(v4
, "status", stastr4
);
408 json_object_int_add(v4
, "effectivePriority", vr
->v4
->priority
);
409 json_object_int_add(v4
, "masterAdverInterval",
410 vr
->v4
->master_adver_interval
* CS2MS
);
411 json_object_int_add(v4
, "skewTime", vr
->v4
->skew_time
* CS2MS
);
412 json_object_int_add(v4
, "masterDownInterval",
413 vr
->v4
->master_down_interval
* CS2MS
);
415 json_object_int_add(v4_stats
, "adverTx", vr
->v4
->stats
.adver_tx_cnt
);
416 json_object_int_add(v4_stats
, "adverRx", vr
->v4
->stats
.adver_rx_cnt
);
417 json_object_int_add(v4_stats
, "garpTx", vr
->v4
->stats
.garp_tx_cnt
);
418 json_object_int_add(v4_stats
, "transitions", vr
->v4
->stats
.trans_cnt
);
419 json_object_object_add(v4
, "stats", v4_stats
);
421 if (vr
->v4
->addrs
->count
) {
422 for (ALL_LIST_ELEMENTS_RO(vr
->v4
->addrs
, ln
, ip
)) {
423 inet_ntop(vr
->v4
->family
, &ip
->ipaddr_v4
, ipstr
,
425 json_object_array_add(v4_addrs
,
426 json_object_new_string(ipstr
));
429 json_object_object_add(v4
, "addresses", v4_addrs
);
430 json_object_object_add(j
, "v4", v4
);
433 json_object_string_add(v6
, "interface",
434 vr
->v6
->mvl_ifp
? vr
->v6
->mvl_ifp
->name
: "");
435 json_object_string_add(v6
, "vmac", ethstr6
);
436 ipaddr2str(&vr
->v6
->src
, sipstr6
, sizeof(sipstr6
));
437 if (strlen(sipstr6
) == 0 && vr
->v6
->src
.ip
.addr
== 0x00)
438 strlcat(sipstr6
, "::", sizeof(sipstr6
));
439 json_object_string_add(v6
, "primaryAddress", sipstr6
);
440 json_object_string_add(v6
, "status", stastr6
);
441 json_object_int_add(v6
, "effectivePriority", vr
->v6
->priority
);
442 json_object_int_add(v6
, "masterAdverInterval",
443 vr
->v6
->master_adver_interval
* CS2MS
);
444 json_object_int_add(v6
, "skewTime", vr
->v6
->skew_time
* CS2MS
);
445 json_object_int_add(v6
, "masterDownInterval",
446 vr
->v6
->master_down_interval
* CS2MS
);
448 json_object_int_add(v6_stats
, "adverTx", vr
->v6
->stats
.adver_tx_cnt
);
449 json_object_int_add(v6_stats
, "adverRx", vr
->v6
->stats
.adver_rx_cnt
);
450 json_object_int_add(v6_stats
, "neighborAdverTx",
451 vr
->v6
->stats
.una_tx_cnt
);
452 json_object_int_add(v6_stats
, "transitions", vr
->v6
->stats
.trans_cnt
);
453 json_object_object_add(v6
, "stats", v6_stats
);
455 if (vr
->v6
->addrs
->count
) {
456 for (ALL_LIST_ELEMENTS_RO(vr
->v6
->addrs
, ln
, ip
)) {
457 inet_ntop(vr
->v6
->family
, &ip
->ipaddr_v6
, ipstr
,
459 json_object_array_add(v6_addrs
,
460 json_object_new_string(ipstr
));
463 json_object_object_add(v6
, "addresses", v6_addrs
);
464 json_object_object_add(j
, "v6", v6
);
470 * Dump VRRP instance status to VTY.
476 * VRRP router to dump
478 static void vrrp_show(struct vty
*vty
, struct vrrp_vrouter
*vr
)
480 char ethstr4
[ETHER_ADDR_STRLEN
];
481 char ethstr6
[ETHER_ADDR_STRLEN
];
482 char ipstr
[INET6_ADDRSTRLEN
];
483 const char *stastr4
= vrrp_state_names
[vr
->v4
->fsm
.state
];
484 const char *stastr6
= vrrp_state_names
[vr
->v6
->fsm
.state
];
485 char sipstr4
[INET6_ADDRSTRLEN
] = {};
486 char sipstr6
[INET6_ADDRSTRLEN
] = {};
490 struct ttable
*tt
= ttable_new(&ttable_styles
[TTSTYLE_BLANK
]);
492 ttable_add_row(tt
, "%s|%u", "Virtual Router ID", vr
->vrid
);
493 ttable_add_row(tt
, "%s|%hhu", "Protocol Version", vr
->version
);
494 ttable_add_row(tt
, "%s|%s", "Autoconfigured",
495 vr
->autoconf
? "Yes" : "No");
496 ttable_add_row(tt
, "%s|%s", "Shutdown", vr
->shutdown
? "Yes" : "No");
497 ttable_add_row(tt
, "%s|%s", "Interface", vr
->ifp
->name
);
498 prefix_mac2str(&vr
->v4
->vmac
, ethstr4
, sizeof(ethstr4
));
499 prefix_mac2str(&vr
->v6
->vmac
, ethstr6
, sizeof(ethstr6
));
500 ttable_add_row(tt
, "%s|%s", "VRRP interface (v4)",
501 vr
->v4
->mvl_ifp
? vr
->v4
->mvl_ifp
->name
: "None");
502 ttable_add_row(tt
, "%s|%s", "VRRP interface (v6)",
503 vr
->v6
->mvl_ifp
? vr
->v6
->mvl_ifp
->name
: "None");
504 ipaddr2str(&vr
->v4
->src
, sipstr4
, sizeof(sipstr4
));
505 ipaddr2str(&vr
->v6
->src
, sipstr6
, sizeof(sipstr6
));
506 if (strlen(sipstr6
) == 0 && vr
->v6
->src
.ip
.addr
== 0x00)
507 strlcat(sipstr6
, "::", sizeof(sipstr6
));
508 ttable_add_row(tt
, "%s|%s", "Primary IP (v4)", sipstr4
);
509 ttable_add_row(tt
, "%s|%s", "Primary IP (v6)", sipstr6
);
510 ttable_add_row(tt
, "%s|%s", "Virtual MAC (v4)", ethstr4
);
511 ttable_add_row(tt
, "%s|%s", "Virtual MAC (v6)", ethstr6
);
512 ttable_add_row(tt
, "%s|%s", "Status (v4)", stastr4
);
513 ttable_add_row(tt
, "%s|%s", "Status (v6)", stastr6
);
514 ttable_add_row(tt
, "%s|%hhu", "Priority", vr
->priority
);
515 ttable_add_row(tt
, "%s|%hhu", "Effective Priority (v4)",
517 ttable_add_row(tt
, "%s|%hhu", "Effective Priority (v6)",
519 ttable_add_row(tt
, "%s|%s", "Preempt Mode",
520 vr
->preempt_mode
? "Yes" : "No");
521 ttable_add_row(tt
, "%s|%s", "Accept Mode",
522 vr
->accept_mode
? "Yes" : "No");
523 ttable_add_row(tt
, "%s|%s", "Checksum with IPv4 Pseudoheader",
524 vr
->checksum_with_ipv4_pseudoheader
? "Yes" : "No");
525 ttable_add_row(tt
, "%s|%d ms", "Advertisement Interval",
526 vr
->advertisement_interval
* CS2MS
);
527 ttable_add_row(tt
, "%s|%d ms (stale)",
528 "Master Advertisement Interval (v4) Rx",
529 vr
->v4
->master_adver_interval
* CS2MS
);
530 ttable_add_row(tt
, "%s|%d ms (stale)",
531 "Master Advertisement Interval (v6) Rx",
532 vr
->v6
->master_adver_interval
* CS2MS
);
533 ttable_add_row(tt
, "%s|%u", "Advertisements Tx (v4)",
534 vr
->v4
->stats
.adver_tx_cnt
);
535 ttable_add_row(tt
, "%s|%u", "Advertisements Tx (v6)",
536 vr
->v6
->stats
.adver_tx_cnt
);
537 ttable_add_row(tt
, "%s|%u", "Advertisements Rx (v4)",
538 vr
->v4
->stats
.adver_rx_cnt
);
539 ttable_add_row(tt
, "%s|%u", "Advertisements Rx (v6)",
540 vr
->v6
->stats
.adver_rx_cnt
);
541 ttable_add_row(tt
, "%s|%u", "Gratuitous ARP Tx (v4)",
542 vr
->v4
->stats
.garp_tx_cnt
);
543 ttable_add_row(tt
, "%s|%u", "Neigh. Adverts Tx (v6)",
544 vr
->v6
->stats
.una_tx_cnt
);
545 ttable_add_row(tt
, "%s|%u", "State transitions (v4)",
546 vr
->v4
->stats
.trans_cnt
);
547 ttable_add_row(tt
, "%s|%u", "State transitions (v6)",
548 vr
->v6
->stats
.trans_cnt
);
549 ttable_add_row(tt
, "%s|%d ms", "Skew Time (v4)",
550 vr
->v4
->skew_time
* CS2MS
);
551 ttable_add_row(tt
, "%s|%d ms", "Skew Time (v6)",
552 vr
->v6
->skew_time
* CS2MS
);
553 ttable_add_row(tt
, "%s|%d ms", "Master Down Interval (v4)",
554 vr
->v4
->master_down_interval
* CS2MS
);
555 ttable_add_row(tt
, "%s|%d ms", "Master Down Interval (v6)",
556 vr
->v6
->master_down_interval
* CS2MS
);
557 ttable_add_row(tt
, "%s|%u", "IPv4 Addresses", vr
->v4
->addrs
->count
);
561 memset(fill
, '.', sizeof(fill
));
562 fill
[sizeof(fill
) - 1] = 0x00;
563 if (vr
->v4
->addrs
->count
) {
564 for (ALL_LIST_ELEMENTS_RO(vr
->v4
->addrs
, ln
, ip
)) {
565 inet_ntop(vr
->v4
->family
, &ip
->ipaddr_v4
, ipstr
,
567 ttable_add_row(tt
, "%s|%s", fill
, ipstr
);
571 ttable_add_row(tt
, "%s|%u", "IPv6 Addresses", vr
->v6
->addrs
->count
);
573 if (vr
->v6
->addrs
->count
) {
574 for (ALL_LIST_ELEMENTS_RO(vr
->v6
->addrs
, ln
, ip
)) {
575 inet_ntop(vr
->v6
->family
, &ip
->ipaddr_v6
, ipstr
,
577 ttable_add_row(tt
, "%s|%s", fill
, ipstr
);
581 char *table
= ttable_dump(tt
, "\n");
583 vty_out(vty
, "\n%s\n", table
);
584 XFREE(MTYPE_TMP
, table
);
589 * Sort comparator, used when sorting VRRP instances for display purposes.
591 * Sorts by interface name first, then by VRID ascending.
593 static int vrrp_instance_display_sort_cmp(const void **d1
, const void **d2
)
595 const struct vrrp_vrouter
*vr1
= *d1
;
596 const struct vrrp_vrouter
*vr2
= *d2
;
599 result
= strcmp(vr1
->ifp
->name
, vr2
->ifp
->name
);
600 result
+= !result
* (vr1
->vrid
- vr2
->vrid
);
605 /* clang-format off */
607 DEFPY_YANG(vrrp_vrid_show
,
609 "show vrrp [interface INTERFACE$ifn] [(1-255)$vrid] [json$json]",
613 "Only show VRRP instances on this interface\n"
617 struct vrrp_vrouter
*vr
;
619 struct list
*ll
= hash_to_list(vrrp_vrouters_hash
);
620 struct json_object
*j
= json_object_new_array();
622 list_sort(ll
, vrrp_instance_display_sort_cmp
);
624 for (ALL_LIST_ELEMENTS_RO(ll
, ln
, vr
)) {
625 if (ifn
&& !strmatch(ifn
, vr
->ifp
->name
))
627 if (vrid
&& ((uint8_t) vrid
) != vr
->vrid
)
633 json_object_array_add(j
, vrrp_build_json(vr
));
638 json_object_to_json_string_ext(
639 j
, JSON_C_TO_STRING_PRETTY
));
648 DEFPY_YANG(vrrp_vrid_show_summary
,
649 vrrp_vrid_show_summary_cmd
,
650 "show vrrp [interface INTERFACE$ifn] [(1-255)$vrid] summary",
654 "Only show VRRP instances on this interface\n"
656 "Summarize all VRRP instances\n")
658 struct vrrp_vrouter
*vr
;
660 struct list
*ll
= hash_to_list(vrrp_vrouters_hash
);
662 list_sort(ll
, vrrp_instance_display_sort_cmp
);
664 struct ttable
*tt
= ttable_new(&ttable_styles
[TTSTYLE_BLANK
]);
667 tt
, "Interface|VRID|Priority|IPv4|IPv6|State (v4)|State (v6)");
668 ttable_rowseps(tt
, 0, BOTTOM
, true, '-');
670 for (ALL_LIST_ELEMENTS_RO(ll
, ln
, vr
)) {
671 if (ifn
&& !strmatch(ifn
, vr
->ifp
->name
))
673 if (vrid
&& ((uint8_t)vrid
) != vr
->vrid
)
677 tt
, "%s|%u|%hhu|%d|%d|%s|%s",
678 vr
->ifp
->name
, vr
->vrid
, vr
->priority
,
679 vr
->v4
->addrs
->count
, vr
->v6
->addrs
->count
,
680 vr
->v4
->fsm
.state
== VRRP_STATE_MASTER
? "Master"
682 vr
->v6
->fsm
.state
== VRRP_STATE_MASTER
? "Master"
686 char *table
= ttable_dump(tt
, "\n");
688 vty_out(vty
, "\n%s\n", table
);
689 XFREE(MTYPE_TMP
, table
);
698 DEFPY_YANG(debug_vrrp
,
700 "[no] debug vrrp [{protocol$proto|autoconfigure$ac|packets$pkt|sockets$sock|ndisc$ndisc|arp$arp|zebra$zebra}]",
704 "Debug protocol state\n"
705 "Debug autoconfiguration\n"
706 "Debug sent and received packets\n"
707 "Debug socket creation and configuration\n"
708 "Debug Neighbor Discovery\n"
710 "Debug Zebra events\n")
712 /* If no specific are given on/off them all */
713 if (strmatch(argv
[argc
- 1]->text
, "vrrp"))
714 vrrp_debug_set(NULL
, 0, vty
->node
, !no
, true, true, true, true,
717 vrrp_debug_set(NULL
, 0, vty
->node
, !no
, !!proto
, !!ac
, !!pkt
,
718 !!sock
, !!ndisc
, !!arp
, !!zebra
);
723 DEFUN_NOSH (show_debugging_vrrp
,
724 show_debugging_vrrp_cmd
,
725 "show debugging [vrrp]",
728 "VRRP information\n")
730 vty_out(vty
, "VRRP debugging status:\n");
732 vrrp_debug_status_write(vty
);
734 cmd_show_lib_debugs(vty
);
739 /* clang-format on */
741 static struct cmd_node debug_node
= {
745 .config_write
= vrrp_config_write_debug
,
748 static struct cmd_node vrrp_node
= {
752 .config_write
= vrrp_config_write_global
,
755 void vrrp_vty_init(void)
757 install_node(&debug_node
);
758 install_node(&vrrp_node
);
760 if_cmd_init_default();
762 install_element(VIEW_NODE
, &vrrp_vrid_show_cmd
);
763 install_element(VIEW_NODE
, &vrrp_vrid_show_summary_cmd
);
764 install_element(ENABLE_NODE
, &show_debugging_vrrp_cmd
);
765 install_element(ENABLE_NODE
, &debug_vrrp_cmd
);
766 install_element(CONFIG_NODE
, &debug_vrrp_cmd
);
767 install_element(CONFIG_NODE
, &vrrp_autoconfigure_cmd
);
768 install_element(CONFIG_NODE
, &vrrp_default_cmd
);
769 install_element(INTERFACE_NODE
, &vrrp_vrid_cmd
);
770 install_element(INTERFACE_NODE
, &vrrp_shutdown_cmd
);
771 install_element(INTERFACE_NODE
, &vrrp_priority_cmd
);
772 install_element(INTERFACE_NODE
, &no_vrrp_priority_cmd
);
773 install_element(INTERFACE_NODE
, &vrrp_advertisement_interval_cmd
);
774 install_element(INTERFACE_NODE
, &no_vrrp_advertisement_interval_cmd
);
775 install_element(INTERFACE_NODE
, &vrrp_ip_cmd
);
776 install_element(INTERFACE_NODE
, &vrrp_ip6_cmd
);
777 install_element(INTERFACE_NODE
, &vrrp_preempt_cmd
);
778 install_element(INTERFACE_NODE
,
779 &vrrp_checksum_with_ipv4_pseudoheader_cmd
);