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