diff options
| author | Roy Marples <roy@marples.name> | 2020-10-04 20:32:26 +0100 |
|---|---|---|
| committer | Roy Marples <roy@marples.name> | 2020-10-04 20:32:26 +0100 |
| commit | 68cd699df58b6a5a39d9655d90ba400960fa87d0 (patch) | |
| tree | 5057a543363a414e42ef8466773a14d762a0a6df | |
| parent | 4b40d5ffb0c34d4e99dd121085b46d4f4a896b72 (diff) | |
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 <roy@marples.name>
| -rw-r--r-- | zebra/kernel_socket.c | 26 |
1 files changed, 24 insertions, 2 deletions
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. |
