]>
Commit | Line | Data |
---|---|---|
1 | // SPDX-License-Identifier: GPL-2.0-or-later | |
2 | /* | |
3 | * Copyright (C) 1998 Kunihiro Ishiguro | |
4 | * Copyright (C) 2018 NetDEF, Inc. | |
5 | * Renato Westphal | |
6 | * Copyright (C) 2023 LabN Consulting, L.L.C. | |
7 | */ | |
8 | ||
9 | #include <zebra.h> | |
10 | ||
11 | #include "if.h" | |
12 | #include "vrf.h" | |
13 | #include "log.h" | |
14 | #include "prefix.h" | |
15 | #include "table.h" | |
16 | #include "command.h" | |
17 | #include "if_rmap.h" | |
18 | #include "routemap.h" | |
19 | #include "agg_table.h" | |
20 | #include "northbound.h" | |
21 | #include "libfrr.h" | |
22 | ||
23 | #include "ripngd/ripngd.h" | |
24 | #include "ripngd/ripng_nb.h" | |
25 | #include "ripngd/ripng_debug.h" | |
26 | #include "ripngd/ripng_route.h" | |
27 | ||
28 | /* | |
29 | * XPath: /frr-ripngd:ripngd/instance | |
30 | */ | |
31 | int ripngd_instance_create(struct nb_cb_create_args *args) | |
32 | { | |
33 | struct ripng *ripng; | |
34 | struct vrf *vrf; | |
35 | const char *vrf_name; | |
36 | int socket; | |
37 | ||
38 | vrf_name = yang_dnode_get_string(args->dnode, "./vrf"); | |
39 | vrf = vrf_lookup_by_name(vrf_name); | |
40 | ||
41 | /* | |
42 | * Try to create a RIPng socket only if the VRF is enabled, otherwise | |
43 | * create a disabled RIPng instance and wait for the VRF to be enabled. | |
44 | */ | |
45 | switch (args->event) { | |
46 | case NB_EV_VALIDATE: | |
47 | break; | |
48 | case NB_EV_PREPARE: | |
49 | if (!vrf || !vrf_is_enabled(vrf)) | |
50 | break; | |
51 | ||
52 | socket = ripng_make_socket(vrf); | |
53 | if (socket < 0) | |
54 | return NB_ERR_RESOURCE; | |
55 | args->resource->fd = socket; | |
56 | break; | |
57 | case NB_EV_ABORT: | |
58 | if (!vrf || !vrf_is_enabled(vrf)) | |
59 | break; | |
60 | ||
61 | socket = args->resource->fd; | |
62 | close(socket); | |
63 | break; | |
64 | case NB_EV_APPLY: | |
65 | if (vrf && vrf_is_enabled(vrf)) | |
66 | socket = args->resource->fd; | |
67 | else | |
68 | socket = -1; | |
69 | ||
70 | ripng = ripng_create(vrf_name, vrf, socket); | |
71 | nb_running_set_entry(args->dnode, ripng); | |
72 | break; | |
73 | } | |
74 | ||
75 | return NB_OK; | |
76 | } | |
77 | ||
78 | int ripngd_instance_destroy(struct nb_cb_destroy_args *args) | |
79 | { | |
80 | struct ripng *ripng; | |
81 | ||
82 | if (args->event != NB_EV_APPLY) | |
83 | return NB_OK; | |
84 | ||
85 | ripng = nb_running_unset_entry(args->dnode); | |
86 | ripng_clean(ripng); | |
87 | ||
88 | return NB_OK; | |
89 | } | |
90 | ||
91 | const void *ripngd_instance_get_next(struct nb_cb_get_next_args *args) | |
92 | { | |
93 | struct ripng *ripng = (struct ripng *)args->list_entry; | |
94 | ||
95 | if (args->list_entry == NULL) | |
96 | ripng = RB_MIN(ripng_instance_head, &ripng_instances); | |
97 | else | |
98 | ripng = RB_NEXT(ripng_instance_head, ripng); | |
99 | ||
100 | return ripng; | |
101 | } | |
102 | ||
103 | int ripngd_instance_get_keys(struct nb_cb_get_keys_args *args) | |
104 | { | |
105 | const struct ripng *ripng = args->list_entry; | |
106 | ||
107 | args->keys->num = 1; | |
108 | strlcpy(args->keys->key[0], ripng->vrf_name, | |
109 | sizeof(args->keys->key[0])); | |
110 | ||
111 | return NB_OK; | |
112 | } | |
113 | ||
114 | const void *ripngd_instance_lookup_entry(struct nb_cb_lookup_entry_args *args) | |
115 | { | |
116 | const char *vrf_name = args->keys->key[0]; | |
117 | ||
118 | return ripng_lookup_by_vrf_name(vrf_name); | |
119 | } | |
120 | ||
121 | /* | |
122 | * XPath: /frr-ripngd:ripngd/instance/allow-ecmp | |
123 | */ | |
124 | int ripngd_instance_allow_ecmp_modify(struct nb_cb_modify_args *args) | |
125 | { | |
126 | struct ripng *ripng; | |
127 | ||
128 | if (args->event != NB_EV_APPLY) | |
129 | return NB_OK; | |
130 | ||
131 | ripng = nb_running_get_entry(args->dnode, NULL, true); | |
132 | ripng->ecmp = | |
133 | MIN(yang_dnode_get_uint8(args->dnode, NULL), zebra_ecmp_count); | |
134 | if (!ripng->ecmp) { | |
135 | ripng_ecmp_disable(ripng); | |
136 | return NB_OK; | |
137 | } | |
138 | ||
139 | ripng_ecmp_change(ripng); | |
140 | ||
141 | return NB_OK; | |
142 | } | |
143 | ||
144 | /* | |
145 | * XPath: /frr-ripngd:ripngd/instance/default-information-originate | |
146 | */ | |
147 | int ripngd_instance_default_information_originate_modify( | |
148 | struct nb_cb_modify_args *args) | |
149 | { | |
150 | struct ripng *ripng; | |
151 | bool default_information; | |
152 | struct prefix_ipv6 p; | |
153 | ||
154 | if (args->event != NB_EV_APPLY) | |
155 | return NB_OK; | |
156 | ||
157 | ripng = nb_running_get_entry(args->dnode, NULL, true); | |
158 | default_information = yang_dnode_get_bool(args->dnode, NULL); | |
159 | ||
160 | (void)str2prefix_ipv6("::/0", &p); | |
161 | if (default_information) { | |
162 | ripng_redistribute_add(ripng, ZEBRA_ROUTE_RIPNG, | |
163 | RIPNG_ROUTE_DEFAULT, &p, 0, NULL, 0); | |
164 | } else { | |
165 | ripng_redistribute_delete(ripng, ZEBRA_ROUTE_RIPNG, | |
166 | RIPNG_ROUTE_DEFAULT, &p, 0); | |
167 | } | |
168 | ||
169 | return NB_OK; | |
170 | } | |
171 | ||
172 | /* | |
173 | * XPath: /frr-ripngd:ripngd/instance/default-metric | |
174 | */ | |
175 | int ripngd_instance_default_metric_modify(struct nb_cb_modify_args *args) | |
176 | { | |
177 | struct ripng *ripng; | |
178 | ||
179 | if (args->event != NB_EV_APPLY) | |
180 | return NB_OK; | |
181 | ||
182 | ripng = nb_running_get_entry(args->dnode, NULL, true); | |
183 | ripng->default_metric = yang_dnode_get_uint8(args->dnode, NULL); | |
184 | ||
185 | return NB_OK; | |
186 | } | |
187 | ||
188 | /* | |
189 | * XPath: /frr-ripngd:ripngd/instance/network | |
190 | */ | |
191 | int ripngd_instance_network_create(struct nb_cb_create_args *args) | |
192 | { | |
193 | struct ripng *ripng; | |
194 | struct prefix p; | |
195 | ||
196 | if (args->event != NB_EV_APPLY) | |
197 | return NB_OK; | |
198 | ||
199 | ripng = nb_running_get_entry(args->dnode, NULL, true); | |
200 | yang_dnode_get_ipv6p(&p, args->dnode, NULL); | |
201 | apply_mask_ipv6((struct prefix_ipv6 *)&p); | |
202 | ||
203 | return ripng_enable_network_add(ripng, &p); | |
204 | } | |
205 | ||
206 | int ripngd_instance_network_destroy(struct nb_cb_destroy_args *args) | |
207 | { | |
208 | struct ripng *ripng; | |
209 | struct prefix p; | |
210 | ||
211 | if (args->event != NB_EV_APPLY) | |
212 | return NB_OK; | |
213 | ||
214 | ripng = nb_running_get_entry(args->dnode, NULL, true); | |
215 | yang_dnode_get_ipv6p(&p, args->dnode, NULL); | |
216 | apply_mask_ipv6((struct prefix_ipv6 *)&p); | |
217 | ||
218 | return ripng_enable_network_delete(ripng, &p); | |
219 | } | |
220 | ||
221 | /* | |
222 | * XPath: /frr-ripngd:ripngd/instance/interface | |
223 | */ | |
224 | int ripngd_instance_interface_create(struct nb_cb_create_args *args) | |
225 | { | |
226 | struct ripng *ripng; | |
227 | const char *ifname; | |
228 | ||
229 | if (args->event != NB_EV_APPLY) | |
230 | return NB_OK; | |
231 | ||
232 | ripng = nb_running_get_entry(args->dnode, NULL, true); | |
233 | ifname = yang_dnode_get_string(args->dnode, NULL); | |
234 | ||
235 | return ripng_enable_if_add(ripng, ifname); | |
236 | } | |
237 | ||
238 | int ripngd_instance_interface_destroy(struct nb_cb_destroy_args *args) | |
239 | { | |
240 | struct ripng *ripng; | |
241 | const char *ifname; | |
242 | ||
243 | if (args->event != NB_EV_APPLY) | |
244 | return NB_OK; | |
245 | ||
246 | ripng = nb_running_get_entry(args->dnode, NULL, true); | |
247 | ifname = yang_dnode_get_string(args->dnode, NULL); | |
248 | ||
249 | return ripng_enable_if_delete(ripng, ifname); | |
250 | } | |
251 | ||
252 | /* | |
253 | * XPath: /frr-ripngd:ripngd/instance/offset-list | |
254 | */ | |
255 | int ripngd_instance_offset_list_create(struct nb_cb_create_args *args) | |
256 | { | |
257 | struct ripng *ripng; | |
258 | const char *ifname; | |
259 | struct ripng_offset_list *offset; | |
260 | ||
261 | if (args->event != NB_EV_APPLY) | |
262 | return NB_OK; | |
263 | ||
264 | ripng = nb_running_get_entry(args->dnode, NULL, true); | |
265 | ifname = yang_dnode_get_string(args->dnode, "./interface"); | |
266 | ||
267 | offset = ripng_offset_list_new(ripng, ifname); | |
268 | nb_running_set_entry(args->dnode, offset); | |
269 | ||
270 | return NB_OK; | |
271 | } | |
272 | ||
273 | int ripngd_instance_offset_list_destroy(struct nb_cb_destroy_args *args) | |
274 | { | |
275 | int direct; | |
276 | struct ripng_offset_list *offset; | |
277 | ||
278 | if (args->event != NB_EV_APPLY) | |
279 | return NB_OK; | |
280 | ||
281 | direct = yang_dnode_get_enum(args->dnode, "./direction"); | |
282 | ||
283 | offset = nb_running_unset_entry(args->dnode); | |
284 | if (offset->direct[direct].alist_name) { | |
285 | free(offset->direct[direct].alist_name); | |
286 | offset->direct[direct].alist_name = NULL; | |
287 | } | |
288 | if (offset->direct[RIPNG_OFFSET_LIST_IN].alist_name == NULL | |
289 | && offset->direct[RIPNG_OFFSET_LIST_OUT].alist_name == NULL) | |
290 | ripng_offset_list_del(offset); | |
291 | ||
292 | return NB_OK; | |
293 | } | |
294 | ||
295 | /* | |
296 | * XPath: /frr-ripngd:ripngd/instance/offset-list/access-list | |
297 | */ | |
298 | int ripngd_instance_offset_list_access_list_modify( | |
299 | struct nb_cb_modify_args *args) | |
300 | { | |
301 | int direct; | |
302 | struct ripng_offset_list *offset; | |
303 | const char *alist_name; | |
304 | ||
305 | if (args->event != NB_EV_APPLY) | |
306 | return NB_OK; | |
307 | ||
308 | direct = yang_dnode_get_enum(args->dnode, "../direction"); | |
309 | alist_name = yang_dnode_get_string(args->dnode, NULL); | |
310 | ||
311 | offset = nb_running_get_entry(args->dnode, NULL, true); | |
312 | if (offset->direct[direct].alist_name) | |
313 | free(offset->direct[direct].alist_name); | |
314 | offset->direct[direct].alist_name = strdup(alist_name); | |
315 | ||
316 | return NB_OK; | |
317 | } | |
318 | ||
319 | /* | |
320 | * XPath: /frr-ripngd:ripngd/instance/offset-list/metric | |
321 | */ | |
322 | int ripngd_instance_offset_list_metric_modify(struct nb_cb_modify_args *args) | |
323 | { | |
324 | int direct; | |
325 | uint8_t metric; | |
326 | struct ripng_offset_list *offset; | |
327 | ||
328 | if (args->event != NB_EV_APPLY) | |
329 | return NB_OK; | |
330 | ||
331 | direct = yang_dnode_get_enum(args->dnode, "../direction"); | |
332 | metric = yang_dnode_get_uint8(args->dnode, NULL); | |
333 | ||
334 | offset = nb_running_get_entry(args->dnode, NULL, true); | |
335 | offset->direct[direct].metric = metric; | |
336 | ||
337 | return NB_OK; | |
338 | } | |
339 | ||
340 | /* | |
341 | * XPath: /frr-ripngd:ripngd/instance/passive-interface | |
342 | */ | |
343 | int ripngd_instance_passive_interface_create(struct nb_cb_create_args *args) | |
344 | { | |
345 | struct ripng *ripng; | |
346 | const char *ifname; | |
347 | ||
348 | if (args->event != NB_EV_APPLY) | |
349 | return NB_OK; | |
350 | ||
351 | ripng = nb_running_get_entry(args->dnode, NULL, true); | |
352 | ifname = yang_dnode_get_string(args->dnode, NULL); | |
353 | ||
354 | return ripng_passive_interface_set(ripng, ifname); | |
355 | } | |
356 | ||
357 | int ripngd_instance_passive_interface_destroy(struct nb_cb_destroy_args *args) | |
358 | { | |
359 | struct ripng *ripng; | |
360 | const char *ifname; | |
361 | ||
362 | if (args->event != NB_EV_APPLY) | |
363 | return NB_OK; | |
364 | ||
365 | ripng = nb_running_get_entry(args->dnode, NULL, true); | |
366 | ifname = yang_dnode_get_string(args->dnode, NULL); | |
367 | ||
368 | return ripng_passive_interface_unset(ripng, ifname); | |
369 | } | |
370 | ||
371 | /* | |
372 | * XPath: /frr-ripngd:ripngd/instance/redistribute | |
373 | */ | |
374 | int ripngd_instance_redistribute_create(struct nb_cb_create_args *args) | |
375 | { | |
376 | struct ripng *ripng; | |
377 | int type; | |
378 | ||
379 | if (args->event != NB_EV_APPLY) | |
380 | return NB_OK; | |
381 | ||
382 | ripng = nb_running_get_entry(args->dnode, NULL, true); | |
383 | type = yang_dnode_get_enum(args->dnode, "./protocol"); | |
384 | ||
385 | ripng->redist[type].enabled = true; | |
386 | ||
387 | return NB_OK; | |
388 | } | |
389 | ||
390 | int ripngd_instance_redistribute_destroy(struct nb_cb_destroy_args *args) | |
391 | { | |
392 | struct ripng *ripng; | |
393 | int type; | |
394 | ||
395 | if (args->event != NB_EV_APPLY) | |
396 | return NB_OK; | |
397 | ||
398 | ripng = nb_running_get_entry(args->dnode, NULL, true); | |
399 | type = yang_dnode_get_enum(args->dnode, "./protocol"); | |
400 | ||
401 | ripng->redist[type].enabled = false; | |
402 | if (ripng->redist[type].route_map.name) { | |
403 | free(ripng->redist[type].route_map.name); | |
404 | ripng->redist[type].route_map.name = NULL; | |
405 | ripng->redist[type].route_map.map = NULL; | |
406 | } | |
407 | ripng->redist[type].metric_config = false; | |
408 | ripng->redist[type].metric = 0; | |
409 | ||
410 | if (ripng->enabled) | |
411 | ripng_redistribute_conf_delete(ripng, type); | |
412 | ||
413 | return NB_OK; | |
414 | } | |
415 | ||
416 | void ripngd_instance_redistribute_apply_finish( | |
417 | struct nb_cb_apply_finish_args *args) | |
418 | { | |
419 | struct ripng *ripng; | |
420 | int type; | |
421 | ||
422 | ripng = nb_running_get_entry(args->dnode, NULL, true); | |
423 | type = yang_dnode_get_enum(args->dnode, "./protocol"); | |
424 | ||
425 | if (ripng->enabled) | |
426 | ripng_redistribute_conf_update(ripng, type); | |
427 | } | |
428 | ||
429 | /* | |
430 | * XPath: /frr-ripngd:ripngd/instance/redistribute/route-map | |
431 | */ | |
432 | int ripngd_instance_redistribute_route_map_modify( | |
433 | struct nb_cb_modify_args *args) | |
434 | { | |
435 | struct ripng *ripng; | |
436 | int type; | |
437 | const char *rmap_name; | |
438 | ||
439 | if (args->event != NB_EV_APPLY) | |
440 | return NB_OK; | |
441 | ||
442 | ripng = nb_running_get_entry(args->dnode, NULL, true); | |
443 | type = yang_dnode_get_enum(args->dnode, "../protocol"); | |
444 | rmap_name = yang_dnode_get_string(args->dnode, NULL); | |
445 | ||
446 | if (ripng->redist[type].route_map.name) | |
447 | free(ripng->redist[type].route_map.name); | |
448 | ripng->redist[type].route_map.name = strdup(rmap_name); | |
449 | ripng->redist[type].route_map.map = route_map_lookup_by_name(rmap_name); | |
450 | ||
451 | return NB_OK; | |
452 | } | |
453 | ||
454 | int ripngd_instance_redistribute_route_map_destroy( | |
455 | struct nb_cb_destroy_args *args) | |
456 | { | |
457 | struct ripng *ripng; | |
458 | int type; | |
459 | ||
460 | if (args->event != NB_EV_APPLY) | |
461 | return NB_OK; | |
462 | ||
463 | ripng = nb_running_get_entry(args->dnode, NULL, true); | |
464 | type = yang_dnode_get_enum(args->dnode, "../protocol"); | |
465 | ||
466 | free(ripng->redist[type].route_map.name); | |
467 | ripng->redist[type].route_map.name = NULL; | |
468 | ripng->redist[type].route_map.map = NULL; | |
469 | ||
470 | return NB_OK; | |
471 | } | |
472 | ||
473 | /* | |
474 | * XPath: /frr-ripngd:ripngd/instance/redistribute/metric | |
475 | */ | |
476 | int ripngd_instance_redistribute_metric_modify(struct nb_cb_modify_args *args) | |
477 | { | |
478 | struct ripng *ripng; | |
479 | int type; | |
480 | uint8_t metric; | |
481 | ||
482 | if (args->event != NB_EV_APPLY) | |
483 | return NB_OK; | |
484 | ||
485 | ripng = nb_running_get_entry(args->dnode, NULL, true); | |
486 | type = yang_dnode_get_enum(args->dnode, "../protocol"); | |
487 | metric = yang_dnode_get_uint8(args->dnode, NULL); | |
488 | ||
489 | ripng->redist[type].metric_config = true; | |
490 | ripng->redist[type].metric = metric; | |
491 | ||
492 | return NB_OK; | |
493 | } | |
494 | ||
495 | int ripngd_instance_redistribute_metric_destroy(struct nb_cb_destroy_args *args) | |
496 | { | |
497 | struct ripng *ripng; | |
498 | int type; | |
499 | ||
500 | if (args->event != NB_EV_APPLY) | |
501 | return NB_OK; | |
502 | ||
503 | ripng = nb_running_get_entry(args->dnode, NULL, true); | |
504 | type = yang_dnode_get_enum(args->dnode, "../protocol"); | |
505 | ||
506 | ripng->redist[type].metric_config = false; | |
507 | ripng->redist[type].metric = 0; | |
508 | ||
509 | return NB_OK; | |
510 | } | |
511 | ||
512 | /* | |
513 | * XPath: /frr-ripngd:ripngd/instance/if-route-maps/if-route-map | |
514 | */ | |
515 | int ripngd_instance_if_route_maps_if_route_map_create( | |
516 | struct nb_cb_create_args *args) | |
517 | { | |
518 | /* if_rmap is created when first routemap is added */ | |
519 | return NB_OK; | |
520 | } | |
521 | ||
522 | int ripngd_instance_if_route_maps_if_route_map_destroy( | |
523 | struct nb_cb_destroy_args *args) | |
524 | { | |
525 | struct ripng *ripng; | |
526 | ||
527 | if (args->event != NB_EV_APPLY) | |
528 | return NB_OK; | |
529 | ||
530 | /* | |
531 | * YANG will prune edit deletes up to the most general deleted node so | |
532 | * we need to handle deleting any existing state underneath and not | |
533 | * count on those more specific callbacks being called individually. | |
534 | */ | |
535 | ||
536 | ripng = nb_running_get_entry(args->dnode, NULL, true); | |
537 | if_rmap_yang_destroy_cb(ripng->if_rmap_ctx, args->dnode); | |
538 | ||
539 | return NB_OK; | |
540 | } | |
541 | ||
542 | static void if_route_map_modify(const struct lyd_node *dnode, | |
543 | enum if_rmap_type type, bool delete) | |
544 | { | |
545 | struct ripng *ripng = nb_running_get_entry(dnode, NULL, true); | |
546 | ||
547 | if_rmap_yang_modify_cb(ripng->if_rmap_ctx, dnode, type, delete); | |
548 | } | |
549 | /* | |
550 | * XPath: /frr-ripng:ripng/instance/if-route-maps/if-route-map/in-route-map | |
551 | */ | |
552 | int ripngd_instance_if_route_maps_if_route_map_in_route_map_modify( | |
553 | struct nb_cb_modify_args *args) | |
554 | { | |
555 | if (args->event != NB_EV_APPLY) | |
556 | return NB_OK; | |
557 | ||
558 | if_route_map_modify(args->dnode, IF_RMAP_IN, false); | |
559 | ||
560 | return NB_OK; | |
561 | } | |
562 | ||
563 | int ripngd_instance_if_route_maps_if_route_map_in_route_map_destroy( | |
564 | struct nb_cb_destroy_args *args) | |
565 | { | |
566 | if (args->event != NB_EV_APPLY) | |
567 | return NB_OK; | |
568 | ||
569 | if_route_map_modify(args->dnode, IF_RMAP_IN, true); | |
570 | ||
571 | return NB_OK; | |
572 | } | |
573 | ||
574 | /* | |
575 | * XPath: /frr-ripngd:ripngd/instance/if-route-maps/if-route-map/out-route-map | |
576 | */ | |
577 | int ripngd_instance_if_route_maps_if_route_map_out_route_map_modify( | |
578 | struct nb_cb_modify_args *args) | |
579 | { | |
580 | if (args->event != NB_EV_APPLY) | |
581 | return NB_OK; | |
582 | ||
583 | if_route_map_modify(args->dnode, IF_RMAP_OUT, false); | |
584 | ||
585 | return NB_OK; | |
586 | } | |
587 | ||
588 | int ripngd_instance_if_route_maps_if_route_map_out_route_map_destroy( | |
589 | struct nb_cb_destroy_args *args) | |
590 | { | |
591 | if (args->event != NB_EV_APPLY) | |
592 | return NB_OK; | |
593 | ||
594 | if_route_map_modify(args->dnode, IF_RMAP_OUT, true); | |
595 | ||
596 | return NB_OK; | |
597 | } | |
598 | ||
599 | /* | |
600 | * XPath: /frr-ripngd:ripngd/instance/static-route | |
601 | */ | |
602 | int ripngd_instance_static_route_create(struct nb_cb_create_args *args) | |
603 | { | |
604 | struct ripng *ripng; | |
605 | struct prefix_ipv6 p; | |
606 | ||
607 | if (args->event != NB_EV_APPLY) | |
608 | return NB_OK; | |
609 | ||
610 | ripng = nb_running_get_entry(args->dnode, NULL, true); | |
611 | yang_dnode_get_ipv6p(&p, args->dnode, NULL); | |
612 | apply_mask_ipv6(&p); | |
613 | ||
614 | ripng_redistribute_add(ripng, ZEBRA_ROUTE_RIPNG, RIPNG_ROUTE_STATIC, &p, | |
615 | 0, NULL, 0); | |
616 | ||
617 | return NB_OK; | |
618 | } | |
619 | ||
620 | int ripngd_instance_static_route_destroy(struct nb_cb_destroy_args *args) | |
621 | { | |
622 | struct ripng *ripng; | |
623 | struct prefix_ipv6 p; | |
624 | ||
625 | if (args->event != NB_EV_APPLY) | |
626 | return NB_OK; | |
627 | ||
628 | ripng = nb_running_get_entry(args->dnode, NULL, true); | |
629 | yang_dnode_get_ipv6p(&p, args->dnode, NULL); | |
630 | apply_mask_ipv6(&p); | |
631 | ||
632 | ripng_redistribute_delete(ripng, ZEBRA_ROUTE_RIPNG, RIPNG_ROUTE_STATIC, | |
633 | &p, 0); | |
634 | ||
635 | return NB_OK; | |
636 | } | |
637 | ||
638 | /* | |
639 | * XPath: /frr-ripngd:ripngd/instance/aggregate-address | |
640 | */ | |
641 | int ripngd_instance_aggregate_address_create(struct nb_cb_create_args *args) | |
642 | { | |
643 | struct ripng *ripng; | |
644 | struct prefix_ipv6 p; | |
645 | ||
646 | if (args->event != NB_EV_APPLY) | |
647 | return NB_OK; | |
648 | ||
649 | ripng = nb_running_get_entry(args->dnode, NULL, true); | |
650 | yang_dnode_get_ipv6p(&p, args->dnode, NULL); | |
651 | apply_mask_ipv6(&p); | |
652 | ||
653 | ripng_aggregate_add(ripng, (struct prefix *)&p); | |
654 | ||
655 | return NB_OK; | |
656 | } | |
657 | ||
658 | int ripngd_instance_aggregate_address_destroy(struct nb_cb_destroy_args *args) | |
659 | { | |
660 | struct ripng *ripng; | |
661 | struct prefix_ipv6 p; | |
662 | ||
663 | if (args->event != NB_EV_APPLY) | |
664 | return NB_OK; | |
665 | ||
666 | ripng = nb_running_get_entry(args->dnode, NULL, true); | |
667 | yang_dnode_get_ipv6p(&p, args->dnode, NULL); | |
668 | apply_mask_ipv6(&p); | |
669 | ||
670 | ripng_aggregate_delete(ripng, (struct prefix *)&p); | |
671 | ||
672 | return NB_OK; | |
673 | } | |
674 | ||
675 | /* | |
676 | * XPath: /frr-ripngd:ripngd/instance/timers | |
677 | */ | |
678 | void ripngd_instance_timers_apply_finish(struct nb_cb_apply_finish_args *args) | |
679 | { | |
680 | struct ripng *ripng; | |
681 | ||
682 | ripng = nb_running_get_entry(args->dnode, NULL, true); | |
683 | ||
684 | /* Reset update timer thread. */ | |
685 | ripng_event(ripng, RIPNG_UPDATE_EVENT, 0); | |
686 | } | |
687 | ||
688 | /* | |
689 | * XPath: /frr-ripngd:ripngd/instance/timers/flush-interval | |
690 | */ | |
691 | int ripngd_instance_timers_flush_interval_modify(struct nb_cb_modify_args *args) | |
692 | { | |
693 | struct ripng *ripng; | |
694 | ||
695 | if (args->event != NB_EV_APPLY) | |
696 | return NB_OK; | |
697 | ||
698 | ripng = nb_running_get_entry(args->dnode, NULL, true); | |
699 | ripng->garbage_time = yang_dnode_get_uint16(args->dnode, NULL); | |
700 | ||
701 | return NB_OK; | |
702 | } | |
703 | ||
704 | /* | |
705 | * XPath: /frr-ripngd:ripngd/instance/timers/holddown-interval | |
706 | */ | |
707 | int ripngd_instance_timers_holddown_interval_modify( | |
708 | struct nb_cb_modify_args *args) | |
709 | { | |
710 | struct ripng *ripng; | |
711 | ||
712 | if (args->event != NB_EV_APPLY) | |
713 | return NB_OK; | |
714 | ||
715 | ripng = nb_running_get_entry(args->dnode, NULL, true); | |
716 | ripng->timeout_time = yang_dnode_get_uint16(args->dnode, NULL); | |
717 | ||
718 | return NB_OK; | |
719 | } | |
720 | ||
721 | /* | |
722 | * XPath: /frr-ripngd:ripngd/instance/timers/update-interval | |
723 | */ | |
724 | int ripngd_instance_timers_update_interval_modify( | |
725 | struct nb_cb_modify_args *args) | |
726 | { | |
727 | struct ripng *ripng; | |
728 | ||
729 | if (args->event != NB_EV_APPLY) | |
730 | return NB_OK; | |
731 | ||
732 | ripng = nb_running_get_entry(args->dnode, NULL, true); | |
733 | ripng->update_time = yang_dnode_get_uint16(args->dnode, NULL); | |
734 | ||
735 | return NB_OK; | |
736 | } | |
737 | ||
738 | /* | |
739 | * XPath: /frr-interface:lib/interface/frr-ripngd:ripng/split-horizon | |
740 | */ | |
741 | int lib_interface_ripng_split_horizon_modify(struct nb_cb_modify_args *args) | |
742 | { | |
743 | struct interface *ifp; | |
744 | struct ripng_interface *ri; | |
745 | ||
746 | if (args->event != NB_EV_APPLY) | |
747 | return NB_OK; | |
748 | ||
749 | ifp = nb_running_get_entry(args->dnode, NULL, true); | |
750 | ri = ifp->info; | |
751 | ri->split_horizon = yang_dnode_get_enum(args->dnode, NULL); | |
752 | ||
753 | return NB_OK; | |
754 | } |