1
0
mirror of https://gitlab.labs.nic.cz/labs/bird.git synced 2024-05-11 16:54:54 +00:00

Netlink: Add option to specify netlink socket receive buffer size

Add option 'netlink rx buffer' to specify netlink socket receive buffer
size. Uses SO_RCVBUFFORCE, so it can override rmem_max limit.

Thanks to Trisha Biswas and Michal for the original patches.
This commit is contained in:
Ondrej Zajicek (work)
2022-01-17 05:11:29 +01:00
parent bbc33f6ec3
commit 81ee6cda2e
5 changed files with 2243 additions and 1 deletions

View File

@@ -174,6 +174,27 @@ nl_set_strict_dump(struct nl_sock *nl, int strict)
#endif
}
static void
nl_set_rcvbuf(int fd, uint val)
{
if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &val, sizeof(val)) < 0)
log(L_WARN "KRT: Cannot set netlink rx buffer size to %u: %m", val);
}
static uint
nl_cfg_rx_buffer_size(struct config *cfg)
{
uint bufsize = 0;
struct proto_config *pc;
WALK_LIST(pc, cfg->protos)
if ((pc->protocol == &proto_unix_kernel) && !pc->disabled)
bufsize = MAX(bufsize, ((struct krt_config *) pc)->sys.netlink_rx_buffer);
return bufsize;
}
static void
nl_open(void)
{
@@ -1976,6 +1997,8 @@ krt_do_scan(struct krt_proto *p UNUSED) /* CONFIG_ALL_TABLES_AT_ONCE => p is NUL
static sock *nl_async_sk; /* BIRD socket for asynchronous notifications */
static byte *nl_async_rx_buffer; /* Receive buffer */
static uint nl_async_bufsize; /* Kernel rx buffer size for the netlink socket */
static struct config *nl_last_config; /* For tracking changes to nl_async_bufsize */
static void
nl_async_msg(struct nlmsghdr *h)
@@ -2111,6 +2134,32 @@ nl_open_async(void)
bug("Netlink: sk_open failed");
}
static void
nl_update_async_bufsize(void)
{
/* No async socket */
if (!nl_async_sk)
return;
/* Already reconfigured */
if (nl_last_config == config)
return;
/* Update netlink buffer size */
uint bufsize = nl_cfg_rx_buffer_size(config);
if (bufsize && (bufsize != nl_async_bufsize))
{
/* Log message for reconfigurations only */
if (nl_last_config)
log(L_INFO "KRT: Changing netlink rx buffer size to %u", bufsize);
nl_set_rcvbuf(nl_async_sk->fd, bufsize);
nl_async_bufsize = bufsize;
}
nl_last_config = config;
}
/*
* Interface to the UNIX krt module
@@ -2139,6 +2188,7 @@ krt_sys_start(struct krt_proto *p)
nl_open();
nl_open_async();
nl_update_async_bufsize();
return 1;
}
@@ -2146,12 +2196,16 @@ krt_sys_start(struct krt_proto *p)
void
krt_sys_shutdown(struct krt_proto *p)
{
nl_update_async_bufsize();
HASH_REMOVE2(nl_table_map, RTH, krt_pool, p);
}
int
krt_sys_reconfigure(struct krt_proto *p UNUSED, struct krt_config *n, struct krt_config *o)
{
nl_update_async_bufsize();
return (n->sys.table_id == o->sys.table_id) && (n->sys.metric == o->sys.metric);
}