bgpd: Do not delete BGP dynamic peers if graceful restart kicks in

```
~# vtysh -c 'show bgp ipv4 unicast summary' | grep 192.168.10.17
*donatas-pc(192.168.10.17)           4      65002         8        12        0    0    0 00:01:35            2       14 N/A
```

Before shutting down 192.168.10.17:

```
~# vtysh -c 'show bgp ipv4 unicast 100.100.100.100/32'
BGP routing table entry for 100.100.100.100/32, version 7
Paths: (2 available, best #2, table default)
  Advertised to non peer-group peers:
  home-spine1.donatas.net(192.168.0.2)
  65002, (stale)
    192.168.10.17 from donatas-pc(192.168.10.17) (0.0.0.0)
      Origin incomplete, valid, external
      Last update: Sat Jan 15 21:45:47 2022
  65001
    192.168.0.2 from home-spine1.donatas.net(192.168.0.2) (2.2.2.2)
      Origin incomplete, metric 0, valid, external, best (Older Path)
      Last update: Sat Jan 15 21:25:19 2022
```

After 192.168.10.17 is down:

```
~# vtysh -c 'show bgp ipv4 unicast summary' | grep 192.168.10.17
donatas-pc(192.168.10.17)            4      65002         5         9        0    0    0 00:00:12       Active        0 N/A

~# vtysh -c 'show bgp ipv4 unicast 100.100.100.100/32'
BGP routing table entry for 100.100.100.100/32, version 7
Paths: (2 available, best #2, table default)
  Advertised to non peer-group peers:
  home-spine1.donatas.net(192.168.0.2)
  65002, (stale)
    192.168.10.17 from donatas-pc(192.168.10.17) (0.0.0.0)
      Origin incomplete, valid, external
      Community: llgr-stale
      Last update: Sat Jan 15 21:49:01 2022
      Time until Long-lived stale route deleted: 16
  65001
    192.168.0.2 from home-spine1.donatas.net(192.168.0.2) (2.2.2.2)
      Origin incomplete, metric 0, valid, external, best (First path received)
      Last update: Sat Jan 15 21:25:19 2022
```

Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
This commit is contained in:
Donatas Abraitis 2022-01-15 23:16:15 +02:00
parent 0fd57f5600
commit af8496af08
2 changed files with 21 additions and 7 deletions

View file

@ -662,6 +662,14 @@ static void bgp_graceful_restart_timer_off(struct peer *peer)
UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT);
BGP_TIMER_OFF(peer->t_gr_stale);
if (peer_dynamic_neighbor(peer) &&
!(CHECK_FLAG(peer->flags, PEER_FLAG_DELETE))) {
if (bgp_debug_neighbor_events(peer))
zlog_debug("%s (dynamic neighbor) deleted", peer->host);
peer_delete(peer);
}
bgp_timer_set(peer);
}
@ -1380,8 +1388,8 @@ int bgp_stop(struct peer *peer)
&& peer->last_reset == PEER_DOWN_UPDATE_SOURCE_CHANGE)
bfd_sess_uninstall(peer->bfd_config->session);
if (peer_dynamic_neighbor(peer)
&& !(CHECK_FLAG(peer->flags, PEER_FLAG_DELETE))) {
if (peer_dynamic_neighbor_no_nsf(peer) &&
!(CHECK_FLAG(peer->flags, PEER_FLAG_DELETE))) {
if (bgp_debug_neighbor_events(peer))
zlog_debug("%s (dynamic neighbor) deleted", peer->host);
peer_delete(peer);
@ -1602,7 +1610,7 @@ static int bgp_stop_with_error(struct peer *peer)
if (peer->v_start >= (60 * 2))
peer->v_start = (60 * 2);
if (peer_dynamic_neighbor(peer)) {
if (peer_dynamic_neighbor_no_nsf(peer)) {
if (bgp_debug_neighbor_events(peer))
zlog_debug("%s (dynamic neighbor) deleted", peer->host);
peer_delete(peer);
@ -1620,7 +1628,7 @@ static int bgp_stop_with_notify(struct peer *peer, uint8_t code,
/* Send notify to remote peer */
bgp_notify_send(peer, code, sub_code);
if (peer_dynamic_neighbor(peer)) {
if (peer_dynamic_neighbor_no_nsf(peer)) {
if (bgp_debug_neighbor_events(peer))
zlog_debug("%s (dynamic neighbor) deleted", peer->host);
peer_delete(peer);
@ -1781,7 +1789,7 @@ static int bgp_connect_success_w_delayopen(struct peer *peer)
/* TCP connect fail */
static int bgp_connect_fail(struct peer *peer)
{
if (peer_dynamic_neighbor(peer)) {
if (peer_dynamic_neighbor_no_nsf(peer)) {
if (bgp_debug_neighbor_events(peer))
zlog_debug("%s (dynamic neighbor) deleted", peer->host);
peer_delete(peer);

View file

@ -2380,9 +2380,15 @@ static inline bool peer_established(struct peer *peer)
return peer->status == Established;
}
static inline int peer_dynamic_neighbor(struct peer *peer)
static inline bool peer_dynamic_neighbor(struct peer *peer)
{
return (CHECK_FLAG(peer->flags, PEER_FLAG_DYNAMIC_NEIGHBOR)) ? 1 : 0;
return CHECK_FLAG(peer->flags, PEER_FLAG_DYNAMIC_NEIGHBOR);
}
static inline bool peer_dynamic_neighbor_no_nsf(struct peer *peer)
{
return (peer_dynamic_neighbor(peer) &&
!CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT));
}
static inline int peer_cap_enhe(struct peer *peer, afi_t afi, safi_t safi)