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