summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_bmp.c
diff options
context:
space:
mode:
authorAndy Lemin <andy@lemin.io>2020-11-17 14:24:59 +0100
committerAndy Lemin <andy@lemin.io>2020-11-17 14:24:59 +0100
commit8252b4771021742340f2466f5546feb48b28ec83 (patch)
tree708ead6215fde89efcf64bed9240fbf08f816fe2 /bgpd/bgp_bmp.c
parentMerge pull request #7518 from donaldsharp/asic_offload_more (diff)
downloadfrr-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.c31
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);