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