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