diff options
author | Andy Lemin <andy@lemin.io> | 2020-11-17 14:24:59 +0100 |
---|---|---|
committer | Andy Lemin <andy@lemin.io> | 2020-11-17 14:24:59 +0100 |
commit | 8252b4771021742340f2466f5546feb48b28ec83 (patch) | |
tree | 708ead6215fde89efcf64bed9240fbf08f816fe2 /bgpd/bgp_bmp.c | |
parent | Merge pull request #7518 from donaldsharp/asic_offload_more (diff) | |
download | frr-8252b4771021742340f2466f5546feb48b28ec83.tar.xz frr-8252b4771021742340f2466f5546feb48b28ec83.zip |
bgpd: added bmp read check to detect broken sessions
Signed-off-by: Andy Lemin <andy@lemin.io>
Diffstat (limited to 'bgpd/bgp_bmp.c')
-rw-r--r-- | bgpd/bgp_bmp.c | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/bgpd/bgp_bmp.c b/bgpd/bgp_bmp.c index af88547ca..3a19a3c4c 100644 --- a/bgpd/bgp_bmp.c +++ b/bgpd/bgp_bmp.c @@ -1329,6 +1329,33 @@ static int bmp_stats(struct thread *thread) return 0; } +/* read from the BMP socket to detect session termination */ +static int bmp_read(struct thread *t) +{ + struct bmp *bmp = THREAD_ARG(t); + char buf[1024]; + ssize_t n; + + bmp->t_read = NULL; + + n = read(bmp->socket, buf, sizeof(buf)); + if (n >= 1) { + zlog_info("bmp[%s]: unexpectedly received %zu bytes", bmp->remote, n); + } else if (n == 0) { + /* the TCP session was terminated by the far end */ + bmp_wrerr(bmp, NULL, true); + return 0; + } else if (!(errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)) { + /* the TCP session experienced a fatal error, likely a timeout */ + bmp_wrerr(bmp, NULL, false); + return -1; + } + + thread_add_read(bm->master, bmp_read, bmp, bmp->socket, &bmp->t_read); + + return 0; +} + static struct bmp *bmp_open(struct bmp_targets *bt, int bmp_sock) { union sockunion su, *sumem; @@ -1349,7 +1376,6 @@ static struct bmp *bmp_open(struct bmp_targets *bt, int bmp_sock) set_nonblocking(bmp_sock); set_cloexec(bmp_sock); - shutdown(bmp_sock, SHUT_RD); sockunion2hostprefix(&su, &p); @@ -1400,6 +1426,7 @@ static struct bmp *bmp_open(struct bmp_targets *bt, int bmp_sock) bmp->state = BMP_PeerUp; bmp->pullwr = pullwr_new(bm->master, bmp_sock, bmp, bmp_wrfill, bmp_wrerr); + thread_add_read(bm->master, bmp_read, bmp, bmp_sock, &bmp->t_read); bmp_send_initiation(bmp); return bmp; @@ -1432,6 +1459,8 @@ static void bmp_close(struct bmp *bmp) struct bmp_queue_entry *bqe; struct bmp_mirrorq *bmq; + THREAD_OFF(bmp->t_read); + if (bmp->active) bmp_active_disconnected(bmp->active); |