diff --git a/udp.c b/udp.c index 38bb8d8..eb32dda 100644 --- a/udp.c +++ b/udp.c @@ -109,6 +109,7 @@ #include #include #include +#include #include "checksum.h" #include "util.h" @@ -266,7 +267,6 @@ static struct mmsghdr udp_mmh_sendto [UDP_SPLICE_FRAMES]; void udp_remap_to_tap(struct ctx *c, in_port_t port, in_port_t delta) { c->udp.fwd_in.f.delta[port] = delta; - c->udp.fwd_in.rdelta[port + delta] = USHRT_MAX - delta; } /** @@ -278,7 +278,23 @@ void udp_remap_to_tap(struct ctx *c, in_port_t port, in_port_t delta) void udp_remap_to_init(struct ctx *c, in_port_t port, in_port_t delta) { c->udp.fwd_out.f.delta[port] = delta; - c->udp.fwd_out.rdelta[port + delta] = USHRT_MAX - delta; +} + +/** + * udp_invert_portmap() - Compute reverse port translations for return packets + * @fwd: Port forwarding configuration to compute reverse map for + */ +static void udp_invert_portmap(struct udp_port_fwd *fwd) +{ + int i; + + assert(ARRAY_SIZE(fwd->f.delta) == ARRAY_SIZE(fwd->rdelta)); + for (i = 0; i < ARRAY_SIZE(fwd->f.delta); i++) { + in_port_t delta = fwd->f.delta[i]; + + if (delta) + fwd->rdelta[(in_port_t)i + delta] = USHRT_MAX - delta; + } } /** @@ -1267,7 +1283,7 @@ static void udp_splice_iov_init(void) * * Return: 0 */ -int udp_init(const struct ctx *c) +int udp_init(struct ctx *c) { if (c->ifi4) udp_sock4_iov_init(); @@ -1275,6 +1291,9 @@ int udp_init(const struct ctx *c) if (c->ifi6) udp_sock6_iov_init(); + udp_invert_portmap(&c->udp.fwd_in); + udp_invert_portmap(&c->udp.fwd_out); + if (c->mode == MODE_PASTA) { udp_splice_iov_init(); NS_CALL(udp_sock_init_ns, c); diff --git a/udp.h b/udp.h index cfd1a97..25422b6 100644 --- a/udp.h +++ b/udp.h @@ -14,7 +14,7 @@ int udp_tap_handler(struct ctx *c, int af, const void *addr, const struct pool *p, const struct timespec *now); void udp_sock_init(const struct ctx *c, int ns, sa_family_t af, const void *addr, in_port_t port); -int udp_init(const struct ctx *c); +int udp_init(struct ctx *c); void udp_timer(struct ctx *c, const struct timespec *ts); void udp_update_l2_buf(const unsigned char *eth_d, const unsigned char *eth_s, const uint32_t *ip_da);