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