]> git.proxmox.com Git - mirror_frr.git/blob - ripngd/ripng_nb_config.c
Merge pull request #12196 from opensourcerouting/xref-vtysh
[mirror_frr.git] / ripngd / ripng_nb_config.c
1 /*
2 * Copyright (C) 1998 Kunihiro Ishiguro
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 "agg_table.h"
31 #include "northbound.h"
32 #include "libfrr.h"
33
34 #include "ripngd/ripngd.h"
35 #include "ripngd/ripng_nb.h"
36 #include "ripngd/ripng_debug.h"
37 #include "ripngd/ripng_route.h"
38
39 /*
40 * XPath: /frr-ripngd:ripngd/instance
41 */
42 int ripngd_instance_create(struct nb_cb_create_args *args)
43 {
44 struct ripng *ripng;
45 struct vrf *vrf;
46 const char *vrf_name;
47 int socket;
48
49 vrf_name = yang_dnode_get_string(args->dnode, "./vrf");
50 vrf = vrf_lookup_by_name(vrf_name);
51
52 /*
53 * Try to create a RIPng socket only if the VRF is enabled, otherwise
54 * create a disabled RIPng instance and wait for the VRF to be enabled.
55 */
56 switch (args->event) {
57 case NB_EV_VALIDATE:
58 break;
59 case NB_EV_PREPARE:
60 if (!vrf || !vrf_is_enabled(vrf))
61 break;
62
63 socket = ripng_make_socket(vrf);
64 if (socket < 0)
65 return NB_ERR_RESOURCE;
66 args->resource->fd = socket;
67 break;
68 case NB_EV_ABORT:
69 if (!vrf || !vrf_is_enabled(vrf))
70 break;
71
72 socket = args->resource->fd;
73 close(socket);
74 break;
75 case NB_EV_APPLY:
76 if (vrf && vrf_is_enabled(vrf))
77 socket = args->resource->fd;
78 else
79 socket = -1;
80
81 ripng = ripng_create(vrf_name, vrf, socket);
82 nb_running_set_entry(args->dnode, ripng);
83 break;
84 }
85
86 return NB_OK;
87 }
88
89 int ripngd_instance_destroy(struct nb_cb_destroy_args *args)
90 {
91 struct ripng *ripng;
92
93 if (args->event != NB_EV_APPLY)
94 return NB_OK;
95
96 ripng = nb_running_unset_entry(args->dnode);
97 ripng_clean(ripng);
98
99 return NB_OK;
100 }
101
102 const void *ripngd_instance_get_next(struct nb_cb_get_next_args *args)
103 {
104 struct ripng *ripng = (struct ripng *)args->list_entry;
105
106 if (args->list_entry == NULL)
107 ripng = RB_MIN(ripng_instance_head, &ripng_instances);
108 else
109 ripng = RB_NEXT(ripng_instance_head, ripng);
110
111 return ripng;
112 }
113
114 int ripngd_instance_get_keys(struct nb_cb_get_keys_args *args)
115 {
116 const struct ripng *ripng = args->list_entry;
117
118 args->keys->num = 1;
119 strlcpy(args->keys->key[0], ripng->vrf_name,
120 sizeof(args->keys->key[0]));
121
122 return NB_OK;
123 }
124
125 const void *ripngd_instance_lookup_entry(struct nb_cb_lookup_entry_args *args)
126 {
127 const char *vrf_name = args->keys->key[0];
128
129 return ripng_lookup_by_vrf_name(vrf_name);
130 }
131
132 /*
133 * XPath: /frr-ripngd:ripngd/instance/allow-ecmp
134 */
135 int ripngd_instance_allow_ecmp_modify(struct nb_cb_modify_args *args)
136 {
137 struct ripng *ripng;
138
139 if (args->event != NB_EV_APPLY)
140 return NB_OK;
141
142 ripng = nb_running_get_entry(args->dnode, NULL, true);
143 ripng->ecmp = yang_dnode_get_bool(args->dnode, NULL);
144 if (!ripng->ecmp)
145 ripng_ecmp_disable(ripng);
146
147 return NB_OK;
148 }
149
150 /*
151 * XPath: /frr-ripngd:ripngd/instance/default-information-originate
152 */
153 int ripngd_instance_default_information_originate_modify(
154 struct nb_cb_modify_args *args)
155 {
156 struct ripng *ripng;
157 bool default_information;
158 struct prefix_ipv6 p;
159
160 if (args->event != NB_EV_APPLY)
161 return NB_OK;
162
163 ripng = nb_running_get_entry(args->dnode, NULL, true);
164 default_information = yang_dnode_get_bool(args->dnode, NULL);
165
166 (void)str2prefix_ipv6("::/0", &p);
167 if (default_information) {
168 ripng_redistribute_add(ripng, ZEBRA_ROUTE_RIPNG,
169 RIPNG_ROUTE_DEFAULT, &p, 0, NULL, 0);
170 } else {
171 ripng_redistribute_delete(ripng, ZEBRA_ROUTE_RIPNG,
172 RIPNG_ROUTE_DEFAULT, &p, 0);
173 }
174
175 return NB_OK;
176 }
177
178 /*
179 * XPath: /frr-ripngd:ripngd/instance/default-metric
180 */
181 int ripngd_instance_default_metric_modify(struct nb_cb_modify_args *args)
182 {
183 struct ripng *ripng;
184
185 if (args->event != NB_EV_APPLY)
186 return NB_OK;
187
188 ripng = nb_running_get_entry(args->dnode, NULL, true);
189 ripng->default_metric = yang_dnode_get_uint8(args->dnode, NULL);
190
191 return NB_OK;
192 }
193
194 /*
195 * XPath: /frr-ripngd:ripngd/instance/network
196 */
197 int ripngd_instance_network_create(struct nb_cb_create_args *args)
198 {
199 struct ripng *ripng;
200 struct prefix p;
201
202 if (args->event != NB_EV_APPLY)
203 return NB_OK;
204
205 ripng = nb_running_get_entry(args->dnode, NULL, true);
206 yang_dnode_get_ipv6p(&p, args->dnode, NULL);
207 apply_mask_ipv6((struct prefix_ipv6 *)&p);
208
209 return ripng_enable_network_add(ripng, &p);
210 }
211
212 int ripngd_instance_network_destroy(struct nb_cb_destroy_args *args)
213 {
214 struct ripng *ripng;
215 struct prefix p;
216
217 if (args->event != NB_EV_APPLY)
218 return NB_OK;
219
220 ripng = nb_running_get_entry(args->dnode, NULL, true);
221 yang_dnode_get_ipv6p(&p, args->dnode, NULL);
222 apply_mask_ipv6((struct prefix_ipv6 *)&p);
223
224 return ripng_enable_network_delete(ripng, &p);
225 }
226
227 /*
228 * XPath: /frr-ripngd:ripngd/instance/interface
229 */
230 int ripngd_instance_interface_create(struct nb_cb_create_args *args)
231 {
232 struct ripng *ripng;
233 const char *ifname;
234
235 if (args->event != NB_EV_APPLY)
236 return NB_OK;
237
238 ripng = nb_running_get_entry(args->dnode, NULL, true);
239 ifname = yang_dnode_get_string(args->dnode, NULL);
240
241 return ripng_enable_if_add(ripng, ifname);
242 }
243
244 int ripngd_instance_interface_destroy(struct nb_cb_destroy_args *args)
245 {
246 struct ripng *ripng;
247 const char *ifname;
248
249 if (args->event != NB_EV_APPLY)
250 return NB_OK;
251
252 ripng = nb_running_get_entry(args->dnode, NULL, true);
253 ifname = yang_dnode_get_string(args->dnode, NULL);
254
255 return ripng_enable_if_delete(ripng, ifname);
256 }
257
258 /*
259 * XPath: /frr-ripngd:ripngd/instance/offset-list
260 */
261 int ripngd_instance_offset_list_create(struct nb_cb_create_args *args)
262 {
263 struct ripng *ripng;
264 const char *ifname;
265 struct ripng_offset_list *offset;
266
267 if (args->event != NB_EV_APPLY)
268 return NB_OK;
269
270 ripng = nb_running_get_entry(args->dnode, NULL, true);
271 ifname = yang_dnode_get_string(args->dnode, "./interface");
272
273 offset = ripng_offset_list_new(ripng, ifname);
274 nb_running_set_entry(args->dnode, offset);
275
276 return NB_OK;
277 }
278
279 int ripngd_instance_offset_list_destroy(struct nb_cb_destroy_args *args)
280 {
281 int direct;
282 struct ripng_offset_list *offset;
283
284 if (args->event != NB_EV_APPLY)
285 return NB_OK;
286
287 direct = yang_dnode_get_enum(args->dnode, "./direction");
288
289 offset = nb_running_unset_entry(args->dnode);
290 if (offset->direct[direct].alist_name) {
291 free(offset->direct[direct].alist_name);
292 offset->direct[direct].alist_name = NULL;
293 }
294 if (offset->direct[RIPNG_OFFSET_LIST_IN].alist_name == NULL
295 && offset->direct[RIPNG_OFFSET_LIST_OUT].alist_name == NULL)
296 ripng_offset_list_del(offset);
297
298 return NB_OK;
299 }
300
301 /*
302 * XPath: /frr-ripngd:ripngd/instance/offset-list/access-list
303 */
304 int ripngd_instance_offset_list_access_list_modify(
305 struct nb_cb_modify_args *args)
306 {
307 int direct;
308 struct ripng_offset_list *offset;
309 const char *alist_name;
310
311 if (args->event != NB_EV_APPLY)
312 return NB_OK;
313
314 direct = yang_dnode_get_enum(args->dnode, "../direction");
315 alist_name = yang_dnode_get_string(args->dnode, NULL);
316
317 offset = nb_running_get_entry(args->dnode, NULL, true);
318 if (offset->direct[direct].alist_name)
319 free(offset->direct[direct].alist_name);
320 offset->direct[direct].alist_name = strdup(alist_name);
321
322 return NB_OK;
323 }
324
325 /*
326 * XPath: /frr-ripngd:ripngd/instance/offset-list/metric
327 */
328 int ripngd_instance_offset_list_metric_modify(struct nb_cb_modify_args *args)
329 {
330 int direct;
331 uint8_t metric;
332 struct ripng_offset_list *offset;
333
334 if (args->event != NB_EV_APPLY)
335 return NB_OK;
336
337 direct = yang_dnode_get_enum(args->dnode, "../direction");
338 metric = yang_dnode_get_uint8(args->dnode, NULL);
339
340 offset = nb_running_get_entry(args->dnode, NULL, true);
341 offset->direct[direct].metric = metric;
342
343 return NB_OK;
344 }
345
346 /*
347 * XPath: /frr-ripngd:ripngd/instance/passive-interface
348 */
349 int ripngd_instance_passive_interface_create(struct nb_cb_create_args *args)
350 {
351 struct ripng *ripng;
352 const char *ifname;
353
354 if (args->event != NB_EV_APPLY)
355 return NB_OK;
356
357 ripng = nb_running_get_entry(args->dnode, NULL, true);
358 ifname = yang_dnode_get_string(args->dnode, NULL);
359
360 return ripng_passive_interface_set(ripng, ifname);
361 }
362
363 int ripngd_instance_passive_interface_destroy(struct nb_cb_destroy_args *args)
364 {
365 struct ripng *ripng;
366 const char *ifname;
367
368 if (args->event != NB_EV_APPLY)
369 return NB_OK;
370
371 ripng = nb_running_get_entry(args->dnode, NULL, true);
372 ifname = yang_dnode_get_string(args->dnode, NULL);
373
374 return ripng_passive_interface_unset(ripng, ifname);
375 }
376
377 /*
378 * XPath: /frr-ripngd:ripngd/instance/redistribute
379 */
380 int ripngd_instance_redistribute_create(struct nb_cb_create_args *args)
381 {
382 struct ripng *ripng;
383 int type;
384
385 if (args->event != NB_EV_APPLY)
386 return NB_OK;
387
388 ripng = nb_running_get_entry(args->dnode, NULL, true);
389 type = yang_dnode_get_enum(args->dnode, "./protocol");
390
391 ripng->redist[type].enabled = true;
392
393 return NB_OK;
394 }
395
396 int ripngd_instance_redistribute_destroy(struct nb_cb_destroy_args *args)
397 {
398 struct ripng *ripng;
399 int type;
400
401 if (args->event != NB_EV_APPLY)
402 return NB_OK;
403
404 ripng = nb_running_get_entry(args->dnode, NULL, true);
405 type = yang_dnode_get_enum(args->dnode, "./protocol");
406
407 ripng->redist[type].enabled = false;
408 if (ripng->redist[type].route_map.name) {
409 free(ripng->redist[type].route_map.name);
410 ripng->redist[type].route_map.name = NULL;
411 ripng->redist[type].route_map.map = NULL;
412 }
413 ripng->redist[type].metric_config = false;
414 ripng->redist[type].metric = 0;
415
416 if (ripng->enabled)
417 ripng_redistribute_conf_delete(ripng, type);
418
419 return NB_OK;
420 }
421
422 void ripngd_instance_redistribute_apply_finish(
423 struct nb_cb_apply_finish_args *args)
424 {
425 struct ripng *ripng;
426 int type;
427
428 ripng = nb_running_get_entry(args->dnode, NULL, true);
429 type = yang_dnode_get_enum(args->dnode, "./protocol");
430
431 if (ripng->enabled)
432 ripng_redistribute_conf_update(ripng, type);
433 }
434
435 /*
436 * XPath: /frr-ripngd:ripngd/instance/redistribute/route-map
437 */
438 int ripngd_instance_redistribute_route_map_modify(
439 struct nb_cb_modify_args *args)
440 {
441 struct ripng *ripng;
442 int type;
443 const char *rmap_name;
444
445 if (args->event != NB_EV_APPLY)
446 return NB_OK;
447
448 ripng = nb_running_get_entry(args->dnode, NULL, true);
449 type = yang_dnode_get_enum(args->dnode, "../protocol");
450 rmap_name = yang_dnode_get_string(args->dnode, NULL);
451
452 if (ripng->redist[type].route_map.name)
453 free(ripng->redist[type].route_map.name);
454 ripng->redist[type].route_map.name = strdup(rmap_name);
455 ripng->redist[type].route_map.map = route_map_lookup_by_name(rmap_name);
456
457 return NB_OK;
458 }
459
460 int ripngd_instance_redistribute_route_map_destroy(
461 struct nb_cb_destroy_args *args)
462 {
463 struct ripng *ripng;
464 int type;
465
466 if (args->event != NB_EV_APPLY)
467 return NB_OK;
468
469 ripng = nb_running_get_entry(args->dnode, NULL, true);
470 type = yang_dnode_get_enum(args->dnode, "../protocol");
471
472 free(ripng->redist[type].route_map.name);
473 ripng->redist[type].route_map.name = NULL;
474 ripng->redist[type].route_map.map = NULL;
475
476 return NB_OK;
477 }
478
479 /*
480 * XPath: /frr-ripngd:ripngd/instance/redistribute/metric
481 */
482 int ripngd_instance_redistribute_metric_modify(struct nb_cb_modify_args *args)
483 {
484 struct ripng *ripng;
485 int type;
486 uint8_t metric;
487
488 if (args->event != NB_EV_APPLY)
489 return NB_OK;
490
491 ripng = nb_running_get_entry(args->dnode, NULL, true);
492 type = yang_dnode_get_enum(args->dnode, "../protocol");
493 metric = yang_dnode_get_uint8(args->dnode, NULL);
494
495 ripng->redist[type].metric_config = true;
496 ripng->redist[type].metric = metric;
497
498 return NB_OK;
499 }
500
501 int ripngd_instance_redistribute_metric_destroy(struct nb_cb_destroy_args *args)
502 {
503 struct ripng *ripng;
504 int type;
505
506 if (args->event != NB_EV_APPLY)
507 return NB_OK;
508
509 ripng = nb_running_get_entry(args->dnode, NULL, true);
510 type = yang_dnode_get_enum(args->dnode, "../protocol");
511
512 ripng->redist[type].metric_config = false;
513 ripng->redist[type].metric = 0;
514
515 return NB_OK;
516 }
517
518 /*
519 * XPath: /frr-ripngd:ripngd/instance/static-route
520 */
521 int ripngd_instance_static_route_create(struct nb_cb_create_args *args)
522 {
523 struct ripng *ripng;
524 struct prefix_ipv6 p;
525
526 if (args->event != NB_EV_APPLY)
527 return NB_OK;
528
529 ripng = nb_running_get_entry(args->dnode, NULL, true);
530 yang_dnode_get_ipv6p(&p, args->dnode, NULL);
531 apply_mask_ipv6(&p);
532
533 ripng_redistribute_add(ripng, ZEBRA_ROUTE_RIPNG, RIPNG_ROUTE_STATIC, &p,
534 0, NULL, 0);
535
536 return NB_OK;
537 }
538
539 int ripngd_instance_static_route_destroy(struct nb_cb_destroy_args *args)
540 {
541 struct ripng *ripng;
542 struct prefix_ipv6 p;
543
544 if (args->event != NB_EV_APPLY)
545 return NB_OK;
546
547 ripng = nb_running_get_entry(args->dnode, NULL, true);
548 yang_dnode_get_ipv6p(&p, args->dnode, NULL);
549 apply_mask_ipv6(&p);
550
551 ripng_redistribute_delete(ripng, ZEBRA_ROUTE_RIPNG, RIPNG_ROUTE_STATIC,
552 &p, 0);
553
554 return NB_OK;
555 }
556
557 /*
558 * XPath: /frr-ripngd:ripngd/instance/aggregate-address
559 */
560 int ripngd_instance_aggregate_address_create(struct nb_cb_create_args *args)
561 {
562 struct ripng *ripng;
563 struct prefix_ipv6 p;
564
565 if (args->event != NB_EV_APPLY)
566 return NB_OK;
567
568 ripng = nb_running_get_entry(args->dnode, NULL, true);
569 yang_dnode_get_ipv6p(&p, args->dnode, NULL);
570 apply_mask_ipv6(&p);
571
572 ripng_aggregate_add(ripng, (struct prefix *)&p);
573
574 return NB_OK;
575 }
576
577 int ripngd_instance_aggregate_address_destroy(struct nb_cb_destroy_args *args)
578 {
579 struct ripng *ripng;
580 struct prefix_ipv6 p;
581
582 if (args->event != NB_EV_APPLY)
583 return NB_OK;
584
585 ripng = nb_running_get_entry(args->dnode, NULL, true);
586 yang_dnode_get_ipv6p(&p, args->dnode, NULL);
587 apply_mask_ipv6(&p);
588
589 ripng_aggregate_delete(ripng, (struct prefix *)&p);
590
591 return NB_OK;
592 }
593
594 /*
595 * XPath: /frr-ripngd:ripngd/instance/timers
596 */
597 void ripngd_instance_timers_apply_finish(struct nb_cb_apply_finish_args *args)
598 {
599 struct ripng *ripng;
600
601 ripng = nb_running_get_entry(args->dnode, NULL, true);
602
603 /* Reset update timer thread. */
604 ripng_event(ripng, RIPNG_UPDATE_EVENT, 0);
605 }
606
607 /*
608 * XPath: /frr-ripngd:ripngd/instance/timers/flush-interval
609 */
610 int ripngd_instance_timers_flush_interval_modify(struct nb_cb_modify_args *args)
611 {
612 struct ripng *ripng;
613
614 if (args->event != NB_EV_APPLY)
615 return NB_OK;
616
617 ripng = nb_running_get_entry(args->dnode, NULL, true);
618 ripng->garbage_time = yang_dnode_get_uint16(args->dnode, NULL);
619
620 return NB_OK;
621 }
622
623 /*
624 * XPath: /frr-ripngd:ripngd/instance/timers/holddown-interval
625 */
626 int ripngd_instance_timers_holddown_interval_modify(
627 struct nb_cb_modify_args *args)
628 {
629 struct ripng *ripng;
630
631 if (args->event != NB_EV_APPLY)
632 return NB_OK;
633
634 ripng = nb_running_get_entry(args->dnode, NULL, true);
635 ripng->timeout_time = yang_dnode_get_uint16(args->dnode, NULL);
636
637 return NB_OK;
638 }
639
640 /*
641 * XPath: /frr-ripngd:ripngd/instance/timers/update-interval
642 */
643 int ripngd_instance_timers_update_interval_modify(
644 struct nb_cb_modify_args *args)
645 {
646 struct ripng *ripng;
647
648 if (args->event != NB_EV_APPLY)
649 return NB_OK;
650
651 ripng = nb_running_get_entry(args->dnode, NULL, true);
652 ripng->update_time = yang_dnode_get_uint16(args->dnode, NULL);
653
654 return NB_OK;
655 }
656
657 /*
658 * XPath: /frr-interface:lib/interface/frr-ripngd:ripng/split-horizon
659 */
660 int lib_interface_ripng_split_horizon_modify(struct nb_cb_modify_args *args)
661 {
662 struct interface *ifp;
663 struct ripng_interface *ri;
664
665 if (args->event != NB_EV_APPLY)
666 return NB_OK;
667
668 ifp = nb_running_get_entry(args->dnode, NULL, true);
669 ri = ifp->info;
670 ri->split_horizon = yang_dnode_get_enum(args->dnode, NULL);
671
672 return NB_OK;
673 }