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"
25 #include "lib/prefix.h"
26 #include "lib/termtable.h"
30 #include "vrrp_debug.h"
31 #include "vrrp_memory.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
? VRRP_DEFAULT_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 (1-4096)",
140 NO_STR VRRP_STR VRRP_VRID_STR VRRP_ADVINT_STR
141 "Advertisement interval in centiseconds")
143 VTY_DECLVAR_CONTEXT(interface
, ifp
);
145 struct vrrp_vrouter
*vr
;
146 uint16_t newadvint
= no
? VRRP_DEFAULT_ADVINT
: advertisement_interval
;
148 VROUTER_GET_VTY(vty
, ifp
, vrid
, vr
);
149 vrrp_set_advertisement_interval(vr
, newadvint
);
156 "[no] vrrp (1-255)$vrid ip A.B.C.D",
163 VTY_DECLVAR_CONTEXT(interface
, ifp
);
165 struct vrrp_vrouter
*vr
;
166 bool deactivated
= false;
167 bool activated
= false;
169 int ret
= CMD_SUCCESS
;
171 VROUTER_GET_VTY(vty
, ifp
, vrid
, vr
);
173 bool will_activate
= (vr
->v4
->fsm
.state
== VRRP_STATE_INITIALIZE
);
176 int oldstate
= vr
->v4
->fsm
.state
;
177 failed
= vrrp_del_ipv4(vr
, ip
);
178 vrrp_check_start(vr
);
179 deactivated
= (vr
->v4
->fsm
.state
== VRRP_STATE_INITIALIZE
180 && oldstate
!= VRRP_STATE_INITIALIZE
);
182 int oldstate
= vr
->v4
->fsm
.state
;
183 failed
= vrrp_add_ipv4(vr
, ip
);
184 vrrp_check_start(vr
);
185 activated
= (vr
->v4
->fsm
.state
!= VRRP_STATE_INITIALIZE
186 && oldstate
== VRRP_STATE_INITIALIZE
);
190 vty_out(vty
, "%% Activated IPv4 Virtual Router %ld\n", vrid
);
192 vty_out(vty
, "%% Deactivated IPv4 Virtual Router %ld\n", vrid
);
194 vty_out(vty
, "%% Failed to %s virtual IP\n",
195 no
? "remove" : "add");
196 ret
= CMD_WARNING_CONFIG_FAILED
;
197 if (will_activate
&& !activated
) {
199 "%% Failed to activate IPv4 Virtual Router %ld\n",
209 "[no] vrrp (1-255)$vrid ipv6 X:X::X:X",
216 VTY_DECLVAR_CONTEXT(interface
, ifp
);
218 struct vrrp_vrouter
*vr
;
219 bool deactivated
= false;
220 bool activated
= false;
222 int ret
= CMD_SUCCESS
;
224 VROUTER_GET_VTY(vty
, ifp
, vrid
, vr
);
226 if (vr
->version
!= 3) {
228 "%% Cannot add IPv6 address to VRRPv2 virtual router\n");
229 return CMD_WARNING_CONFIG_FAILED
;
232 bool will_activate
= (vr
->v6
->fsm
.state
== VRRP_STATE_INITIALIZE
);
235 int oldstate
= vr
->v6
->fsm
.state
;
236 failed
= vrrp_del_ipv6(vr
, ipv6
);
237 deactivated
= (vr
->v6
->fsm
.state
== VRRP_STATE_INITIALIZE
238 && oldstate
!= VRRP_STATE_INITIALIZE
);
240 int oldstate
= vr
->v6
->fsm
.state
;
241 failed
= vrrp_add_ipv6(vr
, ipv6
);
242 activated
= (vr
->v6
->fsm
.state
!= VRRP_STATE_INITIALIZE
243 && oldstate
== VRRP_STATE_INITIALIZE
);
247 vty_out(vty
, "%% Activated IPv6 Virtual Router %ld\n", vrid
);
249 vty_out(vty
, "%% Deactivated IPv6 Virtual Router %ld\n", vrid
);
251 vty_out(vty
, "%% Failed to %s virtual IP\n",
252 no
? "remove" : "add");
253 ret
= CMD_WARNING_CONFIG_FAILED
;
254 if (will_activate
&& !activated
) {
256 "%% Failed to activate IPv6 Virtual Router %ld\n",
266 "[no] vrrp (1-255)$vrid preempt",
272 VTY_DECLVAR_CONTEXT(interface
, ifp
);
274 struct vrrp_vrouter
*vr
;
276 VROUTER_GET_VTY(vty
, ifp
, vrid
, vr
);
278 vr
->preempt_mode
= !no
;
283 DEFPY(vrrp_autoconfigure
,
284 vrrp_autoconfigure_cmd
,
285 "[no] vrrp autoconfigure [version (2-3)]",
288 "Automatically set up VRRP instances on VRRP-compatible interfaces\n"
289 "Version for automatically configured instances\n"
292 version
= version
? version
: 3;
295 vrrp_autoconfig_on(version
);
297 vrrp_autoconfig_off();
302 static void vrrp_show(struct vty
*vty
, struct vrrp_vrouter
*vr
)
304 char ethstr4
[ETHER_ADDR_STRLEN
];
305 char ethstr6
[ETHER_ADDR_STRLEN
];
306 char ipstr
[INET6_ADDRSTRLEN
];
307 const char *stastr4
= vrrp_state_names
[vr
->v4
->fsm
.state
];
308 const char *stastr6
= vrrp_state_names
[vr
->v6
->fsm
.state
];
312 struct ttable
*tt
= ttable_new(&ttable_styles
[TTSTYLE_BLANK
]);
314 ttable_add_row(tt
, "%s|%" PRIu32
, "Virtual Router ID", vr
->vrid
);
315 ttable_add_row(tt
, "%s|%" PRIu8
, "Protocol Version", vr
->version
);
316 ttable_add_row(tt
, "%s|%s", "Autoconfigured",
317 vr
->autoconf
? "Yes" : "No");
318 ttable_add_row(tt
, "%s|%s", "Shutdown", vr
->shutdown
? "Yes" : "No");
319 ttable_add_row(tt
, "%s|%s", "Interface", vr
->ifp
->name
);
320 prefix_mac2str(&vr
->v4
->vmac
, ethstr4
, sizeof(ethstr4
));
321 prefix_mac2str(&vr
->v6
->vmac
, ethstr6
, sizeof(ethstr6
));
322 ttable_add_row(tt
, "%s|%s", "VRRP interface (v4)",
323 vr
->v4
->mvl_ifp
? vr
->v4
->mvl_ifp
->name
: "None");
324 ttable_add_row(tt
, "%s|%s", "VRRP interface (v6)",
325 vr
->v6
->mvl_ifp
? vr
->v6
->mvl_ifp
->name
: "None");
326 ttable_add_row(tt
, "%s|%s", "Virtual MAC (v4)", ethstr4
);
327 ttable_add_row(tt
, "%s|%s", "Virtual MAC (v6)", ethstr6
);
328 ttable_add_row(tt
, "%s|%s", "Status (v4)", stastr4
);
329 ttable_add_row(tt
, "%s|%s", "Status (v6)", stastr6
);
330 ttable_add_row(tt
, "%s|%" PRIu8
, "Priority", vr
->priority
);
331 ttable_add_row(tt
, "%s|%" PRIu8
, "Effective Priority (v4)",
333 ttable_add_row(tt
, "%s|%" PRIu8
, "Effective Priority (v6)",
335 ttable_add_row(tt
, "%s|%s", "Preempt Mode",
336 vr
->preempt_mode
? "Yes" : "No");
337 ttable_add_row(tt
, "%s|%s", "Accept Mode",
338 vr
->accept_mode
? "Yes" : "No");
339 ttable_add_row(tt
, "%s|%" PRIu16
" cs", "Advertisement Interval",
340 vr
->advertisement_interval
);
341 ttable_add_row(tt
, "%s|%" PRIu16
" cs", "Master Advertisement Interval (v4)",
342 vr
->v4
->master_adver_interval
);
343 ttable_add_row(tt
, "%s|%" PRIu16
" cs", "Master Advertisement Interval (v6)",
344 vr
->v6
->master_adver_interval
);
345 ttable_add_row(tt
, "%s|%" PRIu16
" cs", "Skew Time (v4)", vr
->v4
->skew_time
);
346 ttable_add_row(tt
, "%s|%" PRIu16
" cs", "Skew Time (v6)", vr
->v6
->skew_time
);
347 ttable_add_row(tt
, "%s|%" PRIu16
" cs", "Master Down Interval (v4)",
348 vr
->v4
->master_down_interval
);
349 ttable_add_row(tt
, "%s|%" PRIu16
" cs", "Master Down Interval (v6)",
350 vr
->v6
->master_down_interval
);
351 ttable_add_row(tt
, "%s|%u", "IPv4 Addresses", vr
->v4
->addrs
->count
);
354 memset(fill
, '.', sizeof(fill
));
355 fill
[sizeof(fill
) - 1] = 0x00;
356 if (vr
->v4
->addrs
->count
) {
357 for (ALL_LIST_ELEMENTS_RO(vr
->v4
->addrs
, ln
, ip
)) {
358 inet_ntop(vr
->v4
->family
, &ip
->ipaddr_v4
, ipstr
,
360 ttable_add_row(tt
, "%s|%s", fill
, ipstr
);
364 ttable_add_row(tt
, "%s|%u", "IPv6 Addresses", vr
->v6
->addrs
->count
);
366 if (vr
->v6
->addrs
->count
) {
367 for (ALL_LIST_ELEMENTS_RO(vr
->v6
->addrs
, ln
, ip
)) {
368 inet_ntop(vr
->v6
->family
, &ip
->ipaddr_v6
, ipstr
,
370 ttable_add_row(tt
, "%s|%s", fill
, ipstr
);
374 char *table
= ttable_dump(tt
, "\n");
375 vty_out(vty
, "\n%s\n", table
);
376 XFREE(MTYPE_TMP
, table
);
381 DEFPY(vrrp_vrid_show
,
383 "show vrrp [interface INTERFACE$ifn] [(1-255)$vrid]",
387 "Only show VRRP instances on this interface\n"
390 struct vrrp_vrouter
*vr
;
392 struct list
*ll
= hash_to_list(vrrp_vrouters_hash
);
394 for (ALL_LIST_ELEMENTS_RO(ll
, ln
, vr
)) {
395 if (ifn
&& !strmatch(ifn
, vr
->ifp
->name
))
397 if (vrid
&& vrid
!= vr
->vrid
)
411 "[no] debug vrrp [{protocol$proto|autoconfigure$ac|packets$pkt|sockets$sock|ndisc$ndisc|arp$arp|zebra$zebra}]",
415 "Debug protocol state\n"
416 "Debug autoconfiguration\n"
417 "Debug sent and received packets\n"
418 "Debug socket creation and configuration\n"
419 "Debug Neighbor Discovery\n"
421 "Debug Zebra events\n")
423 /* If no specific are given on/off them all */
424 if (strmatch(argv
[argc
- 1]->text
, "vrrp"))
425 vrrp_debug_set(NULL
, 0, vty
->node
, !no
, true, true, true, true,
428 vrrp_debug_set(NULL
, 0, vty
->node
, !no
, !!proto
, !!ac
, !!pkt
,
429 !!sock
, !!ndisc
, !!arp
, !!zebra
);
434 DEFUN_NOSH (show_debugging_vrrp
,
435 show_debugging_vrrp_cmd
,
436 "show debugging [vrrp]",
439 "VRRP information\n")
441 vty_out(vty
, "VRRP debugging status:\n");
443 vrrp_debug_status_write(vty
);
448 /* clang-format on */
450 static struct cmd_node interface_node
= {INTERFACE_NODE
, "%s(config-if)# ", 1};
451 static struct cmd_node debug_node
= {DEBUG_NODE
, "", 1};
452 static struct cmd_node vrrp_node
= {VRRP_NODE
, "", 1};
454 void vrrp_vty_init(void)
456 install_node(&debug_node
, vrrp_config_write_debug
);
457 install_node(&interface_node
, vrrp_config_write_interface
);
458 install_node(&vrrp_node
, vrrp_config_write_global
);
461 install_element(VIEW_NODE
, &vrrp_vrid_show_cmd
);
462 install_element(VIEW_NODE
, &show_debugging_vrrp_cmd
);
463 install_element(VIEW_NODE
, &debug_vrrp_cmd
);
464 install_element(CONFIG_NODE
, &debug_vrrp_cmd
);
465 install_element(CONFIG_NODE
, &vrrp_autoconfigure_cmd
);
466 install_element(INTERFACE_NODE
, &vrrp_vrid_cmd
);
467 install_element(INTERFACE_NODE
, &vrrp_shutdown_cmd
);
468 install_element(INTERFACE_NODE
, &vrrp_priority_cmd
);
469 install_element(INTERFACE_NODE
, &vrrp_advertisement_interval_cmd
);
470 install_element(INTERFACE_NODE
, &vrrp_ip_cmd
);
471 install_element(INTERFACE_NODE
, &vrrp_ip6_cmd
);
472 install_element(INTERFACE_NODE
, &vrrp_preempt_cmd
);