2 * Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro <kunihiro@zebra.org>
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 "northbound.h"
33 #include "ripd/ripd.h"
34 #include "ripd/rip_cli.h"
37 * XPath: /frr-ripd:ripd/instance
39 static int ripd_instance_create(enum nb_event event
,
40 const struct lyd_node
*dnode
,
41 union nb_resource
*resource
)
49 socket
= rip_create_socket();
51 return NB_ERR_RESOURCE
;
52 resource
->fd
= socket
;
55 socket
= resource
->fd
;
59 socket
= resource
->fd
;
67 static int ripd_instance_delete(enum nb_event event
,
68 const struct lyd_node
*dnode
)
70 if (event
!= NB_EV_APPLY
)
79 * XPath: /frr-ripd:ripd/instance/allow-ecmp
81 static int ripd_instance_allow_ecmp_modify(enum nb_event event
,
82 const struct lyd_node
*dnode
,
83 union nb_resource
*resource
)
85 if (event
!= NB_EV_APPLY
)
88 rip
->ecmp
= yang_dnode_get_bool(dnode
, NULL
);
96 * XPath: /frr-ripd:ripd/instance/default-information-originate
99 ripd_instance_default_information_originate_modify(enum nb_event event
,
100 const struct lyd_node
*dnode
,
101 union nb_resource
*resource
)
103 bool default_information
;
104 struct prefix_ipv4 p
;
106 if (event
!= NB_EV_APPLY
)
109 default_information
= yang_dnode_get_bool(dnode
, NULL
);
111 memset(&p
, 0, sizeof(struct prefix_ipv4
));
113 if (default_information
) {
116 memset(&nh
, 0, sizeof(nh
));
117 nh
.type
= NEXTHOP_TYPE_IPV4
;
118 rip_redistribute_add(ZEBRA_ROUTE_RIP
, RIP_ROUTE_DEFAULT
, &p
,
121 rip_redistribute_delete(ZEBRA_ROUTE_RIP
, RIP_ROUTE_DEFAULT
, &p
,
129 * XPath: /frr-ripd:ripd/instance/default-metric
131 static int ripd_instance_default_metric_modify(enum nb_event event
,
132 const struct lyd_node
*dnode
,
133 union nb_resource
*resource
)
135 if (event
!= NB_EV_APPLY
)
138 rip
->default_metric
= yang_dnode_get_uint8(dnode
, NULL
);
139 /* rip_update_default_metric (); */
145 * XPath: /frr-ripd:ripd/instance/distance/default
147 static int ripd_instance_distance_default_modify(enum nb_event event
,
148 const struct lyd_node
*dnode
,
149 union nb_resource
*resource
)
151 if (event
!= NB_EV_APPLY
)
154 rip
->distance
= yang_dnode_get_uint8(dnode
, NULL
);
160 * XPath: /frr-ripd:ripd/instance/distance/source
162 static int ripd_instance_distance_source_create(enum nb_event event
,
163 const struct lyd_node
*dnode
,
164 union nb_resource
*resource
)
166 struct prefix_ipv4 prefix
;
167 struct route_node
*rn
;
169 if (event
!= NB_EV_APPLY
)
172 yang_dnode_get_ipv4p(&prefix
, dnode
, "./prefix");
174 /* Get RIP distance node. */
175 rn
= route_node_get(rip_distance_table
, (struct prefix
*)&prefix
);
176 rn
->info
= rip_distance_new();
177 yang_dnode_set_entry(dnode
, rn
);
182 static int ripd_instance_distance_source_delete(enum nb_event event
,
183 const struct lyd_node
*dnode
)
185 struct route_node
*rn
;
186 struct rip_distance
*rdistance
;
188 if (event
!= NB_EV_APPLY
)
191 rn
= yang_dnode_get_entry(dnode
);
192 rdistance
= rn
->info
;
193 if (rdistance
->access_list
)
194 free(rdistance
->access_list
);
195 rip_distance_free(rdistance
);
198 route_unlock_node(rn
);
204 * XPath: /frr-ripd:ripd/instance/distance/source/distance
207 ripd_instance_distance_source_distance_modify(enum nb_event event
,
208 const struct lyd_node
*dnode
,
209 union nb_resource
*resource
)
211 struct route_node
*rn
;
213 struct rip_distance
*rdistance
;
215 if (event
!= NB_EV_APPLY
)
218 /* Set distance value. */
219 rn
= yang_dnode_get_entry(dnode
);
220 distance
= yang_dnode_get_uint8(dnode
, NULL
);
221 rdistance
= rn
->info
;
222 rdistance
->distance
= distance
;
228 * XPath: /frr-ripd:ripd/instance/distance/source/access-list
231 ripd_instance_distance_source_access_list_modify(enum nb_event event
,
232 const struct lyd_node
*dnode
,
233 union nb_resource
*resource
)
235 const char *acl_name
;
236 struct route_node
*rn
;
237 struct rip_distance
*rdistance
;
239 if (event
!= NB_EV_APPLY
)
242 acl_name
= yang_dnode_get_string(dnode
, NULL
);
244 /* Set access-list */
245 rn
= yang_dnode_get_entry(dnode
);
246 rdistance
= rn
->info
;
247 if (rdistance
->access_list
)
248 free(rdistance
->access_list
);
249 rdistance
->access_list
= strdup(acl_name
);
255 ripd_instance_distance_source_access_list_delete(enum nb_event event
,
256 const struct lyd_node
*dnode
)
258 struct route_node
*rn
;
259 struct rip_distance
*rdistance
;
261 if (event
!= NB_EV_APPLY
)
264 /* Reset access-list configuration. */
265 rn
= yang_dnode_get_entry(dnode
);
266 rdistance
= rn
->info
;
267 free(rdistance
->access_list
);
268 rdistance
->access_list
= NULL
;
274 * XPath: /frr-ripd:ripd/instance/explicit-neighbor
276 static int ripd_instance_explicit_neighbor_create(enum nb_event event
,
277 const struct lyd_node
*dnode
,
278 union nb_resource
*resource
)
280 struct prefix_ipv4 p
;
282 if (event
!= NB_EV_APPLY
)
286 p
.prefixlen
= IPV4_MAX_BITLEN
;
287 yang_dnode_get_ipv4(&p
.prefix
, dnode
, NULL
);
289 return rip_neighbor_add(&p
);
292 static int ripd_instance_explicit_neighbor_delete(enum nb_event event
,
293 const struct lyd_node
*dnode
)
295 struct prefix_ipv4 p
;
297 if (event
!= NB_EV_APPLY
)
301 p
.prefixlen
= IPV4_MAX_BITLEN
;
302 yang_dnode_get_ipv4(&p
.prefix
, dnode
, NULL
);
304 return rip_neighbor_delete(&p
);
308 * XPath: /frr-ripd:ripd/instance/network
310 static int ripd_instance_network_create(enum nb_event event
,
311 const struct lyd_node
*dnode
,
312 union nb_resource
*resource
)
316 if (event
!= NB_EV_APPLY
)
319 yang_dnode_get_ipv4p(&p
, dnode
, NULL
);
321 return rip_enable_network_add(&p
);
324 static int ripd_instance_network_delete(enum nb_event event
,
325 const struct lyd_node
*dnode
)
329 if (event
!= NB_EV_APPLY
)
332 yang_dnode_get_ipv4p(&p
, dnode
, NULL
);
334 return rip_enable_network_delete(&p
);
338 * XPath: /frr-ripd:ripd/instance/interface
340 static int ripd_instance_interface_create(enum nb_event event
,
341 const struct lyd_node
*dnode
,
342 union nb_resource
*resource
)
346 if (event
!= NB_EV_APPLY
)
349 ifname
= yang_dnode_get_string(dnode
, NULL
);
351 return rip_enable_if_add(ifname
);
354 static int ripd_instance_interface_delete(enum nb_event event
,
355 const struct lyd_node
*dnode
)
359 if (event
!= NB_EV_APPLY
)
362 ifname
= yang_dnode_get_string(dnode
, NULL
);
364 return rip_enable_if_delete(ifname
);
368 * XPath: /frr-ripd:ripd/instance/offset-list
370 static int ripd_instance_offset_list_create(enum nb_event event
,
371 const struct lyd_node
*dnode
,
372 union nb_resource
*resource
)
375 struct rip_offset_list
*offset
;
377 if (event
!= NB_EV_APPLY
)
380 ifname
= yang_dnode_get_string(dnode
, "./interface");
382 offset
= rip_offset_list_new(ifname
);
383 yang_dnode_set_entry(dnode
, offset
);
388 static int ripd_instance_offset_list_delete(enum nb_event event
,
389 const struct lyd_node
*dnode
)
392 struct rip_offset_list
*offset
;
394 if (event
!= NB_EV_APPLY
)
397 direct
= yang_dnode_get_enum(dnode
, "./direction");
399 offset
= yang_dnode_get_entry(dnode
);
400 if (offset
->direct
[direct
].alist_name
) {
401 free(offset
->direct
[direct
].alist_name
);
402 offset
->direct
[direct
].alist_name
= NULL
;
404 if (offset
->direct
[RIP_OFFSET_LIST_IN
].alist_name
== NULL
405 && offset
->direct
[RIP_OFFSET_LIST_OUT
].alist_name
== NULL
)
406 offset_list_del(offset
);
412 * XPath: /frr-ripd:ripd/instance/offset-list/access-list
415 ripd_instance_offset_list_access_list_modify(enum nb_event event
,
416 const struct lyd_node
*dnode
,
417 union nb_resource
*resource
)
420 struct rip_offset_list
*offset
;
421 const char *alist_name
;
423 if (event
!= NB_EV_APPLY
)
426 direct
= yang_dnode_get_enum(dnode
, "../direction");
427 alist_name
= yang_dnode_get_string(dnode
, NULL
);
429 offset
= yang_dnode_get_entry(dnode
);
430 if (offset
->direct
[direct
].alist_name
)
431 free(offset
->direct
[direct
].alist_name
);
432 offset
->direct
[direct
].alist_name
= strdup(alist_name
);
438 * XPath: /frr-ripd:ripd/instance/offset-list/metric
440 static int ripd_instance_offset_list_metric_modify(enum nb_event event
,
441 const struct lyd_node
*dnode
,
442 union nb_resource
*resource
)
446 struct rip_offset_list
*offset
;
448 if (event
!= NB_EV_APPLY
)
451 direct
= yang_dnode_get_enum(dnode
, "../direction");
452 metric
= yang_dnode_get_uint8(dnode
, NULL
);
454 offset
= yang_dnode_get_entry(dnode
);
455 offset
->direct
[direct
].metric
= metric
;
461 * XPath: /frr-ripd:ripd/instance/passive-default
463 static int ripd_instance_passive_default_modify(enum nb_event event
,
464 const struct lyd_node
*dnode
,
465 union nb_resource
*resource
)
467 if (event
!= NB_EV_APPLY
)
470 rip
->passive_default
= yang_dnode_get_bool(dnode
, NULL
);
471 rip_passive_nondefault_clean();
477 * XPath: /frr-ripd:ripd/instance/passive-interface
479 static int ripd_instance_passive_interface_create(enum nb_event event
,
480 const struct lyd_node
*dnode
,
481 union nb_resource
*resource
)
485 if (event
!= NB_EV_APPLY
)
488 ifname
= yang_dnode_get_string(dnode
, NULL
);
490 return rip_passive_nondefault_set(ifname
);
493 static int ripd_instance_passive_interface_delete(enum nb_event event
,
494 const struct lyd_node
*dnode
)
498 if (event
!= NB_EV_APPLY
)
501 ifname
= yang_dnode_get_string(dnode
, NULL
);
503 return rip_passive_nondefault_unset(ifname
);
507 * XPath: /frr-ripd:ripd/instance/non-passive-interface
510 ripd_instance_non_passive_interface_create(enum nb_event event
,
511 const struct lyd_node
*dnode
,
512 union nb_resource
*resource
)
516 if (event
!= NB_EV_APPLY
)
519 ifname
= yang_dnode_get_string(dnode
, NULL
);
521 return rip_passive_nondefault_unset(ifname
);
525 ripd_instance_non_passive_interface_delete(enum nb_event event
,
526 const struct lyd_node
*dnode
)
530 if (event
!= NB_EV_APPLY
)
533 ifname
= yang_dnode_get_string(dnode
, NULL
);
535 return rip_passive_nondefault_set(ifname
);
539 * XPath: /frr-ripd:ripd/instance/redistribute
541 static int ripd_instance_redistribute_create(enum nb_event event
,
542 const struct lyd_node
*dnode
,
543 union nb_resource
*resource
)
548 static int ripd_instance_redistribute_delete(enum nb_event event
,
549 const struct lyd_node
*dnode
)
553 if (event
!= NB_EV_APPLY
)
556 type
= yang_dnode_get_enum(dnode
, "./protocol");
558 rip_redistribute_conf_delete(type
);
564 ripd_instance_redistribute_apply_finish(const struct lyd_node
*dnode
)
568 type
= yang_dnode_get_enum(dnode
, "./protocol");
569 rip_redistribute_conf_update(type
);
573 * XPath: /frr-ripd:ripd/instance/redistribute/route-map
576 ripd_instance_redistribute_route_map_modify(enum nb_event event
,
577 const struct lyd_node
*dnode
,
578 union nb_resource
*resource
)
581 const char *rmap_name
;
583 if (event
!= NB_EV_APPLY
)
586 type
= yang_dnode_get_enum(dnode
, "../protocol");
587 rmap_name
= yang_dnode_get_string(dnode
, NULL
);
589 if (rip
->route_map
[type
].name
)
590 free(rip
->route_map
[type
].name
);
591 rip
->route_map
[type
].name
= strdup(rmap_name
);
592 rip
->route_map
[type
].map
= route_map_lookup_by_name(rmap_name
);
598 ripd_instance_redistribute_route_map_delete(enum nb_event event
,
599 const struct lyd_node
*dnode
)
603 if (event
!= NB_EV_APPLY
)
606 type
= yang_dnode_get_enum(dnode
, "../protocol");
608 if (rip
->route_map
[type
].name
) {
609 free(rip
->route_map
[type
].name
);
610 rip
->route_map
[type
].name
= NULL
;
617 * XPath: /frr-ripd:ripd/instance/redistribute/metric
620 ripd_instance_redistribute_metric_modify(enum nb_event event
,
621 const struct lyd_node
*dnode
,
622 union nb_resource
*resource
)
627 if (event
!= NB_EV_APPLY
)
630 type
= yang_dnode_get_enum(dnode
, "../protocol");
631 metric
= yang_dnode_get_uint8(dnode
, NULL
);
633 rip
->route_map
[type
].metric_config
= true;
634 rip
->route_map
[type
].metric
= metric
;
640 ripd_instance_redistribute_metric_delete(enum nb_event event
,
641 const struct lyd_node
*dnode
)
645 if (event
!= NB_EV_APPLY
)
648 type
= yang_dnode_get_enum(dnode
, "../protocol");
650 rip
->route_map
[type
].metric_config
= false;
651 rip
->route_map
[type
].metric
= 0;
657 * XPath: /frr-ripd:ripd/instance/static-route
659 static int ripd_instance_static_route_create(enum nb_event event
,
660 const struct lyd_node
*dnode
,
661 union nb_resource
*resource
)
664 struct prefix_ipv4 p
;
666 if (event
!= NB_EV_APPLY
)
669 yang_dnode_get_ipv4p(&p
, dnode
, NULL
);
671 memset(&nh
, 0, sizeof(nh
));
672 nh
.type
= NEXTHOP_TYPE_IPV4
;
673 rip_redistribute_add(ZEBRA_ROUTE_RIP
, RIP_ROUTE_STATIC
, &p
, &nh
, 0, 0,
679 static int ripd_instance_static_route_delete(enum nb_event event
,
680 const struct lyd_node
*dnode
)
682 struct prefix_ipv4 p
;
684 if (event
!= NB_EV_APPLY
)
687 yang_dnode_get_ipv4p(&p
, dnode
, NULL
);
689 rip_redistribute_delete(ZEBRA_ROUTE_RIP
, RIP_ROUTE_STATIC
, &p
, 0);
695 * XPath: /frr-ripd:ripd/instance/timers/
697 static void ripd_instance_timers_apply_finish(const struct lyd_node
*dnode
)
699 /* Reset update timer thread. */
700 rip_event(RIP_UPDATE_EVENT
, 0);
704 * XPath: /frr-ripd:ripd/instance/timers/flush-interval
707 ripd_instance_timers_flush_interval_modify(enum nb_event event
,
708 const struct lyd_node
*dnode
,
709 union nb_resource
*resource
)
711 if (event
!= NB_EV_APPLY
)
714 rip
->garbage_time
= yang_dnode_get_uint32(dnode
, NULL
);
720 * XPath: /frr-ripd:ripd/instance/timers/holddown-interval
723 ripd_instance_timers_holddown_interval_modify(enum nb_event event
,
724 const struct lyd_node
*dnode
,
725 union nb_resource
*resource
)
727 if (event
!= NB_EV_APPLY
)
730 rip
->timeout_time
= yang_dnode_get_uint32(dnode
, NULL
);
736 * XPath: /frr-ripd:ripd/instance/timers/update-interval
739 ripd_instance_timers_update_interval_modify(enum nb_event event
,
740 const struct lyd_node
*dnode
,
741 union nb_resource
*resource
)
743 if (event
!= NB_EV_APPLY
)
746 rip
->update_time
= yang_dnode_get_uint32(dnode
, NULL
);
752 * XPath: /frr-ripd:ripd/instance/version/receive
754 static int ripd_instance_version_receive_modify(enum nb_event event
,
755 const struct lyd_node
*dnode
,
756 union nb_resource
*resource
)
758 if (event
!= NB_EV_APPLY
)
761 rip
->version_recv
= yang_dnode_get_enum(dnode
, NULL
);
767 * XPath: /frr-ripd:ripd/instance/version/send
769 static int ripd_instance_version_send_modify(enum nb_event event
,
770 const struct lyd_node
*dnode
,
771 union nb_resource
*resource
)
773 if (event
!= NB_EV_APPLY
)
776 rip
->version_send
= yang_dnode_get_enum(dnode
, NULL
);
782 * XPath: /frr-interface:lib/interface/frr-ripd:rip/split-horizon
784 static int lib_interface_rip_split_horizon_modify(enum nb_event event
,
785 const struct lyd_node
*dnode
,
786 union nb_resource
*resource
)
788 struct interface
*ifp
;
789 struct rip_interface
*ri
;
791 if (event
!= NB_EV_APPLY
)
794 ifp
= yang_dnode_get_entry(dnode
);
796 ri
->split_horizon
= yang_dnode_get_enum(dnode
, NULL
);
802 * XPath: /frr-interface:lib/interface/frr-ripd:rip/v2-broadcast
804 static int lib_interface_rip_v2_broadcast_modify(enum nb_event event
,
805 const struct lyd_node
*dnode
,
806 union nb_resource
*resource
)
808 struct interface
*ifp
;
809 struct rip_interface
*ri
;
811 if (event
!= NB_EV_APPLY
)
814 ifp
= yang_dnode_get_entry(dnode
);
816 ri
->v2_broadcast
= yang_dnode_get_bool(dnode
, NULL
);
822 * XPath: /frr-interface:lib/interface/frr-ripd:rip/version-receive
825 lib_interface_rip_version_receive_modify(enum nb_event event
,
826 const struct lyd_node
*dnode
,
827 union nb_resource
*resource
)
829 struct interface
*ifp
;
830 struct rip_interface
*ri
;
832 if (event
!= NB_EV_APPLY
)
835 ifp
= yang_dnode_get_entry(dnode
);
837 ri
->ri_receive
= yang_dnode_get_enum(dnode
, NULL
);
843 * XPath: /frr-interface:lib/interface/frr-ripd:rip/version-send
845 static int lib_interface_rip_version_send_modify(enum nb_event event
,
846 const struct lyd_node
*dnode
,
847 union nb_resource
*resource
)
849 struct interface
*ifp
;
850 struct rip_interface
*ri
;
852 if (event
!= NB_EV_APPLY
)
855 ifp
= yang_dnode_get_entry(dnode
);
857 ri
->ri_send
= yang_dnode_get_enum(dnode
, NULL
);
863 * XPath: /frr-interface:lib/interface/frr-ripd:rip/authentication-scheme/mode
865 static int lib_interface_rip_authentication_scheme_mode_modify(
866 enum nb_event event
, const struct lyd_node
*dnode
,
867 union nb_resource
*resource
)
869 struct interface
*ifp
;
870 struct rip_interface
*ri
;
872 if (event
!= NB_EV_APPLY
)
875 ifp
= yang_dnode_get_entry(dnode
);
877 ri
->auth_type
= yang_dnode_get_enum(dnode
, NULL
);
884 * /frr-interface:lib/interface/frr-ripd:rip/authentication-scheme/md5-auth-length
886 static int lib_interface_rip_authentication_scheme_md5_auth_length_modify(
887 enum nb_event event
, const struct lyd_node
*dnode
,
888 union nb_resource
*resource
)
890 struct interface
*ifp
;
891 struct rip_interface
*ri
;
893 if (event
!= NB_EV_APPLY
)
896 ifp
= yang_dnode_get_entry(dnode
);
898 ri
->md5_auth_len
= yang_dnode_get_enum(dnode
, NULL
);
903 static int lib_interface_rip_authentication_scheme_md5_auth_length_delete(
904 enum nb_event event
, const struct lyd_node
*dnode
)
906 struct interface
*ifp
;
907 struct rip_interface
*ri
;
909 if (event
!= NB_EV_APPLY
)
912 ifp
= yang_dnode_get_entry(dnode
);
914 ri
->md5_auth_len
= yang_get_default_enum(
915 "%s/authentication-scheme/md5-auth-length", RIP_IFACE
);
921 * XPath: /frr-interface:lib/interface/frr-ripd:rip/authentication-password
924 lib_interface_rip_authentication_password_modify(enum nb_event event
,
925 const struct lyd_node
*dnode
,
926 union nb_resource
*resource
)
928 struct interface
*ifp
;
929 struct rip_interface
*ri
;
931 if (event
!= NB_EV_APPLY
)
934 ifp
= yang_dnode_get_entry(dnode
);
937 XFREE(MTYPE_RIP_INTERFACE_STRING
, ri
->auth_str
);
938 ri
->auth_str
= XSTRDUP(MTYPE_RIP_INTERFACE_STRING
,
939 yang_dnode_get_string(dnode
, NULL
));
945 lib_interface_rip_authentication_password_delete(enum nb_event event
,
946 const struct lyd_node
*dnode
)
948 struct interface
*ifp
;
949 struct rip_interface
*ri
;
951 if (event
!= NB_EV_APPLY
)
954 ifp
= yang_dnode_get_entry(dnode
);
956 XFREE(MTYPE_RIP_INTERFACE_STRING
, ri
->auth_str
);
962 * XPath: /frr-interface:lib/interface/frr-ripd:rip/authentication-key-chain
965 lib_interface_rip_authentication_key_chain_modify(enum nb_event event
,
966 const struct lyd_node
*dnode
,
967 union nb_resource
*resource
)
969 struct interface
*ifp
;
970 struct rip_interface
*ri
;
972 if (event
!= NB_EV_APPLY
)
975 ifp
= yang_dnode_get_entry(dnode
);
978 XFREE(MTYPE_RIP_INTERFACE_STRING
, ri
->key_chain
);
979 ri
->key_chain
= XSTRDUP(MTYPE_RIP_INTERFACE_STRING
,
980 yang_dnode_get_string(dnode
, NULL
));
986 lib_interface_rip_authentication_key_chain_delete(enum nb_event event
,
987 const struct lyd_node
*dnode
)
989 struct interface
*ifp
;
990 struct rip_interface
*ri
;
992 if (event
!= NB_EV_APPLY
)
995 ifp
= yang_dnode_get_entry(dnode
);
997 XFREE(MTYPE_RIP_INTERFACE_STRING
, ri
->key_chain
);
1003 * XPath: /frr-ripd:ripd/state/neighbors/neighbor
1006 ripd_state_neighbors_neighbor_get_next(const char *xpath
,
1007 const void *list_entry
)
1009 struct listnode
*node
;
1011 if (list_entry
== NULL
)
1012 node
= listhead(peer_list
);
1014 node
= listnextnode((struct listnode
*)list_entry
);
1019 static int ripd_state_neighbors_neighbor_get_keys(const void *list_entry
,
1020 struct yang_list_keys
*keys
)
1022 const struct listnode
*node
= list_entry
;
1023 const struct rip_peer
*peer
= listgetdata(node
);
1026 (void)inet_ntop(AF_INET
, &peer
->addr
, keys
->key
[0].value
,
1027 sizeof(keys
->key
[0].value
));
1033 ripd_state_neighbors_neighbor_lookup_entry(const struct yang_list_keys
*keys
)
1035 struct in_addr address
;
1037 yang_str2ipv4(keys
->key
[0].value
, &address
);
1039 return rip_peer_lookup(&address
);
1043 * XPath: /frr-ripd:ripd/state/neighbors/neighbor/address
1045 static struct yang_data
*
1046 ripd_state_neighbors_neighbor_address_get_elem(const char *xpath
,
1047 const void *list_entry
)
1049 const struct rip_peer
*peer
= list_entry
;
1051 return yang_data_new_ipv4(xpath
, &peer
->addr
);
1055 * XPath: /frr-ripd:ripd/state/neighbors/neighbor/last-update
1057 static struct yang_data
*
1058 ripd_state_neighbors_neighbor_last_update_get_elem(const char *xpath
,
1059 const void *list_entry
)
1061 /* TODO: yang:date-and-time is tricky */
1066 * XPath: /frr-ripd:ripd/state/neighbors/neighbor/bad-packets-rcvd
1068 static struct yang_data
*
1069 ripd_state_neighbors_neighbor_bad_packets_rcvd_get_elem(const char *xpath
,
1070 const void *list_entry
)
1072 const struct rip_peer
*peer
= list_entry
;
1074 return yang_data_new_uint32(xpath
, peer
->recv_badpackets
);
1078 * XPath: /frr-ripd:ripd/state/neighbors/neighbor/bad-routes-rcvd
1080 static struct yang_data
*
1081 ripd_state_neighbors_neighbor_bad_routes_rcvd_get_elem(const char *xpath
,
1082 const void *list_entry
)
1084 const struct rip_peer
*peer
= list_entry
;
1086 return yang_data_new_uint32(xpath
, peer
->recv_badroutes
);
1090 * XPath: /frr-ripd:ripd/state/routes/route
1092 static const void *ripd_state_routes_route_get_next(const char *xpath
,
1093 const void *list_entry
)
1095 struct route_node
*rn
;
1100 if (list_entry
== NULL
)
1101 rn
= route_top(rip
->table
);
1103 rn
= route_next((struct route_node
*)list_entry
);
1104 while (rn
&& rn
->info
== NULL
)
1105 rn
= route_next(rn
);
1110 static int ripd_state_routes_route_get_keys(const void *list_entry
,
1111 struct yang_list_keys
*keys
)
1113 const struct route_node
*rn
= list_entry
;
1116 (void)prefix2str(&rn
->p
, keys
->key
[0].value
,
1117 sizeof(keys
->key
[0].value
));
1123 ripd_state_routes_route_lookup_entry(const struct yang_list_keys
*keys
)
1125 struct prefix prefix
;
1126 struct route_node
*rn
;
1128 yang_str2ipv4p(keys
->key
[0].value
, &prefix
);
1130 rn
= route_node_lookup(rip
->table
, &prefix
);
1131 if (!rn
|| !rn
->info
)
1134 route_unlock_node(rn
);
1137 * TODO: we need to handle ECMP properly.
1139 return listnode_head(rn
->info
);
1143 * XPath: /frr-ripd:ripd/state/routes/route/prefix
1145 static struct yang_data
*
1146 ripd_state_routes_route_prefix_get_elem(const char *xpath
,
1147 const void *list_entry
)
1149 const struct rip_info
*rinfo
= list_entry
;
1151 return yang_data_new_ipv4p(xpath
, &rinfo
->rp
->p
);
1155 * XPath: /frr-ripd:ripd/state/routes/route/next-hop
1157 static struct yang_data
*
1158 ripd_state_routes_route_next_hop_get_elem(const char *xpath
,
1159 const void *list_entry
)
1161 const struct rip_info
*rinfo
= list_entry
;
1163 switch (rinfo
->nh
.type
) {
1164 case NEXTHOP_TYPE_IPV4
:
1165 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1166 return yang_data_new_ipv4(xpath
, &rinfo
->nh
.gate
.ipv4
);
1173 * XPath: /frr-ripd:ripd/state/routes/route/interface
1175 static struct yang_data
*
1176 ripd_state_routes_route_interface_get_elem(const char *xpath
,
1177 const void *list_entry
)
1179 const struct rip_info
*rinfo
= list_entry
;
1181 switch (rinfo
->nh
.type
) {
1182 case NEXTHOP_TYPE_IFINDEX
:
1183 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1184 return yang_data_new_string(
1185 xpath
, ifindex2ifname(rinfo
->nh
.ifindex
, VRF_DEFAULT
));
1192 * XPath: /frr-ripd:ripd/state/routes/route/metric
1194 static struct yang_data
*
1195 ripd_state_routes_route_metric_get_elem(const char *xpath
,
1196 const void *list_entry
)
1198 const struct rip_info
*rinfo
= list_entry
;
1200 return yang_data_new_uint8(xpath
, rinfo
->metric
);
1204 * XPath: /frr-ripd:clear-rip-route
1206 static int clear_rip_route_rpc(const char *xpath
, const struct list
*input
,
1207 struct list
*output
)
1209 struct route_node
*rp
;
1210 struct rip_info
*rinfo
;
1212 struct listnode
*listnode
;
1214 /* Clear received RIP routes */
1215 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
)) {
1220 for (ALL_LIST_ELEMENTS_RO(list
, listnode
, rinfo
)) {
1221 if (!rip_route_rte(rinfo
))
1224 if (CHECK_FLAG(rinfo
->flags
, RIP_RTF_FIB
))
1225 rip_zebra_ipv4_delete(rp
);
1230 RIP_TIMER_OFF(rinfo
->t_timeout
);
1231 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
1232 listnode_delete(list
, rinfo
);
1233 rip_info_free(rinfo
);
1236 if (list_isempty(list
)) {
1239 route_unlock_node(rp
);
1247 * XPath: /frr-ripd:authentication-type-failure
1249 void ripd_notif_send_auth_type_failure(const char *ifname
)
1251 const char *xpath
= "/frr-ripd:authentication-type-failure";
1252 struct list
*arguments
;
1253 char xpath_arg
[XPATH_MAXLEN
];
1254 struct yang_data
*data
;
1256 arguments
= yang_data_list_new();
1258 snprintf(xpath_arg
, sizeof(xpath_arg
), "%s/interface-name", xpath
);
1259 data
= yang_data_new_string(xpath_arg
, ifname
);
1260 listnode_add(arguments
, data
);
1262 nb_notification_send(xpath
, arguments
);
1266 * XPath: /frr-ripd:authentication-failure
1268 void ripd_notif_send_auth_failure(const char *ifname
)
1270 const char *xpath
= "/frr-ripd:authentication-failure";
1271 struct list
*arguments
;
1272 char xpath_arg
[XPATH_MAXLEN
];
1273 struct yang_data
*data
;
1275 arguments
= yang_data_list_new();
1277 snprintf(xpath_arg
, sizeof(xpath_arg
), "%s/interface-name", xpath
);
1278 data
= yang_data_new_string(xpath_arg
, ifname
);
1279 listnode_add(arguments
, data
);
1281 nb_notification_send(xpath
, arguments
);
1284 /* clang-format off */
1285 const struct frr_yang_module_info frr_ripd_info
= {
1289 .xpath
= "/frr-ripd:ripd/instance",
1290 .cbs
.create
= ripd_instance_create
,
1291 .cbs
.delete = ripd_instance_delete
,
1292 .cbs
.cli_show
= cli_show_router_rip
,
1295 .xpath
= "/frr-ripd:ripd/instance/allow-ecmp",
1296 .cbs
.modify
= ripd_instance_allow_ecmp_modify
,
1297 .cbs
.cli_show
= cli_show_rip_allow_ecmp
,
1300 .xpath
= "/frr-ripd:ripd/instance/default-information-originate",
1301 .cbs
.modify
= ripd_instance_default_information_originate_modify
,
1302 .cbs
.cli_show
= cli_show_rip_default_information_originate
,
1305 .xpath
= "/frr-ripd:ripd/instance/default-metric",
1306 .cbs
.modify
= ripd_instance_default_metric_modify
,
1307 .cbs
.cli_show
= cli_show_rip_default_metric
,
1310 .xpath
= "/frr-ripd:ripd/instance/distance/default",
1311 .cbs
.modify
= ripd_instance_distance_default_modify
,
1312 .cbs
.cli_show
= cli_show_rip_distance
,
1315 .xpath
= "/frr-ripd:ripd/instance/distance/source",
1316 .cbs
.create
= ripd_instance_distance_source_create
,
1317 .cbs
.delete = ripd_instance_distance_source_delete
,
1318 .cbs
.cli_show
= cli_show_rip_distance_source
,
1321 .xpath
= "/frr-ripd:ripd/instance/distance/source/distance",
1322 .cbs
.modify
= ripd_instance_distance_source_distance_modify
,
1325 .xpath
= "/frr-ripd:ripd/instance/distance/source/access-list",
1326 .cbs
.modify
= ripd_instance_distance_source_access_list_modify
,
1327 .cbs
.delete = ripd_instance_distance_source_access_list_delete
,
1330 .xpath
= "/frr-ripd:ripd/instance/explicit-neighbor",
1331 .cbs
.create
= ripd_instance_explicit_neighbor_create
,
1332 .cbs
.delete = ripd_instance_explicit_neighbor_delete
,
1333 .cbs
.cli_show
= cli_show_rip_neighbor
,
1336 .xpath
= "/frr-ripd:ripd/instance/network",
1337 .cbs
.create
= ripd_instance_network_create
,
1338 .cbs
.delete = ripd_instance_network_delete
,
1339 .cbs
.cli_show
= cli_show_rip_network_prefix
,
1342 .xpath
= "/frr-ripd:ripd/instance/interface",
1343 .cbs
.create
= ripd_instance_interface_create
,
1344 .cbs
.delete = ripd_instance_interface_delete
,
1345 .cbs
.cli_show
= cli_show_rip_network_interface
,
1348 .xpath
= "/frr-ripd:ripd/instance/offset-list",
1349 .cbs
.create
= ripd_instance_offset_list_create
,
1350 .cbs
.delete = ripd_instance_offset_list_delete
,
1351 .cbs
.cli_show
= cli_show_rip_offset_list
,
1354 .xpath
= "/frr-ripd:ripd/instance/offset-list/access-list",
1355 .cbs
.modify
= ripd_instance_offset_list_access_list_modify
,
1358 .xpath
= "/frr-ripd:ripd/instance/offset-list/metric",
1359 .cbs
.modify
= ripd_instance_offset_list_metric_modify
,
1362 .xpath
= "/frr-ripd:ripd/instance/passive-default",
1363 .cbs
.modify
= ripd_instance_passive_default_modify
,
1364 .cbs
.cli_show
= cli_show_rip_passive_default
,
1367 .xpath
= "/frr-ripd:ripd/instance/passive-interface",
1368 .cbs
.create
= ripd_instance_passive_interface_create
,
1369 .cbs
.delete = ripd_instance_passive_interface_delete
,
1370 .cbs
.cli_show
= cli_show_rip_passive_interface
,
1373 .xpath
= "/frr-ripd:ripd/instance/non-passive-interface",
1374 .cbs
.create
= ripd_instance_non_passive_interface_create
,
1375 .cbs
.delete = ripd_instance_non_passive_interface_delete
,
1376 .cbs
.cli_show
= cli_show_rip_non_passive_interface
,
1379 .xpath
= "/frr-ripd:ripd/instance/redistribute",
1380 .cbs
.create
= ripd_instance_redistribute_create
,
1381 .cbs
.delete = ripd_instance_redistribute_delete
,
1382 .cbs
.apply_finish
= ripd_instance_redistribute_apply_finish
,
1383 .cbs
.cli_show
= cli_show_rip_redistribute
,
1386 .xpath
= "/frr-ripd:ripd/instance/redistribute/route-map",
1387 .cbs
.modify
= ripd_instance_redistribute_route_map_modify
,
1388 .cbs
.delete = ripd_instance_redistribute_route_map_delete
,
1391 .xpath
= "/frr-ripd:ripd/instance/redistribute/metric",
1392 .cbs
.modify
= ripd_instance_redistribute_metric_modify
,
1393 .cbs
.delete = ripd_instance_redistribute_metric_delete
,
1396 .xpath
= "/frr-ripd:ripd/instance/static-route",
1397 .cbs
.create
= ripd_instance_static_route_create
,
1398 .cbs
.delete = ripd_instance_static_route_delete
,
1399 .cbs
.cli_show
= cli_show_rip_route
,
1402 .xpath
= "/frr-ripd:ripd/instance/timers",
1403 .cbs
.apply_finish
= ripd_instance_timers_apply_finish
,
1404 .cbs
.cli_show
= cli_show_rip_timers
,
1407 .xpath
= "/frr-ripd:ripd/instance/timers/flush-interval",
1408 .cbs
.modify
= ripd_instance_timers_flush_interval_modify
,
1411 .xpath
= "/frr-ripd:ripd/instance/timers/holddown-interval",
1412 .cbs
.modify
= ripd_instance_timers_holddown_interval_modify
,
1415 .xpath
= "/frr-ripd:ripd/instance/timers/update-interval",
1416 .cbs
.modify
= ripd_instance_timers_update_interval_modify
,
1419 .xpath
= "/frr-ripd:ripd/instance/version",
1420 .cbs
.cli_show
= cli_show_rip_version
,
1423 .xpath
= "/frr-ripd:ripd/instance/version/receive",
1424 .cbs
.modify
= ripd_instance_version_receive_modify
,
1427 .xpath
= "/frr-ripd:ripd/instance/version/send",
1428 .cbs
.modify
= ripd_instance_version_send_modify
,
1431 .xpath
= "/frr-interface:lib/interface/frr-ripd:rip/split-horizon",
1432 .cbs
.modify
= lib_interface_rip_split_horizon_modify
,
1433 .cbs
.cli_show
= cli_show_ip_rip_split_horizon
,
1436 .xpath
= "/frr-interface:lib/interface/frr-ripd:rip/v2-broadcast",
1437 .cbs
.modify
= lib_interface_rip_v2_broadcast_modify
,
1438 .cbs
.cli_show
= cli_show_ip_rip_v2_broadcast
,
1441 .xpath
= "/frr-interface:lib/interface/frr-ripd:rip/version-receive",
1442 .cbs
.modify
= lib_interface_rip_version_receive_modify
,
1443 .cbs
.cli_show
= cli_show_ip_rip_receive_version
,
1446 .xpath
= "/frr-interface:lib/interface/frr-ripd:rip/version-send",
1447 .cbs
.modify
= lib_interface_rip_version_send_modify
,
1448 .cbs
.cli_show
= cli_show_ip_rip_send_version
,
1451 .xpath
= "/frr-interface:lib/interface/frr-ripd:rip/authentication-scheme",
1452 .cbs
.cli_show
= cli_show_ip_rip_authentication_scheme
,
1455 .xpath
= "/frr-interface:lib/interface/frr-ripd:rip/authentication-scheme/mode",
1456 .cbs
.modify
= lib_interface_rip_authentication_scheme_mode_modify
,
1459 .xpath
= "/frr-interface:lib/interface/frr-ripd:rip/authentication-scheme/md5-auth-length",
1460 .cbs
.modify
= lib_interface_rip_authentication_scheme_md5_auth_length_modify
,
1461 .cbs
.delete = lib_interface_rip_authentication_scheme_md5_auth_length_delete
,
1464 .xpath
= "/frr-interface:lib/interface/frr-ripd:rip/authentication-password",
1465 .cbs
.modify
= lib_interface_rip_authentication_password_modify
,
1466 .cbs
.delete = lib_interface_rip_authentication_password_delete
,
1467 .cbs
.cli_show
= cli_show_ip_rip_authentication_string
,
1470 .xpath
= "/frr-interface:lib/interface/frr-ripd:rip/authentication-key-chain",
1471 .cbs
.modify
= lib_interface_rip_authentication_key_chain_modify
,
1472 .cbs
.delete = lib_interface_rip_authentication_key_chain_delete
,
1473 .cbs
.cli_show
= cli_show_ip_rip_authentication_key_chain
,
1476 .xpath
= "/frr-ripd:ripd/state/neighbors/neighbor",
1477 .cbs
.get_next
= ripd_state_neighbors_neighbor_get_next
,
1478 .cbs
.get_keys
= ripd_state_neighbors_neighbor_get_keys
,
1479 .cbs
.lookup_entry
= ripd_state_neighbors_neighbor_lookup_entry
,
1482 .xpath
= "/frr-ripd:ripd/state/neighbors/neighbor/address",
1483 .cbs
.get_elem
= ripd_state_neighbors_neighbor_address_get_elem
,
1486 .xpath
= "/frr-ripd:ripd/state/neighbors/neighbor/last-update",
1487 .cbs
.get_elem
= ripd_state_neighbors_neighbor_last_update_get_elem
,
1490 .xpath
= "/frr-ripd:ripd/state/neighbors/neighbor/bad-packets-rcvd",
1491 .cbs
.get_elem
= ripd_state_neighbors_neighbor_bad_packets_rcvd_get_elem
,
1494 .xpath
= "/frr-ripd:ripd/state/neighbors/neighbor/bad-routes-rcvd",
1495 .cbs
.get_elem
= ripd_state_neighbors_neighbor_bad_routes_rcvd_get_elem
,
1498 .xpath
= "/frr-ripd:ripd/state/routes/route",
1499 .cbs
.get_next
= ripd_state_routes_route_get_next
,
1500 .cbs
.get_keys
= ripd_state_routes_route_get_keys
,
1501 .cbs
.lookup_entry
= ripd_state_routes_route_lookup_entry
,
1504 .xpath
= "/frr-ripd:ripd/state/routes/route/prefix",
1505 .cbs
.get_elem
= ripd_state_routes_route_prefix_get_elem
,
1508 .xpath
= "/frr-ripd:ripd/state/routes/route/next-hop",
1509 .cbs
.get_elem
= ripd_state_routes_route_next_hop_get_elem
,
1512 .xpath
= "/frr-ripd:ripd/state/routes/route/interface",
1513 .cbs
.get_elem
= ripd_state_routes_route_interface_get_elem
,
1516 .xpath
= "/frr-ripd:ripd/state/routes/route/metric",
1517 .cbs
.get_elem
= ripd_state_routes_route_metric_get_elem
,
1520 .xpath
= "/frr-ripd:clear-rip-route",
1521 .cbs
.rpc
= clear_rip_route_rpc
,