]> git.proxmox.com Git - mirror_frr.git/blob - ripd/rip_nb_config.c
Merge pull request #13020 from SaiGomathiN/2462808-3
[mirror_frr.git] / ripd / rip_nb_config.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro <kunihiro@zebra.org>
4 * Copyright (C) 2018 NetDEF, Inc.
5 * Renato Westphal
6 * Copyright (C) 2023 LabN Consulting, L.L.C.
7 */
8
9 #include <zebra.h>
10
11 #include "if.h"
12 #include "vrf.h"
13 #include "log.h"
14 #include "prefix.h"
15 #include "table.h"
16 #include "command.h"
17 #include "if_rmap.h"
18 #include "routemap.h"
19 #include "northbound.h"
20 #include "libfrr.h"
21
22 #include "ripd/ripd.h"
23 #include "ripd/rip_nb.h"
24 #include "ripd/rip_debug.h"
25 #include "ripd/rip_interface.h"
26 #include "ripd/rip_bfd.h"
27
28 DEFINE_MTYPE_STATIC(RIPD, RIP_BFD_PROFILE, "RIP BFD profile name");
29
30 /*
31 * XPath: /frr-ripd:ripd/instance
32 */
33 int ripd_instance_create(struct nb_cb_create_args *args)
34 {
35 struct rip *rip;
36 struct vrf *vrf;
37 const char *vrf_name;
38 int socket;
39
40 vrf_name = yang_dnode_get_string(args->dnode, "./vrf");
41 vrf = vrf_lookup_by_name(vrf_name);
42
43 /*
44 * Try to create a RIP socket only if the VRF is enabled, otherwise
45 * create a disabled RIP instance and wait for the VRF to be enabled.
46 */
47 switch (args->event) {
48 case NB_EV_VALIDATE:
49 break;
50 case NB_EV_PREPARE:
51 if (!vrf || !vrf_is_enabled(vrf))
52 break;
53
54 socket = rip_create_socket(vrf);
55 if (socket < 0)
56 return NB_ERR_RESOURCE;
57 args->resource->fd = socket;
58 break;
59 case NB_EV_ABORT:
60 if (!vrf || !vrf_is_enabled(vrf))
61 break;
62
63 socket = args->resource->fd;
64 close(socket);
65 break;
66 case NB_EV_APPLY:
67 if (vrf && vrf_is_enabled(vrf))
68 socket = args->resource->fd;
69 else
70 socket = -1;
71
72 rip = rip_create(vrf_name, vrf, socket);
73 nb_running_set_entry(args->dnode, rip);
74 break;
75 }
76
77 return NB_OK;
78 }
79
80 int ripd_instance_destroy(struct nb_cb_destroy_args *args)
81 {
82 struct rip *rip;
83
84 if (args->event != NB_EV_APPLY)
85 return NB_OK;
86
87 rip = nb_running_unset_entry(args->dnode);
88 rip_clean(rip);
89
90 return NB_OK;
91 }
92
93 /*
94 * XPath: /frr-ripd:ripd/instance/allow-ecmp
95 */
96 int ripd_instance_allow_ecmp_modify(struct nb_cb_modify_args *args)
97 {
98 struct rip *rip;
99
100 if (args->event != NB_EV_APPLY)
101 return NB_OK;
102
103 rip = nb_running_get_entry(args->dnode, NULL, true);
104 rip->ecmp = yang_dnode_get_bool(args->dnode, NULL);
105 if (!rip->ecmp)
106 rip_ecmp_disable(rip);
107
108 return NB_OK;
109 }
110
111 /*
112 * XPath: /frr-ripd:ripd/instance/default-information-originate
113 */
114 int ripd_instance_default_information_originate_modify(
115 struct nb_cb_modify_args *args)
116 {
117 struct rip *rip;
118 bool default_information;
119 struct prefix_ipv4 p;
120
121 if (args->event != NB_EV_APPLY)
122 return NB_OK;
123
124 rip = nb_running_get_entry(args->dnode, NULL, true);
125 default_information = yang_dnode_get_bool(args->dnode, NULL);
126
127 memset(&p, 0, sizeof(p));
128 p.family = AF_INET;
129 if (default_information) {
130 struct nexthop nh;
131
132 memset(&nh, 0, sizeof(nh));
133 nh.type = NEXTHOP_TYPE_IPV4;
134 rip_redistribute_add(rip, ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT,
135 &p, &nh, 0, 0, 0);
136 } else {
137 rip_redistribute_delete(rip, ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT,
138 &p, 0);
139 }
140
141 return NB_OK;
142 }
143
144 /*
145 * XPath: /frr-ripd:ripd/instance/default-metric
146 */
147 int ripd_instance_default_metric_modify(struct nb_cb_modify_args *args)
148 {
149 struct rip *rip;
150
151 if (args->event != NB_EV_APPLY)
152 return NB_OK;
153
154 rip = nb_running_get_entry(args->dnode, NULL, true);
155 rip->default_metric = yang_dnode_get_uint8(args->dnode, NULL);
156 /* rip_update_default_metric (); */
157
158 return NB_OK;
159 }
160
161 /*
162 * XPath: /frr-ripd:ripd/instance/distance/default
163 */
164 int ripd_instance_distance_default_modify(struct nb_cb_modify_args *args)
165 {
166 struct rip *rip;
167
168 if (args->event != NB_EV_APPLY)
169 return NB_OK;
170
171 rip = nb_running_get_entry(args->dnode, NULL, true);
172 rip->distance = yang_dnode_get_uint8(args->dnode, NULL);
173
174 return NB_OK;
175 }
176
177 /*
178 * XPath: /frr-ripd:ripd/instance/distance/source
179 */
180 int ripd_instance_distance_source_create(struct nb_cb_create_args *args)
181 {
182 struct rip *rip;
183 struct prefix_ipv4 prefix;
184 struct route_node *rn;
185
186 if (args->event != NB_EV_APPLY)
187 return NB_OK;
188
189 yang_dnode_get_ipv4p(&prefix, args->dnode, "./prefix");
190 apply_mask_ipv4(&prefix);
191
192 /* Get RIP distance node. */
193 rip = nb_running_get_entry(args->dnode, NULL, true);
194 rn = route_node_get(rip->distance_table, (struct prefix *)&prefix);
195 rn->info = rip_distance_new();
196 nb_running_set_entry(args->dnode, rn);
197
198 return NB_OK;
199 }
200
201 int ripd_instance_distance_source_destroy(struct nb_cb_destroy_args *args)
202 {
203 struct route_node *rn;
204 struct rip_distance *rdistance;
205
206 if (args->event != NB_EV_APPLY)
207 return NB_OK;
208
209 rn = nb_running_unset_entry(args->dnode);
210 rdistance = rn->info;
211 rip_distance_free(rdistance);
212 rn->info = NULL;
213 route_unlock_node(rn);
214
215 return NB_OK;
216 }
217
218 /*
219 * XPath: /frr-ripd:ripd/instance/distance/source/distance
220 */
221 int ripd_instance_distance_source_distance_modify(
222 struct nb_cb_modify_args *args)
223 {
224 struct route_node *rn;
225 uint8_t distance;
226 struct rip_distance *rdistance;
227
228 if (args->event != NB_EV_APPLY)
229 return NB_OK;
230
231 /* Set distance value. */
232 rn = nb_running_get_entry(args->dnode, NULL, true);
233 distance = yang_dnode_get_uint8(args->dnode, NULL);
234 rdistance = rn->info;
235 rdistance->distance = distance;
236
237 return NB_OK;
238 }
239
240 /*
241 * XPath: /frr-ripd:ripd/instance/distance/source/access-list
242 */
243 int ripd_instance_distance_source_access_list_modify(
244 struct nb_cb_modify_args *args)
245 {
246 const char *acl_name;
247 struct route_node *rn;
248 struct rip_distance *rdistance;
249
250 if (args->event != NB_EV_APPLY)
251 return NB_OK;
252
253 acl_name = yang_dnode_get_string(args->dnode, NULL);
254
255 /* Set access-list */
256 rn = nb_running_get_entry(args->dnode, NULL, true);
257 rdistance = rn->info;
258 if (rdistance->access_list)
259 free(rdistance->access_list);
260 rdistance->access_list = strdup(acl_name);
261
262 return NB_OK;
263 }
264
265 int ripd_instance_distance_source_access_list_destroy(
266 struct nb_cb_destroy_args *args)
267 {
268 struct route_node *rn;
269 struct rip_distance *rdistance;
270
271 if (args->event != NB_EV_APPLY)
272 return NB_OK;
273
274 /* Reset access-list configuration. */
275 rn = nb_running_get_entry(args->dnode, NULL, true);
276 rdistance = rn->info;
277 free(rdistance->access_list);
278 rdistance->access_list = NULL;
279
280 return NB_OK;
281 }
282
283 /*
284 * XPath: /frr-ripd:ripd/instance/explicit-neighbor
285 */
286 int ripd_instance_explicit_neighbor_create(struct nb_cb_create_args *args)
287 {
288 struct rip *rip;
289 struct prefix_ipv4 p;
290
291 if (args->event != NB_EV_APPLY)
292 return NB_OK;
293
294 rip = nb_running_get_entry(args->dnode, NULL, true);
295 p.family = AF_INET;
296 p.prefixlen = IPV4_MAX_BITLEN;
297 yang_dnode_get_ipv4(&p.prefix, args->dnode, NULL);
298
299 return rip_neighbor_add(rip, &p);
300 }
301
302 int ripd_instance_explicit_neighbor_destroy(struct nb_cb_destroy_args *args)
303 {
304 struct rip *rip;
305 struct prefix_ipv4 p;
306
307 if (args->event != NB_EV_APPLY)
308 return NB_OK;
309
310 rip = nb_running_get_entry(args->dnode, NULL, true);
311 p.family = AF_INET;
312 p.prefixlen = IPV4_MAX_BITLEN;
313 yang_dnode_get_ipv4(&p.prefix, args->dnode, NULL);
314
315 return rip_neighbor_delete(rip, &p);
316 }
317
318 /*
319 * XPath: /frr-ripd:ripd/instance/network
320 */
321 int ripd_instance_network_create(struct nb_cb_create_args *args)
322 {
323 struct rip *rip;
324 struct prefix p;
325
326 if (args->event != NB_EV_APPLY)
327 return NB_OK;
328
329 rip = nb_running_get_entry(args->dnode, NULL, true);
330 yang_dnode_get_ipv4p(&p, args->dnode, NULL);
331 apply_mask_ipv4((struct prefix_ipv4 *)&p);
332
333 return rip_enable_network_add(rip, &p);
334 }
335
336 int ripd_instance_network_destroy(struct nb_cb_destroy_args *args)
337 {
338 struct rip *rip;
339 struct prefix p;
340
341 if (args->event != NB_EV_APPLY)
342 return NB_OK;
343
344 rip = nb_running_get_entry(args->dnode, NULL, true);
345 yang_dnode_get_ipv4p(&p, args->dnode, NULL);
346 apply_mask_ipv4((struct prefix_ipv4 *)&p);
347
348 return rip_enable_network_delete(rip, &p);
349 }
350
351 /*
352 * XPath: /frr-ripd:ripd/instance/interface
353 */
354 int ripd_instance_interface_create(struct nb_cb_create_args *args)
355 {
356 struct rip *rip;
357 const char *ifname;
358
359 if (args->event != NB_EV_APPLY)
360 return NB_OK;
361
362 rip = nb_running_get_entry(args->dnode, NULL, true);
363 ifname = yang_dnode_get_string(args->dnode, NULL);
364
365 return rip_enable_if_add(rip, ifname);
366 }
367
368 int ripd_instance_interface_destroy(struct nb_cb_destroy_args *args)
369 {
370 struct rip *rip;
371 const char *ifname;
372
373 if (args->event != NB_EV_APPLY)
374 return NB_OK;
375
376 rip = nb_running_get_entry(args->dnode, NULL, true);
377 ifname = yang_dnode_get_string(args->dnode, NULL);
378
379 return rip_enable_if_delete(rip, ifname);
380 }
381
382 /*
383 * XPath: /frr-ripd:ripd/instance/offset-list
384 */
385 int ripd_instance_offset_list_create(struct nb_cb_create_args *args)
386 {
387 struct rip *rip;
388 const char *ifname;
389 struct rip_offset_list *offset;
390
391 if (args->event != NB_EV_APPLY)
392 return NB_OK;
393
394 rip = nb_running_get_entry(args->dnode, NULL, true);
395 ifname = yang_dnode_get_string(args->dnode, "./interface");
396
397 offset = rip_offset_list_new(rip, ifname);
398 nb_running_set_entry(args->dnode, offset);
399
400 return NB_OK;
401 }
402
403 int ripd_instance_offset_list_destroy(struct nb_cb_destroy_args *args)
404 {
405 int direct;
406 struct rip_offset_list *offset;
407
408 if (args->event != NB_EV_APPLY)
409 return NB_OK;
410
411 direct = yang_dnode_get_enum(args->dnode, "./direction");
412
413 offset = nb_running_unset_entry(args->dnode);
414 if (offset->direct[direct].alist_name) {
415 free(offset->direct[direct].alist_name);
416 offset->direct[direct].alist_name = NULL;
417 }
418 if (offset->direct[RIP_OFFSET_LIST_IN].alist_name == NULL
419 && offset->direct[RIP_OFFSET_LIST_OUT].alist_name == NULL)
420 offset_list_del(offset);
421
422 return NB_OK;
423 }
424
425 /*
426 * XPath: /frr-ripd:ripd/instance/offset-list/access-list
427 */
428 int ripd_instance_offset_list_access_list_modify(struct nb_cb_modify_args *args)
429 {
430 int direct;
431 struct rip_offset_list *offset;
432 const char *alist_name;
433
434 if (args->event != NB_EV_APPLY)
435 return NB_OK;
436
437 direct = yang_dnode_get_enum(args->dnode, "../direction");
438 alist_name = yang_dnode_get_string(args->dnode, NULL);
439
440 offset = nb_running_get_entry(args->dnode, NULL, true);
441 if (offset->direct[direct].alist_name)
442 free(offset->direct[direct].alist_name);
443 offset->direct[direct].alist_name = strdup(alist_name);
444
445 return NB_OK;
446 }
447
448 /*
449 * XPath: /frr-ripd:ripd/instance/offset-list/metric
450 */
451 int ripd_instance_offset_list_metric_modify(struct nb_cb_modify_args *args)
452 {
453 int direct;
454 uint8_t metric;
455 struct rip_offset_list *offset;
456
457 if (args->event != NB_EV_APPLY)
458 return NB_OK;
459
460 direct = yang_dnode_get_enum(args->dnode, "../direction");
461 metric = yang_dnode_get_uint8(args->dnode, NULL);
462
463 offset = nb_running_get_entry(args->dnode, NULL, true);
464 offset->direct[direct].metric = metric;
465
466 return NB_OK;
467 }
468
469 /*
470 * XPath: /frr-ripd:ripd/instance/passive-default
471 */
472 int ripd_instance_passive_default_modify(struct nb_cb_modify_args *args)
473 {
474 struct rip *rip;
475
476 if (args->event != NB_EV_APPLY)
477 return NB_OK;
478
479 rip = nb_running_get_entry(args->dnode, NULL, true);
480 rip->passive_default = yang_dnode_get_bool(args->dnode, NULL);
481 rip_passive_nondefault_clean(rip);
482
483 return NB_OK;
484 }
485
486 /*
487 * XPath: /frr-ripd:ripd/instance/passive-interface
488 */
489 int ripd_instance_passive_interface_create(struct nb_cb_create_args *args)
490 {
491 struct rip *rip;
492 const char *ifname;
493
494 if (args->event != NB_EV_APPLY)
495 return NB_OK;
496
497 rip = nb_running_get_entry(args->dnode, NULL, true);
498 ifname = yang_dnode_get_string(args->dnode, NULL);
499
500 return rip_passive_nondefault_set(rip, ifname);
501 }
502
503 int ripd_instance_passive_interface_destroy(struct nb_cb_destroy_args *args)
504 {
505 struct rip *rip;
506 const char *ifname;
507
508 if (args->event != NB_EV_APPLY)
509 return NB_OK;
510
511 rip = nb_running_get_entry(args->dnode, NULL, true);
512 ifname = yang_dnode_get_string(args->dnode, NULL);
513
514 return rip_passive_nondefault_unset(rip, ifname);
515 }
516
517 /*
518 * XPath: /frr-ripd:ripd/instance/non-passive-interface
519 */
520 int ripd_instance_non_passive_interface_create(struct nb_cb_create_args *args)
521 {
522 struct rip *rip;
523 const char *ifname;
524
525 if (args->event != NB_EV_APPLY)
526 return NB_OK;
527
528 rip = nb_running_get_entry(args->dnode, NULL, true);
529 ifname = yang_dnode_get_string(args->dnode, NULL);
530
531 return rip_passive_nondefault_set(rip, ifname);
532 }
533
534 int ripd_instance_non_passive_interface_destroy(struct nb_cb_destroy_args *args)
535 {
536 struct rip *rip;
537 const char *ifname;
538
539 if (args->event != NB_EV_APPLY)
540 return NB_OK;
541
542 rip = nb_running_get_entry(args->dnode, NULL, true);
543 ifname = yang_dnode_get_string(args->dnode, NULL);
544
545 return rip_passive_nondefault_unset(rip, ifname);
546 }
547
548 /*
549 * XPath: /frr-ripd:ripd/instance/redistribute
550 */
551 int ripd_instance_redistribute_create(struct nb_cb_create_args *args)
552 {
553 struct rip *rip;
554 int type;
555
556 if (args->event != NB_EV_APPLY)
557 return NB_OK;
558
559 rip = nb_running_get_entry(args->dnode, NULL, true);
560 type = yang_dnode_get_enum(args->dnode, "./protocol");
561
562 rip->redist[type].enabled = true;
563
564 return NB_OK;
565 }
566
567 int ripd_instance_redistribute_destroy(struct nb_cb_destroy_args *args)
568 {
569 struct rip *rip;
570 int type;
571
572 if (args->event != NB_EV_APPLY)
573 return NB_OK;
574
575 rip = nb_running_get_entry(args->dnode, NULL, true);
576 type = yang_dnode_get_enum(args->dnode, "./protocol");
577
578 rip->redist[type].enabled = false;
579 if (rip->redist[type].route_map.name) {
580 free(rip->redist[type].route_map.name);
581 rip->redist[type].route_map.name = NULL;
582 rip->redist[type].route_map.map = NULL;
583 }
584 rip->redist[type].metric_config = false;
585 rip->redist[type].metric = 0;
586
587 if (rip->enabled)
588 rip_redistribute_conf_delete(rip, type);
589
590 return NB_OK;
591 }
592
593 void ripd_instance_redistribute_apply_finish(
594 struct nb_cb_apply_finish_args *args)
595 {
596 struct rip *rip;
597 int type;
598
599 rip = nb_running_get_entry(args->dnode, NULL, true);
600 type = yang_dnode_get_enum(args->dnode, "./protocol");
601
602 if (rip->enabled)
603 rip_redistribute_conf_update(rip, type);
604 }
605
606 /*
607 * XPath: /frr-ripd:ripd/instance/redistribute/route-map
608 */
609 int ripd_instance_redistribute_route_map_modify(struct nb_cb_modify_args *args)
610 {
611 struct rip *rip;
612 int type;
613 const char *rmap_name;
614
615 if (args->event != NB_EV_APPLY)
616 return NB_OK;
617
618 rip = nb_running_get_entry(args->dnode, NULL, true);
619 type = yang_dnode_get_enum(args->dnode, "../protocol");
620 rmap_name = yang_dnode_get_string(args->dnode, NULL);
621
622 if (rip->redist[type].route_map.name)
623 free(rip->redist[type].route_map.name);
624 rip->redist[type].route_map.name = strdup(rmap_name);
625 rip->redist[type].route_map.map = route_map_lookup_by_name(rmap_name);
626
627 return NB_OK;
628 }
629
630 int ripd_instance_redistribute_route_map_destroy(
631 struct nb_cb_destroy_args *args)
632 {
633 struct rip *rip;
634 int type;
635
636 if (args->event != NB_EV_APPLY)
637 return NB_OK;
638
639 rip = nb_running_get_entry(args->dnode, NULL, true);
640 type = yang_dnode_get_enum(args->dnode, "../protocol");
641
642 free(rip->redist[type].route_map.name);
643 rip->redist[type].route_map.name = NULL;
644 rip->redist[type].route_map.map = NULL;
645
646 return NB_OK;
647 }
648
649 /*
650 * XPath: /frr-ripd:ripd/instance/redistribute/metric
651 */
652 int ripd_instance_redistribute_metric_modify(struct nb_cb_modify_args *args)
653 {
654 struct rip *rip;
655 int type;
656 uint8_t metric;
657
658 if (args->event != NB_EV_APPLY)
659 return NB_OK;
660
661 rip = nb_running_get_entry(args->dnode, NULL, true);
662 type = yang_dnode_get_enum(args->dnode, "../protocol");
663 metric = yang_dnode_get_uint8(args->dnode, NULL);
664
665 rip->redist[type].metric_config = true;
666 rip->redist[type].metric = metric;
667
668 return NB_OK;
669 }
670
671 int ripd_instance_redistribute_metric_destroy(struct nb_cb_destroy_args *args)
672 {
673 struct rip *rip;
674 int type;
675
676 if (args->event != NB_EV_APPLY)
677 return NB_OK;
678
679 rip = nb_running_get_entry(args->dnode, NULL, true);
680 type = yang_dnode_get_enum(args->dnode, "../protocol");
681
682 rip->redist[type].metric_config = false;
683 rip->redist[type].metric = 0;
684
685 return NB_OK;
686 }
687
688 /*
689 * XPath: /frr-ripd:ripd/instance/if-route-maps/if-route-map
690 */
691 int ripd_instance_if_route_maps_if_route_map_create(
692 struct nb_cb_create_args *args)
693 {
694 /* if_rmap is created when first routemap is added */
695 return NB_OK;
696 }
697
698 int ripd_instance_if_route_maps_if_route_map_destroy(
699 struct nb_cb_destroy_args *args)
700 {
701 struct rip *rip;
702
703 if (args->event != NB_EV_APPLY)
704 return NB_OK;
705
706 /*
707 * YANG will prune edit deletes up to the most general deleted node so
708 * we need to handle deleting any existing state underneath and not
709 * count on those more specific callbacks being called individually.
710 */
711
712 rip = nb_running_get_entry(args->dnode, NULL, true);
713 if_rmap_yang_destroy_cb(rip->if_rmap_ctx, args->dnode);
714
715 return NB_OK;
716 }
717
718 static void if_route_map_modify(const struct lyd_node *dnode,
719 enum if_rmap_type type, bool delete)
720 {
721 struct rip *rip = nb_running_get_entry(dnode, NULL, true);
722
723 if_rmap_yang_modify_cb(rip->if_rmap_ctx, dnode, type, delete);
724 }
725
726 /*
727 * XPath: /frr-ripd:ripd/instance/if-route-maps/if-route-map/in-route-map
728 */
729 int ripd_instance_if_route_maps_if_route_map_in_route_map_modify(
730 struct nb_cb_modify_args *args)
731 {
732 if (args->event != NB_EV_APPLY)
733 return NB_OK;
734
735 if_route_map_modify(args->dnode, IF_RMAP_IN, false);
736
737 return NB_OK;
738 }
739
740 int ripd_instance_if_route_maps_if_route_map_in_route_map_destroy(
741 struct nb_cb_destroy_args *args)
742 {
743 if (args->event != NB_EV_APPLY)
744 return NB_OK;
745
746 if_route_map_modify(args->dnode, IF_RMAP_IN, true);
747
748 return NB_OK;
749 }
750
751 /*
752 * XPath: /frr-ripd:ripd/instance/if-route-maps/if-route-map/out-route-map
753 */
754 int ripd_instance_if_route_maps_if_route_map_out_route_map_modify(
755 struct nb_cb_modify_args *args)
756 {
757 if (args->event != NB_EV_APPLY)
758 return NB_OK;
759
760 if_route_map_modify(args->dnode, IF_RMAP_OUT, false);
761
762 return NB_OK;
763 }
764
765 int ripd_instance_if_route_maps_if_route_map_out_route_map_destroy(
766 struct nb_cb_destroy_args *args)
767 {
768 if (args->event != NB_EV_APPLY)
769 return NB_OK;
770
771 if_route_map_modify(args->dnode, IF_RMAP_OUT, true);
772
773 return NB_OK;
774 }
775
776 /*
777 * XPath: /frr-ripd:ripd/instance/static-route
778 */
779 int ripd_instance_static_route_create(struct nb_cb_create_args *args)
780 {
781 struct rip *rip;
782 struct nexthop nh;
783 struct prefix_ipv4 p;
784
785 if (args->event != NB_EV_APPLY)
786 return NB_OK;
787
788 rip = nb_running_get_entry(args->dnode, NULL, true);
789 yang_dnode_get_ipv4p(&p, args->dnode, NULL);
790 apply_mask_ipv4(&p);
791
792 memset(&nh, 0, sizeof(nh));
793 nh.type = NEXTHOP_TYPE_IPV4;
794 rip_redistribute_add(rip, ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, &nh, 0,
795 0, 0);
796
797 return NB_OK;
798 }
799
800 int ripd_instance_static_route_destroy(struct nb_cb_destroy_args *args)
801 {
802 struct rip *rip;
803 struct prefix_ipv4 p;
804
805 if (args->event != NB_EV_APPLY)
806 return NB_OK;
807
808 rip = nb_running_get_entry(args->dnode, NULL, true);
809 yang_dnode_get_ipv4p(&p, args->dnode, NULL);
810 apply_mask_ipv4(&p);
811
812 rip_redistribute_delete(rip, ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, 0);
813
814 return NB_OK;
815 }
816
817 /*
818 * XPath: /frr-ripd:ripd/instance/timers/
819 */
820 void ripd_instance_timers_apply_finish(struct nb_cb_apply_finish_args *args)
821 {
822 struct rip *rip;
823
824 rip = nb_running_get_entry(args->dnode, NULL, true);
825
826 /* Reset update timer thread. */
827 rip_event(rip, RIP_UPDATE_EVENT, 0);
828 }
829
830 /*
831 * XPath: /frr-ripd:ripd/instance/timers/flush-interval
832 */
833 int ripd_instance_timers_flush_interval_modify(struct nb_cb_modify_args *args)
834 {
835 struct rip *rip;
836
837 if (args->event != NB_EV_APPLY)
838 return NB_OK;
839
840 rip = nb_running_get_entry(args->dnode, NULL, true);
841 rip->garbage_time = yang_dnode_get_uint32(args->dnode, NULL);
842
843 return NB_OK;
844 }
845
846 /*
847 * XPath: /frr-ripd:ripd/instance/timers/holddown-interval
848 */
849 int ripd_instance_timers_holddown_interval_modify(
850 struct nb_cb_modify_args *args)
851 {
852 struct rip *rip;
853
854 if (args->event != NB_EV_APPLY)
855 return NB_OK;
856
857 rip = nb_running_get_entry(args->dnode, NULL, true);
858 rip->timeout_time = yang_dnode_get_uint32(args->dnode, NULL);
859
860 return NB_OK;
861 }
862
863 /*
864 * XPath: /frr-ripd:ripd/instance/timers/update-interval
865 */
866 int ripd_instance_timers_update_interval_modify(struct nb_cb_modify_args *args)
867 {
868 struct rip *rip;
869
870 if (args->event != NB_EV_APPLY)
871 return NB_OK;
872
873 rip = nb_running_get_entry(args->dnode, NULL, true);
874 rip->update_time = yang_dnode_get_uint32(args->dnode, NULL);
875
876 return NB_OK;
877 }
878
879 /*
880 * XPath: /frr-ripd:ripd/instance/version/receive
881 */
882 int ripd_instance_version_receive_modify(struct nb_cb_modify_args *args)
883 {
884 struct rip *rip;
885
886 if (args->event != NB_EV_APPLY)
887 return NB_OK;
888
889 rip = nb_running_get_entry(args->dnode, NULL, true);
890 rip->version_recv = yang_dnode_get_enum(args->dnode, NULL);
891
892 return NB_OK;
893 }
894
895 /*
896 * XPath: /frr-ripd:ripd/instance/version/send
897 */
898 int ripd_instance_version_send_modify(struct nb_cb_modify_args *args)
899 {
900 struct rip *rip;
901
902 if (args->event != NB_EV_APPLY)
903 return NB_OK;
904
905 rip = nb_running_get_entry(args->dnode, NULL, true);
906 rip->version_send = yang_dnode_get_enum(args->dnode, NULL);
907
908 return NB_OK;
909 }
910
911 /*
912 * XPath: /frr-ripd:ripd/instance/default-bfd-profile
913 */
914 int ripd_instance_default_bfd_profile_modify(struct nb_cb_modify_args *args)
915 {
916 struct rip *rip;
917
918 if (args->event != NB_EV_APPLY)
919 return NB_OK;
920
921 rip = nb_running_get_entry(args->dnode, NULL, true);
922 XFREE(MTYPE_RIP_BFD_PROFILE, rip->default_bfd_profile);
923 rip->default_bfd_profile =
924 XSTRDUP(MTYPE_RIP_BFD_PROFILE,
925 yang_dnode_get_string(args->dnode, NULL));
926 rip_bfd_instance_update(rip);
927
928 return NB_OK;
929 }
930
931 int ripd_instance_default_bfd_profile_destroy(struct nb_cb_destroy_args *args)
932 {
933 struct rip *rip;
934
935 if (args->event != NB_EV_APPLY)
936 return NB_OK;
937
938 rip = nb_running_get_entry(args->dnode, NULL, true);
939 XFREE(MTYPE_RIP_BFD_PROFILE, rip->default_bfd_profile);
940 rip_bfd_instance_update(rip);
941
942 return NB_OK;
943 }
944
945 /*
946 * XPath: /frr-interface:lib/interface/frr-ripd:rip/split-horizon
947 */
948 int lib_interface_rip_split_horizon_modify(struct nb_cb_modify_args *args)
949 {
950 struct interface *ifp;
951 struct rip_interface *ri;
952
953 if (args->event != NB_EV_APPLY)
954 return NB_OK;
955
956 ifp = nb_running_get_entry(args->dnode, NULL, true);
957 ri = ifp->info;
958 ri->split_horizon = yang_dnode_get_enum(args->dnode, NULL);
959
960 return NB_OK;
961 }
962
963 /*
964 * XPath: /frr-interface:lib/interface/frr-ripd:rip/v2-broadcast
965 */
966 int lib_interface_rip_v2_broadcast_modify(struct nb_cb_modify_args *args)
967 {
968 struct interface *ifp;
969 struct rip_interface *ri;
970
971 if (args->event != NB_EV_APPLY)
972 return NB_OK;
973
974 ifp = nb_running_get_entry(args->dnode, NULL, true);
975 ri = ifp->info;
976 ri->v2_broadcast = yang_dnode_get_bool(args->dnode, NULL);
977
978 return NB_OK;
979 }
980
981 /*
982 * XPath: /frr-interface:lib/interface/frr-ripd:rip/version-receive
983 */
984 int lib_interface_rip_version_receive_modify(struct nb_cb_modify_args *args)
985 {
986 struct interface *ifp;
987 struct rip_interface *ri;
988
989 if (args->event != NB_EV_APPLY)
990 return NB_OK;
991
992 ifp = nb_running_get_entry(args->dnode, NULL, true);
993 ri = ifp->info;
994 ri->ri_receive = yang_dnode_get_enum(args->dnode, NULL);
995
996 return NB_OK;
997 }
998
999 /*
1000 * XPath: /frr-interface:lib/interface/frr-ripd:rip/version-send
1001 */
1002 int lib_interface_rip_version_send_modify(struct nb_cb_modify_args *args)
1003 {
1004 struct interface *ifp;
1005 struct rip_interface *ri;
1006
1007 if (args->event != NB_EV_APPLY)
1008 return NB_OK;
1009
1010 ifp = nb_running_get_entry(args->dnode, NULL, true);
1011 ri = ifp->info;
1012 ri->ri_send = yang_dnode_get_enum(args->dnode, NULL);
1013
1014 return NB_OK;
1015 }
1016
1017 /*
1018 * XPath: /frr-interface:lib/interface/frr-ripd:rip/authentication-scheme/mode
1019 */
1020 int lib_interface_rip_authentication_scheme_mode_modify(
1021 struct nb_cb_modify_args *args)
1022 {
1023 struct interface *ifp;
1024 struct rip_interface *ri;
1025
1026 if (args->event != NB_EV_APPLY)
1027 return NB_OK;
1028
1029 ifp = nb_running_get_entry(args->dnode, NULL, true);
1030 ri = ifp->info;
1031 ri->auth_type = yang_dnode_get_enum(args->dnode, NULL);
1032
1033 return NB_OK;
1034 }
1035
1036 /*
1037 * XPath:
1038 * /frr-interface:lib/interface/frr-ripd:rip/authentication-scheme/md5-auth-length
1039 */
1040 int lib_interface_rip_authentication_scheme_md5_auth_length_modify(
1041 struct nb_cb_modify_args *args)
1042 {
1043 struct interface *ifp;
1044 struct rip_interface *ri;
1045
1046 if (args->event != NB_EV_APPLY)
1047 return NB_OK;
1048
1049 ifp = nb_running_get_entry(args->dnode, NULL, true);
1050 ri = ifp->info;
1051 ri->md5_auth_len = yang_dnode_get_enum(args->dnode, NULL);
1052
1053 return NB_OK;
1054 }
1055
1056 int lib_interface_rip_authentication_scheme_md5_auth_length_destroy(
1057 struct nb_cb_destroy_args *args)
1058 {
1059 struct interface *ifp;
1060 struct rip_interface *ri;
1061
1062 if (args->event != NB_EV_APPLY)
1063 return NB_OK;
1064
1065 ifp = nb_running_get_entry(args->dnode, NULL, true);
1066 ri = ifp->info;
1067 ri->md5_auth_len = yang_get_default_enum(
1068 "%s/authentication-scheme/md5-auth-length", RIP_IFACE);
1069
1070 return NB_OK;
1071 }
1072
1073 /*
1074 * XPath: /frr-interface:lib/interface/frr-ripd:rip/authentication-password
1075 */
1076 int lib_interface_rip_authentication_password_modify(
1077 struct nb_cb_modify_args *args)
1078 {
1079 struct interface *ifp;
1080 struct rip_interface *ri;
1081
1082 if (args->event != NB_EV_APPLY)
1083 return NB_OK;
1084
1085 ifp = nb_running_get_entry(args->dnode, NULL, true);
1086 ri = ifp->info;
1087 XFREE(MTYPE_RIP_INTERFACE_STRING, ri->auth_str);
1088 ri->auth_str = XSTRDUP(MTYPE_RIP_INTERFACE_STRING,
1089 yang_dnode_get_string(args->dnode, NULL));
1090
1091 return NB_OK;
1092 }
1093
1094 int lib_interface_rip_authentication_password_destroy(
1095 struct nb_cb_destroy_args *args)
1096 {
1097 struct interface *ifp;
1098 struct rip_interface *ri;
1099
1100 if (args->event != NB_EV_APPLY)
1101 return NB_OK;
1102
1103 ifp = nb_running_get_entry(args->dnode, NULL, true);
1104 ri = ifp->info;
1105 XFREE(MTYPE_RIP_INTERFACE_STRING, ri->auth_str);
1106
1107 return NB_OK;
1108 }
1109
1110 /*
1111 * XPath: /frr-interface:lib/interface/frr-ripd:rip/bfd-monitoring
1112 */
1113 int lib_interface_rip_bfd_create(struct nb_cb_create_args *args)
1114 {
1115 struct interface *ifp;
1116 struct rip_interface *ri;
1117
1118 if (args->event != NB_EV_APPLY)
1119 return NB_OK;
1120
1121 ifp = nb_running_get_entry(args->dnode, NULL, true);
1122 ri = ifp->info;
1123 ri->bfd.enabled = yang_dnode_get_bool(args->dnode, "./enable");
1124 XFREE(MTYPE_RIP_BFD_PROFILE, ri->bfd.profile);
1125 if (yang_dnode_exists(args->dnode, "./profile"))
1126 ri->bfd.profile = XSTRDUP(
1127 MTYPE_RIP_BFD_PROFILE,
1128 yang_dnode_get_string(args->dnode, "./profile"));
1129
1130 rip_bfd_interface_update(ri);
1131
1132 return NB_OK;
1133 }
1134
1135 int lib_interface_rip_bfd_destroy(struct nb_cb_destroy_args *args)
1136 {
1137 struct interface *ifp;
1138 struct rip_interface *ri;
1139
1140 if (args->event != NB_EV_APPLY)
1141 return NB_OK;
1142
1143 ifp = nb_running_get_entry(args->dnode, NULL, true);
1144 ri = ifp->info;
1145 ri->bfd.enabled = false;
1146 XFREE(MTYPE_RIP_BFD_PROFILE, ri->bfd.profile);
1147 rip_bfd_interface_update(ri);
1148
1149 return NB_OK;
1150 }
1151
1152 /*
1153 * XPath: /frr-interface:lib/interface/frr-ripd:rip/bfd-monitoring/enable
1154 */
1155 int lib_interface_rip_bfd_enable_modify(struct nb_cb_modify_args *args)
1156 {
1157 struct interface *ifp;
1158 struct rip_interface *ri;
1159
1160 if (args->event != NB_EV_APPLY)
1161 return NB_OK;
1162
1163 ifp = nb_running_get_entry(args->dnode, NULL, true);
1164 ri = ifp->info;
1165 ri->bfd.enabled = yang_dnode_get_bool(args->dnode, NULL);
1166 rip_bfd_interface_update(ri);
1167
1168 return NB_OK;
1169 }
1170
1171 /*
1172 * XPath: /frr-interface:lib/interface/frr-ripd:rip/bfd-monitoring/profile
1173 */
1174 int lib_interface_rip_bfd_profile_modify(struct nb_cb_modify_args *args)
1175 {
1176 struct interface *ifp;
1177 struct rip_interface *ri;
1178
1179 if (args->event != NB_EV_APPLY)
1180 return NB_OK;
1181
1182 ifp = nb_running_get_entry(args->dnode, NULL, true);
1183 ri = ifp->info;
1184 XFREE(MTYPE_RIP_BFD_PROFILE, ri->bfd.profile);
1185 ri->bfd.profile = XSTRDUP(MTYPE_RIP_BFD_PROFILE,
1186 yang_dnode_get_string(args->dnode, NULL));
1187 rip_bfd_interface_update(ri);
1188
1189 return NB_OK;
1190 }
1191
1192 int lib_interface_rip_bfd_profile_destroy(struct nb_cb_destroy_args *args)
1193 {
1194 struct interface *ifp;
1195 struct rip_interface *ri;
1196
1197 if (args->event != NB_EV_APPLY)
1198 return NB_OK;
1199
1200 ifp = nb_running_get_entry(args->dnode, NULL, true);
1201 ri = ifp->info;
1202 XFREE(MTYPE_RIP_BFD_PROFILE, ri->bfd.profile);
1203 rip_bfd_interface_update(ri);
1204
1205 return NB_OK;
1206 }
1207
1208 /*
1209 * XPath: /frr-interface:lib/interface/frr-ripd:rip/authentication-key-chain
1210 */
1211 int lib_interface_rip_authentication_key_chain_modify(
1212 struct nb_cb_modify_args *args)
1213 {
1214 struct interface *ifp;
1215 struct rip_interface *ri;
1216
1217 if (args->event != NB_EV_APPLY)
1218 return NB_OK;
1219
1220 ifp = nb_running_get_entry(args->dnode, NULL, true);
1221 ri = ifp->info;
1222 XFREE(MTYPE_RIP_INTERFACE_STRING, ri->key_chain);
1223 ri->key_chain = XSTRDUP(MTYPE_RIP_INTERFACE_STRING,
1224 yang_dnode_get_string(args->dnode, NULL));
1225
1226 return NB_OK;
1227 }
1228
1229 int lib_interface_rip_authentication_key_chain_destroy(
1230 struct nb_cb_destroy_args *args)
1231 {
1232 struct interface *ifp;
1233 struct rip_interface *ri;
1234
1235 if (args->event != NB_EV_APPLY)
1236 return NB_OK;
1237
1238 ifp = nb_running_get_entry(args->dnode, NULL, true);
1239 ri = ifp->info;
1240 XFREE(MTYPE_RIP_INTERFACE_STRING, ri->key_chain);
1241
1242 return NB_OK;
1243 }