]> git.proxmox.com Git - mirror_frr.git/blame - ripd/rip_northbound.c
ripd: failure to create a socket shouldn't be a fatal error
[mirror_frr.git] / ripd / rip_northbound.c
CommitLineData
707656ec
RW
1/*
2 * Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro <kunihiro@zebra.org>
3 * Copyright (C) 2018 NetDEF, Inc.
4 * Renato Westphal
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include <zebra.h>
22
23#include "if.h"
24#include "vrf.h"
25#include "log.h"
26#include "prefix.h"
27#include "table.h"
28#include "command.h"
908f0020 29#include "routemap.h"
707656ec
RW
30#include "northbound.h"
31#include "libfrr.h"
32
33#include "ripd/ripd.h"
34#include "ripd/rip_cli.h"
35
36/*
37 * XPath: /frr-ripd:ripd/instance
38 */
39static int ripd_instance_create(enum nb_event event,
40 const struct lyd_node *dnode,
41 union nb_resource *resource)
42{
045c5389
RW
43 struct rip *rip;
44 struct vrf *vrf;
8c9226c2
RW
45 int socket;
46
47 switch (event) {
48 case NB_EV_VALIDATE:
49 break;
50 case NB_EV_PREPARE:
51 socket = rip_create_socket();
52 if (socket < 0)
53 return NB_ERR_RESOURCE;
54 resource->fd = socket;
55 break;
56 case NB_EV_ABORT:
57 socket = resource->fd;
58 close(socket);
59 break;
60 case NB_EV_APPLY:
045c5389 61 vrf = vrf_lookup_by_id(VRF_DEFAULT);
8c9226c2 62 socket = resource->fd;
045c5389
RW
63 rip = rip_create(vrf, socket);
64 yang_dnode_set_entry(dnode, rip);
8c9226c2
RW
65 break;
66 }
67
707656ec
RW
68 return NB_OK;
69}
70
71static int ripd_instance_delete(enum nb_event event,
72 const struct lyd_node *dnode)
73{
045c5389
RW
74 struct rip *rip;
75
8c9226c2
RW
76 if (event != NB_EV_APPLY)
77 return NB_OK;
78
045c5389
RW
79 rip = yang_dnode_get_entry(dnode, true);
80 rip_clean(rip);
8c9226c2 81
707656ec
RW
82 return NB_OK;
83}
84
85/*
86 * XPath: /frr-ripd:ripd/instance/allow-ecmp
87 */
88static int ripd_instance_allow_ecmp_modify(enum nb_event event,
89 const struct lyd_node *dnode,
90 union nb_resource *resource)
91{
045c5389
RW
92 struct rip *rip;
93
edbf59d2
RW
94 if (event != NB_EV_APPLY)
95 return NB_OK;
96
045c5389 97 rip = yang_dnode_get_entry(dnode, true);
edbf59d2
RW
98 rip->ecmp = yang_dnode_get_bool(dnode, NULL);
99 if (!rip->ecmp)
045c5389 100 rip_ecmp_disable(rip);
edbf59d2 101
707656ec
RW
102 return NB_OK;
103}
104
105/*
106 * XPath: /frr-ripd:ripd/instance/default-information-originate
107 */
108static int
109ripd_instance_default_information_originate_modify(enum nb_event event,
110 const struct lyd_node *dnode,
111 union nb_resource *resource)
112{
045c5389 113 struct rip *rip;
0b0609ba
RW
114 bool default_information;
115 struct prefix_ipv4 p;
116
117 if (event != NB_EV_APPLY)
118 return NB_OK;
119
045c5389 120 rip = yang_dnode_get_entry(dnode, true);
0b0609ba
RW
121 default_information = yang_dnode_get_bool(dnode, NULL);
122
123 memset(&p, 0, sizeof(struct prefix_ipv4));
124 p.family = AF_INET;
125 if (default_information) {
126 struct nexthop nh;
127
128 memset(&nh, 0, sizeof(nh));
129 nh.type = NEXTHOP_TYPE_IPV4;
045c5389
RW
130 rip_redistribute_add(rip, ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT,
131 &p, &nh, 0, 0, 0);
0b0609ba 132 } else {
045c5389
RW
133 rip_redistribute_delete(rip, ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT,
134 &p, 0);
0b0609ba
RW
135 }
136
707656ec
RW
137 return NB_OK;
138}
139
140/*
141 * XPath: /frr-ripd:ripd/instance/default-metric
142 */
143static int ripd_instance_default_metric_modify(enum nb_event event,
144 const struct lyd_node *dnode,
145 union nb_resource *resource)
146{
045c5389
RW
147 struct rip *rip;
148
282ae30c
RW
149 if (event != NB_EV_APPLY)
150 return NB_OK;
151
045c5389 152 rip = yang_dnode_get_entry(dnode, true);
282ae30c
RW
153 rip->default_metric = yang_dnode_get_uint8(dnode, NULL);
154 /* rip_update_default_metric (); */
155
707656ec
RW
156 return NB_OK;
157}
158
159/*
160 * XPath: /frr-ripd:ripd/instance/distance/default
161 */
162static int ripd_instance_distance_default_modify(enum nb_event event,
163 const struct lyd_node *dnode,
164 union nb_resource *resource)
165{
045c5389
RW
166 struct rip *rip;
167
7f8a9cba
RW
168 if (event != NB_EV_APPLY)
169 return NB_OK;
170
045c5389 171 rip = yang_dnode_get_entry(dnode, true);
7f8a9cba
RW
172 rip->distance = yang_dnode_get_uint8(dnode, NULL);
173
707656ec
RW
174 return NB_OK;
175}
176
177/*
178 * XPath: /frr-ripd:ripd/instance/distance/source
179 */
180static int ripd_instance_distance_source_create(enum nb_event event,
181 const struct lyd_node *dnode,
182 union nb_resource *resource)
183{
045c5389 184 struct rip *rip;
23b23d8c
RW
185 struct prefix_ipv4 prefix;
186 struct route_node *rn;
187
188 if (event != NB_EV_APPLY)
189 return NB_OK;
190
191 yang_dnode_get_ipv4p(&prefix, dnode, "./prefix");
d682d365 192 apply_mask_ipv4(&prefix);
23b23d8c
RW
193
194 /* Get RIP distance node. */
045c5389 195 rip = yang_dnode_get_entry(dnode, true);
2826309c 196 rn = route_node_get(rip->distance_table, (struct prefix *)&prefix);
23b23d8c
RW
197 rn->info = rip_distance_new();
198 yang_dnode_set_entry(dnode, rn);
199
707656ec
RW
200 return NB_OK;
201}
202
203static int ripd_instance_distance_source_delete(enum nb_event event,
204 const struct lyd_node *dnode)
205{
23b23d8c
RW
206 struct route_node *rn;
207 struct rip_distance *rdistance;
208
209 if (event != NB_EV_APPLY)
210 return NB_OK;
211
25c780a3 212 rn = yang_dnode_get_entry(dnode, true);
23b23d8c 213 rdistance = rn->info;
23b23d8c 214 rip_distance_free(rdistance);
23b23d8c
RW
215 rn->info = NULL;
216 route_unlock_node(rn);
217
707656ec
RW
218 return NB_OK;
219}
220
221/*
222 * XPath: /frr-ripd:ripd/instance/distance/source/distance
223 */
224static int
225ripd_instance_distance_source_distance_modify(enum nb_event event,
226 const struct lyd_node *dnode,
227 union nb_resource *resource)
228{
23b23d8c
RW
229 struct route_node *rn;
230 uint8_t distance;
231 struct rip_distance *rdistance;
232
233 if (event != NB_EV_APPLY)
234 return NB_OK;
235
236 /* Set distance value. */
25c780a3 237 rn = yang_dnode_get_entry(dnode, true);
23b23d8c
RW
238 distance = yang_dnode_get_uint8(dnode, NULL);
239 rdistance = rn->info;
240 rdistance->distance = distance;
241
707656ec
RW
242 return NB_OK;
243}
244
245/*
246 * XPath: /frr-ripd:ripd/instance/distance/source/access-list
247 */
248static int
249ripd_instance_distance_source_access_list_modify(enum nb_event event,
250 const struct lyd_node *dnode,
251 union nb_resource *resource)
252{
23b23d8c
RW
253 const char *acl_name;
254 struct route_node *rn;
255 struct rip_distance *rdistance;
256
257 if (event != NB_EV_APPLY)
258 return NB_OK;
259
260 acl_name = yang_dnode_get_string(dnode, NULL);
261
262 /* Set access-list */
25c780a3 263 rn = yang_dnode_get_entry(dnode, true);
23b23d8c
RW
264 rdistance = rn->info;
265 if (rdistance->access_list)
266 free(rdistance->access_list);
267 rdistance->access_list = strdup(acl_name);
268
707656ec
RW
269 return NB_OK;
270}
271
272static int
273ripd_instance_distance_source_access_list_delete(enum nb_event event,
274 const struct lyd_node *dnode)
275{
23b23d8c
RW
276 struct route_node *rn;
277 struct rip_distance *rdistance;
278
279 if (event != NB_EV_APPLY)
280 return NB_OK;
281
282 /* Reset access-list configuration. */
25c780a3 283 rn = yang_dnode_get_entry(dnode, true);
23b23d8c
RW
284 rdistance = rn->info;
285 free(rdistance->access_list);
286 rdistance->access_list = NULL;
287
707656ec
RW
288 return NB_OK;
289}
290
291/*
292 * XPath: /frr-ripd:ripd/instance/explicit-neighbor
293 */
294static int ripd_instance_explicit_neighbor_create(enum nb_event event,
295 const struct lyd_node *dnode,
296 union nb_resource *resource)
297{
045c5389 298 struct rip *rip;
f0ab22fb
RW
299 struct prefix_ipv4 p;
300
301 if (event != NB_EV_APPLY)
302 return NB_OK;
303
045c5389 304 rip = yang_dnode_get_entry(dnode, true);
f0ab22fb
RW
305 p.family = AF_INET;
306 p.prefixlen = IPV4_MAX_BITLEN;
307 yang_dnode_get_ipv4(&p.prefix, dnode, NULL);
308
045c5389 309 return rip_neighbor_add(rip, &p);
707656ec
RW
310}
311
312static int ripd_instance_explicit_neighbor_delete(enum nb_event event,
313 const struct lyd_node *dnode)
314{
045c5389 315 struct rip *rip;
f0ab22fb
RW
316 struct prefix_ipv4 p;
317
318 if (event != NB_EV_APPLY)
319 return NB_OK;
320
045c5389 321 rip = yang_dnode_get_entry(dnode, true);
f0ab22fb
RW
322 p.family = AF_INET;
323 p.prefixlen = IPV4_MAX_BITLEN;
324 yang_dnode_get_ipv4(&p.prefix, dnode, NULL);
325
045c5389 326 return rip_neighbor_delete(rip, &p);
707656ec
RW
327}
328
329/*
330 * XPath: /frr-ripd:ripd/instance/network
331 */
332static int ripd_instance_network_create(enum nb_event event,
333 const struct lyd_node *dnode,
334 union nb_resource *resource)
335{
045c5389 336 struct rip *rip;
3d7a1be8
RW
337 struct prefix p;
338
339 if (event != NB_EV_APPLY)
340 return NB_OK;
341
045c5389 342 rip = yang_dnode_get_entry(dnode, true);
3d7a1be8 343 yang_dnode_get_ipv4p(&p, dnode, NULL);
d682d365 344 apply_mask_ipv4((struct prefix_ipv4 *)&p);
3d7a1be8 345
045c5389 346 return rip_enable_network_add(rip, &p);
707656ec
RW
347}
348
349static int ripd_instance_network_delete(enum nb_event event,
350 const struct lyd_node *dnode)
351{
045c5389 352 struct rip *rip;
3d7a1be8
RW
353 struct prefix p;
354
355 if (event != NB_EV_APPLY)
356 return NB_OK;
357
045c5389 358 rip = yang_dnode_get_entry(dnode, true);
3d7a1be8 359 yang_dnode_get_ipv4p(&p, dnode, NULL);
d682d365 360 apply_mask_ipv4((struct prefix_ipv4 *)&p);
3d7a1be8 361
045c5389 362 return rip_enable_network_delete(rip, &p);
707656ec
RW
363}
364
365/*
366 * XPath: /frr-ripd:ripd/instance/interface
367 */
368static int ripd_instance_interface_create(enum nb_event event,
369 const struct lyd_node *dnode,
370 union nb_resource *resource)
371{
045c5389 372 struct rip *rip;
3d7a1be8
RW
373 const char *ifname;
374
375 if (event != NB_EV_APPLY)
376 return NB_OK;
377
045c5389 378 rip = yang_dnode_get_entry(dnode, true);
3d7a1be8
RW
379 ifname = yang_dnode_get_string(dnode, NULL);
380
045c5389 381 return rip_enable_if_add(rip, ifname);
707656ec
RW
382}
383
384static int ripd_instance_interface_delete(enum nb_event event,
385 const struct lyd_node *dnode)
386{
045c5389 387 struct rip *rip;
3d7a1be8
RW
388 const char *ifname;
389
390 if (event != NB_EV_APPLY)
391 return NB_OK;
392
045c5389 393 rip = yang_dnode_get_entry(dnode, true);
3d7a1be8
RW
394 ifname = yang_dnode_get_string(dnode, NULL);
395
045c5389 396 return rip_enable_if_delete(rip, ifname);
707656ec
RW
397}
398
399/*
400 * XPath: /frr-ripd:ripd/instance/offset-list
401 */
402static int ripd_instance_offset_list_create(enum nb_event event,
403 const struct lyd_node *dnode,
404 union nb_resource *resource)
405{
045c5389 406 struct rip *rip;
8c942f65
RW
407 const char *ifname;
408 struct rip_offset_list *offset;
409
410 if (event != NB_EV_APPLY)
411 return NB_OK;
412
045c5389 413 rip = yang_dnode_get_entry(dnode, true);
8c942f65
RW
414 ifname = yang_dnode_get_string(dnode, "./interface");
415
045c5389 416 offset = rip_offset_list_new(rip, ifname);
8c942f65
RW
417 yang_dnode_set_entry(dnode, offset);
418
707656ec
RW
419 return NB_OK;
420}
421
422static int ripd_instance_offset_list_delete(enum nb_event event,
423 const struct lyd_node *dnode)
424{
8c942f65
RW
425 int direct;
426 struct rip_offset_list *offset;
427
428 if (event != NB_EV_APPLY)
429 return NB_OK;
430
431 direct = yang_dnode_get_enum(dnode, "./direction");
432
25c780a3 433 offset = yang_dnode_get_entry(dnode, true);
8c942f65
RW
434 if (offset->direct[direct].alist_name) {
435 free(offset->direct[direct].alist_name);
436 offset->direct[direct].alist_name = NULL;
437 }
438 if (offset->direct[RIP_OFFSET_LIST_IN].alist_name == NULL
439 && offset->direct[RIP_OFFSET_LIST_OUT].alist_name == NULL)
440 offset_list_del(offset);
441
707656ec
RW
442 return NB_OK;
443}
444
445/*
446 * XPath: /frr-ripd:ripd/instance/offset-list/access-list
447 */
448static int
449ripd_instance_offset_list_access_list_modify(enum nb_event event,
450 const struct lyd_node *dnode,
451 union nb_resource *resource)
452{
8c942f65
RW
453 int direct;
454 struct rip_offset_list *offset;
455 const char *alist_name;
456
457 if (event != NB_EV_APPLY)
458 return NB_OK;
459
460 direct = yang_dnode_get_enum(dnode, "../direction");
461 alist_name = yang_dnode_get_string(dnode, NULL);
462
25c780a3 463 offset = yang_dnode_get_entry(dnode, true);
8c942f65
RW
464 if (offset->direct[direct].alist_name)
465 free(offset->direct[direct].alist_name);
466 offset->direct[direct].alist_name = strdup(alist_name);
467
707656ec
RW
468 return NB_OK;
469}
470
471/*
472 * XPath: /frr-ripd:ripd/instance/offset-list/metric
473 */
474static int ripd_instance_offset_list_metric_modify(enum nb_event event,
475 const struct lyd_node *dnode,
476 union nb_resource *resource)
477{
8c942f65
RW
478 int direct;
479 uint8_t metric;
480 struct rip_offset_list *offset;
481
482 if (event != NB_EV_APPLY)
483 return NB_OK;
484
485 direct = yang_dnode_get_enum(dnode, "../direction");
486 metric = yang_dnode_get_uint8(dnode, NULL);
487
25c780a3 488 offset = yang_dnode_get_entry(dnode, true);
8c942f65
RW
489 offset->direct[direct].metric = metric;
490
707656ec
RW
491 return NB_OK;
492}
493
494/*
495 * XPath: /frr-ripd:ripd/instance/passive-default
496 */
497static int ripd_instance_passive_default_modify(enum nb_event event,
498 const struct lyd_node *dnode,
499 union nb_resource *resource)
500{
045c5389
RW
501 struct rip *rip;
502
44f2f852
RW
503 if (event != NB_EV_APPLY)
504 return NB_OK;
505
045c5389 506 rip = yang_dnode_get_entry(dnode, true);
44f2f852 507 rip->passive_default = yang_dnode_get_bool(dnode, NULL);
045c5389 508 rip_passive_nondefault_clean(rip);
44f2f852 509
707656ec
RW
510 return NB_OK;
511}
512
513/*
514 * XPath: /frr-ripd:ripd/instance/passive-interface
515 */
516static int ripd_instance_passive_interface_create(enum nb_event event,
517 const struct lyd_node *dnode,
518 union nb_resource *resource)
519{
045c5389 520 struct rip *rip;
44f2f852
RW
521 const char *ifname;
522
523 if (event != NB_EV_APPLY)
524 return NB_OK;
525
045c5389 526 rip = yang_dnode_get_entry(dnode, true);
44f2f852
RW
527 ifname = yang_dnode_get_string(dnode, NULL);
528
045c5389 529 return rip_passive_nondefault_set(rip, ifname);
707656ec
RW
530}
531
532static int ripd_instance_passive_interface_delete(enum nb_event event,
533 const struct lyd_node *dnode)
534{
045c5389 535 struct rip *rip;
44f2f852
RW
536 const char *ifname;
537
538 if (event != NB_EV_APPLY)
539 return NB_OK;
540
045c5389 541 rip = yang_dnode_get_entry(dnode, true);
44f2f852
RW
542 ifname = yang_dnode_get_string(dnode, NULL);
543
045c5389 544 return rip_passive_nondefault_unset(rip, ifname);
707656ec
RW
545}
546
547/*
548 * XPath: /frr-ripd:ripd/instance/non-passive-interface
549 */
550static int
551ripd_instance_non_passive_interface_create(enum nb_event event,
552 const struct lyd_node *dnode,
553 union nb_resource *resource)
554{
045c5389 555 struct rip *rip;
44f2f852
RW
556 const char *ifname;
557
558 if (event != NB_EV_APPLY)
559 return NB_OK;
560
045c5389 561 rip = yang_dnode_get_entry(dnode, true);
44f2f852
RW
562 ifname = yang_dnode_get_string(dnode, NULL);
563
045c5389 564 return rip_passive_nondefault_unset(rip, ifname);
707656ec
RW
565}
566
567static int
568ripd_instance_non_passive_interface_delete(enum nb_event event,
569 const struct lyd_node *dnode)
570{
045c5389 571 struct rip *rip;
44f2f852
RW
572 const char *ifname;
573
574 if (event != NB_EV_APPLY)
575 return NB_OK;
576
045c5389 577 rip = yang_dnode_get_entry(dnode, true);
44f2f852
RW
578 ifname = yang_dnode_get_string(dnode, NULL);
579
045c5389 580 return rip_passive_nondefault_set(rip, ifname);
707656ec
RW
581}
582
583/*
584 * XPath: /frr-ripd:ripd/instance/redistribute
585 */
586static int ripd_instance_redistribute_create(enum nb_event event,
587 const struct lyd_node *dnode,
588 union nb_resource *resource)
589{
707656ec
RW
590 return NB_OK;
591}
592
593static int ripd_instance_redistribute_delete(enum nb_event event,
594 const struct lyd_node *dnode)
595{
045c5389 596 struct rip *rip;
908f0020
RW
597 int type;
598
599 if (event != NB_EV_APPLY)
600 return NB_OK;
601
045c5389 602 rip = yang_dnode_get_entry(dnode, true);
908f0020
RW
603 type = yang_dnode_get_enum(dnode, "./protocol");
604
045c5389 605 rip_redistribute_conf_delete(rip, type);
908f0020 606
707656ec
RW
607 return NB_OK;
608}
609
908f0020
RW
610static void
611ripd_instance_redistribute_apply_finish(const struct lyd_node *dnode)
612{
045c5389 613 struct rip *rip;
908f0020
RW
614 int type;
615
045c5389 616 rip = yang_dnode_get_entry(dnode, true);
908f0020 617 type = yang_dnode_get_enum(dnode, "./protocol");
045c5389
RW
618
619 rip_redistribute_conf_update(rip, type);
908f0020
RW
620}
621
707656ec
RW
622/*
623 * XPath: /frr-ripd:ripd/instance/redistribute/route-map
624 */
625static int
626ripd_instance_redistribute_route_map_modify(enum nb_event event,
627 const struct lyd_node *dnode,
628 union nb_resource *resource)
629{
045c5389 630 struct rip *rip;
908f0020
RW
631 int type;
632 const char *rmap_name;
633
634 if (event != NB_EV_APPLY)
635 return NB_OK;
636
045c5389 637 rip = yang_dnode_get_entry(dnode, true);
908f0020
RW
638 type = yang_dnode_get_enum(dnode, "../protocol");
639 rmap_name = yang_dnode_get_string(dnode, NULL);
640
641 if (rip->route_map[type].name)
642 free(rip->route_map[type].name);
643 rip->route_map[type].name = strdup(rmap_name);
644 rip->route_map[type].map = route_map_lookup_by_name(rmap_name);
645
707656ec
RW
646 return NB_OK;
647}
648
649static int
650ripd_instance_redistribute_route_map_delete(enum nb_event event,
651 const struct lyd_node *dnode)
652{
045c5389 653 struct rip *rip;
908f0020
RW
654 int type;
655
656 if (event != NB_EV_APPLY)
657 return NB_OK;
658
045c5389 659 rip = yang_dnode_get_entry(dnode, true);
908f0020
RW
660 type = yang_dnode_get_enum(dnode, "../protocol");
661
d682d365
RW
662 free(rip->route_map[type].name);
663 rip->route_map[type].name = NULL;
664 rip->route_map[type].map = NULL;
908f0020 665
707656ec
RW
666 return NB_OK;
667}
668
669/*
670 * XPath: /frr-ripd:ripd/instance/redistribute/metric
671 */
672static int
673ripd_instance_redistribute_metric_modify(enum nb_event event,
674 const struct lyd_node *dnode,
675 union nb_resource *resource)
676{
045c5389 677 struct rip *rip;
908f0020
RW
678 int type;
679 uint8_t metric;
680
681 if (event != NB_EV_APPLY)
682 return NB_OK;
683
045c5389 684 rip = yang_dnode_get_entry(dnode, true);
908f0020
RW
685 type = yang_dnode_get_enum(dnode, "../protocol");
686 metric = yang_dnode_get_uint8(dnode, NULL);
687
688 rip->route_map[type].metric_config = true;
689 rip->route_map[type].metric = metric;
690
707656ec
RW
691 return NB_OK;
692}
693
694static int
695ripd_instance_redistribute_metric_delete(enum nb_event event,
696 const struct lyd_node *dnode)
697{
045c5389 698 struct rip *rip;
908f0020
RW
699 int type;
700
701 if (event != NB_EV_APPLY)
702 return NB_OK;
703
045c5389 704 rip = yang_dnode_get_entry(dnode, true);
908f0020
RW
705 type = yang_dnode_get_enum(dnode, "../protocol");
706
707 rip->route_map[type].metric_config = false;
708 rip->route_map[type].metric = 0;
709
707656ec
RW
710 return NB_OK;
711}
712
713/*
714 * XPath: /frr-ripd:ripd/instance/static-route
715 */
716static int ripd_instance_static_route_create(enum nb_event event,
717 const struct lyd_node *dnode,
718 union nb_resource *resource)
719{
045c5389 720 struct rip *rip;
40687878
RW
721 struct nexthop nh;
722 struct prefix_ipv4 p;
723
724 if (event != NB_EV_APPLY)
725 return NB_OK;
726
045c5389 727 rip = yang_dnode_get_entry(dnode, true);
40687878 728 yang_dnode_get_ipv4p(&p, dnode, NULL);
d682d365 729 apply_mask_ipv4(&p);
40687878
RW
730
731 memset(&nh, 0, sizeof(nh));
732 nh.type = NEXTHOP_TYPE_IPV4;
045c5389
RW
733 rip_redistribute_add(rip, ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, &nh, 0,
734 0, 0);
40687878 735
707656ec
RW
736 return NB_OK;
737}
738
739static int ripd_instance_static_route_delete(enum nb_event event,
740 const struct lyd_node *dnode)
741{
045c5389 742 struct rip *rip;
40687878
RW
743 struct prefix_ipv4 p;
744
745 if (event != NB_EV_APPLY)
746 return NB_OK;
747
045c5389 748 rip = yang_dnode_get_entry(dnode, true);
40687878 749 yang_dnode_get_ipv4p(&p, dnode, NULL);
d682d365 750 apply_mask_ipv4(&p);
40687878 751
045c5389 752 rip_redistribute_delete(rip, ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, 0);
40687878 753
707656ec
RW
754 return NB_OK;
755}
756
b745780b
RW
757/*
758 * XPath: /frr-ripd:ripd/instance/timers/
759 */
760static void ripd_instance_timers_apply_finish(const struct lyd_node *dnode)
761{
045c5389
RW
762 struct rip *rip;
763
764 rip = yang_dnode_get_entry(dnode, true);
765
b745780b 766 /* Reset update timer thread. */
045c5389 767 rip_event(rip, RIP_UPDATE_EVENT, 0);
b745780b
RW
768}
769
707656ec
RW
770/*
771 * XPath: /frr-ripd:ripd/instance/timers/flush-interval
772 */
773static int
774ripd_instance_timers_flush_interval_modify(enum nb_event event,
775 const struct lyd_node *dnode,
776 union nb_resource *resource)
777{
045c5389
RW
778 struct rip *rip;
779
b745780b
RW
780 if (event != NB_EV_APPLY)
781 return NB_OK;
782
045c5389 783 rip = yang_dnode_get_entry(dnode, true);
b745780b
RW
784 rip->garbage_time = yang_dnode_get_uint32(dnode, NULL);
785
707656ec
RW
786 return NB_OK;
787}
788
789/*
790 * XPath: /frr-ripd:ripd/instance/timers/holddown-interval
791 */
792static int
793ripd_instance_timers_holddown_interval_modify(enum nb_event event,
794 const struct lyd_node *dnode,
795 union nb_resource *resource)
796{
045c5389
RW
797 struct rip *rip;
798
b745780b
RW
799 if (event != NB_EV_APPLY)
800 return NB_OK;
801
045c5389 802 rip = yang_dnode_get_entry(dnode, true);
b745780b
RW
803 rip->timeout_time = yang_dnode_get_uint32(dnode, NULL);
804
707656ec
RW
805 return NB_OK;
806}
807
808/*
809 * XPath: /frr-ripd:ripd/instance/timers/update-interval
810 */
811static int
812ripd_instance_timers_update_interval_modify(enum nb_event event,
813 const struct lyd_node *dnode,
814 union nb_resource *resource)
815{
045c5389
RW
816 struct rip *rip;
817
b745780b
RW
818 if (event != NB_EV_APPLY)
819 return NB_OK;
820
045c5389 821 rip = yang_dnode_get_entry(dnode, true);
b745780b
RW
822 rip->update_time = yang_dnode_get_uint32(dnode, NULL);
823
707656ec
RW
824 return NB_OK;
825}
826
827/*
828 * XPath: /frr-ripd:ripd/instance/version/receive
829 */
830static int ripd_instance_version_receive_modify(enum nb_event event,
831 const struct lyd_node *dnode,
832 union nb_resource *resource)
833{
045c5389
RW
834 struct rip *rip;
835
90eff9da
RW
836 if (event != NB_EV_APPLY)
837 return NB_OK;
838
045c5389 839 rip = yang_dnode_get_entry(dnode, true);
90eff9da
RW
840 rip->version_recv = yang_dnode_get_enum(dnode, NULL);
841
707656ec
RW
842 return NB_OK;
843}
844
845/*
846 * XPath: /frr-ripd:ripd/instance/version/send
847 */
848static int ripd_instance_version_send_modify(enum nb_event event,
849 const struct lyd_node *dnode,
850 union nb_resource *resource)
851{
045c5389
RW
852 struct rip *rip;
853
90eff9da
RW
854 if (event != NB_EV_APPLY)
855 return NB_OK;
856
045c5389 857 rip = yang_dnode_get_entry(dnode, true);
90eff9da
RW
858 rip->version_send = yang_dnode_get_enum(dnode, NULL);
859
707656ec
RW
860 return NB_OK;
861}
862
863/*
864 * XPath: /frr-interface:lib/interface/frr-ripd:rip/split-horizon
865 */
866static int lib_interface_rip_split_horizon_modify(enum nb_event event,
867 const struct lyd_node *dnode,
868 union nb_resource *resource)
869{
94b117b2
RW
870 struct interface *ifp;
871 struct rip_interface *ri;
872
873 if (event != NB_EV_APPLY)
874 return NB_OK;
875
25c780a3 876 ifp = yang_dnode_get_entry(dnode, true);
94b117b2
RW
877 ri = ifp->info;
878 ri->split_horizon = yang_dnode_get_enum(dnode, NULL);
879
707656ec
RW
880 return NB_OK;
881}
882
883/*
884 * XPath: /frr-interface:lib/interface/frr-ripd:rip/v2-broadcast
885 */
886static int lib_interface_rip_v2_broadcast_modify(enum nb_event event,
887 const struct lyd_node *dnode,
888 union nb_resource *resource)
889{
94b117b2
RW
890 struct interface *ifp;
891 struct rip_interface *ri;
892
893 if (event != NB_EV_APPLY)
894 return NB_OK;
895
25c780a3 896 ifp = yang_dnode_get_entry(dnode, true);
94b117b2
RW
897 ri = ifp->info;
898 ri->v2_broadcast = yang_dnode_get_bool(dnode, NULL);
899
707656ec
RW
900 return NB_OK;
901}
902
903/*
904 * XPath: /frr-interface:lib/interface/frr-ripd:rip/version-receive
905 */
906static int
907lib_interface_rip_version_receive_modify(enum nb_event event,
908 const struct lyd_node *dnode,
909 union nb_resource *resource)
910{
94b117b2
RW
911 struct interface *ifp;
912 struct rip_interface *ri;
913
914 if (event != NB_EV_APPLY)
915 return NB_OK;
916
25c780a3 917 ifp = yang_dnode_get_entry(dnode, true);
94b117b2
RW
918 ri = ifp->info;
919 ri->ri_receive = yang_dnode_get_enum(dnode, NULL);
920
707656ec
RW
921 return NB_OK;
922}
923
924/*
925 * XPath: /frr-interface:lib/interface/frr-ripd:rip/version-send
926 */
927static int lib_interface_rip_version_send_modify(enum nb_event event,
928 const struct lyd_node *dnode,
929 union nb_resource *resource)
930{
94b117b2
RW
931 struct interface *ifp;
932 struct rip_interface *ri;
933
934 if (event != NB_EV_APPLY)
935 return NB_OK;
936
25c780a3 937 ifp = yang_dnode_get_entry(dnode, true);
94b117b2
RW
938 ri = ifp->info;
939 ri->ri_send = yang_dnode_get_enum(dnode, NULL);
940
707656ec
RW
941 return NB_OK;
942}
943
944/*
945 * XPath: /frr-interface:lib/interface/frr-ripd:rip/authentication-scheme/mode
946 */
947static int lib_interface_rip_authentication_scheme_mode_modify(
948 enum nb_event event, const struct lyd_node *dnode,
949 union nb_resource *resource)
950{
94b117b2
RW
951 struct interface *ifp;
952 struct rip_interface *ri;
953
954 if (event != NB_EV_APPLY)
955 return NB_OK;
956
25c780a3 957 ifp = yang_dnode_get_entry(dnode, true);
94b117b2
RW
958 ri = ifp->info;
959 ri->auth_type = yang_dnode_get_enum(dnode, NULL);
960
707656ec
RW
961 return NB_OK;
962}
963
964/*
965 * XPath:
966 * /frr-interface:lib/interface/frr-ripd:rip/authentication-scheme/md5-auth-length
967 */
968static int lib_interface_rip_authentication_scheme_md5_auth_length_modify(
969 enum nb_event event, const struct lyd_node *dnode,
970 union nb_resource *resource)
971{
94b117b2
RW
972 struct interface *ifp;
973 struct rip_interface *ri;
974
975 if (event != NB_EV_APPLY)
976 return NB_OK;
977
25c780a3 978 ifp = yang_dnode_get_entry(dnode, true);
94b117b2
RW
979 ri = ifp->info;
980 ri->md5_auth_len = yang_dnode_get_enum(dnode, NULL);
981
707656ec
RW
982 return NB_OK;
983}
984
985static int lib_interface_rip_authentication_scheme_md5_auth_length_delete(
986 enum nb_event event, const struct lyd_node *dnode)
987{
94b117b2
RW
988 struct interface *ifp;
989 struct rip_interface *ri;
990
991 if (event != NB_EV_APPLY)
992 return NB_OK;
993
25c780a3 994 ifp = yang_dnode_get_entry(dnode, true);
94b117b2
RW
995 ri = ifp->info;
996 ri->md5_auth_len = yang_get_default_enum(
997 "%s/authentication-scheme/md5-auth-length", RIP_IFACE);
998
707656ec
RW
999 return NB_OK;
1000}
1001
1002/*
1003 * XPath: /frr-interface:lib/interface/frr-ripd:rip/authentication-password
1004 */
1005static int
1006lib_interface_rip_authentication_password_modify(enum nb_event event,
1007 const struct lyd_node *dnode,
1008 union nb_resource *resource)
1009{
94b117b2
RW
1010 struct interface *ifp;
1011 struct rip_interface *ri;
1012
1013 if (event != NB_EV_APPLY)
1014 return NB_OK;
1015
25c780a3 1016 ifp = yang_dnode_get_entry(dnode, true);
94b117b2
RW
1017 ri = ifp->info;
1018 if (ri->auth_str)
1019 XFREE(MTYPE_RIP_INTERFACE_STRING, ri->auth_str);
1020 ri->auth_str = XSTRDUP(MTYPE_RIP_INTERFACE_STRING,
1021 yang_dnode_get_string(dnode, NULL));
1022
707656ec
RW
1023 return NB_OK;
1024}
1025
1026static int
1027lib_interface_rip_authentication_password_delete(enum nb_event event,
1028 const struct lyd_node *dnode)
1029{
94b117b2
RW
1030 struct interface *ifp;
1031 struct rip_interface *ri;
1032
1033 if (event != NB_EV_APPLY)
1034 return NB_OK;
1035
25c780a3 1036 ifp = yang_dnode_get_entry(dnode, true);
94b117b2
RW
1037 ri = ifp->info;
1038 XFREE(MTYPE_RIP_INTERFACE_STRING, ri->auth_str);
1039
707656ec
RW
1040 return NB_OK;
1041}
1042
1043/*
1044 * XPath: /frr-interface:lib/interface/frr-ripd:rip/authentication-key-chain
1045 */
1046static int
1047lib_interface_rip_authentication_key_chain_modify(enum nb_event event,
1048 const struct lyd_node *dnode,
1049 union nb_resource *resource)
1050{
94b117b2
RW
1051 struct interface *ifp;
1052 struct rip_interface *ri;
1053
1054 if (event != NB_EV_APPLY)
1055 return NB_OK;
1056
25c780a3 1057 ifp = yang_dnode_get_entry(dnode, true);
94b117b2
RW
1058 ri = ifp->info;
1059 if (ri->key_chain)
1060 XFREE(MTYPE_RIP_INTERFACE_STRING, ri->key_chain);
1061 ri->key_chain = XSTRDUP(MTYPE_RIP_INTERFACE_STRING,
1062 yang_dnode_get_string(dnode, NULL));
1063
707656ec
RW
1064 return NB_OK;
1065}
1066
1067static int
1068lib_interface_rip_authentication_key_chain_delete(enum nb_event event,
1069 const struct lyd_node *dnode)
1070{
94b117b2
RW
1071 struct interface *ifp;
1072 struct rip_interface *ri;
1073
1074 if (event != NB_EV_APPLY)
1075 return NB_OK;
1076
25c780a3 1077 ifp = yang_dnode_get_entry(dnode, true);
94b117b2
RW
1078 ri = ifp->info;
1079 XFREE(MTYPE_RIP_INTERFACE_STRING, ri->key_chain);
1080
707656ec
RW
1081 return NB_OK;
1082}
1083
1084/*
1085 * XPath: /frr-ripd:ripd/state/neighbors/neighbor
1086 */
1087static const void *
1a4bc045 1088ripd_state_neighbors_neighbor_get_next(const void *parent_list_entry,
707656ec
RW
1089 const void *list_entry)
1090{
045c5389 1091 struct rip *rip;
5c1a8497
RW
1092 struct listnode *node;
1093
045c5389 1094 rip = rip_lookup_by_vrf_id(VRF_DEFAULT);
29e897ad
RW
1095 if (rip == NULL)
1096 return NULL;
1097
5c1a8497 1098 if (list_entry == NULL)
29e897ad 1099 node = listhead(rip->peer_list);
5c1a8497
RW
1100 else
1101 node = listnextnode((struct listnode *)list_entry);
1102
1103 return node;
707656ec
RW
1104}
1105
1106static int ripd_state_neighbors_neighbor_get_keys(const void *list_entry,
1107 struct yang_list_keys *keys)
1108{
5c1a8497
RW
1109 const struct listnode *node = list_entry;
1110 const struct rip_peer *peer = listgetdata(node);
1111
1112 keys->num = 1;
80243aef
RW
1113 (void)inet_ntop(AF_INET, &peer->addr, keys->key[0],
1114 sizeof(keys->key[0]));
5c1a8497 1115
707656ec
RW
1116 return NB_OK;
1117}
1118
1119static const void *
1a4bc045
RW
1120ripd_state_neighbors_neighbor_lookup_entry(const void *parent_list_entry,
1121 const struct yang_list_keys *keys)
707656ec 1122{
045c5389 1123 struct rip *rip;
5c1a8497 1124 struct in_addr address;
9c472033
RW
1125 struct rip_peer *peer;
1126 struct listnode *node;
5c1a8497 1127
80243aef 1128 yang_str2ipv4(keys->key[0], &address);
5c1a8497 1129
045c5389 1130 rip = rip_lookup_by_vrf_id(VRF_DEFAULT);
29e897ad
RW
1131 if (rip == NULL)
1132 return NULL;
1133
1134 for (ALL_LIST_ELEMENTS_RO(rip->peer_list, node, peer)) {
9c472033
RW
1135 if (IPV4_ADDR_SAME(&peer->addr, &address))
1136 return node;
1137 }
5c1a8497 1138
9c472033 1139 return NULL;
707656ec
RW
1140}
1141
1142/*
1143 * XPath: /frr-ripd:ripd/state/neighbors/neighbor/address
1144 */
1145static struct yang_data *
1146ripd_state_neighbors_neighbor_address_get_elem(const char *xpath,
1147 const void *list_entry)
1148{
9c472033
RW
1149 const struct listnode *node = list_entry;
1150 const struct rip_peer *peer = listgetdata(node);
5c1a8497
RW
1151
1152 return yang_data_new_ipv4(xpath, &peer->addr);
707656ec
RW
1153}
1154
1155/*
1156 * XPath: /frr-ripd:ripd/state/neighbors/neighbor/last-update
1157 */
1158static struct yang_data *
1159ripd_state_neighbors_neighbor_last_update_get_elem(const char *xpath,
1160 const void *list_entry)
1161{
5c1a8497 1162 /* TODO: yang:date-and-time is tricky */
707656ec
RW
1163 return NULL;
1164}
1165
1166/*
1167 * XPath: /frr-ripd:ripd/state/neighbors/neighbor/bad-packets-rcvd
1168 */
1169static struct yang_data *
1170ripd_state_neighbors_neighbor_bad_packets_rcvd_get_elem(const char *xpath,
1171 const void *list_entry)
1172{
9c472033
RW
1173 const struct listnode *node = list_entry;
1174 const struct rip_peer *peer = listgetdata(node);
5c1a8497
RW
1175
1176 return yang_data_new_uint32(xpath, peer->recv_badpackets);
707656ec
RW
1177}
1178
1179/*
1180 * XPath: /frr-ripd:ripd/state/neighbors/neighbor/bad-routes-rcvd
1181 */
1182static struct yang_data *
1183ripd_state_neighbors_neighbor_bad_routes_rcvd_get_elem(const char *xpath,
1184 const void *list_entry)
1185{
9c472033
RW
1186 const struct listnode *node = list_entry;
1187 const struct rip_peer *peer = listgetdata(node);
5c1a8497
RW
1188
1189 return yang_data_new_uint32(xpath, peer->recv_badroutes);
707656ec
RW
1190}
1191
1192/*
1193 * XPath: /frr-ripd:ripd/state/routes/route
1194 */
1a4bc045
RW
1195static const void *
1196ripd_state_routes_route_get_next(const void *parent_list_entry,
1197 const void *list_entry)
707656ec 1198{
045c5389 1199 struct rip *rip;
6270ce38
RW
1200 struct route_node *rn;
1201
045c5389 1202 rip = rip_lookup_by_vrf_id(VRF_DEFAULT);
6270ce38
RW
1203 if (rip == NULL)
1204 return NULL;
1205
1206 if (list_entry == NULL)
1207 rn = route_top(rip->table);
1208 else
1209 rn = route_next((struct route_node *)list_entry);
1210 while (rn && rn->info == NULL)
1211 rn = route_next(rn);
1212
1213 return rn;
707656ec
RW
1214}
1215
1216static int ripd_state_routes_route_get_keys(const void *list_entry,
1217 struct yang_list_keys *keys)
1218{
6270ce38
RW
1219 const struct route_node *rn = list_entry;
1220
1221 keys->num = 1;
80243aef 1222 (void)prefix2str(&rn->p, keys->key[0], sizeof(keys->key[0]));
6270ce38 1223
707656ec
RW
1224 return NB_OK;
1225}
1226
1227static const void *
1a4bc045
RW
1228ripd_state_routes_route_lookup_entry(const void *parent_list_entry,
1229 const struct yang_list_keys *keys)
707656ec 1230{
045c5389 1231 struct rip *rip;
6270ce38
RW
1232 struct prefix prefix;
1233 struct route_node *rn;
1234
80243aef 1235 yang_str2ipv4p(keys->key[0], &prefix);
6270ce38 1236
045c5389
RW
1237 rip = rip_lookup_by_vrf_id(VRF_DEFAULT);
1238 if (rip == NULL)
1239 return NULL;
1240
6270ce38
RW
1241 rn = route_node_lookup(rip->table, &prefix);
1242 if (!rn || !rn->info)
1243 return NULL;
1244
1245 route_unlock_node(rn);
1246
9c472033 1247 return rn;
707656ec
RW
1248}
1249
1250/*
1251 * XPath: /frr-ripd:ripd/state/routes/route/prefix
1252 */
1253static struct yang_data *
1254ripd_state_routes_route_prefix_get_elem(const char *xpath,
1255 const void *list_entry)
1256{
9c472033
RW
1257 const struct route_node *rn = list_entry;
1258 const struct rip_info *rinfo = listnode_head(rn->info);
6270ce38
RW
1259
1260 return yang_data_new_ipv4p(xpath, &rinfo->rp->p);
707656ec
RW
1261}
1262
1263/*
1264 * XPath: /frr-ripd:ripd/state/routes/route/next-hop
1265 */
1266static struct yang_data *
1267ripd_state_routes_route_next_hop_get_elem(const char *xpath,
1268 const void *list_entry)
1269{
9c472033
RW
1270 const struct route_node *rn = list_entry;
1271 const struct rip_info *rinfo = listnode_head(rn->info);
6270ce38
RW
1272
1273 switch (rinfo->nh.type) {
1274 case NEXTHOP_TYPE_IPV4:
1275 case NEXTHOP_TYPE_IPV4_IFINDEX:
1276 return yang_data_new_ipv4(xpath, &rinfo->nh.gate.ipv4);
1277 default:
1278 return NULL;
1279 }
707656ec
RW
1280}
1281
1282/*
1283 * XPath: /frr-ripd:ripd/state/routes/route/interface
1284 */
1285static struct yang_data *
1286ripd_state_routes_route_interface_get_elem(const char *xpath,
1287 const void *list_entry)
1288{
9c472033
RW
1289 const struct route_node *rn = list_entry;
1290 const struct rip_info *rinfo = listnode_head(rn->info);
6270ce38
RW
1291
1292 switch (rinfo->nh.type) {
1293 case NEXTHOP_TYPE_IFINDEX:
1294 case NEXTHOP_TYPE_IPV4_IFINDEX:
1295 return yang_data_new_string(
1296 xpath, ifindex2ifname(rinfo->nh.ifindex, VRF_DEFAULT));
1297 default:
1298 return NULL;
1299 }
707656ec
RW
1300}
1301
1302/*
1303 * XPath: /frr-ripd:ripd/state/routes/route/metric
1304 */
1305static struct yang_data *
1306ripd_state_routes_route_metric_get_elem(const char *xpath,
1307 const void *list_entry)
1308{
9c472033
RW
1309 const struct route_node *rn = list_entry;
1310 const struct rip_info *rinfo = listnode_head(rn->info);
6270ce38
RW
1311
1312 return yang_data_new_uint8(xpath, rinfo->metric);
707656ec
RW
1313}
1314
1315/*
1316 * XPath: /frr-ripd:clear-rip-route
1317 */
1318static int clear_rip_route_rpc(const char *xpath, const struct list *input,
1319 struct list *output)
1320{
045c5389 1321 struct rip *rip;
1137aef4
RW
1322 struct route_node *rp;
1323 struct rip_info *rinfo;
1324 struct list *list;
1325 struct listnode *listnode;
1326
045c5389 1327 rip = rip_lookup_by_vrf_id(VRF_DEFAULT);
bb5d09c9
RW
1328 if (!rip)
1329 return NB_OK;
1330
1137aef4
RW
1331 /* Clear received RIP routes */
1332 for (rp = route_top(rip->table); rp; rp = route_next(rp)) {
1333 list = rp->info;
1334 if (!list)
1335 continue;
1336
1337 for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) {
1338 if (!rip_route_rte(rinfo))
1339 continue;
1340
1341 if (CHECK_FLAG(rinfo->flags, RIP_RTF_FIB))
045c5389 1342 rip_zebra_ipv4_delete(rip, rp);
1137aef4
RW
1343 break;
1344 }
1345
1346 if (rinfo) {
1347 RIP_TIMER_OFF(rinfo->t_timeout);
1348 RIP_TIMER_OFF(rinfo->t_garbage_collect);
1349 listnode_delete(list, rinfo);
1350 rip_info_free(rinfo);
1351 }
1352
1353 if (list_isempty(list)) {
1354 list_delete(&list);
1355 rp->info = NULL;
1356 route_unlock_node(rp);
1357 }
1358 }
1359
707656ec
RW
1360 return NB_OK;
1361}
1362
fe339c95
RW
1363/*
1364 * XPath: /frr-ripd:authentication-type-failure
1365 */
1366void ripd_notif_send_auth_type_failure(const char *ifname)
1367{
1368 const char *xpath = "/frr-ripd:authentication-type-failure";
1369 struct list *arguments;
1370 char xpath_arg[XPATH_MAXLEN];
1371 struct yang_data *data;
1372
1373 arguments = yang_data_list_new();
1374
1375 snprintf(xpath_arg, sizeof(xpath_arg), "%s/interface-name", xpath);
1376 data = yang_data_new_string(xpath_arg, ifname);
1377 listnode_add(arguments, data);
1378
1379 nb_notification_send(xpath, arguments);
1380}
1381
1382/*
1383 * XPath: /frr-ripd:authentication-failure
1384 */
1385void ripd_notif_send_auth_failure(const char *ifname)
1386{
1387 const char *xpath = "/frr-ripd:authentication-failure";
1388 struct list *arguments;
1389 char xpath_arg[XPATH_MAXLEN];
1390 struct yang_data *data;
1391
1392 arguments = yang_data_list_new();
1393
1394 snprintf(xpath_arg, sizeof(xpath_arg), "%s/interface-name", xpath);
1395 data = yang_data_new_string(xpath_arg, ifname);
1396 listnode_add(arguments, data);
1397
1398 nb_notification_send(xpath, arguments);
1399}
1400
707656ec
RW
1401/* clang-format off */
1402const struct frr_yang_module_info frr_ripd_info = {
1403 .name = "frr-ripd",
1404 .nodes = {
1405 {
1406 .xpath = "/frr-ripd:ripd/instance",
1407 .cbs.create = ripd_instance_create,
1408 .cbs.delete = ripd_instance_delete,
8c9226c2 1409 .cbs.cli_show = cli_show_router_rip,
707656ec
RW
1410 },
1411 {
1412 .xpath = "/frr-ripd:ripd/instance/allow-ecmp",
1413 .cbs.modify = ripd_instance_allow_ecmp_modify,
edbf59d2 1414 .cbs.cli_show = cli_show_rip_allow_ecmp,
707656ec
RW
1415 },
1416 {
1417 .xpath = "/frr-ripd:ripd/instance/default-information-originate",
1418 .cbs.modify = ripd_instance_default_information_originate_modify,
0b0609ba 1419 .cbs.cli_show = cli_show_rip_default_information_originate,
707656ec
RW
1420 },
1421 {
1422 .xpath = "/frr-ripd:ripd/instance/default-metric",
1423 .cbs.modify = ripd_instance_default_metric_modify,
282ae30c 1424 .cbs.cli_show = cli_show_rip_default_metric,
707656ec
RW
1425 },
1426 {
1427 .xpath = "/frr-ripd:ripd/instance/distance/default",
1428 .cbs.modify = ripd_instance_distance_default_modify,
7f8a9cba 1429 .cbs.cli_show = cli_show_rip_distance,
707656ec
RW
1430 },
1431 {
1432 .xpath = "/frr-ripd:ripd/instance/distance/source",
1433 .cbs.create = ripd_instance_distance_source_create,
1434 .cbs.delete = ripd_instance_distance_source_delete,
23b23d8c 1435 .cbs.cli_show = cli_show_rip_distance_source,
707656ec
RW
1436 },
1437 {
1438 .xpath = "/frr-ripd:ripd/instance/distance/source/distance",
1439 .cbs.modify = ripd_instance_distance_source_distance_modify,
1440 },
1441 {
1442 .xpath = "/frr-ripd:ripd/instance/distance/source/access-list",
1443 .cbs.modify = ripd_instance_distance_source_access_list_modify,
1444 .cbs.delete = ripd_instance_distance_source_access_list_delete,
1445 },
1446 {
1447 .xpath = "/frr-ripd:ripd/instance/explicit-neighbor",
1448 .cbs.create = ripd_instance_explicit_neighbor_create,
1449 .cbs.delete = ripd_instance_explicit_neighbor_delete,
f0ab22fb 1450 .cbs.cli_show = cli_show_rip_neighbor,
707656ec
RW
1451 },
1452 {
1453 .xpath = "/frr-ripd:ripd/instance/network",
1454 .cbs.create = ripd_instance_network_create,
1455 .cbs.delete = ripd_instance_network_delete,
3d7a1be8 1456 .cbs.cli_show = cli_show_rip_network_prefix,
707656ec
RW
1457 },
1458 {
1459 .xpath = "/frr-ripd:ripd/instance/interface",
1460 .cbs.create = ripd_instance_interface_create,
1461 .cbs.delete = ripd_instance_interface_delete,
3d7a1be8 1462 .cbs.cli_show = cli_show_rip_network_interface,
707656ec
RW
1463 },
1464 {
1465 .xpath = "/frr-ripd:ripd/instance/offset-list",
1466 .cbs.create = ripd_instance_offset_list_create,
1467 .cbs.delete = ripd_instance_offset_list_delete,
8c942f65 1468 .cbs.cli_show = cli_show_rip_offset_list,
707656ec
RW
1469 },
1470 {
1471 .xpath = "/frr-ripd:ripd/instance/offset-list/access-list",
1472 .cbs.modify = ripd_instance_offset_list_access_list_modify,
1473 },
1474 {
1475 .xpath = "/frr-ripd:ripd/instance/offset-list/metric",
1476 .cbs.modify = ripd_instance_offset_list_metric_modify,
1477 },
1478 {
1479 .xpath = "/frr-ripd:ripd/instance/passive-default",
1480 .cbs.modify = ripd_instance_passive_default_modify,
44f2f852 1481 .cbs.cli_show = cli_show_rip_passive_default,
707656ec
RW
1482 },
1483 {
1484 .xpath = "/frr-ripd:ripd/instance/passive-interface",
1485 .cbs.create = ripd_instance_passive_interface_create,
1486 .cbs.delete = ripd_instance_passive_interface_delete,
44f2f852 1487 .cbs.cli_show = cli_show_rip_passive_interface,
707656ec
RW
1488 },
1489 {
1490 .xpath = "/frr-ripd:ripd/instance/non-passive-interface",
1491 .cbs.create = ripd_instance_non_passive_interface_create,
1492 .cbs.delete = ripd_instance_non_passive_interface_delete,
44f2f852 1493 .cbs.cli_show = cli_show_rip_non_passive_interface,
707656ec
RW
1494 },
1495 {
1496 .xpath = "/frr-ripd:ripd/instance/redistribute",
1497 .cbs.create = ripd_instance_redistribute_create,
1498 .cbs.delete = ripd_instance_redistribute_delete,
908f0020
RW
1499 .cbs.apply_finish = ripd_instance_redistribute_apply_finish,
1500 .cbs.cli_show = cli_show_rip_redistribute,
707656ec
RW
1501 },
1502 {
1503 .xpath = "/frr-ripd:ripd/instance/redistribute/route-map",
1504 .cbs.modify = ripd_instance_redistribute_route_map_modify,
1505 .cbs.delete = ripd_instance_redistribute_route_map_delete,
1506 },
1507 {
1508 .xpath = "/frr-ripd:ripd/instance/redistribute/metric",
1509 .cbs.modify = ripd_instance_redistribute_metric_modify,
1510 .cbs.delete = ripd_instance_redistribute_metric_delete,
1511 },
1512 {
1513 .xpath = "/frr-ripd:ripd/instance/static-route",
1514 .cbs.create = ripd_instance_static_route_create,
1515 .cbs.delete = ripd_instance_static_route_delete,
40687878 1516 .cbs.cli_show = cli_show_rip_route,
707656ec 1517 },
b745780b
RW
1518 {
1519 .xpath = "/frr-ripd:ripd/instance/timers",
1520 .cbs.apply_finish = ripd_instance_timers_apply_finish,
1521 .cbs.cli_show = cli_show_rip_timers,
1522 },
707656ec
RW
1523 {
1524 .xpath = "/frr-ripd:ripd/instance/timers/flush-interval",
1525 .cbs.modify = ripd_instance_timers_flush_interval_modify,
1526 },
1527 {
1528 .xpath = "/frr-ripd:ripd/instance/timers/holddown-interval",
1529 .cbs.modify = ripd_instance_timers_holddown_interval_modify,
1530 },
1531 {
1532 .xpath = "/frr-ripd:ripd/instance/timers/update-interval",
1533 .cbs.modify = ripd_instance_timers_update_interval_modify,
1534 },
90eff9da
RW
1535 {
1536 .xpath = "/frr-ripd:ripd/instance/version",
1537 .cbs.cli_show = cli_show_rip_version,
1538 },
707656ec
RW
1539 {
1540 .xpath = "/frr-ripd:ripd/instance/version/receive",
1541 .cbs.modify = ripd_instance_version_receive_modify,
1542 },
1543 {
1544 .xpath = "/frr-ripd:ripd/instance/version/send",
1545 .cbs.modify = ripd_instance_version_send_modify,
1546 },
1547 {
1548 .xpath = "/frr-interface:lib/interface/frr-ripd:rip/split-horizon",
1549 .cbs.modify = lib_interface_rip_split_horizon_modify,
94b117b2 1550 .cbs.cli_show = cli_show_ip_rip_split_horizon,
707656ec
RW
1551 },
1552 {
1553 .xpath = "/frr-interface:lib/interface/frr-ripd:rip/v2-broadcast",
1554 .cbs.modify = lib_interface_rip_v2_broadcast_modify,
94b117b2 1555 .cbs.cli_show = cli_show_ip_rip_v2_broadcast,
707656ec
RW
1556 },
1557 {
1558 .xpath = "/frr-interface:lib/interface/frr-ripd:rip/version-receive",
1559 .cbs.modify = lib_interface_rip_version_receive_modify,
94b117b2 1560 .cbs.cli_show = cli_show_ip_rip_receive_version,
707656ec
RW
1561 },
1562 {
1563 .xpath = "/frr-interface:lib/interface/frr-ripd:rip/version-send",
1564 .cbs.modify = lib_interface_rip_version_send_modify,
94b117b2
RW
1565 .cbs.cli_show = cli_show_ip_rip_send_version,
1566 },
1567 {
1568 .xpath = "/frr-interface:lib/interface/frr-ripd:rip/authentication-scheme",
1569 .cbs.cli_show = cli_show_ip_rip_authentication_scheme,
707656ec
RW
1570 },
1571 {
1572 .xpath = "/frr-interface:lib/interface/frr-ripd:rip/authentication-scheme/mode",
1573 .cbs.modify = lib_interface_rip_authentication_scheme_mode_modify,
1574 },
1575 {
1576 .xpath = "/frr-interface:lib/interface/frr-ripd:rip/authentication-scheme/md5-auth-length",
1577 .cbs.modify = lib_interface_rip_authentication_scheme_md5_auth_length_modify,
1578 .cbs.delete = lib_interface_rip_authentication_scheme_md5_auth_length_delete,
1579 },
1580 {
1581 .xpath = "/frr-interface:lib/interface/frr-ripd:rip/authentication-password",
1582 .cbs.modify = lib_interface_rip_authentication_password_modify,
1583 .cbs.delete = lib_interface_rip_authentication_password_delete,
94b117b2 1584 .cbs.cli_show = cli_show_ip_rip_authentication_string,
707656ec
RW
1585 },
1586 {
1587 .xpath = "/frr-interface:lib/interface/frr-ripd:rip/authentication-key-chain",
1588 .cbs.modify = lib_interface_rip_authentication_key_chain_modify,
1589 .cbs.delete = lib_interface_rip_authentication_key_chain_delete,
94b117b2 1590 .cbs.cli_show = cli_show_ip_rip_authentication_key_chain,
707656ec
RW
1591 },
1592 {
1593 .xpath = "/frr-ripd:ripd/state/neighbors/neighbor",
1594 .cbs.get_next = ripd_state_neighbors_neighbor_get_next,
1595 .cbs.get_keys = ripd_state_neighbors_neighbor_get_keys,
1596 .cbs.lookup_entry = ripd_state_neighbors_neighbor_lookup_entry,
1597 },
1598 {
1599 .xpath = "/frr-ripd:ripd/state/neighbors/neighbor/address",
1600 .cbs.get_elem = ripd_state_neighbors_neighbor_address_get_elem,
1601 },
1602 {
1603 .xpath = "/frr-ripd:ripd/state/neighbors/neighbor/last-update",
1604 .cbs.get_elem = ripd_state_neighbors_neighbor_last_update_get_elem,
1605 },
1606 {
1607 .xpath = "/frr-ripd:ripd/state/neighbors/neighbor/bad-packets-rcvd",
1608 .cbs.get_elem = ripd_state_neighbors_neighbor_bad_packets_rcvd_get_elem,
1609 },
1610 {
1611 .xpath = "/frr-ripd:ripd/state/neighbors/neighbor/bad-routes-rcvd",
1612 .cbs.get_elem = ripd_state_neighbors_neighbor_bad_routes_rcvd_get_elem,
1613 },
1614 {
1615 .xpath = "/frr-ripd:ripd/state/routes/route",
1616 .cbs.get_next = ripd_state_routes_route_get_next,
1617 .cbs.get_keys = ripd_state_routes_route_get_keys,
1618 .cbs.lookup_entry = ripd_state_routes_route_lookup_entry,
1619 },
1620 {
1621 .xpath = "/frr-ripd:ripd/state/routes/route/prefix",
1622 .cbs.get_elem = ripd_state_routes_route_prefix_get_elem,
1623 },
1624 {
1625 .xpath = "/frr-ripd:ripd/state/routes/route/next-hop",
1626 .cbs.get_elem = ripd_state_routes_route_next_hop_get_elem,
1627 },
1628 {
1629 .xpath = "/frr-ripd:ripd/state/routes/route/interface",
1630 .cbs.get_elem = ripd_state_routes_route_interface_get_elem,
1631 },
1632 {
1633 .xpath = "/frr-ripd:ripd/state/routes/route/metric",
1634 .cbs.get_elem = ripd_state_routes_route_metric_get_elem,
1635 },
1636 {
1637 .xpath = "/frr-ripd:clear-rip-route",
1638 .cbs.rpc = clear_rip_route_rpc,
1639 },
1640 {
1641 .xpath = NULL,
1642 },
1643 }
1644};