]>
git.proxmox.com Git - mirror_frr.git/blob - ospfd/ospf_bfd.c
2 * ospf_bfd.c: OSPF BFD handling routines
4 * @copyright Copyright (C) 2015 Cumulus Networks, Inc.
6 * This file is part of GNU Zebra.
8 * GNU Zebra is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2, or (at your option) any
13 * GNU Zebra is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with this program; see the file COPYING; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
38 #include "ospf_asbr.h"
40 #include "ospf_lsdb.h"
41 #include "ospf_neighbor.h"
42 #include "ospf_interface.h"
45 #include "ospf_dump.h"
48 DEFINE_MTYPE_STATIC(OSPFD
, BFD_CONFIG
, "BFD configuration data");
51 * ospf_bfd_trigger_event - Neighbor is registered/deregistered with BFD when
52 * neighbor state is changed to/from 2way.
54 void ospf_bfd_trigger_event(struct ospf_neighbor
*nbr
, int old_state
, int state
)
56 if ((old_state
< NSM_TwoWay
) && (state
>= NSM_TwoWay
))
57 bfd_sess_install(nbr
->bfd_session
);
58 else if ((old_state
>= NSM_TwoWay
) && (state
< NSM_TwoWay
))
59 bfd_sess_uninstall(nbr
->bfd_session
);
62 static void ospf_bfd_session_change(struct bfd_session_params
*bsp
,
63 const struct bfd_session_status
*bss
,
66 struct ospf_neighbor
*nbr
= arg
;
68 /* BFD peer went down. */
69 if (bss
->state
== BFD_STATUS_DOWN
70 && bss
->previous_state
== BFD_STATUS_UP
) {
71 if (IS_DEBUG_OSPF(bfd
, BFD_LIB
))
72 zlog_debug("%s: NSM[%s:%pI4]: BFD Down", __func__
,
73 IF_NAME(nbr
->oi
), &nbr
->address
.u
.prefix4
);
75 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_InactivityTimer
);
78 /* BFD peer went up. */
79 if (bss
->state
== BSS_UP
&& bss
->previous_state
== BSS_DOWN
)
80 if (IS_DEBUG_OSPF(bfd
, BFD_LIB
))
81 zlog_debug("%s: NSM[%s:%pI4]: BFD Up", __func__
,
82 IF_NAME(nbr
->oi
), &nbr
->address
.u
.prefix4
);
85 void ospf_neighbor_bfd_apply(struct ospf_neighbor
*nbr
)
87 struct ospf_interface
*oi
= nbr
->oi
;
88 struct ospf_if_params
*oip
= IF_DEF_PARAMS(oi
->ifp
);
90 /* BFD configuration was removed. */
91 if (oip
->bfd_config
== NULL
) {
92 bfd_sess_free(&nbr
->bfd_session
);
96 /* New BFD session. */
97 if (nbr
->bfd_session
== NULL
) {
98 nbr
->bfd_session
= bfd_sess_new(ospf_bfd_session_change
, nbr
);
99 bfd_sess_set_ipv4_addrs(nbr
->bfd_session
, NULL
, &nbr
->src
);
100 bfd_sess_set_interface(nbr
->bfd_session
, oi
->ifp
->name
);
101 bfd_sess_set_vrf(nbr
->bfd_session
, oi
->ospf
->vrf_id
);
102 bfd_sess_enable(nbr
->bfd_session
, true);
105 /* Set new configuration. */
106 bfd_sess_set_timers(nbr
->bfd_session
,
107 oip
->bfd_config
->detection_multiplier
,
108 oip
->bfd_config
->min_rx
, oip
->bfd_config
->min_tx
);
109 bfd_sess_set_profile(nbr
->bfd_session
, oip
->bfd_config
->profile
);
111 /* Don't start sessions on down OSPF sessions. */
112 if (nbr
->state
< NSM_TwoWay
)
115 bfd_sess_install(nbr
->bfd_session
);
118 static void ospf_interface_bfd_apply(struct interface
*ifp
)
120 struct ospf_interface
*oi
;
121 struct route_table
*nbrs
;
122 struct ospf_neighbor
*nbr
;
123 struct route_node
*irn
;
124 struct route_node
*nrn
;
126 /* Iterate over all interfaces and set neighbors BFD session. */
127 for (irn
= route_top(IF_OIFS(ifp
)); irn
; irn
= route_next(irn
)) {
128 if ((oi
= irn
->info
) == NULL
)
130 if ((nbrs
= oi
->nbrs
) == NULL
)
132 for (nrn
= route_top(nbrs
); nrn
; nrn
= route_next(nrn
)) {
133 if ((nbr
= nrn
->info
) == NULL
|| nbr
== oi
->nbr_self
)
136 ospf_neighbor_bfd_apply(nbr
);
141 static void ospf_interface_enable_bfd(struct interface
*ifp
)
143 struct ospf_if_params
*oip
= IF_DEF_PARAMS(ifp
);
148 /* Allocate memory for configurations and set defaults. */
149 oip
->bfd_config
= XCALLOC(MTYPE_BFD_CONFIG
, sizeof(*oip
->bfd_config
));
150 oip
->bfd_config
->detection_multiplier
= BFD_DEF_DETECT_MULT
;
151 oip
->bfd_config
->min_rx
= BFD_DEF_MIN_RX
;
152 oip
->bfd_config
->min_tx
= BFD_DEF_MIN_TX
;
155 void ospf_interface_disable_bfd(struct interface
*ifp
,
156 struct ospf_if_params
*oip
)
158 XFREE(MTYPE_BFD_CONFIG
, oip
->bfd_config
);
159 ospf_interface_bfd_apply(ifp
);
163 * ospf_bfd_write_config - Write the interface BFD configuration.
165 void ospf_bfd_write_config(struct vty
*vty
, const struct ospf_if_params
*params
166 __attribute__((unused
)))
169 if (params
->bfd_config
->detection_multiplier
!= BFD_DEF_DETECT_MULT
170 || params
->bfd_config
->min_rx
!= BFD_DEF_MIN_RX
171 || params
->bfd_config
->min_tx
!= BFD_DEF_MIN_TX
)
172 vty_out(vty
, " ip ospf bfd %d %d %d\n",
173 params
->bfd_config
->detection_multiplier
,
174 params
->bfd_config
->min_rx
, params
->bfd_config
->min_tx
);
176 #endif /* ! HAVE_BFDD */
177 vty_out(vty
, " ip ospf bfd\n");
179 if (params
->bfd_config
->profile
[0])
180 vty_out(vty
, " ip ospf bfd profile %s\n",
181 params
->bfd_config
->profile
);
184 void ospf_interface_bfd_show(struct vty
*vty
, const struct interface
*ifp
,
185 struct json_object
*json
)
187 struct ospf_if_params
*params
= IF_DEF_PARAMS(ifp
);
188 struct bfd_configuration
*bfd_config
= params
->bfd_config
;
189 struct json_object
*json_bfd
;
191 if (bfd_config
== NULL
)
195 json_bfd
= json_object_new_object();
196 json_object_int_add(json_bfd
, "detectionMultiplier",
197 bfd_config
->detection_multiplier
);
198 json_object_int_add(json_bfd
, "rxMinInterval",
200 json_object_int_add(json_bfd
, "txMinInterval",
202 json_object_object_add(json
, "peerBfdInfo", json_bfd
);
205 " BFD: Detect Multiplier: %d, Min Rx interval: %d, Min Tx interval: %d\n",
206 bfd_config
->detection_multiplier
, bfd_config
->min_rx
,
214 "OSPF interface commands\n"
215 "Enables BFD support\n")
217 VTY_DECLVAR_CONTEXT(interface
, ifp
);
218 ospf_interface_enable_bfd(ifp
);
219 ospf_interface_bfd_apply(ifp
);
227 #endif /* HAVE_BFDD */
229 ip_ospf_bfd_param_cmd
,
230 "ip ospf bfd (2-255) (50-60000) (50-60000)",
232 "OSPF interface commands\n"
233 "Enables BFD support\n"
234 "Detect Multiplier\n"
235 "Required min receive interval\n"
236 "Desired min transmit interval\n")
238 VTY_DECLVAR_CONTEXT(interface
, ifp
);
239 struct ospf_if_params
*params
;
241 int idx_number_2
= 4;
242 int idx_number_3
= 5;
244 ospf_interface_enable_bfd(ifp
);
246 params
= IF_DEF_PARAMS(ifp
);
247 params
->bfd_config
->detection_multiplier
=
248 strtol(argv
[idx_number
]->arg
, NULL
, 10);
249 params
->bfd_config
->min_rx
= strtol(argv
[idx_number_2
]->arg
, NULL
, 10);
250 params
->bfd_config
->min_tx
= strtol(argv
[idx_number_3
]->arg
, NULL
, 10);
252 ospf_interface_bfd_apply(ifp
);
257 DEFUN (ip_ospf_bfd_prof
,
258 ip_ospf_bfd_prof_cmd
,
259 "ip ospf bfd profile BFDPROF",
261 "OSPF interface commands\n"
262 "Enables BFD support\n"
264 BFD_PROFILE_NAME_STR
)
266 VTY_DECLVAR_CONTEXT(interface
, ifp
);
267 struct ospf_if_params
*params
;
270 ospf_interface_enable_bfd(ifp
);
271 params
= IF_DEF_PARAMS(ifp
);
272 strlcpy(params
->bfd_config
->profile
, argv
[idx_prof
]->arg
,
273 sizeof(params
->bfd_config
->profile
));
274 ospf_interface_bfd_apply(ifp
);
279 DEFUN (no_ip_ospf_bfd_prof
,
280 no_ip_ospf_bfd_prof_cmd
,
281 "no ip ospf bfd profile [BFDPROF]",
284 "OSPF interface commands\n"
285 "Enables BFD support\n"
287 BFD_PROFILE_NAME_STR
)
289 VTY_DECLVAR_CONTEXT(interface
, ifp
);
290 struct ospf_if_params
*params
;
292 ospf_interface_enable_bfd(ifp
);
293 params
= IF_DEF_PARAMS(ifp
);
294 params
->bfd_config
->profile
[0] = 0;
295 ospf_interface_bfd_apply(ifp
);
300 DEFUN (no_ip_ospf_bfd
,
305 "no ip ospf bfd [(2-255) (50-60000) (50-60000)]",
306 #endif /* HAVE_BFDD */
309 "OSPF interface commands\n"
310 "Disables BFD support\n"
312 "Detect Multiplier\n"
313 "Required min receive interval\n"
314 "Desired min transmit interval\n"
315 #endif /* !HAVE_BFDD */
318 VTY_DECLVAR_CONTEXT(interface
, ifp
);
319 ospf_interface_disable_bfd(ifp
, IF_DEF_PARAMS(ifp
));
323 void ospf_bfd_init(struct thread_master
*tm
)
325 bfd_protocol_integration_init(zclient
, tm
);
327 /* Install BFD command */
328 install_element(INTERFACE_NODE
, &ip_ospf_bfd_cmd
);
329 install_element(INTERFACE_NODE
, &ip_ospf_bfd_param_cmd
);
330 install_element(INTERFACE_NODE
, &ip_ospf_bfd_prof_cmd
);
331 install_element(INTERFACE_NODE
, &no_ip_ospf_bfd_prof_cmd
);
332 install_element(INTERFACE_NODE
, &no_ip_ospf_bfd_cmd
);