On Fri, Sep 05, 2025 at 10:11:53PM -0400, Jon Maloy wrote: > tcp_rst_no_conn() needs to identify and specify which source MAC > address to use when sending an RST to the guest. This is because > it doesn't have access to any flow structure where this address > could be fetched. > > Signed-off-by: Jon Maloy > > --- > v3: - Adapted to the signature change in nl_mac_get() function, so that > we now consider only the template interface when checking the > ARP/NDP table. > v4: - Adapted to previous name changes in this series > v5: - Eliminated use of function fwd_iany_nat(). > - Instead using the translation result of an attempted NAT lookup. > --- > tcp.c | 14 +++++++++++--- > 1 file changed, 11 insertions(+), 3 deletions(-) > > diff --git a/tcp.c b/tcp.c > index 383654c..54e75bb 100644 > --- a/tcp.c > +++ b/tcp.c > @@ -1912,6 +1912,8 @@ static void tcp_rst_no_conn(const struct ctx *c, int af, > const struct tcphdr *th, size_t l4len) > { > struct iov_tail payload = IOV_TAIL(NULL, 0, 0); > + unsigned char src_mac[ETH_ALEN]; > + union inany_addr tgt, tgt_nat; 'tgt' is not a good name here. 'tgt' typically refers to the "target" (non initiating) side of a flow. But in this instance there is no flow. > struct tcphdr *rsth; > char buf[USHRT_MAX]; > uint32_t psum = 0; > @@ -1921,9 +1923,15 @@ static void tcp_rst_no_conn(const struct ctx *c, int af, > if (th->rst) > return; > > + /* Try to use true MAC address if remote host's address or > + * NAT translated address can be found in ARP/NDP table. > + */ > + inany_from_af(&tgt, af, daddr); > + nat_outbound(c, &tgt, &tgt_nat); > + fwd_neigh_mac_get(c, &tgt_nat, src_mac); I'm not convinced we actually want to do a MAC lookup in this case. In this case the guest has send us a packet that looks bogus. The RST is explicitly something we're synthesizing, not something that's _actually_ from the peer. We have to lie about the IP address or the guest won't attach this RST to the right connection, but I don't see that we need to lie about the MAC address as well - especially since it has a cost to do so. Or to look at it another way, if we get here the guest's idea of what the surrounding network is already out of sync with passt's idea. So trying to preserve that idea by faking the MAC is kind of pointless. > if (af == AF_INET) { > - struct iphdr *ip4h = tap_push_l2h(c, buf, c->our_tap_mac, > - ETH_P_IP); > + struct iphdr *ip4h = tap_push_l2h(c, buf, src_mac, ETH_P_IP); > const struct in_addr *rst_src = daddr; > const struct in_addr *rst_dst = saddr; > > @@ -1933,7 +1941,7 @@ static void tcp_rst_no_conn(const struct ctx *c, int af, > *rst_src, *rst_dst); > > } else { > - struct ipv6hdr *ip6h = tap_push_l2h(c, buf, c->our_tap_mac, ETH_P_IPV6); > + struct ipv6hdr *ip6h = tap_push_l2h(c, buf, src_mac, ETH_P_IPV6); > const struct in6_addr *rst_src = daddr; > const struct in6_addr *rst_dst = saddr; > > -- > 2.50.1 > -- David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson