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