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>
This commit is contained in:
Roy Marples 2020-10-04 20:32:26 +01:00
parent 4b40d5ffb0
commit 68cd699df5

View File

@ -1340,13 +1340,27 @@ static int kernel_read(struct thread *thread)
nbytes = read(sock, &buf, sizeof(buf)); nbytes = read(sock, &buf, sizeof(buf));
if (nbytes <= 0) { if (nbytes < 0) {
if (nbytes < 0 && errno != EWOULDBLOCK && errno != EAGAIN) 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", flog_err_sys(EC_LIB_SOCKET, "routing socket error: %s",
safe_strerror(errno)); safe_strerror(errno));
return 0; return 0;
} }
if (nbytes == 0)
return 0;
thread_add_read(zrouter.master, kernel_read, NULL, sock, NULL); thread_add_read(zrouter.master, kernel_read, NULL, sock, NULL);
if (IS_ZEBRA_DEBUG_KERNEL) if (IS_ZEBRA_DEBUG_KERNEL)
@ -1412,6 +1426,14 @@ static void routing_socket(struct zebra_ns *zns)
return; 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 /* XXX: Socket should be NONBLOCK, however as we currently
* discard failed writes, this will lead to inconsistencies. * discard failed writes, this will lead to inconsistencies.
* For now, socket must be blocking. * For now, socket must be blocking.