]>
git.proxmox.com Git - mirror_frr.git/blob - ospfd/ospf_bfd.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * ospf_bfd.c: OSPF BFD handling routines
5 * @copyright Copyright (C) 2015 Cumulus Networks, Inc.
23 #include "ospf_asbr.h"
25 #include "ospf_lsdb.h"
26 #include "ospf_neighbor.h"
27 #include "ospf_interface.h"
30 #include "ospf_dump.h"
33 DEFINE_MTYPE_STATIC(OSPFD
, BFD_CONFIG
, "BFD configuration data");
36 * ospf_bfd_trigger_event - Neighbor is registered/deregistered with BFD when
37 * neighbor state is changed to/from 2way.
39 void ospf_bfd_trigger_event(struct ospf_neighbor
*nbr
, int old_state
, int state
)
41 if ((old_state
< NSM_TwoWay
) && (state
>= NSM_TwoWay
))
42 bfd_sess_install(nbr
->bfd_session
);
43 else if ((old_state
>= NSM_TwoWay
) && (state
< NSM_TwoWay
))
44 bfd_sess_uninstall(nbr
->bfd_session
);
47 static void ospf_bfd_session_change(struct bfd_session_params
*bsp
,
48 const struct bfd_session_status
*bss
,
51 struct ospf_neighbor
*nbr
= arg
;
53 /* BFD peer went down. */
54 if (bss
->state
== BFD_STATUS_DOWN
55 && bss
->previous_state
== BFD_STATUS_UP
) {
56 if (IS_DEBUG_OSPF(bfd
, BFD_LIB
))
57 zlog_debug("%s: NSM[%s:%pI4]: BFD Down", __func__
,
58 IF_NAME(nbr
->oi
), &nbr
->address
.u
.prefix4
);
60 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_InactivityTimer
);
63 /* BFD peer went up. */
64 if (bss
->state
== BSS_UP
&& bss
->previous_state
== BSS_DOWN
)
65 if (IS_DEBUG_OSPF(bfd
, BFD_LIB
))
66 zlog_debug("%s: NSM[%s:%pI4]: BFD Up", __func__
,
67 IF_NAME(nbr
->oi
), &nbr
->address
.u
.prefix4
);
70 void ospf_neighbor_bfd_apply(struct ospf_neighbor
*nbr
)
72 struct ospf_interface
*oi
= nbr
->oi
;
73 struct ospf_if_params
*oip
= IF_DEF_PARAMS(oi
->ifp
);
75 /* BFD configuration was removed. */
76 if (oip
->bfd_config
== NULL
) {
77 bfd_sess_free(&nbr
->bfd_session
);
81 /* New BFD session. */
82 if (nbr
->bfd_session
== NULL
) {
83 nbr
->bfd_session
= bfd_sess_new(ospf_bfd_session_change
, nbr
);
84 bfd_sess_set_ipv4_addrs(nbr
->bfd_session
, NULL
, &nbr
->src
);
85 bfd_sess_set_interface(nbr
->bfd_session
, oi
->ifp
->name
);
86 bfd_sess_set_vrf(nbr
->bfd_session
, oi
->ospf
->vrf_id
);
89 /* Set new configuration. */
90 bfd_sess_set_timers(nbr
->bfd_session
,
91 oip
->bfd_config
->detection_multiplier
,
92 oip
->bfd_config
->min_rx
, oip
->bfd_config
->min_tx
);
93 bfd_sess_set_profile(nbr
->bfd_session
, oip
->bfd_config
->profile
);
95 /* Don't start sessions on down OSPF sessions. */
96 if (nbr
->state
< NSM_TwoWay
)
99 bfd_sess_install(nbr
->bfd_session
);
102 static void ospf_interface_bfd_apply(struct interface
*ifp
)
104 struct ospf_interface
*oi
;
105 struct route_table
*nbrs
;
106 struct ospf_neighbor
*nbr
;
107 struct route_node
*irn
;
108 struct route_node
*nrn
;
110 /* Iterate over all interfaces and set neighbors BFD session. */
111 for (irn
= route_top(IF_OIFS(ifp
)); irn
; irn
= route_next(irn
)) {
112 if ((oi
= irn
->info
) == NULL
)
114 if ((nbrs
= oi
->nbrs
) == NULL
)
116 for (nrn
= route_top(nbrs
); nrn
; nrn
= route_next(nrn
)) {
117 if ((nbr
= nrn
->info
) == NULL
|| nbr
== oi
->nbr_self
)
120 ospf_neighbor_bfd_apply(nbr
);
125 static void ospf_interface_enable_bfd(struct interface
*ifp
)
127 struct ospf_if_params
*oip
= IF_DEF_PARAMS(ifp
);
132 /* Allocate memory for configurations and set defaults. */
133 oip
->bfd_config
= XCALLOC(MTYPE_BFD_CONFIG
, sizeof(*oip
->bfd_config
));
134 oip
->bfd_config
->detection_multiplier
= BFD_DEF_DETECT_MULT
;
135 oip
->bfd_config
->min_rx
= BFD_DEF_MIN_RX
;
136 oip
->bfd_config
->min_tx
= BFD_DEF_MIN_TX
;
139 void ospf_interface_disable_bfd(struct interface
*ifp
,
140 struct ospf_if_params
*oip
)
142 XFREE(MTYPE_BFD_CONFIG
, oip
->bfd_config
);
143 ospf_interface_bfd_apply(ifp
);
147 * ospf_bfd_write_config - Write the interface BFD configuration.
149 void ospf_bfd_write_config(struct vty
*vty
, const struct ospf_if_params
*params
150 __attribute__((unused
)))
153 if (params
->bfd_config
->detection_multiplier
!= BFD_DEF_DETECT_MULT
154 || params
->bfd_config
->min_rx
!= BFD_DEF_MIN_RX
155 || params
->bfd_config
->min_tx
!= BFD_DEF_MIN_TX
)
156 vty_out(vty
, " ip ospf bfd %d %d %d\n",
157 params
->bfd_config
->detection_multiplier
,
158 params
->bfd_config
->min_rx
, params
->bfd_config
->min_tx
);
160 #endif /* ! HAVE_BFDD */
161 vty_out(vty
, " ip ospf bfd\n");
163 if (params
->bfd_config
->profile
[0])
164 vty_out(vty
, " ip ospf bfd profile %s\n",
165 params
->bfd_config
->profile
);
168 void ospf_interface_bfd_show(struct vty
*vty
, const struct interface
*ifp
,
169 struct json_object
*json
)
171 struct ospf_if_params
*params
= IF_DEF_PARAMS(ifp
);
172 struct bfd_configuration
*bfd_config
= params
->bfd_config
;
173 struct json_object
*json_bfd
;
175 if (bfd_config
== NULL
)
179 json_bfd
= json_object_new_object();
180 json_object_int_add(json_bfd
, "detectionMultiplier",
181 bfd_config
->detection_multiplier
);
182 json_object_int_add(json_bfd
, "rxMinInterval",
184 json_object_int_add(json_bfd
, "txMinInterval",
186 json_object_object_add(json
, "peerBfdInfo", json_bfd
);
189 " BFD: Detect Multiplier: %d, Min Rx interval: %d, Min Tx interval: %d\n",
190 bfd_config
->detection_multiplier
, bfd_config
->min_rx
,
198 "OSPF interface commands\n"
199 "Enables BFD support\n")
201 VTY_DECLVAR_CONTEXT(interface
, ifp
);
202 ospf_interface_enable_bfd(ifp
);
203 ospf_interface_bfd_apply(ifp
);
211 #endif /* HAVE_BFDD */
213 ip_ospf_bfd_param_cmd
,
214 "ip ospf bfd (2-255) (50-60000) (50-60000)",
216 "OSPF interface commands\n"
217 "Enables BFD support\n"
218 "Detect Multiplier\n"
219 "Required min receive interval\n"
220 "Desired min transmit interval\n")
222 VTY_DECLVAR_CONTEXT(interface
, ifp
);
223 struct ospf_if_params
*params
;
225 int idx_number_2
= 4;
226 int idx_number_3
= 5;
228 ospf_interface_enable_bfd(ifp
);
230 params
= IF_DEF_PARAMS(ifp
);
231 params
->bfd_config
->detection_multiplier
=
232 strtol(argv
[idx_number
]->arg
, NULL
, 10);
233 params
->bfd_config
->min_rx
= strtol(argv
[idx_number_2
]->arg
, NULL
, 10);
234 params
->bfd_config
->min_tx
= strtol(argv
[idx_number_3
]->arg
, NULL
, 10);
236 ospf_interface_bfd_apply(ifp
);
241 DEFUN (ip_ospf_bfd_prof
,
242 ip_ospf_bfd_prof_cmd
,
243 "ip ospf bfd profile BFDPROF",
245 "OSPF interface commands\n"
246 "Enables BFD support\n"
248 BFD_PROFILE_NAME_STR
)
250 VTY_DECLVAR_CONTEXT(interface
, ifp
);
251 struct ospf_if_params
*params
;
254 params
= IF_DEF_PARAMS(ifp
);
255 if (!params
->bfd_config
) {
256 vty_out(vty
, "ip ospf bfd has not been set\n");
260 strlcpy(params
->bfd_config
->profile
, argv
[idx_prof
]->arg
,
261 sizeof(params
->bfd_config
->profile
));
262 ospf_interface_bfd_apply(ifp
);
267 DEFUN (no_ip_ospf_bfd_prof
,
268 no_ip_ospf_bfd_prof_cmd
,
269 "no ip ospf bfd profile [BFDPROF]",
272 "OSPF interface commands\n"
273 "Enables BFD support\n"
275 BFD_PROFILE_NAME_STR
)
277 VTY_DECLVAR_CONTEXT(interface
, ifp
);
278 struct ospf_if_params
*params
;
280 params
= IF_DEF_PARAMS(ifp
);
281 if (!params
->bfd_config
)
284 params
->bfd_config
->profile
[0] = 0;
285 ospf_interface_bfd_apply(ifp
);
290 DEFUN (no_ip_ospf_bfd
,
295 "no ip ospf bfd [(2-255) (50-60000) (50-60000)]",
296 #endif /* HAVE_BFDD */
299 "OSPF interface commands\n"
300 "Disables BFD support\n"
302 "Detect Multiplier\n"
303 "Required min receive interval\n"
304 "Desired min transmit interval\n"
305 #endif /* !HAVE_BFDD */
308 VTY_DECLVAR_CONTEXT(interface
, ifp
);
309 ospf_interface_disable_bfd(ifp
, IF_DEF_PARAMS(ifp
));
313 void ospf_bfd_init(struct event_loop
*tm
)
315 bfd_protocol_integration_init(zclient
, tm
);
317 /* Install BFD command */
318 install_element(INTERFACE_NODE
, &ip_ospf_bfd_cmd
);
319 install_element(INTERFACE_NODE
, &ip_ospf_bfd_param_cmd
);
320 install_element(INTERFACE_NODE
, &ip_ospf_bfd_prof_cmd
);
321 install_element(INTERFACE_NODE
, &no_ip_ospf_bfd_prof_cmd
);
322 install_element(INTERFACE_NODE
, &no_ip_ospf_bfd_cmd
);