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;
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);
+
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