aboutgitcodebugslistschat
path: root/icmp.c
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2024-07-18 15:26:38 +1000
committerStefano Brivio <sbrivio@redhat.com>2024-07-19 18:33:13 +0200
commit6d76278c21ce2aae7f68ba6807de570cc88f5499 (patch)
treef95f1d0419d6d6b4337af880ec82922b412bc92c /icmp.c
parent5cffb1bf64d5133387de3587fcf7c51f2c88df6c (diff)
downloadpasst-6d76278c21ce2aae7f68ba6807de570cc88f5499.tar
passt-6d76278c21ce2aae7f68ba6807de570cc88f5499.tar.gz
passt-6d76278c21ce2aae7f68ba6807de570cc88f5499.tar.bz2
passt-6d76278c21ce2aae7f68ba6807de570cc88f5499.tar.lz
passt-6d76278c21ce2aae7f68ba6807de570cc88f5499.tar.xz
passt-6d76278c21ce2aae7f68ba6807de570cc88f5499.tar.zst
passt-6d76278c21ce2aae7f68ba6807de570cc88f5499.zip
icmp: Obtain destination addresses from the flowsides
icmp_sock_handler() obtains the guest address from it's most recently observed IP. However, this can now be obtained from the common flowside information. icmp_tap_handler() builds its socket address for sendto() directly from the destination address supplied by the incoming tap packet. This can instead be generated from the flow. Using the flowsides as the common source of truth here prepares us for allowing more flexible NAT and forwarding by properly initialising that flowside information. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Diffstat (limited to 'icmp.c')
-rw-r--r--icmp.c27
1 files changed, 17 insertions, 10 deletions
diff --git a/icmp.c b/icmp.c
index f7bd9f8..82a95e8 100644
--- a/icmp.c
+++ b/icmp.c
@@ -127,11 +127,18 @@ void icmp_sock_handler(const struct ctx *c, union epoll_ref ref)
flow_dbg(pingf, "echo reply to tap, ID: %"PRIu16", seq: %"PRIu16,
ini->eport, seq);
- if (pingf->f.type == FLOW_PING4)
- tap_icmp4_send(c, sr.sa4.sin_addr, tap_ip4_daddr(c), buf, n);
- else if (pingf->f.type == FLOW_PING6)
- tap_icmp6_send(c, &sr.sa6.sin6_addr,
- tap_ip6_daddr(c, &sr.sa6.sin6_addr), buf, n);
+ if (pingf->f.type == FLOW_PING4) {
+ const struct in_addr *saddr = inany_v4(&ini->faddr);
+ const struct in_addr *daddr = inany_v4(&ini->eaddr);
+
+ ASSERT(saddr && daddr); /* Must have IPv4 addresses */
+ tap_icmp4_send(c, *saddr, *daddr, buf, n);
+ } else if (pingf->f.type == FLOW_PING6) {
+ const struct in6_addr *saddr = &ini->faddr.a6;
+ const struct in6_addr *daddr = &ini->eaddr.a6;
+
+ tap_icmp6_send(c, saddr, daddr, buf, n);
+ }
return;
unexpected:
@@ -241,11 +248,12 @@ int icmp_tap_handler(const struct ctx *c, uint8_t pif, sa_family_t af,
const void *saddr, const void *daddr,
const struct pool *p, const struct timespec *now)
{
- union sockaddr_inany sa = { .sa_family = af };
- const socklen_t sl = af == AF_INET ? sizeof(sa.sa4) : sizeof(sa.sa6);
struct icmp_ping_flow *pingf, **id_sock;
+ const struct flowside *tgt;
+ union sockaddr_inany sa;
size_t dlen, l4len;
uint16_t id, seq;
+ socklen_t sl;
void *pkt;
(void)saddr;
@@ -266,7 +274,6 @@ int icmp_tap_handler(const struct ctx *c, uint8_t pif, sa_family_t af,
id = ntohs(ih->un.echo.id);
id_sock = &icmp_id_map[V4][id];
seq = ntohs(ih->un.echo.sequence);
- sa.sa4.sin_addr = *(struct in_addr *)daddr;
} else if (af == AF_INET6) {
const struct icmp6hdr *ih;
@@ -282,8 +289,6 @@ int icmp_tap_handler(const struct ctx *c, uint8_t pif, sa_family_t af,
id = ntohs(ih->icmp6_identifier);
id_sock = &icmp_id_map[V6][id];
seq = ntohs(ih->icmp6_sequence);
- sa.sa6.sin6_addr = *(struct in6_addr *)daddr;
- sa.sa6.sin6_scope_id = c->ifi6;
} else {
ASSERT(0);
}
@@ -292,8 +297,10 @@ int icmp_tap_handler(const struct ctx *c, uint8_t pif, sa_family_t af,
if (!(pingf = icmp_ping_new(c, id_sock, af, id, saddr, daddr)))
return 1;
+ tgt = &pingf->f.side[TGTSIDE];
pingf->ts = now->tv_sec;
+ pif_sockaddr(c, &sa, &sl, PIF_HOST, &tgt->eaddr, 0);
if (sendto(pingf->sock, pkt, l4len, MSG_NOSIGNAL, &sa.sa, sl) < 0) {
flow_dbg(pingf, "failed to relay request to socket: %s",
strerror(errno));