diff options
| author | Rafael Zalamena <rzalamena@opensourcerouting.org> | 2020-05-21 16:02:44 -0300 |
|---|---|---|
| committer | Rafael Zalamena <rzalamena@opensourcerouting.org> | 2020-05-29 17:48:14 -0300 |
| commit | 95a99382cbeb756344c02aef44f862abee53c3b8 (patch) | |
| tree | b1818ee18200846361b474df2edeabda3442499e /bgpd/bgp_bfd.c | |
| parent | 68286f96197c7d1775eb75acc6713b05e57a95d7 (diff) | |
bgpd: fix crash on daemon exit
Don't attempt to send BFD daemon a message to remove the peer
registration on daemon exit, otherwise we'll access a dangling
interface pointer and we'll crash.
This crash was not previosly possible because the function that built
the message was passing the interface pointer but not using it due to
the exit condition.
In `lib/bfd.c`:
```
void bfd_peer_sendmsg(struct zclient *zclient, struct bfd_info *bfd_info,
int family, void *dst_ip, void *src_ip, char *if_name,
int ttl, int multihop, int cbit, int command,
int set_flag, vrf_id_t vrf_id)
{
struct bfd_session_arg args = {};
size_t addrlen;
/* Individual reg/dereg messages are suppressed during shutdown. */
if (CHECK_FLAG(bfd_gbl.flags, BFD_GBL_FLAG_IN_SHUTDOWN)) {
if (bfd_debug)
zlog_debug(
"%s: Suppressing BFD peer reg/dereg messages",
__func__);
return;
}
```
Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
Diffstat (limited to 'bgpd/bgp_bfd.c')
| -rw-r--r-- | bgpd/bgp_bfd.c | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/bgpd/bgp_bfd.c b/bgpd/bgp_bfd.c index 74ff6f4472..ad31fd6418 100644 --- a/bgpd/bgp_bfd.c +++ b/bgpd/bgp_bfd.c @@ -101,6 +101,19 @@ static void bgp_bfd_peer_sendmsg(struct peer *peer, int command) vrf_id_t vrf_id; size_t addrlen; + /* + * XXX: some pointers are dangling during shutdown, so instead of + * trying to send a message during signal handlers lets just wait BGP + * to terminate zebra's connection and BFD will automatically find + * out that we are no longer expecting notifications. + * + * The pointer that is causing a crash here is `peer->nexthop.ifp`. + * That happens because at this point of the shutdown all interfaces are + * already `free()`d. + */ + if (bm->terminating) + return; + bfd_info = (struct bfd_info *)peer->bfd_info; vrf_id = peer->bgp->vrf_id; |
