]> git.proxmox.com Git - mirror_frr.git/blame - vrrpd/vrrp_vty.c
vrrpd: add debugging knobs
[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"
25#include "lib/prefix.h"
26#include "lib/termtable.h"
27#include "lib/vty.h"
5435a2bf
QY
28
29#include "vrrp.h"
78fb3dbe 30#include "vrrp_debug.h"
5435a2bf 31#include "vrrp_memory.h"
78fb3dbe 32#include "vrrp_vty.h"
c23edd74
QY
33#ifndef VTYSH_EXTRACT_PL
34#include "vrrpd/vrrp_vty_clippy.c"
35#endif
5435a2bf
QY
36
37
38#define VRRP_STR "Virtual Router Redundancy Protocol\n"
39#define VRRP_VRID_STR "Virtual Router ID\n"
c23edd74 40#define VRRP_PRIORITY_STR "Virtual Router Priority\n"
6287cefe 41#define VRRP_ADVINT_STR "Virtual Router Advertisement Interval\n"
c23edd74 42#define VRRP_IP_STR "Virtual Router IPv4 address\n"
99966840 43#define VRRP_VERSION_STR "VRRP protocol version\n"
c23edd74 44
4f0b6b45 45#define VROUTER_GET_VTY(_vty, _ifp, _vrid, _vr) \
c23edd74 46 do { \
4f0b6b45 47 _vr = vrrp_lookup(_ifp, _vrid); \
c23edd74
QY
48 if (!_vr) { \
49 vty_out(_vty, \
50 "%% Please configure VRRP instance %u\n", \
51 (unsigned int)_vrid); \
52 return CMD_WARNING_CONFIG_FAILED; \
53 } \
54 } while (0);
5435a2bf 55
c23edd74 56DEFPY(vrrp_vrid,
5435a2bf 57 vrrp_vrid_cmd,
99966840 58 "[no] vrrp (1-255)$vrid [version (2-3)]",
5435a2bf
QY
59 NO_STR
60 VRRP_STR
99966840
QY
61 VRRP_VRID_STR
62 VRRP_VERSION_STR
63 VRRP_VERSION_STR)
5435a2bf
QY
64{
65 VTY_DECLVAR_CONTEXT(interface, ifp);
5435a2bf 66
4f0b6b45 67 struct vrrp_vrouter *vr = vrrp_lookup(ifp, vrid);
6287cefe 68
99966840
QY
69 if (version == 0)
70 version = 3;
71
6287cefe
QY
72 if (no && vr)
73 vrrp_vrouter_destroy(vr);
74 else if (no && !vr)
75 vty_out(vty, "%% VRRP instance %ld does not exist on %s\n",
76 vrid, ifp->name);
77 else if (!vr)
99966840 78 vrrp_vrouter_create(ifp, vrid, version);
6287cefe
QY
79 else if (vr)
80 vty_out(vty, "%% VRRP instance %ld already exists on %s\n",
81 vrid, ifp->name);
5435a2bf
QY
82
83 return CMD_SUCCESS;
84}
85
c23edd74
QY
86DEFPY(vrrp_priority,
87 vrrp_priority_cmd,
bac08ded 88 "[no] vrrp (1-255)$vrid priority (1-254)",
c23edd74
QY
89 NO_STR
90 VRRP_STR
91 VRRP_VRID_STR
92 VRRP_PRIORITY_STR
bac08ded 93 "Priority value")
c23edd74 94{
4f0b6b45
QY
95 VTY_DECLVAR_CONTEXT(interface, ifp);
96
c23edd74 97 struct vrrp_vrouter *vr;
6287cefe 98 uint8_t newprio = no ? VRRP_DEFAULT_PRIORITY : priority;
c23edd74 99
4f0b6b45 100 VROUTER_GET_VTY(vty, ifp, vrid, vr);
1d21789e 101
6287cefe 102 vrrp_set_priority(vr, newprio);
1d21789e 103
1d21789e
QY
104 return CMD_SUCCESS;
105}
106
107DEFPY(vrrp_advertisement_interval,
108 vrrp_advertisement_interval_cmd,
109 "[no] vrrp (1-255)$vrid advertisement-interval (1-4096)",
6287cefe
QY
110 NO_STR VRRP_STR VRRP_VRID_STR VRRP_ADVINT_STR
111 "Advertisement interval in centiseconds")
1d21789e 112{
4f0b6b45
QY
113 VTY_DECLVAR_CONTEXT(interface, ifp);
114
1d21789e 115 struct vrrp_vrouter *vr;
6287cefe 116 uint16_t newadvint = no ? VRRP_DEFAULT_ADVINT : advertisement_interval;
1d21789e 117
4f0b6b45 118 VROUTER_GET_VTY(vty, ifp, vrid, vr);
6287cefe 119 vrrp_set_advertisement_interval(vr, newadvint);
c23edd74
QY
120
121 return CMD_SUCCESS;
122}
123
124DEFPY(vrrp_ip,
125 vrrp_ip_cmd,
862f2f37 126 "[no] vrrp (1-255)$vrid ip A.B.C.D",
c23edd74
QY
127 NO_STR
128 VRRP_STR
129 VRRP_VRID_STR
862f2f37 130 "Add IPv4 address\n"
c23edd74
QY
131 VRRP_IP_STR)
132{
4f0b6b45
QY
133 VTY_DECLVAR_CONTEXT(interface, ifp);
134
c23edd74 135 struct vrrp_vrouter *vr;
2cd90902
QY
136 bool deactivated = false;
137 bool activated = false;
138 bool failed = false;
139 int ret = CMD_SUCCESS;
c23edd74 140
4f0b6b45 141 VROUTER_GET_VTY(vty, ifp, vrid, vr);
c23edd74 142
2cd90902 143 bool will_activate = (vr->v4->fsm.state == VRRP_STATE_INITIALIZE);
862f2f37 144
2cd90902
QY
145 if (no) {
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);
862f2f37 150 } else {
2cd90902
QY
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);
155 }
156
157 if (activated)
158 vty_out(vty, "%% Activated IPv4 Virtual Router %ld\n", vrid);
159 if (deactivated)
160 vty_out(vty, "%% Deactivated IPv4 Virtual Router %ld\n", vrid);
161 if (failed) {
1af0eb1f 162 vty_out(vty, "%% Failed to %s virtual IP\n",
2cd90902
QY
163 no ? "remove" : "add");
164 ret = CMD_WARNING_CONFIG_FAILED;
165 if (will_activate && !activated) {
166 vty_out(vty,
167 "%% Failed to activate IPv4 Virtual Router %ld\n",
168 vrid);
169 }
862f2f37
QY
170 }
171
172 return ret;
173}
174
175DEFPY(vrrp_ip6,
176 vrrp_ip6_cmd,
177 "[no] vrrp (1-255)$vrid ipv6 X:X::X:X",
178 NO_STR
179 VRRP_STR
180 VRRP_VRID_STR
181 "Add IPv6 address\n"
182 VRRP_IP_STR)
183{
4f0b6b45
QY
184 VTY_DECLVAR_CONTEXT(interface, ifp);
185
862f2f37 186 struct vrrp_vrouter *vr;
2cd90902
QY
187 bool deactivated = false;
188 bool activated = false;
189 bool failed = false;
190 int ret = CMD_SUCCESS;
862f2f37 191
4f0b6b45 192 VROUTER_GET_VTY(vty, ifp, vrid, vr);
862f2f37 193
99966840
QY
194 if (vr->version != 3) {
195 vty_out(vty,
196 "%% Cannot add IPv6 address to VRRPv2 virtual router\n");
197 return CMD_WARNING_CONFIG_FAILED;
198 }
199
2cd90902 200 bool will_activate = (vr->v6->fsm.state == VRRP_STATE_INITIALIZE);
1d21789e 201
2cd90902
QY
202 if (no) {
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);
1d21789e 207 } else {
2cd90902
QY
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);
212 }
213
214 if (activated)
215 vty_out(vty, "%% Activated IPv6 Virtual Router %ld\n", vrid);
216 if (deactivated)
217 vty_out(vty, "%% Deactivated IPv6 Virtual Router %ld\n", vrid);
218 if (failed) {
219 vty_out(vty, "%% Failed to %s virtual IP",
220 no ? "remove" : "add");
221 ret = CMD_WARNING_CONFIG_FAILED;
222 if (will_activate && !activated) {
223 vty_out(vty,
224 "%% Failed to activate IPv4 Virtual Router %ld\n",
225 vrid);
226 }
1d21789e
QY
227 }
228
229 return ret;
c23edd74
QY
230}
231
8ec51216
QY
232DEFPY(vrrp_preempt,
233 vrrp_preempt_cmd,
234 "[no] vrrp (1-255)$vrid preempt",
235 NO_STR
236 VRRP_STR
237 VRRP_VRID_STR
238 "Preempt mode\n")
239{
240 VTY_DECLVAR_CONTEXT(interface, ifp);
241
242 struct vrrp_vrouter *vr;
243
244 VROUTER_GET_VTY(vty, ifp, vrid, vr);
245
246 vr->preempt_mode = !no;
247
248 return CMD_SUCCESS;
249}
250
27fd8827
QY
251DEFPY(vrrp_autoconfigure,
252 vrrp_autoconfigure_cmd,
253 "[no] vrrp autoconfigure [version (2-3)]",
53e60e5c
QY
254 NO_STR
255 VRRP_STR
256 "Automatically set up VRRP instances on VRRP-compatible interfaces\n"
257 "Version for automatically configured instances\n"
258 VRRP_VERSION_STR)
259{
53e60e5c
QY
260 version = version ? version : 3;
261
27fd8827
QY
262 if (!no)
263 vrrp_autoconfig_on(version);
264 else
265 vrrp_autoconfig_off();
53e60e5c
QY
266
267 return CMD_SUCCESS;
268}
269
1d21789e 270static void vrrp_show(struct vty *vty, struct vrrp_vrouter *vr)
c23edd74 271{
862f2f37
QY
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];
277 struct listnode *ln;
278 struct ipaddr *ip;
c23edd74
QY
279
280 struct ttable *tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
281
282 ttable_add_row(tt, "%s|%" PRIu32, "Virtual Router ID", vr->vrid);
99966840 283 ttable_add_row(tt, "%s|%" PRIu8, "Protocol Version", vr->version);
27fd8827
QY
284 ttable_add_row(tt, "%s|%s", "Autoconfigured",
285 vr->autoconf ? "Yes" : "No");
5302f67b 286 ttable_add_row(tt, "%s|%s", "Interface", vr->ifp->name);
862f2f37
QY
287 prefix_mac2str(&vr->v4->vmac, ethstr4, sizeof(ethstr4));
288 prefix_mac2str(&vr->v6->vmac, ethstr6, sizeof(ethstr6));
5302f67b
QY
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");
862f2f37
QY
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);
c23edd74 297 ttable_add_row(tt, "%s|%" PRIu8, "Priority", vr->priority);
862f2f37
QY
298 ttable_add_row(tt, "%s|%" PRIu8, "Effective Priority (v4)",
299 vr->v4->priority);
300 ttable_add_row(tt, "%s|%" PRIu8, "Effective Priority (v6)",
301 vr->v6->priority);
c23edd74
QY
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");
69f63d1a 306 ttable_add_row(tt, "%s|%" PRIu16" cs", "Advertisement Interval",
c23edd74 307 vr->advertisement_interval);
862f2f37
QY
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);
c23edd74 319
92c399a4 320 char fill[35];
5302f67b
QY
321 memset(fill, '.', sizeof(fill));
322 fill[sizeof(fill) - 1] = 0x00;
862f2f37 323 if (vr->v4->addrs->count) {
862f2f37
QY
324 for (ALL_LIST_ELEMENTS_RO(vr->v4->addrs, ln, ip)) {
325 inet_ntop(vr->v4->family, &ip->ipaddr_v4, ipstr,
326 sizeof(ipstr));
5302f67b 327 ttable_add_row(tt, "%s|%s", fill, ipstr);
862f2f37 328 }
862f2f37
QY
329 }
330
5302f67b
QY
331 ttable_add_row(tt, "%s|%u", "IPv6 Addresses", vr->v6->addrs->count);
332
862f2f37 333 if (vr->v6->addrs->count) {
862f2f37
QY
334 for (ALL_LIST_ELEMENTS_RO(vr->v6->addrs, ln, ip)) {
335 inet_ntop(vr->v6->family, &ip->ipaddr_v6, ipstr,
336 sizeof(ipstr));
5302f67b 337 ttable_add_row(tt, "%s|%s", fill, ipstr);
c23edd74 338 }
c23edd74 339 }
5302f67b
QY
340
341 char *table = ttable_dump(tt, "\n");
342 vty_out(vty, "\n%s\n", table);
343 XFREE(MTYPE_TMP, table);
344 ttable_del(tt);
345
1d21789e
QY
346}
347
348DEFPY(vrrp_vrid_show,
349 vrrp_vrid_show_cmd,
4f0b6b45 350 "show vrrp [interface INTERFACE$ifn] [(1-255)$vrid]",
1d21789e
QY
351 SHOW_STR
352 VRRP_STR
4f0b6b45
QY
353 INTERFACE_STR
354 "Only show VRRP instances on this interface\n"
1d21789e
QY
355 VRRP_VRID_STR)
356{
357 struct vrrp_vrouter *vr;
4f0b6b45
QY
358 struct listnode *ln;
359 struct list *ll = hash_to_list(vrrp_vrouters_hash);
1d21789e 360
4f0b6b45
QY
361 for (ALL_LIST_ELEMENTS_RO(ll, ln, vr)) {
362 if (ifn && !strmatch(ifn, vr->ifp->name))
363 continue;
364 if (vrid && vrid != vr->vrid)
365 continue;
5302f67b 366
4f0b6b45 367 vrrp_show(vty, vr);
1d21789e 368 }
c23edd74 369
4f0b6b45
QY
370 list_delete(&ll);
371
c23edd74
QY
372 return CMD_SUCCESS;
373}
374
78fb3dbe
QY
375
376DEFPY(debug_vrrp,
377 debug_vrrp_cmd,
378 "[no] debug vrrp [{protocol$proto|autoconfigure$ac|packets$pkt|sockets$sock|ndisc$ndisc|arp$arp|zebra$zebra}]",
379 NO_STR
380 DEBUG_STR
381 VRRP_STR
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"
387 "Debug ARP\n"
388 "Debug Zebra events\n")
389{
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,
393 true, true, true);
394 else
395 vrrp_debug_set(NULL, 0, vty->node, !no, !!proto, !!ac, !!pkt,
396 !!sock, !!ndisc, !!arp, !!zebra);
397
398 return CMD_SUCCESS;
399}
400
401DEFUN_NOSH (show_debugging_vrrp,
402 show_debugging_vrrp_cmd,
403 "show debugging [vrrp]",
404 SHOW_STR
405 DEBUG_STR
406 "VRRP information\n")
407{
408 vty_out(vty, "VRRP debugging status:\n");
409
410 vrrp_debug_status_write(vty);
411
412 return CMD_SUCCESS;
413}
414
5435a2bf
QY
415static struct cmd_node interface_node = {
416 INTERFACE_NODE,
417 "%s(config-if)# ", 1
418};
419
78fb3dbe
QY
420static struct cmd_node debug_node = {DEBUG_NODE, "", 1};
421
5435a2bf
QY
422void vrrp_vty_init(void)
423{
78fb3dbe 424 install_node(&debug_node, vrrp_debug_config_write);
5435a2bf
QY
425 install_node(&interface_node, NULL);
426 if_cmd_init();
78fb3dbe 427
c23edd74 428 install_element(VIEW_NODE, &vrrp_vrid_show_cmd);
78fb3dbe
QY
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);
27fd8827 432 install_element(CONFIG_NODE, &vrrp_autoconfigure_cmd);
5435a2bf 433 install_element(INTERFACE_NODE, &vrrp_vrid_cmd);
c23edd74 434 install_element(INTERFACE_NODE, &vrrp_priority_cmd);
1d21789e 435 install_element(INTERFACE_NODE, &vrrp_advertisement_interval_cmd);
c23edd74 436 install_element(INTERFACE_NODE, &vrrp_ip_cmd);
862f2f37 437 install_element(INTERFACE_NODE, &vrrp_ip6_cmd);
8ec51216 438 install_element(INTERFACE_NODE, &vrrp_preempt_cmd);
5435a2bf 439}