intel/openlldp

Out of buffers

Closed this issue · 3 comments

The following perror is triggered occasionally:

perror("recvfrom(Event interface)");

Speficically with the message:
"No buffer space available"

This usually means that the kernel has sent lots of messages down the socket and the receiver couldn't keep up.

We can either test for this and emit a lower-priority message, or we can try to re-write the polling mechanism to call the poll more frequently. Not sure what the best approach is.

Actually, this seems wrong:

if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcv_size, sizeof(int)) < 0) {

This means at best we can support 4k worth of backlog on the socket... but the default on my fedora system is like 200k - why do we shrink it?

How do you feel about the following (untested) patch:

From c807220d96262e270b4548fa759225385f209cbe Mon Sep 17 00:00:00 2001
From: Aaron Conole <aconole@redhat.com>
Date: Tue, 17 Mar 2020 09:39:39 -0400
Subject: [PATCH] event_iface: allow configurable buffer size

Signed-off-by: Aaron Conole <aconole@redhat.com>
---
 event_iface.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/event_iface.c b/event_iface.c
index 43a95c7..86c10da 100644
--- a/event_iface.c
+++ b/event_iface.c
@@ -44,6 +44,7 @@
 #include <syslog.h>
 #include <unistd.h>
 #include <fcntl.h>
+#include "config.h"
 #include "linux/if.h"
 #include "linux/if_vlan.h"
 #include "linux/rtnetlink.h"
@@ -415,18 +416,25 @@ event_iface_receive(int sock, UNUSED void *eloop_ctx, UNUSED void *sock_ctx)
 	event_if_process_recvmsg(nlh);
 }
 
+extern config_t lldpad_cfg;
+
 int event_iface_init()
 {
 	int fd;
-	int rcv_size = MAX_PAYLOAD;
+	int rcv_size = 0;
 	struct sockaddr_nl snl;
+	int rc;
 
 	fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
 
 	if (fd < 0)
 		return fd;
 
-	if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcv_size, sizeof(int)) < 0) {
+#define NL_SOCK_BUF_SETTING "nlsock_bufsz"
+	rc = config_lookup_int(&lldpad_cfg, NL_SOCK_BUF_SETTING, &rcv_size);
+	if (rc != CONFIG_FALSE && rcv_size &&
+	    setsockopt(fd, SOL_SOCKET, SO_RCVBUF,
+		       &rcv_size, sizeof(int)) < 0) {
 		close(fd);
 		return -EIO;
 	}
-- 
2.24.1

Closing this since it will be resolved as part of resovling #67