]>
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" | |
6e21b5ae | 25 | #include "lib/json.h" |
862f2f37 QY |
26 | #include "lib/prefix.h" |
27 | #include "lib/termtable.h" | |
28 | #include "lib/vty.h" | |
5435a2bf QY |
29 | |
30 | #include "vrrp.h" | |
78fb3dbe | 31 | #include "vrrp_debug.h" |
5435a2bf | 32 | #include "vrrp_memory.h" |
78fb3dbe | 33 | #include "vrrp_vty.h" |
c23edd74 QY |
34 | #ifndef VTYSH_EXTRACT_PL |
35 | #include "vrrpd/vrrp_vty_clippy.c" | |
36 | #endif | |
5435a2bf QY |
37 | |
38 | ||
39 | #define VRRP_STR "Virtual Router Redundancy Protocol\n" | |
40 | #define VRRP_VRID_STR "Virtual Router ID\n" | |
c23edd74 | 41 | #define VRRP_PRIORITY_STR "Virtual Router Priority\n" |
6287cefe | 42 | #define VRRP_ADVINT_STR "Virtual Router Advertisement Interval\n" |
c23edd74 | 43 | #define VRRP_IP_STR "Virtual Router IPv4 address\n" |
99966840 | 44 | #define VRRP_VERSION_STR "VRRP protocol version\n" |
c23edd74 | 45 | |
4f0b6b45 | 46 | #define VROUTER_GET_VTY(_vty, _ifp, _vrid, _vr) \ |
c23edd74 | 47 | do { \ |
4f0b6b45 | 48 | _vr = vrrp_lookup(_ifp, _vrid); \ |
c23edd74 QY |
49 | if (!_vr) { \ |
50 | vty_out(_vty, \ | |
51 | "%% Please configure VRRP instance %u\n", \ | |
52 | (unsigned int)_vrid); \ | |
53 | return CMD_WARNING_CONFIG_FAILED; \ | |
54 | } \ | |
55 | } while (0); | |
5435a2bf | 56 | |
b637bcd4 QY |
57 | /* clang-format off */ |
58 | ||
c23edd74 | 59 | DEFPY(vrrp_vrid, |
5435a2bf | 60 | vrrp_vrid_cmd, |
99966840 | 61 | "[no] vrrp (1-255)$vrid [version (2-3)]", |
5435a2bf QY |
62 | NO_STR |
63 | VRRP_STR | |
99966840 QY |
64 | VRRP_VRID_STR |
65 | VRRP_VERSION_STR | |
66 | VRRP_VERSION_STR) | |
5435a2bf QY |
67 | { |
68 | VTY_DECLVAR_CONTEXT(interface, ifp); | |
5435a2bf | 69 | |
4f0b6b45 | 70 | struct vrrp_vrouter *vr = vrrp_lookup(ifp, vrid); |
6287cefe | 71 | |
99966840 QY |
72 | if (version == 0) |
73 | version = 3; | |
74 | ||
6287cefe QY |
75 | if (no && vr) |
76 | vrrp_vrouter_destroy(vr); | |
77 | else if (no && !vr) | |
78 | vty_out(vty, "%% VRRP instance %ld does not exist on %s\n", | |
79 | vrid, ifp->name); | |
80 | else if (!vr) | |
99966840 | 81 | vrrp_vrouter_create(ifp, vrid, version); |
6287cefe QY |
82 | else if (vr) |
83 | vty_out(vty, "%% VRRP instance %ld already exists on %s\n", | |
84 | vrid, ifp->name); | |
5435a2bf QY |
85 | |
86 | return CMD_SUCCESS; | |
87 | } | |
88 | ||
f96a183b QY |
89 | DEFPY(vrrp_shutdown, |
90 | vrrp_shutdown_cmd, | |
91 | "[no] vrrp (1-255)$vrid shutdown", | |
92 | NO_STR | |
93 | VRRP_STR | |
94 | VRRP_VRID_STR | |
95 | "Force VRRP router into administrative shutdown\n") | |
96 | { | |
97 | VTY_DECLVAR_CONTEXT(interface, ifp); | |
98 | ||
99 | struct vrrp_vrouter *vr; | |
100 | ||
101 | VROUTER_GET_VTY(vty, ifp, vrid, vr); | |
102 | ||
103 | if (!no) { | |
104 | if (vr->v4->fsm.state != VRRP_STATE_INITIALIZE) | |
105 | vrrp_event(vr->v4, VRRP_EVENT_SHUTDOWN); | |
106 | if (vr->v6->fsm.state != VRRP_STATE_INITIALIZE) | |
107 | vrrp_event(vr->v6, VRRP_EVENT_SHUTDOWN); | |
108 | vr->shutdown = true; | |
109 | } else { | |
110 | vr->shutdown = false; | |
111 | vrrp_check_start(vr); | |
112 | } | |
113 | ||
114 | return CMD_SUCCESS; | |
115 | } | |
116 | ||
c23edd74 QY |
117 | DEFPY(vrrp_priority, |
118 | vrrp_priority_cmd, | |
bac08ded | 119 | "[no] vrrp (1-255)$vrid priority (1-254)", |
c23edd74 QY |
120 | NO_STR |
121 | VRRP_STR | |
122 | VRRP_VRID_STR | |
123 | VRRP_PRIORITY_STR | |
bac08ded | 124 | "Priority value") |
c23edd74 | 125 | { |
4f0b6b45 QY |
126 | VTY_DECLVAR_CONTEXT(interface, ifp); |
127 | ||
c23edd74 | 128 | struct vrrp_vrouter *vr; |
6287cefe | 129 | uint8_t newprio = no ? VRRP_DEFAULT_PRIORITY : priority; |
c23edd74 | 130 | |
4f0b6b45 | 131 | VROUTER_GET_VTY(vty, ifp, vrid, vr); |
1d21789e | 132 | |
6287cefe | 133 | vrrp_set_priority(vr, newprio); |
1d21789e | 134 | |
1d21789e QY |
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 | 143 | { |
4f0b6b45 QY |
144 | VTY_DECLVAR_CONTEXT(interface, ifp); |
145 | ||
1d21789e | 146 | struct vrrp_vrouter *vr; |
6287cefe | 147 | uint16_t newadvint = no ? VRRP_DEFAULT_ADVINT : advertisement_interval; |
1d21789e | 148 | |
4f0b6b45 | 149 | VROUTER_GET_VTY(vty, ifp, vrid, vr); |
6287cefe | 150 | vrrp_set_advertisement_interval(vr, newadvint); |
c23edd74 QY |
151 | |
152 | return CMD_SUCCESS; | |
153 | } | |
154 | ||
155 | DEFPY(vrrp_ip, | |
156 | vrrp_ip_cmd, | |
862f2f37 | 157 | "[no] vrrp (1-255)$vrid ip A.B.C.D", |
c23edd74 QY |
158 | NO_STR |
159 | VRRP_STR | |
160 | VRRP_VRID_STR | |
862f2f37 | 161 | "Add IPv4 address\n" |
c23edd74 QY |
162 | VRRP_IP_STR) |
163 | { | |
4f0b6b45 QY |
164 | VTY_DECLVAR_CONTEXT(interface, ifp); |
165 | ||
c23edd74 | 166 | struct vrrp_vrouter *vr; |
2cd90902 QY |
167 | bool deactivated = false; |
168 | bool activated = false; | |
169 | bool failed = false; | |
170 | int ret = CMD_SUCCESS; | |
c23edd74 | 171 | |
4f0b6b45 | 172 | VROUTER_GET_VTY(vty, ifp, vrid, vr); |
c23edd74 | 173 | |
2cd90902 | 174 | bool will_activate = (vr->v4->fsm.state == VRRP_STATE_INITIALIZE); |
862f2f37 | 175 | |
2cd90902 QY |
176 | if (no) { |
177 | int oldstate = vr->v4->fsm.state; | |
6e93585e QY |
178 | failed = vrrp_del_ipv4(vr, ip); |
179 | vrrp_check_start(vr); | |
2cd90902 QY |
180 | deactivated = (vr->v4->fsm.state == VRRP_STATE_INITIALIZE |
181 | && oldstate != VRRP_STATE_INITIALIZE); | |
862f2f37 | 182 | } else { |
2cd90902 | 183 | int oldstate = vr->v4->fsm.state; |
6e93585e QY |
184 | failed = vrrp_add_ipv4(vr, ip); |
185 | vrrp_check_start(vr); | |
2cd90902 QY |
186 | activated = (vr->v4->fsm.state != VRRP_STATE_INITIALIZE |
187 | && oldstate == VRRP_STATE_INITIALIZE); | |
188 | } | |
189 | ||
190 | if (activated) | |
191 | vty_out(vty, "%% Activated IPv4 Virtual Router %ld\n", vrid); | |
192 | if (deactivated) | |
193 | vty_out(vty, "%% Deactivated IPv4 Virtual Router %ld\n", vrid); | |
194 | if (failed) { | |
1af0eb1f | 195 | vty_out(vty, "%% Failed to %s virtual IP\n", |
2cd90902 QY |
196 | no ? "remove" : "add"); |
197 | ret = CMD_WARNING_CONFIG_FAILED; | |
198 | if (will_activate && !activated) { | |
199 | vty_out(vty, | |
200 | "%% Failed to activate IPv4 Virtual Router %ld\n", | |
201 | vrid); | |
202 | } | |
862f2f37 QY |
203 | } |
204 | ||
205 | return ret; | |
206 | } | |
207 | ||
208 | DEFPY(vrrp_ip6, | |
209 | vrrp_ip6_cmd, | |
210 | "[no] vrrp (1-255)$vrid ipv6 X:X::X:X", | |
211 | NO_STR | |
212 | VRRP_STR | |
213 | VRRP_VRID_STR | |
214 | "Add IPv6 address\n" | |
215 | VRRP_IP_STR) | |
216 | { | |
4f0b6b45 QY |
217 | VTY_DECLVAR_CONTEXT(interface, ifp); |
218 | ||
862f2f37 | 219 | struct vrrp_vrouter *vr; |
2cd90902 QY |
220 | bool deactivated = false; |
221 | bool activated = false; | |
222 | bool failed = false; | |
223 | int ret = CMD_SUCCESS; | |
862f2f37 | 224 | |
4f0b6b45 | 225 | VROUTER_GET_VTY(vty, ifp, vrid, vr); |
862f2f37 | 226 | |
99966840 QY |
227 | if (vr->version != 3) { |
228 | vty_out(vty, | |
229 | "%% Cannot add IPv6 address to VRRPv2 virtual router\n"); | |
230 | return CMD_WARNING_CONFIG_FAILED; | |
231 | } | |
232 | ||
2cd90902 | 233 | bool will_activate = (vr->v6->fsm.state == VRRP_STATE_INITIALIZE); |
1d21789e | 234 | |
2cd90902 QY |
235 | if (no) { |
236 | int oldstate = vr->v6->fsm.state; | |
6e93585e | 237 | failed = vrrp_del_ipv6(vr, ipv6); |
2cd90902 QY |
238 | deactivated = (vr->v6->fsm.state == VRRP_STATE_INITIALIZE |
239 | && oldstate != VRRP_STATE_INITIALIZE); | |
1d21789e | 240 | } else { |
2cd90902 | 241 | int oldstate = vr->v6->fsm.state; |
6e93585e | 242 | failed = vrrp_add_ipv6(vr, ipv6); |
2cd90902 QY |
243 | activated = (vr->v6->fsm.state != VRRP_STATE_INITIALIZE |
244 | && oldstate == VRRP_STATE_INITIALIZE); | |
245 | } | |
246 | ||
247 | if (activated) | |
248 | vty_out(vty, "%% Activated IPv6 Virtual Router %ld\n", vrid); | |
249 | if (deactivated) | |
250 | vty_out(vty, "%% Deactivated IPv6 Virtual Router %ld\n", vrid); | |
251 | if (failed) { | |
d5a6ff43 | 252 | vty_out(vty, "%% Failed to %s virtual IP\n", |
2cd90902 QY |
253 | no ? "remove" : "add"); |
254 | ret = CMD_WARNING_CONFIG_FAILED; | |
255 | if (will_activate && !activated) { | |
256 | vty_out(vty, | |
d5a6ff43 | 257 | "%% Failed to activate IPv6 Virtual Router %ld\n", |
2cd90902 QY |
258 | vrid); |
259 | } | |
1d21789e QY |
260 | } |
261 | ||
262 | return ret; | |
c23edd74 QY |
263 | } |
264 | ||
8ec51216 QY |
265 | DEFPY(vrrp_preempt, |
266 | vrrp_preempt_cmd, | |
267 | "[no] vrrp (1-255)$vrid preempt", | |
268 | NO_STR | |
269 | VRRP_STR | |
270 | VRRP_VRID_STR | |
271 | "Preempt mode\n") | |
272 | { | |
273 | VTY_DECLVAR_CONTEXT(interface, ifp); | |
274 | ||
275 | struct vrrp_vrouter *vr; | |
276 | ||
277 | VROUTER_GET_VTY(vty, ifp, vrid, vr); | |
278 | ||
279 | vr->preempt_mode = !no; | |
280 | ||
281 | return CMD_SUCCESS; | |
282 | } | |
283 | ||
27fd8827 QY |
284 | DEFPY(vrrp_autoconfigure, |
285 | vrrp_autoconfigure_cmd, | |
286 | "[no] vrrp autoconfigure [version (2-3)]", | |
53e60e5c QY |
287 | NO_STR |
288 | VRRP_STR | |
289 | "Automatically set up VRRP instances on VRRP-compatible interfaces\n" | |
290 | "Version for automatically configured instances\n" | |
291 | VRRP_VERSION_STR) | |
292 | { | |
53e60e5c QY |
293 | version = version ? version : 3; |
294 | ||
27fd8827 QY |
295 | if (!no) |
296 | vrrp_autoconfig_on(version); | |
297 | else | |
298 | vrrp_autoconfig_off(); | |
53e60e5c QY |
299 | |
300 | return CMD_SUCCESS; | |
301 | } | |
302 | ||
6e21b5ae QY |
303 | /* |
304 | * Build JSON representation of VRRP instance. | |
305 | * | |
306 | * vr | |
307 | * VRRP router to build json object from | |
308 | * | |
309 | * Returns: | |
310 | * JSON representation of VRRP instance. Must be freed by caller. | |
311 | */ | |
312 | static struct json_object *vrrp_build_json(struct vrrp_vrouter *vr) | |
313 | { | |
314 | char ethstr4[ETHER_ADDR_STRLEN]; | |
315 | char ethstr6[ETHER_ADDR_STRLEN]; | |
316 | char ipstr[INET6_ADDRSTRLEN]; | |
317 | const char *stastr4 = vrrp_state_names[vr->v4->fsm.state]; | |
318 | const char *stastr6 = vrrp_state_names[vr->v6->fsm.state]; | |
319 | struct listnode *ln; | |
320 | struct ipaddr *ip; | |
321 | struct json_object *j = json_object_new_object(); | |
322 | struct json_object *v4 = json_object_new_object(); | |
323 | struct json_object *v4_addrs = json_object_new_array(); | |
324 | struct json_object *v6 = json_object_new_object(); | |
325 | struct json_object *v6_addrs = json_object_new_array(); | |
326 | ||
327 | prefix_mac2str(&vr->v4->vmac, ethstr4, sizeof(ethstr4)); | |
328 | prefix_mac2str(&vr->v6->vmac, ethstr6, sizeof(ethstr6)); | |
329 | ||
330 | json_object_int_add(j, "vrid", vr->vrid); | |
331 | json_object_int_add(j, "version", vr->version); | |
332 | json_object_boolean_add(j, "autoconfigured", vr->autoconf); | |
333 | json_object_boolean_add(j, "shutdown", vr->shutdown); | |
334 | json_object_boolean_add(j, "preempt_mode", vr->preempt_mode); | |
335 | json_object_boolean_add(j, "accept_mode", vr->accept_mode); | |
336 | json_object_string_add(j, "interface", vr->ifp->name); | |
337 | /* v4 */ | |
338 | json_object_string_add(v4, "interface", | |
339 | vr->v4->mvl_ifp ? vr->v4->mvl_ifp->name : ""); | |
340 | json_object_string_add(v4, "vmac", ethstr4); | |
341 | json_object_string_add(v4, "status", stastr4); | |
342 | json_object_int_add(v4, "effective_priority", vr->v4->priority); | |
343 | json_object_int_add(v4, "master_adver_interval", | |
344 | vr->v4->master_adver_interval); | |
345 | json_object_int_add(v4, "skew_time", vr->v4->skew_time); | |
346 | json_object_int_add(v4, "master_down_interval", | |
347 | vr->v4->master_down_interval); | |
348 | if (vr->v4->addrs->count) { | |
349 | for (ALL_LIST_ELEMENTS_RO(vr->v4->addrs, ln, ip)) { | |
350 | inet_ntop(vr->v4->family, &ip->ipaddr_v4, ipstr, | |
351 | sizeof(ipstr)); | |
352 | json_object_array_add(v4_addrs, | |
353 | json_object_new_string(ipstr)); | |
354 | } | |
355 | } | |
356 | json_object_object_add(v4, "addresses", v4_addrs); | |
357 | json_object_object_add(j, "v4", v4); | |
358 | ||
359 | /* v6 */ | |
360 | json_object_string_add(v6, "interface", | |
361 | vr->v6->mvl_ifp ? vr->v6->mvl_ifp->name : ""); | |
362 | json_object_string_add(v6, "vmac", ethstr6); | |
363 | json_object_string_add(v6, "status", stastr6); | |
364 | json_object_int_add(v6, "effective_priority", vr->v6->priority); | |
365 | json_object_int_add(v6, "master_adver_interval", | |
366 | vr->v6->master_adver_interval); | |
367 | json_object_int_add(v6, "skew_time", vr->v6->skew_time); | |
368 | json_object_int_add(v6, "master_down_interval", | |
369 | vr->v6->master_down_interval); | |
370 | if (vr->v6->addrs->count) { | |
371 | for (ALL_LIST_ELEMENTS_RO(vr->v6->addrs, ln, ip)) { | |
372 | inet_ntop(vr->v6->family, &ip->ipaddr_v6, ipstr, | |
373 | sizeof(ipstr)); | |
374 | json_object_array_add(v6_addrs, | |
375 | json_object_new_string(ipstr)); | |
376 | } | |
377 | } | |
378 | json_object_object_add(v6, "addresses", v6_addrs); | |
379 | json_object_object_add(j, "v6", v6); | |
380 | ||
381 | return j; | |
382 | } | |
383 | ||
1d21789e | 384 | static void vrrp_show(struct vty *vty, struct vrrp_vrouter *vr) |
c23edd74 | 385 | { |
862f2f37 QY |
386 | char ethstr4[ETHER_ADDR_STRLEN]; |
387 | char ethstr6[ETHER_ADDR_STRLEN]; | |
388 | char ipstr[INET6_ADDRSTRLEN]; | |
389 | const char *stastr4 = vrrp_state_names[vr->v4->fsm.state]; | |
390 | const char *stastr6 = vrrp_state_names[vr->v6->fsm.state]; | |
391 | struct listnode *ln; | |
392 | struct ipaddr *ip; | |
c23edd74 QY |
393 | |
394 | struct ttable *tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]); | |
395 | ||
396 | ttable_add_row(tt, "%s|%" PRIu32, "Virtual Router ID", vr->vrid); | |
99966840 | 397 | ttable_add_row(tt, "%s|%" PRIu8, "Protocol Version", vr->version); |
27fd8827 QY |
398 | ttable_add_row(tt, "%s|%s", "Autoconfigured", |
399 | vr->autoconf ? "Yes" : "No"); | |
f96a183b | 400 | ttable_add_row(tt, "%s|%s", "Shutdown", vr->shutdown ? "Yes" : "No"); |
5302f67b | 401 | ttable_add_row(tt, "%s|%s", "Interface", vr->ifp->name); |
862f2f37 QY |
402 | prefix_mac2str(&vr->v4->vmac, ethstr4, sizeof(ethstr4)); |
403 | prefix_mac2str(&vr->v6->vmac, ethstr6, sizeof(ethstr6)); | |
5302f67b QY |
404 | ttable_add_row(tt, "%s|%s", "VRRP interface (v4)", |
405 | vr->v4->mvl_ifp ? vr->v4->mvl_ifp->name : "None"); | |
406 | ttable_add_row(tt, "%s|%s", "VRRP interface (v6)", | |
407 | vr->v6->mvl_ifp ? vr->v6->mvl_ifp->name : "None"); | |
862f2f37 QY |
408 | ttable_add_row(tt, "%s|%s", "Virtual MAC (v4)", ethstr4); |
409 | ttable_add_row(tt, "%s|%s", "Virtual MAC (v6)", ethstr6); | |
410 | ttable_add_row(tt, "%s|%s", "Status (v4)", stastr4); | |
411 | ttable_add_row(tt, "%s|%s", "Status (v6)", stastr6); | |
c23edd74 | 412 | ttable_add_row(tt, "%s|%" PRIu8, "Priority", vr->priority); |
862f2f37 QY |
413 | ttable_add_row(tt, "%s|%" PRIu8, "Effective Priority (v4)", |
414 | vr->v4->priority); | |
415 | ttable_add_row(tt, "%s|%" PRIu8, "Effective Priority (v6)", | |
416 | vr->v6->priority); | |
c23edd74 QY |
417 | ttable_add_row(tt, "%s|%s", "Preempt Mode", |
418 | vr->preempt_mode ? "Yes" : "No"); | |
419 | ttable_add_row(tt, "%s|%s", "Accept Mode", | |
420 | vr->accept_mode ? "Yes" : "No"); | |
69f63d1a | 421 | ttable_add_row(tt, "%s|%" PRIu16" cs", "Advertisement Interval", |
c23edd74 | 422 | vr->advertisement_interval); |
862f2f37 QY |
423 | ttable_add_row(tt, "%s|%" PRIu16" cs", "Master Advertisement Interval (v4)", |
424 | vr->v4->master_adver_interval); | |
425 | ttable_add_row(tt, "%s|%" PRIu16" cs", "Master Advertisement Interval (v6)", | |
426 | vr->v6->master_adver_interval); | |
427 | ttable_add_row(tt, "%s|%" PRIu16" cs", "Skew Time (v4)", vr->v4->skew_time); | |
428 | ttable_add_row(tt, "%s|%" PRIu16" cs", "Skew Time (v6)", vr->v6->skew_time); | |
429 | ttable_add_row(tt, "%s|%" PRIu16" cs", "Master Down Interval (v4)", | |
430 | vr->v4->master_down_interval); | |
431 | ttable_add_row(tt, "%s|%" PRIu16" cs", "Master Down Interval (v6)", | |
432 | vr->v6->master_down_interval); | |
433 | ttable_add_row(tt, "%s|%u", "IPv4 Addresses", vr->v4->addrs->count); | |
c23edd74 | 434 | |
92c399a4 | 435 | char fill[35]; |
5302f67b QY |
436 | memset(fill, '.', sizeof(fill)); |
437 | fill[sizeof(fill) - 1] = 0x00; | |
862f2f37 | 438 | if (vr->v4->addrs->count) { |
862f2f37 QY |
439 | for (ALL_LIST_ELEMENTS_RO(vr->v4->addrs, ln, ip)) { |
440 | inet_ntop(vr->v4->family, &ip->ipaddr_v4, ipstr, | |
441 | sizeof(ipstr)); | |
5302f67b | 442 | ttable_add_row(tt, "%s|%s", fill, ipstr); |
862f2f37 | 443 | } |
862f2f37 QY |
444 | } |
445 | ||
5302f67b QY |
446 | ttable_add_row(tt, "%s|%u", "IPv6 Addresses", vr->v6->addrs->count); |
447 | ||
862f2f37 | 448 | if (vr->v6->addrs->count) { |
862f2f37 QY |
449 | for (ALL_LIST_ELEMENTS_RO(vr->v6->addrs, ln, ip)) { |
450 | inet_ntop(vr->v6->family, &ip->ipaddr_v6, ipstr, | |
451 | sizeof(ipstr)); | |
5302f67b | 452 | ttable_add_row(tt, "%s|%s", fill, ipstr); |
c23edd74 | 453 | } |
c23edd74 | 454 | } |
5302f67b QY |
455 | |
456 | char *table = ttable_dump(tt, "\n"); | |
457 | vty_out(vty, "\n%s\n", table); | |
458 | XFREE(MTYPE_TMP, table); | |
459 | ttable_del(tt); | |
1d21789e QY |
460 | } |
461 | ||
462 | DEFPY(vrrp_vrid_show, | |
463 | vrrp_vrid_show_cmd, | |
6e21b5ae | 464 | "show vrrp [interface INTERFACE$ifn] [(1-255)$vrid] [json$json]", |
1d21789e QY |
465 | SHOW_STR |
466 | VRRP_STR | |
4f0b6b45 QY |
467 | INTERFACE_STR |
468 | "Only show VRRP instances on this interface\n" | |
6e21b5ae QY |
469 | VRRP_VRID_STR |
470 | JSON_STR) | |
1d21789e QY |
471 | { |
472 | struct vrrp_vrouter *vr; | |
4f0b6b45 QY |
473 | struct listnode *ln; |
474 | struct list *ll = hash_to_list(vrrp_vrouters_hash); | |
6e21b5ae | 475 | struct json_object *j = json_object_new_array(); |
1d21789e | 476 | |
4f0b6b45 QY |
477 | for (ALL_LIST_ELEMENTS_RO(ll, ln, vr)) { |
478 | if (ifn && !strmatch(ifn, vr->ifp->name)) | |
479 | continue; | |
480 | if (vrid && vrid != vr->vrid) | |
481 | continue; | |
5302f67b | 482 | |
6e21b5ae QY |
483 | if (!json) |
484 | vrrp_show(vty, vr); | |
485 | else | |
486 | json_object_array_add(j, vrrp_build_json(vr)); | |
1d21789e | 487 | } |
c23edd74 | 488 | |
6e21b5ae QY |
489 | if (json) |
490 | vty_out(vty, "%s\n", | |
491 | json_object_to_json_string_ext( | |
492 | j, JSON_C_TO_STRING_PRETTY)); | |
493 | ||
494 | json_object_free(j); | |
495 | ||
4f0b6b45 QY |
496 | list_delete(&ll); |
497 | ||
c23edd74 QY |
498 | return CMD_SUCCESS; |
499 | } | |
500 | ||
78fb3dbe QY |
501 | |
502 | DEFPY(debug_vrrp, | |
503 | debug_vrrp_cmd, | |
504 | "[no] debug vrrp [{protocol$proto|autoconfigure$ac|packets$pkt|sockets$sock|ndisc$ndisc|arp$arp|zebra$zebra}]", | |
505 | NO_STR | |
506 | DEBUG_STR | |
507 | VRRP_STR | |
508 | "Debug protocol state\n" | |
509 | "Debug autoconfiguration\n" | |
510 | "Debug sent and received packets\n" | |
511 | "Debug socket creation and configuration\n" | |
512 | "Debug Neighbor Discovery\n" | |
513 | "Debug ARP\n" | |
514 | "Debug Zebra events\n") | |
515 | { | |
516 | /* If no specific are given on/off them all */ | |
517 | if (strmatch(argv[argc - 1]->text, "vrrp")) | |
518 | vrrp_debug_set(NULL, 0, vty->node, !no, true, true, true, true, | |
519 | true, true, true); | |
520 | else | |
521 | vrrp_debug_set(NULL, 0, vty->node, !no, !!proto, !!ac, !!pkt, | |
522 | !!sock, !!ndisc, !!arp, !!zebra); | |
523 | ||
524 | return CMD_SUCCESS; | |
525 | } | |
526 | ||
527 | DEFUN_NOSH (show_debugging_vrrp, | |
528 | show_debugging_vrrp_cmd, | |
529 | "show debugging [vrrp]", | |
530 | SHOW_STR | |
531 | DEBUG_STR | |
532 | "VRRP information\n") | |
533 | { | |
534 | vty_out(vty, "VRRP debugging status:\n"); | |
535 | ||
536 | vrrp_debug_status_write(vty); | |
537 | ||
538 | return CMD_SUCCESS; | |
539 | } | |
540 | ||
b637bcd4 QY |
541 | /* clang-format on */ |
542 | ||
f828842a | 543 | static struct cmd_node interface_node = {INTERFACE_NODE, "%s(config-if)# ", 1}; |
78fb3dbe | 544 | static struct cmd_node debug_node = {DEBUG_NODE, "", 1}; |
f828842a | 545 | static struct cmd_node vrrp_node = {VRRP_NODE, "", 1}; |
78fb3dbe | 546 | |
5435a2bf QY |
547 | void vrrp_vty_init(void) |
548 | { | |
f828842a QY |
549 | install_node(&debug_node, vrrp_config_write_debug); |
550 | install_node(&interface_node, vrrp_config_write_interface); | |
551 | install_node(&vrrp_node, vrrp_config_write_global); | |
5435a2bf | 552 | if_cmd_init(); |
78fb3dbe | 553 | |
c23edd74 | 554 | install_element(VIEW_NODE, &vrrp_vrid_show_cmd); |
78fb3dbe QY |
555 | install_element(VIEW_NODE, &show_debugging_vrrp_cmd); |
556 | install_element(VIEW_NODE, &debug_vrrp_cmd); | |
557 | install_element(CONFIG_NODE, &debug_vrrp_cmd); | |
27fd8827 | 558 | install_element(CONFIG_NODE, &vrrp_autoconfigure_cmd); |
5435a2bf | 559 | install_element(INTERFACE_NODE, &vrrp_vrid_cmd); |
f96a183b | 560 | install_element(INTERFACE_NODE, &vrrp_shutdown_cmd); |
c23edd74 | 561 | install_element(INTERFACE_NODE, &vrrp_priority_cmd); |
1d21789e | 562 | install_element(INTERFACE_NODE, &vrrp_advertisement_interval_cmd); |
c23edd74 | 563 | install_element(INTERFACE_NODE, &vrrp_ip_cmd); |
862f2f37 | 564 | install_element(INTERFACE_NODE, &vrrp_ip6_cmd); |
8ec51216 | 565 | install_element(INTERFACE_NODE, &vrrp_preempt_cmd); |
5435a2bf | 566 | } |