]>
Commit | Line | Data |
---|---|---|
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 QY |
41 | #define VRRP_IP_STR "Virtual Router IPv4 address\n" |
42 | ||
43 | #define VROUTER_GET_VTY(_vty, _vrid, _vr) \ | |
44 | do { \ | |
45 | _vr = vrrp_lookup(_vrid); \ | |
46 | if (!_vr) { \ | |
47 | vty_out(_vty, \ | |
48 | "%% Please configure VRRP instance %u\n", \ | |
49 | (unsigned int)_vrid); \ | |
50 | return CMD_WARNING_CONFIG_FAILED; \ | |
51 | } \ | |
52 | } while (0); | |
5435a2bf QY |
53 | |
54 | DEFUN_NOSH (show_debugging_vrrpd, | |
55 | show_debugging_vrrpd_cmd, | |
56 | "show debugging [vrrp]", | |
57 | SHOW_STR | |
58 | DEBUG_STR | |
59 | "VRRP information\n") | |
60 | { | |
61 | vty_out(vty, "VRRP debugging status\n"); | |
62 | ||
63 | return CMD_SUCCESS; | |
64 | } | |
65 | ||
c23edd74 | 66 | DEFPY(vrrp_vrid, |
5435a2bf | 67 | vrrp_vrid_cmd, |
c23edd74 | 68 | "[no] vrrp (1-255)$vrid", |
5435a2bf QY |
69 | NO_STR |
70 | VRRP_STR | |
71 | VRRP_VRID_STR) | |
72 | { | |
73 | VTY_DECLVAR_CONTEXT(interface, ifp); | |
5435a2bf | 74 | |
6287cefe QY |
75 | struct vrrp_vrouter *vr = vrrp_lookup(vrid); |
76 | ||
77 | if (no && vr) | |
78 | vrrp_vrouter_destroy(vr); | |
79 | else if (no && !vr) | |
80 | vty_out(vty, "%% VRRP instance %ld does not exist on %s\n", | |
81 | vrid, ifp->name); | |
82 | else if (!vr) | |
83 | vrrp_vrouter_create(ifp, vrid); | |
84 | else if (vr) | |
85 | vty_out(vty, "%% VRRP instance %ld already exists on %s\n", | |
86 | vrid, ifp->name); | |
5435a2bf QY |
87 | |
88 | return CMD_SUCCESS; | |
89 | } | |
90 | ||
c23edd74 QY |
91 | DEFPY(vrrp_priority, |
92 | vrrp_priority_cmd, | |
bac08ded | 93 | "[no] vrrp (1-255)$vrid priority (1-254)", |
c23edd74 QY |
94 | NO_STR |
95 | VRRP_STR | |
96 | VRRP_VRID_STR | |
97 | VRRP_PRIORITY_STR | |
bac08ded | 98 | "Priority value") |
c23edd74 QY |
99 | { |
100 | struct vrrp_vrouter *vr; | |
862f2f37 QY |
101 | struct vrrp_router *r; |
102 | bool nr[2] = { false, false }; | |
1d21789e | 103 | int ret = CMD_SUCCESS; |
6287cefe | 104 | uint8_t newprio = no ? VRRP_DEFAULT_PRIORITY : priority; |
c23edd74 QY |
105 | |
106 | VROUTER_GET_VTY(vty, vrid, vr); | |
1d21789e | 107 | |
862f2f37 QY |
108 | r = vr->v4; |
109 | for (int i = 0; i < 2; i++) { | |
6287cefe QY |
110 | nr[i] = r->is_active && r->fsm.state != VRRP_STATE_INITIALIZE |
111 | && vr->priority != newprio; | |
862f2f37 QY |
112 | if (nr[i]) { |
113 | vty_out(vty, | |
6287cefe QY |
114 | "%% WARNING: Restarting %s Virtual Router %ld to update priority\n", |
115 | family2str(r->family), vrid); | |
862f2f37 QY |
116 | (void)vrrp_event(r, VRRP_EVENT_SHUTDOWN); |
117 | } | |
118 | r = vr->v6; | |
1d21789e QY |
119 | } |
120 | ||
6287cefe | 121 | vrrp_set_priority(vr, newprio); |
1d21789e | 122 | |
862f2f37 QY |
123 | r = vr->v4; |
124 | for (int i = 0; i < 2; i++) { | |
125 | if (nr[i]) { | |
126 | ret = vrrp_event(r, VRRP_EVENT_STARTUP); | |
127 | if (ret < 0) | |
128 | vty_out(vty, | |
129 | "%% Failed to start Virtual Router %ld (%s)\n", | |
6287cefe | 130 | vrid, family2str(r->family)); |
862f2f37 QY |
131 | } |
132 | r = vr->v6; | |
1d21789e QY |
133 | } |
134 | ||
135 | return CMD_SUCCESS; | |
136 | } | |
137 | ||
138 | DEFPY(vrrp_advertisement_interval, | |
139 | vrrp_advertisement_interval_cmd, | |
140 | "[no] vrrp (1-255)$vrid advertisement-interval (1-4096)", | |
6287cefe QY |
141 | NO_STR VRRP_STR VRRP_VRID_STR VRRP_ADVINT_STR |
142 | "Advertisement interval in centiseconds") | |
1d21789e QY |
143 | { |
144 | struct vrrp_vrouter *vr; | |
6287cefe | 145 | uint16_t newadvint = no ? VRRP_DEFAULT_ADVINT : advertisement_interval; |
1d21789e QY |
146 | |
147 | VROUTER_GET_VTY(vty, vrid, vr); | |
6287cefe | 148 | vrrp_set_advertisement_interval(vr, newadvint); |
c23edd74 QY |
149 | |
150 | return CMD_SUCCESS; | |
151 | } | |
152 | ||
153 | DEFPY(vrrp_ip, | |
154 | vrrp_ip_cmd, | |
862f2f37 | 155 | "[no] vrrp (1-255)$vrid ip A.B.C.D", |
c23edd74 QY |
156 | NO_STR |
157 | VRRP_STR | |
158 | VRRP_VRID_STR | |
862f2f37 | 159 | "Add IPv4 address\n" |
c23edd74 QY |
160 | VRRP_IP_STR) |
161 | { | |
162 | struct vrrp_vrouter *vr; | |
1d21789e | 163 | int ret; |
c23edd74 QY |
164 | |
165 | VROUTER_GET_VTY(vty, vrid, vr); | |
862f2f37 | 166 | vrrp_add_ipv4(vr, ip); |
c23edd74 | 167 | |
862f2f37 | 168 | if (vr->v4->fsm.state == VRRP_STATE_INITIALIZE) { |
1d21789e | 169 | vty_out(vty, "%% Activating Virtual Router %ld\n", vrid); |
862f2f37 QY |
170 | ret = vrrp_event(vr->v4, VRRP_EVENT_STARTUP); |
171 | ret = ret < 0 ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS; | |
172 | ||
173 | if (ret == CMD_WARNING_CONFIG_FAILED) | |
174 | vty_out(vty, "%% Failed to start Virtual Router %ld\n", | |
175 | vrid); | |
176 | } else { | |
177 | ret = CMD_SUCCESS; | |
178 | } | |
179 | ||
180 | return ret; | |
181 | } | |
182 | ||
183 | DEFPY(vrrp_ip6, | |
184 | vrrp_ip6_cmd, | |
185 | "[no] vrrp (1-255)$vrid ipv6 X:X::X:X", | |
186 | NO_STR | |
187 | VRRP_STR | |
188 | VRRP_VRID_STR | |
189 | "Add IPv6 address\n" | |
190 | VRRP_IP_STR) | |
191 | { | |
192 | struct vrrp_vrouter *vr; | |
193 | int ret; | |
194 | ||
195 | VROUTER_GET_VTY(vty, vrid, vr); | |
196 | vrrp_add_ipv6(vr, ipv6); | |
197 | ||
198 | if (vr->v6->fsm.state == VRRP_STATE_INITIALIZE) { | |
199 | vty_out(vty, "%% Activating Virtual Router %ld\n", vrid); | |
200 | ret = vrrp_event(vr->v6, VRRP_EVENT_STARTUP); | |
1d21789e QY |
201 | ret = ret < 0 ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS; |
202 | ||
203 | if (ret == CMD_WARNING_CONFIG_FAILED) | |
204 | vty_out(vty, "%% Failed to start Virtual Router %ld\n", | |
205 | vrid); | |
206 | } else { | |
207 | ret = CMD_SUCCESS; | |
208 | } | |
209 | ||
210 | return ret; | |
c23edd74 QY |
211 | } |
212 | ||
1d21789e | 213 | static void vrrp_show(struct vty *vty, struct vrrp_vrouter *vr) |
c23edd74 | 214 | { |
862f2f37 QY |
215 | char ethstr4[ETHER_ADDR_STRLEN]; |
216 | char ethstr6[ETHER_ADDR_STRLEN]; | |
217 | char ipstr[INET6_ADDRSTRLEN]; | |
218 | const char *stastr4 = vrrp_state_names[vr->v4->fsm.state]; | |
219 | const char *stastr6 = vrrp_state_names[vr->v6->fsm.state]; | |
220 | struct listnode *ln; | |
221 | struct ipaddr *ip; | |
c23edd74 QY |
222 | |
223 | struct ttable *tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]); | |
224 | ||
225 | ttable_add_row(tt, "%s|%" PRIu32, "Virtual Router ID", vr->vrid); | |
5302f67b | 226 | ttable_add_row(tt, "%s|%s", "Interface", vr->ifp->name); |
862f2f37 QY |
227 | prefix_mac2str(&vr->v4->vmac, ethstr4, sizeof(ethstr4)); |
228 | prefix_mac2str(&vr->v6->vmac, ethstr6, sizeof(ethstr6)); | |
5302f67b QY |
229 | ttable_add_row(tt, "%s|%s", "VRRP interface (v4)", |
230 | vr->v4->mvl_ifp ? vr->v4->mvl_ifp->name : "None"); | |
231 | ttable_add_row(tt, "%s|%s", "VRRP interface (v6)", | |
232 | vr->v6->mvl_ifp ? vr->v6->mvl_ifp->name : "None"); | |
862f2f37 QY |
233 | ttable_add_row(tt, "%s|%s", "Virtual MAC (v4)", ethstr4); |
234 | ttable_add_row(tt, "%s|%s", "Virtual MAC (v6)", ethstr6); | |
235 | ttable_add_row(tt, "%s|%s", "Status (v4)", stastr4); | |
236 | ttable_add_row(tt, "%s|%s", "Status (v6)", stastr6); | |
c23edd74 | 237 | ttable_add_row(tt, "%s|%" PRIu8, "Priority", vr->priority); |
862f2f37 QY |
238 | ttable_add_row(tt, "%s|%" PRIu8, "Effective Priority (v4)", |
239 | vr->v4->priority); | |
240 | ttable_add_row(tt, "%s|%" PRIu8, "Effective Priority (v6)", | |
241 | vr->v6->priority); | |
c23edd74 QY |
242 | ttable_add_row(tt, "%s|%s", "Preempt Mode", |
243 | vr->preempt_mode ? "Yes" : "No"); | |
244 | ttable_add_row(tt, "%s|%s", "Accept Mode", | |
245 | vr->accept_mode ? "Yes" : "No"); | |
69f63d1a | 246 | ttable_add_row(tt, "%s|%" PRIu16" cs", "Advertisement Interval", |
c23edd74 | 247 | vr->advertisement_interval); |
862f2f37 QY |
248 | ttable_add_row(tt, "%s|%" PRIu16" cs", "Master Advertisement Interval (v4)", |
249 | vr->v4->master_adver_interval); | |
250 | ttable_add_row(tt, "%s|%" PRIu16" cs", "Master Advertisement Interval (v6)", | |
251 | vr->v6->master_adver_interval); | |
252 | ttable_add_row(tt, "%s|%" PRIu16" cs", "Skew Time (v4)", vr->v4->skew_time); | |
253 | ttable_add_row(tt, "%s|%" PRIu16" cs", "Skew Time (v6)", vr->v6->skew_time); | |
254 | ttable_add_row(tt, "%s|%" PRIu16" cs", "Master Down Interval (v4)", | |
255 | vr->v4->master_down_interval); | |
256 | ttable_add_row(tt, "%s|%" PRIu16" cs", "Master Down Interval (v6)", | |
257 | vr->v6->master_down_interval); | |
258 | ttable_add_row(tt, "%s|%u", "IPv4 Addresses", vr->v4->addrs->count); | |
c23edd74 | 259 | |
5302f67b QY |
260 | char fill[37]; |
261 | memset(fill, '.', sizeof(fill)); | |
262 | fill[sizeof(fill) - 1] = 0x00; | |
862f2f37 | 263 | if (vr->v4->addrs->count) { |
862f2f37 QY |
264 | for (ALL_LIST_ELEMENTS_RO(vr->v4->addrs, ln, ip)) { |
265 | inet_ntop(vr->v4->family, &ip->ipaddr_v4, ipstr, | |
266 | sizeof(ipstr)); | |
5302f67b | 267 | ttable_add_row(tt, "%s|%s", fill, ipstr); |
862f2f37 | 268 | } |
862f2f37 QY |
269 | } |
270 | ||
5302f67b QY |
271 | ttable_add_row(tt, "%s|%u", "IPv6 Addresses", vr->v6->addrs->count); |
272 | ||
862f2f37 | 273 | if (vr->v6->addrs->count) { |
862f2f37 QY |
274 | for (ALL_LIST_ELEMENTS_RO(vr->v6->addrs, ln, ip)) { |
275 | inet_ntop(vr->v6->family, &ip->ipaddr_v6, ipstr, | |
276 | sizeof(ipstr)); | |
5302f67b | 277 | ttable_add_row(tt, "%s|%s", fill, ipstr); |
c23edd74 | 278 | } |
c23edd74 | 279 | } |
5302f67b QY |
280 | |
281 | char *table = ttable_dump(tt, "\n"); | |
282 | vty_out(vty, "\n%s\n", table); | |
283 | XFREE(MTYPE_TMP, table); | |
284 | ttable_del(tt); | |
285 | ||
1d21789e QY |
286 | } |
287 | ||
288 | DEFPY(vrrp_vrid_show, | |
289 | vrrp_vrid_show_cmd, | |
290 | "show vrrp [(1-255)$vrid]", | |
291 | SHOW_STR | |
292 | VRRP_STR | |
293 | VRRP_VRID_STR) | |
294 | { | |
295 | struct vrrp_vrouter *vr; | |
296 | ||
297 | if (vrid) { | |
298 | VROUTER_GET_VTY(vty, vrid, vr); | |
299 | vrrp_show(vty, vr); | |
300 | } else { | |
301 | struct list *ll = hash_to_list(vrrp_vrouters_hash); | |
302 | struct listnode *ln; | |
303 | ||
304 | for (ALL_LIST_ELEMENTS_RO(ll, ln, vr)) | |
305 | vrrp_show(vty, vr); | |
5302f67b QY |
306 | |
307 | list_delete_and_null(&ll); | |
1d21789e | 308 | } |
c23edd74 QY |
309 | |
310 | return CMD_SUCCESS; | |
311 | } | |
312 | ||
5435a2bf QY |
313 | static struct cmd_node interface_node = { |
314 | INTERFACE_NODE, | |
315 | "%s(config-if)# ", 1 | |
316 | }; | |
317 | ||
318 | void vrrp_vty_init(void) | |
319 | { | |
320 | install_node(&interface_node, NULL); | |
321 | if_cmd_init(); | |
322 | install_element(VIEW_NODE, &show_debugging_vrrpd_cmd); | |
c23edd74 | 323 | install_element(VIEW_NODE, &vrrp_vrid_show_cmd); |
5435a2bf | 324 | install_element(INTERFACE_NODE, &vrrp_vrid_cmd); |
c23edd74 | 325 | install_element(INTERFACE_NODE, &vrrp_priority_cmd); |
1d21789e | 326 | install_element(INTERFACE_NODE, &vrrp_advertisement_interval_cmd); |
c23edd74 | 327 | install_element(INTERFACE_NODE, &vrrp_ip_cmd); |
862f2f37 | 328 | install_element(INTERFACE_NODE, &vrrp_ip6_cmd); |
5435a2bf | 329 | } |