diff options
author | Stefano Brivio <sbrivio@redhat.com> | 2020-07-18 01:02:39 +0200 |
---|---|---|
committer | Stefano Brivio <sbrivio@redhat.com> | 2021-02-16 07:57:51 +0100 |
commit | fa2d20908d061fc7a4c56e793487da861af58aca (patch) | |
tree | 3f0fbf127cee167f113b82586488d3081a85a38b /qrap.c | |
parent | cefcf0bc2c73ecdbfc44c07b08df2ed69db57e2b (diff) | |
download | passt-fa2d20908d061fc7a4c56e793487da861af58aca.tar passt-fa2d20908d061fc7a4c56e793487da861af58aca.tar.gz passt-fa2d20908d061fc7a4c56e793487da861af58aca.tar.bz2 passt-fa2d20908d061fc7a4c56e793487da861af58aca.tar.lz passt-fa2d20908d061fc7a4c56e793487da861af58aca.tar.xz passt-fa2d20908d061fc7a4c56e793487da861af58aca.tar.zst passt-fa2d20908d061fc7a4c56e793487da861af58aca.zip |
merd: Switch to AF_UNIX for qemu tap, provide wrapper
We can bypass a full-fledged network interface between qemu and merd by
connecting the qemu tap file descriptor to a provided UNIX domain
socket: this could be implemented in qemu eventually, qrap covers this
meanwhile.
This also avoids the need for the AF_PACKET socket towards the guest.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Diffstat (limited to 'qrap.c')
-rw-r--r-- | qrap.c | 79 |
1 files changed, 79 insertions, 0 deletions
@@ -0,0 +1,79 @@ +/* MERD - MacVTap Egress and Routing Daemon + * + * qrap.c - qemu wrapper connecting UNIX domain socket to tap file descriptor + * + * Author: Stefano Brivio <sbrivio@redhat.com> + * License: GPLv2 + * + * TODO: Implement this functionality directly in qemu: we have TCP and UDP + * socket back-ends already. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <errno.h> +#include <limits.h> + +#include "merd.h" + +/** + * usage() - Print usage and exit + * @name: Executable name + */ +void usage(const char *name) +{ + fprintf(stderr, "Usage: %s FDNUM QEMU_CMD ...\n", name); + + exit(EXIT_FAILURE); +} + +/** + * main() - Entry point and main loop + * @argc: Argument count + * @argv: File descriptor number, then qemu with arguments + * + * Return: 0 once interrupted, non-zero on failure + */ +int main(int argc, char **argv) +{ + struct sockaddr_un addr = { + .sun_family = AF_UNIX, + .sun_path = UNIX_SOCK_PATH, + }; + long fd; + int s; + + if (argc < 3) + usage(argv[0]); + + fd = strtol(argv[1], NULL, 0); + if (fd < 3 || fd > INT_MAX || errno) + usage(argv[0]); + + s = socket(AF_UNIX, SOCK_STREAM, 0); + if (s < 0) { + perror("socket"); + exit(EXIT_FAILURE); + } + + if (connect(s, (const struct sockaddr *)&addr, sizeof(addr)) < 0) { + perror("connect"); + exit(EXIT_FAILURE); + } + + if (dup2(s, (int)fd) < 0) { + perror("dup"); + exit(EXIT_FAILURE); + } + + close(s); + + execvp(argv[2], argv + 2); + perror("execvp"); + + return EXIT_FAILURE; +} |