]>
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);
132 ripng
->ecmp
= yang_dnode_get_bool(args
->dnode
, NULL
);
134 ripng_ecmp_disable(ripng
);
140 * XPath: /frr-ripngd:ripngd/instance/default-information-originate
142 int ripngd_instance_default_information_originate_modify(
143 struct nb_cb_modify_args
*args
)
146 bool default_information
;
147 struct prefix_ipv6 p
;
149 if (args
->event
!= NB_EV_APPLY
)
152 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
153 default_information
= yang_dnode_get_bool(args
->dnode
, NULL
);
155 (void)str2prefix_ipv6("::/0", &p
);
156 if (default_information
) {
157 ripng_redistribute_add(ripng
, ZEBRA_ROUTE_RIPNG
,
158 RIPNG_ROUTE_DEFAULT
, &p
, 0, NULL
, 0);
160 ripng_redistribute_delete(ripng
, ZEBRA_ROUTE_RIPNG
,
161 RIPNG_ROUTE_DEFAULT
, &p
, 0);
168 * XPath: /frr-ripngd:ripngd/instance/default-metric
170 int ripngd_instance_default_metric_modify(struct nb_cb_modify_args
*args
)
174 if (args
->event
!= NB_EV_APPLY
)
177 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
178 ripng
->default_metric
= yang_dnode_get_uint8(args
->dnode
, NULL
);
184 * XPath: /frr-ripngd:ripngd/instance/network
186 int ripngd_instance_network_create(struct nb_cb_create_args
*args
)
191 if (args
->event
!= NB_EV_APPLY
)
194 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
195 yang_dnode_get_ipv6p(&p
, args
->dnode
, NULL
);
196 apply_mask_ipv6((struct prefix_ipv6
*)&p
);
198 return ripng_enable_network_add(ripng
, &p
);
201 int ripngd_instance_network_destroy(struct nb_cb_destroy_args
*args
)
206 if (args
->event
!= NB_EV_APPLY
)
209 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
210 yang_dnode_get_ipv6p(&p
, args
->dnode
, NULL
);
211 apply_mask_ipv6((struct prefix_ipv6
*)&p
);
213 return ripng_enable_network_delete(ripng
, &p
);
217 * XPath: /frr-ripngd:ripngd/instance/interface
219 int ripngd_instance_interface_create(struct nb_cb_create_args
*args
)
224 if (args
->event
!= NB_EV_APPLY
)
227 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
228 ifname
= yang_dnode_get_string(args
->dnode
, NULL
);
230 return ripng_enable_if_add(ripng
, ifname
);
233 int ripngd_instance_interface_destroy(struct nb_cb_destroy_args
*args
)
238 if (args
->event
!= NB_EV_APPLY
)
241 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
242 ifname
= yang_dnode_get_string(args
->dnode
, NULL
);
244 return ripng_enable_if_delete(ripng
, ifname
);
248 * XPath: /frr-ripngd:ripngd/instance/offset-list
250 int ripngd_instance_offset_list_create(struct nb_cb_create_args
*args
)
254 struct ripng_offset_list
*offset
;
256 if (args
->event
!= NB_EV_APPLY
)
259 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
260 ifname
= yang_dnode_get_string(args
->dnode
, "./interface");
262 offset
= ripng_offset_list_new(ripng
, ifname
);
263 nb_running_set_entry(args
->dnode
, offset
);
268 int ripngd_instance_offset_list_destroy(struct nb_cb_destroy_args
*args
)
271 struct ripng_offset_list
*offset
;
273 if (args
->event
!= NB_EV_APPLY
)
276 direct
= yang_dnode_get_enum(args
->dnode
, "./direction");
278 offset
= nb_running_unset_entry(args
->dnode
);
279 if (offset
->direct
[direct
].alist_name
) {
280 free(offset
->direct
[direct
].alist_name
);
281 offset
->direct
[direct
].alist_name
= NULL
;
283 if (offset
->direct
[RIPNG_OFFSET_LIST_IN
].alist_name
== NULL
284 && offset
->direct
[RIPNG_OFFSET_LIST_OUT
].alist_name
== NULL
)
285 ripng_offset_list_del(offset
);
291 * XPath: /frr-ripngd:ripngd/instance/offset-list/access-list
293 int ripngd_instance_offset_list_access_list_modify(
294 struct nb_cb_modify_args
*args
)
297 struct ripng_offset_list
*offset
;
298 const char *alist_name
;
300 if (args
->event
!= NB_EV_APPLY
)
303 direct
= yang_dnode_get_enum(args
->dnode
, "../direction");
304 alist_name
= yang_dnode_get_string(args
->dnode
, NULL
);
306 offset
= nb_running_get_entry(args
->dnode
, NULL
, true);
307 if (offset
->direct
[direct
].alist_name
)
308 free(offset
->direct
[direct
].alist_name
);
309 offset
->direct
[direct
].alist_name
= strdup(alist_name
);
315 * XPath: /frr-ripngd:ripngd/instance/offset-list/metric
317 int ripngd_instance_offset_list_metric_modify(struct nb_cb_modify_args
*args
)
321 struct ripng_offset_list
*offset
;
323 if (args
->event
!= NB_EV_APPLY
)
326 direct
= yang_dnode_get_enum(args
->dnode
, "../direction");
327 metric
= yang_dnode_get_uint8(args
->dnode
, NULL
);
329 offset
= nb_running_get_entry(args
->dnode
, NULL
, true);
330 offset
->direct
[direct
].metric
= metric
;
336 * XPath: /frr-ripngd:ripngd/instance/passive-interface
338 int ripngd_instance_passive_interface_create(struct nb_cb_create_args
*args
)
343 if (args
->event
!= NB_EV_APPLY
)
346 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
347 ifname
= yang_dnode_get_string(args
->dnode
, NULL
);
349 return ripng_passive_interface_set(ripng
, ifname
);
352 int ripngd_instance_passive_interface_destroy(struct nb_cb_destroy_args
*args
)
357 if (args
->event
!= NB_EV_APPLY
)
360 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
361 ifname
= yang_dnode_get_string(args
->dnode
, NULL
);
363 return ripng_passive_interface_unset(ripng
, ifname
);
367 * XPath: /frr-ripngd:ripngd/instance/redistribute
369 int ripngd_instance_redistribute_create(struct nb_cb_create_args
*args
)
374 if (args
->event
!= NB_EV_APPLY
)
377 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
378 type
= yang_dnode_get_enum(args
->dnode
, "./protocol");
380 ripng
->redist
[type
].enabled
= true;
385 int ripngd_instance_redistribute_destroy(struct nb_cb_destroy_args
*args
)
390 if (args
->event
!= NB_EV_APPLY
)
393 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
394 type
= yang_dnode_get_enum(args
->dnode
, "./protocol");
396 ripng
->redist
[type
].enabled
= false;
397 if (ripng
->redist
[type
].route_map
.name
) {
398 free(ripng
->redist
[type
].route_map
.name
);
399 ripng
->redist
[type
].route_map
.name
= NULL
;
400 ripng
->redist
[type
].route_map
.map
= NULL
;
402 ripng
->redist
[type
].metric_config
= false;
403 ripng
->redist
[type
].metric
= 0;
406 ripng_redistribute_conf_delete(ripng
, type
);
411 void ripngd_instance_redistribute_apply_finish(
412 struct nb_cb_apply_finish_args
*args
)
417 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
418 type
= yang_dnode_get_enum(args
->dnode
, "./protocol");
421 ripng_redistribute_conf_update(ripng
, type
);
425 * XPath: /frr-ripngd:ripngd/instance/redistribute/route-map
427 int ripngd_instance_redistribute_route_map_modify(
428 struct nb_cb_modify_args
*args
)
432 const char *rmap_name
;
434 if (args
->event
!= NB_EV_APPLY
)
437 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
438 type
= yang_dnode_get_enum(args
->dnode
, "../protocol");
439 rmap_name
= yang_dnode_get_string(args
->dnode
, NULL
);
441 if (ripng
->redist
[type
].route_map
.name
)
442 free(ripng
->redist
[type
].route_map
.name
);
443 ripng
->redist
[type
].route_map
.name
= strdup(rmap_name
);
444 ripng
->redist
[type
].route_map
.map
= route_map_lookup_by_name(rmap_name
);
449 int ripngd_instance_redistribute_route_map_destroy(
450 struct nb_cb_destroy_args
*args
)
455 if (args
->event
!= NB_EV_APPLY
)
458 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
459 type
= yang_dnode_get_enum(args
->dnode
, "../protocol");
461 free(ripng
->redist
[type
].route_map
.name
);
462 ripng
->redist
[type
].route_map
.name
= NULL
;
463 ripng
->redist
[type
].route_map
.map
= NULL
;
469 * XPath: /frr-ripngd:ripngd/instance/redistribute/metric
471 int ripngd_instance_redistribute_metric_modify(struct nb_cb_modify_args
*args
)
477 if (args
->event
!= NB_EV_APPLY
)
480 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
481 type
= yang_dnode_get_enum(args
->dnode
, "../protocol");
482 metric
= yang_dnode_get_uint8(args
->dnode
, NULL
);
484 ripng
->redist
[type
].metric_config
= true;
485 ripng
->redist
[type
].metric
= metric
;
490 int ripngd_instance_redistribute_metric_destroy(struct nb_cb_destroy_args
*args
)
495 if (args
->event
!= NB_EV_APPLY
)
498 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
499 type
= yang_dnode_get_enum(args
->dnode
, "../protocol");
501 ripng
->redist
[type
].metric_config
= false;
502 ripng
->redist
[type
].metric
= 0;
508 * XPath: /frr-ripngd:ripngd/instance/if-route-maps/if-route-map
510 int ripngd_instance_if_route_maps_if_route_map_create(
511 struct nb_cb_create_args
*args
)
513 /* if_rmap is created when first routemap is added */
517 int ripngd_instance_if_route_maps_if_route_map_destroy(
518 struct nb_cb_destroy_args
*args
)
522 if (args
->event
!= NB_EV_APPLY
)
526 * YANG will prune edit deletes up to the most general deleted node so
527 * we need to handle deleting any existing state underneath and not
528 * count on those more specific callbacks being called individually.
531 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
532 if_rmap_yang_destroy_cb(ripng
->if_rmap_ctx
, args
->dnode
);
537 static void if_route_map_modify(const struct lyd_node
*dnode
,
538 enum if_rmap_type type
, bool delete)
540 struct ripng
*ripng
= nb_running_get_entry(dnode
, NULL
, true);
542 if_rmap_yang_modify_cb(ripng
->if_rmap_ctx
, dnode
, type
, delete);
545 * XPath: /frr-ripng:ripng/instance/if-route-maps/if-route-map/in-route-map
547 int ripngd_instance_if_route_maps_if_route_map_in_route_map_modify(
548 struct nb_cb_modify_args
*args
)
550 if (args
->event
!= NB_EV_APPLY
)
553 if_route_map_modify(args
->dnode
, IF_RMAP_IN
, false);
558 int ripngd_instance_if_route_maps_if_route_map_in_route_map_destroy(
559 struct nb_cb_destroy_args
*args
)
561 if (args
->event
!= NB_EV_APPLY
)
564 if_route_map_modify(args
->dnode
, IF_RMAP_IN
, true);
570 * XPath: /frr-ripngd:ripngd/instance/if-route-maps/if-route-map/out-route-map
572 int ripngd_instance_if_route_maps_if_route_map_out_route_map_modify(
573 struct nb_cb_modify_args
*args
)
575 if (args
->event
!= NB_EV_APPLY
)
578 if_route_map_modify(args
->dnode
, IF_RMAP_OUT
, false);
583 int ripngd_instance_if_route_maps_if_route_map_out_route_map_destroy(
584 struct nb_cb_destroy_args
*args
)
586 if (args
->event
!= NB_EV_APPLY
)
589 if_route_map_modify(args
->dnode
, IF_RMAP_OUT
, true);
595 * XPath: /frr-ripngd:ripngd/instance/static-route
597 int ripngd_instance_static_route_create(struct nb_cb_create_args
*args
)
600 struct prefix_ipv6 p
;
602 if (args
->event
!= NB_EV_APPLY
)
605 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
606 yang_dnode_get_ipv6p(&p
, args
->dnode
, NULL
);
609 ripng_redistribute_add(ripng
, ZEBRA_ROUTE_RIPNG
, RIPNG_ROUTE_STATIC
, &p
,
615 int ripngd_instance_static_route_destroy(struct nb_cb_destroy_args
*args
)
618 struct prefix_ipv6 p
;
620 if (args
->event
!= NB_EV_APPLY
)
623 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
624 yang_dnode_get_ipv6p(&p
, args
->dnode
, NULL
);
627 ripng_redistribute_delete(ripng
, ZEBRA_ROUTE_RIPNG
, RIPNG_ROUTE_STATIC
,
634 * XPath: /frr-ripngd:ripngd/instance/aggregate-address
636 int ripngd_instance_aggregate_address_create(struct nb_cb_create_args
*args
)
639 struct prefix_ipv6 p
;
641 if (args
->event
!= NB_EV_APPLY
)
644 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
645 yang_dnode_get_ipv6p(&p
, args
->dnode
, NULL
);
648 ripng_aggregate_add(ripng
, (struct prefix
*)&p
);
653 int ripngd_instance_aggregate_address_destroy(struct nb_cb_destroy_args
*args
)
656 struct prefix_ipv6 p
;
658 if (args
->event
!= NB_EV_APPLY
)
661 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
662 yang_dnode_get_ipv6p(&p
, args
->dnode
, NULL
);
665 ripng_aggregate_delete(ripng
, (struct prefix
*)&p
);
671 * XPath: /frr-ripngd:ripngd/instance/timers
673 void ripngd_instance_timers_apply_finish(struct nb_cb_apply_finish_args
*args
)
677 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
679 /* Reset update timer thread. */
680 ripng_event(ripng
, RIPNG_UPDATE_EVENT
, 0);
684 * XPath: /frr-ripngd:ripngd/instance/timers/flush-interval
686 int ripngd_instance_timers_flush_interval_modify(struct nb_cb_modify_args
*args
)
690 if (args
->event
!= NB_EV_APPLY
)
693 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
694 ripng
->garbage_time
= yang_dnode_get_uint16(args
->dnode
, NULL
);
700 * XPath: /frr-ripngd:ripngd/instance/timers/holddown-interval
702 int ripngd_instance_timers_holddown_interval_modify(
703 struct nb_cb_modify_args
*args
)
707 if (args
->event
!= NB_EV_APPLY
)
710 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
711 ripng
->timeout_time
= yang_dnode_get_uint16(args
->dnode
, NULL
);
717 * XPath: /frr-ripngd:ripngd/instance/timers/update-interval
719 int ripngd_instance_timers_update_interval_modify(
720 struct nb_cb_modify_args
*args
)
724 if (args
->event
!= NB_EV_APPLY
)
727 ripng
= nb_running_get_entry(args
->dnode
, NULL
, true);
728 ripng
->update_time
= yang_dnode_get_uint16(args
->dnode
, NULL
);
734 * XPath: /frr-interface:lib/interface/frr-ripngd:ripng/split-horizon
736 int lib_interface_ripng_split_horizon_modify(struct nb_cb_modify_args
*args
)
738 struct interface
*ifp
;
739 struct ripng_interface
*ri
;
741 if (args
->event
!= NB_EV_APPLY
)
744 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
746 ri
->split_horizon
= yang_dnode_get_enum(args
->dnode
, NULL
);