summaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
Diffstat (limited to 'libbb')
-rw-r--r--libbb/xconnect.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/libbb/xconnect.c b/libbb/xconnect.c
index 39e56b2..ea5fe17 100644
--- a/libbb/xconnect.c
+++ b/libbb/xconnect.c
@@ -11,6 +11,9 @@
#include <netinet/in.h>
#include <net/if.h>
#include <sys/un.h>
+#if ENABLE_IFPLUGD || ENABLE_FEATURE_MDEV_DAEMON || ENABLE_UEVENT
+# include <linux/netlink.h>
+#endif
#include "libbb.h"
int FAST_FUNC setsockopt_int(int fd, int level, int optname, int optval)
@@ -412,6 +415,38 @@ int FAST_FUNC create_and_bind_dgram_or_die(const char *bindaddr, int port)
}
+#if ENABLE_IFPLUGD || ENABLE_FEATURE_MDEV_DAEMON || ENABLE_UEVENT
+int FAST_FUNC create_and_bind_to_netlink(int proto, int grp, unsigned rcvbuf)
+{
+ struct sockaddr_nl sa;
+ int fd;
+
+ memset(&sa, 0, sizeof(sa));
+ sa.nl_family = AF_NETLINK;
+ sa.nl_pid = getpid();
+ sa.nl_groups = grp;
+ fd = xsocket(AF_NETLINK, SOCK_DGRAM, proto);
+ xbind(fd, (struct sockaddr *) &sa, sizeof(sa));
+ close_on_exec_on(fd);
+
+ if (rcvbuf != 0) {
+ // SO_RCVBUFFORCE (root only) can go above net.core.rmem_max sysctl
+ setsockopt_SOL_SOCKET_int(fd, SO_RCVBUF, rcvbuf);
+ setsockopt_SOL_SOCKET_int(fd, SO_RCVBUFFORCE, rcvbuf);
+# if 0
+ {
+ int z;
+ socklen_t zl = sizeof(z);
+ getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &z, &zl);
+ bb_error_msg("SO_RCVBUF:%d", z);
+ }
+# endif
+ }
+
+ return fd;
+}
+#endif
+
int FAST_FUNC create_and_connect_stream_or_die(const char *peer, int port)
{
int fd;