]>
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 | 131 | ripng = nb_running_get_entry(args->dnode, NULL, true); |
6c5ffa88 DA |
132 | ripng->ecmp = |
133 | MIN(yang_dnode_get_uint8(args->dnode, NULL), zebra_ecmp_count); | |
57aedde6 | 134 | if (!ripng->ecmp) { |
ca473936 | 135 | ripng_ecmp_disable(ripng); |
57aedde6 DA |
136 | return NB_OK; |
137 | } | |
138 | ||
139 | ripng_ecmp_change(ripng); | |
ca473936 RW |
140 | |
141 | return NB_OK; | |
142 | } | |
143 | ||
144 | /* | |
145 | * XPath: /frr-ripngd:ripngd/instance/default-information-originate | |
146 | */ | |
147 | int ripngd_instance_default_information_originate_modify( | |
60ee8be1 | 148 | struct nb_cb_modify_args *args) |
ca473936 RW |
149 | { |
150 | struct ripng *ripng; | |
151 | bool default_information; | |
152 | struct prefix_ipv6 p; | |
153 | ||
60ee8be1 | 154 | if (args->event != NB_EV_APPLY) |
ca473936 RW |
155 | return NB_OK; |
156 | ||
60ee8be1 RW |
157 | ripng = nb_running_get_entry(args->dnode, NULL, true); |
158 | default_information = yang_dnode_get_bool(args->dnode, NULL); | |
ca473936 | 159 | |
147bb9ed | 160 | (void)str2prefix_ipv6("::/0", &p); |
ca473936 RW |
161 | if (default_information) { |
162 | ripng_redistribute_add(ripng, ZEBRA_ROUTE_RIPNG, | |
163 | RIPNG_ROUTE_DEFAULT, &p, 0, NULL, 0); | |
164 | } else { | |
165 | ripng_redistribute_delete(ripng, ZEBRA_ROUTE_RIPNG, | |
166 | RIPNG_ROUTE_DEFAULT, &p, 0); | |
167 | } | |
168 | ||
169 | return NB_OK; | |
170 | } | |
171 | ||
172 | /* | |
173 | * XPath: /frr-ripngd:ripngd/instance/default-metric | |
174 | */ | |
60ee8be1 | 175 | int ripngd_instance_default_metric_modify(struct nb_cb_modify_args *args) |
ca473936 RW |
176 | { |
177 | struct ripng *ripng; | |
178 | ||
60ee8be1 | 179 | if (args->event != NB_EV_APPLY) |
ca473936 RW |
180 | return NB_OK; |
181 | ||
60ee8be1 RW |
182 | ripng = nb_running_get_entry(args->dnode, NULL, true); |
183 | ripng->default_metric = yang_dnode_get_uint8(args->dnode, NULL); | |
ca473936 RW |
184 | |
185 | return NB_OK; | |
186 | } | |
187 | ||
188 | /* | |
189 | * XPath: /frr-ripngd:ripngd/instance/network | |
190 | */ | |
60ee8be1 | 191 | int ripngd_instance_network_create(struct nb_cb_create_args *args) |
ca473936 RW |
192 | { |
193 | struct ripng *ripng; | |
194 | struct prefix p; | |
195 | ||
60ee8be1 | 196 | if (args->event != NB_EV_APPLY) |
ca473936 RW |
197 | return NB_OK; |
198 | ||
60ee8be1 RW |
199 | ripng = nb_running_get_entry(args->dnode, NULL, true); |
200 | yang_dnode_get_ipv6p(&p, args->dnode, NULL); | |
ca473936 RW |
201 | apply_mask_ipv6((struct prefix_ipv6 *)&p); |
202 | ||
203 | return ripng_enable_network_add(ripng, &p); | |
204 | } | |
205 | ||
60ee8be1 | 206 | int ripngd_instance_network_destroy(struct nb_cb_destroy_args *args) |
ca473936 RW |
207 | { |
208 | struct ripng *ripng; | |
209 | struct prefix p; | |
210 | ||
60ee8be1 | 211 | if (args->event != NB_EV_APPLY) |
ca473936 RW |
212 | return NB_OK; |
213 | ||
60ee8be1 RW |
214 | ripng = nb_running_get_entry(args->dnode, NULL, true); |
215 | yang_dnode_get_ipv6p(&p, args->dnode, NULL); | |
ca473936 RW |
216 | apply_mask_ipv6((struct prefix_ipv6 *)&p); |
217 | ||
218 | return ripng_enable_network_delete(ripng, &p); | |
219 | } | |
220 | ||
221 | /* | |
222 | * XPath: /frr-ripngd:ripngd/instance/interface | |
223 | */ | |
60ee8be1 | 224 | int ripngd_instance_interface_create(struct nb_cb_create_args *args) |
ca473936 RW |
225 | { |
226 | struct ripng *ripng; | |
227 | const char *ifname; | |
228 | ||
60ee8be1 | 229 | if (args->event != NB_EV_APPLY) |
ca473936 RW |
230 | return NB_OK; |
231 | ||
60ee8be1 RW |
232 | ripng = nb_running_get_entry(args->dnode, NULL, true); |
233 | ifname = yang_dnode_get_string(args->dnode, NULL); | |
ca473936 RW |
234 | |
235 | return ripng_enable_if_add(ripng, ifname); | |
236 | } | |
237 | ||
60ee8be1 | 238 | int ripngd_instance_interface_destroy(struct nb_cb_destroy_args *args) |
ca473936 RW |
239 | { |
240 | struct ripng *ripng; | |
241 | const char *ifname; | |
242 | ||
60ee8be1 | 243 | if (args->event != NB_EV_APPLY) |
ca473936 RW |
244 | return NB_OK; |
245 | ||
60ee8be1 RW |
246 | ripng = nb_running_get_entry(args->dnode, NULL, true); |
247 | ifname = yang_dnode_get_string(args->dnode, NULL); | |
ca473936 RW |
248 | |
249 | return ripng_enable_if_delete(ripng, ifname); | |
250 | } | |
251 | ||
252 | /* | |
253 | * XPath: /frr-ripngd:ripngd/instance/offset-list | |
254 | */ | |
60ee8be1 | 255 | int ripngd_instance_offset_list_create(struct nb_cb_create_args *args) |
ca473936 RW |
256 | { |
257 | struct ripng *ripng; | |
258 | const char *ifname; | |
259 | struct ripng_offset_list *offset; | |
260 | ||
60ee8be1 | 261 | if (args->event != NB_EV_APPLY) |
ca473936 RW |
262 | return NB_OK; |
263 | ||
60ee8be1 RW |
264 | ripng = nb_running_get_entry(args->dnode, NULL, true); |
265 | ifname = yang_dnode_get_string(args->dnode, "./interface"); | |
ca473936 RW |
266 | |
267 | offset = ripng_offset_list_new(ripng, ifname); | |
60ee8be1 | 268 | nb_running_set_entry(args->dnode, offset); |
ca473936 RW |
269 | |
270 | return NB_OK; | |
271 | } | |
272 | ||
60ee8be1 | 273 | int ripngd_instance_offset_list_destroy(struct nb_cb_destroy_args *args) |
ca473936 RW |
274 | { |
275 | int direct; | |
276 | struct ripng_offset_list *offset; | |
277 | ||
60ee8be1 | 278 | if (args->event != NB_EV_APPLY) |
ca473936 RW |
279 | return NB_OK; |
280 | ||
60ee8be1 | 281 | direct = yang_dnode_get_enum(args->dnode, "./direction"); |
ca473936 | 282 | |
60ee8be1 | 283 | offset = nb_running_unset_entry(args->dnode); |
ca473936 RW |
284 | if (offset->direct[direct].alist_name) { |
285 | free(offset->direct[direct].alist_name); | |
286 | offset->direct[direct].alist_name = NULL; | |
287 | } | |
288 | if (offset->direct[RIPNG_OFFSET_LIST_IN].alist_name == NULL | |
289 | && offset->direct[RIPNG_OFFSET_LIST_OUT].alist_name == NULL) | |
290 | ripng_offset_list_del(offset); | |
291 | ||
292 | return NB_OK; | |
293 | } | |
294 | ||
295 | /* | |
296 | * XPath: /frr-ripngd:ripngd/instance/offset-list/access-list | |
297 | */ | |
60ee8be1 RW |
298 | int ripngd_instance_offset_list_access_list_modify( |
299 | struct nb_cb_modify_args *args) | |
ca473936 RW |
300 | { |
301 | int direct; | |
302 | struct ripng_offset_list *offset; | |
303 | const char *alist_name; | |
304 | ||
60ee8be1 | 305 | if (args->event != NB_EV_APPLY) |
ca473936 RW |
306 | return NB_OK; |
307 | ||
60ee8be1 RW |
308 | direct = yang_dnode_get_enum(args->dnode, "../direction"); |
309 | alist_name = yang_dnode_get_string(args->dnode, NULL); | |
ca473936 | 310 | |
60ee8be1 | 311 | offset = nb_running_get_entry(args->dnode, NULL, true); |
ca473936 RW |
312 | if (offset->direct[direct].alist_name) |
313 | free(offset->direct[direct].alist_name); | |
314 | offset->direct[direct].alist_name = strdup(alist_name); | |
315 | ||
316 | return NB_OK; | |
317 | } | |
318 | ||
319 | /* | |
320 | * XPath: /frr-ripngd:ripngd/instance/offset-list/metric | |
321 | */ | |
60ee8be1 | 322 | int ripngd_instance_offset_list_metric_modify(struct nb_cb_modify_args *args) |
ca473936 RW |
323 | { |
324 | int direct; | |
325 | uint8_t metric; | |
326 | struct ripng_offset_list *offset; | |
327 | ||
60ee8be1 | 328 | if (args->event != NB_EV_APPLY) |
ca473936 RW |
329 | return NB_OK; |
330 | ||
60ee8be1 RW |
331 | direct = yang_dnode_get_enum(args->dnode, "../direction"); |
332 | metric = yang_dnode_get_uint8(args->dnode, NULL); | |
ca473936 | 333 | |
60ee8be1 | 334 | offset = nb_running_get_entry(args->dnode, NULL, true); |
ca473936 RW |
335 | offset->direct[direct].metric = metric; |
336 | ||
337 | return NB_OK; | |
338 | } | |
339 | ||
340 | /* | |
341 | * XPath: /frr-ripngd:ripngd/instance/passive-interface | |
342 | */ | |
60ee8be1 | 343 | int ripngd_instance_passive_interface_create(struct nb_cb_create_args *args) |
ca473936 RW |
344 | { |
345 | struct ripng *ripng; | |
346 | const char *ifname; | |
347 | ||
60ee8be1 | 348 | if (args->event != NB_EV_APPLY) |
ca473936 RW |
349 | return NB_OK; |
350 | ||
60ee8be1 RW |
351 | ripng = nb_running_get_entry(args->dnode, NULL, true); |
352 | ifname = yang_dnode_get_string(args->dnode, NULL); | |
ca473936 RW |
353 | |
354 | return ripng_passive_interface_set(ripng, ifname); | |
355 | } | |
356 | ||
60ee8be1 | 357 | int ripngd_instance_passive_interface_destroy(struct nb_cb_destroy_args *args) |
ca473936 RW |
358 | { |
359 | struct ripng *ripng; | |
360 | const char *ifname; | |
361 | ||
60ee8be1 | 362 | if (args->event != NB_EV_APPLY) |
ca473936 RW |
363 | return NB_OK; |
364 | ||
60ee8be1 RW |
365 | ripng = nb_running_get_entry(args->dnode, NULL, true); |
366 | ifname = yang_dnode_get_string(args->dnode, NULL); | |
ca473936 RW |
367 | |
368 | return ripng_passive_interface_unset(ripng, ifname); | |
369 | } | |
370 | ||
371 | /* | |
372 | * XPath: /frr-ripngd:ripngd/instance/redistribute | |
373 | */ | |
60ee8be1 | 374 | int ripngd_instance_redistribute_create(struct nb_cb_create_args *args) |
ca473936 RW |
375 | { |
376 | struct ripng *ripng; | |
377 | int type; | |
378 | ||
60ee8be1 | 379 | if (args->event != NB_EV_APPLY) |
ca473936 RW |
380 | return NB_OK; |
381 | ||
60ee8be1 RW |
382 | ripng = nb_running_get_entry(args->dnode, NULL, true); |
383 | type = yang_dnode_get_enum(args->dnode, "./protocol"); | |
ca473936 RW |
384 | |
385 | ripng->redist[type].enabled = true; | |
386 | ||
387 | return NB_OK; | |
388 | } | |
389 | ||
60ee8be1 | 390 | int ripngd_instance_redistribute_destroy(struct nb_cb_destroy_args *args) |
ca473936 RW |
391 | { |
392 | struct ripng *ripng; | |
393 | int type; | |
394 | ||
60ee8be1 | 395 | if (args->event != NB_EV_APPLY) |
ca473936 RW |
396 | return NB_OK; |
397 | ||
60ee8be1 RW |
398 | ripng = nb_running_get_entry(args->dnode, NULL, true); |
399 | type = yang_dnode_get_enum(args->dnode, "./protocol"); | |
ca473936 RW |
400 | |
401 | ripng->redist[type].enabled = false; | |
402 | if (ripng->redist[type].route_map.name) { | |
403 | free(ripng->redist[type].route_map.name); | |
404 | ripng->redist[type].route_map.name = NULL; | |
405 | ripng->redist[type].route_map.map = NULL; | |
406 | } | |
407 | ripng->redist[type].metric_config = false; | |
408 | ripng->redist[type].metric = 0; | |
409 | ||
410 | if (ripng->enabled) | |
411 | ripng_redistribute_conf_delete(ripng, type); | |
412 | ||
413 | return NB_OK; | |
414 | } | |
415 | ||
60ee8be1 RW |
416 | void ripngd_instance_redistribute_apply_finish( |
417 | struct nb_cb_apply_finish_args *args) | |
ca473936 RW |
418 | { |
419 | struct ripng *ripng; | |
420 | int type; | |
421 | ||
60ee8be1 RW |
422 | ripng = nb_running_get_entry(args->dnode, NULL, true); |
423 | type = yang_dnode_get_enum(args->dnode, "./protocol"); | |
ca473936 RW |
424 | |
425 | if (ripng->enabled) | |
426 | ripng_redistribute_conf_update(ripng, type); | |
427 | } | |
428 | ||
429 | /* | |
430 | * XPath: /frr-ripngd:ripngd/instance/redistribute/route-map | |
431 | */ | |
60ee8be1 RW |
432 | int ripngd_instance_redistribute_route_map_modify( |
433 | struct nb_cb_modify_args *args) | |
ca473936 RW |
434 | { |
435 | struct ripng *ripng; | |
436 | int type; | |
437 | const char *rmap_name; | |
438 | ||
60ee8be1 | 439 | if (args->event != NB_EV_APPLY) |
ca473936 RW |
440 | return NB_OK; |
441 | ||
60ee8be1 RW |
442 | ripng = nb_running_get_entry(args->dnode, NULL, true); |
443 | type = yang_dnode_get_enum(args->dnode, "../protocol"); | |
444 | rmap_name = yang_dnode_get_string(args->dnode, NULL); | |
ca473936 RW |
445 | |
446 | if (ripng->redist[type].route_map.name) | |
447 | free(ripng->redist[type].route_map.name); | |
448 | ripng->redist[type].route_map.name = strdup(rmap_name); | |
449 | ripng->redist[type].route_map.map = route_map_lookup_by_name(rmap_name); | |
450 | ||
451 | return NB_OK; | |
452 | } | |
453 | ||
60ee8be1 RW |
454 | int ripngd_instance_redistribute_route_map_destroy( |
455 | struct nb_cb_destroy_args *args) | |
ca473936 RW |
456 | { |
457 | struct ripng *ripng; | |
458 | int type; | |
459 | ||
60ee8be1 | 460 | if (args->event != NB_EV_APPLY) |
ca473936 RW |
461 | return NB_OK; |
462 | ||
60ee8be1 RW |
463 | ripng = nb_running_get_entry(args->dnode, NULL, true); |
464 | type = yang_dnode_get_enum(args->dnode, "../protocol"); | |
ca473936 RW |
465 | |
466 | free(ripng->redist[type].route_map.name); | |
467 | ripng->redist[type].route_map.name = NULL; | |
468 | ripng->redist[type].route_map.map = NULL; | |
469 | ||
470 | return NB_OK; | |
471 | } | |
472 | ||
473 | /* | |
474 | * XPath: /frr-ripngd:ripngd/instance/redistribute/metric | |
475 | */ | |
60ee8be1 | 476 | int ripngd_instance_redistribute_metric_modify(struct nb_cb_modify_args *args) |
ca473936 RW |
477 | { |
478 | struct ripng *ripng; | |
479 | int type; | |
480 | uint8_t metric; | |
481 | ||
60ee8be1 | 482 | if (args->event != NB_EV_APPLY) |
ca473936 RW |
483 | return NB_OK; |
484 | ||
60ee8be1 RW |
485 | ripng = nb_running_get_entry(args->dnode, NULL, true); |
486 | type = yang_dnode_get_enum(args->dnode, "../protocol"); | |
487 | metric = yang_dnode_get_uint8(args->dnode, NULL); | |
ca473936 RW |
488 | |
489 | ripng->redist[type].metric_config = true; | |
490 | ripng->redist[type].metric = metric; | |
491 | ||
492 | return NB_OK; | |
493 | } | |
494 | ||
60ee8be1 | 495 | int ripngd_instance_redistribute_metric_destroy(struct nb_cb_destroy_args *args) |
ca473936 RW |
496 | { |
497 | struct ripng *ripng; | |
498 | int type; | |
499 | ||
60ee8be1 | 500 | if (args->event != NB_EV_APPLY) |
ca473936 RW |
501 | return NB_OK; |
502 | ||
60ee8be1 RW |
503 | ripng = nb_running_get_entry(args->dnode, NULL, true); |
504 | type = yang_dnode_get_enum(args->dnode, "../protocol"); | |
ca473936 RW |
505 | |
506 | ripng->redist[type].metric_config = false; | |
507 | ripng->redist[type].metric = 0; | |
508 | ||
509 | return NB_OK; | |
510 | } | |
511 | ||
e40c4208 CH |
512 | /* |
513 | * XPath: /frr-ripngd:ripngd/instance/if-route-maps/if-route-map | |
514 | */ | |
515 | int ripngd_instance_if_route_maps_if_route_map_create( | |
516 | struct nb_cb_create_args *args) | |
517 | { | |
518 | /* if_rmap is created when first routemap is added */ | |
519 | return NB_OK; | |
520 | } | |
521 | ||
522 | int ripngd_instance_if_route_maps_if_route_map_destroy( | |
523 | struct nb_cb_destroy_args *args) | |
524 | { | |
525 | struct ripng *ripng; | |
526 | ||
527 | if (args->event != NB_EV_APPLY) | |
528 | return NB_OK; | |
529 | ||
530 | /* | |
531 | * YANG will prune edit deletes up to the most general deleted node so | |
532 | * we need to handle deleting any existing state underneath and not | |
533 | * count on those more specific callbacks being called individually. | |
534 | */ | |
535 | ||
536 | ripng = nb_running_get_entry(args->dnode, NULL, true); | |
537 | if_rmap_yang_destroy_cb(ripng->if_rmap_ctx, args->dnode); | |
538 | ||
539 | return NB_OK; | |
540 | } | |
541 | ||
542 | static void if_route_map_modify(const struct lyd_node *dnode, | |
543 | enum if_rmap_type type, bool delete) | |
544 | { | |
545 | struct ripng *ripng = nb_running_get_entry(dnode, NULL, true); | |
546 | ||
547 | if_rmap_yang_modify_cb(ripng->if_rmap_ctx, dnode, type, delete); | |
548 | } | |
549 | /* | |
550 | * XPath: /frr-ripng:ripng/instance/if-route-maps/if-route-map/in-route-map | |
551 | */ | |
552 | int ripngd_instance_if_route_maps_if_route_map_in_route_map_modify( | |
553 | struct nb_cb_modify_args *args) | |
554 | { | |
555 | if (args->event != NB_EV_APPLY) | |
556 | return NB_OK; | |
557 | ||
558 | if_route_map_modify(args->dnode, IF_RMAP_IN, false); | |
559 | ||
560 | return NB_OK; | |
561 | } | |
562 | ||
563 | int ripngd_instance_if_route_maps_if_route_map_in_route_map_destroy( | |
564 | struct nb_cb_destroy_args *args) | |
565 | { | |
566 | if (args->event != NB_EV_APPLY) | |
567 | return NB_OK; | |
568 | ||
569 | if_route_map_modify(args->dnode, IF_RMAP_IN, true); | |
570 | ||
571 | return NB_OK; | |
572 | } | |
573 | ||
574 | /* | |
575 | * XPath: /frr-ripngd:ripngd/instance/if-route-maps/if-route-map/out-route-map | |
576 | */ | |
577 | int ripngd_instance_if_route_maps_if_route_map_out_route_map_modify( | |
578 | struct nb_cb_modify_args *args) | |
579 | { | |
580 | if (args->event != NB_EV_APPLY) | |
581 | return NB_OK; | |
582 | ||
583 | if_route_map_modify(args->dnode, IF_RMAP_OUT, false); | |
584 | ||
585 | return NB_OK; | |
586 | } | |
587 | ||
588 | int ripngd_instance_if_route_maps_if_route_map_out_route_map_destroy( | |
589 | struct nb_cb_destroy_args *args) | |
590 | { | |
591 | if (args->event != NB_EV_APPLY) | |
592 | return NB_OK; | |
593 | ||
594 | if_route_map_modify(args->dnode, IF_RMAP_OUT, true); | |
595 | ||
596 | return NB_OK; | |
597 | } | |
598 | ||
ca473936 RW |
599 | /* |
600 | * XPath: /frr-ripngd:ripngd/instance/static-route | |
601 | */ | |
60ee8be1 | 602 | int ripngd_instance_static_route_create(struct nb_cb_create_args *args) |
ca473936 RW |
603 | { |
604 | struct ripng *ripng; | |
605 | struct prefix_ipv6 p; | |
606 | ||
60ee8be1 | 607 | if (args->event != NB_EV_APPLY) |
ca473936 RW |
608 | return NB_OK; |
609 | ||
60ee8be1 RW |
610 | ripng = nb_running_get_entry(args->dnode, NULL, true); |
611 | yang_dnode_get_ipv6p(&p, args->dnode, NULL); | |
ca473936 RW |
612 | apply_mask_ipv6(&p); |
613 | ||
614 | ripng_redistribute_add(ripng, ZEBRA_ROUTE_RIPNG, RIPNG_ROUTE_STATIC, &p, | |
615 | 0, NULL, 0); | |
616 | ||
617 | return NB_OK; | |
618 | } | |
619 | ||
60ee8be1 | 620 | int ripngd_instance_static_route_destroy(struct nb_cb_destroy_args *args) |
ca473936 RW |
621 | { |
622 | struct ripng *ripng; | |
623 | struct prefix_ipv6 p; | |
624 | ||
60ee8be1 | 625 | if (args->event != NB_EV_APPLY) |
ca473936 RW |
626 | return NB_OK; |
627 | ||
60ee8be1 RW |
628 | ripng = nb_running_get_entry(args->dnode, NULL, true); |
629 | yang_dnode_get_ipv6p(&p, args->dnode, NULL); | |
ca473936 RW |
630 | apply_mask_ipv6(&p); |
631 | ||
632 | ripng_redistribute_delete(ripng, ZEBRA_ROUTE_RIPNG, RIPNG_ROUTE_STATIC, | |
633 | &p, 0); | |
634 | ||
635 | return NB_OK; | |
636 | } | |
637 | ||
638 | /* | |
639 | * XPath: /frr-ripngd:ripngd/instance/aggregate-address | |
640 | */ | |
60ee8be1 | 641 | int ripngd_instance_aggregate_address_create(struct nb_cb_create_args *args) |
ca473936 RW |
642 | { |
643 | struct ripng *ripng; | |
644 | struct prefix_ipv6 p; | |
645 | ||
60ee8be1 | 646 | if (args->event != NB_EV_APPLY) |
ca473936 RW |
647 | return NB_OK; |
648 | ||
60ee8be1 RW |
649 | ripng = nb_running_get_entry(args->dnode, NULL, true); |
650 | yang_dnode_get_ipv6p(&p, args->dnode, NULL); | |
ca473936 RW |
651 | apply_mask_ipv6(&p); |
652 | ||
653 | ripng_aggregate_add(ripng, (struct prefix *)&p); | |
654 | ||
655 | return NB_OK; | |
656 | } | |
657 | ||
60ee8be1 | 658 | int ripngd_instance_aggregate_address_destroy(struct nb_cb_destroy_args *args) |
ca473936 RW |
659 | { |
660 | struct ripng *ripng; | |
661 | struct prefix_ipv6 p; | |
662 | ||
60ee8be1 | 663 | if (args->event != NB_EV_APPLY) |
ca473936 RW |
664 | return NB_OK; |
665 | ||
60ee8be1 RW |
666 | ripng = nb_running_get_entry(args->dnode, NULL, true); |
667 | yang_dnode_get_ipv6p(&p, args->dnode, NULL); | |
ca473936 RW |
668 | apply_mask_ipv6(&p); |
669 | ||
670 | ripng_aggregate_delete(ripng, (struct prefix *)&p); | |
671 | ||
672 | return NB_OK; | |
673 | } | |
674 | ||
675 | /* | |
676 | * XPath: /frr-ripngd:ripngd/instance/timers | |
677 | */ | |
60ee8be1 | 678 | void ripngd_instance_timers_apply_finish(struct nb_cb_apply_finish_args *args) |
ca473936 RW |
679 | { |
680 | struct ripng *ripng; | |
681 | ||
60ee8be1 | 682 | ripng = nb_running_get_entry(args->dnode, NULL, true); |
ca473936 RW |
683 | |
684 | /* Reset update timer thread. */ | |
685 | ripng_event(ripng, RIPNG_UPDATE_EVENT, 0); | |
686 | } | |
687 | ||
688 | /* | |
689 | * XPath: /frr-ripngd:ripngd/instance/timers/flush-interval | |
690 | */ | |
60ee8be1 | 691 | int ripngd_instance_timers_flush_interval_modify(struct nb_cb_modify_args *args) |
ca473936 RW |
692 | { |
693 | struct ripng *ripng; | |
694 | ||
60ee8be1 | 695 | if (args->event != NB_EV_APPLY) |
ca473936 RW |
696 | return NB_OK; |
697 | ||
60ee8be1 RW |
698 | ripng = nb_running_get_entry(args->dnode, NULL, true); |
699 | ripng->garbage_time = yang_dnode_get_uint16(args->dnode, NULL); | |
ca473936 RW |
700 | |
701 | return NB_OK; | |
702 | } | |
703 | ||
704 | /* | |
705 | * XPath: /frr-ripngd:ripngd/instance/timers/holddown-interval | |
706 | */ | |
707 | int ripngd_instance_timers_holddown_interval_modify( | |
60ee8be1 | 708 | struct nb_cb_modify_args *args) |
ca473936 RW |
709 | { |
710 | struct ripng *ripng; | |
711 | ||
60ee8be1 | 712 | if (args->event != NB_EV_APPLY) |
ca473936 RW |
713 | return NB_OK; |
714 | ||
60ee8be1 RW |
715 | ripng = nb_running_get_entry(args->dnode, NULL, true); |
716 | ripng->timeout_time = yang_dnode_get_uint16(args->dnode, NULL); | |
ca473936 RW |
717 | |
718 | return NB_OK; | |
719 | } | |
720 | ||
721 | /* | |
722 | * XPath: /frr-ripngd:ripngd/instance/timers/update-interval | |
723 | */ | |
60ee8be1 RW |
724 | int ripngd_instance_timers_update_interval_modify( |
725 | struct nb_cb_modify_args *args) | |
ca473936 RW |
726 | { |
727 | struct ripng *ripng; | |
728 | ||
60ee8be1 | 729 | if (args->event != NB_EV_APPLY) |
ca473936 RW |
730 | return NB_OK; |
731 | ||
60ee8be1 RW |
732 | ripng = nb_running_get_entry(args->dnode, NULL, true); |
733 | ripng->update_time = yang_dnode_get_uint16(args->dnode, NULL); | |
ca473936 RW |
734 | |
735 | return NB_OK; | |
736 | } | |
737 | ||
738 | /* | |
739 | * XPath: /frr-interface:lib/interface/frr-ripngd:ripng/split-horizon | |
740 | */ | |
60ee8be1 | 741 | int lib_interface_ripng_split_horizon_modify(struct nb_cb_modify_args *args) |
ca473936 RW |
742 | { |
743 | struct interface *ifp; | |
744 | struct ripng_interface *ri; | |
745 | ||
60ee8be1 | 746 | if (args->event != NB_EV_APPLY) |
ca473936 RW |
747 | return NB_OK; |
748 | ||
60ee8be1 | 749 | ifp = nb_running_get_entry(args->dnode, NULL, true); |
ca473936 | 750 | ri = ifp->info; |
60ee8be1 | 751 | ri->split_horizon = yang_dnode_get_enum(args->dnode, NULL); |
ca473936 RW |
752 | |
753 | return NB_OK; | |
754 | } |