]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_bfd.c
Merge remote-tracking branch 'origin/master' into evpn_plus_struct_attr
[mirror_frr.git] / bgpd / bgp_bfd.c
CommitLineData
c43ed2e4
DS
1/**
2 * bgp_bfd.c: BGP BFD handling routines
3 *
4 * @copyright Copyright (C) 2015 Cumulus Networks, Inc.
5 *
6 * This file is part of GNU Zebra.
7 *
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
11 * later version.
12 *
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.
17 *
896014f4
DL
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
c43ed2e4
DS
21 */
22
23#include <zebra.h>
24
25#include "command.h"
26#include "linklist.h"
27#include "memory.h"
28#include "prefix.h"
29#include "thread.h"
30#include "buffer.h"
31#include "stream.h"
32#include "zclient.h"
7f342629 33#include "bfd.h"
856ca177 34#include "lib/json.h"
039f3a34
DS
35#include "filter.h"
36
c43ed2e4 37#include "bgpd/bgpd.h"
7f342629 38#include "bgp_fsm.h"
c43ed2e4
DS
39#include "bgpd/bgp_bfd.h"
40#include "bgpd/bgp_debug.h"
41#include "bgpd/bgp_vty.h"
42
43extern struct zclient *zclient;
44
c43ed2e4
DS
45/*
46 * bgp_bfd_peer_group2peer_copy - Copy the BFD information from peer group template
47 * to peer.
48 */
49void
50bgp_bfd_peer_group2peer_copy(struct peer *conf, struct peer *peer)
51{
7f342629
DS
52 struct bfd_info *bfd_info;
53 struct bfd_info *conf_bfd_info;
54
55 if (!conf->bfd_info)
56 return;
57
58 conf_bfd_info = (struct bfd_info *)conf->bfd_info;
59 if (!peer->bfd_info)
60 peer->bfd_info = bfd_info_create();
c43ed2e4 61
7f342629 62 bfd_info = (struct bfd_info *)peer->bfd_info;
c43ed2e4
DS
63
64 /* Copy BFD parameter values */
65 bfd_info->required_min_rx = conf_bfd_info->required_min_rx;
66 bfd_info->desired_min_tx = conf_bfd_info->desired_min_tx;
67 bfd_info->detect_mult = conf_bfd_info->detect_mult;
986aa00f 68 bfd_info->type = conf_bfd_info->type;
c43ed2e4
DS
69}
70
71/*
72 * bgp_bfd_is_peer_multihop - returns whether BFD peer is multi-hop or single hop.
73 */
8c4f6381 74int
c43ed2e4
DS
75bgp_bfd_is_peer_multihop(struct peer *peer)
76{
986aa00f 77 struct bfd_info *bfd_info;
78
79 bfd_info = (struct bfd_info *)peer->bfd_info;
80
81 if (!bfd_info)
82 return 0;
83
84 if((bfd_info->type == BFD_TYPE_MULTIHOP) ||
85 ((peer->sort == BGP_PEER_IBGP) && !peer->shared_network) ||
86 is_ebgp_multihop_configured(peer))
c43ed2e4
DS
87 return 1;
88 else
89 return 0;
90}
91
92/*
7f342629
DS
93 * bgp_bfd_peer_sendmsg - Format and send a Peer register/Unregister
94 * command to Zebra to be forwarded to BFD
c43ed2e4
DS
95 */
96static void
7f342629 97bgp_bfd_peer_sendmsg (struct peer *peer, int command)
c43ed2e4 98{
7f342629 99 struct bfd_info *bfd_info;
d553294e 100 vrf_id_t vrf_id = VRF_DEFAULT;
986aa00f 101 int multihop;
7f342629
DS
102
103 bfd_info = (struct bfd_info *)peer->bfd_info;
104
d553294e 105 if (peer->bgp && (peer->bgp->inst_type == BGP_INSTANCE_TYPE_VRF))
106 vrf_id = peer->bgp->vrf_id;
107
986aa00f 108 if (command == ZEBRA_BFD_DEST_DEREGISTER)
109 {
110 multihop = CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_TYPE_MULTIHOP);
111 UNSET_FLAG(bfd_info->flags, BFD_FLAG_BFD_TYPE_MULTIHOP);
112 }
113 else
114 {
115 multihop = bgp_bfd_is_peer_multihop(peer);
116 if ((command == ZEBRA_BFD_DEST_REGISTER) && multihop)
117 SET_FLAG(bfd_info->flags, BFD_FLAG_BFD_TYPE_MULTIHOP);
118 }
119
7f342629
DS
120 if (peer->su.sa.sa_family == AF_INET)
121 bfd_peer_sendmsg (zclient, bfd_info, AF_INET,
122 &peer->su.sin.sin_addr,
123 (peer->su_local) ? &peer->su_local->sin.sin_addr : NULL,
124 (peer->nexthop.ifp) ? peer->nexthop.ifp->name : NULL,
986aa00f 125 peer->ttl, multihop, command, 1, vrf_id);
7f342629
DS
126 else if (peer->su.sa.sa_family == AF_INET6)
127 bfd_peer_sendmsg (zclient, bfd_info, AF_INET6,
128 &peer->su.sin6.sin6_addr,
129 (peer->su_local) ? &peer->su_local->sin6.sin6_addr : NULL,
130 (peer->nexthop.ifp) ? peer->nexthop.ifp->name : NULL,
986aa00f 131 peer->ttl, multihop, command, 1, vrf_id);
c43ed2e4
DS
132}
133
134/*
135 * bgp_bfd_register_peer - register a peer with BFD through zebra
136 * for monitoring the peer rechahability.
137 */
138void
139bgp_bfd_register_peer (struct peer *peer)
140{
7f342629 141 struct bfd_info *bfd_info;
c43ed2e4 142
7f342629
DS
143 if (!peer->bfd_info)
144 return;
145 bfd_info = (struct bfd_info *)peer->bfd_info;
c43ed2e4
DS
146
147 /* Check if BFD is enabled and peer has already been registered with BFD */
7f342629 148 if (CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_REG))
c43ed2e4
DS
149 return;
150
7f342629 151 bgp_bfd_peer_sendmsg(peer, ZEBRA_BFD_DEST_REGISTER);
c43ed2e4
DS
152}
153
154/**
155 * bgp_bfd_deregister_peer - deregister a peer with BFD through zebra
156 * for stopping the monitoring of the peer
157 * rechahability.
158 */
159void
160bgp_bfd_deregister_peer (struct peer *peer)
161{
7f342629 162 struct bfd_info *bfd_info;
c43ed2e4 163
7f342629
DS
164 if (!peer->bfd_info)
165 return;
166 bfd_info = (struct bfd_info *)peer->bfd_info;
c43ed2e4
DS
167
168 /* Check if BFD is eanbled and peer has not been registered */
7f342629 169 if (!CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_REG))
c43ed2e4
DS
170 return;
171
5c940836 172 bfd_info->status = BFD_STATUS_DOWN;
173 bfd_info->last_update = bgp_clock();
174
7f342629 175 bgp_bfd_peer_sendmsg(peer, ZEBRA_BFD_DEST_DEREGISTER);
c43ed2e4
DS
176}
177
178/*
179 * bgp_bfd_update_peer - update peer with BFD with new BFD paramters
180 * through zebra.
181 */
7f342629 182static void
c43ed2e4
DS
183bgp_bfd_update_peer (struct peer *peer)
184{
7f342629 185 struct bfd_info *bfd_info;
c43ed2e4 186
7f342629
DS
187 if (!peer->bfd_info)
188 return;
189 bfd_info = (struct bfd_info *)peer->bfd_info;
c43ed2e4
DS
190
191 /* Check if the peer has been registered with BFD*/
7f342629 192 if (!CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_REG))
c43ed2e4
DS
193 return;
194
7f342629 195 bgp_bfd_peer_sendmsg(peer, ZEBRA_BFD_DEST_UPDATE);
c43ed2e4
DS
196}
197
986aa00f 198/*
199 * bgp_bfd_update_type - update session type with BFD through zebra.
200 */
201static void
202bgp_bfd_update_type (struct peer *peer)
203{
204 struct bfd_info *bfd_info;
205 int multihop;
206
207 if (!peer->bfd_info)
208 return;
209 bfd_info = (struct bfd_info *)peer->bfd_info;
210
211 /* Check if the peer has been registered with BFD*/
212 if (!CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_REG))
213 return;
214
215 if (bfd_info->type == BFD_TYPE_NOT_CONFIGURED)
216 {
217 multihop = bgp_bfd_is_peer_multihop(peer);
218 if ((multihop && !CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_TYPE_MULTIHOP)) ||
219 (!multihop && CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_TYPE_MULTIHOP)))
220 {
221 bgp_bfd_peer_sendmsg(peer, ZEBRA_BFD_DEST_DEREGISTER);
222 bgp_bfd_peer_sendmsg(peer, ZEBRA_BFD_DEST_REGISTER);
223 }
224 }
225 else
226 {
227 if ((bfd_info->type == BFD_TYPE_MULTIHOP &&
228 !CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_TYPE_MULTIHOP)) ||
229 (bfd_info->type == BFD_TYPE_SINGLEHOP &&
230 CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_TYPE_MULTIHOP)))
231 {
232 bgp_bfd_peer_sendmsg(peer, ZEBRA_BFD_DEST_DEREGISTER);
233 bgp_bfd_peer_sendmsg(peer, ZEBRA_BFD_DEST_REGISTER);
234 }
235 }
236}
237
c43ed2e4
DS
238/*
239 * bgp_bfd_dest_replay - Replay all the peers that have BFD enabled
240 * to zebra
241 */
7f342629 242static int
7076bb2f
FL
243bgp_bfd_dest_replay (int command, struct zclient *client, zebra_size_t length,
244 vrf_id_t vrf_id)
c43ed2e4
DS
245{
246 struct listnode *mnode, *node, *nnode;
247 struct bgp *bgp;
248 struct peer *peer;
249
250 if (BGP_DEBUG (zebra, ZEBRA))
251 zlog_debug("Zebra: BFD Dest replay request");
252
055c4dfc 253 /* Send the client registration */
254 bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER);
255
c43ed2e4
DS
256 /* Replay the peer, if BFD is enabled in BGP */
257
258 for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp))
259 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
260 {
c43ed2e4
DS
261 bgp_bfd_update_peer(peer);
262 }
263
264 return 0;
265}
266
267/*
68fe91d6 268 * bgp_bfd_peer_status_update - Update the BFD status if it has changed. Bring
269 * down the peer if the BFD session went down from * up.
270 */
271static void
272bgp_bfd_peer_status_update (struct peer *peer, int status)
273{
274 struct bfd_info *bfd_info;
275 int old_status;
276
277 bfd_info = (struct bfd_info *)peer->bfd_info;
278
279 if (bfd_info->status == status)
280 return;
281
282 old_status = bfd_info->status;
283 bfd_info->status = status;
284 bfd_info->last_update = bgp_clock();
285
286 if ((status == BFD_STATUS_DOWN) && (old_status == BFD_STATUS_UP))
287 {
288 peer->last_reset = PEER_DOWN_BFD_DOWN;
289 BGP_EVENT_ADD (peer, BGP_Stop);
290 }
291}
292
293/*
294 * bgp_bfd_dest_update - Find the peer for which the BFD status
295 * has changed and bring down the peer
296 * connectivity if the BFD session went down.
c43ed2e4 297 */
7f342629 298static int
68fe91d6 299bgp_bfd_dest_update (int command, struct zclient *zclient,
7076bb2f 300 zebra_size_t length, vrf_id_t vrf_id)
c43ed2e4
DS
301{
302 struct interface *ifp;
303 struct prefix dp;
304 struct prefix sp;
68fe91d6 305 int status;
c43ed2e4 306
1e22a2af 307 ifp = bfd_get_peer_info (zclient->ibuf, &dp, &sp, &status, vrf_id);
c43ed2e4
DS
308
309 if (BGP_DEBUG (zebra, ZEBRA))
310 {
4690c7d7 311 char buf[2][PREFIX2STR_BUFFER];
c43ed2e4
DS
312 prefix2str(&dp, buf[0], sizeof(buf[0]));
313 if (ifp)
314 {
3fa113f0 315 zlog_debug("Zebra: vrf %d interface %s bfd destination %s %s",
316 vrf_id, ifp->name, buf[0], bfd_get_status_str(status));
c43ed2e4
DS
317 }
318 else
319 {
320 prefix2str(&sp, buf[1], sizeof(buf[1]));
3fa113f0 321 zlog_debug("Zebra: vrf %d source %s bfd destination %s %s",
322 vrf_id, buf[1], buf[0], bfd_get_status_str(status));
c43ed2e4
DS
323 }
324 }
325
326 /* Bring the peer down if BFD is enabled in BGP */
327 {
328 struct listnode *mnode, *node, *nnode;
329 struct bgp *bgp;
330 struct peer *peer;
331
332 for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp))
333 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
334 {
7f342629 335 if (!peer->bfd_info)
c43ed2e4
DS
336 continue;
337
7bbc6864
DS
338 if ((dp.family == AF_INET) && (peer->su.sa.sa_family == AF_INET))
339 {
340 if (dp.u.prefix4.s_addr != peer->su.sin.sin_addr.s_addr)
341 continue;
342 }
7bbc6864
DS
343 else if ((dp.family == AF_INET6) &&
344 (peer->su.sa.sa_family == AF_INET6))
345 {
346 if (memcmp(&dp.u.prefix6, &peer->su.sin6.sin6_addr,
347 sizeof (struct in6_addr)))
348 continue;
349 }
c43ed2e4
DS
350 else
351 continue;
352
353 if (ifp && (ifp == peer->nexthop.ifp))
7bbc6864 354 {
68fe91d6 355 bgp_bfd_peer_status_update(peer, status);
7bbc6864 356 }
c43ed2e4
DS
357 else
358 {
359 if (!peer->su_local)
360 continue;
361
7bbc6864
DS
362 if ((sp.family == AF_INET) &&
363 (peer->su_local->sa.sa_family == AF_INET))
364 {
365 if (sp.u.prefix4.s_addr != peer->su_local->sin.sin_addr.s_addr)
366 continue;
367 }
7bbc6864
DS
368 else if ((sp.family == AF_INET6) &&
369 (peer->su_local->sa.sa_family == AF_INET6))
370 {
371 if (memcmp(&sp.u.prefix6, &peer->su_local->sin6.sin6_addr,
372 sizeof (struct in6_addr)))
373 continue;
374 }
c43ed2e4
DS
375 else
376 continue;
7bbc6864 377
d553294e 378 if ((vrf_id != VRF_DEFAULT) && (peer->bgp->vrf_id != vrf_id))
379 continue;
380
68fe91d6 381 bgp_bfd_peer_status_update(peer, status);
c43ed2e4
DS
382 }
383 }
384 }
385
386 return 0;
387}
388
389/*
390 * bgp_bfd_peer_param_set - Set the configured BFD paramter values for peer.
391 */
7f342629 392static int
c43ed2e4 393bgp_bfd_peer_param_set (struct peer *peer, u_int32_t min_rx, u_int32_t min_tx,
7f342629 394 u_int8_t detect_mult, int defaults)
c43ed2e4
DS
395{
396 struct peer_group *group;
397 struct listnode *node, *nnode;
7f342629 398 int command = 0;
c43ed2e4 399
68fe91d6 400 bfd_set_param((struct bfd_info **)&(peer->bfd_info), min_rx, min_tx,
401 detect_mult, defaults, &command);
c43ed2e4
DS
402
403 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
404 {
405 group = peer->group;
406 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
407 {
7f342629 408 command = 0;
68fe91d6 409 bfd_set_param((struct bfd_info **)&(peer->bfd_info), min_rx, min_tx,
410 detect_mult, defaults, &command);
c43ed2e4 411
7f342629
DS
412 if ((peer->status == Established) &&
413 (command == ZEBRA_BFD_DEST_REGISTER))
c43ed2e4 414 bgp_bfd_register_peer(peer);
7f342629 415 else if (command == ZEBRA_BFD_DEST_UPDATE)
c43ed2e4
DS
416 bgp_bfd_update_peer(peer);
417 }
418 }
7f342629 419 else
c43ed2e4 420 {
7f342629
DS
421 if ((peer->status == Established) &&
422 (command == ZEBRA_BFD_DEST_REGISTER))
c43ed2e4 423 bgp_bfd_register_peer(peer);
7f342629 424 else if (command == ZEBRA_BFD_DEST_UPDATE)
c43ed2e4
DS
425 bgp_bfd_update_peer(peer);
426 }
427 return 0;
428}
429
430/*
986aa00f 431 * bgp_bfd_peer_param_unset - Delete the configured BFD paramter values for peer.
c43ed2e4 432 */
7f342629 433static int
c43ed2e4
DS
434bgp_bfd_peer_param_unset (struct peer *peer)
435{
436 struct peer_group *group;
437 struct listnode *node, *nnode;
c43ed2e4 438
7f342629
DS
439 if (!peer->bfd_info)
440 return 0;
c43ed2e4
DS
441
442 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
443 {
7f342629 444 bfd_info_free(&(peer->bfd_info));
c43ed2e4
DS
445 group = peer->group;
446 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
447 {
c43ed2e4 448 bgp_bfd_deregister_peer(peer);
7f342629 449 bfd_info_free(&(peer->bfd_info));
c43ed2e4
DS
450 }
451 }
452 else
7f342629
DS
453 {
454 bgp_bfd_deregister_peer(peer);
455 bfd_info_free(&(peer->bfd_info));
456 }
c43ed2e4
DS
457 return 0;
458}
459
986aa00f 460/*
461 * bgp_bfd_peer_param_type_set - set the BFD session type (multihop or singlehop)
462 */
463static int
464bgp_bfd_peer_param_type_set (struct peer *peer, enum bfd_sess_type type)
465{
466 struct peer_group *group;
467 struct listnode *node, *nnode;
468 int command = 0;
469 struct bfd_info *bfd_info;
470
471 if (!peer->bfd_info)
472 bfd_set_param((struct bfd_info **)&(peer->bfd_info), BFD_DEF_MIN_RX,
473 BFD_DEF_MIN_TX, BFD_DEF_DETECT_MULT, 1, &command);
474
475 bfd_info = (struct bfd_info *)peer->bfd_info;
476 bfd_info->type = type;
477
478 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
479 {
480 group = peer->group;
481 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
482 {
483 command = 0;
484 if (!peer->bfd_info)
485 bfd_set_param((struct bfd_info **)&(peer->bfd_info),
486 BFD_DEF_MIN_RX, BFD_DEF_MIN_TX,
487 BFD_DEF_DETECT_MULT, 1, &command);
488
489 bfd_info = (struct bfd_info *)peer->bfd_info;
490 bfd_info->type = type;
491
492 if (peer->status == Established)
493 {
494 if (command == ZEBRA_BFD_DEST_REGISTER)
495 bgp_bfd_register_peer(peer);
496 else
497 bgp_bfd_update_type(peer);
498 }
499 }
500 }
501 else
502 {
503 if (peer->status == Established)
504 {
505 if (command == ZEBRA_BFD_DEST_REGISTER)
506 bgp_bfd_register_peer(peer);
507 else
508 bgp_bfd_update_type(peer);
509 }
510 }
511
512 return 0;
513}
514
c43ed2e4
DS
515/*
516 * bgp_bfd_peer_config_write - Write the peer BFD configuration.
517 */
518void
519bgp_bfd_peer_config_write(struct vty *vty, struct peer *peer, char *addr)
520{
7f342629 521 struct bfd_info *bfd_info;
c43ed2e4 522
7f342629
DS
523 if (!peer->bfd_info)
524 return;
525
526 bfd_info = (struct bfd_info *)peer->bfd_info;
c43ed2e4 527
7f342629 528 if (CHECK_FLAG (bfd_info->flags, BFD_FLAG_PARAM_CFG))
5c7571d4 529 vty_out (vty, " neighbor %s bfd %d %d %d\n", addr,
c43ed2e4 530 bfd_info->detect_mult, bfd_info->required_min_rx,
96ade3ed 531 bfd_info->desired_min_tx);
986aa00f 532
533 if (bfd_info->type != BFD_TYPE_NOT_CONFIGURED)
5c7571d4 534 vty_out (vty, " neighbor %s bfd %s\n", addr,
96ade3ed 535 (bfd_info->type == BFD_TYPE_MULTIHOP) ? "multihop" : "singlehop");
986aa00f 536
537 if (!CHECK_FLAG (bfd_info->flags, BFD_FLAG_PARAM_CFG) &&
538 (bfd_info->type == BFD_TYPE_NOT_CONFIGURED))
5c7571d4 539 vty_out (vty, " neighbor %s bfd\n", addr);
c43ed2e4
DS
540}
541
542/*
543 * bgp_bfd_show_info - Show the peer BFD information.
544 */
545void
856ca177 546bgp_bfd_show_info(struct vty *vty, struct peer *peer, u_char use_json, json_object *json_neigh)
c43ed2e4 547{
68fe91d6 548 bfd_show_info(vty, (struct bfd_info *)peer->bfd_info,
549 bgp_bfd_is_peer_multihop(peer), 0, use_json, json_neigh);
c43ed2e4
DS
550}
551
552DEFUN (neighbor_bfd,
553 neighbor_bfd_cmd,
9ccf14f7 554 "neighbor <A.B.C.D|X:X::X:X|WORD> bfd",
c43ed2e4
DS
555 NEIGHBOR_STR
556 NEIGHBOR_ADDR_STR2
557 "Enables BFD support\n")
558{
5bf15956 559 int idx_peer = 1;
c43ed2e4
DS
560 struct peer *peer;
561 int ret;
c43ed2e4 562
5bf15956 563 peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
c43ed2e4 564 if (! peer)
f1a05de9 565 return CMD_WARNING_CONFIG_FAILED;
c43ed2e4 566
7f342629
DS
567 ret = bgp_bfd_peer_param_set (peer, BFD_DEF_MIN_RX, BFD_DEF_MIN_TX,
568 BFD_DEF_DETECT_MULT, 1);
c43ed2e4
DS
569 if (ret != 0)
570 return bgp_vty_return (vty, ret);
571
572 return CMD_SUCCESS;
573
574}
575
576DEFUN (neighbor_bfd_param,
577 neighbor_bfd_param_cmd,
9ccf14f7 578 "neighbor <A.B.C.D|X:X::X:X|WORD> bfd (2-255) (50-60000) (50-60000)",
c43ed2e4
DS
579 NEIGHBOR_STR
580 NEIGHBOR_ADDR_STR2
581 "Enables BFD support\n"
582 "Detect Multiplier\n"
583 "Required min receive interval\n"
584 "Desired min transmit interval\n")
585{
5bf15956
DW
586 int idx_peer = 1;
587 int idx_number_1 = 3;
588 int idx_number_2 = 4;
589 int idx_number_3 = 5;
c43ed2e4
DS
590 struct peer *peer;
591 u_int32_t rx_val;
592 u_int32_t tx_val;
593 u_int8_t dm_val;
594 int ret;
c43ed2e4 595
5bf15956 596 peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
c43ed2e4 597 if (!peer)
f1a05de9 598 return CMD_WARNING_CONFIG_FAILED;
c43ed2e4 599
5bf15956 600 if ((ret = bfd_validate_param (vty, argv[idx_number_1]->arg, argv[idx_number_2]->arg, argv[idx_number_3]->arg, &dm_val,
7f342629
DS
601 &rx_val, &tx_val)) != CMD_SUCCESS)
602 return ret;
c43ed2e4 603
7f342629 604 ret = bgp_bfd_peer_param_set (peer, rx_val, tx_val, dm_val, 0);
c43ed2e4
DS
605 if (ret != 0)
606 return bgp_vty_return (vty, ret);
607
608 return CMD_SUCCESS;
609
610}
611
986aa00f 612DEFUN_HIDDEN (neighbor_bfd_type,
613 neighbor_bfd_type_cmd,
e83a9414 614 "neighbor <A.B.C.D|X:X::X:X|WORD> bfd <multihop|singlehop>",
986aa00f 615 NEIGHBOR_STR
616 NEIGHBOR_ADDR_STR2
617 "Enables BFD support\n"
d7fa34c1
QY
618 "Multihop session\n"
619 "Single hop session\n")
986aa00f 620{
5bf15956
DW
621 int idx_peer = 1;
622 int idx_hop = 3;
986aa00f 623 struct peer *peer;
624 enum bfd_sess_type type;
625 int ret;
626
5bf15956 627 peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
986aa00f 628 if (!peer)
f1a05de9 629 return CMD_WARNING_CONFIG_FAILED;
986aa00f 630
7e045c3d 631 if (strmatch(argv[idx_hop]->text, "singlehop"))
986aa00f 632 type = BFD_TYPE_SINGLEHOP;
7e045c3d 633 else if (strmatch(argv[idx_hop]->text, "multihop"))
986aa00f 634 type = BFD_TYPE_MULTIHOP;
635 else
f1a05de9 636 return CMD_WARNING_CONFIG_FAILED;
986aa00f 637
638 ret = bgp_bfd_peer_param_type_set (peer, type);
639 if (ret != 0)
640 return bgp_vty_return (vty, ret);
641
642 return CMD_SUCCESS;
643}
644
c43ed2e4
DS
645DEFUN (no_neighbor_bfd,
646 no_neighbor_bfd_cmd,
5bf15956 647 "no neighbor <A.B.C.D|X:X::X:X|WORD> bfd [(2-255) (50-60000) (50-60000)]",
c43ed2e4
DS
648 NO_STR
649 NEIGHBOR_STR
650 NEIGHBOR_ADDR_STR2
5bf15956
DW
651 "Disables BFD support\n"
652 "Detect Multiplier\n"
653 "Required min receive interval\n"
654 "Desired min transmit interval\n")
c43ed2e4 655{
5bf15956 656 int idx_peer = 2;
c43ed2e4
DS
657 struct peer *peer;
658 int ret;
659
5bf15956 660 peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
c43ed2e4 661 if (! peer)
f1a05de9 662 return CMD_WARNING_CONFIG_FAILED;
c43ed2e4 663
c43ed2e4
DS
664 ret = bgp_bfd_peer_param_unset(peer);
665 if (ret != 0)
666 return bgp_vty_return (vty, ret);
667
c43ed2e4
DS
668 return CMD_SUCCESS;
669}
670
813d4307 671
986aa00f 672DEFUN_HIDDEN (no_neighbor_bfd_type,
673 no_neighbor_bfd_type_cmd,
e83a9414 674 "no neighbor <A.B.C.D|X:X::X:X|WORD> bfd <multihop|singlehop>",
986aa00f 675 NO_STR
676 NEIGHBOR_STR
677 NEIGHBOR_ADDR_STR2
678 "Disables BFD support\n"
3a2d747c
QY
679 "Multihop session\n"
680 "Singlehop session\n")
986aa00f 681{
5bf15956 682 int idx_peer = 2;
986aa00f 683 struct peer *peer;
684 int ret;
685
5bf15956 686 peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
986aa00f 687 if (! peer)
f1a05de9 688 return CMD_WARNING_CONFIG_FAILED;
986aa00f 689
690 if (!peer->bfd_info)
691 return 0;
692
693 ret = bgp_bfd_peer_param_type_set(peer, BFD_TYPE_NOT_CONFIGURED);
694 if (ret != 0)
695 return bgp_vty_return (vty, ret);
696
697 return CMD_SUCCESS;
698}
699
c43ed2e4
DS
700void
701bgp_bfd_init(void)
702{
567b877d 703 bfd_gbl_init();
704
c43ed2e4 705 /* Initialize BFD client functions */
68fe91d6 706 zclient->interface_bfd_dest_update = bgp_bfd_dest_update;
c43ed2e4
DS
707 zclient->bfd_dest_replay = bgp_bfd_dest_replay;
708
709 /* "neighbor bfd" commands. */
710 install_element (BGP_NODE, &neighbor_bfd_cmd);
711 install_element (BGP_NODE, &neighbor_bfd_param_cmd);
986aa00f 712 install_element (BGP_NODE, &neighbor_bfd_type_cmd);
c43ed2e4 713 install_element (BGP_NODE, &no_neighbor_bfd_cmd);
986aa00f 714 install_element (BGP_NODE, &no_neighbor_bfd_type_cmd);
c43ed2e4 715}