Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package passt for openSUSE:Factory checked in at 2024-11-27 22:10:47 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/passt (Old) and /work/SRC/openSUSE:Factory/.passt.new.28523 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "passt" Wed Nov 27 22:10:47 2024 rev:19 rq:1226923 version:20241127.c0fbc7e Changes: -------- --- /work/SRC/openSUSE:Factory/passt/passt.changes 2024-11-26 20:55:35.569669173 +0100 +++ /work/SRC/openSUSE:Factory/.passt.new.28523/passt.changes 2024-11-27 22:12:37.327685256 +0100 @@ -1,0 +2,14 @@ +Wed Nov 27 14:19:40 UTC 2024 - dcer...@suse.com + +- Update to version 20241127.c0fbc7e: + * dhcp: Honour broadcast flag (RFC 2131, 4.1) + * dhcp: Introduce support for Rapid Commit (option 80, RFC 4039) + * dhcp: Use -1 as "missing option" length instead of 0 + * treewide: Introduce 'local mode' for disconnected setups + * test: Improve logic for waiting for SLAAC & DAD to complete in NDP tests + * ndp: Don't send first periodic router advertisement right after guest connects + * test/perf: Select a single IPv6 namespace address in pasta tests + * conf, passt.1: Update --mac-addr default in usage() and man page + * passt.1: Fix "default" note about --map-guest-addr + +------------------------------------------------------------------- Old: ---- passt-20241121.238c69f.tar.zst New: ---- passt-20241127.c0fbc7e.tar.zst ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ passt.spec ++++++ --- /var/tmp/diff_new_pack.uclOjn/_old 2024-11-27 22:12:37.775703967 +0100 +++ /var/tmp/diff_new_pack.uclOjn/_new 2024-11-27 22:12:37.779704134 +0100 @@ -45,7 +45,7 @@ %global selinuxtype targeted Name: passt -Version: 20241121.238c69f +Version: 20241127.c0fbc7e Release: 0 Summary: User-mode networking daemons for virtual machines and namespaces License: GPL-2.0-or-later AND BSD-3-Clause ++++++ _service ++++++ --- /var/tmp/diff_new_pack.uclOjn/_old 2024-11-27 22:12:37.819705808 +0100 +++ /var/tmp/diff_new_pack.uclOjn/_new 2024-11-27 22:12:37.823705976 +0100 @@ -4,7 +4,7 @@ <param name="scm">git</param> <param name="changesgenerate">enable</param> <param name="versionformat">%cs.%h</param> - <param name="revision">2024_11_21.238c69f</param> + <param name="revision">2024_11_27.c0fbc7e</param> </service> <service mode="manual" name="recompress"> <param name="file">*.tar</param> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.uclOjn/_old 2024-11-27 22:12:37.847706980 +0100 +++ /var/tmp/diff_new_pack.uclOjn/_new 2024-11-27 22:12:37.851707148 +0100 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://passt.top/passt</param> - <param name="changesrevision">238c69f9af458e41dea5ad8c988dbf65b05b5172</param></service></servicedata> + <param name="changesrevision">c0fbc7ef2ae2919bf6162b4149d341f448289836</param></service></servicedata> (No newline at EOF) ++++++ passt-20241121.238c69f.tar.zst -> passt-20241127.c0fbc7e.tar.zst ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/passt-20241121.238c69f/conf.c new/passt-20241127.c0fbc7e/conf.c --- old/passt-20241121.238c69f/conf.c 2024-11-21 06:52:36.000000000 +0100 +++ new/passt-20241127.c0fbc7e/conf.c 2024-11-27 05:37:28.000000000 +0100 @@ -48,6 +48,20 @@ #define NETNS_RUN_DIR "/run/netns" +#define IP4_LL_GUEST_ADDR (struct in_addr){ htonl_constant(0xa9fe0201) } + /* 169.254.2.1, libslirp default: 10.0.2.1 */ + +#define IP4_LL_GUEST_GW (struct in_addr){ htonl_constant(0xa9fe0202) } + /* 169.254.2.2, libslirp default: 10.0.2.2 */ + +#define IP4_LL_PREFIX_LEN 16 + +#define IP6_LL_GUEST_GW (struct in6_addr) \ + {{{ 0xfe, 0x80, 0, 0, 0, 0, 0, 0, \ + 0, 0, 0, 0, 0, 0, 0, 0x01 }}} + +const char *pasta_default_ifn = "tap0"; + /** * next_chunk - Return the next piece of a string delimited by a character * @s: String to search @@ -631,7 +645,7 @@ ifi = nl_get_ext_if(nl_sock, AF_INET); if (!ifi) { - info("Couldn't pick external interface: disabling IPv4"); + debug("Failed to detect external interface for IPv4"); return 0; } @@ -639,8 +653,8 @@ int rc = nl_route_get_def(nl_sock, ifi, AF_INET, &ip4->guest_gw); if (rc < 0) { - err("Couldn't discover IPv4 gateway address: %s", - strerror(-rc)); + debug("Couldn't discover IPv4 gateway address: %s", + strerror(-rc)); return 0; } } @@ -649,8 +663,8 @@ int rc = nl_addr_get(nl_sock, ifi, AF_INET, &ip4->addr, &ip4->prefix_len, NULL); if (rc < 0) { - err("Couldn't discover IPv4 address: %s", - strerror(-rc)); + debug("Couldn't discover IPv4 address: %s", + strerror(-rc)); return 0; } } @@ -678,6 +692,19 @@ } /** + * conf_ip4_local() - Configure IPv4 addresses and attributes for local mode + * @ip4: IPv4 context (will be written) + */ +static void conf_ip4_local(struct ip4_ctx *ip4) +{ + ip4->addr_seen = ip4->addr = IP4_LL_GUEST_ADDR; + ip4->our_tap_addr = ip4->guest_gw = IP4_LL_GUEST_GW; + ip4->prefix_len = IP4_LL_PREFIX_LEN; + + ip4->no_copy_addrs = ip4->no_copy_routes = true; +} + +/** * conf_ip6() - Verify or detect IPv6 support, get relevant addresses * @ifi: Host interface to attempt (0 to determine one) * @ip6: IPv6 context (will be written) @@ -693,15 +720,15 @@ ifi = nl_get_ext_if(nl_sock, AF_INET6); if (!ifi) { - info("Couldn't pick external interface: disabling IPv6"); + debug("Failed to detect external interface for IPv6"); return 0; } if (IN6_IS_ADDR_UNSPECIFIED(&ip6->guest_gw)) { rc = nl_route_get_def(nl_sock, ifi, AF_INET6, &ip6->guest_gw); if (rc < 0) { - err("Couldn't discover IPv6 gateway address: %s", - strerror(-rc)); + debug("Couldn't discover IPv6 gateway address: %s", + strerror(-rc)); return 0; } } @@ -710,7 +737,7 @@ IN6_IS_ADDR_UNSPECIFIED(&ip6->addr) ? &ip6->addr : NULL, &prefix_len, &ip6->our_tap_ll); if (rc < 0) { - err("Couldn't discover IPv6 address: %s", strerror(-rc)); + debug("Couldn't discover IPv6 address: %s", strerror(-rc)); return 0; } @@ -727,6 +754,17 @@ } /** + * conf_ip6_local() - Configure IPv6 addresses and attributes for local mode + * @ip6: IPv6 context (will be written) + */ +static void conf_ip6_local(struct ip6_ctx *ip6) +{ + ip6->our_tap_ll = ip6->guest_gw = IP6_LL_GUEST_GW; + + ip6->no_copy_addrs = ip6->no_copy_routes = true; +} + +/** * usage() - Print usage, exit with given status code * @name: Executable name * @f: Stream to print usage info to @@ -788,7 +826,7 @@ " -n, --netmask MASK Assign IPv4 MASK, dot-decimal or bits\n" " default: netmask from matching address on the host\n" " -M, --mac-addr ADDR Use source MAC address ADDR\n" - " default: MAC address from interface with default route\n" + " default: 9a:55:9a:55:9a:55 (locally administered)\n" " -g, --gateway ADDR Pass IPv4 or IPv6 address as gateway\n" " default: gateway from interface with default route\n" " -i, --interface NAME Interface for addresses and routes\n" @@ -948,12 +986,14 @@ char bufmac[ETH_ADDRSTRLEN], ifn[IFNAMSIZ]; int i; - info("Template interface: %s%s%s%s%s", - c->ifi4 ? if_indextoname(c->ifi4, ifn) : "", - c->ifi4 ? " (IPv4)" : "", - (c->ifi4 && c->ifi6) ? ", " : "", - c->ifi6 ? if_indextoname(c->ifi6, ifn) : "", - c->ifi6 ? " (IPv6)" : ""); + if (c->ifi4 > 0 || c->ifi6 > 0) { + info("Template interface: %s%s%s%s%s", + c->ifi4 > 0 ? if_indextoname(c->ifi4, ifn) : "", + c->ifi4 > 0 ? " (IPv4)" : "", + (c->ifi4 && c->ifi6) ? ", " : "", + c->ifi6 > 0 ? if_indextoname(c->ifi6, ifn) : "", + c->ifi6 > 0 ? " (IPv6)" : ""); + } if (*c->ip4.ifname_out || *c->ip6.ifname_out) { info("Outbound interface: %s%s%s%s%s", @@ -1024,9 +1064,9 @@ if (!c->no_ndp && !c->no_dhcpv6) info("NDP/DHCPv6:"); - else if (!c->no_ndp) - info("DHCPv6:"); else if (!c->no_dhcpv6) + info("DHCPv6:"); + else if (!c->no_ndp) info("NDP:"); else goto dns6; @@ -1733,10 +1773,23 @@ c->ifi4 = conf_ip4(ifi4, &c->ip4); if (!v4_only) c->ifi6 = conf_ip6(ifi6, &c->ip6); - if ((!c->ifi4 && !c->ifi6) || - (*c->ip4.ifname_out && !c->ifi4) || + if ((*c->ip4.ifname_out && !c->ifi4) || (*c->ip6.ifname_out && !c->ifi6)) die("External interface not usable"); + if (!c->ifi4 && !c->ifi6) { + info("No external interface as template, switch to local mode"); + + conf_ip4_local(&c->ip4); + c->ifi4 = -1; + + conf_ip6_local(&c->ip6); + c->ifi6 = -1; + + if (!*c->pasta_ifn) { + strncpy(c->pasta_ifn, pasta_default_ifn, + sizeof(c->pasta_ifn) - 1); + } + } if (c->ifi4 && !no_map_gw && IN4_IS_ADDR_UNSPECIFIED(&c->ip4.map_host_loopback)) @@ -1840,6 +1893,8 @@ if (!c->ifi6) { c->no_ndp = 1; c->no_dhcpv6 = 1; + } else if (IN6_IS_ADDR_UNSPECIFIED(&c->ip6.addr)) { + c->no_dhcpv6 = 1; } if (!c->mtu) @@ -1848,9 +1903,9 @@ get_dns(c); if (!*c->pasta_ifn) { - if (c->ifi4) + if (c->ifi4 > 0) if_indextoname(c->ifi4, c->pasta_ifn); - else + else if (c->ifi6 > 0) if_indextoname(c->ifi6, c->pasta_ifn); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/passt-20241121.238c69f/dhcp.c new/passt-20241127.c0fbc7e/dhcp.c --- old/passt-20241121.238c69f/dhcp.c 2024-11-21 06:52:36.000000000 +0100 +++ new/passt-20241127.c0fbc7e/dhcp.c 2024-11-27 05:37:28.000000000 +0100 @@ -36,9 +36,9 @@ /** * struct opt - DHCP option * @sent: Convenience flag, set while filling replies - * @slen: Length of option defined for server + * @slen: Length of option defined for server, -1 if not going to be sent * @s: Option payload from server - * @clen: Length of option received from client + * @clen: Length of option received from client, -1 if not received * @c: Option payload from client */ struct opt { @@ -68,6 +68,11 @@ */ void dhcp_init(void) { + int i; + + for (i = 0; i < ARRAY_SIZE(opts); i++) + opts[i].slen = -1; + opts[1] = (struct opt) { 0, 4, { 0 }, 0, { 0 }, }; /* Mask */ opts[3] = (struct opt) { 0, 4, { 0 }, 0, { 0 }, }; /* Router */ opts[51] = (struct opt) { 0, 4, { 0xff, @@ -107,6 +112,8 @@ uint32_t xid; uint16_t secs; uint16_t flags; +#define FLAG_BROADCAST htons_constant(0x8000) + uint32_t ciaddr; struct in_addr yiaddr; uint32_t siaddr; @@ -154,17 +161,17 @@ * option 53 at the beginning of the list. * Put it there explicitly, unless requested via option 55. */ - if (!memchr(opts[55].c, 53, opts[55].clen)) + if (opts[55].clen > 0 && !memchr(opts[55].c, 53, opts[55].clen)) fill_one(m, 53, &offset); for (i = 0; i < opts[55].clen; i++) { o = opts[55].c[i]; - if (opts[o].slen) + if (opts[o].slen != -1) fill_one(m, o, &offset); } for (o = 0; o < 255; o++) { - if (opts[o].slen && !opts[o].sent) + if (opts[o].slen != -1 && !opts[o].sent) fill_one(m, o, &offset); } @@ -264,6 +271,9 @@ ".\xc0"); } } + + if (!opts[119].slen) + opts[119].slen = -1; } /** @@ -277,10 +287,10 @@ { size_t mlen, dlen, offset = 0, opt_len, opt_off = 0; char macstr[ETH_ADDRSTRLEN]; + struct in_addr mask, dst; const struct ethhdr *eh; const struct iphdr *iph; const struct udphdr *uh; - struct in_addr mask; unsigned int i; struct msg *m; @@ -313,6 +323,9 @@ offset += offsetof(struct msg, o); + for (i = 0; i < ARRAY_SIZE(opts); i++) + opts[i].clen = -1; + while (opt_off + 2 < opt_len) { const uint8_t *olen, *val; uint8_t *type; @@ -331,11 +344,19 @@ opt_off += *olen + 2; } - if (opts[53].c[0] == DHCPDISCOVER) { - info("DHCP: offer to discover"); - opts[53].s[0] = DHCPOFFER; - } else if (opts[53].c[0] == DHCPREQUEST || !opts[53].clen) { - info("%s: ack to request", opts[53].clen ? "DHCP" : "BOOTP"); + opts[80].slen = -1; + if (opts[53].clen > 0 && opts[53].c[0] == DHCPDISCOVER) { + if (opts[80].clen == -1) { + info("DHCP: offer to discover"); + opts[53].s[0] = DHCPOFFER; + } else { + info("DHCP: ack to discover (Rapid Commit)"); + opts[53].s[0] = DHCPACK; + opts[80].slen = 0; + } + } else if (opts[53].clen <= 0 || opts[53].c[0] == DHCPREQUEST) { + info("%s: ack to request", /* DHCP needs a valid message type */ + (opts[53].clen <= 0) ? "BOOTP" : "DHCP"); opts[53].s[0] = DHCPACK; } else { return -1; @@ -374,12 +395,20 @@ ((struct in_addr *)opts[6].s)[i] = c->ip4.dns[i]; opts[6].slen += sizeof(uint32_t); } + if (!opts[6].slen) + opts[6].slen = -1; if (!c->no_dhcp_dns_search) opt_set_dns_search(c, sizeof(m->o)); dlen = offsetof(struct msg, o) + fill(m); - tap_udp4_send(c, c->ip4.our_tap_addr, 67, c->ip4.addr, 68, m, dlen); + + if (m->flags & FLAG_BROADCAST) + dst = in4addr_broadcast; + else + dst = c->ip4.addr; + + tap_udp4_send(c, c->ip4.our_tap_addr, 67, dst, 68, m, dlen); return 1; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/passt-20241121.238c69f/ip.h new/passt-20241127.c0fbc7e/ip.h --- old/passt-20241121.238c69f/ip.h 2024-11-21 06:52:36.000000000 +0100 +++ new/passt-20241127.c0fbc7e/ip.h 2024-11-27 05:37:28.000000000 +0100 @@ -101,4 +101,7 @@ }, }; +/* IPv4 Limited Broadcast (RFC 919, Section 7), 255.255.255.255 */ +static const struct in_addr in4addr_broadcast = { 0xffffffff }; + #endif /* IP_H */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/passt-20241121.238c69f/ndp.c new/passt-20241127.c0fbc7e/ndp.c --- old/passt-20241121.238c69f/ndp.c 2024-11-21 06:52:36.000000000 +0100 +++ new/passt-20241127.c0fbc7e/ndp.c 2024-11-27 05:37:28.000000000 +0100 @@ -420,9 +420,13 @@ interval = min_rtr_adv_interval + random() % (max_rtr_adv_interval - min_rtr_adv_interval); + if (!next_ra) + goto first; + info("NDP: sending unsolicited RA, next in %llds", (long long)interval); ndp_ra(c, &in6addr_ll_all_nodes); +first: next_ra = now->tv_sec + interval; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/passt-20241121.238c69f/passt.1 new/passt-20241127.c0fbc7e/passt.1 --- old/passt-20241121.238c69f/passt.1 2024-11-21 06:52:36.000000000 +0100 +++ new/passt-20241127.c0fbc7e/passt.1 2024-11-27 05:37:28.000000000 +0100 @@ -160,7 +160,9 @@ By default, assigned IPv4 and IPv6 addresses are taken from the host interfaces with the first default route, if any, for the corresponding IP version. If no default routes are available and there is any interface with any route for a -given IP version, the first of these interfaces will be chosen instead. +given IP version, the first of these interfaces will be chosen instead. If no +such interface exists, the link-local address 169.254.2.1 is assigned for IPv4, +and no additional address will be assigned for IPv6. .TP .BR \-n ", " \-\-netmask " " \fImask @@ -174,8 +176,7 @@ .BR \-M ", " \-\-mac-addr " " \fIaddr Use source MAC address \fIaddr\fR when communicating to the guest or to the target namespace. -Default is to use the MAC address of the interface with the first IPv4 default -route on the host. +Default is the locally administered MAC addresses 9a:55:9a:55:9a:55. .TP .BR \-g ", " \-\-gateway " " \fIaddr @@ -188,7 +189,9 @@ route is a multipath one, the gateway is the first nexthop router returned by the kernel which has the highest weight in the set of paths. If no default routes are available and there is just one interface with any route, that -interface will be chosen instead. +interface will be chosen instead. If no such interface exists, the link-local +address 169.254.2.2 is used for IPv4, and the link-local address fe80::1 is used +for IPv6. Note: these addresses are also used as source address for packets directed to the guest or to the target namespace having a loopback or local source address, @@ -203,7 +206,9 @@ If no interfaces are given, the interface with the first default routes for each IP version is selected. If no default routes are available and there is just one -interface with any route, that interface will be chosen instead. +interface with any route, that interface will be chosen instead. If no such +interface exists, host interfaces will be ignored for the purposes of assigning +addresses and routes, and link-local addresses will be used instead. .TP .BR \-o ", " \-\-outbound " " \fIaddr @@ -222,7 +227,8 @@ By default, the interface given by the default route is selected. If no default routes are available and there is just one interface with any route, that -interface will be chosen instead. +interface will be chosen instead. If no such interface exists, outbound sockets +will not be bound to any specific interface. .TP .BR \-\-outbound-if6 " " \fIname @@ -232,7 +238,8 @@ By default, the interface given by the default route is selected. If no default routes are available and there is just one interface with any route, that -interface will be chosen instead. +interface will be chosen instead. If no such interface exists, outbound sockets +will not be bound to any specific interface. .TP .BR \-D ", " \-\-dns " " \fIaddr @@ -373,14 +380,14 @@ address on the host. That is, packets from the guest to \fIaddr\fR will be redirected to the address assigned to the guest with \fB-a\fR, or by default the host's global address. This allows the guest to -access services availble on the host's global address, even though its +access services available on the host's global address, even though its own address shadows that of the host. If \fIaddr\fR is 'none', no address is mapped. Only one IPv4 and one IPv6 address can be translated, and if the option is specified multiple times, the last one for each address type takes effect. -Default is no mapping. +By default, mapping happens as described for the \-\-map-host-loopback option. .TP .BR \-4 ", " \-\-ipv4-only @@ -504,6 +511,7 @@ .BR \-I ", " \-\-ns-ifname " " \fIname Name of tap interface to be created in target namespace. By default, the same interface name as the external, routable interface is used. +If no such interface exists, the name \fItap0\fR will be used instead. .TP .BR \-t ", " \-\-tcp-ports " " \fIspec @@ -1032,6 +1040,20 @@ current sending buffer size to guest or target namespace. This might affect throughput of TCP connections. +.SS Local mode for disconnected setups + +If \fBpasst\fR and \fBpasta\fR fail to find a host interface with a configured +address, other than loopback addresses, they will, obviously, not attempt to +source addresses or routes from the host. + +In this case, unless configured otherwise, they will assign the IPv4 link-local +address 169.254.2.1 to the guest or target namespace, and no IPv6 address. The +notion of the guest or target namespace IPv6 address is derived from the first +link-local address observed. + +Default gateways will be assigned as the link-local address 169.254.2.2 for +IPv4, and as the link-local address fe80::1 for IPv6. + .SH LIMITATIONS Currently, IGMP/MLD proxying (RFC 4605) and support for SCTP (RFC 4960) are not diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/passt-20241121.238c69f/passt.h new/passt-20241127.c0fbc7e/passt.h --- old/passt-20241121.238c69f/passt.h 2024-11-21 06:52:36.000000000 +0100 +++ new/passt-20241127.c0fbc7e/passt.h 2024-11-27 05:37:28.000000000 +0100 @@ -202,10 +202,10 @@ * @our_tap_mac: Pasta/passt's MAC on the tap link * @guest_mac: MAC address of guest or namespace, seen or configured * @hash_secret: 128-bit secret for siphash functions - * @ifi4: Index of template interface for IPv4, 0 if IPv4 disabled + * @ifi4: Template interface for IPv4, -1: none, 0: IPv4 disabled * @ip: IPv4 configuration * @dns_search: DNS search list - * @ifi6: Index of template interface for IPv6, 0 if IPv6 disabled + * @ifi6: Template interface for IPv6, -1: none, 0: IPv6 disabled * @ip6: IPv6 configuration * @pasta_ifn: Name of namespace interface for pasta * @pasta_ifi: Index of namespace interface for pasta @@ -258,12 +258,12 @@ unsigned char guest_mac[ETH_ALEN]; uint64_t hash_secret[2]; - unsigned int ifi4; + int ifi4; struct ip4_ctx ip4; struct fqdn dns_search[MAXDNSRCH]; - unsigned int ifi6; + int ifi6; struct ip6_ctx ip6; char pasta_ifn[IF_NAMESIZE]; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/passt-20241121.238c69f/pasta.c new/passt-20241127.c0fbc7e/pasta.c --- old/passt-20241121.238c69f/pasta.c 2024-11-21 06:52:36.000000000 +0100 +++ new/passt-20241127.c0fbc7e/pasta.c 2024-11-27 05:37:28.000000000 +0100 @@ -369,8 +369,11 @@ 0, IFF_NOARP); if (c->ip6.no_copy_addrs) { - rc = nl_addr_set(nl_sock_ns, c->pasta_ifi, - AF_INET6, &c->ip6.addr, 64); + if (!IN6_IS_ADDR_UNSPECIFIED(&c->ip6.addr)) { + rc = nl_addr_set(nl_sock_ns, + c->pasta_ifi, AF_INET6, + &c->ip6.addr, 64); + } } else { rc = nl_addr_dup(nl_sock, c->ifi6, nl_sock_ns, c->pasta_ifi, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/passt-20241121.238c69f/tap.c new/passt-20241127.c0fbc7e/tap.c --- old/passt-20241121.238c69f/tap.c 2024-11-21 06:52:36.000000000 +0100 +++ new/passt-20241127.c0fbc7e/tap.c 2024-11-27 05:37:28.000000000 +0100 @@ -803,6 +803,9 @@ if (IN6_IS_ADDR_UNSPECIFIED(&c->ip6.addr_seen)) { c->ip6.addr_seen = *saddr; } + + if (IN6_IS_ADDR_UNSPECIFIED(&c->ip6.addr)) + c->ip6.addr = *saddr; } else if (!IN6_IS_ADDR_UNSPECIFIED(saddr)){ c->ip6.addr_seen = *saddr; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/passt-20241121.238c69f/test/passt/ndp new/passt-20241127.c0fbc7e/test/passt/ndp --- old/passt-20241121.238c69f/test/passt/ndp 2024-11-21 06:52:36.000000000 +0100 +++ new/passt-20241127.c0fbc7e/test/passt/ndp 2024-11-27 05:37:28.000000000 +0100 @@ -17,13 +17,13 @@ test Interface name gout IFNAME ip -j link show | jq -rM '.[] | select(.link_type == "ether").ifname' guest ip link set dev __IFNAME__ up -# Wait for DAD to complete -guest while ip -j -6 addr show tentative | jq -e '.[].addr_info'; do sleep 0.1; done +# Wait for SLAAC & DAD to complete +guest while ! ip -j -6 addr show dev __IFNAME__ | jq -e '.[].addr_info.[] | select(.protocol == "kernel_ra")'; do sleep 0.1; done hout HOST_IFNAME6 ip -j -6 route show|jq -rM '[.[] | select(.dst == "default").dev] | .[0]' check [ -n "__IFNAME__" ] test SLAAC: prefix -gout ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__IFNAME__").addr_info[] | select(.scope == "global" and .protocol == "kernel_ra") | .local + "/" + (.prefixlen | tostring)] | .[0]' +gout ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__IFNAME__").addr_info[] | select(.protocol == "kernel_ra") | .local + "/" + (.prefixlen | tostring)] | .[0]' gout PREFIX6 sipcalc __ADDR6__ | grep prefix | cut -d' ' -f4 hout HOST_ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope == "global" and .deprecated != true).local] | .[0]' hout HOST_PREFIX6 sipcalc __HOST_ADDR6__/64 | grep prefix | cut -d' ' -f4 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/passt-20241121.238c69f/test/pasta/ndp new/passt-20241127.c0fbc7e/test/pasta/ndp --- old/passt-20241121.238c69f/test/pasta/ndp 2024-11-21 06:52:36.000000000 +0100 +++ new/passt-20241127.c0fbc7e/test/pasta/ndp 2024-11-27 05:37:28.000000000 +0100 @@ -18,11 +18,11 @@ nsout IFNAME ip -j link show | jq -rM '.[] | select(.link_type == "ether").ifname' check [ -n "__IFNAME__" ] ns ip link set dev __IFNAME__ up -# Wait for DAD to complete -ns while ip -j -6 addr show tentative | jq -e '.[].addr_info'; do sleep 0.1; done +# Wait for SLAAC & DAD to complete +ns while ! ip -j -6 addr show dev __IFNAME__ | jq -e '.[].addr_info.[] | select(.protocol == "kernel_ra")'; do sleep 0.1; done test SLAAC: prefix -nsout ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__IFNAME__").addr_info[] | select(.scope == "global" and .protocol == "kernel_ra") | .local + "/" + (.prefixlen | tostring)] | .[0]' +nsout ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__IFNAME__").addr_info[] | select(.protocol == "kernel_ra") | .local + "/" + (.prefixlen | tostring)] | .[0]' nsout PREFIX6 sipcalc __ADDR6__ | grep prefix | cut -d' ' -f4 hout HOST_ADDR6 ip -j -6 addr show|jq -rM ['.[] | select(.ifname == "__IFNAME__").addr_info[] | select(.scope == "global" and .deprecated != true).local] | .[0]' hout HOST_PREFIX6 sipcalc __HOST_ADDR6__/64 | grep prefix | cut -d' ' -f4 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/passt-20241121.238c69f/test/perf/pasta_tcp new/passt-20241127.c0fbc7e/test/perf/pasta_tcp --- old/passt-20241121.238c69f/test/perf/pasta_tcp 2024-11-21 06:52:36.000000000 +0100 +++ new/passt-20241127.c0fbc7e/test/perf/pasta_tcp 2024-11-27 05:37:28.000000000 +0100 @@ -211,7 +211,7 @@ iperf3s ns 10002 nsout IFNAME ip -j link show | jq -rM '.[] | select(.link_type == "ether").ifname' -nsout ADDR6 ip -j -6 addr show|jq -rM '.[] | select(.ifname == "__IFNAME__").addr_info[] | select(.scope == "global").local' +nsout ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__IFNAME__").addr_info[] | select(.scope == "global").local] | .[0]' bw - bw - bw - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/passt-20241121.238c69f/test/perf/pasta_udp new/passt-20241127.c0fbc7e/test/perf/pasta_udp --- old/passt-20241121.238c69f/test/perf/pasta_udp 2024-11-21 06:52:36.000000000 +0100 +++ new/passt-20241127.c0fbc7e/test/perf/pasta_udp 2024-11-27 05:37:28.000000000 +0100 @@ -196,7 +196,7 @@ iperf3s ns 10002 nsout IFNAME ip -j link show | jq -rM '.[] | select(.link_type == "ether").ifname' -nsout ADDR6 ip -j -6 addr show|jq -rM '.[] | select(.ifname == "__IFNAME__").addr_info[] | select(.scope == "global").local' +nsout ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__IFNAME__").addr_info[] | select(.scope == "global").local] | .[0]' iperf3 BW host __ADDR6__ 10002 __TIME__ __OPTS__ -b 8G -l 1472 bw __BW__ 0.3 0.5 iperf3 BW host __ADDR6__ 10002 __TIME__ __OPTS__ -b 12G -l 3972