net-misc/bird: Backporting netlink filters on Linux from 2.0.9

Upstream commit id e818f16448e918ed07633480291283f3449dd9e4

Package-Manager: Portage-3.0.30, Repoman-3.0.3
Signed-off-by: Alarig Le Lay <alarig@swordarmor.fr>
This commit is contained in:
Alarig Le Lay 2022-02-19 13:05:13 +01:00
parent 48d854b110
commit b19dd4efd9
Signed by: alarig
GPG key ID: 7AFE62C6DF8BCDEC
2 changed files with 128 additions and 1 deletions

View file

@ -1,4 +1,4 @@
# Copyright 2020-2021 Gentoo Authors
# Copyright 2020-2022 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
EAPI=7
@ -34,6 +34,10 @@ FILECAPS=(
CAP_NET_RAW usr/sbin/bird
)
PATCHES=(
"${FILESDIR}/${P}-linux-netlink-filters.patch"
)
src_configure() {
econf \
--localstatedir="${EPREFIX}/var" \

View file

@ -0,0 +1,123 @@
diff --git a/sysdep/linux/netlink.c b/sysdep/linux/netlink.c
index 71b290fd..29b744cb 100644
--- a/sysdep/linux/netlink.c
+++ b/sysdep/linux/netlink.c
@@ -69,6 +69,10 @@
#define RTA_ENCAP 22
#endif
+#ifndef NETLINK_GET_STRICT_CHK
+#define NETLINK_GET_STRICT_CHK 12
+#endif
+
#define krt_ipv4(p) ((p)->af == AF_INET)
#define krt_ecmp6(p) ((p)->af == AF_INET6)
@@ -158,11 +162,39 @@ nl_open_sock(struct nl_sock *nl)
}
static void
-nl_set_strict_dump(struct nl_sock *nl, int strict)
+nl_set_strict_dump(struct nl_sock *nl UNUSED, int strict UNUSED)
{
+ /*
+ * Strict checking is not necessary, it improves behavior on newer kernels.
+ * If it is not available (missing SOL_NETLINK compile-time, or ENOPROTOOPT
+ * run-time), we can just ignore it.
+ */
+#ifdef SOL_NETLINK
setsockopt(nl->fd, SOL_NETLINK, NETLINK_GET_STRICT_CHK, &strict, sizeof(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)
{
@@ -1965,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)
@@ -2100,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
@@ -2128,6 +2188,7 @@ krt_sys_start(struct krt_proto *p)
nl_open();
nl_open_async();
+ nl_update_async_bufsize();
return 1;
}
@@ -2135,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);
}