Revert "net/pimd - pull in 3e7fb0317c to prevent kernel crashes and "kernel busy" messages"

This reverts commit ce73023837.

Although it probably fixes part of the problem, pimd on FreeBSD still seems to be highly unstable even with this patch incorporated.
This commit is contained in:
Ad Schellevis 2021-11-04 22:10:27 +01:00
parent e814cc23e5
commit 2a14ee5ab7
2 changed files with 0 additions and 110 deletions

View file

@ -1,6 +1,5 @@
PORTNAME= pimd
PORTVERSION= 2.3.2
PORTREVISION= 1
CATEGORIES= net
MAINTAINER= olivier@FreeBSD.org

View file

@ -1,109 +0,0 @@
From 3e7fb0317cfa957911e20d5fc405585808abfd92 Mon Sep 17 00:00:00 2001
From: Damien Deville <damien.deville@stormshield.eu>
Date: Fri, 12 Mar 2021 08:59:10 +0100
Subject: [PATCH] Remove read retry logic and instead, use select() with a
small timeout (100ms). This is needed because FreeBSD route socket replies
for RTM_GET are queued by the kernel and thus are asynchronous. This fixes
"Kernel busy" error messages which happens when pimd reads too fast after a
write on route socket.
Sponsored by: Stormshield
---
src/routesock.c | 61 +++++++++++++++++++++++++++++++++++++------------
1 file changed, 47 insertions(+), 14 deletions(-)
diff --git a/src/routesock.c b/src/routesock.c
index a6aae4f..e2d33b3 100644
--- routesock.c
+++ routesock.c
@@ -48,6 +48,7 @@
#include <arpa/inet.h>
#include <netdb.h>
#include <stdlib.h>
+#include <sys/time.h>
/* All the BSDs have routing sockets (not Netlink), but only Linux seems
* to have SIOCGETRPF, which is used in the #else below ... the original
@@ -125,11 +126,13 @@ int init_routesock(void)
/* get the rpf neighbor info */
int k_req_incoming(uint32_t source, struct rpfctl *rpf)
{
- int rlen, l, flags = RTF_STATIC, retry_count = 3;
+ int rlen, l, flags = RTF_STATIC;
sup su;
static int seq;
char *cp = m_rtmsg.m_space;
struct rpfctl rpfinfo;
+ struct timeval wtime;
+ fd_set fdbits;
/* TODO: a hack!!!! */
#ifdef HAVE_SA_LEN
@@ -230,24 +233,54 @@ int k_req_incoming(uint32_t source, struct rpfctl *rpf)
pid = getpid();
while (1) {
- rlen = read(routing_socket, &m_rtmsg, sizeof(m_rtmsg));
- if (rlen < 0) {
- if (errno == EINTR)
- continue; /* Signalled, retry syscall. */
- if (errno == EAGAIN && retry_count--) {
- logit(LOG_DEBUG, 0, "Kernel busy, retrying (%d/3) routing socket read in one sec ...", 3 - retry_count);
- sleep(1);
- continue;
- }
+ wtime.tv_sec = 0;
+ wtime.tv_usec = 100 * 1000;
- IF_DEBUG(DEBUG_RPF | DEBUG_KERN)
- logit(LOG_DEBUG, errno, "Read from routing socket failed");
+ FD_ZERO(&fdbits);
+ FD_SET(routing_socket, &fdbits);
+ rlen = select(routing_socket + 1, &fdbits, 0, 0, &wtime);
+ if (rlen == 0) {
+ logit(LOG_WARNING, 0, "Timeout waiting for reply from routing socket for %s",
+ inet_fmt(source, s1, sizeof(s1)));
return FALSE;
}
- if (rlen > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid))
- continue;
+ if ( rlen < 0) {
+ switch (errno) {
+ case EINTR:
+ /* FALLTHROUGH */
+ case EAGAIN:
+ continue; /* Signalled, retry syscall. */
+
+ default:
+ IF_DEBUG(DEBUG_RPF | DEBUG_KERN)
+ logit(LOG_DEBUG, errno, "Select error on routing socket for %s",
+ inet_fmt(source, s1, sizeof(s1)));
+ return FALSE;
+ }
+ }
+
+ if (FD_ISSET(routing_socket, &fdbits)) {
+ rlen = read(routing_socket, &m_rtmsg, sizeof(m_rtmsg));
+ if (rlen < 0) {
+ if (errno == EINTR)
+ continue; /* Signalled, retry syscall. */
+
+ IF_DEBUG(DEBUG_RPF | DEBUG_KERN)
+ logit(LOG_DEBUG, errno, "Read from routing socket failed for %s",
+ inet_fmt(source, s1, sizeof(s1)));
+
+ return FALSE;
+ }
+
+ if (rlen > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid)) {
+ IF_DEBUG(DEBUG_RPF | DEBUG_KERN)
+ logit(LOG_DEBUG, 0, "Reply not for me, retrying: want %d(%ld) got %d(%ld)",
+ seq, (long) pid, rtm.rtm_seq, (long) rtm.rtm_pid);
+ continue;
+ }
+ }
break;
}