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