From: Roy Marples Date: Sun, 4 Oct 2020 19:32:26 +0000 (+0100) Subject: BSD: Detect route(4) overflows X-Git-Tag: base_7.6~462^2~1 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=68cd699df58b6a5a39d9655d90ba400960fa87d0;p=matthieu%2Ffrr.git BSD: Detect route(4) overflows NetBSD and DragonFlyBSD support reporting of route(4) overflows by setting the socket option SO_RERROR. This is handled the same as on Linux by exiting with a -1 error code. Signed-off-by: Roy Marples --- diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c index 40ac44b77f..16a9669e89 100644 --- a/zebra/kernel_socket.c +++ b/zebra/kernel_socket.c @@ -1340,13 +1340,27 @@ static int kernel_read(struct thread *thread) nbytes = read(sock, &buf, sizeof(buf)); - if (nbytes <= 0) { - if (nbytes < 0 && errno != EWOULDBLOCK && errno != EAGAIN) + if (nbytes < 0) { + if (errno == ENOBUFS) { + flog_err(EC_ZEBRA_RECVMSG_OVERRUN, + "routing socket overrun: %s", + safe_strerror(errno)); + /* + * In this case we are screwed. + * There is no good way to + * recover zebra at this point. + */ + exit(-1); + } + if (errno != EAGAIN && errno != EWOULDBLOCK) flog_err_sys(EC_LIB_SOCKET, "routing socket error: %s", safe_strerror(errno)); return 0; } + if (nbytes == 0) + return 0; + thread_add_read(zrouter.master, kernel_read, NULL, sock, NULL); if (IS_ZEBRA_DEBUG_KERNEL) @@ -1412,6 +1426,14 @@ static void routing_socket(struct zebra_ns *zns) return; } +#ifdef SO_RERROR + /* Allow reporting of route(4) buffer overflow errors */ + int n = 1; + if (setsockopt(routing_sock, SOL_SOCKET, SO_RERROR, &n, sizeof(n)) < 0) + flog_err_sys(EC_LIB_SOCKET, + "Can't set SO_RERROR on routing socket"); +#endif + /* XXX: Socket should be NONBLOCK, however as we currently * discard failed writes, this will lead to inconsistencies. * For now, socket must be blocking.