qrap: Add a neighbour solicitation to probe frames, instead of just ARP

For a while now, passt disables ARP functionality completely if IPv4
is disabled. If qrap sends an ARP request as a probe in that case, it
will receive no answer and move on, trying to find another instance.

Add a second probe frame, a hardcoded neighbour solicitation, so that
we get a neighbour advertisement if IPv6 is enabled.

Without this change, IPv6-only operation is completely broken.

Reported-by: Wenli Quan <wquan@redhat.com>
Reported-by: Alona Paz <alkaplan@redhat.com>
Link: https://bugzilla.redhat.com/show_bug.cgi?id=2106257
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
Stefano Brivio 2022-07-20 18:19:57 +02:00
parent b86cd006d3
commit 9af2e5d5fc

36
qrap.c
View file

@ -24,9 +24,12 @@
#include <fcntl.h> #include <fcntl.h>
#include <net/if_arp.h> #include <net/if_arp.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <netinet/ip6.h>
#include <netinet/if_ether.h> #include <netinet/if_ether.h>
#include <time.h> #include <time.h>
#include <linux/icmpv6.h>
#include "util.h" #include "util.h"
#include "passt.h" #include "passt.h"
#include "arp.h" #include "arp.h"
@ -121,12 +124,18 @@ int main(int argc, char **argv)
const struct pci_dev *dev = NULL; const struct pci_dev *dev = NULL;
long fd; long fd;
struct { struct {
uint32_t vnet_len; uint32_t vnet_len4;
struct ethhdr eh; struct ethhdr eh4;
struct arphdr ah; struct arphdr ah;
struct arpmsg am; struct arpmsg am;
} probe = {
.vnet_len = htonl(42), uint32_t vnet_len6;
struct ethhdr eh6;
struct ipv6hdr ip6hr;
struct icmp6hdr ihr;
struct in6_addr target;
} __attribute__((__packed__)) probe = {
.vnet_len4 = htonl(42),
{ {
.h_dest = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, .h_dest = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
.h_source = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, .h_source = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
@ -141,6 +150,25 @@ int main(int argc, char **argv)
{ {
.sha = { 0 }, .sip = { 0 }, .tha = { 0 }, .tip = { 0 }, .sha = { 0 }, .sip = { 0 }, .tha = { 0 }, .tip = { 0 },
}, },
.vnet_len6 = htonl(78),
{
.h_dest = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
.h_source = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
.h_proto = htons(ETH_P_IPV6),
},
{
.version = 6,
.payload_len = htons(24),
.nexthdr = IPPROTO_ICMPV6,
.hop_limit = 255,
.saddr = IN6ADDR_LOOPBACK_INIT,
.daddr = IN6ADDR_ANY_INIT,
},
{
.icmp6_type = 135,
.icmp6_code = 0,
},
IN6ADDR_ANY_INIT,
}; };
char probe_r; char probe_r;