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