aboutgitcodebugslistschat
diff options
context:
space:
mode:
authorStefano Brivio <sbrivio@redhat.com>2021-05-21 11:14:52 +0200
committerStefano Brivio <sbrivio@redhat.com>2021-05-21 11:14:52 +0200
commitad4a85c86056dbab773ba3e2823b51cf1d128245 (patch)
treead2f703a77aa4e5cec0b0b0e791a7d3340b8deb7
parent19d254bbbb3ab319d15891ff7287f5182980c105 (diff)
downloadpasst-ad4a85c86056dbab773ba3e2823b51cf1d128245.tar
passt-ad4a85c86056dbab773ba3e2823b51cf1d128245.tar.gz
passt-ad4a85c86056dbab773ba3e2823b51cf1d128245.tar.bz2
passt-ad4a85c86056dbab773ba3e2823b51cf1d128245.tar.lz
passt-ad4a85c86056dbab773ba3e2823b51cf1d128245.tar.xz
passt-ad4a85c86056dbab773ba3e2823b51cf1d128245.tar.zst
passt-ad4a85c86056dbab773ba3e2823b51cf1d128245.zip
qrap: Connect to the first available instance of passt, probe via ARP request
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
-rw-r--r--arp.c15
-rw-r--r--arp.h14
-rw-r--r--qrap.c64
3 files changed, 68 insertions, 25 deletions
diff --git a/arp.c b/arp.c
index d1052ec..20f08b2 100644
--- a/arp.c
+++ b/arp.c
@@ -26,20 +26,7 @@
#include "dhcp.h"
#include "util.h"
#include "tap.h"
-
-/**
- * struct arpmsg - 802.2 ARP IPv4 payload
- * @sha: Sender hardware address
- * @sip: Sender IP address
- * @tha: Target hardware address
- * @tip: Target IP address
- */
-struct arpmsg {
- unsigned char sha[ETH_ALEN];
- unsigned char sip[4];
- unsigned char tha[ETH_ALEN];
- unsigned char tip[4];
-} __attribute__((__packed__));
+#include "arp.h"
/**
* arp() - Check if this is an ARP message, reply as needed
diff --git a/arp.h b/arp.h
index 70188b3..e9b5adf 100644
--- a/arp.h
+++ b/arp.h
@@ -1 +1,15 @@
+/**
+ * struct arpmsg - 802.2 ARP IPv4 payload
+ * @sha: Sender hardware address
+ * @sip: Sender IP address
+ * @tha: Target hardware address
+ * @tip: Target IP address
+ */
+struct arpmsg {
+ unsigned char sha[ETH_ALEN];
+ unsigned char sip[4];
+ unsigned char tha[ETH_ALEN];
+ unsigned char tip[4];
+} __attribute__((__packed__));
+
int arp(struct ctx *c, struct ethhdr *eh, size_t len);
diff --git a/qrap.c b/qrap.c
index fc7b397..5c535ff 100644
--- a/qrap.c
+++ b/qrap.c
@@ -14,21 +14,22 @@
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
-#include <sys/un.h>
#include <errno.h>
#include <linux/if_ether.h>
#include <linux/ipv6.h>
#include <linux/limits.h>
+#include <linux/un.h>
#include <limits.h>
-#include <net/if.h>
+#include <fcntl.h>
+#include <net/if_arp.h>
#include "passt.h"
-
-#define STRINGIFY(x) #x
-#define STR(x) STRINGIFY(x)
+#include "util.h"
+#include "arp.h"
static char *qemu_names[] = {
"kvm",
@@ -101,10 +102,32 @@ int main(int argc, char **argv)
int i, s, qemu_argc = 0, addr_map = 0, has_dev = 0;
struct sockaddr_un addr = {
.sun_family = AF_UNIX,
- .sun_path = UNIX_SOCK_PATH,
};
const struct pci_dev *dev = NULL;
long fd;
+ struct {
+ uint32_t vnet_len;
+ struct ethhdr eh;
+ struct arphdr ah;
+ struct arpmsg am;
+ } probe = {
+ htonl(42),
+ {
+ .h_dest = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
+ .h_source = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
+ .h_proto = htons(ETH_P_ARP),
+ },
+ { .ar_hrd = htons(ARPHRD_ETHER),
+ .ar_pro = htons(ETH_P_IP),
+ .ar_hln = ETH_ALEN,
+ .ar_pln = 4,
+ .ar_op = htons(ARPOP_REQUEST),
+ },
+ {
+ .sha = { 0 }, .sip = { 0 }, .tha = { 0 }, .tip = { 0 },
+ },
+ };
+ char probe_r;
if (argc >= 3) {
fd = strtol(argv[1], NULL, 0);
@@ -193,13 +216,32 @@ int main(int argc, char **argv)
qemu_argv[qemu_argc] = NULL;
valid_args:
- s = socket(AF_UNIX, SOCK_STREAM, 0);
- if (s < 0) {
- perror("socket");
- exit(EXIT_FAILURE);
+ for (i = 1; i < UNIX_SOCK_MAX; i++) {
+ struct timeval tv = { .tv_sec = 0, .tv_usec = 100 * 1000 };
+
+ s = socket(AF_UNIX, SOCK_STREAM, 0);
+ setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
+
+ if (s < 0) {
+ perror("socket");
+ exit(EXIT_FAILURE);
+ }
+
+ snprintf(addr.sun_path, UNIX_PATH_MAX, UNIX_SOCK_PATH, i);
+ if (!connect(s, (const struct sockaddr *)&addr, sizeof(addr)) &&
+ send(s, &probe, sizeof(probe), 0) == sizeof(probe) &&
+ recv(s, &probe_r, 1, MSG_PEEK) > 0) {
+ tv.tv_usec = 0;
+ setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
+ break;
+ }
+
+ perror("send");
+
+ close(s);
}
- if (connect(s, (const struct sockaddr *)&addr, sizeof(addr)) < 0) {
+ if (i == UNIX_SOCK_MAX) {
perror("connect");
exit(EXIT_FAILURE);
}