]>
Commit | Line | Data |
---|---|---|
f25c244b RZ |
1 | /* |
2 | * EIGRP daemon CLI implementation. | |
3 | * | |
4 | * Copyright (C) 2019 Network Device Education Foundation, Inc. ("NetDEF") | |
5 | * Rafael Zalamena | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License as published by | |
9 | * the Free Software Foundation; either version 2 of the License, or | |
10 | * (at your option) any later version. | |
11 | * | |
12 | * This program is distributed in the hope that it will be useful, | |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | * GNU General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License | |
18 | * along with this program; if not, write to the Free Software | |
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | |
20 | * 02110-1301 USA. | |
21 | */ | |
22 | ||
23 | #include <zebra.h> | |
24 | ||
25 | #include "lib/command.h" | |
26 | #include "lib/log.h" | |
27 | #include "lib/northbound_cli.h" | |
28 | ||
29 | #include "eigrp_structs.h" | |
30 | #include "eigrpd.h" | |
31 | #include "eigrp_zebra.h" | |
b66c8fbb | 32 | #include "eigrp_cli.h" |
f25c244b RZ |
33 | |
34 | #ifndef VTYSH_EXTRACT_PL | |
35 | #include "eigrpd/eigrp_cli_clippy.c" | |
36 | #endif /* VTYSH_EXTRACT_PL */ | |
37 | ||
38 | /* | |
39 | * XPath: /frr-eigrpd:eigrpd/instance | |
40 | */ | |
ca77b518 | 41 | DEFPY_YANG_NOSH( |
f25c244b RZ |
42 | router_eigrp, |
43 | router_eigrp_cmd, | |
e9449961 | 44 | "router eigrp (1-65535)$as [vrf NAME]", |
f25c244b RZ |
45 | ROUTER_STR |
46 | EIGRP_STR | |
e9449961 DS |
47 | AS_STR |
48 | VRF_CMD_HELP_STR) | |
f25c244b RZ |
49 | { |
50 | char xpath[XPATH_MAXLEN]; | |
51 | int rv; | |
52 | ||
53 | snprintf(xpath, sizeof(xpath), | |
e9449961 DS |
54 | "/frr-eigrpd:eigrpd/instance[asn='%s'][vrf='%s']", |
55 | as_str, vrf ? vrf : VRF_DEFAULT_NAME); | |
f25c244b RZ |
56 | |
57 | nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); | |
58 | rv = nb_cli_apply_changes(vty, NULL); | |
59 | if (rv == CMD_SUCCESS) | |
60 | VTY_PUSH_XPATH(EIGRP_NODE, xpath); | |
61 | ||
62 | return rv; | |
63 | } | |
64 | ||
ca77b518 | 65 | DEFPY_YANG( |
f25c244b RZ |
66 | no_router_eigrp, |
67 | no_router_eigrp_cmd, | |
e9449961 | 68 | "no router eigrp (1-65535)$as [vrf NAME]", |
f25c244b RZ |
69 | NO_STR |
70 | ROUTER_STR | |
71 | EIGRP_STR | |
e9449961 DS |
72 | AS_STR |
73 | VRF_CMD_HELP_STR) | |
f25c244b RZ |
74 | { |
75 | char xpath[XPATH_MAXLEN]; | |
76 | ||
77 | snprintf(xpath, sizeof(xpath), | |
e9449961 DS |
78 | "/frr-eigrpd:eigrpd/instance[asn='%s'][vrf='%s']", |
79 | as_str, vrf ? vrf : VRF_DEFAULT_NAME); | |
f25c244b RZ |
80 | |
81 | nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); | |
82 | return nb_cli_apply_changes(vty, NULL); | |
83 | } | |
84 | ||
85 | void eigrp_cli_show_header(struct vty *vty, struct lyd_node *dnode, | |
86 | bool show_defaults) | |
87 | { | |
88 | const char *asn = yang_dnode_get_string(dnode, "./asn"); | |
e9449961 | 89 | const char *vrf = yang_dnode_get_string(dnode, "./vrf"); |
f25c244b | 90 | |
e9449961 DS |
91 | vty_out(vty, "router eigrp %s", asn); |
92 | if (strcmp(vrf, VRF_DEFAULT_NAME)) | |
93 | vty_out(vty, " vrf %s", vrf); | |
94 | vty_out(vty, "\n"); | |
f25c244b RZ |
95 | } |
96 | ||
97 | void eigrp_cli_show_end_header(struct vty *vty, struct lyd_node *dnode) | |
98 | { | |
99 | vty_out(vty, "!\n"); | |
100 | } | |
101 | ||
102 | /* | |
103 | * XPath: /frr-eigrpd:eigrpd/instance/router-id | |
104 | */ | |
ca77b518 | 105 | DEFPY_YANG( |
f25c244b RZ |
106 | eigrp_router_id, |
107 | eigrp_router_id_cmd, | |
108 | "eigrp router-id A.B.C.D$addr", | |
109 | EIGRP_STR | |
110 | "Router ID for this EIGRP process\n" | |
111 | "EIGRP Router-ID in IP address format\n") | |
112 | { | |
113 | nb_cli_enqueue_change(vty, "./router-id", NB_OP_MODIFY, addr_str); | |
114 | return nb_cli_apply_changes(vty, NULL); | |
115 | } | |
116 | ||
ca77b518 | 117 | DEFPY_YANG( |
f25c244b RZ |
118 | no_eigrp_router_id, |
119 | no_eigrp_router_id_cmd, | |
120 | "no eigrp router-id [A.B.C.D]", | |
121 | NO_STR | |
122 | EIGRP_STR | |
123 | "Router ID for this EIGRP process\n" | |
124 | "EIGRP Router-ID in IP address format\n") | |
125 | { | |
126 | nb_cli_enqueue_change(vty, "./router-id", NB_OP_DESTROY, NULL); | |
127 | return nb_cli_apply_changes(vty, NULL); | |
128 | } | |
129 | ||
130 | void eigrp_cli_show_router_id(struct vty *vty, struct lyd_node *dnode, | |
131 | bool show_defaults) | |
132 | { | |
133 | const char *router_id = yang_dnode_get_string(dnode, NULL); | |
134 | ||
135 | vty_out(vty, " eigrp router-id %s\n", router_id); | |
136 | } | |
137 | ||
138 | /* | |
139 | * XPath: /frr-eigrpd:eigrpd/instance/passive-interface | |
140 | */ | |
ca77b518 | 141 | DEFPY_YANG( |
f25c244b RZ |
142 | eigrp_passive_interface, |
143 | eigrp_passive_interface_cmd, | |
144 | "[no] passive-interface IFNAME", | |
145 | NO_STR | |
146 | "Suppress routing updates on an interface\n" | |
147 | "Interface to suppress on\n") | |
148 | { | |
149 | if (no) | |
150 | nb_cli_enqueue_change(vty, "./passive-interface", | |
151 | NB_OP_DESTROY, ifname); | |
152 | else | |
153 | nb_cli_enqueue_change(vty, "./passive-interface", | |
154 | NB_OP_CREATE, ifname); | |
155 | ||
156 | return nb_cli_apply_changes(vty, NULL); | |
157 | } | |
158 | ||
159 | void eigrp_cli_show_passive_interface(struct vty *vty, struct lyd_node *dnode, | |
160 | bool show_defaults) | |
161 | { | |
162 | const char *ifname = yang_dnode_get_string(dnode, NULL); | |
163 | ||
164 | vty_out(vty, " passive-interface %s\n", ifname); | |
165 | } | |
166 | ||
167 | /* | |
168 | * XPath: /frr-eigrpd:eigrpd/instance/active-time | |
169 | */ | |
ca77b518 | 170 | DEFPY_YANG( |
f25c244b RZ |
171 | eigrp_timers_active, |
172 | eigrp_timers_active_cmd, | |
173 | "timers active-time <(1-65535)$timer|disabled$disabled>", | |
174 | "Adjust routing timers\n" | |
175 | "Time limit for active state\n" | |
176 | "Active state time limit in seconds\n" | |
177 | "Disable time limit for active state\n") | |
178 | { | |
179 | if (disabled) | |
180 | nb_cli_enqueue_change(vty, "./active-time", NB_OP_MODIFY, "0"); | |
181 | else | |
182 | nb_cli_enqueue_change(vty, "./active-time", | |
183 | NB_OP_MODIFY, timer_str); | |
184 | ||
185 | return nb_cli_apply_changes(vty, NULL); | |
186 | } | |
187 | ||
ca77b518 | 188 | DEFPY_YANG( |
f25c244b RZ |
189 | no_eigrp_timers_active, |
190 | no_eigrp_timers_active_cmd, | |
191 | "no timers active-time [<(1-65535)|disabled>]", | |
192 | NO_STR | |
193 | "Adjust routing timers\n" | |
194 | "Time limit for active state\n" | |
195 | "Active state time limit in seconds\n" | |
196 | "Disable time limit for active state\n") | |
197 | { | |
198 | nb_cli_enqueue_change(vty, "./active-time", NB_OP_DESTROY, NULL); | |
199 | return nb_cli_apply_changes(vty, NULL); | |
200 | } | |
201 | ||
202 | void eigrp_cli_show_active_time(struct vty *vty, struct lyd_node *dnode, | |
203 | bool show_defaults) | |
204 | { | |
205 | const char *timer = yang_dnode_get_string(dnode, NULL); | |
206 | ||
207 | vty_out(vty, " timers active-time %s\n", timer); | |
208 | } | |
209 | ||
210 | /* | |
211 | * XPath: /frr-eigrpd:eigrpd/instance/variance | |
212 | */ | |
ca77b518 | 213 | DEFPY_YANG( |
f25c244b RZ |
214 | eigrp_variance, |
215 | eigrp_variance_cmd, | |
216 | "variance (1-128)$variance", | |
217 | "Control load balancing variance\n" | |
218 | "Metric variance multiplier\n") | |
219 | { | |
220 | nb_cli_enqueue_change(vty, "./variance", NB_OP_MODIFY, variance_str); | |
221 | return nb_cli_apply_changes(vty, NULL); | |
222 | } | |
223 | ||
ca77b518 | 224 | DEFPY_YANG( |
f25c244b RZ |
225 | no_eigrp_variance, |
226 | no_eigrp_variance_cmd, | |
227 | "no variance [(1-128)]", | |
228 | NO_STR | |
229 | "Control load balancing variance\n" | |
230 | "Metric variance multiplier\n") | |
231 | { | |
232 | nb_cli_enqueue_change(vty, "./variance", NB_OP_DESTROY, NULL); | |
233 | return nb_cli_apply_changes(vty, NULL); | |
234 | } | |
235 | ||
236 | void eigrp_cli_show_variance(struct vty *vty, struct lyd_node *dnode, | |
237 | bool show_defaults) | |
238 | { | |
239 | const char *variance = yang_dnode_get_string(dnode, NULL); | |
240 | ||
241 | vty_out(vty, " variance %s\n", variance); | |
242 | } | |
243 | ||
244 | /* | |
245 | * XPath: /frr-eigrpd:eigrpd/instance/maximum-paths | |
246 | */ | |
ca77b518 | 247 | DEFPY_YANG( |
f25c244b RZ |
248 | eigrp_maximum_paths, |
249 | eigrp_maximum_paths_cmd, | |
250 | "maximum-paths (1-32)$maximum_paths", | |
251 | "Forward packets over multiple paths\n" | |
252 | "Number of paths\n") | |
253 | { | |
254 | nb_cli_enqueue_change(vty, "./maximum-paths", NB_OP_MODIFY, | |
255 | maximum_paths_str); | |
256 | return nb_cli_apply_changes(vty, NULL); | |
257 | } | |
258 | ||
ca77b518 | 259 | DEFPY_YANG( |
f25c244b RZ |
260 | no_eigrp_maximum_paths, |
261 | no_eigrp_maximum_paths_cmd, | |
262 | "no maximum-paths [(1-32)]", | |
263 | NO_STR | |
264 | "Forward packets over multiple paths\n" | |
265 | "Number of paths\n") | |
266 | { | |
267 | nb_cli_enqueue_change(vty, "./maximum-paths", NB_OP_DESTROY, NULL); | |
268 | return nb_cli_apply_changes(vty, NULL); | |
269 | } | |
270 | ||
271 | void eigrp_cli_show_maximum_paths(struct vty *vty, struct lyd_node *dnode, | |
272 | bool show_defaults) | |
273 | { | |
274 | const char *maximum_paths = yang_dnode_get_string(dnode, NULL); | |
275 | ||
276 | vty_out(vty, " maximum-paths %s\n", maximum_paths); | |
277 | } | |
278 | ||
279 | /* | |
280 | * XPath: /frr-eigrpd:eigrpd/instance/metric-weights/K1 | |
281 | * XPath: /frr-eigrpd:eigrpd/instance/metric-weights/K2 | |
282 | * XPath: /frr-eigrpd:eigrpd/instance/metric-weights/K3 | |
283 | * XPath: /frr-eigrpd:eigrpd/instance/metric-weights/K4 | |
284 | * XPath: /frr-eigrpd:eigrpd/instance/metric-weights/K5 | |
285 | * XPath: /frr-eigrpd:eigrpd/instance/metric-weights/K6 | |
286 | */ | |
ca77b518 | 287 | DEFPY_YANG( |
f25c244b RZ |
288 | eigrp_metric_weights, |
289 | eigrp_metric_weights_cmd, | |
290 | "metric weights (0-255)$k1 (0-255)$k2 (0-255)$k3 (0-255)$k4 (0-255)$k5 [(0-255)$k6]", | |
291 | "Modify metrics and parameters for advertisement\n" | |
292 | "Modify metric coefficients\n" | |
293 | "K1\n" | |
294 | "K2\n" | |
295 | "K3\n" | |
296 | "K4\n" | |
297 | "K5\n" | |
298 | "K6\n") | |
299 | { | |
300 | nb_cli_enqueue_change(vty, "./metric-weights/K1", NB_OP_MODIFY, k1_str); | |
301 | nb_cli_enqueue_change(vty, "./metric-weights/K2", NB_OP_MODIFY, k2_str); | |
302 | nb_cli_enqueue_change(vty, "./metric-weights/K3", NB_OP_MODIFY, k3_str); | |
303 | nb_cli_enqueue_change(vty, "./metric-weights/K4", NB_OP_MODIFY, k4_str); | |
304 | nb_cli_enqueue_change(vty, "./metric-weights/K5", NB_OP_MODIFY, k5_str); | |
305 | if (k6) | |
306 | nb_cli_enqueue_change(vty, "./metric-weights/K6", | |
307 | NB_OP_MODIFY, k6_str); | |
308 | ||
309 | return nb_cli_apply_changes(vty, NULL); | |
310 | } | |
311 | ||
ca77b518 | 312 | DEFPY_YANG( |
f25c244b RZ |
313 | no_eigrp_metric_weights, |
314 | no_eigrp_metric_weights_cmd, | |
315 | "no metric weights [(0-255) (0-255) (0-255) (0-255) (0-255) (0-255)]", | |
316 | NO_STR | |
317 | "Modify metrics and parameters for advertisement\n" | |
318 | "Modify metric coefficients\n" | |
319 | "K1\n" | |
320 | "K2\n" | |
321 | "K3\n" | |
322 | "K4\n" | |
323 | "K5\n" | |
324 | "K6\n") | |
325 | { | |
326 | nb_cli_enqueue_change(vty, "./metric-weights/K1", NB_OP_DESTROY, NULL); | |
327 | nb_cli_enqueue_change(vty, "./metric-weights/K2", NB_OP_DESTROY, NULL); | |
328 | nb_cli_enqueue_change(vty, "./metric-weights/K3", NB_OP_DESTROY, NULL); | |
329 | nb_cli_enqueue_change(vty, "./metric-weights/K4", NB_OP_DESTROY, NULL); | |
330 | nb_cli_enqueue_change(vty, "./metric-weights/K5", NB_OP_DESTROY, NULL); | |
331 | nb_cli_enqueue_change(vty, "./metric-weights/K6", NB_OP_DESTROY, NULL); | |
332 | return nb_cli_apply_changes(vty, NULL); | |
333 | } | |
334 | ||
335 | void eigrp_cli_show_metrics(struct vty *vty, struct lyd_node *dnode, | |
336 | bool show_defaults) | |
337 | { | |
338 | const char *k1, *k2, *k3, *k4, *k5, *k6; | |
339 | ||
340 | k1 = yang_dnode_exists(dnode, "./K1") ? | |
341 | yang_dnode_get_string(dnode, "./K1") : "0"; | |
342 | k2 = yang_dnode_exists(dnode, "./K2") ? | |
343 | yang_dnode_get_string(dnode, "./K2") : "0"; | |
344 | k3 = yang_dnode_exists(dnode, "./K3") ? | |
345 | yang_dnode_get_string(dnode, "./K3") : "0"; | |
346 | k4 = yang_dnode_exists(dnode, "./K4") ? | |
347 | yang_dnode_get_string(dnode, "./K4") : "0"; | |
348 | k5 = yang_dnode_exists(dnode, "./K5") ? | |
349 | yang_dnode_get_string(dnode, "./K5") : "0"; | |
350 | k6 = yang_dnode_exists(dnode, "./K6") ? | |
351 | yang_dnode_get_string(dnode, "./K6") : "0"; | |
352 | ||
353 | vty_out(vty, " metric weights %s %s %s %s %s", | |
354 | k1, k2, k3, k4, k5); | |
355 | if (k6) | |
356 | vty_out(vty, " %s", k6); | |
357 | vty_out(vty, "\n"); | |
358 | } | |
359 | ||
360 | /* | |
361 | * XPath: /frr-eigrpd:eigrpd/instance/network | |
362 | */ | |
ca77b518 | 363 | DEFPY_YANG( |
f25c244b RZ |
364 | eigrp_network, |
365 | eigrp_network_cmd, | |
366 | "[no] network A.B.C.D/M$prefix", | |
367 | NO_STR | |
368 | "Enable routing on an IP network\n" | |
369 | "EIGRP network prefix\n") | |
370 | { | |
371 | if (no) | |
372 | nb_cli_enqueue_change(vty, "./network", NB_OP_DESTROY, | |
373 | prefix_str); | |
374 | else | |
375 | nb_cli_enqueue_change(vty, "./network", NB_OP_CREATE, | |
376 | prefix_str); | |
377 | ||
378 | return nb_cli_apply_changes(vty, NULL); | |
379 | } | |
380 | ||
381 | void eigrp_cli_show_network(struct vty *vty, struct lyd_node *dnode, | |
382 | bool show_defaults) | |
383 | { | |
384 | const char *prefix = yang_dnode_get_string(dnode, NULL); | |
385 | ||
386 | vty_out(vty, " network %s\n", prefix); | |
387 | } | |
388 | ||
389 | /* | |
390 | * XPath: /frr-eigrpd:eigrpd/instance/neighbor | |
391 | */ | |
ca77b518 | 392 | DEFPY_YANG( |
f25c244b RZ |
393 | eigrp_neighbor, |
394 | eigrp_neighbor_cmd, | |
395 | "[no] neighbor A.B.C.D$addr", | |
396 | NO_STR | |
397 | "Specify a neighbor router\n" | |
398 | "Neighbor address\n") | |
399 | { | |
400 | if (no) | |
401 | nb_cli_enqueue_change(vty, "./neighbor", NB_OP_DESTROY, | |
402 | addr_str); | |
403 | else | |
404 | nb_cli_enqueue_change(vty, "./neighbor", NB_OP_CREATE, | |
405 | addr_str); | |
406 | ||
407 | return nb_cli_apply_changes(vty, NULL); | |
408 | } | |
409 | ||
410 | void eigrp_cli_show_neighbor(struct vty *vty, struct lyd_node *dnode, | |
411 | bool show_defaults) | |
412 | { | |
413 | const char *prefix = yang_dnode_get_string(dnode, NULL); | |
414 | ||
415 | vty_out(vty, " neighbor %s\n", prefix); | |
416 | } | |
417 | ||
418 | /* | |
419 | * XPath: /frr-eigrpd:eigrpd/instance/redistribute | |
420 | * XPath: /frr-eigrpd:eigrpd/instance/redistribute/route-map | |
421 | * XPath: /frr-eigrpd:eigrpd/instance/redistribute/metrics/bandwidth | |
422 | * XPath: /frr-eigrpd:eigrpd/instance/redistribute/metrics/delay | |
423 | * XPath: /frr-eigrpd:eigrpd/instance/redistribute/metrics/reliability | |
424 | * XPath: /frr-eigrpd:eigrpd/instance/redistribute/metrics/load | |
425 | * XPath: /frr-eigrpd:eigrpd/instance/redistribute/metrics/mtu | |
426 | */ | |
ca77b518 | 427 | DEFPY_YANG( |
f25c244b RZ |
428 | eigrp_redistribute_source_metric, |
429 | eigrp_redistribute_source_metric_cmd, | |
430 | "[no] redistribute " FRR_REDIST_STR_EIGRPD | |
431 | "$proto [metric (1-4294967295)$bw (0-4294967295)$delay (0-255)$rlbt (1-255)$load (1-65535)$mtu]", | |
432 | NO_STR | |
433 | REDIST_STR | |
434 | FRR_REDIST_HELP_STR_EIGRPD | |
435 | "Metric for redistributed routes\n" | |
436 | "Bandwidth metric in Kbits per second\n" | |
437 | "EIGRP delay metric, in 10 microsecond units\n" | |
438 | "EIGRP reliability metric where 255 is 100% reliable2 ?\n" | |
439 | "EIGRP Effective bandwidth metric (Loading) where 255 is 100% loaded\n" | |
440 | "EIGRP MTU of the path\n") | |
441 | { | |
442 | char xpath[XPATH_MAXLEN], xpath_metric[XPATH_MAXLEN + 64]; | |
443 | ||
444 | snprintf(xpath, sizeof(xpath), "./redistribute[protocol='%s']", proto); | |
445 | ||
446 | if (no) { | |
447 | nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); | |
448 | return nb_cli_apply_changes(vty, NULL); | |
449 | } | |
450 | ||
451 | nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); | |
452 | if (bw == 0 || delay == 0 || rlbt == 0 || load == 0 || mtu == 0) | |
453 | return nb_cli_apply_changes(vty, NULL); | |
454 | ||
455 | snprintf(xpath_metric, sizeof(xpath_metric), "%s/metrics/bandwidth", | |
456 | xpath); | |
457 | nb_cli_enqueue_change(vty, xpath_metric, NB_OP_MODIFY, bw_str); | |
458 | snprintf(xpath_metric, sizeof(xpath_metric), "%s/metrics/delay", xpath); | |
459 | nb_cli_enqueue_change(vty, xpath_metric, NB_OP_MODIFY, delay_str); | |
460 | snprintf(xpath_metric, sizeof(xpath_metric), "%s/metrics/reliability", | |
461 | xpath); | |
462 | nb_cli_enqueue_change(vty, xpath_metric, NB_OP_MODIFY, rlbt_str); | |
463 | snprintf(xpath_metric, sizeof(xpath_metric), "%s/metrics/load", xpath); | |
464 | nb_cli_enqueue_change(vty, xpath_metric, NB_OP_MODIFY, load_str); | |
465 | snprintf(xpath_metric, sizeof(xpath_metric), "%s/metrics/mtu", xpath); | |
466 | nb_cli_enqueue_change(vty, xpath_metric, NB_OP_MODIFY, mtu_str); | |
467 | return nb_cli_apply_changes(vty, NULL); | |
468 | } | |
469 | ||
470 | void eigrp_cli_show_redistribute(struct vty *vty, struct lyd_node *dnode, | |
471 | bool show_defaults) | |
472 | { | |
473 | const char *proto = yang_dnode_get_string(dnode, "./protocol"); | |
474 | const char *bw, *delay, *load, *mtu, *rlbt; | |
475 | ||
476 | bw = yang_dnode_exists(dnode, "./metrics/bandwidth") ? | |
477 | yang_dnode_get_string(dnode, "./metrics/bandwidth") : NULL; | |
478 | delay = yang_dnode_exists(dnode, "./metrics/delay") ? | |
479 | yang_dnode_get_string(dnode, "./metrics/delay") : NULL; | |
480 | rlbt = yang_dnode_exists(dnode, "./metrics/reliability") ? | |
481 | yang_dnode_get_string(dnode, "./metrics/reliability") : NULL; | |
482 | load = yang_dnode_exists(dnode, "./metrics/load") ? | |
483 | yang_dnode_get_string(dnode, "./metrics/load") : NULL; | |
484 | mtu = yang_dnode_exists(dnode, "./metrics/mtu") ? | |
485 | yang_dnode_get_string(dnode, "./metrics/mtu") : NULL; | |
486 | ||
487 | vty_out(vty, " redistribute %s", proto); | |
488 | if (bw || rlbt || delay || load || mtu) | |
489 | vty_out(vty, " metric %s %s %s %s %s", bw, delay, rlbt, load, | |
490 | mtu); | |
491 | vty_out(vty, "\n"); | |
492 | } | |
493 | ||
494 | /* | |
495 | * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/delay | |
496 | */ | |
ca77b518 | 497 | DEFPY_YANG( |
f25c244b RZ |
498 | eigrp_if_delay, |
499 | eigrp_if_delay_cmd, | |
500 | "delay (1-16777215)$delay", | |
501 | "Specify interface throughput delay\n" | |
502 | "Throughput delay (tens of microseconds)\n") | |
503 | { | |
504 | nb_cli_enqueue_change(vty, "./frr-eigrpd:eigrp/delay", | |
505 | NB_OP_MODIFY, delay_str); | |
506 | return nb_cli_apply_changes(vty, NULL); | |
507 | } | |
508 | ||
ca77b518 | 509 | DEFPY_YANG( |
f25c244b RZ |
510 | no_eigrp_if_delay, |
511 | no_eigrp_if_delay_cmd, | |
512 | "no delay [(1-16777215)]", | |
513 | NO_STR | |
514 | "Specify interface throughput delay\n" | |
515 | "Throughput delay (tens of microseconds)\n") | |
516 | { | |
517 | nb_cli_enqueue_change(vty, "./frr-eigrpd:eigrp/delay", | |
518 | NB_OP_DESTROY, NULL); | |
519 | return nb_cli_apply_changes(vty, NULL); | |
520 | } | |
521 | ||
522 | void eigrp_cli_show_delay(struct vty *vty, struct lyd_node *dnode, | |
523 | bool show_defaults) | |
524 | { | |
525 | const char *delay = yang_dnode_get_string(dnode, NULL); | |
526 | ||
527 | vty_out(vty, " delay %s\n", delay); | |
528 | } | |
529 | ||
530 | /* | |
531 | * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/bandwidth | |
532 | */ | |
ca77b518 | 533 | DEFPY_YANG( |
f25c244b RZ |
534 | eigrp_if_bandwidth, |
535 | eigrp_if_bandwidth_cmd, | |
536 | "eigrp bandwidth (1-10000000)$bw", | |
537 | EIGRP_STR | |
538 | "Set bandwidth informational parameter\n" | |
539 | "Bandwidth in kilobits\n") | |
540 | { | |
541 | nb_cli_enqueue_change(vty, "./frr-eigrpd:eigrp/bandwidth", | |
542 | NB_OP_MODIFY, bw_str); | |
543 | return nb_cli_apply_changes(vty, NULL); | |
544 | } | |
545 | ||
ca77b518 | 546 | DEFPY_YANG( |
f25c244b RZ |
547 | no_eigrp_if_bandwidth, |
548 | no_eigrp_if_bandwidth_cmd, | |
549 | "no eigrp bandwidth [(1-10000000)]", | |
550 | NO_STR | |
551 | EIGRP_STR | |
552 | "Set bandwidth informational parameter\n" | |
553 | "Bandwidth in kilobits\n") | |
554 | { | |
555 | nb_cli_enqueue_change(vty, "./frr-eigrpd:eigrp/bandwidth", | |
556 | NB_OP_DESTROY, NULL); | |
557 | return nb_cli_apply_changes(vty, NULL); | |
558 | } | |
559 | ||
560 | void eigrp_cli_show_bandwidth(struct vty *vty, struct lyd_node *dnode, | |
561 | bool show_defaults) | |
562 | { | |
563 | const char *bandwidth = yang_dnode_get_string(dnode, NULL); | |
564 | ||
565 | vty_out(vty, " eigrp bandwidth %s\n", bandwidth); | |
566 | } | |
567 | ||
568 | /* | |
569 | * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/hello-interval | |
570 | */ | |
ca77b518 | 571 | DEFPY_YANG( |
f25c244b RZ |
572 | eigrp_if_ip_hellointerval, |
573 | eigrp_if_ip_hellointerval_cmd, | |
574 | "ip hello-interval eigrp (1-65535)$hello", | |
575 | "Interface Internet Protocol config commands\n" | |
576 | "Configures EIGRP hello interval\n" | |
577 | EIGRP_STR | |
578 | "Seconds between hello transmissions\n") | |
579 | { | |
580 | nb_cli_enqueue_change(vty, "./frr-eigrpd:eigrp/hello-interval", | |
581 | NB_OP_MODIFY, hello_str); | |
582 | return nb_cli_apply_changes(vty, NULL); | |
583 | } | |
584 | ||
ca77b518 | 585 | DEFPY_YANG( |
f25c244b RZ |
586 | no_eigrp_if_ip_hellointerval, |
587 | no_eigrp_if_ip_hellointerval_cmd, | |
588 | "no ip hello-interval eigrp [(1-65535)]", | |
589 | NO_STR | |
590 | "Interface Internet Protocol config commands\n" | |
591 | "Configures EIGRP hello interval\n" | |
592 | EIGRP_STR | |
593 | "Seconds between hello transmissions\n") | |
594 | { | |
595 | nb_cli_enqueue_change(vty, "./frr-eigrpd:eigrp/hello-interval", | |
596 | NB_OP_DESTROY, NULL); | |
597 | return nb_cli_apply_changes(vty, NULL); | |
598 | } | |
599 | ||
600 | ||
601 | void eigrp_cli_show_hello_interval(struct vty *vty, struct lyd_node *dnode, | |
602 | bool show_defaults) | |
603 | { | |
604 | const char *hello = yang_dnode_get_string(dnode, NULL); | |
605 | ||
606 | vty_out(vty, " ip hello-interval eigrp %s\n", hello); | |
607 | } | |
608 | ||
609 | /* | |
610 | * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/hold-time | |
611 | */ | |
ca77b518 | 612 | DEFPY_YANG( |
f25c244b RZ |
613 | eigrp_if_ip_holdinterval, |
614 | eigrp_if_ip_holdinterval_cmd, | |
615 | "ip hold-time eigrp (1-65535)$hold", | |
616 | "Interface Internet Protocol config commands\n" | |
617 | "Configures EIGRP IPv4 hold time\n" | |
618 | EIGRP_STR | |
619 | "Seconds before neighbor is considered down\n") | |
620 | { | |
621 | nb_cli_enqueue_change(vty, "./frr-eigrpd:eigrp/hold-time", | |
622 | NB_OP_MODIFY, hold_str); | |
623 | return nb_cli_apply_changes(vty, NULL); | |
624 | } | |
625 | ||
ca77b518 | 626 | DEFPY_YANG( |
f25c244b RZ |
627 | no_eigrp_if_ip_holdinterval, |
628 | no_eigrp_if_ip_holdinterval_cmd, | |
629 | "no ip hold-time eigrp [(1-65535)]", | |
630 | NO_STR | |
631 | "Interface Internet Protocol config commands\n" | |
632 | "Configures EIGRP IPv4 hold time\n" | |
633 | EIGRP_STR | |
634 | "Seconds before neighbor is considered down\n") | |
635 | { | |
636 | nb_cli_enqueue_change(vty, "./frr-eigrpd:eigrp/hold-time", | |
637 | NB_OP_DESTROY, NULL); | |
638 | return nb_cli_apply_changes(vty, NULL); | |
639 | } | |
640 | ||
641 | void eigrp_cli_show_hold_time(struct vty *vty, struct lyd_node *dnode, | |
642 | bool show_defaults) | |
643 | { | |
644 | const char *holdtime = yang_dnode_get_string(dnode, NULL); | |
645 | ||
646 | vty_out(vty, " ip hold-time eigrp %s\n", holdtime); | |
647 | } | |
648 | ||
649 | /* | |
650 | * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/split-horizon | |
651 | */ | |
652 | /* NOT implemented. */ | |
653 | ||
654 | /* | |
655 | * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/instance | |
656 | * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/instance/summarize-addresses | |
657 | */ | |
ca77b518 | 658 | DEFPY_YANG( |
f25c244b RZ |
659 | eigrp_ip_summary_address, |
660 | eigrp_ip_summary_address_cmd, | |
661 | "ip summary-address eigrp (1-65535)$as A.B.C.D/M$prefix", | |
662 | "Interface Internet Protocol config commands\n" | |
663 | "Perform address summarization\n" | |
664 | EIGRP_STR | |
665 | AS_STR | |
666 | "Summary <network>/<length>, e.g. 192.168.0.0/16\n") | |
667 | { | |
668 | char xpath[XPATH_MAXLEN], xpath_auth[XPATH_MAXLEN + 64]; | |
669 | ||
670 | snprintf(xpath, sizeof(xpath), "./frr-eigrpd:eigrp/instance[asn='%s']", | |
671 | as_str); | |
672 | nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); | |
673 | ||
77a42534 | 674 | snprintf(xpath_auth, sizeof(xpath_auth), "%s/summarize-addresses", xpath); |
f25c244b RZ |
675 | nb_cli_enqueue_change(vty, xpath_auth, NB_OP_CREATE, prefix_str); |
676 | ||
677 | return nb_cli_apply_changes(vty, NULL); | |
678 | } | |
679 | ||
ca77b518 | 680 | DEFPY_YANG( |
f25c244b RZ |
681 | no_eigrp_ip_summary_address, |
682 | no_eigrp_ip_summary_address_cmd, | |
683 | "no ip summary-address eigrp (1-65535)$as A.B.C.D/M$prefix", | |
684 | NO_STR | |
685 | "Interface Internet Protocol config commands\n" | |
686 | "Perform address summarization\n" | |
687 | EIGRP_STR | |
688 | AS_STR | |
689 | "Summary <network>/<length>, e.g. 192.168.0.0/16\n") | |
690 | { | |
691 | char xpath[XPATH_MAXLEN], xpath_auth[XPATH_MAXLEN + 64]; | |
692 | ||
693 | snprintf(xpath, sizeof(xpath), "./frr-eigrpd:eigrp/instance[asn='%s']", | |
694 | as_str); | |
695 | nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); | |
696 | ||
77a42534 | 697 | snprintf(xpath_auth, sizeof(xpath_auth), "%s/summarize-addresses", xpath); |
f25c244b RZ |
698 | nb_cli_enqueue_change(vty, xpath_auth, NB_OP_DESTROY, prefix_str); |
699 | ||
700 | return nb_cli_apply_changes(vty, NULL); | |
701 | } | |
702 | ||
703 | void eigrp_cli_show_summarize_address(struct vty *vty, struct lyd_node *dnode, | |
704 | bool show_defaults) | |
705 | { | |
7f9c68df IR |
706 | const struct lyd_node *instance = yang_dnode_get_parent(dnode, "instance"); |
707 | uint16_t asn = yang_dnode_get_uint16(instance, "./asn"); | |
f25c244b RZ |
708 | const char *summarize_address = yang_dnode_get_string(dnode, NULL); |
709 | ||
7f9c68df IR |
710 | vty_out(vty, " ip summary-address eigrp %d %s\n", asn, |
711 | summarize_address); | |
f25c244b RZ |
712 | } |
713 | ||
714 | /* | |
715 | * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/instance | |
716 | * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/instance/authentication | |
717 | */ | |
ca77b518 | 718 | DEFPY_YANG( |
f25c244b RZ |
719 | eigrp_authentication_mode, |
720 | eigrp_authentication_mode_cmd, | |
721 | "ip authentication mode eigrp (1-65535)$as <md5|hmac-sha-256>$crypt", | |
722 | "Interface Internet Protocol config commands\n" | |
723 | "Authentication subcommands\n" | |
724 | "Mode\n" | |
725 | EIGRP_STR | |
726 | AS_STR | |
727 | "Keyed message digest\n" | |
728 | "HMAC SHA256 algorithm \n") | |
729 | { | |
730 | char xpath[XPATH_MAXLEN], xpath_auth[XPATH_MAXLEN + 64]; | |
731 | ||
732 | snprintf(xpath, sizeof(xpath), "./frr-eigrpd:eigrp/instance[asn='%s']", | |
733 | as_str); | |
734 | nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); | |
735 | ||
736 | snprintf(xpath_auth, sizeof(xpath_auth), "%s/authentication", xpath); | |
737 | nb_cli_enqueue_change(vty, xpath_auth, NB_OP_MODIFY, crypt); | |
738 | ||
739 | return nb_cli_apply_changes(vty, NULL); | |
740 | } | |
741 | ||
ca77b518 | 742 | DEFPY_YANG( |
f25c244b RZ |
743 | no_eigrp_authentication_mode, |
744 | no_eigrp_authentication_mode_cmd, | |
745 | "no ip authentication mode eigrp (1-65535)$as [<md5|hmac-sha-256>]", | |
746 | NO_STR | |
747 | "Interface Internet Protocol config commands\n" | |
748 | "Authentication subcommands\n" | |
749 | "Mode\n" | |
750 | EIGRP_STR | |
751 | AS_STR | |
752 | "Keyed message digest\n" | |
753 | "HMAC SHA256 algorithm \n") | |
754 | { | |
755 | char xpath[XPATH_MAXLEN], xpath_auth[XPATH_MAXLEN + 64]; | |
756 | ||
757 | snprintf(xpath, sizeof(xpath), "./frr-eigrpd:eigrp/instance[asn='%s']", | |
758 | as_str); | |
759 | nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); | |
760 | ||
761 | snprintf(xpath_auth, sizeof(xpath_auth), "%s/authentication", xpath); | |
762 | nb_cli_enqueue_change(vty, xpath_auth, NB_OP_MODIFY, "none"); | |
763 | ||
764 | return nb_cli_apply_changes(vty, NULL); | |
765 | } | |
766 | ||
767 | void eigrp_cli_show_authentication(struct vty *vty, struct lyd_node *dnode, | |
768 | bool show_defaults) | |
769 | { | |
7f9c68df IR |
770 | const struct lyd_node *instance = yang_dnode_get_parent(dnode, "instance"); |
771 | uint16_t asn = yang_dnode_get_uint16(instance, "./asn"); | |
f25c244b RZ |
772 | const char *crypt = yang_dnode_get_string(dnode, NULL); |
773 | ||
7f9c68df | 774 | vty_out(vty, " ip authentication mode eigrp %d %s\n", asn, crypt); |
f25c244b RZ |
775 | } |
776 | ||
777 | /* | |
778 | * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/instance | |
779 | * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/instance/keychain | |
780 | */ | |
ca77b518 | 781 | DEFPY_YANG( |
f25c244b RZ |
782 | eigrp_authentication_keychain, |
783 | eigrp_authentication_keychain_cmd, | |
784 | "ip authentication key-chain eigrp (1-65535)$as WORD$name", | |
785 | "Interface Internet Protocol config commands\n" | |
786 | "Authentication subcommands\n" | |
787 | "Key-chain\n" | |
788 | EIGRP_STR | |
789 | AS_STR | |
790 | "Name of key-chain\n") | |
791 | { | |
792 | char xpath[XPATH_MAXLEN], xpath_auth[XPATH_MAXLEN + 64]; | |
793 | ||
794 | snprintf(xpath, sizeof(xpath), "./frr-eigrpd:eigrp/instance[asn='%s']", | |
795 | as_str); | |
796 | nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); | |
797 | ||
798 | snprintf(xpath_auth, sizeof(xpath_auth), "%s/keychain", xpath); | |
799 | nb_cli_enqueue_change(vty, xpath_auth, NB_OP_MODIFY, name); | |
800 | ||
801 | return nb_cli_apply_changes(vty, NULL); | |
802 | } | |
803 | ||
ca77b518 | 804 | DEFPY_YANG( |
f25c244b RZ |
805 | no_eigrp_authentication_keychain, |
806 | no_eigrp_authentication_keychain_cmd, | |
807 | "no ip authentication key-chain eigrp (1-65535)$as [WORD]", | |
808 | NO_STR | |
809 | "Interface Internet Protocol config commands\n" | |
810 | "Authentication subcommands\n" | |
811 | "Key-chain\n" | |
812 | EIGRP_STR | |
813 | AS_STR | |
814 | "Name of key-chain\n") | |
815 | { | |
816 | char xpath[XPATH_MAXLEN], xpath_auth[XPATH_MAXLEN + 64]; | |
817 | ||
818 | snprintf(xpath, sizeof(xpath), "./frr-eigrpd:eigrp/instance[asn='%s']", | |
819 | as_str); | |
820 | snprintf(xpath_auth, sizeof(xpath_auth), "%s/keychain", xpath); | |
821 | nb_cli_enqueue_change(vty, xpath_auth, NB_OP_DESTROY, NULL); | |
822 | ||
823 | return nb_cli_apply_changes(vty, NULL); | |
824 | } | |
825 | ||
826 | void eigrp_cli_show_keychain(struct vty *vty, struct lyd_node *dnode, | |
827 | bool show_defaults) | |
828 | { | |
7f9c68df IR |
829 | const struct lyd_node *instance = yang_dnode_get_parent(dnode, "instance"); |
830 | uint16_t asn = yang_dnode_get_uint16(instance, "./asn"); | |
f25c244b RZ |
831 | const char *keychain = yang_dnode_get_string(dnode, NULL); |
832 | ||
7f9c68df IR |
833 | vty_out(vty, " ip authentication key-chain eigrp %d %s\n", asn, |
834 | keychain); | |
f25c244b RZ |
835 | } |
836 | ||
837 | ||
838 | /* | |
839 | * CLI installation procedures. | |
840 | */ | |
612c2c15 | 841 | static int eigrp_config_write(struct vty *vty); |
62b346ee | 842 | static struct cmd_node eigrp_node = { |
f4b8291f | 843 | .name = "eigrp", |
62b346ee | 844 | .node = EIGRP_NODE, |
24389580 | 845 | .parent_node = CONFIG_NODE, |
62b346ee | 846 | .prompt = "%s(config-router)# ", |
612c2c15 | 847 | .config_write = eigrp_config_write, |
62b346ee | 848 | }; |
f25c244b RZ |
849 | |
850 | static int eigrp_config_write(struct vty *vty) | |
851 | { | |
852 | struct lyd_node *dnode; | |
853 | int written = 0; | |
854 | ||
855 | dnode = yang_dnode_get(running_config->dnode, "/frr-eigrpd:eigrpd"); | |
856 | if (dnode) { | |
857 | nb_cli_show_dnode_cmds(vty, dnode, false); | |
858 | written = 1; | |
859 | } | |
860 | ||
861 | return written; | |
862 | } | |
863 | ||
612c2c15 | 864 | static int eigrp_write_interface(struct vty *vty); |
62b346ee | 865 | static struct cmd_node eigrp_interface_node = { |
f4b8291f | 866 | .name = "interface", |
62b346ee | 867 | .node = INTERFACE_NODE, |
24389580 | 868 | .parent_node = CONFIG_NODE, |
62b346ee | 869 | .prompt = "%s(config-if)# ", |
612c2c15 | 870 | .config_write = eigrp_write_interface, |
62b346ee | 871 | }; |
f25c244b RZ |
872 | |
873 | ||
874 | static int eigrp_write_interface(struct vty *vty) | |
875 | { | |
876 | struct lyd_node *dnode; | |
877 | struct interface *ifp; | |
878 | struct vrf *vrf; | |
879 | int written = 0; | |
880 | ||
881 | RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) { | |
882 | FOR_ALL_INTERFACES(vrf, ifp) { | |
883 | dnode = yang_dnode_get( | |
884 | running_config->dnode, | |
885 | "/frr-interface:lib/interface[name='%s'][vrf='%s']", | |
886 | ifp->name, vrf->name); | |
887 | if (dnode == NULL) | |
888 | continue; | |
889 | ||
890 | written = 1; | |
891 | nb_cli_show_dnode_cmds(vty, dnode, false); | |
892 | } | |
893 | } | |
894 | ||
895 | return written; | |
896 | } | |
897 | ||
898 | void | |
899 | eigrp_cli_init(void) | |
900 | { | |
901 | install_element(CONFIG_NODE, &router_eigrp_cmd); | |
902 | install_element(CONFIG_NODE, &no_router_eigrp_cmd); | |
903 | ||
612c2c15 | 904 | install_node(&eigrp_node); |
f25c244b RZ |
905 | install_default(EIGRP_NODE); |
906 | ||
907 | install_element(EIGRP_NODE, &eigrp_router_id_cmd); | |
908 | install_element(EIGRP_NODE, &no_eigrp_router_id_cmd); | |
909 | install_element(EIGRP_NODE, &eigrp_passive_interface_cmd); | |
910 | install_element(EIGRP_NODE, &eigrp_timers_active_cmd); | |
911 | install_element(EIGRP_NODE, &no_eigrp_timers_active_cmd); | |
912 | install_element(EIGRP_NODE, &eigrp_variance_cmd); | |
913 | install_element(EIGRP_NODE, &no_eigrp_variance_cmd); | |
914 | install_element(EIGRP_NODE, &eigrp_maximum_paths_cmd); | |
915 | install_element(EIGRP_NODE, &no_eigrp_maximum_paths_cmd); | |
916 | install_element(EIGRP_NODE, &eigrp_metric_weights_cmd); | |
917 | install_element(EIGRP_NODE, &no_eigrp_metric_weights_cmd); | |
918 | install_element(EIGRP_NODE, &eigrp_network_cmd); | |
919 | install_element(EIGRP_NODE, &eigrp_neighbor_cmd); | |
920 | install_element(EIGRP_NODE, &eigrp_redistribute_source_metric_cmd); | |
921 | ||
612c2c15 | 922 | install_node(&eigrp_interface_node); |
f25c244b RZ |
923 | if_cmd_init(); |
924 | ||
925 | install_element(INTERFACE_NODE, &eigrp_if_delay_cmd); | |
926 | install_element(INTERFACE_NODE, &no_eigrp_if_delay_cmd); | |
927 | install_element(INTERFACE_NODE, &eigrp_if_bandwidth_cmd); | |
928 | install_element(INTERFACE_NODE, &no_eigrp_if_bandwidth_cmd); | |
929 | install_element(INTERFACE_NODE, &eigrp_if_ip_hellointerval_cmd); | |
930 | install_element(INTERFACE_NODE, &no_eigrp_if_ip_hellointerval_cmd); | |
931 | install_element(INTERFACE_NODE, &eigrp_if_ip_holdinterval_cmd); | |
932 | install_element(INTERFACE_NODE, &no_eigrp_if_ip_holdinterval_cmd); | |
933 | install_element(INTERFACE_NODE, &eigrp_ip_summary_address_cmd); | |
934 | install_element(INTERFACE_NODE, &no_eigrp_ip_summary_address_cmd); | |
935 | install_element(INTERFACE_NODE, &eigrp_authentication_mode_cmd); | |
936 | install_element(INTERFACE_NODE, &no_eigrp_authentication_mode_cmd); | |
937 | install_element(INTERFACE_NODE, &eigrp_authentication_keychain_cmd); | |
938 | install_element(INTERFACE_NODE, &no_eigrp_authentication_keychain_cmd); | |
939 | } |