udp: Remove rdelta port forwarding maps
In addition to the struct fwd_ports used by both UDP and TCP to track port forwarding, UDP also included an 'rdelta' field, which contained the reverse mapping of the main port map. This was used so that we could properly direct reply packets to a forwarded packet where we change the destination port. This has now been taken over by the flow table: reply packets will match the flow of the originating packet, and that gives the correct ports on the originating side. So, eliminate the rdelta field, and with it struct udp_fwd_ports, which now has no additional information over struct fwd_ports. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
parent
d89b3aa097
commit
d29fa0856e
4 changed files with 27 additions and 67 deletions
14
conf.c
14
conf.c
|
@ -1248,7 +1248,7 @@ void conf(struct ctx *c, int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
c->tcp.fwd_in.mode = c->tcp.fwd_out.mode = FWD_UNSET;
|
c->tcp.fwd_in.mode = c->tcp.fwd_out.mode = FWD_UNSET;
|
||||||
c->udp.fwd_in.f.mode = c->udp.fwd_out.f.mode = FWD_UNSET;
|
c->udp.fwd_in.mode = c->udp.fwd_out.mode = FWD_UNSET;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
name = getopt_long(argc, argv, optstring, options, NULL);
|
name = getopt_long(argc, argv, optstring, options, NULL);
|
||||||
|
@ -1664,7 +1664,7 @@ void conf(struct ctx *c, int argc, char **argv)
|
||||||
if (name == 't')
|
if (name == 't')
|
||||||
conf_ports(c, name, optarg, &c->tcp.fwd_in);
|
conf_ports(c, name, optarg, &c->tcp.fwd_in);
|
||||||
else if (name == 'u')
|
else if (name == 'u')
|
||||||
conf_ports(c, name, optarg, &c->udp.fwd_in.f);
|
conf_ports(c, name, optarg, &c->udp.fwd_in);
|
||||||
} while (name != -1);
|
} while (name != -1);
|
||||||
|
|
||||||
if (c->mode == MODE_PASTA)
|
if (c->mode == MODE_PASTA)
|
||||||
|
@ -1699,7 +1699,7 @@ void conf(struct ctx *c, int argc, char **argv)
|
||||||
if (name == 'T')
|
if (name == 'T')
|
||||||
conf_ports(c, name, optarg, &c->tcp.fwd_out);
|
conf_ports(c, name, optarg, &c->tcp.fwd_out);
|
||||||
else if (name == 'U')
|
else if (name == 'U')
|
||||||
conf_ports(c, name, optarg, &c->udp.fwd_out.f);
|
conf_ports(c, name, optarg, &c->udp.fwd_out);
|
||||||
} while (name != -1);
|
} while (name != -1);
|
||||||
|
|
||||||
if (!c->ifi4)
|
if (!c->ifi4)
|
||||||
|
@ -1726,10 +1726,10 @@ void conf(struct ctx *c, int argc, char **argv)
|
||||||
c->tcp.fwd_in.mode = fwd_default;
|
c->tcp.fwd_in.mode = fwd_default;
|
||||||
if (!c->tcp.fwd_out.mode)
|
if (!c->tcp.fwd_out.mode)
|
||||||
c->tcp.fwd_out.mode = fwd_default;
|
c->tcp.fwd_out.mode = fwd_default;
|
||||||
if (!c->udp.fwd_in.f.mode)
|
if (!c->udp.fwd_in.mode)
|
||||||
c->udp.fwd_in.f.mode = fwd_default;
|
c->udp.fwd_in.mode = fwd_default;
|
||||||
if (!c->udp.fwd_out.f.mode)
|
if (!c->udp.fwd_out.mode)
|
||||||
c->udp.fwd_out.f.mode = fwd_default;
|
c->udp.fwd_out.mode = fwd_default;
|
||||||
|
|
||||||
fwd_scan_ports_init(c);
|
fwd_scan_ports_init(c);
|
||||||
|
|
||||||
|
|
24
fwd.c
24
fwd.c
|
@ -129,18 +129,18 @@ void fwd_scan_ports_init(struct ctx *c)
|
||||||
|
|
||||||
c->tcp.fwd_in.scan4 = c->tcp.fwd_in.scan6 = -1;
|
c->tcp.fwd_in.scan4 = c->tcp.fwd_in.scan6 = -1;
|
||||||
c->tcp.fwd_out.scan4 = c->tcp.fwd_out.scan6 = -1;
|
c->tcp.fwd_out.scan4 = c->tcp.fwd_out.scan6 = -1;
|
||||||
c->udp.fwd_in.f.scan4 = c->udp.fwd_in.f.scan6 = -1;
|
c->udp.fwd_in.scan4 = c->udp.fwd_in.scan6 = -1;
|
||||||
c->udp.fwd_out.f.scan4 = c->udp.fwd_out.f.scan6 = -1;
|
c->udp.fwd_out.scan4 = c->udp.fwd_out.scan6 = -1;
|
||||||
|
|
||||||
if (c->tcp.fwd_in.mode == FWD_AUTO) {
|
if (c->tcp.fwd_in.mode == FWD_AUTO) {
|
||||||
c->tcp.fwd_in.scan4 = open_in_ns(c, "/proc/net/tcp", flags);
|
c->tcp.fwd_in.scan4 = open_in_ns(c, "/proc/net/tcp", flags);
|
||||||
c->tcp.fwd_in.scan6 = open_in_ns(c, "/proc/net/tcp6", flags);
|
c->tcp.fwd_in.scan6 = open_in_ns(c, "/proc/net/tcp6", flags);
|
||||||
fwd_scan_ports_tcp(&c->tcp.fwd_in, &c->tcp.fwd_out);
|
fwd_scan_ports_tcp(&c->tcp.fwd_in, &c->tcp.fwd_out);
|
||||||
}
|
}
|
||||||
if (c->udp.fwd_in.f.mode == FWD_AUTO) {
|
if (c->udp.fwd_in.mode == FWD_AUTO) {
|
||||||
c->udp.fwd_in.f.scan4 = open_in_ns(c, "/proc/net/udp", flags);
|
c->udp.fwd_in.scan4 = open_in_ns(c, "/proc/net/udp", flags);
|
||||||
c->udp.fwd_in.f.scan6 = open_in_ns(c, "/proc/net/udp6", flags);
|
c->udp.fwd_in.scan6 = open_in_ns(c, "/proc/net/udp6", flags);
|
||||||
fwd_scan_ports_udp(&c->udp.fwd_in.f, &c->udp.fwd_out.f,
|
fwd_scan_ports_udp(&c->udp.fwd_in, &c->udp.fwd_out,
|
||||||
&c->tcp.fwd_in, &c->tcp.fwd_out);
|
&c->tcp.fwd_in, &c->tcp.fwd_out);
|
||||||
}
|
}
|
||||||
if (c->tcp.fwd_out.mode == FWD_AUTO) {
|
if (c->tcp.fwd_out.mode == FWD_AUTO) {
|
||||||
|
@ -148,10 +148,10 @@ void fwd_scan_ports_init(struct ctx *c)
|
||||||
c->tcp.fwd_out.scan6 = open("/proc/net/tcp6", flags);
|
c->tcp.fwd_out.scan6 = open("/proc/net/tcp6", flags);
|
||||||
fwd_scan_ports_tcp(&c->tcp.fwd_out, &c->tcp.fwd_in);
|
fwd_scan_ports_tcp(&c->tcp.fwd_out, &c->tcp.fwd_in);
|
||||||
}
|
}
|
||||||
if (c->udp.fwd_out.f.mode == FWD_AUTO) {
|
if (c->udp.fwd_out.mode == FWD_AUTO) {
|
||||||
c->udp.fwd_out.f.scan4 = open("/proc/net/udp", flags);
|
c->udp.fwd_out.scan4 = open("/proc/net/udp", flags);
|
||||||
c->udp.fwd_out.f.scan6 = open("/proc/net/udp6", flags);
|
c->udp.fwd_out.scan6 = open("/proc/net/udp6", flags);
|
||||||
fwd_scan_ports_udp(&c->udp.fwd_out.f, &c->udp.fwd_in.f,
|
fwd_scan_ports_udp(&c->udp.fwd_out, &c->udp.fwd_in,
|
||||||
&c->tcp.fwd_out, &c->tcp.fwd_in);
|
&c->tcp.fwd_out, &c->tcp.fwd_in);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -242,7 +242,7 @@ uint8_t fwd_nat_from_splice(const struct ctx *c, uint8_t proto,
|
||||||
if (proto == IPPROTO_TCP)
|
if (proto == IPPROTO_TCP)
|
||||||
tgt->eport += c->tcp.fwd_out.delta[tgt->eport];
|
tgt->eport += c->tcp.fwd_out.delta[tgt->eport];
|
||||||
else if (proto == IPPROTO_UDP)
|
else if (proto == IPPROTO_UDP)
|
||||||
tgt->eport += c->udp.fwd_out.f.delta[tgt->eport];
|
tgt->eport += c->udp.fwd_out.delta[tgt->eport];
|
||||||
|
|
||||||
/* Let the kernel pick a host side source port */
|
/* Let the kernel pick a host side source port */
|
||||||
tgt->fport = 0;
|
tgt->fport = 0;
|
||||||
|
@ -271,7 +271,7 @@ uint8_t fwd_nat_from_host(const struct ctx *c, uint8_t proto,
|
||||||
if (proto == IPPROTO_TCP)
|
if (proto == IPPROTO_TCP)
|
||||||
tgt->eport += c->tcp.fwd_in.delta[tgt->eport];
|
tgt->eport += c->tcp.fwd_in.delta[tgt->eport];
|
||||||
else if (proto == IPPROTO_UDP)
|
else if (proto == IPPROTO_UDP)
|
||||||
tgt->eport += c->udp.fwd_in.f.delta[tgt->eport];
|
tgt->eport += c->udp.fwd_in.delta[tgt->eport];
|
||||||
|
|
||||||
if (c->mode == MODE_PASTA && inany_is_loopback(&ini->eaddr) &&
|
if (c->mode == MODE_PASTA && inany_is_loopback(&ini->eaddr) &&
|
||||||
(proto == IPPROTO_TCP || proto == IPPROTO_UDP)) {
|
(proto == IPPROTO_TCP || proto == IPPROTO_UDP)) {
|
||||||
|
|
42
udp.c
42
udp.c
|
@ -205,33 +205,6 @@ void udp_portmap_clear(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 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_fwd_ports *fwd)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
static_assert(ARRAY_SIZE(fwd->f.delta) == ARRAY_SIZE(fwd->rdelta),
|
|
||||||
"Forward and reverse delta arrays must have same size");
|
|
||||||
for (i = 0; i < ARRAY_SIZE(fwd->f.delta); i++) {
|
|
||||||
in_port_t delta = fwd->f.delta[i];
|
|
||||||
|
|
||||||
if (delta) {
|
|
||||||
/* Keep rport calculation separate from its usage: we
|
|
||||||
* need to perform the sum in in_port_t width (that is,
|
|
||||||
* modulo 65536), but C promotion rules would sum the
|
|
||||||
* two terms as 'int', if we just open-coded the array
|
|
||||||
* index as 'i + delta'.
|
|
||||||
*/
|
|
||||||
in_port_t rport = i + delta;
|
|
||||||
|
|
||||||
fwd->rdelta[rport] = NUM_PORTS - delta;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* udp_update_l2_buf() - Update L2 buffers with Ethernet and IPv4 addresses
|
* udp_update_l2_buf() - Update L2 buffers with Ethernet and IPv4 addresses
|
||||||
* @eth_d: Ethernet destination address, NULL if unchanged
|
* @eth_d: Ethernet destination address, NULL if unchanged
|
||||||
|
@ -1080,9 +1053,9 @@ static void udp_port_rebind(struct ctx *c, bool outbound)
|
||||||
{
|
{
|
||||||
int (*socks)[NUM_PORTS] = outbound ? udp_splice_ns : udp_splice_init;
|
int (*socks)[NUM_PORTS] = outbound ? udp_splice_ns : udp_splice_init;
|
||||||
const uint8_t *fmap
|
const uint8_t *fmap
|
||||||
= outbound ? c->udp.fwd_out.f.map : c->udp.fwd_in.f.map;
|
= outbound ? c->udp.fwd_out.map : c->udp.fwd_in.map;
|
||||||
const uint8_t *rmap
|
const uint8_t *rmap
|
||||||
= outbound ? c->udp.fwd_in.f.map : c->udp.fwd_out.f.map;
|
= outbound ? c->udp.fwd_in.map : c->udp.fwd_out.map;
|
||||||
unsigned port;
|
unsigned port;
|
||||||
|
|
||||||
for (port = 0; port < NUM_PORTS; port++) {
|
for (port = 0; port < NUM_PORTS; port++) {
|
||||||
|
@ -1158,14 +1131,14 @@ void udp_timer(struct ctx *c, const struct timespec *now)
|
||||||
ASSERT(!c->no_udp);
|
ASSERT(!c->no_udp);
|
||||||
|
|
||||||
if (c->mode == MODE_PASTA) {
|
if (c->mode == MODE_PASTA) {
|
||||||
if (c->udp.fwd_out.f.mode == FWD_AUTO) {
|
if (c->udp.fwd_out.mode == FWD_AUTO) {
|
||||||
fwd_scan_ports_udp(&c->udp.fwd_out.f, &c->udp.fwd_in.f,
|
fwd_scan_ports_udp(&c->udp.fwd_out, &c->udp.fwd_in,
|
||||||
&c->tcp.fwd_out, &c->tcp.fwd_in);
|
&c->tcp.fwd_out, &c->tcp.fwd_in);
|
||||||
NS_CALL(udp_port_rebind_outbound, c);
|
NS_CALL(udp_port_rebind_outbound, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->udp.fwd_in.f.mode == FWD_AUTO) {
|
if (c->udp.fwd_in.mode == FWD_AUTO) {
|
||||||
fwd_scan_ports_udp(&c->udp.fwd_in.f, &c->udp.fwd_out.f,
|
fwd_scan_ports_udp(&c->udp.fwd_in, &c->udp.fwd_out,
|
||||||
&c->tcp.fwd_in, &c->tcp.fwd_out);
|
&c->tcp.fwd_in, &c->tcp.fwd_out);
|
||||||
udp_port_rebind(c, false);
|
udp_port_rebind(c, false);
|
||||||
}
|
}
|
||||||
|
@ -1184,9 +1157,6 @@ int udp_init(struct ctx *c)
|
||||||
|
|
||||||
udp_iov_init(c);
|
udp_iov_init(c);
|
||||||
|
|
||||||
udp_invert_portmap(&c->udp.fwd_in);
|
|
||||||
udp_invert_portmap(&c->udp.fwd_out);
|
|
||||||
|
|
||||||
if (c->mode == MODE_PASTA) {
|
if (c->mode == MODE_PASTA) {
|
||||||
udp_splice_iov_init();
|
udp_splice_iov_init();
|
||||||
NS_CALL(udp_port_rebind_outbound, c);
|
NS_CALL(udp_port_rebind_outbound, c);
|
||||||
|
|
14
udp.h
14
udp.h
|
@ -41,16 +41,6 @@ union udp_epoll_ref {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* udp_fwd_ports - UDP specific port forwarding configuration
|
|
||||||
* @f: Generic forwarding configuration
|
|
||||||
* @rdelta: Reversed delta map to translate source ports on return packets
|
|
||||||
*/
|
|
||||||
struct udp_fwd_ports {
|
|
||||||
struct fwd_ports f;
|
|
||||||
in_port_t rdelta[NUM_PORTS];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct udp_ctx - Execution context for UDP
|
* struct udp_ctx - Execution context for UDP
|
||||||
* @fwd_in: Port forwarding configuration for inbound packets
|
* @fwd_in: Port forwarding configuration for inbound packets
|
||||||
|
@ -58,8 +48,8 @@ struct udp_fwd_ports {
|
||||||
* @timer_run: Timestamp of most recent timer run
|
* @timer_run: Timestamp of most recent timer run
|
||||||
*/
|
*/
|
||||||
struct udp_ctx {
|
struct udp_ctx {
|
||||||
struct udp_fwd_ports fwd_in;
|
struct fwd_ports fwd_in;
|
||||||
struct udp_fwd_ports fwd_out;
|
struct fwd_ports fwd_out;
|
||||||
struct timespec timer_run;
|
struct timespec timer_run;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue