]> git.proxmox.com Git - mirror_frr.git/blob - ripngd/ripng_northbound.c
ripngd: retrofit the 'offset-list' command to the new northbound model
[mirror_frr.git] / ripngd / ripng_northbound.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 "northbound.h"
31 #include "libfrr.h"
32
33 #include "ripngd/ripngd.h"
34 #include "ripngd/ripng_cli.h"
35
36 /*
37 * XPath: /frr-ripngd:ripngd/instance
38 */
39 static int ripngd_instance_create(enum nb_event event,
40 const struct lyd_node *dnode,
41 union nb_resource *resource)
42 {
43 int socket;
44
45 switch (event) {
46 case NB_EV_VALIDATE:
47 break;
48 case NB_EV_PREPARE:
49 socket = ripng_make_socket();
50 if (socket < 0)
51 return NB_ERR_RESOURCE;
52 resource->fd = socket;
53 break;
54 case NB_EV_ABORT:
55 socket = resource->fd;
56 close(socket);
57 break;
58 case NB_EV_APPLY:
59 socket = resource->fd;
60 ripng_create(socket);
61 break;
62 }
63
64 return NB_OK;
65 }
66
67 static int ripngd_instance_delete(enum nb_event event,
68 const struct lyd_node *dnode)
69 {
70 if (event != NB_EV_APPLY)
71 return NB_OK;
72
73 ripng_clean();
74
75 return NB_OK;
76 }
77
78 /*
79 * XPath: /frr-ripngd:ripngd/instance/allow-ecmp
80 */
81 static int ripngd_instance_allow_ecmp_modify(enum nb_event event,
82 const struct lyd_node *dnode,
83 union nb_resource *resource)
84 {
85 if (event != NB_EV_APPLY)
86 return NB_OK;
87
88 ripng->ecmp = yang_dnode_get_bool(dnode, NULL);
89 if (!ripng->ecmp)
90 ripng_ecmp_disable();
91
92 return NB_OK;
93 }
94
95 /*
96 * XPath: /frr-ripngd:ripngd/instance/default-information-originate
97 */
98 static int ripngd_instance_default_information_originate_modify(
99 enum nb_event event, const struct lyd_node *dnode,
100 union nb_resource *resource)
101 {
102 bool default_information;
103 struct prefix_ipv6 p;
104
105 if (event != NB_EV_APPLY)
106 return NB_OK;
107
108 default_information = yang_dnode_get_bool(dnode, NULL);
109 str2prefix_ipv6("::/0", &p);
110 if (default_information) {
111 ripng_redistribute_add(ZEBRA_ROUTE_RIPNG, RIPNG_ROUTE_DEFAULT,
112 &p, 0, NULL, 0);
113 } else {
114 ripng_redistribute_delete(ZEBRA_ROUTE_RIPNG,
115 RIPNG_ROUTE_DEFAULT, &p, 0);
116 }
117
118 return NB_OK;
119 }
120
121 /*
122 * XPath: /frr-ripngd:ripngd/instance/default-metric
123 */
124 static int ripngd_instance_default_metric_modify(enum nb_event event,
125 const struct lyd_node *dnode,
126 union nb_resource *resource)
127 {
128 if (event != NB_EV_APPLY)
129 return NB_OK;
130
131 ripng->default_metric = yang_dnode_get_uint8(dnode, NULL);
132
133 return NB_OK;
134 }
135
136 /*
137 * XPath: /frr-ripngd:ripngd/instance/network
138 */
139 static int ripngd_instance_network_create(enum nb_event event,
140 const struct lyd_node *dnode,
141 union nb_resource *resource)
142 {
143 struct prefix p;
144
145 if (event != NB_EV_APPLY)
146 return NB_OK;
147
148 yang_dnode_get_ipv6p(&p, dnode, NULL);
149 apply_mask_ipv6((struct prefix_ipv6 *)&p);
150
151 return ripng_enable_network_add(&p);
152 }
153
154 static int ripngd_instance_network_delete(enum nb_event event,
155 const struct lyd_node *dnode)
156 {
157 struct prefix p;
158
159 if (event != NB_EV_APPLY)
160 return NB_OK;
161
162 yang_dnode_get_ipv6p(&p, dnode, NULL);
163 apply_mask_ipv6((struct prefix_ipv6 *)&p);
164
165 return ripng_enable_network_delete(&p);
166 }
167
168 /*
169 * XPath: /frr-ripngd:ripngd/instance/interface
170 */
171 static int ripngd_instance_interface_create(enum nb_event event,
172 const struct lyd_node *dnode,
173 union nb_resource *resource)
174 {
175 const char *ifname;
176
177 if (event != NB_EV_APPLY)
178 return NB_OK;
179
180 ifname = yang_dnode_get_string(dnode, NULL);
181
182 return ripng_enable_if_add(ifname);
183 }
184
185 static int ripngd_instance_interface_delete(enum nb_event event,
186 const struct lyd_node *dnode)
187 {
188 const char *ifname;
189
190 if (event != NB_EV_APPLY)
191 return NB_OK;
192
193 ifname = yang_dnode_get_string(dnode, NULL);
194
195 return ripng_enable_if_delete(ifname);
196 }
197
198 /*
199 * XPath: /frr-ripngd:ripngd/instance/offset-list
200 */
201 static int ripngd_instance_offset_list_create(enum nb_event event,
202 const struct lyd_node *dnode,
203 union nb_resource *resource)
204 {
205 const char *ifname;
206 struct ripng_offset_list *offset;
207
208 if (event != NB_EV_APPLY)
209 return NB_OK;
210
211 ifname = yang_dnode_get_string(dnode, "./interface");
212
213 offset = ripng_offset_list_new(ifname);
214 yang_dnode_set_entry(dnode, offset);
215
216 return NB_OK;
217 }
218
219 static int ripngd_instance_offset_list_delete(enum nb_event event,
220 const struct lyd_node *dnode)
221 {
222 int direct;
223 struct ripng_offset_list *offset;
224
225 if (event != NB_EV_APPLY)
226 return NB_OK;
227
228 direct = yang_dnode_get_enum(dnode, "./direction");
229
230 offset = yang_dnode_get_entry(dnode, true);
231 if (offset->direct[direct].alist_name) {
232 free(offset->direct[direct].alist_name);
233 offset->direct[direct].alist_name = NULL;
234 }
235 if (offset->direct[RIPNG_OFFSET_LIST_IN].alist_name == NULL
236 && offset->direct[RIPNG_OFFSET_LIST_OUT].alist_name == NULL)
237 ripng_offset_list_del(offset);
238
239 return NB_OK;
240 }
241
242 /*
243 * XPath: /frr-ripngd:ripngd/instance/offset-list/access-list
244 */
245 static int
246 ripngd_instance_offset_list_access_list_modify(enum nb_event event,
247 const struct lyd_node *dnode,
248 union nb_resource *resource)
249 {
250 int direct;
251 struct ripng_offset_list *offset;
252 const char *alist_name;
253
254 if (event != NB_EV_APPLY)
255 return NB_OK;
256
257 direct = yang_dnode_get_enum(dnode, "../direction");
258 alist_name = yang_dnode_get_string(dnode, NULL);
259
260 offset = yang_dnode_get_entry(dnode, true);
261 if (offset->direct[direct].alist_name)
262 free(offset->direct[direct].alist_name);
263 offset->direct[direct].alist_name = strdup(alist_name);
264
265 return NB_OK;
266 }
267
268 /*
269 * XPath: /frr-ripngd:ripngd/instance/offset-list/metric
270 */
271 static int
272 ripngd_instance_offset_list_metric_modify(enum nb_event event,
273 const struct lyd_node *dnode,
274 union nb_resource *resource)
275 {
276 int direct;
277 uint8_t metric;
278 struct ripng_offset_list *offset;
279
280 if (event != NB_EV_APPLY)
281 return NB_OK;
282
283 direct = yang_dnode_get_enum(dnode, "../direction");
284 metric = yang_dnode_get_uint8(dnode, NULL);
285
286 offset = yang_dnode_get_entry(dnode, true);
287 offset->direct[direct].metric = metric;
288
289 return NB_OK;
290 }
291
292 /*
293 * XPath: /frr-ripngd:ripngd/instance/passive-interface
294 */
295 static int
296 ripngd_instance_passive_interface_create(enum nb_event event,
297 const struct lyd_node *dnode,
298 union nb_resource *resource)
299 {
300 /* TODO: implement me. */
301 return NB_OK;
302 }
303
304 static int
305 ripngd_instance_passive_interface_delete(enum nb_event event,
306 const struct lyd_node *dnode)
307 {
308 /* TODO: implement me. */
309 return NB_OK;
310 }
311
312 /*
313 * XPath: /frr-ripngd:ripngd/instance/redistribute
314 */
315 static int ripngd_instance_redistribute_create(enum nb_event event,
316 const struct lyd_node *dnode,
317 union nb_resource *resource)
318 {
319 /* TODO: implement me. */
320 return NB_OK;
321 }
322
323 static int ripngd_instance_redistribute_delete(enum nb_event event,
324 const struct lyd_node *dnode)
325 {
326 /* TODO: implement me. */
327 return NB_OK;
328 }
329
330 /*
331 * XPath: /frr-ripngd:ripngd/instance/redistribute/route-map
332 */
333 static int
334 ripngd_instance_redistribute_route_map_modify(enum nb_event event,
335 const struct lyd_node *dnode,
336 union nb_resource *resource)
337 {
338 /* TODO: implement me. */
339 return NB_OK;
340 }
341
342 static int
343 ripngd_instance_redistribute_route_map_delete(enum nb_event event,
344 const struct lyd_node *dnode)
345 {
346 /* TODO: implement me. */
347 return NB_OK;
348 }
349
350 /*
351 * XPath: /frr-ripngd:ripngd/instance/redistribute/metric
352 */
353 static int
354 ripngd_instance_redistribute_metric_modify(enum nb_event event,
355 const struct lyd_node *dnode,
356 union nb_resource *resource)
357 {
358 /* TODO: implement me. */
359 return NB_OK;
360 }
361
362 static int
363 ripngd_instance_redistribute_metric_delete(enum nb_event event,
364 const struct lyd_node *dnode)
365 {
366 /* TODO: implement me. */
367 return NB_OK;
368 }
369
370 /*
371 * XPath: /frr-ripngd:ripngd/instance/static-route
372 */
373 static int ripngd_instance_static_route_create(enum nb_event event,
374 const struct lyd_node *dnode,
375 union nb_resource *resource)
376 {
377 /* TODO: implement me. */
378 return NB_OK;
379 }
380
381 static int ripngd_instance_static_route_delete(enum nb_event event,
382 const struct lyd_node *dnode)
383 {
384 /* TODO: implement me. */
385 return NB_OK;
386 }
387
388 /*
389 * XPath: /frr-ripngd:ripngd/instance/aggregate-address
390 */
391 static int
392 ripngd_instance_aggregate_address_create(enum nb_event event,
393 const struct lyd_node *dnode,
394 union nb_resource *resource)
395 {
396 /* TODO: implement me. */
397 return NB_OK;
398 }
399
400 static int
401 ripngd_instance_aggregate_address_delete(enum nb_event event,
402 const struct lyd_node *dnode)
403 {
404 /* TODO: implement me. */
405 return NB_OK;
406 }
407
408 /*
409 * XPath: /frr-ripngd:ripngd/instance/timers/flush-interval
410 */
411 static int
412 ripngd_instance_timers_flush_interval_modify(enum nb_event event,
413 const struct lyd_node *dnode,
414 union nb_resource *resource)
415 {
416 /* TODO: implement me. */
417 return NB_OK;
418 }
419
420 /*
421 * XPath: /frr-ripngd:ripngd/instance/timers/holddown-interval
422 */
423 static int
424 ripngd_instance_timers_holddown_interval_modify(enum nb_event event,
425 const struct lyd_node *dnode,
426 union nb_resource *resource)
427 {
428 /* TODO: implement me. */
429 return NB_OK;
430 }
431
432 /*
433 * XPath: /frr-ripngd:ripngd/instance/timers/update-interval
434 */
435 static int
436 ripngd_instance_timers_update_interval_modify(enum nb_event event,
437 const struct lyd_node *dnode,
438 union nb_resource *resource)
439 {
440 /* TODO: implement me. */
441 return NB_OK;
442 }
443
444 /*
445 * XPath: /frr-ripngd:ripngd/state/neighbors/neighbor
446 */
447 static const void *
448 ripngd_state_neighbors_neighbor_get_next(const void *parent_list_entry,
449 const void *list_entry)
450 {
451 /* TODO: implement me. */
452 return NULL;
453 }
454
455 static int ripngd_state_neighbors_neighbor_get_keys(const void *list_entry,
456 struct yang_list_keys *keys)
457 {
458 /* TODO: implement me. */
459 return NB_OK;
460 }
461
462 static const void *
463 ripngd_state_neighbors_neighbor_lookup_entry(const void *parent_list_entry,
464 const struct yang_list_keys *keys)
465 {
466 /* TODO: implement me. */
467 return NULL;
468 }
469
470 /*
471 * XPath: /frr-ripngd:ripngd/state/neighbors/neighbor/address
472 */
473 static struct yang_data *
474 ripngd_state_neighbors_neighbor_address_get_elem(const char *xpath,
475 const void *list_entry)
476 {
477 /* TODO: implement me. */
478 return NULL;
479 }
480
481 /*
482 * XPath: /frr-ripngd:ripngd/state/neighbors/neighbor/last-update
483 */
484 static struct yang_data *
485 ripngd_state_neighbors_neighbor_last_update_get_elem(const char *xpath,
486 const void *list_entry)
487 {
488 /* TODO: implement me. */
489 return NULL;
490 }
491
492 /*
493 * XPath: /frr-ripngd:ripngd/state/neighbors/neighbor/bad-packets-rcvd
494 */
495 static struct yang_data *
496 ripngd_state_neighbors_neighbor_bad_packets_rcvd_get_elem(
497 const char *xpath, const void *list_entry)
498 {
499 /* TODO: implement me. */
500 return NULL;
501 }
502
503 /*
504 * XPath: /frr-ripngd:ripngd/state/neighbors/neighbor/bad-routes-rcvd
505 */
506 static struct yang_data *
507 ripngd_state_neighbors_neighbor_bad_routes_rcvd_get_elem(const char *xpath,
508 const void *list_entry)
509 {
510 /* TODO: implement me. */
511 return NULL;
512 }
513
514 /*
515 * XPath: /frr-ripngd:ripngd/state/routes/route
516 */
517 static const void *
518 ripngd_state_routes_route_get_next(const void *parent_list_entry,
519 const void *list_entry)
520 {
521 /* TODO: implement me. */
522 return NULL;
523 }
524
525 static int ripngd_state_routes_route_get_keys(const void *list_entry,
526 struct yang_list_keys *keys)
527 {
528 /* TODO: implement me. */
529 return NB_OK;
530 }
531
532 static const void *
533 ripngd_state_routes_route_lookup_entry(const void *parent_list_entry,
534 const struct yang_list_keys *keys)
535 {
536 /* TODO: implement me. */
537 return NULL;
538 }
539
540 /*
541 * XPath: /frr-ripngd:ripngd/state/routes/route/prefix
542 */
543 static struct yang_data *
544 ripngd_state_routes_route_prefix_get_elem(const char *xpath,
545 const void *list_entry)
546 {
547 /* TODO: implement me. */
548 return NULL;
549 }
550
551 /*
552 * XPath: /frr-ripngd:ripngd/state/routes/route/next-hop
553 */
554 static struct yang_data *
555 ripngd_state_routes_route_next_hop_get_elem(const char *xpath,
556 const void *list_entry)
557 {
558 /* TODO: implement me. */
559 return NULL;
560 }
561
562 /*
563 * XPath: /frr-ripngd:ripngd/state/routes/route/interface
564 */
565 static struct yang_data *
566 ripngd_state_routes_route_interface_get_elem(const char *xpath,
567 const void *list_entry)
568 {
569 /* TODO: implement me. */
570 return NULL;
571 }
572
573 /*
574 * XPath: /frr-ripngd:ripngd/state/routes/route/metric
575 */
576 static struct yang_data *
577 ripngd_state_routes_route_metric_get_elem(const char *xpath,
578 const void *list_entry)
579 {
580 /* TODO: implement me. */
581 return NULL;
582 }
583
584 /*
585 * XPath: /frr-ripngd:clear-ripng-route
586 */
587 static int clear_ripng_route_rpc(const char *xpath, const struct list *input,
588 struct list *output)
589 {
590 /* TODO: implement me. */
591 return NB_OK;
592 }
593
594 /*
595 * XPath: /frr-interface:lib/interface/frr-ripngd:ripng/split-horizon
596 */
597 static int
598 lib_interface_ripng_split_horizon_modify(enum nb_event event,
599 const struct lyd_node *dnode,
600 union nb_resource *resource)
601 {
602 /* TODO: implement me. */
603 return NB_OK;
604 }
605
606 /* clang-format off */
607 const struct frr_yang_module_info frr_ripngd_info = {
608 .name = "frr-ripngd",
609 .nodes = {
610 {
611 .xpath = "/frr-ripngd:ripngd/instance",
612 .cbs.create = ripngd_instance_create,
613 .cbs.delete = ripngd_instance_delete,
614 .cbs.cli_show = cli_show_router_ripng,
615 },
616 {
617 .xpath = "/frr-ripngd:ripngd/instance/allow-ecmp",
618 .cbs.modify = ripngd_instance_allow_ecmp_modify,
619 .cbs.cli_show = cli_show_ripng_allow_ecmp,
620 },
621 {
622 .xpath = "/frr-ripngd:ripngd/instance/default-information-originate",
623 .cbs.modify = ripngd_instance_default_information_originate_modify,
624 .cbs.cli_show = cli_show_ripng_default_information_originate,
625 },
626 {
627 .xpath = "/frr-ripngd:ripngd/instance/default-metric",
628 .cbs.modify = ripngd_instance_default_metric_modify,
629 .cbs.cli_show = cli_show_ripng_default_metric,
630 },
631 {
632 .xpath = "/frr-ripngd:ripngd/instance/network",
633 .cbs.create = ripngd_instance_network_create,
634 .cbs.delete = ripngd_instance_network_delete,
635 .cbs.cli_show = cli_show_ripng_network_prefix,
636 },
637 {
638 .xpath = "/frr-ripngd:ripngd/instance/interface",
639 .cbs.create = ripngd_instance_interface_create,
640 .cbs.delete = ripngd_instance_interface_delete,
641 .cbs.cli_show = cli_show_ripng_network_interface,
642 },
643 {
644 .xpath = "/frr-ripngd:ripngd/instance/offset-list",
645 .cbs.create = ripngd_instance_offset_list_create,
646 .cbs.delete = ripngd_instance_offset_list_delete,
647 .cbs.cli_show = cli_show_ripng_offset_list,
648 },
649 {
650 .xpath = "/frr-ripngd:ripngd/instance/offset-list/access-list",
651 .cbs.modify = ripngd_instance_offset_list_access_list_modify,
652 },
653 {
654 .xpath = "/frr-ripngd:ripngd/instance/offset-list/metric",
655 .cbs.modify = ripngd_instance_offset_list_metric_modify,
656 },
657 {
658 .xpath = "/frr-ripngd:ripngd/instance/passive-interface",
659 .cbs.create = ripngd_instance_passive_interface_create,
660 .cbs.delete = ripngd_instance_passive_interface_delete,
661 },
662 {
663 .xpath = "/frr-ripngd:ripngd/instance/redistribute",
664 .cbs.create = ripngd_instance_redistribute_create,
665 .cbs.delete = ripngd_instance_redistribute_delete,
666 },
667 {
668 .xpath = "/frr-ripngd:ripngd/instance/redistribute/route-map",
669 .cbs.modify = ripngd_instance_redistribute_route_map_modify,
670 .cbs.delete = ripngd_instance_redistribute_route_map_delete,
671 },
672 {
673 .xpath = "/frr-ripngd:ripngd/instance/redistribute/metric",
674 .cbs.modify = ripngd_instance_redistribute_metric_modify,
675 .cbs.delete = ripngd_instance_redistribute_metric_delete,
676 },
677 {
678 .xpath = "/frr-ripngd:ripngd/instance/static-route",
679 .cbs.create = ripngd_instance_static_route_create,
680 .cbs.delete = ripngd_instance_static_route_delete,
681 },
682 {
683 .xpath = "/frr-ripngd:ripngd/instance/aggregate-address",
684 .cbs.create = ripngd_instance_aggregate_address_create,
685 .cbs.delete = ripngd_instance_aggregate_address_delete,
686 },
687 {
688 .xpath = "/frr-ripngd:ripngd/instance/timers/flush-interval",
689 .cbs.modify = ripngd_instance_timers_flush_interval_modify,
690 },
691 {
692 .xpath = "/frr-ripngd:ripngd/instance/timers/holddown-interval",
693 .cbs.modify = ripngd_instance_timers_holddown_interval_modify,
694 },
695 {
696 .xpath = "/frr-ripngd:ripngd/instance/timers/update-interval",
697 .cbs.modify = ripngd_instance_timers_update_interval_modify,
698 },
699 {
700 .xpath = "/frr-ripngd:ripngd/state/neighbors/neighbor",
701 .cbs.get_next = ripngd_state_neighbors_neighbor_get_next,
702 .cbs.get_keys = ripngd_state_neighbors_neighbor_get_keys,
703 .cbs.lookup_entry = ripngd_state_neighbors_neighbor_lookup_entry,
704 },
705 {
706 .xpath = "/frr-ripngd:ripngd/state/neighbors/neighbor/address",
707 .cbs.get_elem = ripngd_state_neighbors_neighbor_address_get_elem,
708 },
709 {
710 .xpath = "/frr-ripngd:ripngd/state/neighbors/neighbor/last-update",
711 .cbs.get_elem = ripngd_state_neighbors_neighbor_last_update_get_elem,
712 },
713 {
714 .xpath = "/frr-ripngd:ripngd/state/neighbors/neighbor/bad-packets-rcvd",
715 .cbs.get_elem = ripngd_state_neighbors_neighbor_bad_packets_rcvd_get_elem,
716 },
717 {
718 .xpath = "/frr-ripngd:ripngd/state/neighbors/neighbor/bad-routes-rcvd",
719 .cbs.get_elem = ripngd_state_neighbors_neighbor_bad_routes_rcvd_get_elem,
720 },
721 {
722 .xpath = "/frr-ripngd:ripngd/state/routes/route",
723 .cbs.get_next = ripngd_state_routes_route_get_next,
724 .cbs.get_keys = ripngd_state_routes_route_get_keys,
725 .cbs.lookup_entry = ripngd_state_routes_route_lookup_entry,
726 },
727 {
728 .xpath = "/frr-ripngd:ripngd/state/routes/route/prefix",
729 .cbs.get_elem = ripngd_state_routes_route_prefix_get_elem,
730 },
731 {
732 .xpath = "/frr-ripngd:ripngd/state/routes/route/next-hop",
733 .cbs.get_elem = ripngd_state_routes_route_next_hop_get_elem,
734 },
735 {
736 .xpath = "/frr-ripngd:ripngd/state/routes/route/interface",
737 .cbs.get_elem = ripngd_state_routes_route_interface_get_elem,
738 },
739 {
740 .xpath = "/frr-ripngd:ripngd/state/routes/route/metric",
741 .cbs.get_elem = ripngd_state_routes_route_metric_get_elem,
742 },
743 {
744 .xpath = "/frr-ripngd:clear-ripng-route",
745 .cbs.rpc = clear_ripng_route_rpc,
746 },
747 {
748 .xpath = "/frr-interface:lib/interface/frr-ripngd:ripng/split-horizon",
749 .cbs.modify = lib_interface_ripng_split_horizon_modify,
750 },
751 {
752 .xpath = NULL,
753 },
754 }
755 };