As suggested here:
https://github.com/systemd/systemd/pull/4296#issuecomment-
251911349
Let's try AF_INET first as socket, but let's fall back to AF_NETLINK, so that
we can use a protocol-independent socket here if possible. This has the benefit
that our code will still work even if AF_INET/AF_INET6 is made unavailable (for
exmple via seccomp), at least on current kernels.
return NULL;
}
+
+int socket_ioctl_fd(void) {
+ int fd;
+
+ /* Create a socket to invoke the various network interface ioctl()s on. Traditionally only AF_INET was good for
+ * that. Since kernel 4.6 AF_NETLINK works for this too. We first try to use AF_INET hence, but if that's not
+ * available (for example, because it is made unavailable via SECCOMP or such), we'll fall back to the more
+ * generic AF_NETLINK. */
+
+ fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC, 0);
+ if (fd < 0)
+ fd = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_GENERIC);
+ if (fd < 0)
+ return -errno;
+
+ return fd;
+}
1 + strnlen(_sa->sun_path+1, sizeof(_sa->sun_path)-1) : \
strnlen(_sa->sun_path, sizeof(_sa->sun_path))); \
})
+
+int socket_ioctl_fd(void);
#include "parse-util.h"
#include "path-util.h"
#include "set.h"
+#include "socket-util.h"
#include "stat-util.h"
#include "string-util.h"
#include "strv.h"
if (r < 0)
return r;
- sk = socket(PF_INET, SOCK_DGRAM, 0);
+ sk = socket_ioctl_fd();
if (sk < 0)
- return -errno;
+ return sk;
r = ioctl(sk, SIOCGIFNAME, &ifr);
if (r < 0)
#include "conf-parser.h"
#include "ethtool-util.h"
#include "log.h"
+#include "socket-util.h"
#include "string-table.h"
#include "strxcpyx.h"
#include "util.h"
assert_return(ret, -EINVAL);
- fd = socket(PF_INET, SOCK_DGRAM, 0);
+ fd = socket_ioctl_fd();
if (fd < 0)
- return -errno;
-
+ return fd;
*ret = fd;
return 0;