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