2 * Copyright (C) 1998 Kunihiro Ishiguro
3 * Copyright (C) 2018 NetDEF, Inc.
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
30 #include "agg_table.h"
31 #include "northbound.h"
34 #include "ripngd/ripngd.h"
35 #include "ripngd/ripng_debug.h"
36 #include "ripngd/ripng_route.h"
37 #include "ripngd/ripng_cli.h"
40 * XPath: /frr-ripngd:ripngd/instance
42 static int ripngd_instance_create(enum nb_event event
,
43 const struct lyd_node
*dnode
,
44 union nb_resource
*resource
)
51 vrf_name
= yang_dnode_get_string(dnode
, "./vrf");
52 vrf
= vrf_lookup_by_name(vrf_name
);
55 * Try to create a RIPng socket only if the VRF is enabled, otherwise
56 * create a disabled RIPng instance and wait for the VRF to be enabled.
62 if (!vrf
|| !vrf_is_enabled(vrf
))
65 socket
= ripng_make_socket(vrf
);
67 return NB_ERR_RESOURCE
;
68 resource
->fd
= socket
;
71 if (!vrf
|| !vrf_is_enabled(vrf
))
74 socket
= resource
->fd
;
78 if (vrf
&& vrf_is_enabled(vrf
))
79 socket
= resource
->fd
;
83 ripng
= ripng_create(vrf_name
, vrf
, socket
);
84 nb_running_set_entry(dnode
, ripng
);
91 static int ripngd_instance_destroy(enum nb_event event
,
92 const struct lyd_node
*dnode
)
96 if (event
!= NB_EV_APPLY
)
99 ripng
= nb_running_unset_entry(dnode
);
105 static const void *ripngd_instance_get_next(const void *parent_list_entry
,
106 const void *list_entry
)
108 const struct ripng
*ripng
= list_entry
;
110 if (list_entry
== NULL
)
111 ripng
= RB_MIN(ripng_instance_head
, &ripng_instances
);
113 ripng
= RB_NEXT(ripng_instance_head
, (struct ripng
*)ripng
);
118 static int ripngd_instance_get_keys(const void *list_entry
,
119 struct yang_list_keys
*keys
)
121 const struct ripng
*ripng
= list_entry
;
124 strlcpy(keys
->key
[0], ripng
->vrf_name
, sizeof(keys
->key
[0]));
130 ripngd_instance_lookup_entry(const void *parent_list_entry
,
131 const struct yang_list_keys
*keys
)
133 const char *vrf_name
= keys
->key
[0];
135 return ripng_lookup_by_vrf_name(vrf_name
);
139 * XPath: /frr-ripngd:ripngd/instance/allow-ecmp
141 static int ripngd_instance_allow_ecmp_modify(enum nb_event event
,
142 const struct lyd_node
*dnode
,
143 union nb_resource
*resource
)
147 if (event
!= NB_EV_APPLY
)
150 ripng
= nb_running_get_entry(dnode
, NULL
, true);
151 ripng
->ecmp
= yang_dnode_get_bool(dnode
, NULL
);
153 ripng_ecmp_disable(ripng
);
159 * XPath: /frr-ripngd:ripngd/instance/default-information-originate
161 static int ripngd_instance_default_information_originate_modify(
162 enum nb_event event
, const struct lyd_node
*dnode
,
163 union nb_resource
*resource
)
166 bool default_information
;
167 struct prefix_ipv6 p
;
169 if (event
!= NB_EV_APPLY
)
172 ripng
= nb_running_get_entry(dnode
, NULL
, true);
173 default_information
= yang_dnode_get_bool(dnode
, NULL
);
175 str2prefix_ipv6("::/0", &p
);
176 if (default_information
) {
177 ripng_redistribute_add(ripng
, ZEBRA_ROUTE_RIPNG
,
178 RIPNG_ROUTE_DEFAULT
, &p
, 0, NULL
, 0);
180 ripng_redistribute_delete(ripng
, ZEBRA_ROUTE_RIPNG
,
181 RIPNG_ROUTE_DEFAULT
, &p
, 0);
188 * XPath: /frr-ripngd:ripngd/instance/default-metric
190 static int ripngd_instance_default_metric_modify(enum nb_event event
,
191 const struct lyd_node
*dnode
,
192 union nb_resource
*resource
)
196 if (event
!= NB_EV_APPLY
)
199 ripng
= nb_running_get_entry(dnode
, NULL
, true);
200 ripng
->default_metric
= yang_dnode_get_uint8(dnode
, NULL
);
206 * XPath: /frr-ripngd:ripngd/instance/network
208 static int ripngd_instance_network_create(enum nb_event event
,
209 const struct lyd_node
*dnode
,
210 union nb_resource
*resource
)
215 if (event
!= NB_EV_APPLY
)
218 ripng
= nb_running_get_entry(dnode
, NULL
, true);
219 yang_dnode_get_ipv6p(&p
, dnode
, NULL
);
220 apply_mask_ipv6((struct prefix_ipv6
*)&p
);
222 return ripng_enable_network_add(ripng
, &p
);
225 static int ripngd_instance_network_destroy(enum nb_event event
,
226 const struct lyd_node
*dnode
)
231 if (event
!= NB_EV_APPLY
)
234 ripng
= nb_running_get_entry(dnode
, NULL
, true);
235 yang_dnode_get_ipv6p(&p
, dnode
, NULL
);
236 apply_mask_ipv6((struct prefix_ipv6
*)&p
);
238 return ripng_enable_network_delete(ripng
, &p
);
242 * XPath: /frr-ripngd:ripngd/instance/interface
244 static int ripngd_instance_interface_create(enum nb_event event
,
245 const struct lyd_node
*dnode
,
246 union nb_resource
*resource
)
251 if (event
!= NB_EV_APPLY
)
254 ripng
= nb_running_get_entry(dnode
, NULL
, true);
255 ifname
= yang_dnode_get_string(dnode
, NULL
);
257 return ripng_enable_if_add(ripng
, ifname
);
260 static int ripngd_instance_interface_destroy(enum nb_event event
,
261 const struct lyd_node
*dnode
)
266 if (event
!= NB_EV_APPLY
)
269 ripng
= nb_running_get_entry(dnode
, NULL
, true);
270 ifname
= yang_dnode_get_string(dnode
, NULL
);
272 return ripng_enable_if_delete(ripng
, ifname
);
276 * XPath: /frr-ripngd:ripngd/instance/offset-list
278 static int ripngd_instance_offset_list_create(enum nb_event event
,
279 const struct lyd_node
*dnode
,
280 union nb_resource
*resource
)
284 struct ripng_offset_list
*offset
;
286 if (event
!= NB_EV_APPLY
)
289 ripng
= nb_running_get_entry(dnode
, NULL
, true);
290 ifname
= yang_dnode_get_string(dnode
, "./interface");
292 offset
= ripng_offset_list_new(ripng
, ifname
);
293 nb_running_set_entry(dnode
, offset
);
298 static int ripngd_instance_offset_list_destroy(enum nb_event event
,
299 const struct lyd_node
*dnode
)
302 struct ripng_offset_list
*offset
;
304 if (event
!= NB_EV_APPLY
)
307 direct
= yang_dnode_get_enum(dnode
, "./direction");
309 offset
= nb_running_unset_entry(dnode
);
310 if (offset
->direct
[direct
].alist_name
) {
311 free(offset
->direct
[direct
].alist_name
);
312 offset
->direct
[direct
].alist_name
= NULL
;
314 if (offset
->direct
[RIPNG_OFFSET_LIST_IN
].alist_name
== NULL
315 && offset
->direct
[RIPNG_OFFSET_LIST_OUT
].alist_name
== NULL
)
316 ripng_offset_list_del(offset
);
322 * XPath: /frr-ripngd:ripngd/instance/offset-list/access-list
325 ripngd_instance_offset_list_access_list_modify(enum nb_event event
,
326 const struct lyd_node
*dnode
,
327 union nb_resource
*resource
)
330 struct ripng_offset_list
*offset
;
331 const char *alist_name
;
333 if (event
!= NB_EV_APPLY
)
336 direct
= yang_dnode_get_enum(dnode
, "../direction");
337 alist_name
= yang_dnode_get_string(dnode
, NULL
);
339 offset
= nb_running_get_entry(dnode
, NULL
, true);
340 if (offset
->direct
[direct
].alist_name
)
341 free(offset
->direct
[direct
].alist_name
);
342 offset
->direct
[direct
].alist_name
= strdup(alist_name
);
348 * XPath: /frr-ripngd:ripngd/instance/offset-list/metric
351 ripngd_instance_offset_list_metric_modify(enum nb_event event
,
352 const struct lyd_node
*dnode
,
353 union nb_resource
*resource
)
357 struct ripng_offset_list
*offset
;
359 if (event
!= NB_EV_APPLY
)
362 direct
= yang_dnode_get_enum(dnode
, "../direction");
363 metric
= yang_dnode_get_uint8(dnode
, NULL
);
365 offset
= nb_running_get_entry(dnode
, NULL
, true);
366 offset
->direct
[direct
].metric
= metric
;
372 * XPath: /frr-ripngd:ripngd/instance/passive-interface
375 ripngd_instance_passive_interface_create(enum nb_event event
,
376 const struct lyd_node
*dnode
,
377 union nb_resource
*resource
)
382 if (event
!= NB_EV_APPLY
)
385 ripng
= nb_running_get_entry(dnode
, NULL
, true);
386 ifname
= yang_dnode_get_string(dnode
, NULL
);
388 return ripng_passive_interface_set(ripng
, ifname
);
392 ripngd_instance_passive_interface_destroy(enum nb_event event
,
393 const struct lyd_node
*dnode
)
398 if (event
!= NB_EV_APPLY
)
401 ripng
= nb_running_get_entry(dnode
, NULL
, true);
402 ifname
= yang_dnode_get_string(dnode
, NULL
);
404 return ripng_passive_interface_unset(ripng
, ifname
);
408 * XPath: /frr-ripngd:ripngd/instance/redistribute
410 static int ripngd_instance_redistribute_create(enum nb_event event
,
411 const struct lyd_node
*dnode
,
412 union nb_resource
*resource
)
417 if (event
!= NB_EV_APPLY
)
420 ripng
= nb_running_get_entry(dnode
, NULL
, true);
421 type
= yang_dnode_get_enum(dnode
, "./protocol");
423 ripng
->redist
[type
].enabled
= true;
428 static int ripngd_instance_redistribute_destroy(enum nb_event event
,
429 const struct lyd_node
*dnode
)
434 if (event
!= NB_EV_APPLY
)
437 ripng
= nb_running_get_entry(dnode
, NULL
, true);
438 type
= yang_dnode_get_enum(dnode
, "./protocol");
440 ripng
->redist
[type
].enabled
= false;
441 if (ripng
->redist
[type
].route_map
.name
) {
442 free(ripng
->redist
[type
].route_map
.name
);
443 ripng
->redist
[type
].route_map
.name
= NULL
;
444 ripng
->redist
[type
].route_map
.map
= NULL
;
446 ripng
->redist
[type
].metric_config
= false;
447 ripng
->redist
[type
].metric
= 0;
450 ripng_redistribute_conf_delete(ripng
, type
);
456 ripngd_instance_redistribute_apply_finish(const struct lyd_node
*dnode
)
461 ripng
= nb_running_get_entry(dnode
, NULL
, true);
462 type
= yang_dnode_get_enum(dnode
, "./protocol");
465 ripng_redistribute_conf_update(ripng
, type
);
469 * XPath: /frr-ripngd:ripngd/instance/redistribute/route-map
472 ripngd_instance_redistribute_route_map_modify(enum nb_event event
,
473 const struct lyd_node
*dnode
,
474 union nb_resource
*resource
)
478 const char *rmap_name
;
480 if (event
!= NB_EV_APPLY
)
483 ripng
= nb_running_get_entry(dnode
, NULL
, true);
484 type
= yang_dnode_get_enum(dnode
, "../protocol");
485 rmap_name
= yang_dnode_get_string(dnode
, NULL
);
487 if (ripng
->redist
[type
].route_map
.name
)
488 free(ripng
->redist
[type
].route_map
.name
);
489 ripng
->redist
[type
].route_map
.name
= strdup(rmap_name
);
490 ripng
->redist
[type
].route_map
.map
= route_map_lookup_by_name(rmap_name
);
496 ripngd_instance_redistribute_route_map_destroy(enum nb_event event
,
497 const struct lyd_node
*dnode
)
502 if (event
!= NB_EV_APPLY
)
505 ripng
= nb_running_get_entry(dnode
, NULL
, true);
506 type
= yang_dnode_get_enum(dnode
, "../protocol");
508 free(ripng
->redist
[type
].route_map
.name
);
509 ripng
->redist
[type
].route_map
.name
= NULL
;
510 ripng
->redist
[type
].route_map
.map
= NULL
;
516 * XPath: /frr-ripngd:ripngd/instance/redistribute/metric
519 ripngd_instance_redistribute_metric_modify(enum nb_event event
,
520 const struct lyd_node
*dnode
,
521 union nb_resource
*resource
)
527 if (event
!= NB_EV_APPLY
)
530 ripng
= nb_running_get_entry(dnode
, NULL
, true);
531 type
= yang_dnode_get_enum(dnode
, "../protocol");
532 metric
= yang_dnode_get_uint8(dnode
, NULL
);
534 ripng
->redist
[type
].metric_config
= true;
535 ripng
->redist
[type
].metric
= metric
;
541 ripngd_instance_redistribute_metric_destroy(enum nb_event event
,
542 const struct lyd_node
*dnode
)
547 if (event
!= NB_EV_APPLY
)
550 ripng
= nb_running_get_entry(dnode
, NULL
, true);
551 type
= yang_dnode_get_enum(dnode
, "../protocol");
553 ripng
->redist
[type
].metric_config
= false;
554 ripng
->redist
[type
].metric
= 0;
560 * XPath: /frr-ripngd:ripngd/instance/static-route
562 static int ripngd_instance_static_route_create(enum nb_event event
,
563 const struct lyd_node
*dnode
,
564 union nb_resource
*resource
)
567 struct prefix_ipv6 p
;
569 if (event
!= NB_EV_APPLY
)
572 ripng
= nb_running_get_entry(dnode
, NULL
, true);
573 yang_dnode_get_ipv6p(&p
, dnode
, NULL
);
576 ripng_redistribute_add(ripng
, ZEBRA_ROUTE_RIPNG
, RIPNG_ROUTE_STATIC
, &p
,
582 static int ripngd_instance_static_route_destroy(enum nb_event event
,
583 const struct lyd_node
*dnode
)
586 struct prefix_ipv6 p
;
588 if (event
!= NB_EV_APPLY
)
591 ripng
= nb_running_get_entry(dnode
, NULL
, true);
592 yang_dnode_get_ipv6p(&p
, dnode
, NULL
);
595 ripng_redistribute_delete(ripng
, ZEBRA_ROUTE_RIPNG
, RIPNG_ROUTE_STATIC
,
602 * XPath: /frr-ripngd:ripngd/instance/aggregate-address
605 ripngd_instance_aggregate_address_create(enum nb_event event
,
606 const struct lyd_node
*dnode
,
607 union nb_resource
*resource
)
610 struct prefix_ipv6 p
;
612 if (event
!= NB_EV_APPLY
)
615 ripng
= nb_running_get_entry(dnode
, NULL
, true);
616 yang_dnode_get_ipv6p(&p
, dnode
, NULL
);
619 ripng_aggregate_add(ripng
, (struct prefix
*)&p
);
625 ripngd_instance_aggregate_address_destroy(enum nb_event event
,
626 const struct lyd_node
*dnode
)
629 struct prefix_ipv6 p
;
631 if (event
!= NB_EV_APPLY
)
634 ripng
= nb_running_get_entry(dnode
, NULL
, true);
635 yang_dnode_get_ipv6p(&p
, dnode
, NULL
);
638 ripng_aggregate_delete(ripng
, (struct prefix
*)&p
);
644 * XPath: /frr-ripngd:ripngd/instance/timers
646 static void ripngd_instance_timers_apply_finish(const struct lyd_node
*dnode
)
650 ripng
= nb_running_get_entry(dnode
, NULL
, true);
652 /* Reset update timer thread. */
653 ripng_event(ripng
, RIPNG_UPDATE_EVENT
, 0);
657 * XPath: /frr-ripngd:ripngd/instance/timers/flush-interval
660 ripngd_instance_timers_flush_interval_modify(enum nb_event event
,
661 const struct lyd_node
*dnode
,
662 union nb_resource
*resource
)
666 if (event
!= NB_EV_APPLY
)
669 ripng
= nb_running_get_entry(dnode
, NULL
, true);
670 ripng
->garbage_time
= yang_dnode_get_uint16(dnode
, NULL
);
676 * XPath: /frr-ripngd:ripngd/instance/timers/holddown-interval
679 ripngd_instance_timers_holddown_interval_modify(enum nb_event event
,
680 const struct lyd_node
*dnode
,
681 union nb_resource
*resource
)
685 if (event
!= NB_EV_APPLY
)
688 ripng
= nb_running_get_entry(dnode
, NULL
, true);
689 ripng
->timeout_time
= yang_dnode_get_uint16(dnode
, NULL
);
695 * XPath: /frr-ripngd:ripngd/instance/timers/update-interval
698 ripngd_instance_timers_update_interval_modify(enum nb_event event
,
699 const struct lyd_node
*dnode
,
700 union nb_resource
*resource
)
704 if (event
!= NB_EV_APPLY
)
707 ripng
= nb_running_get_entry(dnode
, NULL
, true);
708 ripng
->update_time
= yang_dnode_get_uint16(dnode
, NULL
);
714 * XPath: /frr-ripngd:ripngd/instance/state/neighbors/neighbor
717 ripngd_instance_state_neighbors_neighbor_get_next(const void *parent_list_entry
,
718 const void *list_entry
)
720 const struct ripng
*ripng
= parent_list_entry
;
721 struct listnode
*node
;
723 if (list_entry
== NULL
)
724 node
= listhead(ripng
->peer_list
);
726 node
= listnextnode((struct listnode
*)list_entry
);
732 ripngd_instance_state_neighbors_neighbor_get_keys(const void *list_entry
,
733 struct yang_list_keys
*keys
)
735 const struct listnode
*node
= list_entry
;
736 const struct ripng_peer
*peer
= listgetdata(node
);
739 (void)inet_ntop(AF_INET6
, &peer
->addr
, keys
->key
[0],
740 sizeof(keys
->key
[0]));
745 static const void *ripngd_instance_state_neighbors_neighbor_lookup_entry(
746 const void *parent_list_entry
, const struct yang_list_keys
*keys
)
748 const struct ripng
*ripng
= parent_list_entry
;
749 struct in6_addr address
;
750 struct ripng_peer
*peer
;
751 struct listnode
*node
;
753 yang_str2ipv6(keys
->key
[0], &address
);
755 for (ALL_LIST_ELEMENTS_RO(ripng
->peer_list
, node
, peer
)) {
756 if (IPV6_ADDR_SAME(&peer
->addr
, &address
))
764 * XPath: /frr-ripngd:ripngd/instance/state/neighbors/neighbor/address
766 static struct yang_data
*
767 ripngd_instance_state_neighbors_neighbor_address_get_elem(
768 const char *xpath
, const void *list_entry
)
770 const struct listnode
*node
= list_entry
;
771 const struct ripng_peer
*peer
= listgetdata(node
);
773 return yang_data_new_ipv6(xpath
, &peer
->addr
);
777 * XPath: /frr-ripngd:ripngd/instance/state/neighbors/neighbor/last-update
779 static struct yang_data
*
780 ripngd_instance_state_neighbors_neighbor_last_update_get_elem(
781 const char *xpath
, const void *list_entry
)
783 /* TODO: yang:date-and-time is tricky */
788 * XPath: /frr-ripngd:ripngd/instance/state/neighbors/neighbor/bad-packets-rcvd
790 static struct yang_data
*
791 ripngd_instance_state_neighbors_neighbor_bad_packets_rcvd_get_elem(
792 const char *xpath
, const void *list_entry
)
794 const struct listnode
*node
= list_entry
;
795 const struct ripng_peer
*peer
= listgetdata(node
);
797 return yang_data_new_uint32(xpath
, peer
->recv_badpackets
);
801 * XPath: /frr-ripngd:ripngd/instance/state/neighbors/neighbor/bad-routes-rcvd
803 static struct yang_data
*
804 ripngd_instance_state_neighbors_neighbor_bad_routes_rcvd_get_elem(
805 const char *xpath
, const void *list_entry
)
807 const struct listnode
*node
= list_entry
;
808 const struct ripng_peer
*peer
= listgetdata(node
);
810 return yang_data_new_uint32(xpath
, peer
->recv_badroutes
);
814 * XPath: /frr-ripngd:ripngd/instance/state/routes/route
817 ripngd_instance_state_routes_route_get_next(const void *parent_list_entry
,
818 const void *list_entry
)
820 const struct ripng
*ripng
= parent_list_entry
;
823 if (list_entry
== NULL
)
824 rn
= agg_route_top(ripng
->table
);
826 rn
= agg_route_next((struct agg_node
*)list_entry
);
827 while (rn
&& rn
->info
== NULL
)
828 rn
= agg_route_next(rn
);
834 ripngd_instance_state_routes_route_get_keys(const void *list_entry
,
835 struct yang_list_keys
*keys
)
837 const struct agg_node
*rn
= list_entry
;
840 (void)prefix2str(&rn
->p
, keys
->key
[0], sizeof(keys
->key
[0]));
845 static const void *ripngd_instance_state_routes_route_lookup_entry(
846 const void *parent_list_entry
, const struct yang_list_keys
*keys
)
848 const struct ripng
*ripng
= parent_list_entry
;
849 struct prefix prefix
;
852 yang_str2ipv6p(keys
->key
[0], &prefix
);
854 rn
= agg_node_lookup(ripng
->table
, &prefix
);
855 if (!rn
|| !rn
->info
)
864 * XPath: /frr-ripngd:ripngd/instance/state/routes/route/prefix
866 static struct yang_data
*
867 ripngd_instance_state_routes_route_prefix_get_elem(const char *xpath
,
868 const void *list_entry
)
870 const struct agg_node
*rn
= list_entry
;
871 const struct ripng_info
*rinfo
= listnode_head(rn
->info
);
873 return yang_data_new_ipv6p(xpath
, &rinfo
->rp
->p
);
877 * XPath: /frr-ripngd:ripngd/instance/state/routes/route/next-hop
879 static struct yang_data
*
880 ripngd_instance_state_routes_route_next_hop_get_elem(const char *xpath
,
881 const void *list_entry
)
883 const struct agg_node
*rn
= list_entry
;
884 const struct ripng_info
*rinfo
= listnode_head(rn
->info
);
886 return yang_data_new_ipv6(xpath
, &rinfo
->nexthop
);
890 * XPath: /frr-ripngd:ripngd/instance/state/routes/route/interface
892 static struct yang_data
*
893 ripngd_instance_state_routes_route_interface_get_elem(const char *xpath
,
894 const void *list_entry
)
896 const struct agg_node
*rn
= list_entry
;
897 const struct ripng_info
*rinfo
= listnode_head(rn
->info
);
898 const struct ripng
*ripng
= ripng_info_get_instance(rinfo
);
900 return yang_data_new_string(
901 xpath
, ifindex2ifname(rinfo
->ifindex
, ripng
->vrf
->vrf_id
));
905 * XPath: /frr-ripngd:ripngd/instance/state/routes/route/metric
907 static struct yang_data
*
908 ripngd_instance_state_routes_route_metric_get_elem(const char *xpath
,
909 const void *list_entry
)
911 const struct agg_node
*rn
= list_entry
;
912 const struct ripng_info
*rinfo
= listnode_head(rn
->info
);
914 return yang_data_new_uint8(xpath
, rinfo
->metric
);
918 * XPath: /frr-ripngd:clear-ripng-route
920 static void clear_ripng_route(struct ripng
*ripng
)
924 if (IS_RIPNG_DEBUG_EVENT
)
925 zlog_debug("Clearing all RIPng routes (VRF %s)",
928 /* Clear received RIPng routes */
929 for (rp
= agg_route_top(ripng
->table
); rp
; rp
= agg_route_next(rp
)) {
931 struct listnode
*listnode
;
932 struct ripng_info
*rinfo
;
938 for (ALL_LIST_ELEMENTS_RO(list
, listnode
, rinfo
)) {
939 if (!ripng_route_rte(rinfo
))
942 if (CHECK_FLAG(rinfo
->flags
, RIPNG_RTF_FIB
))
943 ripng_zebra_ipv6_delete(ripng
, rp
);
948 RIPNG_TIMER_OFF(rinfo
->t_timeout
);
949 RIPNG_TIMER_OFF(rinfo
->t_garbage_collect
);
950 listnode_delete(list
, rinfo
);
951 ripng_info_free(rinfo
);
954 if (list_isempty(list
)) {
962 static int clear_ripng_route_rpc(const char *xpath
, const struct list
*input
,
966 struct yang_data
*yang_vrf
;
968 yang_vrf
= yang_data_list_find(input
, "%s/%s", xpath
, "input/vrf");
970 ripng
= ripng_lookup_by_vrf_name(yang_vrf
->value
);
972 clear_ripng_route(ripng
);
976 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
981 clear_ripng_route(ripng
);
989 * XPath: /frr-interface:lib/interface/frr-ripngd:ripng/split-horizon
992 lib_interface_ripng_split_horizon_modify(enum nb_event event
,
993 const struct lyd_node
*dnode
,
994 union nb_resource
*resource
)
996 struct interface
*ifp
;
997 struct ripng_interface
*ri
;
999 if (event
!= NB_EV_APPLY
)
1002 ifp
= nb_running_get_entry(dnode
, NULL
, true);
1004 ri
->split_horizon
= yang_dnode_get_enum(dnode
, NULL
);
1009 /* clang-format off */
1010 const struct frr_yang_module_info frr_ripngd_info
= {
1011 .name
= "frr-ripngd",
1014 .xpath
= "/frr-ripngd:ripngd/instance",
1015 .cbs
.create
= ripngd_instance_create
,
1016 .cbs
.destroy
= ripngd_instance_destroy
,
1017 .cbs
.get_next
= ripngd_instance_get_next
,
1018 .cbs
.get_keys
= ripngd_instance_get_keys
,
1019 .cbs
.lookup_entry
= ripngd_instance_lookup_entry
,
1020 .cbs
.cli_show
= cli_show_router_ripng
,
1023 .xpath
= "/frr-ripngd:ripngd/instance/allow-ecmp",
1024 .cbs
.modify
= ripngd_instance_allow_ecmp_modify
,
1025 .cbs
.cli_show
= cli_show_ripng_allow_ecmp
,
1028 .xpath
= "/frr-ripngd:ripngd/instance/default-information-originate",
1029 .cbs
.modify
= ripngd_instance_default_information_originate_modify
,
1030 .cbs
.cli_show
= cli_show_ripng_default_information_originate
,
1033 .xpath
= "/frr-ripngd:ripngd/instance/default-metric",
1034 .cbs
.modify
= ripngd_instance_default_metric_modify
,
1035 .cbs
.cli_show
= cli_show_ripng_default_metric
,
1038 .xpath
= "/frr-ripngd:ripngd/instance/network",
1039 .cbs
.create
= ripngd_instance_network_create
,
1040 .cbs
.destroy
= ripngd_instance_network_destroy
,
1041 .cbs
.cli_show
= cli_show_ripng_network_prefix
,
1044 .xpath
= "/frr-ripngd:ripngd/instance/interface",
1045 .cbs
.create
= ripngd_instance_interface_create
,
1046 .cbs
.destroy
= ripngd_instance_interface_destroy
,
1047 .cbs
.cli_show
= cli_show_ripng_network_interface
,
1050 .xpath
= "/frr-ripngd:ripngd/instance/offset-list",
1051 .cbs
.create
= ripngd_instance_offset_list_create
,
1052 .cbs
.destroy
= ripngd_instance_offset_list_destroy
,
1053 .cbs
.cli_show
= cli_show_ripng_offset_list
,
1056 .xpath
= "/frr-ripngd:ripngd/instance/offset-list/access-list",
1057 .cbs
.modify
= ripngd_instance_offset_list_access_list_modify
,
1060 .xpath
= "/frr-ripngd:ripngd/instance/offset-list/metric",
1061 .cbs
.modify
= ripngd_instance_offset_list_metric_modify
,
1064 .xpath
= "/frr-ripngd:ripngd/instance/passive-interface",
1065 .cbs
.create
= ripngd_instance_passive_interface_create
,
1066 .cbs
.destroy
= ripngd_instance_passive_interface_destroy
,
1067 .cbs
.cli_show
= cli_show_ripng_passive_interface
,
1070 .xpath
= "/frr-ripngd:ripngd/instance/redistribute",
1071 .cbs
.create
= ripngd_instance_redistribute_create
,
1072 .cbs
.destroy
= ripngd_instance_redistribute_destroy
,
1073 .cbs
.apply_finish
= ripngd_instance_redistribute_apply_finish
,
1074 .cbs
.cli_show
= cli_show_ripng_redistribute
,
1077 .xpath
= "/frr-ripngd:ripngd/instance/redistribute/route-map",
1078 .cbs
.modify
= ripngd_instance_redistribute_route_map_modify
,
1079 .cbs
.destroy
= ripngd_instance_redistribute_route_map_destroy
,
1082 .xpath
= "/frr-ripngd:ripngd/instance/redistribute/metric",
1083 .cbs
.modify
= ripngd_instance_redistribute_metric_modify
,
1084 .cbs
.destroy
= ripngd_instance_redistribute_metric_destroy
,
1087 .xpath
= "/frr-ripngd:ripngd/instance/static-route",
1088 .cbs
.create
= ripngd_instance_static_route_create
,
1089 .cbs
.destroy
= ripngd_instance_static_route_destroy
,
1090 .cbs
.cli_show
= cli_show_ripng_route
,
1093 .xpath
= "/frr-ripngd:ripngd/instance/aggregate-address",
1094 .cbs
.create
= ripngd_instance_aggregate_address_create
,
1095 .cbs
.destroy
= ripngd_instance_aggregate_address_destroy
,
1096 .cbs
.cli_show
= cli_show_ripng_aggregate_address
,
1099 .xpath
= "/frr-ripngd:ripngd/instance/timers",
1100 .cbs
.apply_finish
= ripngd_instance_timers_apply_finish
,
1101 .cbs
.cli_show
= cli_show_ripng_timers
,
1104 .xpath
= "/frr-ripngd:ripngd/instance/timers/flush-interval",
1105 .cbs
.modify
= ripngd_instance_timers_flush_interval_modify
,
1108 .xpath
= "/frr-ripngd:ripngd/instance/timers/holddown-interval",
1109 .cbs
.modify
= ripngd_instance_timers_holddown_interval_modify
,
1112 .xpath
= "/frr-ripngd:ripngd/instance/timers/update-interval",
1113 .cbs
.modify
= ripngd_instance_timers_update_interval_modify
,
1116 .xpath
= "/frr-ripngd:ripngd/instance/state/neighbors/neighbor",
1117 .cbs
.get_next
= ripngd_instance_state_neighbors_neighbor_get_next
,
1118 .cbs
.get_keys
= ripngd_instance_state_neighbors_neighbor_get_keys
,
1119 .cbs
.lookup_entry
= ripngd_instance_state_neighbors_neighbor_lookup_entry
,
1122 .xpath
= "/frr-ripngd:ripngd/instance/state/neighbors/neighbor/address",
1123 .cbs
.get_elem
= ripngd_instance_state_neighbors_neighbor_address_get_elem
,
1126 .xpath
= "/frr-ripngd:ripngd/instance/state/neighbors/neighbor/last-update",
1127 .cbs
.get_elem
= ripngd_instance_state_neighbors_neighbor_last_update_get_elem
,
1130 .xpath
= "/frr-ripngd:ripngd/instance/state/neighbors/neighbor/bad-packets-rcvd",
1131 .cbs
.get_elem
= ripngd_instance_state_neighbors_neighbor_bad_packets_rcvd_get_elem
,
1134 .xpath
= "/frr-ripngd:ripngd/instance/state/neighbors/neighbor/bad-routes-rcvd",
1135 .cbs
.get_elem
= ripngd_instance_state_neighbors_neighbor_bad_routes_rcvd_get_elem
,
1138 .xpath
= "/frr-ripngd:ripngd/instance/state/routes/route",
1139 .cbs
.get_next
= ripngd_instance_state_routes_route_get_next
,
1140 .cbs
.get_keys
= ripngd_instance_state_routes_route_get_keys
,
1141 .cbs
.lookup_entry
= ripngd_instance_state_routes_route_lookup_entry
,
1144 .xpath
= "/frr-ripngd:ripngd/instance/state/routes/route/prefix",
1145 .cbs
.get_elem
= ripngd_instance_state_routes_route_prefix_get_elem
,
1148 .xpath
= "/frr-ripngd:ripngd/instance/state/routes/route/next-hop",
1149 .cbs
.get_elem
= ripngd_instance_state_routes_route_next_hop_get_elem
,
1152 .xpath
= "/frr-ripngd:ripngd/instance/state/routes/route/interface",
1153 .cbs
.get_elem
= ripngd_instance_state_routes_route_interface_get_elem
,
1156 .xpath
= "/frr-ripngd:ripngd/instance/state/routes/route/metric",
1157 .cbs
.get_elem
= ripngd_instance_state_routes_route_metric_get_elem
,
1160 .xpath
= "/frr-ripngd:clear-ripng-route",
1161 .cbs
.rpc
= clear_ripng_route_rpc
,
1164 .xpath
= "/frr-interface:lib/interface/frr-ripngd:ripng/split-horizon",
1165 .cbs
.modify
= lib_interface_ripng_split_horizon_modify
,
1166 .cbs
.cli_show
= cli_show_ipv6_ripng_split_horizon
,