--- /dev/null
+# This file is part of systemd.
+#
+# Database for AF_VSOCK driver implementations.
+#
+# Permitted keys:
+# Specify if the driver uses VMADDR_CID_ANY as the local CID.
+# VSOCK_ACCEPT_VMADDR_CID_ANY=1|0
+
+dmi:bvnMicrosoftCorporation:*:pvrHyper-V*
+ VSOCK_ACCEPT_VMADDR_CID_ANY=1
'70-software-radio.hwdb',
'70-sound-card.hwdb',
'70-touchpad.hwdb',
+ '70-vsock.hwdb',
'80-ieee1394-unit-function.hwdb',
'82-net-auto-link-local.hwdb')
('IMDS_KEY_USERDATA', name_literal),
('IMDS_KEY_USERDATA_BASE', name_literal),
('IMDS_KEY_USERDATA_BASE64', name_literal),
+ ('VSOCK_ACCEPT_VMADDR_CID_ANY', zero_one),
)
fixed_props = [Literal(name)('NAME') - Suppress('=') - val('VALUE') for name, val in props]
kbd_props = [
return 0;
}
-int vsock_get_local_cid(unsigned *ret) {
- _cleanup_close_ int vsock_fd = -EBADF;
-
- vsock_fd = open("/dev/vsock", O_RDONLY|O_CLOEXEC);
- if (vsock_fd < 0)
- return log_debug_errno(errno, "Failed to open %s: %m", "/dev/vsock");
-
- unsigned tmp;
- if (ioctl(vsock_fd, IOCTL_VM_SOCKETS_GET_LOCAL_CID, &tmp) < 0)
- return log_debug_errno(errno, "Failed to query local AF_VSOCK CID: %m");
- log_debug("Local AF_VSOCK CID: %u", tmp);
-
- /* If ret == NULL, we're just want to check if AF_VSOCK is available, so accept
- * any address. Otherwise, filter out special addresses that are cannot be used
- * to identify _this_ machine from the outside. */
- if (ret && IN_SET(tmp, VMADDR_CID_LOCAL, VMADDR_CID_HOST, VMADDR_CID_ANY))
- return log_debug_errno(SYNTHETIC_ERRNO(EADDRNOTAVAIL),
- "IOCTL_VM_SOCKETS_GET_LOCAL_CID returned special value (%u), ignoring.", tmp);
-
- if (ret)
- *ret = tmp;
- return 0;
-}
-
int netlink_socket_get_multicast_groups(int fd, size_t *ret_len, uint32_t **ret_groups) {
_cleanup_free_ uint32_t *groups = NULL;
socklen_t len = 0, old_len;
* authoritative. */
#define SOMAXCONN_DELUXE INT_MAX
-int vsock_get_local_cid(unsigned *ret);
-
int netlink_socket_get_multicast_groups(int fd, size_t *ret_len, uint32_t **ret_groups);
int socket_get_cookie(int fd, uint64_t *ret);
#include "parse-util.h"
#include "path-util.h"
#include "service-util.h"
-#include "socket-util.h"
#include "stat-util.h"
#include "string-util.h"
#include "strv.h"
#include "varlink-io.systemd.service.h"
#include "varlink-util.h"
#include "virt.h"
+#include "vsock-util.h"
#define VALID_DEPLOYMENT_CHARS (ALPHANUMERICAL "-.:")
#include "service-util.h"
#include "set.h"
#include "signal-util.h"
-#include "socket-util.h"
#include "special.h"
#include "string-util.h"
+#include "vsock-util.h"
static Manager* manager_unref(Manager *m);
DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_unref);
'vlan-util.c',
'volatile-util.c',
'vpick.c',
+ 'vsock-util.c',
'wall.c',
'watchdog.c',
'web-util.c',
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+#include "sd-hwdb.h"
+
+#include "fd-util.h"
+#include "fileio.h"
+#include "log.h"
+#include "parse-util.h"
+#include "string-util.h"
+#include "vsock-util.h"
+
+static int smbios_get_modalias(char **ret) {
+ int r;
+
+ assert(ret);
+
+ _cleanup_free_ char *modalias = NULL;
+ r = read_virtual_file("/sys/devices/virtual/dmi/id/modalias", SIZE_MAX, &modalias, /* ret_size= */ NULL);
+ if (r < 0)
+ return r;
+
+ truncate_nl(modalias);
+
+ *ret = TAKE_PTR(modalias);
+ return 0;
+}
+
+static int smbios_get_accepts_any(void) {
+ static int accepts_any = -1;
+ int r;
+
+ if (accepts_any >= 0)
+ return accepts_any;
+
+ _cleanup_free_ char *modalias = NULL;
+ r = smbios_get_modalias(&modalias);
+ if (r == -ENOENT)
+ return (accepts_any = false);
+ if (r < 0)
+ return log_debug_errno(r, "Failed to read DMI modalias: %m");
+
+ _cleanup_(sd_hwdb_unrefp) sd_hwdb *hwdb = NULL;
+ r = sd_hwdb_new(&hwdb);
+ if (r < 0)
+ return log_debug_errno(r, "Failed to open hwdb: %m");
+
+ const char *value;
+ r = sd_hwdb_get(hwdb, modalias, "VSOCK_ACCEPT_VMADDR_CID_ANY", &value);
+ if (r < 0) {
+ if (r != -ENOENT)
+ log_debug_errno(r, "Failed to get VSOCK_ACCEPT_VMADDR_CID_ANY, ignoring: %m");
+ return (accepts_any = false);
+ }
+ log_debug("VSOCK_ACCEPT_VMADDR_CID_ANY: %s", value);
+
+ r = parse_boolean(value);
+ if (r < 0) {
+ log_debug_errno(r, "Failed to parse VSOCK_ACCEPT_VMADDR_CID_ANY, ignoring: %m");
+ return (accepts_any = false);
+ }
+
+ return (accepts_any = r);
+}
+
+int vsock_get_local_cid(unsigned *ret) {
+ _cleanup_close_ int vsock_fd = -EBADF;
+
+ vsock_fd = open("/dev/vsock", O_RDONLY|O_CLOEXEC);
+ if (vsock_fd < 0)
+ return log_debug_errno(errno, "Failed to open %s: %m", "/dev/vsock");
+
+ unsigned tmp;
+ if (ioctl(vsock_fd, IOCTL_VM_SOCKETS_GET_LOCAL_CID, &tmp) < 0)
+ return log_debug_errno(errno, "Failed to query local AF_VSOCK CID: %m");
+ log_debug("Local AF_VSOCK CID: %u", tmp);
+
+ /* If ret == NULL, we just want to check if AF_VSOCK is available, so accept any
+ * address. Otherwise, filter out special addresses that cannot be used to identify
+ * _this_ machine from the outside. */
+ if (ret &&
+ (IN_SET(tmp, VMADDR_CID_LOCAL, VMADDR_CID_HOST) ||
+ (tmp == VMADDR_CID_ANY && smbios_get_accepts_any() <= 0)))
+ return log_debug_errno(SYNTHETIC_ERRNO(EADDRNOTAVAIL),
+ "IOCTL_VM_SOCKETS_GET_LOCAL_CID returned special value (%u), ignoring.", tmp);
+
+ if (ret)
+ *ret = tmp;
+ return 0;
+}
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include <linux/vm_sockets.h> /* IWYU pragma: export */
+
+int vsock_get_local_cid(unsigned *ret);
#include "errno-util.h"
#include "log.h"
-#include "socket-util.h"
#include "ssh-util.h"
+#include "vsock-util.h"
int vsock_open_or_warn(int *ret) {
int fd = RET_NERRNO(socket(AF_VSOCK, SOCK_STREAM|SOCK_CLOEXEC, 0));