]>
git.proxmox.com Git - mirror_frr.git/blob - ripngd/ripng_nb_config.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 1998 Kunihiro Ishiguro
4 * Copyright (C) 2018 NetDEF, Inc.
6 * Copyright (C) 2023 LabN Consulting, L.L.C.
19 #include "agg_table.h"
20 #include "northbound.h"
23 #include "ripngd/ripngd.h"
24 #include "ripngd/ripng_nb.h"
25 #include "ripngd/ripng_debug.h"
26 #include "ripngd/ripng_route.h"
29 * XPath: /frr-ripngd:ripngd/instance
31 int ripngd_instance_create(struct nb_cb_create_args
*args
)
38 vrf_name
= yang_dnode_get_string(args
->dnode
, "./vrf");
39 vrf
= vrf_lookup_by_name(vrf_name
);
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.
45 switch (args
->event
) {
49 if (!vrf
|| !vrf_is_enabled(vrf
))
52 socket
= ripng_make_socket(vrf
);
54 return NB_ERR_RESOURCE
;
55 args
->resource
->fd
= socket
;
58 if (!vrf
|| !vrf_is_enabled(vrf
))
61 socket
= args
->resource
->fd
;
65 if (vrf
&& vrf_is_enabled(vrf
))
66 socket
= args
->resource
->fd
;
70 ripng
= ripng_create(vrf_name
, vrf
, socket
);
71 nb_running_set_entry(args
->dnode
, ripng
);
78 int ripngd_instance_destroy(struct nb_cb_destroy_args
*args
)
82 if (args
->event
!= NB_EV_APPLY
)
85 ripng
= nb_running_unset_entry(args
->dnode
);
91 const void *ripngd_instance_get_next(struct nb_cb_get_next_args
*args
)
93 struct ripng
*ripng
= (struct ripng
*)args
->list_entry
;
95 if (args
->list_entry
== NULL
)
96 ripng
= RB_MIN(ripng_instance_head
, &ripng_instances
);
98 ripng
= RB_NEXT(ripng_instance_head
, ripng
);
103 int ripngd_instance_get_keys(struct nb_cb_get_keys_args
*args
)
105 const struct ripng
*ripng
= args
->list_entry
;
108 strlcpy(args
->keys
->key
[0], ripng
->vrf_name
,
109 sizeof(args
->keys
->key
[0]));
114 const void *ripngd_instance_lookup_entry(struct nb_cb_lookup_entry_args
*args
)
116 const char *vrf_name
= args
->keys
->key
[0];
118 return ripng_lookup_by_vrf_name(vrf_name
);
122 * XPath: /frr-ripngd:ripngd/instance/allow-ecmp
124 int ripngd_instance_allow_ecmp_modify(struct nb_cb_modify_args
*args
)
128 if (args
->event
!= NB_EV_APPLY
)
131 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
133 MIN(yang_dnode_get_uint8(args
->dnode
, NULL
), zebra_ecmp_count
);
135 ripng_ecmp_disable(ripng
);
139 ripng_ecmp_change(ripng
);
145 * XPath: /frr-ripngd:ripngd/instance/default-information-originate
147 int ripngd_instance_default_information_originate_modify(
148 struct nb_cb_modify_args
*args
)
151 bool default_information
;
152 struct prefix_ipv6 p
;
154 if (args
->event
!= NB_EV_APPLY
)
157 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
158 default_information
= yang_dnode_get_bool(args
->dnode
, NULL
);
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);
165 ripng_redistribute_delete(ripng
, ZEBRA_ROUTE_RIPNG
,
166 RIPNG_ROUTE_DEFAULT
, &p
, 0);
173 * XPath: /frr-ripngd:ripngd/instance/default-metric
175 int ripngd_instance_default_metric_modify(struct nb_cb_modify_args
*args
)
179 if (args
->event
!= NB_EV_APPLY
)
182 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
183 ripng
->default_metric
= yang_dnode_get_uint8(args
->dnode
, NULL
);
189 * XPath: /frr-ripngd:ripngd/instance/network
191 int ripngd_instance_network_create(struct nb_cb_create_args
*args
)
196 if (args
->event
!= NB_EV_APPLY
)
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
);
203 return ripng_enable_network_add(ripng
, &p
);
206 int ripngd_instance_network_destroy(struct nb_cb_destroy_args
*args
)
211 if (args
->event
!= NB_EV_APPLY
)
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
);
218 return ripng_enable_network_delete(ripng
, &p
);
222 * XPath: /frr-ripngd:ripngd/instance/interface
224 int ripngd_instance_interface_create(struct nb_cb_create_args
*args
)
229 if (args
->event
!= NB_EV_APPLY
)
232 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
233 ifname
= yang_dnode_get_string(args
->dnode
, NULL
);
235 return ripng_enable_if_add(ripng
, ifname
);
238 int ripngd_instance_interface_destroy(struct nb_cb_destroy_args
*args
)
243 if (args
->event
!= NB_EV_APPLY
)
246 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
247 ifname
= yang_dnode_get_string(args
->dnode
, NULL
);
249 return ripng_enable_if_delete(ripng
, ifname
);
253 * XPath: /frr-ripngd:ripngd/instance/offset-list
255 int ripngd_instance_offset_list_create(struct nb_cb_create_args
*args
)
259 struct ripng_offset_list
*offset
;
261 if (args
->event
!= NB_EV_APPLY
)
264 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
265 ifname
= yang_dnode_get_string(args
->dnode
, "./interface");
267 offset
= ripng_offset_list_new(ripng
, ifname
);
268 nb_running_set_entry(args
->dnode
, offset
);
273 int ripngd_instance_offset_list_destroy(struct nb_cb_destroy_args
*args
)
276 struct ripng_offset_list
*offset
;
278 if (args
->event
!= NB_EV_APPLY
)
281 direct
= yang_dnode_get_enum(args
->dnode
, "./direction");
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
;
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
);
296 * XPath: /frr-ripngd:ripngd/instance/offset-list/access-list
298 int ripngd_instance_offset_list_access_list_modify(
299 struct nb_cb_modify_args
*args
)
302 struct ripng_offset_list
*offset
;
303 const char *alist_name
;
305 if (args
->event
!= NB_EV_APPLY
)
308 direct
= yang_dnode_get_enum(args
->dnode
, "../direction");
309 alist_name
= yang_dnode_get_string(args
->dnode
, NULL
);
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
);
320 * XPath: /frr-ripngd:ripngd/instance/offset-list/metric
322 int ripngd_instance_offset_list_metric_modify(struct nb_cb_modify_args
*args
)
326 struct ripng_offset_list
*offset
;
328 if (args
->event
!= NB_EV_APPLY
)
331 direct
= yang_dnode_get_enum(args
->dnode
, "../direction");
332 metric
= yang_dnode_get_uint8(args
->dnode
, NULL
);
334 offset
= nb_running_get_entry(args
->dnode
, NULL
, true);
335 offset
->direct
[direct
].metric
= metric
;
341 * XPath: /frr-ripngd:ripngd/instance/passive-interface
343 int ripngd_instance_passive_interface_create(struct nb_cb_create_args
*args
)
348 if (args
->event
!= NB_EV_APPLY
)
351 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
352 ifname
= yang_dnode_get_string(args
->dnode
, NULL
);
354 return ripng_passive_interface_set(ripng
, ifname
);
357 int ripngd_instance_passive_interface_destroy(struct nb_cb_destroy_args
*args
)
362 if (args
->event
!= NB_EV_APPLY
)
365 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
366 ifname
= yang_dnode_get_string(args
->dnode
, NULL
);
368 return ripng_passive_interface_unset(ripng
, ifname
);
372 * XPath: /frr-ripngd:ripngd/instance/redistribute
374 int ripngd_instance_redistribute_create(struct nb_cb_create_args
*args
)
379 if (args
->event
!= NB_EV_APPLY
)
382 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
383 type
= yang_dnode_get_enum(args
->dnode
, "./protocol");
385 ripng
->redist
[type
].enabled
= true;
390 int ripngd_instance_redistribute_destroy(struct nb_cb_destroy_args
*args
)
395 if (args
->event
!= NB_EV_APPLY
)
398 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
399 type
= yang_dnode_get_enum(args
->dnode
, "./protocol");
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
;
407 ripng
->redist
[type
].metric_config
= false;
408 ripng
->redist
[type
].metric
= 0;
411 ripng_redistribute_conf_delete(ripng
, type
);
416 void ripngd_instance_redistribute_apply_finish(
417 struct nb_cb_apply_finish_args
*args
)
422 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
423 type
= yang_dnode_get_enum(args
->dnode
, "./protocol");
426 ripng_redistribute_conf_update(ripng
, type
);
430 * XPath: /frr-ripngd:ripngd/instance/redistribute/route-map
432 int ripngd_instance_redistribute_route_map_modify(
433 struct nb_cb_modify_args
*args
)
437 const char *rmap_name
;
439 if (args
->event
!= NB_EV_APPLY
)
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
);
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
);
454 int ripngd_instance_redistribute_route_map_destroy(
455 struct nb_cb_destroy_args
*args
)
460 if (args
->event
!= NB_EV_APPLY
)
463 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
464 type
= yang_dnode_get_enum(args
->dnode
, "../protocol");
466 free(ripng
->redist
[type
].route_map
.name
);
467 ripng
->redist
[type
].route_map
.name
= NULL
;
468 ripng
->redist
[type
].route_map
.map
= NULL
;
474 * XPath: /frr-ripngd:ripngd/instance/redistribute/metric
476 int ripngd_instance_redistribute_metric_modify(struct nb_cb_modify_args
*args
)
482 if (args
->event
!= NB_EV_APPLY
)
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
);
489 ripng
->redist
[type
].metric_config
= true;
490 ripng
->redist
[type
].metric
= metric
;
495 int ripngd_instance_redistribute_metric_destroy(struct nb_cb_destroy_args
*args
)
500 if (args
->event
!= NB_EV_APPLY
)
503 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
504 type
= yang_dnode_get_enum(args
->dnode
, "../protocol");
506 ripng
->redist
[type
].metric_config
= false;
507 ripng
->redist
[type
].metric
= 0;
513 * XPath: /frr-ripngd:ripngd/instance/if-route-maps/if-route-map
515 int ripngd_instance_if_route_maps_if_route_map_create(
516 struct nb_cb_create_args
*args
)
518 /* if_rmap is created when first routemap is added */
522 int ripngd_instance_if_route_maps_if_route_map_destroy(
523 struct nb_cb_destroy_args
*args
)
527 if (args
->event
!= NB_EV_APPLY
)
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.
536 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
537 if_rmap_yang_destroy_cb(ripng
->if_rmap_ctx
, args
->dnode
);
542 static void if_route_map_modify(const struct lyd_node
*dnode
,
543 enum if_rmap_type type
, bool delete)
545 struct ripng
*ripng
= nb_running_get_entry(dnode
, NULL
, true);
547 if_rmap_yang_modify_cb(ripng
->if_rmap_ctx
, dnode
, type
, delete);
550 * XPath: /frr-ripng:ripng/instance/if-route-maps/if-route-map/in-route-map
552 int ripngd_instance_if_route_maps_if_route_map_in_route_map_modify(
553 struct nb_cb_modify_args
*args
)
555 if (args
->event
!= NB_EV_APPLY
)
558 if_route_map_modify(args
->dnode
, IF_RMAP_IN
, false);
563 int ripngd_instance_if_route_maps_if_route_map_in_route_map_destroy(
564 struct nb_cb_destroy_args
*args
)
566 if (args
->event
!= NB_EV_APPLY
)
569 if_route_map_modify(args
->dnode
, IF_RMAP_IN
, true);
575 * XPath: /frr-ripngd:ripngd/instance/if-route-maps/if-route-map/out-route-map
577 int ripngd_instance_if_route_maps_if_route_map_out_route_map_modify(
578 struct nb_cb_modify_args
*args
)
580 if (args
->event
!= NB_EV_APPLY
)
583 if_route_map_modify(args
->dnode
, IF_RMAP_OUT
, false);
588 int ripngd_instance_if_route_maps_if_route_map_out_route_map_destroy(
589 struct nb_cb_destroy_args
*args
)
591 if (args
->event
!= NB_EV_APPLY
)
594 if_route_map_modify(args
->dnode
, IF_RMAP_OUT
, true);
600 * XPath: /frr-ripngd:ripngd/instance/static-route
602 int ripngd_instance_static_route_create(struct nb_cb_create_args
*args
)
605 struct prefix_ipv6 p
;
607 if (args
->event
!= NB_EV_APPLY
)
610 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
611 yang_dnode_get_ipv6p(&p
, args
->dnode
, NULL
);
614 ripng_redistribute_add(ripng
, ZEBRA_ROUTE_RIPNG
, RIPNG_ROUTE_STATIC
, &p
,
620 int ripngd_instance_static_route_destroy(struct nb_cb_destroy_args
*args
)
623 struct prefix_ipv6 p
;
625 if (args
->event
!= NB_EV_APPLY
)
628 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
629 yang_dnode_get_ipv6p(&p
, args
->dnode
, NULL
);
632 ripng_redistribute_delete(ripng
, ZEBRA_ROUTE_RIPNG
, RIPNG_ROUTE_STATIC
,
639 * XPath: /frr-ripngd:ripngd/instance/aggregate-address
641 int ripngd_instance_aggregate_address_create(struct nb_cb_create_args
*args
)
644 struct prefix_ipv6 p
;
646 if (args
->event
!= NB_EV_APPLY
)
649 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
650 yang_dnode_get_ipv6p(&p
, args
->dnode
, NULL
);
653 ripng_aggregate_add(ripng
, (struct prefix
*)&p
);
658 int ripngd_instance_aggregate_address_destroy(struct nb_cb_destroy_args
*args
)
661 struct prefix_ipv6 p
;
663 if (args
->event
!= NB_EV_APPLY
)
666 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
667 yang_dnode_get_ipv6p(&p
, args
->dnode
, NULL
);
670 ripng_aggregate_delete(ripng
, (struct prefix
*)&p
);
676 * XPath: /frr-ripngd:ripngd/instance/timers
678 void ripngd_instance_timers_apply_finish(struct nb_cb_apply_finish_args
*args
)
682 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
684 /* Reset update timer thread. */
685 ripng_event(ripng
, RIPNG_UPDATE_EVENT
, 0);
689 * XPath: /frr-ripngd:ripngd/instance/timers/flush-interval
691 int ripngd_instance_timers_flush_interval_modify(struct nb_cb_modify_args
*args
)
695 if (args
->event
!= NB_EV_APPLY
)
698 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
699 ripng
->garbage_time
= yang_dnode_get_uint16(args
->dnode
, NULL
);
705 * XPath: /frr-ripngd:ripngd/instance/timers/holddown-interval
707 int ripngd_instance_timers_holddown_interval_modify(
708 struct nb_cb_modify_args
*args
)
712 if (args
->event
!= NB_EV_APPLY
)
715 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
716 ripng
->timeout_time
= yang_dnode_get_uint16(args
->dnode
, NULL
);
722 * XPath: /frr-ripngd:ripngd/instance/timers/update-interval
724 int ripngd_instance_timers_update_interval_modify(
725 struct nb_cb_modify_args
*args
)
729 if (args
->event
!= NB_EV_APPLY
)
732 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
733 ripng
->update_time
= yang_dnode_get_uint16(args
->dnode
, NULL
);
739 * XPath: /frr-interface:lib/interface/frr-ripngd:ripng/split-horizon
741 int lib_interface_ripng_split_horizon_modify(struct nb_cb_modify_args
*args
)
743 struct interface
*ifp
;
744 struct ripng_interface
*ri
;
746 if (args
->event
!= NB_EV_APPLY
)
749 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
751 ri
->split_horizon
= yang_dnode_get_enum(args
->dnode
, NULL
);