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
)
48 vrf_name
= yang_dnode_get_string(dnode
, "./vrf");
49 vrf
= vrf_lookup_by_name(vrf_name
);
52 * Try to create a RIP socket only if the VRF is enabled, otherwise
53 * create a disabled RIP instance and wait for the VRF to be enabled.
59 if (!vrf
|| !vrf_is_enabled(vrf
))
62 socket
= rip_create_socket(vrf
);
64 return NB_ERR_RESOURCE
;
65 resource
->fd
= socket
;
68 if (!vrf
|| !vrf_is_enabled(vrf
))
71 socket
= resource
->fd
;
75 if (vrf
&& vrf_is_enabled(vrf
))
76 socket
= resource
->fd
;
80 rip
= rip_create(vrf_name
, vrf
, socket
);
81 yang_dnode_set_entry(dnode
, rip
);
88 static int ripd_instance_delete(enum nb_event event
,
89 const struct lyd_node
*dnode
)
93 if (event
!= NB_EV_APPLY
)
96 rip
= yang_dnode_get_entry(dnode
, true);
102 static const void *ripd_instance_get_next(const void *parent_list_entry
,
103 const void *list_entry
)
105 const struct rip
*rip
= list_entry
;
107 if (list_entry
== NULL
)
108 rip
= RB_MIN(rip_instance_head
, &rip_instances
);
110 rip
= RB_NEXT(rip_instance_head
, (struct rip
*)rip
);
115 static int ripd_instance_get_keys(const void *list_entry
,
116 struct yang_list_keys
*keys
)
118 const struct rip
*rip
= list_entry
;
121 strlcpy(keys
->key
[0], rip
->vrf_name
, sizeof(keys
->key
[0]));
126 static const void *ripd_instance_lookup_entry(const void *parent_list_entry
,
127 const struct yang_list_keys
*keys
)
129 const char *vrf_name
= keys
->key
[0];
131 return rip_lookup_by_vrf_name(vrf_name
);
135 * XPath: /frr-ripd:ripd/instance/allow-ecmp
137 static int ripd_instance_allow_ecmp_modify(enum nb_event event
,
138 const struct lyd_node
*dnode
,
139 union nb_resource
*resource
)
143 if (event
!= NB_EV_APPLY
)
146 rip
= yang_dnode_get_entry(dnode
, true);
147 rip
->ecmp
= yang_dnode_get_bool(dnode
, NULL
);
149 rip_ecmp_disable(rip
);
155 * XPath: /frr-ripd:ripd/instance/default-information-originate
158 ripd_instance_default_information_originate_modify(enum nb_event event
,
159 const struct lyd_node
*dnode
,
160 union nb_resource
*resource
)
163 bool default_information
;
164 struct prefix_ipv4 p
;
166 if (event
!= NB_EV_APPLY
)
169 rip
= yang_dnode_get_entry(dnode
, true);
170 default_information
= yang_dnode_get_bool(dnode
, NULL
);
172 memset(&p
, 0, sizeof(struct prefix_ipv4
));
174 if (default_information
) {
177 memset(&nh
, 0, sizeof(nh
));
178 nh
.type
= NEXTHOP_TYPE_IPV4
;
179 rip_redistribute_add(rip
, ZEBRA_ROUTE_RIP
, RIP_ROUTE_DEFAULT
,
182 rip_redistribute_delete(rip
, ZEBRA_ROUTE_RIP
, RIP_ROUTE_DEFAULT
,
190 * XPath: /frr-ripd:ripd/instance/default-metric
192 static int ripd_instance_default_metric_modify(enum nb_event event
,
193 const struct lyd_node
*dnode
,
194 union nb_resource
*resource
)
198 if (event
!= NB_EV_APPLY
)
201 rip
= yang_dnode_get_entry(dnode
, true);
202 rip
->default_metric
= yang_dnode_get_uint8(dnode
, NULL
);
203 /* rip_update_default_metric (); */
209 * XPath: /frr-ripd:ripd/instance/distance/default
211 static int ripd_instance_distance_default_modify(enum nb_event event
,
212 const struct lyd_node
*dnode
,
213 union nb_resource
*resource
)
217 if (event
!= NB_EV_APPLY
)
220 rip
= yang_dnode_get_entry(dnode
, true);
221 rip
->distance
= yang_dnode_get_uint8(dnode
, NULL
);
227 * XPath: /frr-ripd:ripd/instance/distance/source
229 static int ripd_instance_distance_source_create(enum nb_event event
,
230 const struct lyd_node
*dnode
,
231 union nb_resource
*resource
)
234 struct prefix_ipv4 prefix
;
235 struct route_node
*rn
;
237 if (event
!= NB_EV_APPLY
)
240 yang_dnode_get_ipv4p(&prefix
, dnode
, "./prefix");
241 apply_mask_ipv4(&prefix
);
243 /* Get RIP distance node. */
244 rip
= yang_dnode_get_entry(dnode
, true);
245 rn
= route_node_get(rip
->distance_table
, (struct prefix
*)&prefix
);
246 rn
->info
= rip_distance_new();
247 yang_dnode_set_entry(dnode
, rn
);
252 static int ripd_instance_distance_source_delete(enum nb_event event
,
253 const struct lyd_node
*dnode
)
255 struct route_node
*rn
;
256 struct rip_distance
*rdistance
;
258 if (event
!= NB_EV_APPLY
)
261 rn
= yang_dnode_get_entry(dnode
, true);
262 rdistance
= rn
->info
;
263 rip_distance_free(rdistance
);
265 route_unlock_node(rn
);
271 * XPath: /frr-ripd:ripd/instance/distance/source/distance
274 ripd_instance_distance_source_distance_modify(enum nb_event event
,
275 const struct lyd_node
*dnode
,
276 union nb_resource
*resource
)
278 struct route_node
*rn
;
280 struct rip_distance
*rdistance
;
282 if (event
!= NB_EV_APPLY
)
285 /* Set distance value. */
286 rn
= yang_dnode_get_entry(dnode
, true);
287 distance
= yang_dnode_get_uint8(dnode
, NULL
);
288 rdistance
= rn
->info
;
289 rdistance
->distance
= distance
;
295 * XPath: /frr-ripd:ripd/instance/distance/source/access-list
298 ripd_instance_distance_source_access_list_modify(enum nb_event event
,
299 const struct lyd_node
*dnode
,
300 union nb_resource
*resource
)
302 const char *acl_name
;
303 struct route_node
*rn
;
304 struct rip_distance
*rdistance
;
306 if (event
!= NB_EV_APPLY
)
309 acl_name
= yang_dnode_get_string(dnode
, NULL
);
311 /* Set access-list */
312 rn
= yang_dnode_get_entry(dnode
, true);
313 rdistance
= rn
->info
;
314 if (rdistance
->access_list
)
315 free(rdistance
->access_list
);
316 rdistance
->access_list
= strdup(acl_name
);
322 ripd_instance_distance_source_access_list_delete(enum nb_event event
,
323 const struct lyd_node
*dnode
)
325 struct route_node
*rn
;
326 struct rip_distance
*rdistance
;
328 if (event
!= NB_EV_APPLY
)
331 /* Reset access-list configuration. */
332 rn
= yang_dnode_get_entry(dnode
, true);
333 rdistance
= rn
->info
;
334 free(rdistance
->access_list
);
335 rdistance
->access_list
= NULL
;
341 * XPath: /frr-ripd:ripd/instance/explicit-neighbor
343 static int ripd_instance_explicit_neighbor_create(enum nb_event event
,
344 const struct lyd_node
*dnode
,
345 union nb_resource
*resource
)
348 struct prefix_ipv4 p
;
350 if (event
!= NB_EV_APPLY
)
353 rip
= yang_dnode_get_entry(dnode
, true);
355 p
.prefixlen
= IPV4_MAX_BITLEN
;
356 yang_dnode_get_ipv4(&p
.prefix
, dnode
, NULL
);
358 return rip_neighbor_add(rip
, &p
);
361 static int ripd_instance_explicit_neighbor_delete(enum nb_event event
,
362 const struct lyd_node
*dnode
)
365 struct prefix_ipv4 p
;
367 if (event
!= NB_EV_APPLY
)
370 rip
= yang_dnode_get_entry(dnode
, true);
372 p
.prefixlen
= IPV4_MAX_BITLEN
;
373 yang_dnode_get_ipv4(&p
.prefix
, dnode
, NULL
);
375 return rip_neighbor_delete(rip
, &p
);
379 * XPath: /frr-ripd:ripd/instance/network
381 static int ripd_instance_network_create(enum nb_event event
,
382 const struct lyd_node
*dnode
,
383 union nb_resource
*resource
)
388 if (event
!= NB_EV_APPLY
)
391 rip
= yang_dnode_get_entry(dnode
, true);
392 yang_dnode_get_ipv4p(&p
, dnode
, NULL
);
393 apply_mask_ipv4((struct prefix_ipv4
*)&p
);
395 return rip_enable_network_add(rip
, &p
);
398 static int ripd_instance_network_delete(enum nb_event event
,
399 const struct lyd_node
*dnode
)
404 if (event
!= NB_EV_APPLY
)
407 rip
= yang_dnode_get_entry(dnode
, true);
408 yang_dnode_get_ipv4p(&p
, dnode
, NULL
);
409 apply_mask_ipv4((struct prefix_ipv4
*)&p
);
411 return rip_enable_network_delete(rip
, &p
);
415 * XPath: /frr-ripd:ripd/instance/interface
417 static int ripd_instance_interface_create(enum nb_event event
,
418 const struct lyd_node
*dnode
,
419 union nb_resource
*resource
)
424 if (event
!= NB_EV_APPLY
)
427 rip
= yang_dnode_get_entry(dnode
, true);
428 ifname
= yang_dnode_get_string(dnode
, NULL
);
430 return rip_enable_if_add(rip
, ifname
);
433 static int ripd_instance_interface_delete(enum nb_event event
,
434 const struct lyd_node
*dnode
)
439 if (event
!= NB_EV_APPLY
)
442 rip
= yang_dnode_get_entry(dnode
, true);
443 ifname
= yang_dnode_get_string(dnode
, NULL
);
445 return rip_enable_if_delete(rip
, ifname
);
449 * XPath: /frr-ripd:ripd/instance/offset-list
451 static int ripd_instance_offset_list_create(enum nb_event event
,
452 const struct lyd_node
*dnode
,
453 union nb_resource
*resource
)
457 struct rip_offset_list
*offset
;
459 if (event
!= NB_EV_APPLY
)
462 rip
= yang_dnode_get_entry(dnode
, true);
463 ifname
= yang_dnode_get_string(dnode
, "./interface");
465 offset
= rip_offset_list_new(rip
, ifname
);
466 yang_dnode_set_entry(dnode
, offset
);
471 static int ripd_instance_offset_list_delete(enum nb_event event
,
472 const struct lyd_node
*dnode
)
475 struct rip_offset_list
*offset
;
477 if (event
!= NB_EV_APPLY
)
480 direct
= yang_dnode_get_enum(dnode
, "./direction");
482 offset
= yang_dnode_get_entry(dnode
, true);
483 if (offset
->direct
[direct
].alist_name
) {
484 free(offset
->direct
[direct
].alist_name
);
485 offset
->direct
[direct
].alist_name
= NULL
;
487 if (offset
->direct
[RIP_OFFSET_LIST_IN
].alist_name
== NULL
488 && offset
->direct
[RIP_OFFSET_LIST_OUT
].alist_name
== NULL
)
489 offset_list_del(offset
);
495 * XPath: /frr-ripd:ripd/instance/offset-list/access-list
498 ripd_instance_offset_list_access_list_modify(enum nb_event event
,
499 const struct lyd_node
*dnode
,
500 union nb_resource
*resource
)
503 struct rip_offset_list
*offset
;
504 const char *alist_name
;
506 if (event
!= NB_EV_APPLY
)
509 direct
= yang_dnode_get_enum(dnode
, "../direction");
510 alist_name
= yang_dnode_get_string(dnode
, NULL
);
512 offset
= yang_dnode_get_entry(dnode
, true);
513 if (offset
->direct
[direct
].alist_name
)
514 free(offset
->direct
[direct
].alist_name
);
515 offset
->direct
[direct
].alist_name
= strdup(alist_name
);
521 * XPath: /frr-ripd:ripd/instance/offset-list/metric
523 static int ripd_instance_offset_list_metric_modify(enum nb_event event
,
524 const struct lyd_node
*dnode
,
525 union nb_resource
*resource
)
529 struct rip_offset_list
*offset
;
531 if (event
!= NB_EV_APPLY
)
534 direct
= yang_dnode_get_enum(dnode
, "../direction");
535 metric
= yang_dnode_get_uint8(dnode
, NULL
);
537 offset
= yang_dnode_get_entry(dnode
, true);
538 offset
->direct
[direct
].metric
= metric
;
544 * XPath: /frr-ripd:ripd/instance/passive-default
546 static int ripd_instance_passive_default_modify(enum nb_event event
,
547 const struct lyd_node
*dnode
,
548 union nb_resource
*resource
)
552 if (event
!= NB_EV_APPLY
)
555 rip
= yang_dnode_get_entry(dnode
, true);
556 rip
->passive_default
= yang_dnode_get_bool(dnode
, NULL
);
557 rip_passive_nondefault_clean(rip
);
563 * XPath: /frr-ripd:ripd/instance/passive-interface
565 static int ripd_instance_passive_interface_create(enum nb_event event
,
566 const struct lyd_node
*dnode
,
567 union nb_resource
*resource
)
572 if (event
!= NB_EV_APPLY
)
575 rip
= yang_dnode_get_entry(dnode
, true);
576 ifname
= yang_dnode_get_string(dnode
, NULL
);
578 return rip_passive_nondefault_set(rip
, ifname
);
581 static int ripd_instance_passive_interface_delete(enum nb_event event
,
582 const struct lyd_node
*dnode
)
587 if (event
!= NB_EV_APPLY
)
590 rip
= yang_dnode_get_entry(dnode
, true);
591 ifname
= yang_dnode_get_string(dnode
, NULL
);
593 return rip_passive_nondefault_unset(rip
, ifname
);
597 * XPath: /frr-ripd:ripd/instance/non-passive-interface
600 ripd_instance_non_passive_interface_create(enum nb_event event
,
601 const struct lyd_node
*dnode
,
602 union nb_resource
*resource
)
607 if (event
!= NB_EV_APPLY
)
610 rip
= yang_dnode_get_entry(dnode
, true);
611 ifname
= yang_dnode_get_string(dnode
, NULL
);
613 return rip_passive_nondefault_unset(rip
, ifname
);
617 ripd_instance_non_passive_interface_delete(enum nb_event event
,
618 const struct lyd_node
*dnode
)
623 if (event
!= NB_EV_APPLY
)
626 rip
= yang_dnode_get_entry(dnode
, true);
627 ifname
= yang_dnode_get_string(dnode
, NULL
);
629 return rip_passive_nondefault_set(rip
, ifname
);
633 * XPath: /frr-ripd:ripd/instance/redistribute
635 static int ripd_instance_redistribute_create(enum nb_event event
,
636 const struct lyd_node
*dnode
,
637 union nb_resource
*resource
)
642 static int ripd_instance_redistribute_delete(enum nb_event event
,
643 const struct lyd_node
*dnode
)
648 if (event
!= NB_EV_APPLY
)
651 rip
= yang_dnode_get_entry(dnode
, true);
652 type
= yang_dnode_get_enum(dnode
, "./protocol");
654 rip_redistribute_conf_delete(rip
, type
);
660 ripd_instance_redistribute_apply_finish(const struct lyd_node
*dnode
)
665 rip
= yang_dnode_get_entry(dnode
, true);
666 type
= yang_dnode_get_enum(dnode
, "./protocol");
668 rip_redistribute_conf_update(rip
, type
);
672 * XPath: /frr-ripd:ripd/instance/redistribute/route-map
675 ripd_instance_redistribute_route_map_modify(enum nb_event event
,
676 const struct lyd_node
*dnode
,
677 union nb_resource
*resource
)
681 const char *rmap_name
;
683 if (event
!= NB_EV_APPLY
)
686 rip
= yang_dnode_get_entry(dnode
, true);
687 type
= yang_dnode_get_enum(dnode
, "../protocol");
688 rmap_name
= yang_dnode_get_string(dnode
, NULL
);
690 if (rip
->route_map
[type
].name
)
691 free(rip
->route_map
[type
].name
);
692 rip
->route_map
[type
].name
= strdup(rmap_name
);
693 rip
->route_map
[type
].map
= route_map_lookup_by_name(rmap_name
);
699 ripd_instance_redistribute_route_map_delete(enum nb_event event
,
700 const struct lyd_node
*dnode
)
705 if (event
!= NB_EV_APPLY
)
708 rip
= yang_dnode_get_entry(dnode
, true);
709 type
= yang_dnode_get_enum(dnode
, "../protocol");
711 free(rip
->route_map
[type
].name
);
712 rip
->route_map
[type
].name
= NULL
;
713 rip
->route_map
[type
].map
= NULL
;
719 * XPath: /frr-ripd:ripd/instance/redistribute/metric
722 ripd_instance_redistribute_metric_modify(enum nb_event event
,
723 const struct lyd_node
*dnode
,
724 union nb_resource
*resource
)
730 if (event
!= NB_EV_APPLY
)
733 rip
= yang_dnode_get_entry(dnode
, true);
734 type
= yang_dnode_get_enum(dnode
, "../protocol");
735 metric
= yang_dnode_get_uint8(dnode
, NULL
);
737 rip
->route_map
[type
].metric_config
= true;
738 rip
->route_map
[type
].metric
= metric
;
744 ripd_instance_redistribute_metric_delete(enum nb_event event
,
745 const struct lyd_node
*dnode
)
750 if (event
!= NB_EV_APPLY
)
753 rip
= yang_dnode_get_entry(dnode
, true);
754 type
= yang_dnode_get_enum(dnode
, "../protocol");
756 rip
->route_map
[type
].metric_config
= false;
757 rip
->route_map
[type
].metric
= 0;
763 * XPath: /frr-ripd:ripd/instance/static-route
765 static int ripd_instance_static_route_create(enum nb_event event
,
766 const struct lyd_node
*dnode
,
767 union nb_resource
*resource
)
771 struct prefix_ipv4 p
;
773 if (event
!= NB_EV_APPLY
)
776 rip
= yang_dnode_get_entry(dnode
, true);
777 yang_dnode_get_ipv4p(&p
, dnode
, NULL
);
780 memset(&nh
, 0, sizeof(nh
));
781 nh
.type
= NEXTHOP_TYPE_IPV4
;
782 rip_redistribute_add(rip
, ZEBRA_ROUTE_RIP
, RIP_ROUTE_STATIC
, &p
, &nh
, 0,
788 static int ripd_instance_static_route_delete(enum nb_event event
,
789 const struct lyd_node
*dnode
)
792 struct prefix_ipv4 p
;
794 if (event
!= NB_EV_APPLY
)
797 rip
= yang_dnode_get_entry(dnode
, true);
798 yang_dnode_get_ipv4p(&p
, dnode
, NULL
);
801 rip_redistribute_delete(rip
, ZEBRA_ROUTE_RIP
, RIP_ROUTE_STATIC
, &p
, 0);
807 * XPath: /frr-ripd:ripd/instance/timers/
809 static void ripd_instance_timers_apply_finish(const struct lyd_node
*dnode
)
813 rip
= yang_dnode_get_entry(dnode
, true);
815 /* Reset update timer thread. */
816 rip_event(rip
, RIP_UPDATE_EVENT
, 0);
820 * XPath: /frr-ripd:ripd/instance/timers/flush-interval
823 ripd_instance_timers_flush_interval_modify(enum nb_event event
,
824 const struct lyd_node
*dnode
,
825 union nb_resource
*resource
)
829 if (event
!= NB_EV_APPLY
)
832 rip
= yang_dnode_get_entry(dnode
, true);
833 rip
->garbage_time
= yang_dnode_get_uint32(dnode
, NULL
);
839 * XPath: /frr-ripd:ripd/instance/timers/holddown-interval
842 ripd_instance_timers_holddown_interval_modify(enum nb_event event
,
843 const struct lyd_node
*dnode
,
844 union nb_resource
*resource
)
848 if (event
!= NB_EV_APPLY
)
851 rip
= yang_dnode_get_entry(dnode
, true);
852 rip
->timeout_time
= yang_dnode_get_uint32(dnode
, NULL
);
858 * XPath: /frr-ripd:ripd/instance/timers/update-interval
861 ripd_instance_timers_update_interval_modify(enum nb_event event
,
862 const struct lyd_node
*dnode
,
863 union nb_resource
*resource
)
867 if (event
!= NB_EV_APPLY
)
870 rip
= yang_dnode_get_entry(dnode
, true);
871 rip
->update_time
= yang_dnode_get_uint32(dnode
, NULL
);
877 * XPath: /frr-ripd:ripd/instance/version/receive
879 static int ripd_instance_version_receive_modify(enum nb_event event
,
880 const struct lyd_node
*dnode
,
881 union nb_resource
*resource
)
885 if (event
!= NB_EV_APPLY
)
888 rip
= yang_dnode_get_entry(dnode
, true);
889 rip
->version_recv
= yang_dnode_get_enum(dnode
, NULL
);
895 * XPath: /frr-ripd:ripd/instance/version/send
897 static int ripd_instance_version_send_modify(enum nb_event event
,
898 const struct lyd_node
*dnode
,
899 union nb_resource
*resource
)
903 if (event
!= NB_EV_APPLY
)
906 rip
= yang_dnode_get_entry(dnode
, true);
907 rip
->version_send
= yang_dnode_get_enum(dnode
, NULL
);
913 * XPath: /frr-interface:lib/interface/frr-ripd:rip/split-horizon
915 static int lib_interface_rip_split_horizon_modify(enum nb_event event
,
916 const struct lyd_node
*dnode
,
917 union nb_resource
*resource
)
919 struct interface
*ifp
;
920 struct rip_interface
*ri
;
922 if (event
!= NB_EV_APPLY
)
925 ifp
= yang_dnode_get_entry(dnode
, true);
927 ri
->split_horizon
= yang_dnode_get_enum(dnode
, NULL
);
933 * XPath: /frr-interface:lib/interface/frr-ripd:rip/v2-broadcast
935 static int lib_interface_rip_v2_broadcast_modify(enum nb_event event
,
936 const struct lyd_node
*dnode
,
937 union nb_resource
*resource
)
939 struct interface
*ifp
;
940 struct rip_interface
*ri
;
942 if (event
!= NB_EV_APPLY
)
945 ifp
= yang_dnode_get_entry(dnode
, true);
947 ri
->v2_broadcast
= yang_dnode_get_bool(dnode
, NULL
);
953 * XPath: /frr-interface:lib/interface/frr-ripd:rip/version-receive
956 lib_interface_rip_version_receive_modify(enum nb_event event
,
957 const struct lyd_node
*dnode
,
958 union nb_resource
*resource
)
960 struct interface
*ifp
;
961 struct rip_interface
*ri
;
963 if (event
!= NB_EV_APPLY
)
966 ifp
= yang_dnode_get_entry(dnode
, true);
968 ri
->ri_receive
= yang_dnode_get_enum(dnode
, NULL
);
974 * XPath: /frr-interface:lib/interface/frr-ripd:rip/version-send
976 static int lib_interface_rip_version_send_modify(enum nb_event event
,
977 const struct lyd_node
*dnode
,
978 union nb_resource
*resource
)
980 struct interface
*ifp
;
981 struct rip_interface
*ri
;
983 if (event
!= NB_EV_APPLY
)
986 ifp
= yang_dnode_get_entry(dnode
, true);
988 ri
->ri_send
= yang_dnode_get_enum(dnode
, NULL
);
994 * XPath: /frr-interface:lib/interface/frr-ripd:rip/authentication-scheme/mode
996 static int lib_interface_rip_authentication_scheme_mode_modify(
997 enum nb_event event
, const struct lyd_node
*dnode
,
998 union nb_resource
*resource
)
1000 struct interface
*ifp
;
1001 struct rip_interface
*ri
;
1003 if (event
!= NB_EV_APPLY
)
1006 ifp
= yang_dnode_get_entry(dnode
, true);
1008 ri
->auth_type
= yang_dnode_get_enum(dnode
, NULL
);
1015 * /frr-interface:lib/interface/frr-ripd:rip/authentication-scheme/md5-auth-length
1017 static int lib_interface_rip_authentication_scheme_md5_auth_length_modify(
1018 enum nb_event event
, const struct lyd_node
*dnode
,
1019 union nb_resource
*resource
)
1021 struct interface
*ifp
;
1022 struct rip_interface
*ri
;
1024 if (event
!= NB_EV_APPLY
)
1027 ifp
= yang_dnode_get_entry(dnode
, true);
1029 ri
->md5_auth_len
= yang_dnode_get_enum(dnode
, NULL
);
1034 static int lib_interface_rip_authentication_scheme_md5_auth_length_delete(
1035 enum nb_event event
, const struct lyd_node
*dnode
)
1037 struct interface
*ifp
;
1038 struct rip_interface
*ri
;
1040 if (event
!= NB_EV_APPLY
)
1043 ifp
= yang_dnode_get_entry(dnode
, true);
1045 ri
->md5_auth_len
= yang_get_default_enum(
1046 "%s/authentication-scheme/md5-auth-length", RIP_IFACE
);
1052 * XPath: /frr-interface:lib/interface/frr-ripd:rip/authentication-password
1055 lib_interface_rip_authentication_password_modify(enum nb_event event
,
1056 const struct lyd_node
*dnode
,
1057 union nb_resource
*resource
)
1059 struct interface
*ifp
;
1060 struct rip_interface
*ri
;
1062 if (event
!= NB_EV_APPLY
)
1065 ifp
= yang_dnode_get_entry(dnode
, true);
1068 XFREE(MTYPE_RIP_INTERFACE_STRING
, ri
->auth_str
);
1069 ri
->auth_str
= XSTRDUP(MTYPE_RIP_INTERFACE_STRING
,
1070 yang_dnode_get_string(dnode
, NULL
));
1076 lib_interface_rip_authentication_password_delete(enum nb_event event
,
1077 const struct lyd_node
*dnode
)
1079 struct interface
*ifp
;
1080 struct rip_interface
*ri
;
1082 if (event
!= NB_EV_APPLY
)
1085 ifp
= yang_dnode_get_entry(dnode
, true);
1087 XFREE(MTYPE_RIP_INTERFACE_STRING
, ri
->auth_str
);
1093 * XPath: /frr-interface:lib/interface/frr-ripd:rip/authentication-key-chain
1096 lib_interface_rip_authentication_key_chain_modify(enum nb_event event
,
1097 const struct lyd_node
*dnode
,
1098 union nb_resource
*resource
)
1100 struct interface
*ifp
;
1101 struct rip_interface
*ri
;
1103 if (event
!= NB_EV_APPLY
)
1106 ifp
= yang_dnode_get_entry(dnode
, true);
1109 XFREE(MTYPE_RIP_INTERFACE_STRING
, ri
->key_chain
);
1110 ri
->key_chain
= XSTRDUP(MTYPE_RIP_INTERFACE_STRING
,
1111 yang_dnode_get_string(dnode
, NULL
));
1117 lib_interface_rip_authentication_key_chain_delete(enum nb_event event
,
1118 const struct lyd_node
*dnode
)
1120 struct interface
*ifp
;
1121 struct rip_interface
*ri
;
1123 if (event
!= NB_EV_APPLY
)
1126 ifp
= yang_dnode_get_entry(dnode
, true);
1128 XFREE(MTYPE_RIP_INTERFACE_STRING
, ri
->key_chain
);
1134 * XPath: /frr-ripd:ripd/instance/state/neighbors/neighbor
1137 ripd_instance_state_neighbors_neighbor_get_next(const void *parent_list_entry
,
1138 const void *list_entry
)
1140 const struct rip
*rip
= parent_list_entry
;
1141 struct listnode
*node
;
1143 if (list_entry
== NULL
)
1144 node
= listhead(rip
->peer_list
);
1146 node
= listnextnode((struct listnode
*)list_entry
);
1152 ripd_instance_state_neighbors_neighbor_get_keys(const void *list_entry
,
1153 struct yang_list_keys
*keys
)
1155 const struct listnode
*node
= list_entry
;
1156 const struct rip_peer
*peer
= listgetdata(node
);
1159 (void)inet_ntop(AF_INET
, &peer
->addr
, keys
->key
[0],
1160 sizeof(keys
->key
[0]));
1165 static const void *ripd_instance_state_neighbors_neighbor_lookup_entry(
1166 const void *parent_list_entry
, const struct yang_list_keys
*keys
)
1168 const struct rip
*rip
= parent_list_entry
;
1169 struct in_addr address
;
1170 struct rip_peer
*peer
;
1171 struct listnode
*node
;
1173 yang_str2ipv4(keys
->key
[0], &address
);
1175 for (ALL_LIST_ELEMENTS_RO(rip
->peer_list
, node
, peer
)) {
1176 if (IPV4_ADDR_SAME(&peer
->addr
, &address
))
1184 * XPath: /frr-ripd:ripd/instance/state/neighbors/neighbor/address
1186 static struct yang_data
*
1187 ripd_instance_state_neighbors_neighbor_address_get_elem(const char *xpath
,
1188 const void *list_entry
)
1190 const struct listnode
*node
= list_entry
;
1191 const struct rip_peer
*peer
= listgetdata(node
);
1193 return yang_data_new_ipv4(xpath
, &peer
->addr
);
1197 * XPath: /frr-ripd:ripd/instance/state/neighbors/neighbor/last-update
1199 static struct yang_data
*
1200 ripd_instance_state_neighbors_neighbor_last_update_get_elem(
1201 const char *xpath
, const void *list_entry
)
1203 /* TODO: yang:date-and-time is tricky */
1208 * XPath: /frr-ripd:ripd/instance/state/neighbors/neighbor/bad-packets-rcvd
1210 static struct yang_data
*
1211 ripd_instance_state_neighbors_neighbor_bad_packets_rcvd_get_elem(
1212 const char *xpath
, const void *list_entry
)
1214 const struct listnode
*node
= list_entry
;
1215 const struct rip_peer
*peer
= listgetdata(node
);
1217 return yang_data_new_uint32(xpath
, peer
->recv_badpackets
);
1221 * XPath: /frr-ripd:ripd/instance/state/neighbors/neighbor/bad-routes-rcvd
1223 static struct yang_data
*
1224 ripd_instance_state_neighbors_neighbor_bad_routes_rcvd_get_elem(
1225 const char *xpath
, const void *list_entry
)
1227 const struct listnode
*node
= list_entry
;
1228 const struct rip_peer
*peer
= listgetdata(node
);
1230 return yang_data_new_uint32(xpath
, peer
->recv_badroutes
);
1234 * XPath: /frr-ripd:ripd/instance/state/routes/route
1237 ripd_instance_state_routes_route_get_next(const void *parent_list_entry
,
1238 const void *list_entry
)
1240 const struct rip
*rip
= parent_list_entry
;
1241 struct route_node
*rn
;
1243 if (list_entry
== NULL
)
1244 rn
= route_top(rip
->table
);
1246 rn
= route_next((struct route_node
*)list_entry
);
1247 while (rn
&& rn
->info
== NULL
)
1248 rn
= route_next(rn
);
1254 ripd_instance_state_routes_route_get_keys(const void *list_entry
,
1255 struct yang_list_keys
*keys
)
1257 const struct route_node
*rn
= list_entry
;
1260 (void)prefix2str(&rn
->p
, keys
->key
[0], sizeof(keys
->key
[0]));
1266 ripd_instance_state_routes_route_lookup_entry(const void *parent_list_entry
,
1267 const struct yang_list_keys
*keys
)
1269 const struct rip
*rip
= parent_list_entry
;
1270 struct prefix prefix
;
1271 struct route_node
*rn
;
1273 yang_str2ipv4p(keys
->key
[0], &prefix
);
1275 rn
= route_node_lookup(rip
->table
, &prefix
);
1276 if (!rn
|| !rn
->info
)
1279 route_unlock_node(rn
);
1285 * XPath: /frr-ripd:ripd/instance/state/routes/route/prefix
1287 static struct yang_data
*
1288 ripd_instance_state_routes_route_prefix_get_elem(const char *xpath
,
1289 const void *list_entry
)
1291 const struct route_node
*rn
= list_entry
;
1292 const struct rip_info
*rinfo
= listnode_head(rn
->info
);
1294 return yang_data_new_ipv4p(xpath
, &rinfo
->rp
->p
);
1298 * XPath: /frr-ripd:ripd/instance/state/routes/route/next-hop
1300 static struct yang_data
*
1301 ripd_instance_state_routes_route_next_hop_get_elem(const char *xpath
,
1302 const void *list_entry
)
1304 const struct route_node
*rn
= list_entry
;
1305 const struct rip_info
*rinfo
= listnode_head(rn
->info
);
1307 switch (rinfo
->nh
.type
) {
1308 case NEXTHOP_TYPE_IPV4
:
1309 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1310 return yang_data_new_ipv4(xpath
, &rinfo
->nh
.gate
.ipv4
);
1317 * XPath: /frr-ripd:ripd/instance/state/routes/route/interface
1319 static struct yang_data
*
1320 ripd_instance_state_routes_route_interface_get_elem(const char *xpath
,
1321 const void *list_entry
)
1323 const struct route_node
*rn
= list_entry
;
1324 const struct rip_info
*rinfo
= listnode_head(rn
->info
);
1325 const struct rip
*rip
= rip_info_get_instance(rinfo
);
1327 switch (rinfo
->nh
.type
) {
1328 case NEXTHOP_TYPE_IFINDEX
:
1329 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1330 return yang_data_new_string(
1332 ifindex2ifname(rinfo
->nh
.ifindex
, rip
->vrf
->vrf_id
));
1339 * XPath: /frr-ripd:ripd/instance/state/routes/route/metric
1341 static struct yang_data
*
1342 ripd_instance_state_routes_route_metric_get_elem(const char *xpath
,
1343 const void *list_entry
)
1345 const struct route_node
*rn
= list_entry
;
1346 const struct rip_info
*rinfo
= listnode_head(rn
->info
);
1348 return yang_data_new_uint8(xpath
, rinfo
->metric
);
1352 * XPath: /frr-ripd:clear-rip-route
1354 static int clear_rip_route_rpc(const char *xpath
, const struct list
*input
,
1355 struct list
*output
)
1358 struct route_node
*rp
;
1359 struct rip_info
*rinfo
;
1361 struct listnode
*listnode
;
1363 rip
= rip_lookup_by_vrf_id(VRF_DEFAULT
);
1367 /* Clear received RIP routes */
1368 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
)) {
1373 for (ALL_LIST_ELEMENTS_RO(list
, listnode
, rinfo
)) {
1374 if (!rip_route_rte(rinfo
))
1377 if (CHECK_FLAG(rinfo
->flags
, RIP_RTF_FIB
))
1378 rip_zebra_ipv4_delete(rip
, rp
);
1383 RIP_TIMER_OFF(rinfo
->t_timeout
);
1384 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
1385 listnode_delete(list
, rinfo
);
1386 rip_info_free(rinfo
);
1389 if (list_isempty(list
)) {
1392 route_unlock_node(rp
);
1400 * XPath: /frr-ripd:authentication-type-failure
1402 void ripd_notif_send_auth_type_failure(const char *ifname
)
1404 const char *xpath
= "/frr-ripd:authentication-type-failure";
1405 struct list
*arguments
;
1406 char xpath_arg
[XPATH_MAXLEN
];
1407 struct yang_data
*data
;
1409 arguments
= yang_data_list_new();
1411 snprintf(xpath_arg
, sizeof(xpath_arg
), "%s/interface-name", xpath
);
1412 data
= yang_data_new_string(xpath_arg
, ifname
);
1413 listnode_add(arguments
, data
);
1415 nb_notification_send(xpath
, arguments
);
1419 * XPath: /frr-ripd:authentication-failure
1421 void ripd_notif_send_auth_failure(const char *ifname
)
1423 const char *xpath
= "/frr-ripd:authentication-failure";
1424 struct list
*arguments
;
1425 char xpath_arg
[XPATH_MAXLEN
];
1426 struct yang_data
*data
;
1428 arguments
= yang_data_list_new();
1430 snprintf(xpath_arg
, sizeof(xpath_arg
), "%s/interface-name", xpath
);
1431 data
= yang_data_new_string(xpath_arg
, ifname
);
1432 listnode_add(arguments
, data
);
1434 nb_notification_send(xpath
, arguments
);
1437 /* clang-format off */
1438 const struct frr_yang_module_info frr_ripd_info
= {
1442 .xpath
= "/frr-ripd:ripd/instance",
1443 .cbs
.create
= ripd_instance_create
,
1444 .cbs
.delete = ripd_instance_delete
,
1445 .cbs
.get_next
= ripd_instance_get_next
,
1446 .cbs
.get_keys
= ripd_instance_get_keys
,
1447 .cbs
.lookup_entry
= ripd_instance_lookup_entry
,
1448 .cbs
.cli_show
= cli_show_router_rip
,
1451 .xpath
= "/frr-ripd:ripd/instance/allow-ecmp",
1452 .cbs
.modify
= ripd_instance_allow_ecmp_modify
,
1453 .cbs
.cli_show
= cli_show_rip_allow_ecmp
,
1456 .xpath
= "/frr-ripd:ripd/instance/default-information-originate",
1457 .cbs
.modify
= ripd_instance_default_information_originate_modify
,
1458 .cbs
.cli_show
= cli_show_rip_default_information_originate
,
1461 .xpath
= "/frr-ripd:ripd/instance/default-metric",
1462 .cbs
.modify
= ripd_instance_default_metric_modify
,
1463 .cbs
.cli_show
= cli_show_rip_default_metric
,
1466 .xpath
= "/frr-ripd:ripd/instance/distance/default",
1467 .cbs
.modify
= ripd_instance_distance_default_modify
,
1468 .cbs
.cli_show
= cli_show_rip_distance
,
1471 .xpath
= "/frr-ripd:ripd/instance/distance/source",
1472 .cbs
.create
= ripd_instance_distance_source_create
,
1473 .cbs
.delete = ripd_instance_distance_source_delete
,
1474 .cbs
.cli_show
= cli_show_rip_distance_source
,
1477 .xpath
= "/frr-ripd:ripd/instance/distance/source/distance",
1478 .cbs
.modify
= ripd_instance_distance_source_distance_modify
,
1481 .xpath
= "/frr-ripd:ripd/instance/distance/source/access-list",
1482 .cbs
.modify
= ripd_instance_distance_source_access_list_modify
,
1483 .cbs
.delete = ripd_instance_distance_source_access_list_delete
,
1486 .xpath
= "/frr-ripd:ripd/instance/explicit-neighbor",
1487 .cbs
.create
= ripd_instance_explicit_neighbor_create
,
1488 .cbs
.delete = ripd_instance_explicit_neighbor_delete
,
1489 .cbs
.cli_show
= cli_show_rip_neighbor
,
1492 .xpath
= "/frr-ripd:ripd/instance/network",
1493 .cbs
.create
= ripd_instance_network_create
,
1494 .cbs
.delete = ripd_instance_network_delete
,
1495 .cbs
.cli_show
= cli_show_rip_network_prefix
,
1498 .xpath
= "/frr-ripd:ripd/instance/interface",
1499 .cbs
.create
= ripd_instance_interface_create
,
1500 .cbs
.delete = ripd_instance_interface_delete
,
1501 .cbs
.cli_show
= cli_show_rip_network_interface
,
1504 .xpath
= "/frr-ripd:ripd/instance/offset-list",
1505 .cbs
.create
= ripd_instance_offset_list_create
,
1506 .cbs
.delete = ripd_instance_offset_list_delete
,
1507 .cbs
.cli_show
= cli_show_rip_offset_list
,
1510 .xpath
= "/frr-ripd:ripd/instance/offset-list/access-list",
1511 .cbs
.modify
= ripd_instance_offset_list_access_list_modify
,
1514 .xpath
= "/frr-ripd:ripd/instance/offset-list/metric",
1515 .cbs
.modify
= ripd_instance_offset_list_metric_modify
,
1518 .xpath
= "/frr-ripd:ripd/instance/passive-default",
1519 .cbs
.modify
= ripd_instance_passive_default_modify
,
1520 .cbs
.cli_show
= cli_show_rip_passive_default
,
1523 .xpath
= "/frr-ripd:ripd/instance/passive-interface",
1524 .cbs
.create
= ripd_instance_passive_interface_create
,
1525 .cbs
.delete = ripd_instance_passive_interface_delete
,
1526 .cbs
.cli_show
= cli_show_rip_passive_interface
,
1529 .xpath
= "/frr-ripd:ripd/instance/non-passive-interface",
1530 .cbs
.create
= ripd_instance_non_passive_interface_create
,
1531 .cbs
.delete = ripd_instance_non_passive_interface_delete
,
1532 .cbs
.cli_show
= cli_show_rip_non_passive_interface
,
1535 .xpath
= "/frr-ripd:ripd/instance/redistribute",
1536 .cbs
.create
= ripd_instance_redistribute_create
,
1537 .cbs
.delete = ripd_instance_redistribute_delete
,
1538 .cbs
.apply_finish
= ripd_instance_redistribute_apply_finish
,
1539 .cbs
.cli_show
= cli_show_rip_redistribute
,
1542 .xpath
= "/frr-ripd:ripd/instance/redistribute/route-map",
1543 .cbs
.modify
= ripd_instance_redistribute_route_map_modify
,
1544 .cbs
.delete = ripd_instance_redistribute_route_map_delete
,
1547 .xpath
= "/frr-ripd:ripd/instance/redistribute/metric",
1548 .cbs
.modify
= ripd_instance_redistribute_metric_modify
,
1549 .cbs
.delete = ripd_instance_redistribute_metric_delete
,
1552 .xpath
= "/frr-ripd:ripd/instance/static-route",
1553 .cbs
.create
= ripd_instance_static_route_create
,
1554 .cbs
.delete = ripd_instance_static_route_delete
,
1555 .cbs
.cli_show
= cli_show_rip_route
,
1558 .xpath
= "/frr-ripd:ripd/instance/timers",
1559 .cbs
.apply_finish
= ripd_instance_timers_apply_finish
,
1560 .cbs
.cli_show
= cli_show_rip_timers
,
1563 .xpath
= "/frr-ripd:ripd/instance/timers/flush-interval",
1564 .cbs
.modify
= ripd_instance_timers_flush_interval_modify
,
1567 .xpath
= "/frr-ripd:ripd/instance/timers/holddown-interval",
1568 .cbs
.modify
= ripd_instance_timers_holddown_interval_modify
,
1571 .xpath
= "/frr-ripd:ripd/instance/timers/update-interval",
1572 .cbs
.modify
= ripd_instance_timers_update_interval_modify
,
1575 .xpath
= "/frr-ripd:ripd/instance/version",
1576 .cbs
.cli_show
= cli_show_rip_version
,
1579 .xpath
= "/frr-ripd:ripd/instance/version/receive",
1580 .cbs
.modify
= ripd_instance_version_receive_modify
,
1583 .xpath
= "/frr-ripd:ripd/instance/version/send",
1584 .cbs
.modify
= ripd_instance_version_send_modify
,
1587 .xpath
= "/frr-interface:lib/interface/frr-ripd:rip/split-horizon",
1588 .cbs
.modify
= lib_interface_rip_split_horizon_modify
,
1589 .cbs
.cli_show
= cli_show_ip_rip_split_horizon
,
1592 .xpath
= "/frr-interface:lib/interface/frr-ripd:rip/v2-broadcast",
1593 .cbs
.modify
= lib_interface_rip_v2_broadcast_modify
,
1594 .cbs
.cli_show
= cli_show_ip_rip_v2_broadcast
,
1597 .xpath
= "/frr-interface:lib/interface/frr-ripd:rip/version-receive",
1598 .cbs
.modify
= lib_interface_rip_version_receive_modify
,
1599 .cbs
.cli_show
= cli_show_ip_rip_receive_version
,
1602 .xpath
= "/frr-interface:lib/interface/frr-ripd:rip/version-send",
1603 .cbs
.modify
= lib_interface_rip_version_send_modify
,
1604 .cbs
.cli_show
= cli_show_ip_rip_send_version
,
1607 .xpath
= "/frr-interface:lib/interface/frr-ripd:rip/authentication-scheme",
1608 .cbs
.cli_show
= cli_show_ip_rip_authentication_scheme
,
1611 .xpath
= "/frr-interface:lib/interface/frr-ripd:rip/authentication-scheme/mode",
1612 .cbs
.modify
= lib_interface_rip_authentication_scheme_mode_modify
,
1615 .xpath
= "/frr-interface:lib/interface/frr-ripd:rip/authentication-scheme/md5-auth-length",
1616 .cbs
.modify
= lib_interface_rip_authentication_scheme_md5_auth_length_modify
,
1617 .cbs
.delete = lib_interface_rip_authentication_scheme_md5_auth_length_delete
,
1620 .xpath
= "/frr-interface:lib/interface/frr-ripd:rip/authentication-password",
1621 .cbs
.modify
= lib_interface_rip_authentication_password_modify
,
1622 .cbs
.delete = lib_interface_rip_authentication_password_delete
,
1623 .cbs
.cli_show
= cli_show_ip_rip_authentication_string
,
1626 .xpath
= "/frr-interface:lib/interface/frr-ripd:rip/authentication-key-chain",
1627 .cbs
.modify
= lib_interface_rip_authentication_key_chain_modify
,
1628 .cbs
.delete = lib_interface_rip_authentication_key_chain_delete
,
1629 .cbs
.cli_show
= cli_show_ip_rip_authentication_key_chain
,
1632 .xpath
= "/frr-ripd:ripd/instance/state/neighbors/neighbor",
1633 .cbs
.get_next
= ripd_instance_state_neighbors_neighbor_get_next
,
1634 .cbs
.get_keys
= ripd_instance_state_neighbors_neighbor_get_keys
,
1635 .cbs
.lookup_entry
= ripd_instance_state_neighbors_neighbor_lookup_entry
,
1638 .xpath
= "/frr-ripd:ripd/instance/state/neighbors/neighbor/address",
1639 .cbs
.get_elem
= ripd_instance_state_neighbors_neighbor_address_get_elem
,
1642 .xpath
= "/frr-ripd:ripd/instance/state/neighbors/neighbor/last-update",
1643 .cbs
.get_elem
= ripd_instance_state_neighbors_neighbor_last_update_get_elem
,
1646 .xpath
= "/frr-ripd:ripd/instance/state/neighbors/neighbor/bad-packets-rcvd",
1647 .cbs
.get_elem
= ripd_instance_state_neighbors_neighbor_bad_packets_rcvd_get_elem
,
1650 .xpath
= "/frr-ripd:ripd/instance/state/neighbors/neighbor/bad-routes-rcvd",
1651 .cbs
.get_elem
= ripd_instance_state_neighbors_neighbor_bad_routes_rcvd_get_elem
,
1654 .xpath
= "/frr-ripd:ripd/instance/state/routes/route",
1655 .cbs
.get_next
= ripd_instance_state_routes_route_get_next
,
1656 .cbs
.get_keys
= ripd_instance_state_routes_route_get_keys
,
1657 .cbs
.lookup_entry
= ripd_instance_state_routes_route_lookup_entry
,
1660 .xpath
= "/frr-ripd:ripd/instance/state/routes/route/prefix",
1661 .cbs
.get_elem
= ripd_instance_state_routes_route_prefix_get_elem
,
1664 .xpath
= "/frr-ripd:ripd/instance/state/routes/route/next-hop",
1665 .cbs
.get_elem
= ripd_instance_state_routes_route_next_hop_get_elem
,
1668 .xpath
= "/frr-ripd:ripd/instance/state/routes/route/interface",
1669 .cbs
.get_elem
= ripd_instance_state_routes_route_interface_get_elem
,
1672 .xpath
= "/frr-ripd:ripd/instance/state/routes/route/metric",
1673 .cbs
.get_elem
= ripd_instance_state_routes_route_metric_get_elem
,
1676 .xpath
= "/frr-ripd:clear-rip-route",
1677 .cbs
.rpc
= clear_rip_route_rpc
,