]> git.proxmox.com Git - mirror_frr.git/blame - ospfd/ospf_bfd.c
*: Convert event.h to frrevent.h
[mirror_frr.git] / ospfd / ospf_bfd.c
CommitLineData
acddc0ed 1// SPDX-License-Identifier: GPL-2.0-or-later
7f342629
DS
2/**
3 * ospf_bfd.c: OSPF BFD handling routines
4 *
5 * @copyright Copyright (C) 2015 Cumulus Networks, Inc.
7f342629
DS
6 */
7
8#include <zebra.h>
9
10#include "command.h"
659f4e40 11#include "json.h"
7f342629
DS
12#include "linklist.h"
13#include "memory.h"
14#include "prefix.h"
24a58196 15#include "frrevent.h"
7f342629
DS
16#include "buffer.h"
17#include "stream.h"
18#include "zclient.h"
19#include "vty.h"
20#include "table.h"
21#include "bfd.h"
22#include "ospfd.h"
23#include "ospf_asbr.h"
24#include "ospf_lsa.h"
25#include "ospf_lsdb.h"
26#include "ospf_neighbor.h"
27#include "ospf_interface.h"
28#include "ospf_nsm.h"
29#include "ospf_bfd.h"
30#include "ospf_dump.h"
31#include "ospf_vty.h"
32
659f4e40 33DEFINE_MTYPE_STATIC(OSPFD, BFD_CONFIG, "BFD configuration data");
d62a17ae 34
7f342629
DS
35/*
36 * ospf_bfd_trigger_event - Neighbor is registered/deregistered with BFD when
37 * neighbor state is changed to/from 2way.
38 */
d62a17ae 39void ospf_bfd_trigger_event(struct ospf_neighbor *nbr, int old_state, int state)
7f342629 40{
d62a17ae 41 if ((old_state < NSM_TwoWay) && (state >= NSM_TwoWay))
659f4e40 42 bfd_sess_install(nbr->bfd_session);
d62a17ae 43 else if ((old_state >= NSM_TwoWay) && (state < NSM_TwoWay))
659f4e40 44 bfd_sess_uninstall(nbr->bfd_session);
7f342629
DS
45}
46
659f4e40
RZ
47static void ospf_bfd_session_change(struct bfd_session_params *bsp,
48 const struct bfd_session_status *bss,
49 void *arg)
7f342629 50{
659f4e40 51 struct ospf_neighbor *nbr = arg;
d62a17ae 52
659f4e40
RZ
53 /* BFD peer went down. */
54 if (bss->state == BFD_STATUS_DOWN
55 && bss->previous_state == BFD_STATUS_UP) {
e4505a2e
RZ
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);
d62a17ae 59
659f4e40 60 OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_InactivityTimer);
d62a17ae 61 }
62
659f4e40
RZ
63 /* BFD peer went up. */
64 if (bss->state == BSS_UP && bss->previous_state == BSS_DOWN)
e4505a2e
RZ
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);
7f342629
DS
68}
69
659f4e40 70void ospf_neighbor_bfd_apply(struct ospf_neighbor *nbr)
7f342629 71{
659f4e40
RZ
72 struct ospf_interface *oi = nbr->oi;
73 struct ospf_if_params *oip = IF_DEF_PARAMS(oi->ifp);
d62a17ae 74
659f4e40
RZ
75 /* BFD configuration was removed. */
76 if (oip->bfd_config == NULL) {
77 bfd_sess_free(&nbr->bfd_session);
78 return;
d62a17ae 79 }
80
659f4e40
RZ
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);
659f4e40 87 }
d62a17ae 88
659f4e40
RZ
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);
d62a17ae 94
659f4e40
RZ
95 /* Don't start sessions on down OSPF sessions. */
96 if (nbr->state < NSM_TwoWay)
97 return;
d62a17ae 98
659f4e40 99 bfd_sess_install(nbr->bfd_session);
7f342629
DS
100}
101
659f4e40 102static void ospf_interface_bfd_apply(struct interface *ifp)
7f342629 103{
d62a17ae 104 struct ospf_interface *oi;
659f4e40
RZ
105 struct route_table *nbrs;
106 struct ospf_neighbor *nbr;
107 struct route_node *irn;
108 struct route_node *nrn;
6e641a8f 109
659f4e40
RZ
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)
d62a17ae 113 continue;
659f4e40 114 if ((nbrs = oi->nbrs) == NULL)
d62a17ae 115 continue;
659f4e40
RZ
116 for (nrn = route_top(nbrs); nrn; nrn = route_next(nrn)) {
117 if ((nbr = nrn->info) == NULL || nbr == oi->nbr_self)
118 continue;
d62a17ae 119
659f4e40 120 ospf_neighbor_bfd_apply(nbr);
4828ea77 121 }
d62a17ae 122 }
7f342629
DS
123}
124
659f4e40 125static void ospf_interface_enable_bfd(struct interface *ifp)
68fe91d6 126{
659f4e40 127 struct ospf_if_params *oip = IF_DEF_PARAMS(ifp);
d62a17ae 128
659f4e40 129 if (oip->bfd_config)
d62a17ae 130 return;
131
659f4e40
RZ
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;
137}
d62a17ae 138
659f4e40
RZ
139void ospf_interface_disable_bfd(struct interface *ifp,
140 struct ospf_if_params *oip)
141{
142 XFREE(MTYPE_BFD_CONFIG, oip->bfd_config);
143 ospf_interface_bfd_apply(ifp);
68fe91d6 144}
145
7f342629
DS
146/*
147 * ospf_bfd_write_config - Write the interface BFD configuration.
148 */
659f4e40
RZ
149void ospf_bfd_write_config(struct vty *vty, const struct ospf_if_params *params
150 __attribute__((unused)))
7f342629 151{
a0841732 152#if HAVE_BFDD == 0
69b34634
IR
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)
659f4e40
RZ
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);
d62a17ae 159 else
a0841732 160#endif /* ! HAVE_BFDD */
d62a17ae 161 vty_out(vty, " ip ospf bfd\n");
96b52510
RZ
162
163 if (params->bfd_config->profile[0])
164 vty_out(vty, " ip ospf bfd profile %s\n",
165 params->bfd_config->profile);
7f342629
DS
166}
167
659f4e40
RZ
168void ospf_interface_bfd_show(struct vty *vty, const struct interface *ifp,
169 struct json_object *json)
68fe91d6 170{
659f4e40
RZ
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;
7f342629 174
659f4e40
RZ
175 if (bfd_config == NULL)
176 return;
7f342629 177
659f4e40
RZ
178 if (json) {
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",
183 bfd_config->min_rx);
184 json_object_int_add(json_bfd, "txMinInterval",
185 bfd_config->min_tx);
186 json_object_object_add(json, "peerBfdInfo", json_bfd);
187 } else
188 vty_out(vty,
189 " BFD: Detect Multiplier: %d, Min Rx interval: %d, Min Tx interval: %d\n",
190 bfd_config->detection_multiplier, bfd_config->min_rx,
191 bfd_config->min_tx);
7f342629
DS
192}
193
7f342629
DS
194DEFUN (ip_ospf_bfd,
195 ip_ospf_bfd_cmd,
196 "ip ospf bfd",
197 "IP Information\n"
198 "OSPF interface commands\n"
199 "Enables BFD support\n")
200{
d62a17ae 201 VTY_DECLVAR_CONTEXT(interface, ifp);
659f4e40
RZ
202 ospf_interface_enable_bfd(ifp);
203 ospf_interface_bfd_apply(ifp);
d62a17ae 204 return CMD_SUCCESS;
7f342629
DS
205}
206
64dc4b2d
RZ
207#if HAVE_BFDD > 0
208DEFUN_HIDDEN(
209#else
210DEFUN(
211#endif /* HAVE_BFDD */
212 ip_ospf_bfd_param,
7f342629 213 ip_ospf_bfd_param_cmd,
9ccf14f7 214 "ip ospf bfd (2-255) (50-60000) (50-60000)",
7f342629
DS
215 "IP Information\n"
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")
221{
d62a17ae 222 VTY_DECLVAR_CONTEXT(interface, ifp);
659f4e40 223 struct ospf_if_params *params;
d62a17ae 224 int idx_number = 3;
225 int idx_number_2 = 4;
226 int idx_number_3 = 5;
d62a17ae 227
659f4e40 228 ospf_interface_enable_bfd(ifp);
d62a17ae 229
659f4e40
RZ
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);
d62a17ae 235
659f4e40 236 ospf_interface_bfd_apply(ifp);
d62a17ae 237
238 return CMD_SUCCESS;
7f342629
DS
239}
240
96b52510
RZ
241DEFUN (ip_ospf_bfd_prof,
242 ip_ospf_bfd_prof_cmd,
243 "ip ospf bfd profile BFDPROF",
244 "IP Information\n"
245 "OSPF interface commands\n"
246 "Enables BFD support\n"
247 BFD_PROFILE_STR
248 BFD_PROFILE_NAME_STR)
249{
250 VTY_DECLVAR_CONTEXT(interface, ifp);
251 struct ospf_if_params *params;
252 int idx_prof = 4;
253
96b52510 254 params = IF_DEF_PARAMS(ifp);
f3fd7196
DT
255 if (!params->bfd_config) {
256 vty_out(vty, "ip ospf bfd has not been set\n");
257 return CMD_WARNING;
258 }
259
96b52510
RZ
260 strlcpy(params->bfd_config->profile, argv[idx_prof]->arg,
261 sizeof(params->bfd_config->profile));
262 ospf_interface_bfd_apply(ifp);
263
264 return CMD_SUCCESS;
265}
266
267DEFUN (no_ip_ospf_bfd_prof,
268 no_ip_ospf_bfd_prof_cmd,
269 "no ip ospf bfd profile [BFDPROF]",
270 NO_STR
271 "IP Information\n"
272 "OSPF interface commands\n"
273 "Enables BFD support\n"
274 BFD_PROFILE_STR
275 BFD_PROFILE_NAME_STR)
276{
277 VTY_DECLVAR_CONTEXT(interface, ifp);
278 struct ospf_if_params *params;
279
96b52510 280 params = IF_DEF_PARAMS(ifp);
f3fd7196
DT
281 if (!params->bfd_config)
282 return CMD_SUCCESS;
283
96b52510
RZ
284 params->bfd_config->profile[0] = 0;
285 ospf_interface_bfd_apply(ifp);
286
287 return CMD_SUCCESS;
288}
289
7f342629
DS
290DEFUN (no_ip_ospf_bfd,
291 no_ip_ospf_bfd_cmd,
64dc4b2d
RZ
292#if HAVE_BFDD > 0
293 "no ip ospf bfd",
294#else
692b4c65 295 "no ip ospf bfd [(2-255) (50-60000) (50-60000)]",
64dc4b2d 296#endif /* HAVE_BFDD */
7f342629
DS
297 NO_STR
298 "IP Information\n"
299 "OSPF interface commands\n"
692b4c65 300 "Disables BFD support\n"
64dc4b2d 301#if HAVE_BFDD == 0
692b4c65
QY
302 "Detect Multiplier\n"
303 "Required min receive interval\n"
64dc4b2d
RZ
304 "Desired min transmit interval\n"
305#endif /* !HAVE_BFDD */
306)
7f342629 307{
d62a17ae 308 VTY_DECLVAR_CONTEXT(interface, ifp);
659f4e40 309 ospf_interface_disable_bfd(ifp, IF_DEF_PARAMS(ifp));
d62a17ae 310 return CMD_SUCCESS;
7f342629
DS
311}
312
cd9d0537 313void ospf_bfd_init(struct event_loop *tm)
7f342629 314{
659f4e40 315 bfd_protocol_integration_init(zclient, tm);
7f342629 316
d62a17ae 317 /* Install BFD command */
318 install_element(INTERFACE_NODE, &ip_ospf_bfd_cmd);
319 install_element(INTERFACE_NODE, &ip_ospf_bfd_param_cmd);
96b52510
RZ
320 install_element(INTERFACE_NODE, &ip_ospf_bfd_prof_cmd);
321 install_element(INTERFACE_NODE, &no_ip_ospf_bfd_prof_cmd);
d62a17ae 322 install_element(INTERFACE_NODE, &no_ip_ospf_bfd_cmd);
7f342629 323}