]> git.proxmox.com Git - mirror_frr.git/blob - vrrpd/vrrp_vty.c
vrrpd: add debugging knobs
[mirror_frr.git] / vrrpd / vrrp_vty.c
1 /*
2 * VRRP CLI commands.
3 * Copyright (C) 2018-2019 Cumulus Networks, Inc.
4 * Quentin Young
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
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"
28
29 #include "vrrp.h"
30 #include "vrrp_debug.h"
31 #include "vrrp_memory.h"
32 #include "vrrp_vty.h"
33 #ifndef VTYSH_EXTRACT_PL
34 #include "vrrpd/vrrp_vty_clippy.c"
35 #endif
36
37
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"
44
45 #define VROUTER_GET_VTY(_vty, _ifp, _vrid, _vr) \
46 do { \
47 _vr = vrrp_lookup(_ifp, _vrid); \
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);
55
56 DEFPY(vrrp_vrid,
57 vrrp_vrid_cmd,
58 "[no] vrrp (1-255)$vrid [version (2-3)]",
59 NO_STR
60 VRRP_STR
61 VRRP_VRID_STR
62 VRRP_VERSION_STR
63 VRRP_VERSION_STR)
64 {
65 VTY_DECLVAR_CONTEXT(interface, ifp);
66
67 struct vrrp_vrouter *vr = vrrp_lookup(ifp, vrid);
68
69 if (version == 0)
70 version = 3;
71
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)
78 vrrp_vrouter_create(ifp, vrid, version);
79 else if (vr)
80 vty_out(vty, "%% VRRP instance %ld already exists on %s\n",
81 vrid, ifp->name);
82
83 return CMD_SUCCESS;
84 }
85
86 DEFPY(vrrp_priority,
87 vrrp_priority_cmd,
88 "[no] vrrp (1-255)$vrid priority (1-254)",
89 NO_STR
90 VRRP_STR
91 VRRP_VRID_STR
92 VRRP_PRIORITY_STR
93 "Priority value")
94 {
95 VTY_DECLVAR_CONTEXT(interface, ifp);
96
97 struct vrrp_vrouter *vr;
98 uint8_t newprio = no ? VRRP_DEFAULT_PRIORITY : priority;
99
100 VROUTER_GET_VTY(vty, ifp, vrid, vr);
101
102 vrrp_set_priority(vr, newprio);
103
104 return CMD_SUCCESS;
105 }
106
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")
112 {
113 VTY_DECLVAR_CONTEXT(interface, ifp);
114
115 struct vrrp_vrouter *vr;
116 uint16_t newadvint = no ? VRRP_DEFAULT_ADVINT : advertisement_interval;
117
118 VROUTER_GET_VTY(vty, ifp, vrid, vr);
119 vrrp_set_advertisement_interval(vr, newadvint);
120
121 return CMD_SUCCESS;
122 }
123
124 DEFPY(vrrp_ip,
125 vrrp_ip_cmd,
126 "[no] vrrp (1-255)$vrid ip A.B.C.D",
127 NO_STR
128 VRRP_STR
129 VRRP_VRID_STR
130 "Add IPv4 address\n"
131 VRRP_IP_STR)
132 {
133 VTY_DECLVAR_CONTEXT(interface, ifp);
134
135 struct vrrp_vrouter *vr;
136 bool deactivated = false;
137 bool activated = false;
138 bool failed = false;
139 int ret = CMD_SUCCESS;
140
141 VROUTER_GET_VTY(vty, ifp, vrid, vr);
142
143 bool will_activate = (vr->v4->fsm.state == VRRP_STATE_INITIALIZE);
144
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);
150 } else {
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) {
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) {
166 vty_out(vty,
167 "%% Failed to activate IPv4 Virtual Router %ld\n",
168 vrid);
169 }
170 }
171
172 return ret;
173 }
174
175 DEFPY(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 {
184 VTY_DECLVAR_CONTEXT(interface, ifp);
185
186 struct vrrp_vrouter *vr;
187 bool deactivated = false;
188 bool activated = false;
189 bool failed = false;
190 int ret = CMD_SUCCESS;
191
192 VROUTER_GET_VTY(vty, ifp, vrid, vr);
193
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
200 bool will_activate = (vr->v6->fsm.state == VRRP_STATE_INITIALIZE);
201
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);
207 } else {
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 }
227 }
228
229 return ret;
230 }
231
232 DEFPY(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
251 DEFPY(vrrp_autoconfigure,
252 vrrp_autoconfigure_cmd,
253 "[no] vrrp autoconfigure [version (2-3)]",
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 {
260 version = version ? version : 3;
261
262 if (!no)
263 vrrp_autoconfig_on(version);
264 else
265 vrrp_autoconfig_off();
266
267 return CMD_SUCCESS;
268 }
269
270 static void vrrp_show(struct vty *vty, struct vrrp_vrouter *vr)
271 {
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;
279
280 struct ttable *tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
281
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)",
299 vr->v4->priority);
300 ttable_add_row(tt, "%s|%" PRIu8, "Effective Priority (v6)",
301 vr->v6->priority);
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);
319
320 char fill[35];
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,
326 sizeof(ipstr));
327 ttable_add_row(tt, "%s|%s", fill, ipstr);
328 }
329 }
330
331 ttable_add_row(tt, "%s|%u", "IPv6 Addresses", vr->v6->addrs->count);
332
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,
336 sizeof(ipstr));
337 ttable_add_row(tt, "%s|%s", fill, ipstr);
338 }
339 }
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
346 }
347
348 DEFPY(vrrp_vrid_show,
349 vrrp_vrid_show_cmd,
350 "show vrrp [interface INTERFACE$ifn] [(1-255)$vrid]",
351 SHOW_STR
352 VRRP_STR
353 INTERFACE_STR
354 "Only show VRRP instances on this interface\n"
355 VRRP_VRID_STR)
356 {
357 struct vrrp_vrouter *vr;
358 struct listnode *ln;
359 struct list *ll = hash_to_list(vrrp_vrouters_hash);
360
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;
366
367 vrrp_show(vty, vr);
368 }
369
370 list_delete(&ll);
371
372 return CMD_SUCCESS;
373 }
374
375
376 DEFPY(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
401 DEFUN_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
415 static struct cmd_node interface_node = {
416 INTERFACE_NODE,
417 "%s(config-if)# ", 1
418 };
419
420 static struct cmd_node debug_node = {DEBUG_NODE, "", 1};
421
422 void vrrp_vty_init(void)
423 {
424 install_node(&debug_node, vrrp_debug_config_write);
425 install_node(&interface_node, NULL);
426 if_cmd_init();
427
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);
439 }