Currently ping sockets use a custom epoll reference type which includes the ICMP id. However, now that we have entries in the flow table for ping flows, finding that is sufficient to get everything else we want, including the id. Therefore remove the icmp_epoll_ref type and use the general 'flowside' field for ping sockets. Signed-off-by: David Gibson <david(a)gibson.dropbear.id.au> --- icmp.c | 18 ++++++++++-------- icmp.h | 11 ----------- passt.h | 1 - 3 files changed, 10 insertions(+), 20 deletions(-) diff --git a/icmp.c b/icmp.c index 917c810..a073813 100644 --- a/icmp.c +++ b/icmp.c @@ -62,17 +62,16 @@ static struct icmp_ping_flow *icmp_id_map[IP_VERSIONS][ICMP_NUM_IDS]; */ void icmp_sock_handler(const struct ctx *c, int af, union epoll_ref ref) { - struct icmp_ping_flow *pingf = af == AF_INET - ? icmp_id_map[V4][ref.icmp.id] : icmp_id_map[V6][ref.icmp.id]; const char *const pname = af == AF_INET ? "ICMP" : "ICMPv6"; + struct icmp_ping_flow *pingf = PINGF(ref.flowside.flow); char buf[USHRT_MAX]; union { struct sockaddr sa; struct sockaddr_in sa4; struct sockaddr_in6 sa6; } sr; + uint16_t id = TAPFSIDE(pingf)->eport, seq; socklen_t sl = sizeof(sr); - uint16_t seq; ssize_t n; if (c->no_icmp) @@ -96,7 +95,7 @@ void icmp_sock_handler(const struct ctx *c, int af, union epoll_ref ref) goto unexpected; /* Adjust packet back to guest-side ID */ - ih4->un.echo.id = htons(ref.icmp.id); + ih4->un.echo.id = htons(id); seq = ntohs(ih4->un.echo.sequence); } else if (af == AF_INET6) { struct icmp6hdr *ih6 = (struct icmp6hdr *)buf; @@ -106,7 +105,7 @@ void icmp_sock_handler(const struct ctx *c, int af, union epoll_ref ref) goto unexpected; /* Adjust packet back to guest-side ID */ - ih6->icmp6_identifier = htons(ref.icmp.id); + ih6->icmp6_identifier = htons(id); seq = ntohs(ih6->icmp6_sequence); } else { ASSERT(0); @@ -120,7 +119,7 @@ void icmp_sock_handler(const struct ctx *c, int af, union epoll_ref ref) } debug("%s: echo reply to tap, ID: %"PRIu16", seq: %"PRIu16, pname, - ref.icmp.id, seq); + id, seq); if (af == AF_INET) { const struct in_addr *saddr = inany_v4(&TAPFSIDE(pingf)->faddr); const struct in_addr *daddr = inany_v4(&TAPFSIDE(pingf)->eaddr); @@ -173,25 +172,28 @@ static struct icmp_ping_flow *icmp_ping_new(const struct ctx *c, { const char *const pname = af == AF_INET ? "ICMP" : "ICMPv6"; uint8_t flowtype = af == AF_INET ? FLOW_PING4 : FLOW_PING6; - union icmp_epoll_ref iref = { .id = id }; union flow *flow = flow_alloc(); struct icmp_ping_flow *pingf; const void *bind_addr; const char *bind_if; + union epoll_ref ref; int s; if (!flow) return NULL; if (af == AF_INET) { + ref.type = EPOLL_TYPE_ICMP; bind_addr = &c->ip4.addr_out; bind_if = c->ip4.ifname_out; } else { + ref.type = EPOLL_TYPE_ICMPV6; bind_addr = &c->ip6.addr_out; bind_if = c->ip6.ifname_out; } - s = sock_l4(c, af, flow_proto[flowtype], bind_addr, bind_if, 0, iref.u32); + ref.flowside = FLOW_SIDX(flow, SOCKSIDE); + s = sock_l4(c, af, flow_proto[flowtype], bind_addr, bind_if, 0, ref.data); if (s < 0) { warn("Cannot open \"ping\" socket. You might need to:"); diff --git a/icmp.h b/icmp.h index 2897f31..50807c4 100644 --- a/icmp.h +++ b/icmp.h @@ -17,17 +17,6 @@ int icmp_tap_handler(const struct ctx *c, uint8_t pif, int af, const struct pool *p, const struct timespec *now); void icmp_init(void); -/** - * union icmp_epoll_ref - epoll reference portion for ICMP tracking - * @v6: Set for IPv6 sockets or connections - * @u32: Opaque u32 value of reference - * @id: Associated echo identifier, needed if bind() fails - */ -union icmp_epoll_ref { - uint16_t id; - uint32_t u32; -}; - /** * struct icmp_ctx - Execution context for ICMP routines * @timer_run: Timestamp of most recent timer run diff --git a/passt.h b/passt.h index db0cd10..d1ed716 100644 --- a/passt.h +++ b/passt.h @@ -99,7 +99,6 @@ union epoll_ref { flow_sidx_t flowside; union tcp_listen_epoll_ref tcp_listen; union udp_epoll_ref udp; - union icmp_epoll_ref icmp; uint32_t data; }; }; -- 2.43.0