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