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