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 /zebra/kernel_socket.c | |
| 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>
Diffstat (limited to 'zebra/kernel_socket.c')
| -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.  | 
