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