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