Skip to content

Commit 9a109a6

Browse files
authored
Merge pull request FRRouting#18763 from opensourcerouting/fix/bgp_bfd_profile_shutdown
BGP should stay in Idle if BFD profile is in admin shutdown state
2 parents 3f28c22 + 4169f27 commit 9a109a6

11 files changed

Lines changed: 164 additions & 32 deletions

File tree

bgpd/bgp_bfd.c

Lines changed: 110 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
2727
#include "bgpd/bgp_vty.h"
2828
#include "bgpd/bgp_packet.h"
2929
#include "bgpd/bgp_network.h"
30+
#ifndef VTYSH_EXTRACT_PL
31+
#include "bgpd/bgp_bfd_clippy.c"
32+
#endif
3033

3134
DEFINE_MTYPE_STATIC(BGPD, BFD_CONFIG, "BFD configuration data");
3235

@@ -420,8 +423,7 @@ void bgp_peer_remove_bfd_config(struct peer *p)
420423
/*
421424
* bgp_bfd_peer_config_write - Write the peer BFD configuration.
422425
*/
423-
void bgp_bfd_peer_config_write(struct vty *vty, const struct peer *peer,
424-
const char *addr)
426+
void bgp_bfd_peer_config_write(struct vty *vty, struct peer *peer, const char *addr)
425427
{
426428
/*
427429
* Always show group BFD configuration, but peer only when explicitly
@@ -446,13 +448,15 @@ void bgp_bfd_peer_config_write(struct vty *vty, const struct peer *peer,
446448
if (peer->bfd_config->cbit)
447449
vty_out(vty, " neighbor %s bfd check-control-plane-failure\n",
448450
addr);
451+
452+
if (peergroup_flag_check(peer, PEER_FLAG_BFD_STRICT))
453+
vty_out(vty, " neighbor %s bfd strict\n", addr);
449454
}
450455

451456
/*
452457
* bgp_bfd_show_info - Show the peer BFD information.
453458
*/
454-
void bgp_bfd_show_info(struct vty *vty, const struct peer *peer,
455-
json_object *json_neigh)
459+
void bgp_bfd_show_info(struct vty *vty, struct peer *peer, json_object *json_neigh)
456460
{
457461
bfd_sess_show(vty, json_neigh, peer->bfd_config->session);
458462
}
@@ -481,11 +485,49 @@ DEFUN (neighbor_bfd,
481485
return CMD_SUCCESS;
482486
}
483487

488+
#if HAVE_BFDD == 0
489+
DEFUN(
490+
neighbor_bfd_param,
491+
neighbor_bfd_param_cmd,
492+
"neighbor <A.B.C.D|X:X::X:X|WORD> bfd (2-255) (50-60000) (50-60000)",
493+
NEIGHBOR_STR
494+
NEIGHBOR_ADDR_STR2
495+
"Enables BFD support\n"
496+
"Detect Multiplier\n"
497+
"Required min receive interval\n"
498+
"Desired min transmit interval\n")
499+
{
500+
int idx_peer = 1;
501+
int idx_number_1 = 3;
502+
int idx_number_2 = 4;
503+
int idx_number_3 = 5;
504+
long detection_multiplier, min_rx, min_tx;
505+
struct peer *peer;
506+
507+
peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
508+
if (!peer)
509+
return CMD_WARNING_CONFIG_FAILED;
510+
511+
detection_multiplier = strtol(argv[idx_number_1]->arg, NULL, 10);
512+
min_rx = strtol(argv[idx_number_2]->arg, NULL, 10);
513+
min_tx = strtol(argv[idx_number_3]->arg, NULL, 10);
514+
515+
if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
516+
bgp_group_configure_bfd(peer);
517+
else
518+
bgp_peer_configure_bfd(peer, true);
519+
520+
peer->bfd_config->detection_multiplier = detection_multiplier;
521+
peer->bfd_config->min_rx = min_rx;
522+
peer->bfd_config->min_tx = min_tx;
523+
bgp_peer_config_apply(peer, peer->group);
524+
525+
return CMD_SUCCESS;
526+
}
527+
#endif
528+
484529
#if HAVE_BFDD > 0
485530
DEFUN_HIDDEN(
486-
#else
487-
DEFUN(
488-
#endif /* HAVE_BFDD */
489531
neighbor_bfd_param,
490532
neighbor_bfd_param_cmd,
491533
"neighbor <A.B.C.D|X:X::X:X|WORD> bfd (2-255) (50-60000) (50-60000)",
@@ -523,6 +565,28 @@ DEFUN(
523565

524566
return CMD_SUCCESS;
525567
}
568+
#endif
569+
570+
DEFPY (neighbor_bfd_strict,
571+
neighbor_bfd_strict_cmd,
572+
"[no$no] neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor bfd strict",
573+
NO_STR
574+
NEIGHBOR_STR
575+
NEIGHBOR_ADDR_STR2
576+
"BFD support\n"
577+
"Strict mode\n")
578+
{
579+
struct peer *peer;
580+
581+
peer = peer_and_group_lookup_vty(vty, neighbor);
582+
if (!peer)
583+
return CMD_WARNING_CONFIG_FAILED;
584+
585+
if (no)
586+
return peer_flag_unset(peer, PEER_FLAG_BFD_STRICT);
587+
588+
return peer_flag_set(peer, PEER_FLAG_BFD_STRICT);
589+
}
526590

527591
DEFUN (neighbor_bfd_check_controlplane_failure,
528592
neighbor_bfd_check_controlplane_failure_cmd,
@@ -556,38 +620,58 @@ DEFUN (neighbor_bfd_check_controlplane_failure,
556620
return CMD_SUCCESS;
557621
}
558622

623+
#if HAVE_BFDD > 0
559624
DEFUN (no_neighbor_bfd,
560625
no_neighbor_bfd_cmd,
561-
#if HAVE_BFDD > 0
562626
"no neighbor <A.B.C.D|X:X::X:X|WORD> bfd",
563-
#else
627+
NO_STR
628+
NEIGHBOR_STR
629+
NEIGHBOR_ADDR_STR2
630+
"Disables BFD support\n")
631+
{
632+
int idx_peer = 2;
633+
struct peer *peer;
634+
635+
peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
636+
if (!peer)
637+
return CMD_WARNING_CONFIG_FAILED;
638+
639+
if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
640+
bgp_group_remove_bfd(peer);
641+
else
642+
bgp_peer_remove_bfd(peer);
643+
644+
return CMD_SUCCESS;
645+
}
646+
#endif
647+
648+
#if HAVE_BFDD == 0
649+
DEFUN (no_neighbor_bfd,
650+
no_neighbor_bfd_cmd,
564651
"no neighbor <A.B.C.D|X:X::X:X|WORD> bfd [(2-255) (50-60000) (50-60000)]",
565-
#endif /* HAVE_BFDD */
566652
NO_STR
567653
NEIGHBOR_STR
568654
NEIGHBOR_ADDR_STR2
569655
"Disables BFD support\n"
570-
#if HAVE_BFDD == 0
571656
"Detect Multiplier\n"
572657
"Required min receive interval\n"
573-
"Desired min transmit interval\n"
574-
#endif /* !HAVE_BFDD */
575-
)
576-
{
577-
int idx_peer = 2;
578-
struct peer *peer;
658+
"Desired min transmit interval\n")
659+
{
660+
int idx_peer = 2;
661+
struct peer *peer;
579662

580-
peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
581-
if (!peer)
582-
return CMD_WARNING_CONFIG_FAILED;
663+
peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
664+
if (!peer)
665+
return CMD_WARNING_CONFIG_FAILED;
583666

584-
if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
585-
bgp_group_remove_bfd(peer);
586-
else
587-
bgp_peer_remove_bfd(peer);
667+
if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
668+
bgp_group_remove_bfd(peer);
669+
else
670+
bgp_peer_remove_bfd(peer);
588671

589-
return CMD_SUCCESS;
672+
return CMD_SUCCESS;
590673
}
674+
#endif
591675

592676
#if HAVE_BFDD > 0
593677
DEFUN(neighbor_bfd_profile, neighbor_bfd_profile_cmd,
@@ -657,6 +741,7 @@ void bgp_bfd_init(struct event_loop *tm)
657741
install_element(BGP_NODE, &neighbor_bfd_cmd);
658742
install_element(BGP_NODE, &neighbor_bfd_param_cmd);
659743
install_element(BGP_NODE, &neighbor_bfd_check_controlplane_failure_cmd);
744+
install_element(BGP_NODE, &neighbor_bfd_strict_cmd);
660745
install_element(BGP_NODE, &no_neighbor_bfd_cmd);
661746

662747
#if HAVE_BFDD > 0

bgpd/bgp_bfd.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@
1414

1515
extern void bgp_bfd_init(struct event_loop *tm);
1616

17-
extern void bgp_bfd_peer_config_write(struct vty *vty, const struct peer *peer,
18-
const char *addr);
17+
extern void bgp_bfd_peer_config_write(struct vty *vty, struct peer *peer, const char *addr);
1918

2019
/**
2120
* Show BFD information helper.
@@ -25,8 +24,7 @@ extern void bgp_bfd_peer_config_write(struct vty *vty, const struct peer *peer,
2524
* \param use_json unused.
2625
* \param json_neigh JSON object when called as JSON command.
2726
*/
28-
extern void bgp_bfd_show_info(struct vty *vty, const struct peer *peer,
29-
json_object *json_neigh);
27+
extern void bgp_bfd_show_info(struct vty *vty, struct peer *peer, json_object *json_neigh);
3028

3129
/**
3230
* When called on a group it applies configuration to all peers in that group,

bgpd/bgp_network.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,8 @@ static const char *bgp_peer_active2str(enum bgp_peer_active active)
398398
return "unspecified connection";
399399
case BGP_PEER_BFD_DOWN:
400400
return "BFD down";
401+
case BGP_PEER_BFD_ADMIN_DOWN:
402+
return "BFD administrative shutdown";
401403
case BGP_PEER_AF_UNCONFIGURED:
402404
return "no AF activated";
403405
}

bgpd/bgpd.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4790,8 +4790,13 @@ enum bgp_peer_active peer_active(struct peer_connection *connection)
47904790
return BGP_PEER_CONNECTION_UNSPECIFIED;
47914791

47924792
if (peer->bfd_config) {
4793-
if (peer_established(connection) && bfd_session_is_down(peer->bfd_config->session))
4794-
return BGP_PEER_BFD_DOWN;
4793+
/* Only if `neighbor X bfd strict` is enabled */
4794+
if (peergroup_flag_check(peer, PEER_FLAG_BFD_STRICT)) {
4795+
if (bfd_session_is_admin_down(peer->bfd_config->session))
4796+
return BGP_PEER_BFD_ADMIN_DOWN;
4797+
else if (bfd_session_is_down(peer->bfd_config->session))
4798+
return BGP_PEER_BFD_DOWN;
4799+
}
47954800
}
47964801

47974802
if (peer->afc[AFI_IP][SAFI_UNICAST] || peer->afc[AFI_IP][SAFI_MULTICAST]
@@ -4948,6 +4953,7 @@ static const struct peer_flag_action peer_flag_action_list[] = {
49484953
{PEER_FLAG_LONESOUL, 0, peer_change_reset_out},
49494954
{PEER_FLAG_TCP_MSS, 0, peer_change_none},
49504955
{PEER_FLAG_CAPABILITY_LINK_LOCAL, 0, peer_change_none},
4956+
{PEER_FLAG_BFD_STRICT, 0, peer_change_none},
49514957
{0, 0, 0}};
49524958

49534959
static const struct peer_flag_action peer_af_flag_action_list[] = {

bgpd/bgpd.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1696,6 +1696,8 @@ struct peer {
16961696
#define PEER_FLAG_CAPABILITY_LINK_LOCAL (1ULL << 41)
16971697
/* Peer is part of a batch clearing its routes */
16981698
#define PEER_FLAG_CLEARING_BATCH (1ULL << 42)
1699+
/* BFD strict mode */
1700+
#define PEER_FLAG_BFD_STRICT (1ULL << 43)
16991701

17001702
/*
17011703
*GR-Disabled mode means unset PEER_FLAG_GRACEFUL_RESTART
@@ -2435,6 +2437,7 @@ enum bgp_peer_active {
24352437
BGP_PEER_ACTIVE,
24362438
BGP_PEER_CONNECTION_UNSPECIFIED,
24372439
BGP_PEER_BFD_DOWN,
2440+
BGP_PEER_BFD_ADMIN_DOWN,
24382441
BGP_PEER_AF_UNCONFIGURED,
24392442
};
24402443

bgpd/subdir.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ clippy_scan += \
217217
bgpd/bgp_vty.c \
218218
bgpd/bgp_nexthop.c \
219219
bgpd/bgp_snmp.c \
220+
bgpd/bgp_bfd.c \
220221
# end
221222

222223
nodist_bgpd_bgpd_SOURCES = \

doc/user/bfd.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,13 @@ The following commands are available inside the BGP configuration node.
252252
the connection with its neighbor and, when it goes back up, notify
253253
BGP to try to connect to it.
254254

255+
.. clicmd:: neighbor <A.B.C.D|X:X::X:X|WORD> bfd strict
256+
257+
Strict mode is similar to the default mode, but it will not allow BGP to
258+
establish a connection with the peer until the BFD session is up. This
259+
mode is useful when you want to avoid having BGP sessions up when the
260+
underlying link is down. And if the BFD session goes down, the BGP session will
261+
be closed immediately. The same is if BFD is administratively down.
255262

256263
.. clicmd:: neighbor <A.B.C.D|X:X::X:X|WORD> bfd check-control-plane-failure
257264

lib/bfd.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1355,3 +1355,8 @@ bool bfd_session_is_down(const struct bfd_session_params *session)
13551355
return session->bss.state == BSS_DOWN ||
13561356
session->bss.state == BSS_ADMIN_DOWN;
13571357
}
1358+
1359+
bool bfd_session_is_admin_down(const struct bfd_session_params *session)
1360+
{
1361+
return session->bss.state == BSS_ADMIN_DOWN;
1362+
}

lib/bfd.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,7 @@ extern int bfd_nht_update(const struct prefix *match,
463463
const struct zapi_route *route);
464464

465465
extern bool bfd_session_is_down(const struct bfd_session_params *session);
466+
extern bool bfd_session_is_admin_down(const struct bfd_session_params *session);
466467

467468
#ifdef __cplusplus
468469
}

tests/topotests/bgp_bfd_down_cease_notification/r1/bgpd.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ router bgp 65001
44
neighbor 192.168.255.2 timers 3 10
55
neighbor 192.168.255.2 timers connect 1
66
neighbor 192.168.255.2 bfd profile r1
7+
neighbor 192.168.255.2 bfd strict
78
neighbor 192.168.255.2 passive
89
address-family ipv4
910
redistribute connected

0 commit comments

Comments
 (0)