]>
git.proxmox.com Git - mirror_frr.git/blob - bfdd/bfdd_nb_config.c
2 * BFD daemon northbound implementation.
4 * Copyright (C) 2019 Network Device Education Foundation, Inc. ("NetDEF")
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.
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.
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
26 #include "lib/northbound.h"
34 static void bfd_session_get_key(bool mhop
, const struct lyd_node
*dnode
,
37 const char *ifname
= NULL
, *vrfname
= NULL
;
38 struct sockaddr_any psa
, lsa
;
40 /* Required destination parameter. */
41 strtosa(yang_dnode_get_string(dnode
, "./dest-addr"), &psa
);
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
);
48 ifname
= yang_dnode_get_string(dnode
, "./interface");
49 vrfname
= yang_dnode_get_string(dnode
, "./vrf");
51 if (strcmp(ifname
, "*") == 0)
54 /* Generate the corresponding key. */
55 gen_bfd_key(bk
, &psa
, &lsa
, mhop
, ifname
, vrfname
);
58 static int bfd_session_create(struct nb_cb_create_args
*args
, bool mhop
)
60 struct bfd_session
*bs
;
65 switch (args
->event
) {
68 * When `dest-addr` is IPv6 and link-local we must
69 * require interface name, otherwise we can't figure
70 * which interface to use to send the packets.
72 yang_dnode_get_prefix(&p
, args
->dnode
, "./dest-addr");
74 ifname
= yang_dnode_get_string(args
->dnode
, "./interface");
76 if (p
.family
== AF_INET6
&& IN6_IS_ADDR_LINKLOCAL(&p
.u
.prefix6
)
77 && strcmp(ifname
, "*") == 0) {
79 args
->errmsg
, args
->errmsg_len
,
80 "When using link-local you must specify an interface");
81 return NB_ERR_VALIDATION
;
86 bfd_session_get_key(mhop
, args
->dnode
, &bk
);
87 bs
= bfd_key_lookup(bk
);
89 /* This session was already configured by another daemon. */
91 /* Now it is configured also by CLI. */
92 SET_FLAG(bs
->flags
, BFD_SESS_FLAG_CONFIG
);
95 args
->resource
->ptr
= bs
;
99 bs
= bfd_session_new();
101 /* Fill the session key. */
102 bfd_session_get_key(mhop
, args
->dnode
, &bs
->key
);
104 /* Set configuration flags. */
106 SET_FLAG(bs
->flags
, BFD_SESS_FLAG_CONFIG
);
108 SET_FLAG(bs
->flags
, BFD_SESS_FLAG_MH
);
109 if (bs
->key
.family
== AF_INET6
)
110 SET_FLAG(bs
->flags
, BFD_SESS_FLAG_IPV6
);
112 args
->resource
->ptr
= bs
;
116 bs
= args
->resource
->ptr
;
118 /* Only attempt to registrate if freshly allocated. */
119 if (bs
->discrs
.my_discr
== 0 && bs_registrate(bs
) == NULL
)
120 return NB_ERR_RESOURCE
;
122 nb_running_set_entry(args
->dnode
, bs
);
126 bs
= args
->resource
->ptr
;
127 if (bs
->refcount
<= 1)
128 bfd_session_free(bs
);
135 static int bfd_session_destroy(enum nb_event event
,
136 const struct lyd_node
*dnode
, bool mhop
)
138 struct bfd_session
*bs
;
143 bfd_session_get_key(mhop
, dnode
, &bk
);
144 if (bfd_key_lookup(bk
) == NULL
)
145 return NB_ERR_INCONSISTENCY
;
153 bs
= nb_running_unset_entry(dnode
);
154 /* CLI is not using this session anymore. */
155 if (CHECK_FLAG(bs
->flags
, BFD_SESS_FLAG_CONFIG
) == 0)
158 UNSET_FLAG(bs
->flags
, BFD_SESS_FLAG_CONFIG
);
160 /* There are still daemons using it. */
161 if (bs
->refcount
> 0)
164 bfd_session_free(bs
);
176 * XPath: /frr-bfdd:bfdd/bfd
178 int bfdd_bfd_create(struct nb_cb_create_args
*args
)
184 int bfdd_bfd_destroy(struct nb_cb_destroy_args
*args
)
186 switch (args
->event
) {
196 bfd_sessions_remove_manual();
208 * XPath: /frr-bfdd:bfdd/bfd/profile
210 int bfdd_bfd_profile_create(struct nb_cb_create_args
*args
)
212 struct bfd_profile
*bp
;
215 if (args
->event
!= NB_EV_APPLY
)
218 name
= yang_dnode_get_string(args
->dnode
, "./name");
219 bp
= bfd_profile_new(name
);
220 nb_running_set_entry(args
->dnode
, bp
);
225 int bfdd_bfd_profile_destroy(struct nb_cb_destroy_args
*args
)
227 struct bfd_profile
*bp
;
229 if (args
->event
!= NB_EV_APPLY
)
232 bp
= nb_running_unset_entry(args
->dnode
);
233 bfd_profile_free(bp
);
239 * XPath: /frr-bfdd:bfdd/bfd/profile/detection-multiplier
241 int bfdd_bfd_profile_detection_multiplier_modify(struct nb_cb_modify_args
*args
)
243 struct bfd_profile
*bp
;
245 if (args
->event
!= NB_EV_APPLY
)
248 bp
= nb_running_get_entry(args
->dnode
, NULL
, true);
249 bp
->detection_multiplier
= yang_dnode_get_uint8(args
->dnode
, NULL
);
250 bfd_profile_update(bp
);
256 * XPath: /frr-bfdd:bfdd/bfd/profile/desired-transmission-interval
258 int bfdd_bfd_profile_desired_transmission_interval_modify(
259 struct nb_cb_modify_args
*args
)
261 struct bfd_profile
*bp
;
264 switch (args
->event
) {
266 min_tx
= yang_dnode_get_uint32(args
->dnode
, NULL
);
267 if (min_tx
< 10000 || min_tx
> 60000000)
268 return NB_ERR_VALIDATION
;
276 min_tx
= yang_dnode_get_uint32(args
->dnode
, NULL
);
277 bp
= nb_running_get_entry(args
->dnode
, NULL
, true);
278 if (bp
->min_tx
== min_tx
)
282 bfd_profile_update(bp
);
294 * XPath: /frr-bfdd:bfdd/bfd/profile/required-receive-interval
296 int bfdd_bfd_profile_required_receive_interval_modify(
297 struct nb_cb_modify_args
*args
)
299 struct bfd_profile
*bp
;
302 switch (args
->event
) {
304 min_rx
= yang_dnode_get_uint32(args
->dnode
, NULL
);
305 if (min_rx
< 10000 || min_rx
> 60000000)
306 return NB_ERR_VALIDATION
;
314 min_rx
= yang_dnode_get_uint32(args
->dnode
, NULL
);
315 bp
= nb_running_get_entry(args
->dnode
, NULL
, true);
316 if (bp
->min_rx
== min_rx
)
320 bfd_profile_update(bp
);
332 * XPath: /frr-bfdd:bfdd/bfd/profile/administrative-down
334 int bfdd_bfd_profile_administrative_down_modify(struct nb_cb_modify_args
*args
)
336 struct bfd_profile
*bp
;
339 if (args
->event
!= NB_EV_APPLY
)
342 shutdown
= yang_dnode_get_bool(args
->dnode
, NULL
);
343 bp
= nb_running_get_entry(args
->dnode
, NULL
, true);
344 if (bp
->admin_shutdown
== shutdown
)
347 bp
->admin_shutdown
= shutdown
;
348 bfd_profile_update(bp
);
354 * XPath: /frr-bfdd:bfdd/bfd/profile/passive-mode
356 int bfdd_bfd_profile_passive_mode_modify(struct nb_cb_modify_args
*args
)
358 struct bfd_profile
*bp
;
361 if (args
->event
!= NB_EV_APPLY
)
364 passive
= yang_dnode_get_bool(args
->dnode
, NULL
);
365 bp
= nb_running_get_entry(args
->dnode
, NULL
, true);
366 if (bp
->passive
== passive
)
369 bp
->passive
= passive
;
370 bfd_profile_update(bp
);
376 * XPath: /frr-bfdd:bfdd/bfd/profile/minimum-ttl
378 int bfdd_bfd_profile_minimum_ttl_modify(struct nb_cb_modify_args
*args
)
380 struct bfd_profile
*bp
;
383 if (args
->event
!= NB_EV_APPLY
)
386 minimum_ttl
= yang_dnode_get_uint8(args
->dnode
, NULL
);
387 bp
= nb_running_get_entry(args
->dnode
, NULL
, true);
388 if (bp
->minimum_ttl
== minimum_ttl
)
391 bp
->minimum_ttl
= minimum_ttl
;
392 bfd_profile_update(bp
);
397 int bfdd_bfd_profile_minimum_ttl_destroy(struct nb_cb_destroy_args
*args
)
399 struct bfd_profile
*bp
;
401 if (args
->event
!= NB_EV_APPLY
)
404 bp
= nb_running_get_entry(args
->dnode
, NULL
, true);
405 bp
->minimum_ttl
= BFD_DEF_MHOP_TTL
;
406 bfd_profile_update(bp
);
412 * XPath: /frr-bfdd:bfdd/bfd/profile/echo-mode
414 int bfdd_bfd_profile_echo_mode_modify(struct nb_cb_modify_args
*args
)
416 struct bfd_profile
*bp
;
419 if (args
->event
!= NB_EV_APPLY
)
422 echo
= yang_dnode_get_bool(args
->dnode
, NULL
);
423 bp
= nb_running_get_entry(args
->dnode
, NULL
, true);
424 if (bp
->echo_mode
== echo
)
427 bp
->echo_mode
= echo
;
428 bfd_profile_update(bp
);
434 * XPath: /frr-bfdd:bfdd/bfd/profile/desired-echo-echo-transmission-interval
436 int bfdd_bfd_profile_desired_echo_transmission_interval_modify(
437 struct nb_cb_modify_args
*args
)
439 struct bfd_profile
*bp
;
442 switch (args
->event
) {
444 min_rx
= yang_dnode_get_uint32(args
->dnode
, NULL
);
445 if (min_rx
< 10000 || min_rx
> 60000000)
446 return NB_ERR_VALIDATION
;
454 min_rx
= yang_dnode_get_uint32(args
->dnode
, NULL
);
455 bp
= nb_running_get_entry(args
->dnode
, NULL
, true);
456 if (bp
->min_echo_rx
== min_rx
)
459 bp
->min_echo_rx
= min_rx
;
460 bfd_profile_update(bp
);
472 * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop
474 int bfdd_bfd_sessions_single_hop_create(struct nb_cb_create_args
*args
)
476 return bfd_session_create(args
, false);
479 int bfdd_bfd_sessions_single_hop_destroy(struct nb_cb_destroy_args
*args
)
481 return bfd_session_destroy(args
->event
, args
->dnode
, false);
485 * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/source-addr
487 int bfdd_bfd_sessions_single_hop_source_addr_modify(
488 struct nb_cb_modify_args
*args
)
493 int bfdd_bfd_sessions_single_hop_source_addr_destroy(
494 struct nb_cb_destroy_args
*args
)
500 * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/profile
502 int bfdd_bfd_sessions_single_hop_profile_modify(struct nb_cb_modify_args
*args
)
504 struct bfd_session
*bs
;
506 if (args
->event
!= NB_EV_APPLY
)
509 bs
= nb_running_get_entry(args
->dnode
, NULL
, true);
510 bfd_profile_apply(yang_dnode_get_string(args
->dnode
, NULL
), bs
);
515 int bfdd_bfd_sessions_single_hop_profile_destroy(
516 struct nb_cb_destroy_args
*args
)
518 struct bfd_session
*bs
;
520 if (args
->event
!= NB_EV_APPLY
)
523 bs
= nb_running_get_entry(args
->dnode
, NULL
, true);
524 bfd_profile_remove(bs
);
530 * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/detection-multiplier
532 int bfdd_bfd_sessions_single_hop_detection_multiplier_modify(
533 struct nb_cb_modify_args
*args
)
535 uint8_t detection_multiplier
= yang_dnode_get_uint8(args
->dnode
, NULL
);
536 struct bfd_session
*bs
;
538 switch (args
->event
) {
547 bs
= nb_running_get_entry(args
->dnode
, NULL
, true);
548 bs
->peer_profile
.detection_multiplier
= detection_multiplier
;
549 bfd_session_apply(bs
);
561 * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/desired-transmission-interval
563 int bfdd_bfd_sessions_single_hop_desired_transmission_interval_modify(
564 struct nb_cb_modify_args
*args
)
566 uint32_t tx_interval
= yang_dnode_get_uint32(args
->dnode
, NULL
);
567 struct bfd_session
*bs
;
569 switch (args
->event
) {
571 if (tx_interval
< 10000 || tx_interval
> 60000000)
572 return NB_ERR_VALIDATION
;
580 bs
= nb_running_get_entry(args
->dnode
, NULL
, true);
581 if (tx_interval
== bs
->timers
.desired_min_tx
)
584 bs
->peer_profile
.min_tx
= tx_interval
;
585 bfd_session_apply(bs
);
597 * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/required-receive-interval
599 int bfdd_bfd_sessions_single_hop_required_receive_interval_modify(
600 struct nb_cb_modify_args
*args
)
602 uint32_t rx_interval
= yang_dnode_get_uint32(args
->dnode
, NULL
);
603 struct bfd_session
*bs
;
605 switch (args
->event
) {
607 if (rx_interval
< 10000 || rx_interval
> 60000000)
608 return NB_ERR_VALIDATION
;
616 bs
= nb_running_get_entry(args
->dnode
, NULL
, true);
617 if (rx_interval
== bs
->timers
.required_min_rx
)
620 bs
->peer_profile
.min_rx
= rx_interval
;
621 bfd_session_apply(bs
);
633 * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/administrative-down
635 int bfdd_bfd_sessions_single_hop_administrative_down_modify(
636 struct nb_cb_modify_args
*args
)
638 bool shutdown
= yang_dnode_get_bool(args
->dnode
, NULL
);
639 struct bfd_session
*bs
;
641 switch (args
->event
) {
653 bs
= nb_running_get_entry(args
->dnode
, NULL
, true);
654 bs
->peer_profile
.admin_shutdown
= shutdown
;
655 bfd_session_apply(bs
);
661 * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/passive-mode
663 int bfdd_bfd_sessions_single_hop_passive_mode_modify(
664 struct nb_cb_modify_args
*args
)
666 struct bfd_session
*bs
;
669 switch (args
->event
) {
681 passive
= yang_dnode_get_bool(args
->dnode
, NULL
);
683 bs
= nb_running_get_entry(args
->dnode
, NULL
, true);
684 bs
->peer_profile
.passive
= passive
;
685 bfd_session_apply(bs
);
691 * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/echo-mode
693 int bfdd_bfd_sessions_single_hop_echo_mode_modify(
694 struct nb_cb_modify_args
*args
)
696 bool echo
= yang_dnode_get_bool(args
->dnode
, NULL
);
697 struct bfd_session
*bs
;
699 switch (args
->event
) {
711 bs
= nb_running_get_entry(args
->dnode
, NULL
, true);
712 bs
->peer_profile
.echo_mode
= echo
;
713 bfd_session_apply(bs
);
720 * /frr-bfdd:bfdd/bfd/sessions/single-hop/desired-echo-transmission-interval
722 int bfdd_bfd_sessions_single_hop_desired_echo_transmission_interval_modify(
723 struct nb_cb_modify_args
*args
)
725 uint32_t echo_interval
= yang_dnode_get_uint32(args
->dnode
, NULL
);
726 struct bfd_session
*bs
;
728 switch (args
->event
) {
730 if (echo_interval
< 10000 || echo_interval
> 60000000)
731 return NB_ERR_VALIDATION
;
739 bs
= nb_running_get_entry(args
->dnode
, NULL
, true);
740 if (echo_interval
== bs
->timers
.required_min_echo
)
743 bs
->peer_profile
.min_echo_rx
= echo_interval
;
744 bfd_session_apply(bs
);
756 * XPath: /frr-bfdd:bfdd/bfd/sessions/multi-hop
758 int bfdd_bfd_sessions_multi_hop_create(struct nb_cb_create_args
*args
)
760 return bfd_session_create(args
, true);
763 int bfdd_bfd_sessions_multi_hop_destroy(struct nb_cb_destroy_args
*args
)
765 return bfd_session_destroy(args
->event
, args
->dnode
, true);
769 * XPath: /frr-bfdd:bfdd/bfd/sessions/multi-hop/minimum-ttl
771 int bfdd_bfd_sessions_multi_hop_minimum_ttl_modify(
772 struct nb_cb_modify_args
*args
)
774 struct bfd_session
*bs
;
776 switch (args
->event
) {
788 bs
= nb_running_get_entry(args
->dnode
, NULL
, true);
789 bs
->peer_profile
.minimum_ttl
= yang_dnode_get_uint8(args
->dnode
, NULL
);
790 bfd_session_apply(bs
);
795 int bfdd_bfd_sessions_multi_hop_minimum_ttl_destroy(
796 struct nb_cb_destroy_args
*args
)
798 struct bfd_session
*bs
;
800 switch (args
->event
) {
812 bs
= nb_running_get_entry(args
->dnode
, NULL
, true);
813 bs
->peer_profile
.minimum_ttl
= BFD_DEF_MHOP_TTL
;
814 bfd_session_apply(bs
);