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