]>
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" | |
32 | ||
33 | #ifndef VTYSH_EXTRACT_PL | |
34 | #include "eigrpd/eigrp_cli_clippy.c" | |
35 | #endif /* VTYSH_EXTRACT_PL */ | |
36 | ||
37 | /* | |
38 | * XPath: /frr-eigrpd:eigrpd/instance | |
39 | */ | |
ca77b518 | 40 | DEFPY_YANG_NOSH( |
f25c244b RZ |
41 | router_eigrp, |
42 | router_eigrp_cmd, | |
e9449961 | 43 | "router eigrp (1-65535)$as [vrf NAME]", |
f25c244b RZ |
44 | ROUTER_STR |
45 | EIGRP_STR | |
e9449961 DS |
46 | AS_STR |
47 | VRF_CMD_HELP_STR) | |
f25c244b RZ |
48 | { |
49 | char xpath[XPATH_MAXLEN]; | |
50 | int rv; | |
51 | ||
52 | snprintf(xpath, sizeof(xpath), | |
e9449961 DS |
53 | "/frr-eigrpd:eigrpd/instance[asn='%s'][vrf='%s']", |
54 | as_str, vrf ? vrf : VRF_DEFAULT_NAME); | |
f25c244b RZ |
55 | |
56 | nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); | |
57 | rv = nb_cli_apply_changes(vty, NULL); | |
58 | if (rv == CMD_SUCCESS) | |
59 | VTY_PUSH_XPATH(EIGRP_NODE, xpath); | |
60 | ||
61 | return rv; | |
62 | } | |
63 | ||
ca77b518 | 64 | DEFPY_YANG( |
f25c244b RZ |
65 | no_router_eigrp, |
66 | no_router_eigrp_cmd, | |
e9449961 | 67 | "no router eigrp (1-65535)$as [vrf NAME]", |
f25c244b RZ |
68 | NO_STR |
69 | ROUTER_STR | |
70 | EIGRP_STR | |
e9449961 DS |
71 | AS_STR |
72 | VRF_CMD_HELP_STR) | |
f25c244b RZ |
73 | { |
74 | char xpath[XPATH_MAXLEN]; | |
75 | ||
76 | snprintf(xpath, sizeof(xpath), | |
e9449961 DS |
77 | "/frr-eigrpd:eigrpd/instance[asn='%s'][vrf='%s']", |
78 | as_str, vrf ? vrf : VRF_DEFAULT_NAME); | |
f25c244b RZ |
79 | |
80 | nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); | |
81 | return nb_cli_apply_changes(vty, NULL); | |
82 | } | |
83 | ||
84 | void eigrp_cli_show_header(struct vty *vty, struct lyd_node *dnode, | |
85 | bool show_defaults) | |
86 | { | |
87 | const char *asn = yang_dnode_get_string(dnode, "./asn"); | |
e9449961 | 88 | const char *vrf = yang_dnode_get_string(dnode, "./vrf"); |
f25c244b | 89 | |
e9449961 DS |
90 | vty_out(vty, "router eigrp %s", asn); |
91 | if (strcmp(vrf, VRF_DEFAULT_NAME)) | |
92 | vty_out(vty, " vrf %s", vrf); | |
93 | vty_out(vty, "\n"); | |
f25c244b RZ |
94 | } |
95 | ||
96 | void eigrp_cli_show_end_header(struct vty *vty, struct lyd_node *dnode) | |
97 | { | |
98 | vty_out(vty, "!\n"); | |
99 | } | |
100 | ||
101 | /* | |
102 | * XPath: /frr-eigrpd:eigrpd/instance/router-id | |
103 | */ | |
ca77b518 | 104 | DEFPY_YANG( |
f25c244b RZ |
105 | eigrp_router_id, |
106 | eigrp_router_id_cmd, | |
107 | "eigrp router-id A.B.C.D$addr", | |
108 | EIGRP_STR | |
109 | "Router ID for this EIGRP process\n" | |
110 | "EIGRP Router-ID in IP address format\n") | |
111 | { | |
112 | nb_cli_enqueue_change(vty, "./router-id", NB_OP_MODIFY, addr_str); | |
113 | return nb_cli_apply_changes(vty, NULL); | |
114 | } | |
115 | ||
ca77b518 | 116 | DEFPY_YANG( |
f25c244b RZ |
117 | no_eigrp_router_id, |
118 | no_eigrp_router_id_cmd, | |
119 | "no eigrp router-id [A.B.C.D]", | |
120 | NO_STR | |
121 | EIGRP_STR | |
122 | "Router ID for this EIGRP process\n" | |
123 | "EIGRP Router-ID in IP address format\n") | |
124 | { | |
125 | nb_cli_enqueue_change(vty, "./router-id", NB_OP_DESTROY, NULL); | |
126 | return nb_cli_apply_changes(vty, NULL); | |
127 | } | |
128 | ||
129 | void eigrp_cli_show_router_id(struct vty *vty, struct lyd_node *dnode, | |
130 | bool show_defaults) | |
131 | { | |
132 | const char *router_id = yang_dnode_get_string(dnode, NULL); | |
133 | ||
134 | vty_out(vty, " eigrp router-id %s\n", router_id); | |
135 | } | |
136 | ||
137 | /* | |
138 | * XPath: /frr-eigrpd:eigrpd/instance/passive-interface | |
139 | */ | |
ca77b518 | 140 | DEFPY_YANG( |
f25c244b RZ |
141 | eigrp_passive_interface, |
142 | eigrp_passive_interface_cmd, | |
143 | "[no] passive-interface IFNAME", | |
144 | NO_STR | |
145 | "Suppress routing updates on an interface\n" | |
146 | "Interface to suppress on\n") | |
147 | { | |
148 | if (no) | |
149 | nb_cli_enqueue_change(vty, "./passive-interface", | |
150 | NB_OP_DESTROY, ifname); | |
151 | else | |
152 | nb_cli_enqueue_change(vty, "./passive-interface", | |
153 | NB_OP_CREATE, ifname); | |
154 | ||
155 | return nb_cli_apply_changes(vty, NULL); | |
156 | } | |
157 | ||
158 | void eigrp_cli_show_passive_interface(struct vty *vty, struct lyd_node *dnode, | |
159 | bool show_defaults) | |
160 | { | |
161 | const char *ifname = yang_dnode_get_string(dnode, NULL); | |
162 | ||
163 | vty_out(vty, " passive-interface %s\n", ifname); | |
164 | } | |
165 | ||
166 | /* | |
167 | * XPath: /frr-eigrpd:eigrpd/instance/active-time | |
168 | */ | |
ca77b518 | 169 | DEFPY_YANG( |
f25c244b RZ |
170 | eigrp_timers_active, |
171 | eigrp_timers_active_cmd, | |
172 | "timers active-time <(1-65535)$timer|disabled$disabled>", | |
173 | "Adjust routing timers\n" | |
174 | "Time limit for active state\n" | |
175 | "Active state time limit in seconds\n" | |
176 | "Disable time limit for active state\n") | |
177 | { | |
178 | if (disabled) | |
179 | nb_cli_enqueue_change(vty, "./active-time", NB_OP_MODIFY, "0"); | |
180 | else | |
181 | nb_cli_enqueue_change(vty, "./active-time", | |
182 | NB_OP_MODIFY, timer_str); | |
183 | ||
184 | return nb_cli_apply_changes(vty, NULL); | |
185 | } | |
186 | ||
ca77b518 | 187 | DEFPY_YANG( |
f25c244b RZ |
188 | no_eigrp_timers_active, |
189 | no_eigrp_timers_active_cmd, | |
190 | "no timers active-time [<(1-65535)|disabled>]", | |
191 | NO_STR | |
192 | "Adjust routing timers\n" | |
193 | "Time limit for active state\n" | |
194 | "Active state time limit in seconds\n" | |
195 | "Disable time limit for active state\n") | |
196 | { | |
197 | nb_cli_enqueue_change(vty, "./active-time", NB_OP_DESTROY, NULL); | |
198 | return nb_cli_apply_changes(vty, NULL); | |
199 | } | |
200 | ||
201 | void eigrp_cli_show_active_time(struct vty *vty, struct lyd_node *dnode, | |
202 | bool show_defaults) | |
203 | { | |
204 | const char *timer = yang_dnode_get_string(dnode, NULL); | |
205 | ||
206 | vty_out(vty, " timers active-time %s\n", timer); | |
207 | } | |
208 | ||
209 | /* | |
210 | * XPath: /frr-eigrpd:eigrpd/instance/variance | |
211 | */ | |
ca77b518 | 212 | DEFPY_YANG( |
f25c244b RZ |
213 | eigrp_variance, |
214 | eigrp_variance_cmd, | |
215 | "variance (1-128)$variance", | |
216 | "Control load balancing variance\n" | |
217 | "Metric variance multiplier\n") | |
218 | { | |
219 | nb_cli_enqueue_change(vty, "./variance", NB_OP_MODIFY, variance_str); | |
220 | return nb_cli_apply_changes(vty, NULL); | |
221 | } | |
222 | ||
ca77b518 | 223 | DEFPY_YANG( |
f25c244b RZ |
224 | no_eigrp_variance, |
225 | no_eigrp_variance_cmd, | |
226 | "no variance [(1-128)]", | |
227 | NO_STR | |
228 | "Control load balancing variance\n" | |
229 | "Metric variance multiplier\n") | |
230 | { | |
231 | nb_cli_enqueue_change(vty, "./variance", NB_OP_DESTROY, NULL); | |
232 | return nb_cli_apply_changes(vty, NULL); | |
233 | } | |
234 | ||
235 | void eigrp_cli_show_variance(struct vty *vty, struct lyd_node *dnode, | |
236 | bool show_defaults) | |
237 | { | |
238 | const char *variance = yang_dnode_get_string(dnode, NULL); | |
239 | ||
240 | vty_out(vty, " variance %s\n", variance); | |
241 | } | |
242 | ||
243 | /* | |
244 | * XPath: /frr-eigrpd:eigrpd/instance/maximum-paths | |
245 | */ | |
ca77b518 | 246 | DEFPY_YANG( |
f25c244b RZ |
247 | eigrp_maximum_paths, |
248 | eigrp_maximum_paths_cmd, | |
249 | "maximum-paths (1-32)$maximum_paths", | |
250 | "Forward packets over multiple paths\n" | |
251 | "Number of paths\n") | |
252 | { | |
253 | nb_cli_enqueue_change(vty, "./maximum-paths", NB_OP_MODIFY, | |
254 | maximum_paths_str); | |
255 | return nb_cli_apply_changes(vty, NULL); | |
256 | } | |
257 | ||
ca77b518 | 258 | DEFPY_YANG( |
f25c244b RZ |
259 | no_eigrp_maximum_paths, |
260 | no_eigrp_maximum_paths_cmd, | |
261 | "no maximum-paths [(1-32)]", | |
262 | NO_STR | |
263 | "Forward packets over multiple paths\n" | |
264 | "Number of paths\n") | |
265 | { | |
266 | nb_cli_enqueue_change(vty, "./maximum-paths", NB_OP_DESTROY, NULL); | |
267 | return nb_cli_apply_changes(vty, NULL); | |
268 | } | |
269 | ||
270 | void eigrp_cli_show_maximum_paths(struct vty *vty, struct lyd_node *dnode, | |
271 | bool show_defaults) | |
272 | { | |
273 | const char *maximum_paths = yang_dnode_get_string(dnode, NULL); | |
274 | ||
275 | vty_out(vty, " maximum-paths %s\n", maximum_paths); | |
276 | } | |
277 | ||
278 | /* | |
279 | * XPath: /frr-eigrpd:eigrpd/instance/metric-weights/K1 | |
280 | * XPath: /frr-eigrpd:eigrpd/instance/metric-weights/K2 | |
281 | * XPath: /frr-eigrpd:eigrpd/instance/metric-weights/K3 | |
282 | * XPath: /frr-eigrpd:eigrpd/instance/metric-weights/K4 | |
283 | * XPath: /frr-eigrpd:eigrpd/instance/metric-weights/K5 | |
284 | * XPath: /frr-eigrpd:eigrpd/instance/metric-weights/K6 | |
285 | */ | |
ca77b518 | 286 | DEFPY_YANG( |
f25c244b RZ |
287 | eigrp_metric_weights, |
288 | eigrp_metric_weights_cmd, | |
289 | "metric weights (0-255)$k1 (0-255)$k2 (0-255)$k3 (0-255)$k4 (0-255)$k5 [(0-255)$k6]", | |
290 | "Modify metrics and parameters for advertisement\n" | |
291 | "Modify metric coefficients\n" | |
292 | "K1\n" | |
293 | "K2\n" | |
294 | "K3\n" | |
295 | "K4\n" | |
296 | "K5\n" | |
297 | "K6\n") | |
298 | { | |
299 | nb_cli_enqueue_change(vty, "./metric-weights/K1", NB_OP_MODIFY, k1_str); | |
300 | nb_cli_enqueue_change(vty, "./metric-weights/K2", NB_OP_MODIFY, k2_str); | |
301 | nb_cli_enqueue_change(vty, "./metric-weights/K3", NB_OP_MODIFY, k3_str); | |
302 | nb_cli_enqueue_change(vty, "./metric-weights/K4", NB_OP_MODIFY, k4_str); | |
303 | nb_cli_enqueue_change(vty, "./metric-weights/K5", NB_OP_MODIFY, k5_str); | |
304 | if (k6) | |
305 | nb_cli_enqueue_change(vty, "./metric-weights/K6", | |
306 | NB_OP_MODIFY, k6_str); | |
307 | ||
308 | return nb_cli_apply_changes(vty, NULL); | |
309 | } | |
310 | ||
ca77b518 | 311 | DEFPY_YANG( |
f25c244b RZ |
312 | no_eigrp_metric_weights, |
313 | no_eigrp_metric_weights_cmd, | |
314 | "no metric weights [(0-255) (0-255) (0-255) (0-255) (0-255) (0-255)]", | |
315 | NO_STR | |
316 | "Modify metrics and parameters for advertisement\n" | |
317 | "Modify metric coefficients\n" | |
318 | "K1\n" | |
319 | "K2\n" | |
320 | "K3\n" | |
321 | "K4\n" | |
322 | "K5\n" | |
323 | "K6\n") | |
324 | { | |
325 | nb_cli_enqueue_change(vty, "./metric-weights/K1", NB_OP_DESTROY, NULL); | |
326 | nb_cli_enqueue_change(vty, "./metric-weights/K2", NB_OP_DESTROY, NULL); | |
327 | nb_cli_enqueue_change(vty, "./metric-weights/K3", NB_OP_DESTROY, NULL); | |
328 | nb_cli_enqueue_change(vty, "./metric-weights/K4", NB_OP_DESTROY, NULL); | |
329 | nb_cli_enqueue_change(vty, "./metric-weights/K5", NB_OP_DESTROY, NULL); | |
330 | nb_cli_enqueue_change(vty, "./metric-weights/K6", NB_OP_DESTROY, NULL); | |
331 | return nb_cli_apply_changes(vty, NULL); | |
332 | } | |
333 | ||
334 | void eigrp_cli_show_metrics(struct vty *vty, struct lyd_node *dnode, | |
335 | bool show_defaults) | |
336 | { | |
337 | const char *k1, *k2, *k3, *k4, *k5, *k6; | |
338 | ||
339 | k1 = yang_dnode_exists(dnode, "./K1") ? | |
340 | yang_dnode_get_string(dnode, "./K1") : "0"; | |
341 | k2 = yang_dnode_exists(dnode, "./K2") ? | |
342 | yang_dnode_get_string(dnode, "./K2") : "0"; | |
343 | k3 = yang_dnode_exists(dnode, "./K3") ? | |
344 | yang_dnode_get_string(dnode, "./K3") : "0"; | |
345 | k4 = yang_dnode_exists(dnode, "./K4") ? | |
346 | yang_dnode_get_string(dnode, "./K4") : "0"; | |
347 | k5 = yang_dnode_exists(dnode, "./K5") ? | |
348 | yang_dnode_get_string(dnode, "./K5") : "0"; | |
349 | k6 = yang_dnode_exists(dnode, "./K6") ? | |
350 | yang_dnode_get_string(dnode, "./K6") : "0"; | |
351 | ||
352 | vty_out(vty, " metric weights %s %s %s %s %s", | |
353 | k1, k2, k3, k4, k5); | |
354 | if (k6) | |
355 | vty_out(vty, " %s", k6); | |
356 | vty_out(vty, "\n"); | |
357 | } | |
358 | ||
359 | /* | |
360 | * XPath: /frr-eigrpd:eigrpd/instance/network | |
361 | */ | |
ca77b518 | 362 | DEFPY_YANG( |
f25c244b RZ |
363 | eigrp_network, |
364 | eigrp_network_cmd, | |
365 | "[no] network A.B.C.D/M$prefix", | |
366 | NO_STR | |
367 | "Enable routing on an IP network\n" | |
368 | "EIGRP network prefix\n") | |
369 | { | |
370 | if (no) | |
371 | nb_cli_enqueue_change(vty, "./network", NB_OP_DESTROY, | |
372 | prefix_str); | |
373 | else | |
374 | nb_cli_enqueue_change(vty, "./network", NB_OP_CREATE, | |
375 | prefix_str); | |
376 | ||
377 | return nb_cli_apply_changes(vty, NULL); | |
378 | } | |
379 | ||
380 | void eigrp_cli_show_network(struct vty *vty, struct lyd_node *dnode, | |
381 | bool show_defaults) | |
382 | { | |
383 | const char *prefix = yang_dnode_get_string(dnode, NULL); | |
384 | ||
385 | vty_out(vty, " network %s\n", prefix); | |
386 | } | |
387 | ||
388 | /* | |
389 | * XPath: /frr-eigrpd:eigrpd/instance/neighbor | |
390 | */ | |
ca77b518 | 391 | DEFPY_YANG( |
f25c244b RZ |
392 | eigrp_neighbor, |
393 | eigrp_neighbor_cmd, | |
394 | "[no] neighbor A.B.C.D$addr", | |
395 | NO_STR | |
396 | "Specify a neighbor router\n" | |
397 | "Neighbor address\n") | |
398 | { | |
399 | if (no) | |
400 | nb_cli_enqueue_change(vty, "./neighbor", NB_OP_DESTROY, | |
401 | addr_str); | |
402 | else | |
403 | nb_cli_enqueue_change(vty, "./neighbor", NB_OP_CREATE, | |
404 | addr_str); | |
405 | ||
406 | return nb_cli_apply_changes(vty, NULL); | |
407 | } | |
408 | ||
409 | void eigrp_cli_show_neighbor(struct vty *vty, struct lyd_node *dnode, | |
410 | bool show_defaults) | |
411 | { | |
412 | const char *prefix = yang_dnode_get_string(dnode, NULL); | |
413 | ||
414 | vty_out(vty, " neighbor %s\n", prefix); | |
415 | } | |
416 | ||
417 | /* | |
418 | * XPath: /frr-eigrpd:eigrpd/instance/redistribute | |
419 | * XPath: /frr-eigrpd:eigrpd/instance/redistribute/route-map | |
420 | * XPath: /frr-eigrpd:eigrpd/instance/redistribute/metrics/bandwidth | |
421 | * XPath: /frr-eigrpd:eigrpd/instance/redistribute/metrics/delay | |
422 | * XPath: /frr-eigrpd:eigrpd/instance/redistribute/metrics/reliability | |
423 | * XPath: /frr-eigrpd:eigrpd/instance/redistribute/metrics/load | |
424 | * XPath: /frr-eigrpd:eigrpd/instance/redistribute/metrics/mtu | |
425 | */ | |
ca77b518 | 426 | DEFPY_YANG( |
f25c244b RZ |
427 | eigrp_redistribute_source_metric, |
428 | eigrp_redistribute_source_metric_cmd, | |
429 | "[no] redistribute " FRR_REDIST_STR_EIGRPD | |
430 | "$proto [metric (1-4294967295)$bw (0-4294967295)$delay (0-255)$rlbt (1-255)$load (1-65535)$mtu]", | |
431 | NO_STR | |
432 | REDIST_STR | |
433 | FRR_REDIST_HELP_STR_EIGRPD | |
434 | "Metric for redistributed routes\n" | |
435 | "Bandwidth metric in Kbits per second\n" | |
436 | "EIGRP delay metric, in 10 microsecond units\n" | |
437 | "EIGRP reliability metric where 255 is 100% reliable2 ?\n" | |
438 | "EIGRP Effective bandwidth metric (Loading) where 255 is 100% loaded\n" | |
439 | "EIGRP MTU of the path\n") | |
440 | { | |
441 | char xpath[XPATH_MAXLEN], xpath_metric[XPATH_MAXLEN + 64]; | |
442 | ||
443 | snprintf(xpath, sizeof(xpath), "./redistribute[protocol='%s']", proto); | |
444 | ||
445 | if (no) { | |
446 | nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); | |
447 | return nb_cli_apply_changes(vty, NULL); | |
448 | } | |
449 | ||
450 | nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); | |
451 | if (bw == 0 || delay == 0 || rlbt == 0 || load == 0 || mtu == 0) | |
452 | return nb_cli_apply_changes(vty, NULL); | |
453 | ||
454 | snprintf(xpath_metric, sizeof(xpath_metric), "%s/metrics/bandwidth", | |
455 | xpath); | |
456 | nb_cli_enqueue_change(vty, xpath_metric, NB_OP_MODIFY, bw_str); | |
457 | snprintf(xpath_metric, sizeof(xpath_metric), "%s/metrics/delay", xpath); | |
458 | nb_cli_enqueue_change(vty, xpath_metric, NB_OP_MODIFY, delay_str); | |
459 | snprintf(xpath_metric, sizeof(xpath_metric), "%s/metrics/reliability", | |
460 | xpath); | |
461 | nb_cli_enqueue_change(vty, xpath_metric, NB_OP_MODIFY, rlbt_str); | |
462 | snprintf(xpath_metric, sizeof(xpath_metric), "%s/metrics/load", xpath); | |
463 | nb_cli_enqueue_change(vty, xpath_metric, NB_OP_MODIFY, load_str); | |
464 | snprintf(xpath_metric, sizeof(xpath_metric), "%s/metrics/mtu", xpath); | |
465 | nb_cli_enqueue_change(vty, xpath_metric, NB_OP_MODIFY, mtu_str); | |
466 | return nb_cli_apply_changes(vty, NULL); | |
467 | } | |
468 | ||
469 | void eigrp_cli_show_redistribute(struct vty *vty, struct lyd_node *dnode, | |
470 | bool show_defaults) | |
471 | { | |
472 | const char *proto = yang_dnode_get_string(dnode, "./protocol"); | |
473 | const char *bw, *delay, *load, *mtu, *rlbt; | |
474 | ||
475 | bw = yang_dnode_exists(dnode, "./metrics/bandwidth") ? | |
476 | yang_dnode_get_string(dnode, "./metrics/bandwidth") : NULL; | |
477 | delay = yang_dnode_exists(dnode, "./metrics/delay") ? | |
478 | yang_dnode_get_string(dnode, "./metrics/delay") : NULL; | |
479 | rlbt = yang_dnode_exists(dnode, "./metrics/reliability") ? | |
480 | yang_dnode_get_string(dnode, "./metrics/reliability") : NULL; | |
481 | load = yang_dnode_exists(dnode, "./metrics/load") ? | |
482 | yang_dnode_get_string(dnode, "./metrics/load") : NULL; | |
483 | mtu = yang_dnode_exists(dnode, "./metrics/mtu") ? | |
484 | yang_dnode_get_string(dnode, "./metrics/mtu") : NULL; | |
485 | ||
486 | vty_out(vty, " redistribute %s", proto); | |
487 | if (bw || rlbt || delay || load || mtu) | |
488 | vty_out(vty, " metric %s %s %s %s %s", bw, delay, rlbt, load, | |
489 | mtu); | |
490 | vty_out(vty, "\n"); | |
491 | } | |
492 | ||
493 | /* | |
494 | * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/delay | |
495 | */ | |
ca77b518 | 496 | DEFPY_YANG( |
f25c244b RZ |
497 | eigrp_if_delay, |
498 | eigrp_if_delay_cmd, | |
499 | "delay (1-16777215)$delay", | |
500 | "Specify interface throughput delay\n" | |
501 | "Throughput delay (tens of microseconds)\n") | |
502 | { | |
503 | nb_cli_enqueue_change(vty, "./frr-eigrpd:eigrp/delay", | |
504 | NB_OP_MODIFY, delay_str); | |
505 | return nb_cli_apply_changes(vty, NULL); | |
506 | } | |
507 | ||
ca77b518 | 508 | DEFPY_YANG( |
f25c244b RZ |
509 | no_eigrp_if_delay, |
510 | no_eigrp_if_delay_cmd, | |
511 | "no delay [(1-16777215)]", | |
512 | NO_STR | |
513 | "Specify interface throughput delay\n" | |
514 | "Throughput delay (tens of microseconds)\n") | |
515 | { | |
516 | nb_cli_enqueue_change(vty, "./frr-eigrpd:eigrp/delay", | |
517 | NB_OP_DESTROY, NULL); | |
518 | return nb_cli_apply_changes(vty, NULL); | |
519 | } | |
520 | ||
521 | void eigrp_cli_show_delay(struct vty *vty, struct lyd_node *dnode, | |
522 | bool show_defaults) | |
523 | { | |
524 | const char *delay = yang_dnode_get_string(dnode, NULL); | |
525 | ||
526 | vty_out(vty, " delay %s\n", delay); | |
527 | } | |
528 | ||
529 | /* | |
530 | * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/bandwidth | |
531 | */ | |
ca77b518 | 532 | DEFPY_YANG( |
f25c244b RZ |
533 | eigrp_if_bandwidth, |
534 | eigrp_if_bandwidth_cmd, | |
535 | "eigrp bandwidth (1-10000000)$bw", | |
536 | EIGRP_STR | |
537 | "Set bandwidth informational parameter\n" | |
538 | "Bandwidth in kilobits\n") | |
539 | { | |
540 | nb_cli_enqueue_change(vty, "./frr-eigrpd:eigrp/bandwidth", | |
541 | NB_OP_MODIFY, bw_str); | |
542 | return nb_cli_apply_changes(vty, NULL); | |
543 | } | |
544 | ||
ca77b518 | 545 | DEFPY_YANG( |
f25c244b RZ |
546 | no_eigrp_if_bandwidth, |
547 | no_eigrp_if_bandwidth_cmd, | |
548 | "no eigrp bandwidth [(1-10000000)]", | |
549 | NO_STR | |
550 | EIGRP_STR | |
551 | "Set bandwidth informational parameter\n" | |
552 | "Bandwidth in kilobits\n") | |
553 | { | |
554 | nb_cli_enqueue_change(vty, "./frr-eigrpd:eigrp/bandwidth", | |
555 | NB_OP_DESTROY, NULL); | |
556 | return nb_cli_apply_changes(vty, NULL); | |
557 | } | |
558 | ||
559 | void eigrp_cli_show_bandwidth(struct vty *vty, struct lyd_node *dnode, | |
560 | bool show_defaults) | |
561 | { | |
562 | const char *bandwidth = yang_dnode_get_string(dnode, NULL); | |
563 | ||
564 | vty_out(vty, " eigrp bandwidth %s\n", bandwidth); | |
565 | } | |
566 | ||
567 | /* | |
568 | * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/hello-interval | |
569 | */ | |
ca77b518 | 570 | DEFPY_YANG( |
f25c244b RZ |
571 | eigrp_if_ip_hellointerval, |
572 | eigrp_if_ip_hellointerval_cmd, | |
573 | "ip hello-interval eigrp (1-65535)$hello", | |
574 | "Interface Internet Protocol config commands\n" | |
575 | "Configures EIGRP hello interval\n" | |
576 | EIGRP_STR | |
577 | "Seconds between hello transmissions\n") | |
578 | { | |
579 | nb_cli_enqueue_change(vty, "./frr-eigrpd:eigrp/hello-interval", | |
580 | NB_OP_MODIFY, hello_str); | |
581 | return nb_cli_apply_changes(vty, NULL); | |
582 | } | |
583 | ||
ca77b518 | 584 | DEFPY_YANG( |
f25c244b RZ |
585 | no_eigrp_if_ip_hellointerval, |
586 | no_eigrp_if_ip_hellointerval_cmd, | |
587 | "no ip hello-interval eigrp [(1-65535)]", | |
588 | NO_STR | |
589 | "Interface Internet Protocol config commands\n" | |
590 | "Configures EIGRP hello interval\n" | |
591 | EIGRP_STR | |
592 | "Seconds between hello transmissions\n") | |
593 | { | |
594 | nb_cli_enqueue_change(vty, "./frr-eigrpd:eigrp/hello-interval", | |
595 | NB_OP_DESTROY, NULL); | |
596 | return nb_cli_apply_changes(vty, NULL); | |
597 | } | |
598 | ||
599 | ||
600 | void eigrp_cli_show_hello_interval(struct vty *vty, struct lyd_node *dnode, | |
601 | bool show_defaults) | |
602 | { | |
603 | const char *hello = yang_dnode_get_string(dnode, NULL); | |
604 | ||
605 | vty_out(vty, " ip hello-interval eigrp %s\n", hello); | |
606 | } | |
607 | ||
608 | /* | |
609 | * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/hold-time | |
610 | */ | |
ca77b518 | 611 | DEFPY_YANG( |
f25c244b RZ |
612 | eigrp_if_ip_holdinterval, |
613 | eigrp_if_ip_holdinterval_cmd, | |
614 | "ip hold-time eigrp (1-65535)$hold", | |
615 | "Interface Internet Protocol config commands\n" | |
616 | "Configures EIGRP IPv4 hold time\n" | |
617 | EIGRP_STR | |
618 | "Seconds before neighbor is considered down\n") | |
619 | { | |
620 | nb_cli_enqueue_change(vty, "./frr-eigrpd:eigrp/hold-time", | |
621 | NB_OP_MODIFY, hold_str); | |
622 | return nb_cli_apply_changes(vty, NULL); | |
623 | } | |
624 | ||
ca77b518 | 625 | DEFPY_YANG( |
f25c244b RZ |
626 | no_eigrp_if_ip_holdinterval, |
627 | no_eigrp_if_ip_holdinterval_cmd, | |
628 | "no ip hold-time eigrp [(1-65535)]", | |
629 | NO_STR | |
630 | "Interface Internet Protocol config commands\n" | |
631 | "Configures EIGRP IPv4 hold time\n" | |
632 | EIGRP_STR | |
633 | "Seconds before neighbor is considered down\n") | |
634 | { | |
635 | nb_cli_enqueue_change(vty, "./frr-eigrpd:eigrp/hold-time", | |
636 | NB_OP_DESTROY, NULL); | |
637 | return nb_cli_apply_changes(vty, NULL); | |
638 | } | |
639 | ||
640 | void eigrp_cli_show_hold_time(struct vty *vty, struct lyd_node *dnode, | |
641 | bool show_defaults) | |
642 | { | |
643 | const char *holdtime = yang_dnode_get_string(dnode, NULL); | |
644 | ||
645 | vty_out(vty, " ip hold-time eigrp %s\n", holdtime); | |
646 | } | |
647 | ||
648 | /* | |
649 | * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/split-horizon | |
650 | */ | |
651 | /* NOT implemented. */ | |
652 | ||
653 | /* | |
654 | * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/instance | |
655 | * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/instance/summarize-addresses | |
656 | */ | |
ca77b518 | 657 | DEFPY_YANG( |
f25c244b RZ |
658 | eigrp_ip_summary_address, |
659 | eigrp_ip_summary_address_cmd, | |
660 | "ip summary-address eigrp (1-65535)$as A.B.C.D/M$prefix", | |
661 | "Interface Internet Protocol config commands\n" | |
662 | "Perform address summarization\n" | |
663 | EIGRP_STR | |
664 | AS_STR | |
665 | "Summary <network>/<length>, e.g. 192.168.0.0/16\n") | |
666 | { | |
667 | char xpath[XPATH_MAXLEN], xpath_auth[XPATH_MAXLEN + 64]; | |
668 | ||
669 | snprintf(xpath, sizeof(xpath), "./frr-eigrpd:eigrp/instance[asn='%s']", | |
670 | as_str); | |
671 | nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); | |
672 | ||
673 | snprintf(xpath_auth, sizeof(xpath_auth), "%s/summarize-address", xpath); | |
674 | nb_cli_enqueue_change(vty, xpath_auth, NB_OP_CREATE, prefix_str); | |
675 | ||
676 | return nb_cli_apply_changes(vty, NULL); | |
677 | } | |
678 | ||
ca77b518 | 679 | DEFPY_YANG( |
f25c244b RZ |
680 | no_eigrp_ip_summary_address, |
681 | no_eigrp_ip_summary_address_cmd, | |
682 | "no ip summary-address eigrp (1-65535)$as A.B.C.D/M$prefix", | |
683 | NO_STR | |
684 | "Interface Internet Protocol config commands\n" | |
685 | "Perform address summarization\n" | |
686 | EIGRP_STR | |
687 | AS_STR | |
688 | "Summary <network>/<length>, e.g. 192.168.0.0/16\n") | |
689 | { | |
690 | char xpath[XPATH_MAXLEN], xpath_auth[XPATH_MAXLEN + 64]; | |
691 | ||
692 | snprintf(xpath, sizeof(xpath), "./frr-eigrpd:eigrp/instance[asn='%s']", | |
693 | as_str); | |
694 | nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); | |
695 | ||
696 | snprintf(xpath_auth, sizeof(xpath_auth), "%s/summarize-address", xpath); | |
697 | nb_cli_enqueue_change(vty, xpath_auth, NB_OP_DESTROY, prefix_str); | |
698 | ||
699 | return nb_cli_apply_changes(vty, NULL); | |
700 | } | |
701 | ||
702 | void eigrp_cli_show_summarize_address(struct vty *vty, struct lyd_node *dnode, | |
703 | bool show_defaults) | |
704 | { | |
705 | const struct eigrp_interface *eif = nb_running_get_entry(dnode, NULL, | |
706 | true); | |
707 | const char *summarize_address = yang_dnode_get_string(dnode, NULL); | |
708 | ||
709 | vty_out(vty, " ip summary-address eigrp %d %s\n", | |
710 | eif->eigrp->AS, summarize_address); | |
711 | } | |
712 | ||
713 | /* | |
714 | * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/instance | |
715 | * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/instance/authentication | |
716 | */ | |
ca77b518 | 717 | DEFPY_YANG( |
f25c244b RZ |
718 | eigrp_authentication_mode, |
719 | eigrp_authentication_mode_cmd, | |
720 | "ip authentication mode eigrp (1-65535)$as <md5|hmac-sha-256>$crypt", | |
721 | "Interface Internet Protocol config commands\n" | |
722 | "Authentication subcommands\n" | |
723 | "Mode\n" | |
724 | EIGRP_STR | |
725 | AS_STR | |
726 | "Keyed message digest\n" | |
727 | "HMAC SHA256 algorithm \n") | |
728 | { | |
729 | char xpath[XPATH_MAXLEN], xpath_auth[XPATH_MAXLEN + 64]; | |
730 | ||
731 | snprintf(xpath, sizeof(xpath), "./frr-eigrpd:eigrp/instance[asn='%s']", | |
732 | as_str); | |
733 | nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); | |
734 | ||
735 | snprintf(xpath_auth, sizeof(xpath_auth), "%s/authentication", xpath); | |
736 | nb_cli_enqueue_change(vty, xpath_auth, NB_OP_MODIFY, crypt); | |
737 | ||
738 | return nb_cli_apply_changes(vty, NULL); | |
739 | } | |
740 | ||
ca77b518 | 741 | DEFPY_YANG( |
f25c244b RZ |
742 | no_eigrp_authentication_mode, |
743 | no_eigrp_authentication_mode_cmd, | |
744 | "no ip authentication mode eigrp (1-65535)$as [<md5|hmac-sha-256>]", | |
745 | NO_STR | |
746 | "Interface Internet Protocol config commands\n" | |
747 | "Authentication subcommands\n" | |
748 | "Mode\n" | |
749 | EIGRP_STR | |
750 | AS_STR | |
751 | "Keyed message digest\n" | |
752 | "HMAC SHA256 algorithm \n") | |
753 | { | |
754 | char xpath[XPATH_MAXLEN], xpath_auth[XPATH_MAXLEN + 64]; | |
755 | ||
756 | snprintf(xpath, sizeof(xpath), "./frr-eigrpd:eigrp/instance[asn='%s']", | |
757 | as_str); | |
758 | nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); | |
759 | ||
760 | snprintf(xpath_auth, sizeof(xpath_auth), "%s/authentication", xpath); | |
761 | nb_cli_enqueue_change(vty, xpath_auth, NB_OP_MODIFY, "none"); | |
762 | ||
763 | return nb_cli_apply_changes(vty, NULL); | |
764 | } | |
765 | ||
766 | void eigrp_cli_show_authentication(struct vty *vty, struct lyd_node *dnode, | |
767 | bool show_defaults) | |
768 | { | |
769 | const struct eigrp_interface *eif = nb_running_get_entry(dnode, NULL, | |
770 | true); | |
771 | const char *crypt = yang_dnode_get_string(dnode, NULL); | |
772 | ||
773 | vty_out(vty, " ip authentication mode eigrp %d %s\n", | |
774 | eif->eigrp->AS, crypt); | |
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 | { | |
829 | const struct eigrp_interface *eif = nb_running_get_entry(dnode, NULL, | |
830 | true); | |
831 | const char *keychain = yang_dnode_get_string(dnode, NULL); | |
832 | ||
833 | vty_out(vty, " ip authentication key-chain eigrp %d %s\n", | |
834 | eif->eigrp->AS, keychain); | |
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 | } |