]> git.proxmox.com Git - mirror_frr.git/blame - vrrpd/vrrp_vty.c
vrrpd: add support for configuration writing
[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
b637bcd4
QY
56/* clang-format off */
57
c23edd74 58DEFPY(vrrp_vrid,
5435a2bf 59 vrrp_vrid_cmd,
99966840 60 "[no] vrrp (1-255)$vrid [version (2-3)]",
5435a2bf
QY
61 NO_STR
62 VRRP_STR
99966840
QY
63 VRRP_VRID_STR
64 VRRP_VERSION_STR
65 VRRP_VERSION_STR)
5435a2bf
QY
66{
67 VTY_DECLVAR_CONTEXT(interface, ifp);
5435a2bf 68
4f0b6b45 69 struct vrrp_vrouter *vr = vrrp_lookup(ifp, vrid);
6287cefe 70
99966840
QY
71 if (version == 0)
72 version = 3;
73
6287cefe
QY
74 if (no && vr)
75 vrrp_vrouter_destroy(vr);
76 else if (no && !vr)
77 vty_out(vty, "%% VRRP instance %ld does not exist on %s\n",
78 vrid, ifp->name);
79 else if (!vr)
99966840 80 vrrp_vrouter_create(ifp, vrid, version);
6287cefe
QY
81 else if (vr)
82 vty_out(vty, "%% VRRP instance %ld already exists on %s\n",
83 vrid, ifp->name);
5435a2bf
QY
84
85 return CMD_SUCCESS;
86}
87
c23edd74
QY
88DEFPY(vrrp_priority,
89 vrrp_priority_cmd,
bac08ded 90 "[no] vrrp (1-255)$vrid priority (1-254)",
c23edd74
QY
91 NO_STR
92 VRRP_STR
93 VRRP_VRID_STR
94 VRRP_PRIORITY_STR
bac08ded 95 "Priority value")
c23edd74 96{
4f0b6b45
QY
97 VTY_DECLVAR_CONTEXT(interface, ifp);
98
c23edd74 99 struct vrrp_vrouter *vr;
6287cefe 100 uint8_t newprio = no ? VRRP_DEFAULT_PRIORITY : priority;
c23edd74 101
4f0b6b45 102 VROUTER_GET_VTY(vty, ifp, vrid, vr);
1d21789e 103
6287cefe 104 vrrp_set_priority(vr, newprio);
1d21789e 105
1d21789e
QY
106 return CMD_SUCCESS;
107}
108
109DEFPY(vrrp_advertisement_interval,
110 vrrp_advertisement_interval_cmd,
111 "[no] vrrp (1-255)$vrid advertisement-interval (1-4096)",
6287cefe
QY
112 NO_STR VRRP_STR VRRP_VRID_STR VRRP_ADVINT_STR
113 "Advertisement interval in centiseconds")
1d21789e 114{
4f0b6b45
QY
115 VTY_DECLVAR_CONTEXT(interface, ifp);
116
1d21789e 117 struct vrrp_vrouter *vr;
6287cefe 118 uint16_t newadvint = no ? VRRP_DEFAULT_ADVINT : advertisement_interval;
1d21789e 119
4f0b6b45 120 VROUTER_GET_VTY(vty, ifp, vrid, vr);
6287cefe 121 vrrp_set_advertisement_interval(vr, newadvint);
c23edd74
QY
122
123 return CMD_SUCCESS;
124}
125
126DEFPY(vrrp_ip,
127 vrrp_ip_cmd,
862f2f37 128 "[no] vrrp (1-255)$vrid ip A.B.C.D",
c23edd74
QY
129 NO_STR
130 VRRP_STR
131 VRRP_VRID_STR
862f2f37 132 "Add IPv4 address\n"
c23edd74
QY
133 VRRP_IP_STR)
134{
4f0b6b45
QY
135 VTY_DECLVAR_CONTEXT(interface, ifp);
136
c23edd74 137 struct vrrp_vrouter *vr;
2cd90902
QY
138 bool deactivated = false;
139 bool activated = false;
140 bool failed = false;
141 int ret = CMD_SUCCESS;
c23edd74 142
4f0b6b45 143 VROUTER_GET_VTY(vty, ifp, vrid, vr);
c23edd74 144
2cd90902 145 bool will_activate = (vr->v4->fsm.state == VRRP_STATE_INITIALIZE);
862f2f37 146
2cd90902
QY
147 if (no) {
148 int oldstate = vr->v4->fsm.state;
149 failed = vrrp_del_ipv4(vr, ip, true);
150 deactivated = (vr->v4->fsm.state == VRRP_STATE_INITIALIZE
151 && oldstate != VRRP_STATE_INITIALIZE);
862f2f37 152 } else {
2cd90902
QY
153 int oldstate = vr->v4->fsm.state;
154 failed = vrrp_add_ipv4(vr, ip, true);
155 activated = (vr->v4->fsm.state != VRRP_STATE_INITIALIZE
156 && oldstate == VRRP_STATE_INITIALIZE);
157 }
158
159 if (activated)
160 vty_out(vty, "%% Activated IPv4 Virtual Router %ld\n", vrid);
161 if (deactivated)
162 vty_out(vty, "%% Deactivated IPv4 Virtual Router %ld\n", vrid);
163 if (failed) {
1af0eb1f 164 vty_out(vty, "%% Failed to %s virtual IP\n",
2cd90902
QY
165 no ? "remove" : "add");
166 ret = CMD_WARNING_CONFIG_FAILED;
167 if (will_activate && !activated) {
168 vty_out(vty,
169 "%% Failed to activate IPv4 Virtual Router %ld\n",
170 vrid);
171 }
862f2f37
QY
172 }
173
174 return ret;
175}
176
177DEFPY(vrrp_ip6,
178 vrrp_ip6_cmd,
179 "[no] vrrp (1-255)$vrid ipv6 X:X::X:X",
180 NO_STR
181 VRRP_STR
182 VRRP_VRID_STR
183 "Add IPv6 address\n"
184 VRRP_IP_STR)
185{
4f0b6b45
QY
186 VTY_DECLVAR_CONTEXT(interface, ifp);
187
862f2f37 188 struct vrrp_vrouter *vr;
2cd90902
QY
189 bool deactivated = false;
190 bool activated = false;
191 bool failed = false;
192 int ret = CMD_SUCCESS;
862f2f37 193
4f0b6b45 194 VROUTER_GET_VTY(vty, ifp, vrid, vr);
862f2f37 195
99966840
QY
196 if (vr->version != 3) {
197 vty_out(vty,
198 "%% Cannot add IPv6 address to VRRPv2 virtual router\n");
199 return CMD_WARNING_CONFIG_FAILED;
200 }
201
2cd90902 202 bool will_activate = (vr->v6->fsm.state == VRRP_STATE_INITIALIZE);
1d21789e 203
2cd90902
QY
204 if (no) {
205 int oldstate = vr->v6->fsm.state;
206 failed = vrrp_del_ipv6(vr, ipv6, true);
207 deactivated = (vr->v6->fsm.state == VRRP_STATE_INITIALIZE
208 && oldstate != VRRP_STATE_INITIALIZE);
1d21789e 209 } else {
2cd90902
QY
210 int oldstate = vr->v6->fsm.state;
211 failed = vrrp_add_ipv6(vr, ipv6, true);
212 activated = (vr->v6->fsm.state != VRRP_STATE_INITIALIZE
213 && oldstate == VRRP_STATE_INITIALIZE);
214 }
215
216 if (activated)
217 vty_out(vty, "%% Activated IPv6 Virtual Router %ld\n", vrid);
218 if (deactivated)
219 vty_out(vty, "%% Deactivated IPv6 Virtual Router %ld\n", vrid);
220 if (failed) {
221 vty_out(vty, "%% Failed to %s virtual IP",
222 no ? "remove" : "add");
223 ret = CMD_WARNING_CONFIG_FAILED;
224 if (will_activate && !activated) {
225 vty_out(vty,
226 "%% Failed to activate IPv4 Virtual Router %ld\n",
227 vrid);
228 }
1d21789e
QY
229 }
230
231 return ret;
c23edd74
QY
232}
233
8ec51216
QY
234DEFPY(vrrp_preempt,
235 vrrp_preempt_cmd,
236 "[no] vrrp (1-255)$vrid preempt",
237 NO_STR
238 VRRP_STR
239 VRRP_VRID_STR
240 "Preempt mode\n")
241{
242 VTY_DECLVAR_CONTEXT(interface, ifp);
243
244 struct vrrp_vrouter *vr;
245
246 VROUTER_GET_VTY(vty, ifp, vrid, vr);
247
248 vr->preempt_mode = !no;
249
250 return CMD_SUCCESS;
251}
252
27fd8827
QY
253DEFPY(vrrp_autoconfigure,
254 vrrp_autoconfigure_cmd,
255 "[no] vrrp autoconfigure [version (2-3)]",
53e60e5c
QY
256 NO_STR
257 VRRP_STR
258 "Automatically set up VRRP instances on VRRP-compatible interfaces\n"
259 "Version for automatically configured instances\n"
260 VRRP_VERSION_STR)
261{
53e60e5c
QY
262 version = version ? version : 3;
263
27fd8827
QY
264 if (!no)
265 vrrp_autoconfig_on(version);
266 else
267 vrrp_autoconfig_off();
53e60e5c
QY
268
269 return CMD_SUCCESS;
270}
271
1d21789e 272static void vrrp_show(struct vty *vty, struct vrrp_vrouter *vr)
c23edd74 273{
862f2f37
QY
274 char ethstr4[ETHER_ADDR_STRLEN];
275 char ethstr6[ETHER_ADDR_STRLEN];
276 char ipstr[INET6_ADDRSTRLEN];
277 const char *stastr4 = vrrp_state_names[vr->v4->fsm.state];
278 const char *stastr6 = vrrp_state_names[vr->v6->fsm.state];
279 struct listnode *ln;
280 struct ipaddr *ip;
c23edd74
QY
281
282 struct ttable *tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
283
284 ttable_add_row(tt, "%s|%" PRIu32, "Virtual Router ID", vr->vrid);
99966840 285 ttable_add_row(tt, "%s|%" PRIu8, "Protocol Version", vr->version);
27fd8827
QY
286 ttable_add_row(tt, "%s|%s", "Autoconfigured",
287 vr->autoconf ? "Yes" : "No");
5302f67b 288 ttable_add_row(tt, "%s|%s", "Interface", vr->ifp->name);
862f2f37
QY
289 prefix_mac2str(&vr->v4->vmac, ethstr4, sizeof(ethstr4));
290 prefix_mac2str(&vr->v6->vmac, ethstr6, sizeof(ethstr6));
5302f67b
QY
291 ttable_add_row(tt, "%s|%s", "VRRP interface (v4)",
292 vr->v4->mvl_ifp ? vr->v4->mvl_ifp->name : "None");
293 ttable_add_row(tt, "%s|%s", "VRRP interface (v6)",
294 vr->v6->mvl_ifp ? vr->v6->mvl_ifp->name : "None");
862f2f37
QY
295 ttable_add_row(tt, "%s|%s", "Virtual MAC (v4)", ethstr4);
296 ttable_add_row(tt, "%s|%s", "Virtual MAC (v6)", ethstr6);
297 ttable_add_row(tt, "%s|%s", "Status (v4)", stastr4);
298 ttable_add_row(tt, "%s|%s", "Status (v6)", stastr6);
c23edd74 299 ttable_add_row(tt, "%s|%" PRIu8, "Priority", vr->priority);
862f2f37
QY
300 ttable_add_row(tt, "%s|%" PRIu8, "Effective Priority (v4)",
301 vr->v4->priority);
302 ttable_add_row(tt, "%s|%" PRIu8, "Effective Priority (v6)",
303 vr->v6->priority);
c23edd74
QY
304 ttable_add_row(tt, "%s|%s", "Preempt Mode",
305 vr->preempt_mode ? "Yes" : "No");
306 ttable_add_row(tt, "%s|%s", "Accept Mode",
307 vr->accept_mode ? "Yes" : "No");
69f63d1a 308 ttable_add_row(tt, "%s|%" PRIu16" cs", "Advertisement Interval",
c23edd74 309 vr->advertisement_interval);
862f2f37
QY
310 ttable_add_row(tt, "%s|%" PRIu16" cs", "Master Advertisement Interval (v4)",
311 vr->v4->master_adver_interval);
312 ttable_add_row(tt, "%s|%" PRIu16" cs", "Master Advertisement Interval (v6)",
313 vr->v6->master_adver_interval);
314 ttable_add_row(tt, "%s|%" PRIu16" cs", "Skew Time (v4)", vr->v4->skew_time);
315 ttable_add_row(tt, "%s|%" PRIu16" cs", "Skew Time (v6)", vr->v6->skew_time);
316 ttable_add_row(tt, "%s|%" PRIu16" cs", "Master Down Interval (v4)",
317 vr->v4->master_down_interval);
318 ttable_add_row(tt, "%s|%" PRIu16" cs", "Master Down Interval (v6)",
319 vr->v6->master_down_interval);
320 ttable_add_row(tt, "%s|%u", "IPv4 Addresses", vr->v4->addrs->count);
c23edd74 321
92c399a4 322 char fill[35];
5302f67b
QY
323 memset(fill, '.', sizeof(fill));
324 fill[sizeof(fill) - 1] = 0x00;
862f2f37 325 if (vr->v4->addrs->count) {
862f2f37
QY
326 for (ALL_LIST_ELEMENTS_RO(vr->v4->addrs, ln, ip)) {
327 inet_ntop(vr->v4->family, &ip->ipaddr_v4, ipstr,
328 sizeof(ipstr));
5302f67b 329 ttable_add_row(tt, "%s|%s", fill, ipstr);
862f2f37 330 }
862f2f37
QY
331 }
332
5302f67b
QY
333 ttable_add_row(tt, "%s|%u", "IPv6 Addresses", vr->v6->addrs->count);
334
862f2f37 335 if (vr->v6->addrs->count) {
862f2f37
QY
336 for (ALL_LIST_ELEMENTS_RO(vr->v6->addrs, ln, ip)) {
337 inet_ntop(vr->v6->family, &ip->ipaddr_v6, ipstr,
338 sizeof(ipstr));
5302f67b 339 ttable_add_row(tt, "%s|%s", fill, ipstr);
c23edd74 340 }
c23edd74 341 }
5302f67b
QY
342
343 char *table = ttable_dump(tt, "\n");
344 vty_out(vty, "\n%s\n", table);
345 XFREE(MTYPE_TMP, table);
346 ttable_del(tt);
347
1d21789e
QY
348}
349
350DEFPY(vrrp_vrid_show,
351 vrrp_vrid_show_cmd,
4f0b6b45 352 "show vrrp [interface INTERFACE$ifn] [(1-255)$vrid]",
1d21789e
QY
353 SHOW_STR
354 VRRP_STR
4f0b6b45
QY
355 INTERFACE_STR
356 "Only show VRRP instances on this interface\n"
1d21789e
QY
357 VRRP_VRID_STR)
358{
359 struct vrrp_vrouter *vr;
4f0b6b45
QY
360 struct listnode *ln;
361 struct list *ll = hash_to_list(vrrp_vrouters_hash);
1d21789e 362
4f0b6b45
QY
363 for (ALL_LIST_ELEMENTS_RO(ll, ln, vr)) {
364 if (ifn && !strmatch(ifn, vr->ifp->name))
365 continue;
366 if (vrid && vrid != vr->vrid)
367 continue;
5302f67b 368
4f0b6b45 369 vrrp_show(vty, vr);
1d21789e 370 }
c23edd74 371
4f0b6b45
QY
372 list_delete(&ll);
373
c23edd74
QY
374 return CMD_SUCCESS;
375}
376
78fb3dbe
QY
377
378DEFPY(debug_vrrp,
379 debug_vrrp_cmd,
380 "[no] debug vrrp [{protocol$proto|autoconfigure$ac|packets$pkt|sockets$sock|ndisc$ndisc|arp$arp|zebra$zebra}]",
381 NO_STR
382 DEBUG_STR
383 VRRP_STR
384 "Debug protocol state\n"
385 "Debug autoconfiguration\n"
386 "Debug sent and received packets\n"
387 "Debug socket creation and configuration\n"
388 "Debug Neighbor Discovery\n"
389 "Debug ARP\n"
390 "Debug Zebra events\n")
391{
392 /* If no specific are given on/off them all */
393 if (strmatch(argv[argc - 1]->text, "vrrp"))
394 vrrp_debug_set(NULL, 0, vty->node, !no, true, true, true, true,
395 true, true, true);
396 else
397 vrrp_debug_set(NULL, 0, vty->node, !no, !!proto, !!ac, !!pkt,
398 !!sock, !!ndisc, !!arp, !!zebra);
399
400 return CMD_SUCCESS;
401}
402
403DEFUN_NOSH (show_debugging_vrrp,
404 show_debugging_vrrp_cmd,
405 "show debugging [vrrp]",
406 SHOW_STR
407 DEBUG_STR
408 "VRRP information\n")
409{
410 vty_out(vty, "VRRP debugging status:\n");
411
412 vrrp_debug_status_write(vty);
413
414 return CMD_SUCCESS;
415}
416
b637bcd4
QY
417/* clang-format on */
418
f828842a 419static struct cmd_node interface_node = {INTERFACE_NODE, "%s(config-if)# ", 1};
78fb3dbe 420static struct cmd_node debug_node = {DEBUG_NODE, "", 1};
f828842a 421static struct cmd_node vrrp_node = {VRRP_NODE, "", 1};
78fb3dbe 422
5435a2bf
QY
423void vrrp_vty_init(void)
424{
f828842a
QY
425 install_node(&debug_node, vrrp_config_write_debug);
426 install_node(&interface_node, vrrp_config_write_interface);
427 install_node(&vrrp_node, vrrp_config_write_global);
5435a2bf 428 if_cmd_init();
78fb3dbe 429
c23edd74 430 install_element(VIEW_NODE, &vrrp_vrid_show_cmd);
78fb3dbe
QY
431 install_element(VIEW_NODE, &show_debugging_vrrp_cmd);
432 install_element(VIEW_NODE, &debug_vrrp_cmd);
433 install_element(CONFIG_NODE, &debug_vrrp_cmd);
27fd8827 434 install_element(CONFIG_NODE, &vrrp_autoconfigure_cmd);
5435a2bf 435 install_element(INTERFACE_NODE, &vrrp_vrid_cmd);
c23edd74 436 install_element(INTERFACE_NODE, &vrrp_priority_cmd);
1d21789e 437 install_element(INTERFACE_NODE, &vrrp_advertisement_interval_cmd);
c23edd74 438 install_element(INTERFACE_NODE, &vrrp_ip_cmd);
862f2f37 439 install_element(INTERFACE_NODE, &vrrp_ip6_cmd);
8ec51216 440 install_element(INTERFACE_NODE, &vrrp_preempt_cmd);
5435a2bf 441}