]>
Commit | Line | Data |
---|---|---|
7f57883e DS |
1 | /* |
2 | * EIGRP VTY Interface. | |
3 | * Copyright (C) 2013-2016 | |
4 | * Authors: | |
5 | * Donnie Savage | |
6 | * Jan Janovic | |
7 | * Matej Perina | |
8 | * Peter Orsag | |
9 | * Peter Paluch | |
10 | * Frantisek Gazo | |
11 | * Tomas Hvorkovy | |
12 | * Martin Kontsek | |
13 | * Lukas Koribsky | |
14 | * | |
15 | * This file is part of GNU Zebra. | |
16 | * | |
17 | * GNU Zebra is free software; you can redistribute it and/or modify it | |
18 | * under the terms of the GNU General Public License as published by the | |
19 | * Free Software Foundation; either version 2, or (at your option) any | |
20 | * later version. | |
21 | * | |
22 | * GNU Zebra is distributed in the hope that it will be useful, but | |
23 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
25 | * General Public License for more details. | |
26 | * | |
896014f4 DL |
27 | * You should have received a copy of the GNU General Public License along |
28 | * with this program; see the file COPYING; if not, write to the Free Software | |
29 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
7f57883e DS |
30 | */ |
31 | ||
32 | #include <zebra.h> | |
33 | ||
34 | #include "memory.h" | |
35 | #include "thread.h" | |
36 | #include "prefix.h" | |
37 | #include "table.h" | |
38 | #include "vty.h" | |
39 | #include "command.h" | |
40 | #include "plist.h" | |
41 | #include "log.h" | |
42 | #include "zclient.h" | |
43 | #include "keychain.h" | |
44 | #include "linklist.h" | |
45 | #include "distribute.h" | |
46 | ||
47 | #include "eigrpd/eigrp_structs.h" | |
48 | #include "eigrpd/eigrpd.h" | |
49 | #include "eigrpd/eigrp_interface.h" | |
50 | #include "eigrpd/eigrp_neighbor.h" | |
51 | #include "eigrpd/eigrp_packet.h" | |
52 | #include "eigrpd/eigrp_zebra.h" | |
53 | #include "eigrpd/eigrp_vty.h" | |
54 | #include "eigrpd/eigrp_network.h" | |
55 | #include "eigrpd/eigrp_dump.h" | |
56 | #include "eigrpd/eigrp_const.h" | |
57 | ||
085fc344 DS |
58 | #ifndef VTYSH_EXTRACT_PL |
59 | #include "eigrpd/eigrp_vty_clippy.c" | |
60 | #endif | |
61 | ||
b0534a89 DS |
62 | static void eigrp_vty_display_prefix_entry(struct vty *vty, |
63 | struct eigrp *eigrp, | |
64 | struct eigrp_prefix_entry *pe, | |
65 | bool all) | |
66 | { | |
67 | bool first = true; | |
68 | struct eigrp_nexthop_entry *te; | |
69 | struct listnode *node; | |
70 | ||
71 | for (ALL_LIST_ELEMENTS_RO(pe->entries, node, te)) { | |
72 | if (all | |
73 | || (((te->flags | |
74 | & EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG) | |
75 | == EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG) | |
76 | || ((te->flags | |
77 | & EIGRP_NEXTHOP_ENTRY_FSUCCESSOR_FLAG) | |
78 | == EIGRP_NEXTHOP_ENTRY_FSUCCESSOR_FLAG))) { | |
79 | show_ip_eigrp_nexthop_entry(vty, eigrp, te, | |
80 | &first); | |
81 | first = false; | |
82 | } | |
83 | } | |
84 | } | |
85 | ||
cae06ae0 DS |
86 | static struct eigrp *eigrp_vty_get_eigrp(struct vty *vty, const char *vrf_name) |
87 | { | |
88 | struct vrf *vrf; | |
89 | ||
90 | if (vrf_name) | |
91 | vrf = vrf_lookup_by_name(vrf_name); | |
92 | else | |
93 | vrf = vrf_lookup_by_id(VRF_DEFAULT); | |
94 | ||
95 | if (!vrf) { | |
96 | vty_out(vty, "VRF %s specified does not exist", | |
97 | vrf_name ? vrf_name : VRF_DEFAULT_NAME); | |
98 | return NULL; | |
99 | } | |
100 | ||
101 | return eigrp_lookup(vrf->vrf_id); | |
102 | } | |
103 | ||
10b3a325 DS |
104 | static void eigrp_topology_helper(struct vty *vty, struct eigrp *eigrp, |
105 | const char *all) | |
106 | { | |
107 | struct eigrp_prefix_entry *tn; | |
108 | struct route_node *rn; | |
109 | ||
110 | show_ip_eigrp_topology_header(vty, eigrp); | |
111 | ||
112 | for (rn = route_top(eigrp->topology_table); rn; rn = route_next(rn)) { | |
113 | if (!rn->info) | |
114 | continue; | |
115 | ||
116 | tn = rn->info; | |
117 | eigrp_vty_display_prefix_entry(vty, eigrp, tn, | |
118 | all ? true : false); | |
119 | } | |
120 | } | |
121 | ||
13133652 DS |
122 | DEFPY (show_ip_eigrp_topology_all, |
123 | show_ip_eigrp_topology_all_cmd, | |
cae06ae0 | 124 | "show ip eigrp [vrf NAME] topology [all-links$all]", |
7f57883e DS |
125 | SHOW_STR |
126 | IP_STR | |
127 | "IP-EIGRP show commands\n" | |
cae06ae0 | 128 | VRF_CMD_HELP_STR |
7f57883e DS |
129 | "IP-EIGRP topology\n" |
130 | "Show all links in topology table\n") | |
131 | { | |
d62a17ae | 132 | struct eigrp *eigrp; |
d62a17ae | 133 | |
10b3a325 DS |
134 | if (vrf && strncmp(vrf, "all", sizeof("all")) == 0) { |
135 | struct vrf *v; | |
d62a17ae | 136 | |
10b3a325 DS |
137 | RB_FOREACH (v, vrf_name_head, &vrfs_by_name) { |
138 | eigrp = eigrp_lookup(v->vrf_id); | |
139 | if (!eigrp) | |
140 | continue; | |
d62a17ae | 141 | |
10b3a325 | 142 | vty_out(vty, "VRF %s:\n", v->name); |
9ca66cc7 | 143 | |
10b3a325 DS |
144 | eigrp_topology_helper(vty, eigrp, all); |
145 | } | |
146 | } else { | |
147 | eigrp = eigrp_vty_get_eigrp(vty, vrf); | |
148 | if (eigrp == NULL) { | |
149 | vty_out(vty, " EIGRP Routing Process not enabled\n"); | |
150 | return CMD_SUCCESS; | |
151 | } | |
152 | ||
153 | eigrp_topology_helper(vty, eigrp, all); | |
d62a17ae | 154 | } |
155 | ||
156 | return CMD_SUCCESS; | |
7f57883e DS |
157 | } |
158 | ||
13133652 DS |
159 | DEFPY (show_ip_eigrp_topology, |
160 | show_ip_eigrp_topology_cmd, | |
cae06ae0 | 161 | "show ip eigrp [vrf NAME] topology <A.B.C.D$address|A.B.C.D/M$prefix>", |
13133652 DS |
162 | SHOW_STR |
163 | IP_STR | |
164 | "IP-EIGRP show commands\n" | |
cae06ae0 | 165 | VRF_CMD_HELP_STR |
13133652 DS |
166 | "IP-EIGRP topology\n" |
167 | "For a specific address\n" | |
168 | "For a specific prefix\n") | |
169 | { | |
170 | struct eigrp *eigrp; | |
171 | struct eigrp_prefix_entry *tn; | |
172 | struct route_node *rn; | |
173 | struct prefix cmp; | |
174 | ||
10b3a325 DS |
175 | if (vrf && strncmp(vrf, "all", sizeof("all")) == 0) { |
176 | vty_out(vty, "Specifying vrf `all` for a particular address/prefix makes no sense\n"); | |
177 | return CMD_SUCCESS; | |
178 | } | |
179 | ||
cae06ae0 | 180 | eigrp = eigrp_vty_get_eigrp(vty, vrf); |
13133652 DS |
181 | if (eigrp == NULL) { |
182 | vty_out(vty, " EIGRP Routing Process not enabled\n"); | |
183 | return CMD_SUCCESS; | |
184 | } | |
185 | ||
186 | show_ip_eigrp_topology_header(vty, eigrp); | |
187 | ||
188 | if (address_str) | |
189 | prefix_str = address_str; | |
190 | ||
191 | if (str2prefix(prefix_str, &cmp) < 0) { | |
192 | vty_out(vty, "%% Malformed address\n"); | |
193 | return CMD_WARNING; | |
194 | } | |
195 | ||
196 | rn = route_node_match(eigrp->topology_table, &cmp); | |
197 | if (!rn) { | |
198 | vty_out(vty, "%% Network not in table\n"); | |
199 | return CMD_WARNING; | |
200 | } | |
201 | ||
202 | if (!rn->info) { | |
203 | vty_out(vty, "%% Network not in table\n"); | |
204 | route_unlock_node(rn); | |
205 | return CMD_WARNING; | |
206 | } | |
207 | ||
208 | tn = rn->info; | |
209 | eigrp_vty_display_prefix_entry(vty, eigrp, tn, argc == 5); | |
210 | ||
051da24e | 211 | route_unlock_node(rn); |
13133652 DS |
212 | return CMD_SUCCESS; |
213 | } | |
7f57883e | 214 | |
b1d26a40 DS |
215 | static void eigrp_interface_helper(struct vty *vty, struct eigrp *eigrp, |
216 | const char *ifname, const char *detail) | |
217 | { | |
218 | struct eigrp_interface *ei; | |
219 | struct listnode *node; | |
220 | ||
221 | if (!ifname) | |
222 | show_ip_eigrp_interface_header(vty, eigrp); | |
223 | ||
224 | for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) { | |
225 | if (!ifname || strcmp(ei->ifp->name, ifname) == 0) { | |
226 | show_ip_eigrp_interface_sub(vty, eigrp, ei); | |
227 | if (detail) | |
228 | show_ip_eigrp_interface_detail(vty, eigrp, ei); | |
229 | } | |
230 | } | |
231 | } | |
232 | ||
cae06ae0 | 233 | DEFPY (show_ip_eigrp_interfaces, |
7f57883e | 234 | show_ip_eigrp_interfaces_cmd, |
cae06ae0 | 235 | "show ip eigrp [vrf NAME] interfaces [IFNAME] [detail]$detail", |
7f57883e DS |
236 | SHOW_STR |
237 | IP_STR | |
238 | "IP-EIGRP show commands\n" | |
cae06ae0 | 239 | VRF_CMD_HELP_STR |
dbc56a10 DS |
240 | "IP-EIGRP interfaces\n" |
241 | "Interface name to look at\n" | |
242 | "Detailed information\n") | |
7f57883e | 243 | { |
d62a17ae | 244 | struct eigrp *eigrp; |
d62a17ae | 245 | |
b1d26a40 DS |
246 | if (vrf && strncmp(vrf, "all", sizeof("all")) == 0) { |
247 | struct vrf *vrf; | |
d62a17ae | 248 | |
b1d26a40 DS |
249 | RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { |
250 | eigrp = eigrp_lookup(vrf->vrf_id); | |
251 | if (!eigrp) | |
252 | continue; | |
d62a17ae | 253 | |
b1d26a40 DS |
254 | vty_out(vty, "VRF %s:\n", vrf->name); |
255 | ||
256 | eigrp_interface_helper(vty, eigrp, ifname, detail); | |
257 | } | |
258 | } else { | |
259 | eigrp = eigrp_vty_get_eigrp(vty, vrf); | |
260 | if (eigrp == NULL) { | |
261 | vty_out(vty, "EIGRP Routing Process not enabled\n"); | |
262 | return CMD_SUCCESS; | |
d62a17ae | 263 | } |
b1d26a40 DS |
264 | |
265 | eigrp_interface_helper(vty, eigrp, ifname, detail); | |
d62a17ae | 266 | } |
267 | ||
b1d26a40 | 268 | |
d62a17ae | 269 | return CMD_SUCCESS; |
7f57883e DS |
270 | } |
271 | ||
fb41c4f3 DS |
272 | static void eigrp_neighbors_helper(struct vty *vty, struct eigrp *eigrp, |
273 | const char *ifname, const char *detail) | |
274 | { | |
275 | struct eigrp_interface *ei; | |
276 | struct listnode *node, *node2, *nnode2; | |
277 | struct eigrp_neighbor *nbr; | |
278 | ||
279 | show_ip_eigrp_neighbor_header(vty, eigrp); | |
280 | ||
281 | for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) { | |
282 | if (!ifname || strcmp(ei->ifp->name, ifname) == 0) { | |
283 | for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) { | |
284 | if (detail || (nbr->state == EIGRP_NEIGHBOR_UP)) | |
285 | show_ip_eigrp_neighbor_sub(vty, nbr, | |
286 | !!detail); | |
287 | } | |
288 | } | |
289 | } | |
290 | } | |
291 | ||
cae06ae0 | 292 | DEFPY (show_ip_eigrp_neighbors, |
7f57883e | 293 | show_ip_eigrp_neighbors_cmd, |
cae06ae0 | 294 | "show ip eigrp [vrf NAME] neighbors [IFNAME] [detail]$detail", |
7f57883e DS |
295 | SHOW_STR |
296 | IP_STR | |
297 | "IP-EIGRP show commands\n" | |
cae06ae0 | 298 | VRF_CMD_HELP_STR |
dbc56a10 DS |
299 | "IP-EIGRP neighbors\n" |
300 | "Interface to show on\n" | |
301 | "Detailed Information\n") | |
7f57883e | 302 | { |
d62a17ae | 303 | struct eigrp *eigrp; |
d62a17ae | 304 | |
fb41c4f3 DS |
305 | if (vrf && strncmp(vrf, "all", sizeof("all")) == 0) { |
306 | struct vrf *vrf; | |
d62a17ae | 307 | |
fb41c4f3 DS |
308 | RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { |
309 | eigrp = eigrp_lookup(vrf->vrf_id); | |
310 | if (!eigrp) | |
311 | continue; | |
d62a17ae | 312 | |
fb41c4f3 DS |
313 | vty_out(vty, "VRF %s:\n", vrf->name); |
314 | ||
315 | eigrp_neighbors_helper(vty, eigrp, ifname, detail); | |
316 | } | |
317 | } else { | |
318 | eigrp = eigrp_vty_get_eigrp(vty, vrf); | |
319 | if (eigrp == NULL) { | |
320 | vty_out(vty, " EIGRP Routing Process not enabled\n"); | |
321 | return CMD_SUCCESS; | |
d62a17ae | 322 | } |
fb41c4f3 DS |
323 | |
324 | eigrp_neighbors_helper(vty, eigrp, ifname, detail); | |
d62a17ae | 325 | } |
326 | ||
327 | return CMD_SUCCESS; | |
7f57883e DS |
328 | } |
329 | ||
7f57883e DS |
330 | /* |
331 | * Execute hard restart for all neighbors | |
332 | */ | |
cae06ae0 | 333 | DEFPY (clear_ip_eigrp_neighbors, |
7f57883e | 334 | clear_ip_eigrp_neighbors_cmd, |
cae06ae0 | 335 | "clear ip eigrp [vrf NAME] neighbors", |
7f57883e DS |
336 | CLEAR_STR |
337 | IP_STR | |
338 | "Clear IP-EIGRP\n" | |
cae06ae0 | 339 | VRF_CMD_HELP_STR |
7f57883e DS |
340 | "Clear IP-EIGRP neighbors\n") |
341 | { | |
d62a17ae | 342 | struct eigrp *eigrp; |
343 | struct eigrp_interface *ei; | |
344 | struct listnode *node, *node2, *nnode2; | |
345 | struct eigrp_neighbor *nbr; | |
346 | ||
347 | /* Check if eigrp process is enabled */ | |
cae06ae0 | 348 | eigrp = eigrp_vty_get_eigrp(vty, vrf); |
d62a17ae | 349 | if (eigrp == NULL) { |
350 | vty_out(vty, " EIGRP Routing Process not enabled\n"); | |
351 | return CMD_SUCCESS; | |
352 | } | |
353 | ||
354 | /* iterate over all eigrp interfaces */ | |
355 | for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) { | |
356 | /* send Goodbye Hello */ | |
357 | eigrp_hello_send(ei, EIGRP_HELLO_GRACEFUL_SHUTDOWN, NULL); | |
358 | ||
359 | /* iterate over all neighbors on eigrp interface */ | |
360 | for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) { | |
361 | if (nbr->state != EIGRP_NEIGHBOR_DOWN) { | |
362 | zlog_debug( | |
37b4b3cc DS |
363 | "Neighbor %pI4 (%s) is down: manually cleared", |
364 | &nbr->src, | |
d62a17ae | 365 | ifindex2ifname(nbr->ei->ifp->ifindex, |
daa64bdf | 366 | eigrp->vrf_id)); |
d62a17ae | 367 | vty_time_print(vty, 0); |
368 | vty_out(vty, | |
37b4b3cc DS |
369 | "Neighbor %pI4 (%s) is down: manually cleared\n", |
370 | &nbr->src, | |
d62a17ae | 371 | ifindex2ifname(nbr->ei->ifp->ifindex, |
daa64bdf | 372 | eigrp->vrf_id)); |
d62a17ae | 373 | |
374 | /* set neighbor to DOWN */ | |
375 | nbr->state = EIGRP_NEIGHBOR_DOWN; | |
376 | /* delete neighbor */ | |
377 | eigrp_nbr_delete(nbr); | |
378 | } | |
379 | } | |
380 | } | |
381 | ||
382 | return CMD_SUCCESS; | |
7f57883e DS |
383 | } |
384 | ||
385 | /* | |
386 | * Execute hard restart for all neighbors on interface | |
387 | */ | |
cae06ae0 | 388 | DEFPY (clear_ip_eigrp_neighbors_int, |
7f57883e | 389 | clear_ip_eigrp_neighbors_int_cmd, |
cae06ae0 | 390 | "clear ip eigrp [vrf NAME] neighbors IFNAME", |
7f57883e DS |
391 | CLEAR_STR |
392 | IP_STR | |
393 | "Clear IP-EIGRP\n" | |
cae06ae0 | 394 | VRF_CMD_HELP_STR |
7f57883e DS |
395 | "Clear IP-EIGRP neighbors\n" |
396 | "Interface's name\n") | |
397 | { | |
d62a17ae | 398 | struct eigrp *eigrp; |
399 | struct eigrp_interface *ei; | |
400 | struct listnode *node2, *nnode2; | |
401 | struct eigrp_neighbor *nbr; | |
d62a17ae | 402 | |
403 | /* Check if eigrp process is enabled */ | |
cae06ae0 | 404 | eigrp = eigrp_vty_get_eigrp(vty, vrf); |
d62a17ae | 405 | if (eigrp == NULL) { |
406 | vty_out(vty, " EIGRP Routing Process not enabled\n"); | |
407 | return CMD_SUCCESS; | |
408 | } | |
409 | ||
410 | /* lookup interface by specified name */ | |
cae06ae0 | 411 | ei = eigrp_if_lookup_by_name(eigrp, ifname); |
d62a17ae | 412 | if (ei == NULL) { |
cae06ae0 | 413 | vty_out(vty, " Interface (%s) doesn't exist\n", ifname); |
d62a17ae | 414 | return CMD_WARNING; |
415 | } | |
416 | ||
417 | /* send Goodbye Hello */ | |
418 | eigrp_hello_send(ei, EIGRP_HELLO_GRACEFUL_SHUTDOWN, NULL); | |
419 | ||
420 | /* iterate over all neighbors on eigrp interface */ | |
421 | for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) { | |
422 | if (nbr->state != EIGRP_NEIGHBOR_DOWN) { | |
37b4b3cc DS |
423 | zlog_debug( |
424 | "Neighbor %pI4 (%s) is down: manually cleared", | |
425 | &nbr->src, | |
426 | ifindex2ifname(nbr->ei->ifp->ifindex, | |
427 | eigrp->vrf_id)); | |
d62a17ae | 428 | vty_time_print(vty, 0); |
429 | vty_out(vty, | |
37b4b3cc DS |
430 | "Neighbor %pI4 (%s) is down: manually cleared\n", |
431 | &nbr->src, | |
d62a17ae | 432 | ifindex2ifname(nbr->ei->ifp->ifindex, |
daa64bdf | 433 | eigrp->vrf_id)); |
d62a17ae | 434 | |
435 | /* set neighbor to DOWN */ | |
436 | nbr->state = EIGRP_NEIGHBOR_DOWN; | |
437 | /* delete neighbor */ | |
438 | eigrp_nbr_delete(nbr); | |
439 | } | |
440 | } | |
441 | ||
442 | return CMD_SUCCESS; | |
7f57883e DS |
443 | } |
444 | ||
445 | /* | |
446 | * Execute hard restart for neighbor specified by IP | |
447 | */ | |
cae06ae0 | 448 | DEFPY (clear_ip_eigrp_neighbors_IP, |
7f57883e | 449 | clear_ip_eigrp_neighbors_IP_cmd, |
cae06ae0 | 450 | "clear ip eigrp [vrf NAME] neighbors A.B.C.D$nbr_addr", |
7f57883e DS |
451 | CLEAR_STR |
452 | IP_STR | |
453 | "Clear IP-EIGRP\n" | |
cae06ae0 | 454 | VRF_CMD_HELP_STR |
7f57883e DS |
455 | "Clear IP-EIGRP neighbors\n" |
456 | "IP-EIGRP neighbor address\n") | |
457 | { | |
d62a17ae | 458 | struct eigrp *eigrp; |
459 | struct eigrp_neighbor *nbr; | |
d62a17ae | 460 | |
461 | /* Check if eigrp process is enabled */ | |
cae06ae0 | 462 | eigrp = eigrp_vty_get_eigrp(vty, vrf); |
d62a17ae | 463 | if (eigrp == NULL) { |
464 | vty_out(vty, " EIGRP Routing Process not enabled\n"); | |
465 | return CMD_SUCCESS; | |
466 | } | |
467 | ||
468 | /* lookup neighbor in whole process */ | |
469 | nbr = eigrp_nbr_lookup_by_addr_process(eigrp, nbr_addr); | |
470 | ||
471 | /* if neighbor doesn't exists, notify user and exit */ | |
472 | if (nbr == NULL) { | |
473 | vty_out(vty, "Neighbor with entered address doesn't exists.\n"); | |
474 | return CMD_WARNING; | |
475 | } | |
476 | ||
477 | /* execute hard reset on neighbor */ | |
478 | eigrp_nbr_hard_restart(nbr, vty); | |
479 | ||
480 | return CMD_SUCCESS; | |
7f57883e DS |
481 | } |
482 | ||
483 | /* | |
484 | * Execute graceful restart for all neighbors | |
485 | */ | |
cae06ae0 | 486 | DEFPY (clear_ip_eigrp_neighbors_soft, |
7f57883e | 487 | clear_ip_eigrp_neighbors_soft_cmd, |
cae06ae0 | 488 | "clear ip eigrp [vrf NAME] neighbors soft", |
7f57883e DS |
489 | CLEAR_STR |
490 | IP_STR | |
491 | "Clear IP-EIGRP\n" | |
cae06ae0 | 492 | VRF_CMD_HELP_STR |
7f57883e DS |
493 | "Clear IP-EIGRP neighbors\n" |
494 | "Resync with peers without adjacency reset\n") | |
495 | { | |
d62a17ae | 496 | struct eigrp *eigrp; |
7f57883e | 497 | |
d62a17ae | 498 | /* Check if eigrp process is enabled */ |
cae06ae0 | 499 | eigrp = eigrp_vty_get_eigrp(vty, vrf); |
d62a17ae | 500 | if (eigrp == NULL) { |
501 | vty_out(vty, " EIGRP Routing Process not enabled\n"); | |
502 | return CMD_SUCCESS; | |
503 | } | |
7f57883e | 504 | |
d62a17ae | 505 | /* execute graceful restart on all neighbors */ |
506 | eigrp_update_send_process_GR(eigrp, EIGRP_GR_MANUAL, vty); | |
7f57883e | 507 | |
d62a17ae | 508 | return CMD_SUCCESS; |
7f57883e DS |
509 | } |
510 | ||
511 | /* | |
512 | * Execute graceful restart for all neighbors on interface | |
513 | */ | |
cae06ae0 | 514 | DEFPY (clear_ip_eigrp_neighbors_int_soft, |
7f57883e | 515 | clear_ip_eigrp_neighbors_int_soft_cmd, |
cae06ae0 | 516 | "clear ip eigrp [vrf NAME] neighbors IFNAME soft", |
7f57883e DS |
517 | CLEAR_STR |
518 | IP_STR | |
519 | "Clear IP-EIGRP\n" | |
cae06ae0 | 520 | VRF_CMD_HELP_STR |
7f57883e DS |
521 | "Clear IP-EIGRP neighbors\n" |
522 | "Interface's name\n" | |
523 | "Resync with peer without adjacency reset\n") | |
524 | { | |
d62a17ae | 525 | struct eigrp *eigrp; |
526 | struct eigrp_interface *ei; | |
527 | ||
528 | /* Check if eigrp process is enabled */ | |
cae06ae0 | 529 | eigrp = eigrp_vty_get_eigrp(vty, vrf); |
d62a17ae | 530 | if (eigrp == NULL) { |
531 | vty_out(vty, " EIGRP Routing Process not enabled\n"); | |
532 | return CMD_SUCCESS; | |
533 | } | |
534 | ||
535 | /* lookup interface by specified name */ | |
cae06ae0 | 536 | ei = eigrp_if_lookup_by_name(eigrp, ifname); |
d62a17ae | 537 | if (ei == NULL) { |
538 | vty_out(vty, " Interface (%s) doesn't exist\n", argv[4]->arg); | |
539 | return CMD_WARNING; | |
540 | } | |
541 | ||
542 | /* execute graceful restart for all neighbors on interface */ | |
543 | eigrp_update_send_interface_GR(ei, EIGRP_GR_MANUAL, vty); | |
544 | return CMD_SUCCESS; | |
7f57883e DS |
545 | } |
546 | ||
547 | /* | |
548 | * Execute graceful restart for neighbor specified by IP | |
549 | */ | |
cae06ae0 | 550 | DEFPY (clear_ip_eigrp_neighbors_IP_soft, |
7f57883e | 551 | clear_ip_eigrp_neighbors_IP_soft_cmd, |
cae06ae0 | 552 | "clear ip eigrp [vrf NAME] neighbors A.B.C.D$nbr_addr soft", |
7f57883e DS |
553 | CLEAR_STR |
554 | IP_STR | |
555 | "Clear IP-EIGRP\n" | |
cae06ae0 | 556 | VRF_CMD_HELP_STR |
7f57883e DS |
557 | "Clear IP-EIGRP neighbors\n" |
558 | "IP-EIGRP neighbor address\n" | |
559 | "Resync with peer without adjacency reset\n") | |
560 | { | |
d62a17ae | 561 | struct eigrp *eigrp; |
562 | struct eigrp_neighbor *nbr; | |
d62a17ae | 563 | |
d62a17ae | 564 | |
565 | /* Check if eigrp process is enabled */ | |
cae06ae0 | 566 | eigrp = eigrp_vty_get_eigrp(vty, vrf); |
d62a17ae | 567 | if (eigrp == NULL) { |
568 | vty_out(vty, " EIGRP Routing Process not enabled\n"); | |
569 | return CMD_SUCCESS; | |
570 | } | |
571 | ||
572 | /* lookup neighbor in whole process */ | |
573 | nbr = eigrp_nbr_lookup_by_addr_process(eigrp, nbr_addr); | |
574 | ||
575 | /* if neighbor doesn't exists, notify user and exit */ | |
576 | if (nbr == NULL) { | |
577 | vty_out(vty, "Neighbor with entered address doesn't exists.\n"); | |
578 | return CMD_WARNING; | |
579 | } | |
580 | ||
581 | /* execute graceful restart on neighbor */ | |
582 | eigrp_update_send_GR(nbr, EIGRP_GR_MANUAL, vty); | |
583 | ||
584 | return CMD_SUCCESS; | |
7f57883e DS |
585 | } |
586 | ||
d62a17ae | 587 | void eigrp_vty_show_init(void) |
7f57883e | 588 | { |
d62a17ae | 589 | install_element(VIEW_NODE, &show_ip_eigrp_interfaces_cmd); |
7f57883e | 590 | |
d62a17ae | 591 | install_element(VIEW_NODE, &show_ip_eigrp_neighbors_cmd); |
7f57883e | 592 | |
d62a17ae | 593 | install_element(VIEW_NODE, &show_ip_eigrp_topology_cmd); |
13133652 | 594 | install_element(VIEW_NODE, &show_ip_eigrp_topology_all_cmd); |
7f57883e DS |
595 | } |
596 | ||
7f57883e | 597 | /* Install EIGRP related vty commands. */ |
d62a17ae | 598 | void eigrp_vty_init(void) |
7f57883e | 599 | { |
d62a17ae | 600 | /* commands for manual hard restart */ |
601 | install_element(ENABLE_NODE, &clear_ip_eigrp_neighbors_cmd); | |
602 | install_element(ENABLE_NODE, &clear_ip_eigrp_neighbors_int_cmd); | |
603 | install_element(ENABLE_NODE, &clear_ip_eigrp_neighbors_IP_cmd); | |
604 | /* commands for manual graceful restart */ | |
605 | install_element(ENABLE_NODE, &clear_ip_eigrp_neighbors_soft_cmd); | |
606 | install_element(ENABLE_NODE, &clear_ip_eigrp_neighbors_int_soft_cmd); | |
607 | install_element(ENABLE_NODE, &clear_ip_eigrp_neighbors_IP_soft_cmd); | |
7f57883e | 608 | } |