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; \
58 "[no] vrrp (1-255)$vrid [version (2-3)]",
65 VTY_DECLVAR_CONTEXT(interface
, ifp
);
67 struct vrrp_vrouter
*vr
= vrrp_lookup(ifp
, vrid
);
73 vrrp_vrouter_destroy(vr
);
75 vty_out(vty
, "%% VRRP instance %ld does not exist on %s\n",
78 vrrp_vrouter_create(ifp
, vrid
, version
);
80 vty_out(vty
, "%% VRRP instance %ld already exists on %s\n",
88 "[no] vrrp (1-255)$vrid priority (1-254)",
95 VTY_DECLVAR_CONTEXT(interface
, ifp
);
97 struct vrrp_vrouter
*vr
;
98 uint8_t newprio
= no
? VRRP_DEFAULT_PRIORITY
: priority
;
100 VROUTER_GET_VTY(vty
, ifp
, vrid
, vr
);
102 vrrp_set_priority(vr
, newprio
);
107 DEFPY(vrrp_advertisement_interval
,
108 vrrp_advertisement_interval_cmd
,
109 "[no] vrrp (1-255)$vrid advertisement-interval (1-4096)",
110 NO_STR VRRP_STR VRRP_VRID_STR VRRP_ADVINT_STR
111 "Advertisement interval in centiseconds")
113 VTY_DECLVAR_CONTEXT(interface
, ifp
);
115 struct vrrp_vrouter
*vr
;
116 uint16_t newadvint
= no
? VRRP_DEFAULT_ADVINT
: advertisement_interval
;
118 VROUTER_GET_VTY(vty
, ifp
, vrid
, vr
);
119 vrrp_set_advertisement_interval(vr
, newadvint
);
126 "[no] vrrp (1-255)$vrid ip A.B.C.D",
133 VTY_DECLVAR_CONTEXT(interface
, ifp
);
135 struct vrrp_vrouter
*vr
;
136 bool deactivated
= false;
137 bool activated
= false;
139 int ret
= CMD_SUCCESS
;
141 VROUTER_GET_VTY(vty
, ifp
, vrid
, vr
);
143 bool will_activate
= (vr
->v4
->fsm
.state
== VRRP_STATE_INITIALIZE
);
146 int oldstate
= vr
->v4
->fsm
.state
;
147 failed
= vrrp_del_ipv4(vr
, ip
, true);
148 deactivated
= (vr
->v4
->fsm
.state
== VRRP_STATE_INITIALIZE
149 && oldstate
!= VRRP_STATE_INITIALIZE
);
151 int oldstate
= vr
->v4
->fsm
.state
;
152 failed
= vrrp_add_ipv4(vr
, ip
, true);
153 activated
= (vr
->v4
->fsm
.state
!= VRRP_STATE_INITIALIZE
154 && oldstate
== VRRP_STATE_INITIALIZE
);
158 vty_out(vty
, "%% Activated IPv4 Virtual Router %ld\n", vrid
);
160 vty_out(vty
, "%% Deactivated IPv4 Virtual Router %ld\n", vrid
);
162 vty_out(vty
, "%% Failed to %s virtual IP\n",
163 no
? "remove" : "add");
164 ret
= CMD_WARNING_CONFIG_FAILED
;
165 if (will_activate
&& !activated
) {
167 "%% Failed to activate IPv4 Virtual Router %ld\n",
177 "[no] vrrp (1-255)$vrid ipv6 X:X::X:X",
184 VTY_DECLVAR_CONTEXT(interface
, ifp
);
186 struct vrrp_vrouter
*vr
;
187 bool deactivated
= false;
188 bool activated
= false;
190 int ret
= CMD_SUCCESS
;
192 VROUTER_GET_VTY(vty
, ifp
, vrid
, vr
);
194 if (vr
->version
!= 3) {
196 "%% Cannot add IPv6 address to VRRPv2 virtual router\n");
197 return CMD_WARNING_CONFIG_FAILED
;
200 bool will_activate
= (vr
->v6
->fsm
.state
== VRRP_STATE_INITIALIZE
);
203 int oldstate
= vr
->v6
->fsm
.state
;
204 failed
= vrrp_del_ipv6(vr
, ipv6
, true);
205 deactivated
= (vr
->v6
->fsm
.state
== VRRP_STATE_INITIALIZE
206 && oldstate
!= VRRP_STATE_INITIALIZE
);
208 int oldstate
= vr
->v6
->fsm
.state
;
209 failed
= vrrp_add_ipv6(vr
, ipv6
, true);
210 activated
= (vr
->v6
->fsm
.state
!= VRRP_STATE_INITIALIZE
211 && oldstate
== VRRP_STATE_INITIALIZE
);
215 vty_out(vty
, "%% Activated IPv6 Virtual Router %ld\n", vrid
);
217 vty_out(vty
, "%% Deactivated IPv6 Virtual Router %ld\n", vrid
);
219 vty_out(vty
, "%% Failed to %s virtual IP",
220 no
? "remove" : "add");
221 ret
= CMD_WARNING_CONFIG_FAILED
;
222 if (will_activate
&& !activated
) {
224 "%% Failed to activate IPv4 Virtual Router %ld\n",
234 "[no] vrrp (1-255)$vrid preempt",
240 VTY_DECLVAR_CONTEXT(interface
, ifp
);
242 struct vrrp_vrouter
*vr
;
244 VROUTER_GET_VTY(vty
, ifp
, vrid
, vr
);
246 vr
->preempt_mode
= !no
;
251 DEFPY(vrrp_autoconfigure
,
252 vrrp_autoconfigure_cmd
,
253 "[no] vrrp autoconfigure [version (2-3)]",
256 "Automatically set up VRRP instances on VRRP-compatible interfaces\n"
257 "Version for automatically configured instances\n"
260 version
= version
? version
: 3;
263 vrrp_autoconfig_on(version
);
265 vrrp_autoconfig_off();
270 static void vrrp_show(struct vty
*vty
, struct vrrp_vrouter
*vr
)
272 char ethstr4
[ETHER_ADDR_STRLEN
];
273 char ethstr6
[ETHER_ADDR_STRLEN
];
274 char ipstr
[INET6_ADDRSTRLEN
];
275 const char *stastr4
= vrrp_state_names
[vr
->v4
->fsm
.state
];
276 const char *stastr6
= vrrp_state_names
[vr
->v6
->fsm
.state
];
280 struct ttable
*tt
= ttable_new(&ttable_styles
[TTSTYLE_BLANK
]);
282 ttable_add_row(tt
, "%s|%" PRIu32
, "Virtual Router ID", vr
->vrid
);
283 ttable_add_row(tt
, "%s|%" PRIu8
, "Protocol Version", vr
->version
);
284 ttable_add_row(tt
, "%s|%s", "Autoconfigured",
285 vr
->autoconf
? "Yes" : "No");
286 ttable_add_row(tt
, "%s|%s", "Interface", vr
->ifp
->name
);
287 prefix_mac2str(&vr
->v4
->vmac
, ethstr4
, sizeof(ethstr4
));
288 prefix_mac2str(&vr
->v6
->vmac
, ethstr6
, sizeof(ethstr6
));
289 ttable_add_row(tt
, "%s|%s", "VRRP interface (v4)",
290 vr
->v4
->mvl_ifp
? vr
->v4
->mvl_ifp
->name
: "None");
291 ttable_add_row(tt
, "%s|%s", "VRRP interface (v6)",
292 vr
->v6
->mvl_ifp
? vr
->v6
->mvl_ifp
->name
: "None");
293 ttable_add_row(tt
, "%s|%s", "Virtual MAC (v4)", ethstr4
);
294 ttable_add_row(tt
, "%s|%s", "Virtual MAC (v6)", ethstr6
);
295 ttable_add_row(tt
, "%s|%s", "Status (v4)", stastr4
);
296 ttable_add_row(tt
, "%s|%s", "Status (v6)", stastr6
);
297 ttable_add_row(tt
, "%s|%" PRIu8
, "Priority", vr
->priority
);
298 ttable_add_row(tt
, "%s|%" PRIu8
, "Effective Priority (v4)",
300 ttable_add_row(tt
, "%s|%" PRIu8
, "Effective Priority (v6)",
302 ttable_add_row(tt
, "%s|%s", "Preempt Mode",
303 vr
->preempt_mode
? "Yes" : "No");
304 ttable_add_row(tt
, "%s|%s", "Accept Mode",
305 vr
->accept_mode
? "Yes" : "No");
306 ttable_add_row(tt
, "%s|%" PRIu16
" cs", "Advertisement Interval",
307 vr
->advertisement_interval
);
308 ttable_add_row(tt
, "%s|%" PRIu16
" cs", "Master Advertisement Interval (v4)",
309 vr
->v4
->master_adver_interval
);
310 ttable_add_row(tt
, "%s|%" PRIu16
" cs", "Master Advertisement Interval (v6)",
311 vr
->v6
->master_adver_interval
);
312 ttable_add_row(tt
, "%s|%" PRIu16
" cs", "Skew Time (v4)", vr
->v4
->skew_time
);
313 ttable_add_row(tt
, "%s|%" PRIu16
" cs", "Skew Time (v6)", vr
->v6
->skew_time
);
314 ttable_add_row(tt
, "%s|%" PRIu16
" cs", "Master Down Interval (v4)",
315 vr
->v4
->master_down_interval
);
316 ttable_add_row(tt
, "%s|%" PRIu16
" cs", "Master Down Interval (v6)",
317 vr
->v6
->master_down_interval
);
318 ttable_add_row(tt
, "%s|%u", "IPv4 Addresses", vr
->v4
->addrs
->count
);
321 memset(fill
, '.', sizeof(fill
));
322 fill
[sizeof(fill
) - 1] = 0x00;
323 if (vr
->v4
->addrs
->count
) {
324 for (ALL_LIST_ELEMENTS_RO(vr
->v4
->addrs
, ln
, ip
)) {
325 inet_ntop(vr
->v4
->family
, &ip
->ipaddr_v4
, ipstr
,
327 ttable_add_row(tt
, "%s|%s", fill
, ipstr
);
331 ttable_add_row(tt
, "%s|%u", "IPv6 Addresses", vr
->v6
->addrs
->count
);
333 if (vr
->v6
->addrs
->count
) {
334 for (ALL_LIST_ELEMENTS_RO(vr
->v6
->addrs
, ln
, ip
)) {
335 inet_ntop(vr
->v6
->family
, &ip
->ipaddr_v6
, ipstr
,
337 ttable_add_row(tt
, "%s|%s", fill
, ipstr
);
341 char *table
= ttable_dump(tt
, "\n");
342 vty_out(vty
, "\n%s\n", table
);
343 XFREE(MTYPE_TMP
, table
);
348 DEFPY(vrrp_vrid_show
,
350 "show vrrp [interface INTERFACE$ifn] [(1-255)$vrid]",
354 "Only show VRRP instances on this interface\n"
357 struct vrrp_vrouter
*vr
;
359 struct list
*ll
= hash_to_list(vrrp_vrouters_hash
);
361 for (ALL_LIST_ELEMENTS_RO(ll
, ln
, vr
)) {
362 if (ifn
&& !strmatch(ifn
, vr
->ifp
->name
))
364 if (vrid
&& vrid
!= vr
->vrid
)
378 "[no] debug vrrp [{protocol$proto|autoconfigure$ac|packets$pkt|sockets$sock|ndisc$ndisc|arp$arp|zebra$zebra}]",
382 "Debug protocol state\n"
383 "Debug autoconfiguration\n"
384 "Debug sent and received packets\n"
385 "Debug socket creation and configuration\n"
386 "Debug Neighbor Discovery\n"
388 "Debug Zebra events\n")
390 /* If no specific are given on/off them all */
391 if (strmatch(argv
[argc
- 1]->text
, "vrrp"))
392 vrrp_debug_set(NULL
, 0, vty
->node
, !no
, true, true, true, true,
395 vrrp_debug_set(NULL
, 0, vty
->node
, !no
, !!proto
, !!ac
, !!pkt
,
396 !!sock
, !!ndisc
, !!arp
, !!zebra
);
401 DEFUN_NOSH (show_debugging_vrrp
,
402 show_debugging_vrrp_cmd
,
403 "show debugging [vrrp]",
406 "VRRP information\n")
408 vty_out(vty
, "VRRP debugging status:\n");
410 vrrp_debug_status_write(vty
);
415 static struct cmd_node interface_node
= {
420 static struct cmd_node debug_node
= {DEBUG_NODE
, "", 1};
422 void vrrp_vty_init(void)
424 install_node(&debug_node
, vrrp_debug_config_write
);
425 install_node(&interface_node
, NULL
);
428 install_element(VIEW_NODE
, &vrrp_vrid_show_cmd
);
429 install_element(VIEW_NODE
, &show_debugging_vrrp_cmd
);
430 install_element(VIEW_NODE
, &debug_vrrp_cmd
);
431 install_element(CONFIG_NODE
, &debug_vrrp_cmd
);
432 install_element(CONFIG_NODE
, &vrrp_autoconfigure_cmd
);
433 install_element(INTERFACE_NODE
, &vrrp_vrid_cmd
);
434 install_element(INTERFACE_NODE
, &vrrp_priority_cmd
);
435 install_element(INTERFACE_NODE
, &vrrp_advertisement_interval_cmd
);
436 install_element(INTERFACE_NODE
, &vrrp_ip_cmd
);
437 install_element(INTERFACE_NODE
, &vrrp_ip6_cmd
);
438 install_element(INTERFACE_NODE
, &vrrp_preempt_cmd
);