Line data Source code
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 : */
34 0 : static void bfd_session_get_key(bool mhop, const struct lyd_node *dnode,
35 : struct bfd_key *bk)
36 : {
37 0 : const char *ifname = NULL, *vrfname = NULL;
38 0 : struct sockaddr_any psa, lsa;
39 :
40 : /* Required destination parameter. */
41 0 : strtosa(yang_dnode_get_string(dnode, "./dest-addr"), &psa);
42 :
43 : /* Get optional source address. */
44 0 : memset(&lsa, 0, sizeof(lsa));
45 0 : if (yang_dnode_exists(dnode, "./source-addr"))
46 0 : strtosa(yang_dnode_get_string(dnode, "./source-addr"), &lsa);
47 :
48 0 : vrfname = yang_dnode_get_string(dnode, "./vrf");
49 :
50 0 : if (!mhop) {
51 0 : ifname = yang_dnode_get_string(dnode, "./interface");
52 0 : if (strcmp(ifname, "*") == 0)
53 0 : ifname = NULL;
54 : }
55 :
56 : /* Generate the corresponding key. */
57 0 : gen_bfd_key(bk, &psa, &lsa, mhop, ifname, vrfname);
58 0 : }
59 :
60 : struct session_iter {
61 : int count;
62 : bool wildcard;
63 : };
64 :
65 0 : static int session_iter_cb(const struct lyd_node *dnode, void *arg)
66 : {
67 0 : struct session_iter *iter = arg;
68 0 : const char *ifname;
69 :
70 0 : ifname = yang_dnode_get_string(dnode, "./interface");
71 :
72 0 : if (strmatch(ifname, "*"))
73 0 : iter->wildcard = true;
74 :
75 0 : iter->count++;
76 :
77 0 : return YANG_ITER_CONTINUE;
78 : }
79 :
80 0 : static int bfd_session_create(struct nb_cb_create_args *args, bool mhop)
81 : {
82 0 : const struct lyd_node *sess_dnode;
83 0 : struct session_iter iter;
84 0 : struct bfd_session *bs;
85 0 : const char *dest;
86 0 : const char *ifname;
87 0 : const char *vrfname;
88 0 : struct bfd_key bk;
89 0 : struct prefix p;
90 :
91 0 : switch (args->event) {
92 0 : case NB_EV_VALIDATE:
93 0 : yang_dnode_get_prefix(&p, args->dnode, "./dest-addr");
94 :
95 0 : if (mhop) {
96 : /*
97 : * Do not allow IPv6 link-local address for multihop.
98 : */
99 0 : if (p.family == AF_INET6
100 0 : && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
101 0 : snprintf(
102 : args->errmsg, args->errmsg_len,
103 : "Cannot use link-local address for multihop sessions");
104 0 : return NB_ERR_VALIDATION;
105 : }
106 : return NB_OK;
107 : }
108 :
109 : /*
110 : * When `dest-addr` is IPv6 and link-local we must
111 : * require interface name, otherwise we can't figure
112 : * which interface to use to send the packets.
113 : */
114 0 : ifname = yang_dnode_get_string(args->dnode, "./interface");
115 :
116 0 : if (p.family == AF_INET6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)
117 0 : && strcmp(ifname, "*") == 0) {
118 0 : snprintf(
119 : args->errmsg, args->errmsg_len,
120 : "When using link-local you must specify an interface");
121 0 : return NB_ERR_VALIDATION;
122 : }
123 :
124 0 : iter.count = 0;
125 0 : iter.wildcard = false;
126 :
127 0 : sess_dnode = yang_dnode_get_parent(args->dnode, "sessions");
128 :
129 0 : dest = yang_dnode_get_string(args->dnode, "./dest-addr");
130 0 : vrfname = yang_dnode_get_string(args->dnode, "./vrf");
131 :
132 0 : yang_dnode_iterate(session_iter_cb, &iter, sess_dnode,
133 : "./single-hop[dest-addr='%s'][vrf='%s']",
134 : dest, vrfname);
135 :
136 0 : if (iter.wildcard && iter.count > 1) {
137 0 : snprintf(
138 : args->errmsg, args->errmsg_len,
139 : "It is not allowed to configure the same peer with and without ifname");
140 0 : return NB_ERR_VALIDATION;
141 : }
142 : break;
143 :
144 0 : case NB_EV_PREPARE:
145 0 : bfd_session_get_key(mhop, args->dnode, &bk);
146 0 : bs = bfd_key_lookup(bk);
147 :
148 : /* This session was already configured by another daemon. */
149 0 : if (bs != NULL) {
150 : /* Now it is configured also by CLI. */
151 0 : SET_FLAG(bs->flags, BFD_SESS_FLAG_CONFIG);
152 0 : bs->refcount++;
153 :
154 0 : args->resource->ptr = bs;
155 0 : break;
156 : }
157 :
158 0 : bs = bfd_session_new();
159 :
160 : /* Fill the session key. */
161 0 : bfd_session_get_key(mhop, args->dnode, &bs->key);
162 :
163 : /* Set configuration flags. */
164 0 : bs->refcount = 1;
165 0 : SET_FLAG(bs->flags, BFD_SESS_FLAG_CONFIG);
166 0 : if (mhop)
167 0 : SET_FLAG(bs->flags, BFD_SESS_FLAG_MH);
168 0 : if (bs->key.family == AF_INET6)
169 0 : SET_FLAG(bs->flags, BFD_SESS_FLAG_IPV6);
170 :
171 0 : args->resource->ptr = bs;
172 0 : break;
173 :
174 0 : case NB_EV_APPLY:
175 0 : bs = args->resource->ptr;
176 :
177 : /* Only attempt to registrate if freshly allocated. */
178 0 : if (bs->discrs.my_discr == 0 && bs_registrate(bs) == NULL)
179 : return NB_ERR_RESOURCE;
180 :
181 0 : nb_running_set_entry(args->dnode, bs);
182 0 : break;
183 :
184 0 : case NB_EV_ABORT:
185 0 : bs = args->resource->ptr;
186 0 : if (bs->refcount <= 1)
187 0 : bfd_session_free(bs);
188 : break;
189 : }
190 :
191 : return NB_OK;
192 : }
193 :
194 0 : static int bfd_session_destroy(enum nb_event event,
195 : const struct lyd_node *dnode, bool mhop)
196 : {
197 0 : struct bfd_session *bs;
198 0 : struct bfd_key bk;
199 :
200 0 : switch (event) {
201 0 : case NB_EV_VALIDATE:
202 0 : bfd_session_get_key(mhop, dnode, &bk);
203 0 : if (bfd_key_lookup(bk) == NULL)
204 : return NB_ERR_INCONSISTENCY;
205 : break;
206 :
207 : case NB_EV_PREPARE:
208 : /* NOTHING */
209 : break;
210 :
211 0 : case NB_EV_APPLY:
212 0 : bs = nb_running_unset_entry(dnode);
213 : /* CLI is not using this session anymore. */
214 0 : if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_CONFIG) == 0)
215 : break;
216 :
217 0 : UNSET_FLAG(bs->flags, BFD_SESS_FLAG_CONFIG);
218 0 : bs->refcount--;
219 : /* There are still daemons using it. */
220 0 : if (bs->refcount > 0)
221 : break;
222 :
223 0 : bfd_session_free(bs);
224 0 : break;
225 :
226 : case NB_EV_ABORT:
227 : /* NOTHING */
228 : break;
229 : }
230 :
231 : return NB_OK;
232 : }
233 :
234 : /*
235 : * XPath: /frr-bfdd:bfdd/bfd
236 : */
237 24 : int bfdd_bfd_create(struct nb_cb_create_args *args)
238 : {
239 24 : if (args->event != NB_EV_APPLY)
240 : return NB_OK;
241 :
242 : /*
243 : * Set any non-NULL value to be able to call
244 : * nb_running_unset_entry in bfdd_bfd_destroy.
245 : */
246 8 : nb_running_set_entry(args->dnode, (void *)0x1);
247 :
248 8 : return NB_OK;
249 : }
250 :
251 0 : int bfdd_bfd_destroy(struct nb_cb_destroy_args *args)
252 : {
253 0 : switch (args->event) {
254 : case NB_EV_VALIDATE:
255 : /* NOTHING */
256 : return NB_OK;
257 :
258 : case NB_EV_PREPARE:
259 : /* NOTHING */
260 : return NB_OK;
261 :
262 0 : case NB_EV_APPLY:
263 : /*
264 : * We need to call this to unset pointers from
265 : * the child nodes - sessions and profiles.
266 : */
267 0 : nb_running_unset_entry(args->dnode);
268 :
269 0 : bfd_sessions_remove_manual();
270 0 : bfd_profiles_remove();
271 0 : break;
272 :
273 : case NB_EV_ABORT:
274 : /* NOTHING */
275 : return NB_OK;
276 : }
277 :
278 : return NB_OK;
279 : }
280 :
281 : /*
282 : * XPath: /frr-bfdd:bfdd/bfd/profile
283 : */
284 6 : int bfdd_bfd_profile_create(struct nb_cb_create_args *args)
285 : {
286 6 : struct bfd_profile *bp;
287 6 : const char *name;
288 :
289 6 : if (args->event != NB_EV_APPLY)
290 : return NB_OK;
291 :
292 2 : name = yang_dnode_get_string(args->dnode, "./name");
293 2 : bp = bfd_profile_new(name);
294 2 : nb_running_set_entry(args->dnode, bp);
295 :
296 2 : return NB_OK;
297 : }
298 :
299 0 : int bfdd_bfd_profile_destroy(struct nb_cb_destroy_args *args)
300 : {
301 0 : struct bfd_profile *bp;
302 :
303 0 : if (args->event != NB_EV_APPLY)
304 : return NB_OK;
305 :
306 0 : bp = nb_running_unset_entry(args->dnode);
307 0 : bfd_profile_free(bp);
308 :
309 0 : return NB_OK;
310 : }
311 :
312 : /*
313 : * XPath: /frr-bfdd:bfdd/bfd/profile/detection-multiplier
314 : */
315 0 : int bfdd_bfd_profile_detection_multiplier_modify(struct nb_cb_modify_args *args)
316 : {
317 0 : struct bfd_profile *bp;
318 :
319 0 : if (args->event != NB_EV_APPLY)
320 : return NB_OK;
321 :
322 0 : bp = nb_running_get_entry(args->dnode, NULL, true);
323 0 : bp->detection_multiplier = yang_dnode_get_uint8(args->dnode, NULL);
324 0 : bfd_profile_update(bp);
325 :
326 0 : return NB_OK;
327 : }
328 :
329 : /*
330 : * XPath: /frr-bfdd:bfdd/bfd/profile/desired-transmission-interval
331 : */
332 6 : int bfdd_bfd_profile_desired_transmission_interval_modify(
333 : struct nb_cb_modify_args *args)
334 : {
335 6 : struct bfd_profile *bp;
336 :
337 6 : switch (args->event) {
338 : case NB_EV_VALIDATE:
339 : break;
340 :
341 : case NB_EV_PREPARE:
342 : /* NOTHING */
343 : break;
344 :
345 2 : case NB_EV_APPLY:
346 2 : bp = nb_running_get_entry(args->dnode, NULL, true);
347 2 : bp->min_tx = yang_dnode_get_uint32(args->dnode, NULL);
348 2 : bfd_profile_update(bp);
349 2 : break;
350 :
351 : case NB_EV_ABORT:
352 : /* NOTHING */
353 : break;
354 : }
355 :
356 6 : return NB_OK;
357 : }
358 :
359 : /*
360 : * XPath: /frr-bfdd:bfdd/bfd/profile/required-receive-interval
361 : */
362 6 : int bfdd_bfd_profile_required_receive_interval_modify(
363 : struct nb_cb_modify_args *args)
364 : {
365 6 : struct bfd_profile *bp;
366 :
367 6 : switch (args->event) {
368 : case NB_EV_VALIDATE:
369 : break;
370 :
371 : case NB_EV_PREPARE:
372 : /* NOTHING */
373 : break;
374 :
375 2 : case NB_EV_APPLY:
376 2 : bp = nb_running_get_entry(args->dnode, NULL, true);
377 2 : bp->min_rx = yang_dnode_get_uint32(args->dnode, NULL);
378 2 : bfd_profile_update(bp);
379 2 : break;
380 :
381 : case NB_EV_ABORT:
382 : /* NOTHING */
383 : break;
384 : }
385 :
386 6 : return NB_OK;
387 : }
388 :
389 : /*
390 : * XPath: /frr-bfdd:bfdd/bfd/profile/administrative-down
391 : */
392 0 : int bfdd_bfd_profile_administrative_down_modify(struct nb_cb_modify_args *args)
393 : {
394 0 : struct bfd_profile *bp;
395 :
396 0 : if (args->event != NB_EV_APPLY)
397 : return NB_OK;
398 :
399 0 : bp = nb_running_get_entry(args->dnode, NULL, true);
400 0 : bp->admin_shutdown = yang_dnode_get_bool(args->dnode, NULL);
401 0 : bfd_profile_update(bp);
402 :
403 0 : return NB_OK;
404 : }
405 :
406 : /*
407 : * XPath: /frr-bfdd:bfdd/bfd/profile/passive-mode
408 : */
409 0 : int bfdd_bfd_profile_passive_mode_modify(struct nb_cb_modify_args *args)
410 : {
411 0 : struct bfd_profile *bp;
412 :
413 0 : if (args->event != NB_EV_APPLY)
414 : return NB_OK;
415 :
416 0 : bp = nb_running_get_entry(args->dnode, NULL, true);
417 0 : bp->passive = yang_dnode_get_bool(args->dnode, NULL);
418 0 : bfd_profile_update(bp);
419 :
420 0 : return NB_OK;
421 : }
422 :
423 : /*
424 : * XPath: /frr-bfdd:bfdd/bfd/profile/minimum-ttl
425 : */
426 0 : int bfdd_bfd_profile_minimum_ttl_modify(struct nb_cb_modify_args *args)
427 : {
428 0 : struct bfd_profile *bp;
429 :
430 0 : if (args->event != NB_EV_APPLY)
431 : return NB_OK;
432 :
433 0 : bp = nb_running_get_entry(args->dnode, NULL, true);
434 0 : bp->minimum_ttl = yang_dnode_get_uint8(args->dnode, NULL);
435 0 : bfd_profile_update(bp);
436 :
437 0 : return NB_OK;
438 : }
439 :
440 0 : int bfdd_bfd_profile_minimum_ttl_destroy(struct nb_cb_destroy_args *args)
441 : {
442 0 : struct bfd_profile *bp;
443 :
444 0 : if (args->event != NB_EV_APPLY)
445 : return NB_OK;
446 :
447 0 : bp = nb_running_get_entry(args->dnode, NULL, true);
448 0 : bp->minimum_ttl = BFD_DEF_MHOP_TTL;
449 0 : bfd_profile_update(bp);
450 :
451 0 : return NB_OK;
452 : }
453 :
454 : /*
455 : * XPath: /frr-bfdd:bfdd/bfd/profile/echo-mode
456 : */
457 0 : int bfdd_bfd_profile_echo_mode_modify(struct nb_cb_modify_args *args)
458 : {
459 0 : struct bfd_profile *bp;
460 0 : bool echo;
461 :
462 0 : if (args->event != NB_EV_APPLY)
463 : return NB_OK;
464 :
465 0 : echo = yang_dnode_get_bool(args->dnode, NULL);
466 0 : bp = nb_running_get_entry(args->dnode, NULL, true);
467 0 : if (bp->echo_mode == echo)
468 : return NB_OK;
469 :
470 0 : bp->echo_mode = echo;
471 0 : bfd_profile_update(bp);
472 :
473 0 : return NB_OK;
474 : }
475 :
476 : /*
477 : * XPath: /frr-bfdd:bfdd/bfd/profile/desired-echo-transmission-interval
478 : */
479 0 : int bfdd_bfd_profile_desired_echo_transmission_interval_modify(
480 : struct nb_cb_modify_args *args)
481 : {
482 0 : struct bfd_profile *bp;
483 :
484 0 : switch (args->event) {
485 : case NB_EV_VALIDATE:
486 : break;
487 :
488 : case NB_EV_PREPARE:
489 : /* NOTHING */
490 : break;
491 :
492 0 : case NB_EV_APPLY:
493 0 : bp = nb_running_get_entry(args->dnode, NULL, true);
494 0 : bp->min_echo_tx = yang_dnode_get_uint32(args->dnode, NULL);
495 0 : bfd_profile_update(bp);
496 0 : break;
497 :
498 : case NB_EV_ABORT:
499 : /* NOTHING */
500 : break;
501 : }
502 :
503 0 : return NB_OK;
504 : }
505 :
506 : /*
507 : * XPath: /frr-bfdd:bfdd/bfd/profile/required-echo-receive-interval
508 : */
509 0 : int bfdd_bfd_profile_required_echo_receive_interval_modify(
510 : struct nb_cb_modify_args *args)
511 : {
512 0 : struct bfd_profile *bp;
513 :
514 0 : switch (args->event) {
515 : case NB_EV_VALIDATE:
516 : break;
517 :
518 : case NB_EV_PREPARE:
519 : /* NOTHING */
520 : break;
521 :
522 0 : case NB_EV_APPLY:
523 0 : bp = nb_running_get_entry(args->dnode, NULL, true);
524 0 : bp->min_echo_rx = yang_dnode_get_uint32(args->dnode, NULL);
525 0 : bfd_profile_update(bp);
526 0 : break;
527 :
528 : case NB_EV_ABORT:
529 : /* NOTHING */
530 : break;
531 : }
532 :
533 0 : return NB_OK;
534 : }
535 :
536 : /*
537 : * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop
538 : */
539 0 : int bfdd_bfd_sessions_single_hop_create(struct nb_cb_create_args *args)
540 : {
541 0 : return bfd_session_create(args, false);
542 : }
543 :
544 0 : int bfdd_bfd_sessions_single_hop_destroy(struct nb_cb_destroy_args *args)
545 : {
546 0 : return bfd_session_destroy(args->event, args->dnode, false);
547 : }
548 :
549 : /*
550 : * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/source-addr
551 : */
552 0 : int bfdd_bfd_sessions_single_hop_source_addr_modify(
553 : struct nb_cb_modify_args *args)
554 : {
555 0 : return NB_OK;
556 : }
557 :
558 0 : int bfdd_bfd_sessions_single_hop_source_addr_destroy(
559 : struct nb_cb_destroy_args *args)
560 : {
561 0 : return NB_OK;
562 : }
563 :
564 : /*
565 : * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/profile
566 : */
567 0 : int bfdd_bfd_sessions_single_hop_profile_modify(struct nb_cb_modify_args *args)
568 : {
569 0 : struct bfd_session *bs;
570 :
571 0 : if (args->event != NB_EV_APPLY)
572 : return NB_OK;
573 :
574 0 : bs = nb_running_get_entry(args->dnode, NULL, true);
575 0 : bfd_profile_apply(yang_dnode_get_string(args->dnode, NULL), bs);
576 :
577 0 : return NB_OK;
578 : }
579 :
580 0 : int bfdd_bfd_sessions_single_hop_profile_destroy(
581 : struct nb_cb_destroy_args *args)
582 : {
583 0 : struct bfd_session *bs;
584 :
585 0 : if (args->event != NB_EV_APPLY)
586 : return NB_OK;
587 :
588 0 : bs = nb_running_get_entry(args->dnode, NULL, true);
589 0 : bfd_profile_remove(bs);
590 :
591 0 : return NB_OK;
592 : }
593 :
594 : /*
595 : * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/detection-multiplier
596 : */
597 0 : int bfdd_bfd_sessions_single_hop_detection_multiplier_modify(
598 : struct nb_cb_modify_args *args)
599 : {
600 0 : uint8_t detection_multiplier = yang_dnode_get_uint8(args->dnode, NULL);
601 0 : struct bfd_session *bs;
602 :
603 0 : switch (args->event) {
604 : case NB_EV_VALIDATE:
605 : break;
606 :
607 : case NB_EV_PREPARE:
608 : /* NOTHING */
609 : break;
610 :
611 0 : case NB_EV_APPLY:
612 0 : bs = nb_running_get_entry(args->dnode, NULL, true);
613 0 : bs->peer_profile.detection_multiplier = detection_multiplier;
614 0 : bfd_session_apply(bs);
615 0 : break;
616 :
617 : case NB_EV_ABORT:
618 : /* NOTHING */
619 : break;
620 : }
621 :
622 0 : return NB_OK;
623 : }
624 :
625 : /*
626 : * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/desired-transmission-interval
627 : */
628 0 : int bfdd_bfd_sessions_single_hop_desired_transmission_interval_modify(
629 : struct nb_cb_modify_args *args)
630 : {
631 0 : struct bfd_session *bs;
632 :
633 0 : switch (args->event) {
634 : case NB_EV_VALIDATE:
635 : break;
636 :
637 : case NB_EV_PREPARE:
638 : /* NOTHING */
639 : break;
640 :
641 0 : case NB_EV_APPLY:
642 0 : bs = nb_running_get_entry(args->dnode, NULL, true);
643 0 : bs->peer_profile.min_tx =
644 0 : yang_dnode_get_uint32(args->dnode, NULL);
645 0 : bfd_session_apply(bs);
646 0 : break;
647 :
648 : case NB_EV_ABORT:
649 : /* NOTHING */
650 : break;
651 : }
652 :
653 0 : return NB_OK;
654 : }
655 :
656 : /*
657 : * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/required-receive-interval
658 : */
659 0 : int bfdd_bfd_sessions_single_hop_required_receive_interval_modify(
660 : struct nb_cb_modify_args *args)
661 : {
662 0 : struct bfd_session *bs;
663 :
664 0 : switch (args->event) {
665 : case NB_EV_VALIDATE:
666 : break;
667 :
668 : case NB_EV_PREPARE:
669 : /* NOTHING */
670 : break;
671 :
672 0 : case NB_EV_APPLY:
673 0 : bs = nb_running_get_entry(args->dnode, NULL, true);
674 0 : bs->peer_profile.min_rx =
675 0 : yang_dnode_get_uint32(args->dnode, NULL);
676 0 : bfd_session_apply(bs);
677 0 : break;
678 :
679 : case NB_EV_ABORT:
680 : /* NOTHING */
681 : break;
682 : }
683 :
684 0 : return NB_OK;
685 : }
686 :
687 : /*
688 : * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/administrative-down
689 : */
690 0 : int bfdd_bfd_sessions_single_hop_administrative_down_modify(
691 : struct nb_cb_modify_args *args)
692 : {
693 0 : bool shutdown = yang_dnode_get_bool(args->dnode, NULL);
694 0 : struct bfd_session *bs;
695 :
696 0 : switch (args->event) {
697 : case NB_EV_VALIDATE:
698 : case NB_EV_PREPARE:
699 : return NB_OK;
700 :
701 : case NB_EV_APPLY:
702 : break;
703 :
704 : case NB_EV_ABORT:
705 : return NB_OK;
706 : }
707 :
708 0 : bs = nb_running_get_entry(args->dnode, NULL, true);
709 0 : bs->peer_profile.admin_shutdown = shutdown;
710 0 : bfd_session_apply(bs);
711 :
712 0 : return NB_OK;
713 : }
714 :
715 : /*
716 : * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/passive-mode
717 : */
718 0 : int bfdd_bfd_sessions_single_hop_passive_mode_modify(
719 : struct nb_cb_modify_args *args)
720 : {
721 0 : struct bfd_session *bs;
722 0 : bool passive;
723 :
724 0 : switch (args->event) {
725 : case NB_EV_VALIDATE:
726 : case NB_EV_PREPARE:
727 : return NB_OK;
728 :
729 : case NB_EV_APPLY:
730 : break;
731 :
732 : case NB_EV_ABORT:
733 : return NB_OK;
734 : }
735 :
736 0 : passive = yang_dnode_get_bool(args->dnode, NULL);
737 :
738 0 : bs = nb_running_get_entry(args->dnode, NULL, true);
739 0 : bs->peer_profile.passive = passive;
740 0 : bfd_session_apply(bs);
741 :
742 0 : return NB_OK;
743 : }
744 :
745 : /*
746 : * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/echo-mode
747 : */
748 0 : int bfdd_bfd_sessions_single_hop_echo_mode_modify(
749 : struct nb_cb_modify_args *args)
750 : {
751 0 : bool echo = yang_dnode_get_bool(args->dnode, NULL);
752 0 : struct bfd_session *bs;
753 :
754 0 : switch (args->event) {
755 : case NB_EV_VALIDATE:
756 : case NB_EV_PREPARE:
757 : return NB_OK;
758 :
759 : case NB_EV_APPLY:
760 : break;
761 :
762 : case NB_EV_ABORT:
763 : return NB_OK;
764 : }
765 :
766 0 : bs = nb_running_get_entry(args->dnode, NULL, true);
767 0 : bs->peer_profile.echo_mode = echo;
768 0 : bfd_session_apply(bs);
769 :
770 0 : return NB_OK;
771 : }
772 :
773 : /*
774 : * XPath:
775 : * /frr-bfdd:bfdd/bfd/sessions/single-hop/desired-echo-transmission-interval
776 : */
777 0 : int bfdd_bfd_sessions_single_hop_desired_echo_transmission_interval_modify(
778 : struct nb_cb_modify_args *args)
779 : {
780 0 : struct bfd_session *bs;
781 :
782 0 : switch (args->event) {
783 : case NB_EV_VALIDATE:
784 : break;
785 :
786 : case NB_EV_PREPARE:
787 : /* NOTHING */
788 : break;
789 :
790 0 : case NB_EV_APPLY:
791 0 : bs = nb_running_get_entry(args->dnode, NULL, true);
792 0 : bs->peer_profile.min_echo_tx =
793 0 : yang_dnode_get_uint32(args->dnode, NULL);
794 0 : bfd_session_apply(bs);
795 0 : break;
796 :
797 : case NB_EV_ABORT:
798 : /* NOTHING */
799 : break;
800 : }
801 :
802 0 : return NB_OK;
803 : }
804 :
805 : /*
806 : * XPath:
807 : * /frr-bfdd:bfdd/bfd/sessions/single-hop/required-echo-receive-interval
808 : */
809 0 : int bfdd_bfd_sessions_single_hop_required_echo_receive_interval_modify(
810 : struct nb_cb_modify_args *args)
811 : {
812 0 : struct bfd_session *bs;
813 :
814 0 : switch (args->event) {
815 : case NB_EV_VALIDATE:
816 : break;
817 :
818 : case NB_EV_PREPARE:
819 : /* NOTHING */
820 : break;
821 :
822 0 : case NB_EV_APPLY:
823 0 : bs = nb_running_get_entry(args->dnode, NULL, true);
824 0 : bs->peer_profile.min_echo_rx =
825 0 : yang_dnode_get_uint32(args->dnode, NULL);
826 0 : bfd_session_apply(bs);
827 0 : break;
828 :
829 : case NB_EV_ABORT:
830 : /* NOTHING */
831 : break;
832 : }
833 :
834 0 : return NB_OK;
835 : }
836 :
837 : /*
838 : * XPath: /frr-bfdd:bfdd/bfd/sessions/multi-hop
839 : */
840 0 : int bfdd_bfd_sessions_multi_hop_create(struct nb_cb_create_args *args)
841 : {
842 0 : return bfd_session_create(args, true);
843 : }
844 :
845 0 : int bfdd_bfd_sessions_multi_hop_destroy(struct nb_cb_destroy_args *args)
846 : {
847 0 : return bfd_session_destroy(args->event, args->dnode, true);
848 : }
849 :
850 : /*
851 : * XPath: /frr-bfdd:bfdd/bfd/sessions/multi-hop/minimum-ttl
852 : */
853 0 : int bfdd_bfd_sessions_multi_hop_minimum_ttl_modify(
854 : struct nb_cb_modify_args *args)
855 : {
856 0 : struct bfd_session *bs;
857 :
858 0 : switch (args->event) {
859 : case NB_EV_VALIDATE:
860 : case NB_EV_PREPARE:
861 : return NB_OK;
862 :
863 : case NB_EV_APPLY:
864 : break;
865 :
866 : case NB_EV_ABORT:
867 : return NB_OK;
868 : }
869 :
870 0 : bs = nb_running_get_entry(args->dnode, NULL, true);
871 0 : bs->peer_profile.minimum_ttl = yang_dnode_get_uint8(args->dnode, NULL);
872 0 : bfd_session_apply(bs);
873 :
874 0 : return NB_OK;
875 : }
876 :
877 0 : int bfdd_bfd_sessions_multi_hop_minimum_ttl_destroy(
878 : struct nb_cb_destroy_args *args)
879 : {
880 0 : struct bfd_session *bs;
881 :
882 0 : switch (args->event) {
883 : case NB_EV_VALIDATE:
884 : case NB_EV_PREPARE:
885 : return NB_OK;
886 :
887 : case NB_EV_APPLY:
888 : break;
889 :
890 : case NB_EV_ABORT:
891 : return NB_OK;
892 : }
893 :
894 0 : bs = nb_running_get_entry(args->dnode, NULL, true);
895 0 : bs->peer_profile.minimum_ttl = BFD_DEF_MHOP_TTL;
896 0 : bfd_session_apply(bs);
897 :
898 0 : return NB_OK;
899 : }
|