]> git.proxmox.com Git - mirror_frr.git/blame - vrrpd/vrrp_vty.c
tools: fix vrrp autoconfigure reload
[mirror_frr.git] / vrrpd / vrrp_vty.c
CommitLineData
5435a2bf 1/*
63d4bd12
QY
2 * VRRP CLI commands.
3 * Copyright (C) 2018-2019 Cumulus Networks, Inc.
4 * Quentin Young
5435a2bf
QY
5 *
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)
9 * any later version.
10 *
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
14 * more details.
15 *
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
19 */
20#include <zebra.h>
21
862f2f37
QY
22#include "lib/command.h"
23#include "lib/if.h"
24#include "lib/ipaddr.h"
6e21b5ae 25#include "lib/json.h"
862f2f37
QY
26#include "lib/prefix.h"
27#include "lib/termtable.h"
28#include "lib/vty.h"
5435a2bf
QY
29
30#include "vrrp.h"
78fb3dbe 31#include "vrrp_debug.h"
5435a2bf 32#include "vrrp_memory.h"
78fb3dbe 33#include "vrrp_vty.h"
c23edd74
QY
34#ifndef VTYSH_EXTRACT_PL
35#include "vrrpd/vrrp_vty_clippy.c"
36#endif
5435a2bf
QY
37
38
39#define VRRP_STR "Virtual Router Redundancy Protocol\n"
40#define VRRP_VRID_STR "Virtual Router ID\n"
c23edd74 41#define VRRP_PRIORITY_STR "Virtual Router Priority\n"
6287cefe 42#define VRRP_ADVINT_STR "Virtual Router Advertisement Interval\n"
c23edd74 43#define VRRP_IP_STR "Virtual Router IPv4 address\n"
99966840 44#define VRRP_VERSION_STR "VRRP protocol version\n"
c23edd74 45
4f0b6b45 46#define VROUTER_GET_VTY(_vty, _ifp, _vrid, _vr) \
c23edd74 47 do { \
4f0b6b45 48 _vr = vrrp_lookup(_ifp, _vrid); \
c23edd74
QY
49 if (!_vr) { \
50 vty_out(_vty, \
51 "%% Please configure VRRP instance %u\n", \
52 (unsigned int)_vrid); \
53 return CMD_WARNING_CONFIG_FAILED; \
54 } \
2fff50ec 55 } while (0)
5435a2bf 56
b637bcd4
QY
57/* clang-format off */
58
c23edd74 59DEFPY(vrrp_vrid,
5435a2bf 60 vrrp_vrid_cmd,
99966840 61 "[no] vrrp (1-255)$vrid [version (2-3)]",
5435a2bf
QY
62 NO_STR
63 VRRP_STR
99966840
QY
64 VRRP_VRID_STR
65 VRRP_VERSION_STR
66 VRRP_VERSION_STR)
5435a2bf
QY
67{
68 VTY_DECLVAR_CONTEXT(interface, ifp);
5435a2bf 69
4f0b6b45 70 struct vrrp_vrouter *vr = vrrp_lookup(ifp, vrid);
6287cefe 71
99966840
QY
72 if (version == 0)
73 version = 3;
74
6287cefe
QY
75 if (no && vr)
76 vrrp_vrouter_destroy(vr);
77 else if (no && !vr)
78 vty_out(vty, "%% VRRP instance %ld does not exist on %s\n",
79 vrid, ifp->name);
80 else if (!vr)
99966840 81 vrrp_vrouter_create(ifp, vrid, version);
6287cefe
QY
82 else if (vr)
83 vty_out(vty, "%% VRRP instance %ld already exists on %s\n",
84 vrid, ifp->name);
5435a2bf
QY
85
86 return CMD_SUCCESS;
87}
88
f96a183b
QY
89DEFPY(vrrp_shutdown,
90 vrrp_shutdown_cmd,
91 "[no] vrrp (1-255)$vrid shutdown",
92 NO_STR
93 VRRP_STR
94 VRRP_VRID_STR
95 "Force VRRP router into administrative shutdown\n")
96{
97 VTY_DECLVAR_CONTEXT(interface, ifp);
98
99 struct vrrp_vrouter *vr;
100
101 VROUTER_GET_VTY(vty, ifp, vrid, vr);
102
103 if (!no) {
104 if (vr->v4->fsm.state != VRRP_STATE_INITIALIZE)
105 vrrp_event(vr->v4, VRRP_EVENT_SHUTDOWN);
106 if (vr->v6->fsm.state != VRRP_STATE_INITIALIZE)
107 vrrp_event(vr->v6, VRRP_EVENT_SHUTDOWN);
108 vr->shutdown = true;
109 } else {
110 vr->shutdown = false;
111 vrrp_check_start(vr);
112 }
113
114 return CMD_SUCCESS;
115}
116
c23edd74
QY
117DEFPY(vrrp_priority,
118 vrrp_priority_cmd,
d7cfcdc0 119 "[no] vrrp (1-255)$vrid priority (1-254)",
c23edd74
QY
120 NO_STR
121 VRRP_STR
122 VRRP_VRID_STR
123 VRRP_PRIORITY_STR
bac08ded 124 "Priority value")
c23edd74 125{
4f0b6b45
QY
126 VTY_DECLVAR_CONTEXT(interface, ifp);
127
c23edd74 128 struct vrrp_vrouter *vr;
8cd1d277 129 uint8_t newprio = no ? vd.priority : priority;
c23edd74 130
4f0b6b45 131 VROUTER_GET_VTY(vty, ifp, vrid, vr);
1d21789e 132
6287cefe 133 vrrp_set_priority(vr, newprio);
1d21789e 134
1d21789e
QY
135 return CMD_SUCCESS;
136}
137
138DEFPY(vrrp_advertisement_interval,
139 vrrp_advertisement_interval_cmd,
cb44d476 140 "[no] vrrp (1-255)$vrid advertisement-interval (10-40950)",
6287cefe 141 NO_STR VRRP_STR VRRP_VRID_STR VRRP_ADVINT_STR
cb44d476 142 "Advertisement interval in milliseconds; must be multiple of 10")
1d21789e 143{
4f0b6b45
QY
144 VTY_DECLVAR_CONTEXT(interface, ifp);
145
1d21789e 146 struct vrrp_vrouter *vr;
8cd1d277
QY
147 uint16_t newadvint = no ? vd.advertisement_interval :
148 advertisement_interval;
1d21789e 149
cb44d476
QY
150 if (newadvint % 10 != 0) {
151 vty_out(vty, "%% Value must be a multiple of 10\n");
152 return CMD_WARNING_CONFIG_FAILED;
153 }
154
155 /* all internal computations are in centiseconds */
156 newadvint /= CS2MS;
157
4f0b6b45 158 VROUTER_GET_VTY(vty, ifp, vrid, vr);
6287cefe 159 vrrp_set_advertisement_interval(vr, newadvint);
c23edd74
QY
160
161 return CMD_SUCCESS;
162}
163
164DEFPY(vrrp_ip,
165 vrrp_ip_cmd,
862f2f37 166 "[no] vrrp (1-255)$vrid ip A.B.C.D",
c23edd74
QY
167 NO_STR
168 VRRP_STR
169 VRRP_VRID_STR
862f2f37 170 "Add IPv4 address\n"
c23edd74
QY
171 VRRP_IP_STR)
172{
4f0b6b45
QY
173 VTY_DECLVAR_CONTEXT(interface, ifp);
174
c23edd74 175 struct vrrp_vrouter *vr;
2cd90902
QY
176 bool deactivated = false;
177 bool activated = false;
178 bool failed = false;
179 int ret = CMD_SUCCESS;
2fff50ec 180 int oldstate;
c23edd74 181
4f0b6b45 182 VROUTER_GET_VTY(vty, ifp, vrid, vr);
c23edd74 183
2cd90902 184 bool will_activate = (vr->v4->fsm.state == VRRP_STATE_INITIALIZE);
862f2f37 185
2cd90902 186 if (no) {
2fff50ec 187 oldstate = vr->v4->fsm.state;
6e93585e
QY
188 failed = vrrp_del_ipv4(vr, ip);
189 vrrp_check_start(vr);
2cd90902
QY
190 deactivated = (vr->v4->fsm.state == VRRP_STATE_INITIALIZE
191 && oldstate != VRRP_STATE_INITIALIZE);
862f2f37 192 } else {
2fff50ec 193 oldstate = vr->v4->fsm.state;
6e93585e
QY
194 failed = vrrp_add_ipv4(vr, ip);
195 vrrp_check_start(vr);
2cd90902
QY
196 activated = (vr->v4->fsm.state != VRRP_STATE_INITIALIZE
197 && oldstate == VRRP_STATE_INITIALIZE);
198 }
199
200 if (activated)
201 vty_out(vty, "%% Activated IPv4 Virtual Router %ld\n", vrid);
202 if (deactivated)
203 vty_out(vty, "%% Deactivated IPv4 Virtual Router %ld\n", vrid);
204 if (failed) {
1af0eb1f 205 vty_out(vty, "%% Failed to %s virtual IP\n",
2cd90902
QY
206 no ? "remove" : "add");
207 ret = CMD_WARNING_CONFIG_FAILED;
208 if (will_activate && !activated) {
209 vty_out(vty,
210 "%% Failed to activate IPv4 Virtual Router %ld\n",
211 vrid);
212 }
862f2f37
QY
213 }
214
215 return ret;
216}
217
218DEFPY(vrrp_ip6,
219 vrrp_ip6_cmd,
220 "[no] vrrp (1-255)$vrid ipv6 X:X::X:X",
221 NO_STR
222 VRRP_STR
223 VRRP_VRID_STR
224 "Add IPv6 address\n"
225 VRRP_IP_STR)
226{
4f0b6b45
QY
227 VTY_DECLVAR_CONTEXT(interface, ifp);
228
862f2f37 229 struct vrrp_vrouter *vr;
2cd90902
QY
230 bool deactivated = false;
231 bool activated = false;
232 bool failed = false;
233 int ret = CMD_SUCCESS;
2fff50ec 234 int oldstate;
862f2f37 235
4f0b6b45 236 VROUTER_GET_VTY(vty, ifp, vrid, vr);
862f2f37 237
99966840
QY
238 if (vr->version != 3) {
239 vty_out(vty,
240 "%% Cannot add IPv6 address to VRRPv2 virtual router\n");
241 return CMD_WARNING_CONFIG_FAILED;
242 }
243
2cd90902 244 bool will_activate = (vr->v6->fsm.state == VRRP_STATE_INITIALIZE);
1d21789e 245
2cd90902 246 if (no) {
2fff50ec 247 oldstate = vr->v6->fsm.state;
6e93585e 248 failed = vrrp_del_ipv6(vr, ipv6);
29ef66fa 249 vrrp_check_start(vr);
2cd90902
QY
250 deactivated = (vr->v6->fsm.state == VRRP_STATE_INITIALIZE
251 && oldstate != VRRP_STATE_INITIALIZE);
1d21789e 252 } else {
2fff50ec 253 oldstate = vr->v6->fsm.state;
6e93585e 254 failed = vrrp_add_ipv6(vr, ipv6);
29ef66fa 255 vrrp_check_start(vr);
2cd90902
QY
256 activated = (vr->v6->fsm.state != VRRP_STATE_INITIALIZE
257 && oldstate == VRRP_STATE_INITIALIZE);
258 }
259
260 if (activated)
261 vty_out(vty, "%% Activated IPv6 Virtual Router %ld\n", vrid);
262 if (deactivated)
263 vty_out(vty, "%% Deactivated IPv6 Virtual Router %ld\n", vrid);
264 if (failed) {
d5a6ff43 265 vty_out(vty, "%% Failed to %s virtual IP\n",
2cd90902
QY
266 no ? "remove" : "add");
267 ret = CMD_WARNING_CONFIG_FAILED;
268 if (will_activate && !activated) {
269 vty_out(vty,
d5a6ff43 270 "%% Failed to activate IPv6 Virtual Router %ld\n",
2cd90902
QY
271 vrid);
272 }
1d21789e
QY
273 }
274
275 return ret;
c23edd74
QY
276}
277
8ec51216
QY
278DEFPY(vrrp_preempt,
279 vrrp_preempt_cmd,
280 "[no] vrrp (1-255)$vrid preempt",
281 NO_STR
282 VRRP_STR
283 VRRP_VRID_STR
284 "Preempt mode\n")
285{
286 VTY_DECLVAR_CONTEXT(interface, ifp);
287
288 struct vrrp_vrouter *vr;
289
290 VROUTER_GET_VTY(vty, ifp, vrid, vr);
291
292 vr->preempt_mode = !no;
293
294 return CMD_SUCCESS;
295}
296
27fd8827
QY
297DEFPY(vrrp_autoconfigure,
298 vrrp_autoconfigure_cmd,
299 "[no] vrrp autoconfigure [version (2-3)]",
53e60e5c
QY
300 NO_STR
301 VRRP_STR
302 "Automatically set up VRRP instances on VRRP-compatible interfaces\n"
303 "Version for automatically configured instances\n"
304 VRRP_VERSION_STR)
305{
53e60e5c
QY
306 version = version ? version : 3;
307
27fd8827
QY
308 if (!no)
309 vrrp_autoconfig_on(version);
310 else
311 vrrp_autoconfig_off();
53e60e5c
QY
312
313 return CMD_SUCCESS;
314}
315
8cd1d277
QY
316DEFPY(vrrp_default,
317 vrrp_default_cmd,
318 "[no] vrrp default <advertisement-interval$adv (1-4096)$advint|preempt$p|priority$prio (1-254)$prioval|shutdown$s>",
319 NO_STR
320 VRRP_STR
321 "Configure defaults for new VRRP instances\n"
322 VRRP_ADVINT_STR
323 "Advertisement interval in centiseconds\n"
324 "Preempt mode\n"
325 VRRP_PRIORITY_STR
326 "Priority value\n"
327 "Force VRRP router into administrative shutdown\n")
328{
329 if (adv)
330 vd.advertisement_interval = no ? VRRP_DEFAULT_ADVINT : advint;
331 if (p)
332 vd.preempt_mode = !no;
333 if (prio)
334 vd.priority = no ? VRRP_DEFAULT_PRIORITY : prioval;
335 if (s)
336 vd.shutdown = !no;
337
338 return CMD_SUCCESS;
339}
340
6332c77f
QY
341/* clang-format on */
342
6e21b5ae
QY
343/*
344 * Build JSON representation of VRRP instance.
345 *
346 * vr
347 * VRRP router to build json object from
348 *
349 * Returns:
350 * JSON representation of VRRP instance. Must be freed by caller.
351 */
352static struct json_object *vrrp_build_json(struct vrrp_vrouter *vr)
353{
354 char ethstr4[ETHER_ADDR_STRLEN];
355 char ethstr6[ETHER_ADDR_STRLEN];
356 char ipstr[INET6_ADDRSTRLEN];
357 const char *stastr4 = vrrp_state_names[vr->v4->fsm.state];
358 const char *stastr6 = vrrp_state_names[vr->v6->fsm.state];
23804b4f
QY
359 char sipstr4[INET6_ADDRSTRLEN] = {};
360 char sipstr6[INET6_ADDRSTRLEN] = {};
6e21b5ae
QY
361 struct listnode *ln;
362 struct ipaddr *ip;
363 struct json_object *j = json_object_new_object();
364 struct json_object *v4 = json_object_new_object();
6332c77f 365 struct json_object *v4_stats = json_object_new_object();
6e21b5ae
QY
366 struct json_object *v4_addrs = json_object_new_array();
367 struct json_object *v6 = json_object_new_object();
6332c77f 368 struct json_object *v6_stats = json_object_new_object();
6e21b5ae
QY
369 struct json_object *v6_addrs = json_object_new_array();
370
371 prefix_mac2str(&vr->v4->vmac, ethstr4, sizeof(ethstr4));
372 prefix_mac2str(&vr->v6->vmac, ethstr6, sizeof(ethstr6));
373
374 json_object_int_add(j, "vrid", vr->vrid);
375 json_object_int_add(j, "version", vr->version);
376 json_object_boolean_add(j, "autoconfigured", vr->autoconf);
377 json_object_boolean_add(j, "shutdown", vr->shutdown);
b1d7f513
QY
378 json_object_boolean_add(j, "preemptMode", vr->preempt_mode);
379 json_object_boolean_add(j, "acceptMode", vr->accept_mode);
6e21b5ae 380 json_object_string_add(j, "interface", vr->ifp->name);
0a7b203e
QY
381 json_object_int_add(j, "advertisementInterval",
382 vr->advertisement_interval * CS2MS);
6e21b5ae
QY
383 /* v4 */
384 json_object_string_add(v4, "interface",
385 vr->v4->mvl_ifp ? vr->v4->mvl_ifp->name : "");
386 json_object_string_add(v4, "vmac", ethstr4);
23804b4f
QY
387 ipaddr2str(&vr->v4->src, sipstr4, sizeof(sipstr4));
388 json_object_string_add(v4, "primaryAddress", sipstr4);
6e21b5ae 389 json_object_string_add(v4, "status", stastr4);
b1d7f513
QY
390 json_object_int_add(v4, "effectivePriority", vr->v4->priority);
391 json_object_int_add(v4, "masterAdverInterval",
cb44d476
QY
392 vr->v4->master_adver_interval * CS2MS);
393 json_object_int_add(v4, "skewTime", vr->v4->skew_time * CS2MS);
b1d7f513 394 json_object_int_add(v4, "masterDownInterval",
cb44d476 395 vr->v4->master_down_interval * CS2MS);
6332c77f
QY
396 /* v4 stats */
397 json_object_int_add(v4_stats, "adverTx", vr->v4->stats.adver_tx_cnt);
398 json_object_int_add(v4_stats, "adverRx", vr->v4->stats.adver_rx_cnt);
399 json_object_int_add(v4_stats, "garpTx", vr->v4->stats.garp_tx_cnt);
400 json_object_int_add(v4_stats, "transitions", vr->v4->stats.trans_cnt);
401 json_object_object_add(v4, "stats", v4_stats);
402 /* v4 addrs */
6e21b5ae
QY
403 if (vr->v4->addrs->count) {
404 for (ALL_LIST_ELEMENTS_RO(vr->v4->addrs, ln, ip)) {
405 inet_ntop(vr->v4->family, &ip->ipaddr_v4, ipstr,
406 sizeof(ipstr));
407 json_object_array_add(v4_addrs,
408 json_object_new_string(ipstr));
409 }
410 }
411 json_object_object_add(v4, "addresses", v4_addrs);
412 json_object_object_add(j, "v4", v4);
413
414 /* v6 */
415 json_object_string_add(v6, "interface",
416 vr->v6->mvl_ifp ? vr->v6->mvl_ifp->name : "");
417 json_object_string_add(v6, "vmac", ethstr6);
23804b4f
QY
418 ipaddr2str(&vr->v6->src, sipstr6, sizeof(sipstr6));
419 if (strlen(sipstr6) == 0 && vr->v6->src.ip.addr == 0x00)
420 strlcat(sipstr6, "::", sizeof(sipstr6));
421 json_object_string_add(v6, "primaryAddress", sipstr6);
6e21b5ae 422 json_object_string_add(v6, "status", stastr6);
b1d7f513
QY
423 json_object_int_add(v6, "effectivePriority", vr->v6->priority);
424 json_object_int_add(v6, "masterAdverInterval",
cb44d476
QY
425 vr->v6->master_adver_interval * CS2MS);
426 json_object_int_add(v6, "skewTime", vr->v6->skew_time * CS2MS);
b1d7f513 427 json_object_int_add(v6, "masterDownInterval",
cb44d476 428 vr->v6->master_down_interval * CS2MS);
6332c77f
QY
429 /* v6 stats */
430 json_object_int_add(v6_stats, "adverTx", vr->v6->stats.adver_tx_cnt);
431 json_object_int_add(v6_stats, "adverRx", vr->v6->stats.adver_rx_cnt);
432 json_object_int_add(v6_stats, "neighborAdverTx",
433 vr->v6->stats.una_tx_cnt);
434 json_object_int_add(v6_stats, "transitions", vr->v6->stats.trans_cnt);
435 json_object_object_add(v6, "stats", v6_stats);
436 /* v6 addrs */
6e21b5ae
QY
437 if (vr->v6->addrs->count) {
438 for (ALL_LIST_ELEMENTS_RO(vr->v6->addrs, ln, ip)) {
439 inet_ntop(vr->v6->family, &ip->ipaddr_v6, ipstr,
440 sizeof(ipstr));
441 json_object_array_add(v6_addrs,
442 json_object_new_string(ipstr));
443 }
444 }
445 json_object_object_add(v6, "addresses", v6_addrs);
446 json_object_object_add(j, "v6", v6);
447
448 return j;
449}
450
789ce3af
QY
451/*
452 * Dump VRRP instance status to VTY.
453 *
454 * vty
455 * vty to dump to
456 *
457 * vr
458 * VRRP router to dump
459 */
1d21789e 460static void vrrp_show(struct vty *vty, struct vrrp_vrouter *vr)
c23edd74 461{
862f2f37
QY
462 char ethstr4[ETHER_ADDR_STRLEN];
463 char ethstr6[ETHER_ADDR_STRLEN];
464 char ipstr[INET6_ADDRSTRLEN];
465 const char *stastr4 = vrrp_state_names[vr->v4->fsm.state];
466 const char *stastr6 = vrrp_state_names[vr->v6->fsm.state];
23804b4f
QY
467 char sipstr4[INET6_ADDRSTRLEN] = {};
468 char sipstr6[INET6_ADDRSTRLEN] = {};
862f2f37
QY
469 struct listnode *ln;
470 struct ipaddr *ip;
c23edd74
QY
471
472 struct ttable *tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
473
474 ttable_add_row(tt, "%s|%" PRIu32, "Virtual Router ID", vr->vrid);
99966840 475 ttable_add_row(tt, "%s|%" PRIu8, "Protocol Version", vr->version);
27fd8827
QY
476 ttable_add_row(tt, "%s|%s", "Autoconfigured",
477 vr->autoconf ? "Yes" : "No");
f96a183b 478 ttable_add_row(tt, "%s|%s", "Shutdown", vr->shutdown ? "Yes" : "No");
5302f67b 479 ttable_add_row(tt, "%s|%s", "Interface", vr->ifp->name);
862f2f37
QY
480 prefix_mac2str(&vr->v4->vmac, ethstr4, sizeof(ethstr4));
481 prefix_mac2str(&vr->v6->vmac, ethstr6, sizeof(ethstr6));
5302f67b
QY
482 ttable_add_row(tt, "%s|%s", "VRRP interface (v4)",
483 vr->v4->mvl_ifp ? vr->v4->mvl_ifp->name : "None");
484 ttable_add_row(tt, "%s|%s", "VRRP interface (v6)",
485 vr->v6->mvl_ifp ? vr->v6->mvl_ifp->name : "None");
c7e65c4f
QY
486 ipaddr2str(&vr->v4->src, sipstr4, sizeof(sipstr4));
487 ipaddr2str(&vr->v6->src, sipstr6, sizeof(sipstr6));
23804b4f
QY
488 if (strlen(sipstr6) == 0 && vr->v6->src.ip.addr == 0x00)
489 strlcat(sipstr6, "::", sizeof(sipstr6));
c7e65c4f
QY
490 ttable_add_row(tt, "%s|%s", "Primary IP (v4)", sipstr4);
491 ttable_add_row(tt, "%s|%s", "Primary IP (v6)", sipstr6);
862f2f37
QY
492 ttable_add_row(tt, "%s|%s", "Virtual MAC (v4)", ethstr4);
493 ttable_add_row(tt, "%s|%s", "Virtual MAC (v6)", ethstr6);
494 ttable_add_row(tt, "%s|%s", "Status (v4)", stastr4);
495 ttable_add_row(tt, "%s|%s", "Status (v6)", stastr6);
c23edd74 496 ttable_add_row(tt, "%s|%" PRIu8, "Priority", vr->priority);
862f2f37
QY
497 ttable_add_row(tt, "%s|%" PRIu8, "Effective Priority (v4)",
498 vr->v4->priority);
499 ttable_add_row(tt, "%s|%" PRIu8, "Effective Priority (v6)",
500 vr->v6->priority);
c23edd74
QY
501 ttable_add_row(tt, "%s|%s", "Preempt Mode",
502 vr->preempt_mode ? "Yes" : "No");
503 ttable_add_row(tt, "%s|%s", "Accept Mode",
504 vr->accept_mode ? "Yes" : "No");
cb44d476
QY
505 ttable_add_row(tt, "%s|%d ms", "Advertisement Interval",
506 vr->advertisement_interval * CS2MS);
507 ttable_add_row(tt, "%s|%d ms",
789ce3af 508 "Master Advertisement Interval (v4)",
cb44d476
QY
509 vr->v4->master_adver_interval * CS2MS);
510 ttable_add_row(tt, "%s|%d ms",
789ce3af 511 "Master Advertisement Interval (v6)",
cb44d476 512 vr->v6->master_adver_interval * CS2MS);
6332c77f
QY
513 ttable_add_row(tt, "%s|%" PRIu32, "Advertisements Tx (v4)",
514 vr->v4->stats.adver_tx_cnt);
515 ttable_add_row(tt, "%s|%" PRIu32, "Advertisements Tx (v6)",
516 vr->v6->stats.adver_tx_cnt);
517 ttable_add_row(tt, "%s|%" PRIu32, "Advertisements Rx (v4)",
518 vr->v4->stats.adver_rx_cnt);
519 ttable_add_row(tt, "%s|%" PRIu32, "Advertisements Rx (v6)",
520 vr->v6->stats.adver_rx_cnt);
521 ttable_add_row(tt, "%s|%" PRIu32, "Gratuitous ARP Tx (v4)",
522 vr->v4->stats.garp_tx_cnt);
523 ttable_add_row(tt, "%s|%" PRIu32, "Neigh. Adverts Tx (v6)",
524 vr->v6->stats.una_tx_cnt);
525 ttable_add_row(tt, "%s|%" PRIu32, "State transitions (v4)",
526 vr->v4->stats.trans_cnt);
527 ttable_add_row(tt, "%s|%" PRIu32, "State transitions (v6)",
528 vr->v6->stats.trans_cnt);
cb44d476
QY
529 ttable_add_row(tt, "%s|%d ms", "Skew Time (v4)",
530 vr->v4->skew_time * CS2MS);
531 ttable_add_row(tt, "%s|%d ms", "Skew Time (v6)",
532 vr->v6->skew_time * CS2MS);
533 ttable_add_row(tt, "%s|%d ms", "Master Down Interval (v4)",
534 vr->v4->master_down_interval * CS2MS);
535 ttable_add_row(tt, "%s|%d ms", "Master Down Interval (v6)",
536 vr->v6->master_down_interval * CS2MS);
862f2f37 537 ttable_add_row(tt, "%s|%u", "IPv4 Addresses", vr->v4->addrs->count);
c23edd74 538
92c399a4 539 char fill[35];
2fff50ec 540
5302f67b
QY
541 memset(fill, '.', sizeof(fill));
542 fill[sizeof(fill) - 1] = 0x00;
862f2f37 543 if (vr->v4->addrs->count) {
862f2f37
QY
544 for (ALL_LIST_ELEMENTS_RO(vr->v4->addrs, ln, ip)) {
545 inet_ntop(vr->v4->family, &ip->ipaddr_v4, ipstr,
546 sizeof(ipstr));
5302f67b 547 ttable_add_row(tt, "%s|%s", fill, ipstr);
862f2f37 548 }
862f2f37
QY
549 }
550
5302f67b
QY
551 ttable_add_row(tt, "%s|%u", "IPv6 Addresses", vr->v6->addrs->count);
552
862f2f37 553 if (vr->v6->addrs->count) {
862f2f37
QY
554 for (ALL_LIST_ELEMENTS_RO(vr->v6->addrs, ln, ip)) {
555 inet_ntop(vr->v6->family, &ip->ipaddr_v6, ipstr,
556 sizeof(ipstr));
5302f67b 557 ttable_add_row(tt, "%s|%s", fill, ipstr);
c23edd74 558 }
c23edd74 559 }
5302f67b
QY
560
561 char *table = ttable_dump(tt, "\n");
2fff50ec 562
5302f67b
QY
563 vty_out(vty, "\n%s\n", table);
564 XFREE(MTYPE_TMP, table);
565 ttable_del(tt);
1d21789e
QY
566}
567
6332c77f
QY
568/* clang-format off */
569
1d21789e
QY
570DEFPY(vrrp_vrid_show,
571 vrrp_vrid_show_cmd,
6e21b5ae 572 "show vrrp [interface INTERFACE$ifn] [(1-255)$vrid] [json$json]",
1d21789e
QY
573 SHOW_STR
574 VRRP_STR
4f0b6b45
QY
575 INTERFACE_STR
576 "Only show VRRP instances on this interface\n"
6e21b5ae
QY
577 VRRP_VRID_STR
578 JSON_STR)
1d21789e
QY
579{
580 struct vrrp_vrouter *vr;
4f0b6b45
QY
581 struct listnode *ln;
582 struct list *ll = hash_to_list(vrrp_vrouters_hash);
6e21b5ae 583 struct json_object *j = json_object_new_array();
1d21789e 584
4f0b6b45
QY
585 for (ALL_LIST_ELEMENTS_RO(ll, ln, vr)) {
586 if (ifn && !strmatch(ifn, vr->ifp->name))
587 continue;
48cd8f13 588 if (vrid && ((uint8_t) vrid) != vr->vrid)
4f0b6b45 589 continue;
5302f67b 590
6e21b5ae
QY
591 if (!json)
592 vrrp_show(vty, vr);
593 else
594 json_object_array_add(j, vrrp_build_json(vr));
1d21789e 595 }
c23edd74 596
6e21b5ae
QY
597 if (json)
598 vty_out(vty, "%s\n",
599 json_object_to_json_string_ext(
600 j, JSON_C_TO_STRING_PRETTY));
601
602 json_object_free(j);
603
4f0b6b45
QY
604 list_delete(&ll);
605
c23edd74
QY
606 return CMD_SUCCESS;
607}
608
78fb3dbe
QY
609
610DEFPY(debug_vrrp,
611 debug_vrrp_cmd,
612 "[no] debug vrrp [{protocol$proto|autoconfigure$ac|packets$pkt|sockets$sock|ndisc$ndisc|arp$arp|zebra$zebra}]",
613 NO_STR
614 DEBUG_STR
615 VRRP_STR
616 "Debug protocol state\n"
617 "Debug autoconfiguration\n"
618 "Debug sent and received packets\n"
619 "Debug socket creation and configuration\n"
620 "Debug Neighbor Discovery\n"
621 "Debug ARP\n"
622 "Debug Zebra events\n")
623{
624 /* If no specific are given on/off them all */
625 if (strmatch(argv[argc - 1]->text, "vrrp"))
626 vrrp_debug_set(NULL, 0, vty->node, !no, true, true, true, true,
627 true, true, true);
628 else
629 vrrp_debug_set(NULL, 0, vty->node, !no, !!proto, !!ac, !!pkt,
630 !!sock, !!ndisc, !!arp, !!zebra);
631
632 return CMD_SUCCESS;
633}
634
635DEFUN_NOSH (show_debugging_vrrp,
636 show_debugging_vrrp_cmd,
637 "show debugging [vrrp]",
638 SHOW_STR
639 DEBUG_STR
640 "VRRP information\n")
641{
642 vty_out(vty, "VRRP debugging status:\n");
643
644 vrrp_debug_status_write(vty);
645
646 return CMD_SUCCESS;
647}
648
b637bcd4
QY
649/* clang-format on */
650
f828842a 651static struct cmd_node interface_node = {INTERFACE_NODE, "%s(config-if)# ", 1};
78fb3dbe 652static struct cmd_node debug_node = {DEBUG_NODE, "", 1};
f828842a 653static struct cmd_node vrrp_node = {VRRP_NODE, "", 1};
78fb3dbe 654
5435a2bf
QY
655void vrrp_vty_init(void)
656{
f828842a
QY
657 install_node(&debug_node, vrrp_config_write_debug);
658 install_node(&interface_node, vrrp_config_write_interface);
659 install_node(&vrrp_node, vrrp_config_write_global);
5435a2bf 660 if_cmd_init();
78fb3dbe 661
c23edd74 662 install_element(VIEW_NODE, &vrrp_vrid_show_cmd);
78fb3dbe
QY
663 install_element(VIEW_NODE, &show_debugging_vrrp_cmd);
664 install_element(VIEW_NODE, &debug_vrrp_cmd);
665 install_element(CONFIG_NODE, &debug_vrrp_cmd);
27fd8827 666 install_element(CONFIG_NODE, &vrrp_autoconfigure_cmd);
8cd1d277 667 install_element(CONFIG_NODE, &vrrp_default_cmd);
5435a2bf 668 install_element(INTERFACE_NODE, &vrrp_vrid_cmd);
f96a183b 669 install_element(INTERFACE_NODE, &vrrp_shutdown_cmd);
c23edd74 670 install_element(INTERFACE_NODE, &vrrp_priority_cmd);
1d21789e 671 install_element(INTERFACE_NODE, &vrrp_advertisement_interval_cmd);
c23edd74 672 install_element(INTERFACE_NODE, &vrrp_ip_cmd);
862f2f37 673 install_element(INTERFACE_NODE, &vrrp_ip6_cmd);
8ec51216 674 install_element(INTERFACE_NODE, &vrrp_preempt_cmd);
5435a2bf 675}