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