]> git.proxmox.com Git - mirror_frr.git/blame - bfdd/bfdd_nb_config.c
bfdd: add missing includes
[mirror_frr.git] / bfdd / bfdd_nb_config.c
CommitLineData
6c574029
RW
1/*
2 * BFD daemon northbound implementation.
3 *
4 * Copyright (C) 2019 Network Device Education Foundation, Inc. ("NetDEF")
5 * Rafael Zalamena
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301 USA.
21 */
22
23#include <zebra.h>
24
25#include "lib/log.h"
26#include "lib/northbound.h"
27
28#include "bfd.h"
29#include "bfdd_nb.h"
30
31/*
32 * Helpers.
33 */
34static void bfd_session_get_key(bool mhop, const struct lyd_node *dnode,
35 struct bfd_key *bk)
36{
37 const char *ifname = NULL, *vrfname = NULL;
38 struct sockaddr_any psa, lsa;
39
40 /* Required destination parameter. */
41 strtosa(yang_dnode_get_string(dnode, "./dest-addr"), &psa);
42
43 /* Get optional source address. */
44 memset(&lsa, 0, sizeof(lsa));
45 if (yang_dnode_exists(dnode, "./source-addr"))
46 strtosa(yang_dnode_get_string(dnode, "./source-addr"), &lsa);
47
48 /* Get optional interface and vrf names. */
49 if (yang_dnode_exists(dnode, "./interface"))
50 ifname = yang_dnode_get_string(dnode, "./interface");
51 if (yang_dnode_exists(dnode, "./vrf"))
52 vrfname = yang_dnode_get_string(dnode, "./vrf");
53
54 /* Generate the corresponding key. */
55 gen_bfd_key(bk, &psa, &lsa, mhop, ifname, vrfname);
56}
57
58static int bfd_session_create(enum nb_event event, const struct lyd_node *dnode,
59 union nb_resource *resource, bool mhop)
60{
61 struct bfd_session *bs;
62 const char *ifname;
63 struct bfd_key bk;
64 struct prefix p;
65
66 switch (event) {
67 case NB_EV_VALIDATE:
68 /*
69 * When `dest-addr` is IPv6 and link-local we must
70 * require interface name, otherwise we can't figure
71 * which interface to use to send the packets.
72 */
73 yang_dnode_get_prefix(&p, dnode, "./dest-addr");
74
75 /*
76 * To support old FRR versions we must allow empty
77 * interface to be specified, however that should
78 * change in the future.
79 */
80 if (yang_dnode_exists(dnode, "./interface"))
81 ifname = yang_dnode_get_string(dnode, "./interface");
82 else
83 ifname = "";
84
85 if (p.family == AF_INET6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)
86 && strlen(ifname) == 0) {
87 zlog_warn(
3efd0893 88 "%s: when using link-local you must specify an interface.",
6c574029
RW
89 __func__);
90 return NB_ERR_VALIDATION;
91 }
92 break;
93
94 case NB_EV_PREPARE:
95 bfd_session_get_key(mhop, dnode, &bk);
96 bs = bfd_key_lookup(bk);
97
98 /* This session was already configured by another daemon. */
99 if (bs != NULL) {
100 /* Now it is configured also by CLI. */
b88113ef 101 SET_FLAG(bs->flags, BFD_SESS_FLAG_CONFIG);
6c574029
RW
102 bs->refcount++;
103
104 resource->ptr = bs;
105 break;
106 }
107
108 bs = bfd_session_new();
6c574029
RW
109
110 /* Fill the session key. */
111 bfd_session_get_key(mhop, dnode, &bs->key);
112
113 /* Set configuration flags. */
114 bs->refcount = 1;
b88113ef 115 SET_FLAG(bs->flags, BFD_SESS_FLAG_CONFIG);
6c574029 116 if (mhop)
b88113ef 117 SET_FLAG(bs->flags, BFD_SESS_FLAG_MH);
6c574029 118 if (bs->key.family == AF_INET6)
b88113ef 119 SET_FLAG(bs->flags, BFD_SESS_FLAG_IPV6);
6c574029
RW
120
121 resource->ptr = bs;
122 break;
123
124 case NB_EV_APPLY:
125 bs = resource->ptr;
126
127 /* Only attempt to registrate if freshly allocated. */
128 if (bs->discrs.my_discr == 0 && bs_registrate(bs) == NULL)
129 return NB_ERR_RESOURCE;
130
131 nb_running_set_entry(dnode, bs);
132 break;
133
134 case NB_EV_ABORT:
135 bs = resource->ptr;
136 if (bs->refcount <= 1)
137 bfd_session_free(resource->ptr);
138 break;
139 }
140
141 return NB_OK;
142}
143
144static int bfd_session_destroy(enum nb_event event,
145 const struct lyd_node *dnode, bool mhop)
146{
147 struct bfd_session *bs;
148 struct bfd_key bk;
149
150 switch (event) {
151 case NB_EV_VALIDATE:
152 bfd_session_get_key(mhop, dnode, &bk);
153 if (bfd_key_lookup(bk) == NULL)
154 return NB_ERR_INCONSISTENCY;
155 break;
156
157 case NB_EV_PREPARE:
158 /* NOTHING */
159 break;
160
161 case NB_EV_APPLY:
162 bs = nb_running_unset_entry(dnode);
163 /* CLI is not using this session anymore. */
b88113ef 164 if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_CONFIG) == 0)
6c574029
RW
165 break;
166
b88113ef 167 UNSET_FLAG(bs->flags, BFD_SESS_FLAG_CONFIG);
6c574029
RW
168 bs->refcount--;
169 /* There are still daemons using it. */
170 if (bs->refcount > 0)
171 break;
172
173 bfd_session_free(bs);
174 break;
175
176 case NB_EV_ABORT:
177 /* NOTHING */
178 break;
179 }
180
181 return NB_OK;
182}
183
184/*
185 * XPath: /frr-bfdd:bfdd/bfd
186 */
60ee8be1 187int bfdd_bfd_create(struct nb_cb_create_args *args)
6c574029
RW
188{
189 /* NOTHING */
190 return NB_OK;
191}
192
60ee8be1 193int bfdd_bfd_destroy(struct nb_cb_destroy_args *args)
6c574029 194{
60ee8be1 195 switch (args->event) {
6c574029
RW
196 case NB_EV_VALIDATE:
197 /* NOTHING */
198 return NB_OK;
199
200 case NB_EV_PREPARE:
201 /* NOTHING */
202 return NB_OK;
203
204 case NB_EV_APPLY:
205 bfd_sessions_remove_manual();
206 break;
207
208 case NB_EV_ABORT:
209 /* NOTHING */
210 return NB_OK;
211 }
212
213 return NB_OK;
214}
215
ccc9ada8
RZ
216/*
217 * XPath: /frr-bfdd:bfdd/bfd/profile
218 */
219int bfdd_bfd_profile_create(struct nb_cb_create_args *args)
220{
221 struct bfd_profile *bp;
222 const char *name;
223
224 if (args->event != NB_EV_APPLY)
225 return NB_OK;
226
227 name = yang_dnode_get_string(args->dnode, "./name");
228 bp = bfd_profile_new(name);
229 nb_running_set_entry(args->dnode, bp);
230
231 return NB_OK;
232}
233
234int bfdd_bfd_profile_destroy(struct nb_cb_destroy_args *args)
235{
236 struct bfd_profile *bp;
237
238 if (args->event != NB_EV_APPLY)
239 return NB_OK;
240
241 bp = nb_running_unset_entry(args->dnode);
242 bfd_profile_free(bp);
243
244 return NB_OK;
245}
246
247/*
248 * XPath: /frr-bfdd:bfdd/bfd/profile/detection-multiplier
249 */
250int bfdd_bfd_profile_detection_multiplier_modify(struct nb_cb_modify_args *args)
251{
252 struct bfd_profile *bp;
253
254 if (args->event != NB_EV_APPLY)
255 return NB_OK;
256
257 bp = nb_running_get_entry(args->dnode, NULL, true);
258 bp->detection_multiplier = yang_dnode_get_uint8(args->dnode, NULL);
2975f578 259 bfd_profile_update(bp);
ccc9ada8
RZ
260
261 return NB_OK;
262}
263
264/*
265 * XPath: /frr-bfdd:bfdd/bfd/profile/desired-transmission-interval
266 */
267int bfdd_bfd_profile_desired_transmission_interval_modify(
268 struct nb_cb_modify_args *args)
269{
270 struct bfd_profile *bp;
271 uint32_t min_tx;
272
273 switch (args->event) {
274 case NB_EV_VALIDATE:
275 min_tx = yang_dnode_get_uint32(args->dnode, NULL);
276 if (min_tx < 10000 || min_tx > 60000000)
277 return NB_ERR_VALIDATION;
278 break;
279
280 case NB_EV_PREPARE:
281 /* NOTHING */
282 break;
283
284 case NB_EV_APPLY:
285 min_tx = yang_dnode_get_uint32(args->dnode, NULL);
286 bp = nb_running_get_entry(args->dnode, NULL, true);
287 if (bp->min_tx == min_tx)
288 return NB_OK;
289
290 bp->min_tx = min_tx;
291 bfd_profile_update(bp);
292 break;
293
294 case NB_EV_ABORT:
295 /* NOTHING */
296 break;
297 }
298
299 return NB_OK;
300}
301
302/*
303 * XPath: /frr-bfdd:bfdd/bfd/profile/required-receive-interval
304 */
305int bfdd_bfd_profile_required_receive_interval_modify(
306 struct nb_cb_modify_args *args)
307{
308 struct bfd_profile *bp;
309 uint32_t min_rx;
310
311 switch (args->event) {
312 case NB_EV_VALIDATE:
313 min_rx = yang_dnode_get_uint32(args->dnode, NULL);
314 if (min_rx < 10000 || min_rx > 60000000)
315 return NB_ERR_VALIDATION;
316 break;
317
318 case NB_EV_PREPARE:
319 /* NOTHING */
320 break;
321
322 case NB_EV_APPLY:
323 min_rx = yang_dnode_get_uint32(args->dnode, NULL);
324 bp = nb_running_get_entry(args->dnode, NULL, true);
325 if (bp->min_rx == min_rx)
326 return NB_OK;
327
328 bp->min_rx = min_rx;
329 bfd_profile_update(bp);
330 break;
331
332 case NB_EV_ABORT:
333 /* NOTHING */
334 break;
335 }
336
337 return NB_OK;
338}
339
340/*
341 * XPath: /frr-bfdd:bfdd/bfd/profile/administrative-down
342 */
343int bfdd_bfd_profile_administrative_down_modify(struct nb_cb_modify_args *args)
344{
345 struct bfd_profile *bp;
346 bool shutdown;
347
348 if (args->event != NB_EV_APPLY)
349 return NB_OK;
350
351 shutdown = yang_dnode_get_bool(args->dnode, NULL);
352 bp = nb_running_get_entry(args->dnode, NULL, true);
353 if (bp->admin_shutdown == shutdown)
354 return NB_OK;
355
356 bp->admin_shutdown = shutdown;
357 bfd_profile_update(bp);
358
359 return NB_OK;
360}
361
1a2e2fff
RZ
362/*
363 * XPath: /frr-bfdd:bfdd/bfd/profile/passive-mode
364 */
365int bfdd_bfd_profile_passive_mode_modify(struct nb_cb_modify_args *args)
366{
367 struct bfd_profile *bp;
368 bool passive;
369
370 if (args->event != NB_EV_APPLY)
371 return NB_OK;
372
373 passive = yang_dnode_get_bool(args->dnode, NULL);
374 bp = nb_running_get_entry(args->dnode, NULL, true);
375 if (bp->passive == passive)
376 return NB_OK;
377
378 bp->passive = passive;
379 bfd_profile_update(bp);
380
381 return NB_OK;
382}
383
262e1d25
RZ
384/*
385 * XPath: /frr-bfdd:bfdd/bfd/profile/minimum-ttl
386 */
387int bfdd_bfd_profile_minimum_ttl_modify(struct nb_cb_modify_args *args)
388{
389 struct bfd_profile *bp;
390 uint8_t minimum_ttl;
391
392 if (args->event != NB_EV_APPLY)
393 return NB_OK;
394
395 minimum_ttl = yang_dnode_get_uint8(args->dnode, NULL);
396 bp = nb_running_get_entry(args->dnode, NULL, true);
397 if (bp->minimum_ttl == minimum_ttl)
398 return NB_OK;
399
400 bp->minimum_ttl = minimum_ttl;
401 bfd_profile_update(bp);
402
403 return NB_OK;
404}
405
406int bfdd_bfd_profile_minimum_ttl_destroy(struct nb_cb_destroy_args *args)
407{
408 struct bfd_profile *bp;
409
410 if (args->event != NB_EV_APPLY)
411 return NB_OK;
412
413 bp = nb_running_get_entry(args->dnode, NULL, true);
414 bp->minimum_ttl = BFD_DEF_MHOP_TTL;
415 bfd_profile_update(bp);
416
417 return NB_OK;
418}
419
ccc9ada8
RZ
420/*
421 * XPath: /frr-bfdd:bfdd/bfd/profile/echo-mode
422 */
423int bfdd_bfd_profile_echo_mode_modify(struct nb_cb_modify_args *args)
424{
425 struct bfd_profile *bp;
426 bool echo;
427
428 if (args->event != NB_EV_APPLY)
429 return NB_OK;
430
431 echo = yang_dnode_get_bool(args->dnode, NULL);
432 bp = nb_running_get_entry(args->dnode, NULL, true);
433 if (bp->echo_mode == echo)
434 return NB_OK;
435
436 bp->echo_mode = echo;
437 bfd_profile_update(bp);
438
439 return NB_OK;
440}
441
442/*
443 * XPath: /frr-bfdd:bfdd/bfd/profile/desired-echo-echo-transmission-interval
444 */
445int bfdd_bfd_profile_desired_echo_transmission_interval_modify(
446 struct nb_cb_modify_args *args)
447{
448 struct bfd_profile *bp;
449 uint32_t min_rx;
450
451 switch (args->event) {
452 case NB_EV_VALIDATE:
453 min_rx = yang_dnode_get_uint32(args->dnode, NULL);
454 if (min_rx < 10000 || min_rx > 60000000)
455 return NB_ERR_VALIDATION;
456 break;
457
458 case NB_EV_PREPARE:
459 /* NOTHING */
460 break;
461
462 case NB_EV_APPLY:
463 min_rx = yang_dnode_get_uint32(args->dnode, NULL);
464 bp = nb_running_get_entry(args->dnode, NULL, true);
465 if (bp->min_echo_rx == min_rx)
466 return NB_OK;
467
468 bp->min_echo_rx = min_rx;
469 bfd_profile_update(bp);
470 break;
471
472 case NB_EV_ABORT:
473 /* NOTHING */
474 break;
475 }
476
477 return NB_OK;
478}
479
6c574029
RW
480/*
481 * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop
482 */
60ee8be1 483int bfdd_bfd_sessions_single_hop_create(struct nb_cb_create_args *args)
6c574029 484{
60ee8be1
RW
485 return bfd_session_create(args->event, args->dnode, args->resource,
486 false);
6c574029
RW
487}
488
60ee8be1 489int bfdd_bfd_sessions_single_hop_destroy(struct nb_cb_destroy_args *args)
6c574029 490{
60ee8be1 491 return bfd_session_destroy(args->event, args->dnode, false);
6c574029
RW
492}
493
494/*
495 * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/source-addr
496 */
60ee8be1
RW
497int bfdd_bfd_sessions_single_hop_source_addr_modify(
498 struct nb_cb_modify_args *args)
6c574029
RW
499{
500 return NB_OK;
501}
502
503int bfdd_bfd_sessions_single_hop_source_addr_destroy(
60ee8be1 504 struct nb_cb_destroy_args *args)
6c574029
RW
505{
506 return NB_OK;
507}
508
ccc9ada8
RZ
509/*
510 * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/profile
511 */
512int bfdd_bfd_sessions_single_hop_profile_modify(struct nb_cb_modify_args *args)
513{
514 struct bfd_session *bs;
515
516 if (args->event != NB_EV_APPLY)
517 return NB_OK;
518
519 bs = nb_running_get_entry(args->dnode, NULL, true);
520 bfd_profile_apply(yang_dnode_get_string(args->dnode, NULL), bs);
521
522 return NB_OK;
523}
524
525int bfdd_bfd_sessions_single_hop_profile_destroy(
526 struct nb_cb_destroy_args *args)
527{
528 struct bfd_session *bs;
529
530 if (args->event != NB_EV_APPLY)
531 return NB_OK;
532
533 bs = nb_running_get_entry(args->dnode, NULL, true);
534 bfd_profile_remove(bs);
535
536 return NB_OK;
537}
538
6c574029
RW
539/*
540 * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/detection-multiplier
541 */
542int bfdd_bfd_sessions_single_hop_detection_multiplier_modify(
60ee8be1 543 struct nb_cb_modify_args *args)
6c574029 544{
60ee8be1 545 uint8_t detection_multiplier = yang_dnode_get_uint8(args->dnode, NULL);
6c574029
RW
546 struct bfd_session *bs;
547
60ee8be1 548 switch (args->event) {
6c574029
RW
549 case NB_EV_VALIDATE:
550 break;
551
552 case NB_EV_PREPARE:
553 /* NOTHING */
554 break;
555
556 case NB_EV_APPLY:
60ee8be1 557 bs = nb_running_get_entry(args->dnode, NULL, true);
ccc9ada8 558 bs->peer_profile.detection_multiplier = detection_multiplier;
4e38f82a 559 bfd_session_apply(bs);
6c574029
RW
560 break;
561
562 case NB_EV_ABORT:
563 /* NOTHING */
564 break;
565 }
566
567 return NB_OK;
568}
569
570/*
571 * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/desired-transmission-interval
572 */
573int bfdd_bfd_sessions_single_hop_desired_transmission_interval_modify(
60ee8be1 574 struct nb_cb_modify_args *args)
6c574029 575{
60ee8be1 576 uint32_t tx_interval = yang_dnode_get_uint32(args->dnode, NULL);
6c574029
RW
577 struct bfd_session *bs;
578
60ee8be1 579 switch (args->event) {
6c574029
RW
580 case NB_EV_VALIDATE:
581 if (tx_interval < 10000 || tx_interval > 60000000)
582 return NB_ERR_VALIDATION;
583 break;
584
585 case NB_EV_PREPARE:
586 /* NOTHING */
587 break;
588
589 case NB_EV_APPLY:
60ee8be1 590 bs = nb_running_get_entry(args->dnode, NULL, true);
6c574029
RW
591 if (tx_interval == bs->timers.desired_min_tx)
592 return NB_OK;
593
ccc9ada8 594 bs->peer_profile.min_tx = tx_interval;
4e38f82a 595 bfd_session_apply(bs);
6c574029
RW
596 break;
597
598 case NB_EV_ABORT:
599 /* NOTHING */
600 break;
601 }
602
603 return NB_OK;
604}
605
606/*
607 * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/required-receive-interval
608 */
609int bfdd_bfd_sessions_single_hop_required_receive_interval_modify(
60ee8be1 610 struct nb_cb_modify_args *args)
6c574029 611{
60ee8be1 612 uint32_t rx_interval = yang_dnode_get_uint32(args->dnode, NULL);
6c574029
RW
613 struct bfd_session *bs;
614
60ee8be1 615 switch (args->event) {
6c574029
RW
616 case NB_EV_VALIDATE:
617 if (rx_interval < 10000 || rx_interval > 60000000)
618 return NB_ERR_VALIDATION;
619 break;
620
621 case NB_EV_PREPARE:
622 /* NOTHING */
623 break;
624
625 case NB_EV_APPLY:
60ee8be1 626 bs = nb_running_get_entry(args->dnode, NULL, true);
6c574029
RW
627 if (rx_interval == bs->timers.required_min_rx)
628 return NB_OK;
629
ccc9ada8 630 bs->peer_profile.min_rx = rx_interval;
4e38f82a 631 bfd_session_apply(bs);
6c574029
RW
632 break;
633
634 case NB_EV_ABORT:
635 /* NOTHING */
636 break;
637 }
638
639 return NB_OK;
640}
641
642/*
643 * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/administrative-down
644 */
645int bfdd_bfd_sessions_single_hop_administrative_down_modify(
60ee8be1 646 struct nb_cb_modify_args *args)
6c574029 647{
60ee8be1 648 bool shutdown = yang_dnode_get_bool(args->dnode, NULL);
6c574029
RW
649 struct bfd_session *bs;
650
60ee8be1 651 switch (args->event) {
6c574029
RW
652 case NB_EV_VALIDATE:
653 case NB_EV_PREPARE:
654 return NB_OK;
655
656 case NB_EV_APPLY:
657 break;
658
659 case NB_EV_ABORT:
660 return NB_OK;
661 }
662
60ee8be1 663 bs = nb_running_get_entry(args->dnode, NULL, true);
ccc9ada8 664 bs->peer_profile.admin_shutdown = shutdown;
4e38f82a 665 bfd_session_apply(bs);
6c574029
RW
666
667 return NB_OK;
668}
669
1a2e2fff
RZ
670/*
671 * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/passive-mode
672 */
673int bfdd_bfd_sessions_single_hop_passive_mode_modify(
674 struct nb_cb_modify_args *args)
675{
676 struct bfd_session *bs;
677 bool passive;
678
679 switch (args->event) {
680 case NB_EV_VALIDATE:
681 case NB_EV_PREPARE:
682 return NB_OK;
683
684 case NB_EV_APPLY:
685 break;
686
687 case NB_EV_ABORT:
688 return NB_OK;
689 }
690
691 passive = yang_dnode_get_bool(args->dnode, NULL);
692
693 bs = nb_running_get_entry(args->dnode, NULL, true);
694 bs->peer_profile.passive = passive;
4e38f82a 695 bfd_session_apply(bs);
1a2e2fff
RZ
696
697 return NB_OK;
698}
699
6c574029
RW
700/*
701 * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/echo-mode
702 */
60ee8be1
RW
703int bfdd_bfd_sessions_single_hop_echo_mode_modify(
704 struct nb_cb_modify_args *args)
6c574029 705{
60ee8be1 706 bool echo = yang_dnode_get_bool(args->dnode, NULL);
6c574029
RW
707 struct bfd_session *bs;
708
60ee8be1 709 switch (args->event) {
6c574029
RW
710 case NB_EV_VALIDATE:
711 case NB_EV_PREPARE:
712 return NB_OK;
713
714 case NB_EV_APPLY:
715 break;
716
717 case NB_EV_ABORT:
718 return NB_OK;
719 }
720
60ee8be1 721 bs = nb_running_get_entry(args->dnode, NULL, true);
ccc9ada8 722 bs->peer_profile.echo_mode = echo;
4e38f82a 723 bfd_session_apply(bs);
6c574029
RW
724
725 return NB_OK;
726}
727
728/*
729 * XPath:
730 * /frr-bfdd:bfdd/bfd/sessions/single-hop/desired-echo-transmission-interval
731 */
732int bfdd_bfd_sessions_single_hop_desired_echo_transmission_interval_modify(
60ee8be1 733 struct nb_cb_modify_args *args)
6c574029 734{
60ee8be1 735 uint32_t echo_interval = yang_dnode_get_uint32(args->dnode, NULL);
6c574029
RW
736 struct bfd_session *bs;
737
60ee8be1 738 switch (args->event) {
6c574029
RW
739 case NB_EV_VALIDATE:
740 if (echo_interval < 10000 || echo_interval > 60000000)
741 return NB_ERR_VALIDATION;
742 break;
743
744 case NB_EV_PREPARE:
745 /* NOTHING */
746 break;
747
748 case NB_EV_APPLY:
60ee8be1 749 bs = nb_running_get_entry(args->dnode, NULL, true);
6c574029
RW
750 if (echo_interval == bs->timers.required_min_echo)
751 return NB_OK;
752
ccc9ada8 753 bs->peer_profile.min_echo_rx = echo_interval;
4e38f82a 754 bfd_session_apply(bs);
6c574029
RW
755 break;
756
757 case NB_EV_ABORT:
758 /* NOTHING */
759 break;
760 }
761
762 return NB_OK;
763}
764
765/*
766 * XPath: /frr-bfdd:bfdd/bfd/sessions/multi-hop
767 */
60ee8be1 768int bfdd_bfd_sessions_multi_hop_create(struct nb_cb_create_args *args)
6c574029 769{
60ee8be1
RW
770 return bfd_session_create(args->event, args->dnode, args->resource,
771 true);
6c574029
RW
772}
773
60ee8be1 774int bfdd_bfd_sessions_multi_hop_destroy(struct nb_cb_destroy_args *args)
6c574029 775{
60ee8be1 776 return bfd_session_destroy(args->event, args->dnode, true);
6c574029 777}
262e1d25
RZ
778
779/*
780 * XPath: /frr-bfdd:bfdd/bfd/sessions/multi-hop/minimum-ttl
781 */
782int bfdd_bfd_sessions_multi_hop_minimum_ttl_modify(
783 struct nb_cb_modify_args *args)
784{
785 struct bfd_session *bs;
786
787 switch (args->event) {
788 case NB_EV_VALIDATE:
789 case NB_EV_PREPARE:
790 return NB_OK;
791
792 case NB_EV_APPLY:
793 break;
794
795 case NB_EV_ABORT:
796 return NB_OK;
797 }
798
799 bs = nb_running_get_entry(args->dnode, NULL, true);
800 bs->peer_profile.minimum_ttl = yang_dnode_get_uint8(args->dnode, NULL);
801 bfd_session_apply(bs);
802
803 return NB_OK;
804}
805
806int bfdd_bfd_sessions_multi_hop_minimum_ttl_destroy(
807 struct nb_cb_destroy_args *args)
808{
809 struct bfd_session *bs;
810
811 switch (args->event) {
812 case NB_EV_VALIDATE:
813 case NB_EV_PREPARE:
814 return NB_OK;
815
816 case NB_EV_APPLY:
817 break;
818
819 case NB_EV_ABORT:
820 return NB_OK;
821 }
822
823 bs = nb_running_get_entry(args->dnode, NULL, true);
824 bs->peer_profile.minimum_ttl = BFD_DEF_MHOP_TTL;
825 bfd_session_apply(bs);
826
827 return NB_OK;
828}