aboutgitcodebugslistschat
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2024-07-18 15:26:45 +1000
committerStefano Brivio <sbrivio@redhat.com>2024-07-19 18:33:35 +0200
commit8abd06e9fac93b60cc98d90f7310d94cfc295090 (patch)
tree3a360bb4c607e5e08d1bb1df44d9a3190afaf67b
parentc000f2aba6a4612a202ee4e8e66fec2d19deedf7 (diff)
downloadpasst-8abd06e9fac93b60cc98d90f7310d94cfc295090.tar
passt-8abd06e9fac93b60cc98d90f7310d94cfc295090.tar.gz
passt-8abd06e9fac93b60cc98d90f7310d94cfc295090.tar.bz2
passt-8abd06e9fac93b60cc98d90f7310d94cfc295090.tar.lz
passt-8abd06e9fac93b60cc98d90f7310d94cfc295090.tar.xz
passt-8abd06e9fac93b60cc98d90f7310d94cfc295090.tar.zst
passt-8abd06e9fac93b60cc98d90f7310d94cfc295090.zip
fwd: Update flow forwarding logic for UDP
Add logic to the fwd_nat_from_*() functions to forwarding UDP packets. The logic here doesn't exactly match our current forwarding, since our current forwarding has some very strange and buggy edge cases. Instead it's attempting to replicate what appears to be the intended logic behind the current forwarding. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
-rw-r--r--fwd.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/fwd.c b/fwd.c
index 3288b0d..a70ebfd 100644
--- a/fwd.c
+++ b/fwd.c
@@ -169,12 +169,16 @@ void fwd_scan_ports_init(struct ctx *c)
uint8_t fwd_nat_from_tap(const struct ctx *c, uint8_t proto,
const struct flowside *ini, struct flowside *tgt)
{
- (void)proto;
-
tgt->eaddr = ini->faddr;
tgt->eport = ini->fport;
- if (!c->no_map_gw) {
+ if (proto == IPPROTO_UDP && tgt->eport == 53 &&
+ inany_equals4(&tgt->eaddr, &c->ip4.dns_match)) {
+ tgt->eaddr = inany_from_v4(c->ip4.dns_host);
+ } else if (proto == IPPROTO_UDP && tgt->eport == 53 &&
+ inany_equals6(&tgt->eaddr, &c->ip6.dns_match)) {
+ tgt->eaddr.a6 = c->ip6.dns_host;
+ } else if (!c->no_map_gw) {
if (inany_equals4(&tgt->eaddr, &c->ip4.gw))
tgt->eaddr = inany_loopback4;
else if (inany_equals6(&tgt->eaddr, &c->ip6.gw))
@@ -191,6 +195,10 @@ uint8_t fwd_nat_from_tap(const struct ctx *c, uint8_t proto,
/* Let the kernel pick a host side source port */
tgt->fport = 0;
+ if (proto == IPPROTO_UDP) {
+ /* But for UDP we preserve the source port */
+ tgt->fport = ini->eport;
+ }
return PIF_HOST;
}
@@ -233,9 +241,14 @@ uint8_t fwd_nat_from_splice(const struct ctx *c, uint8_t proto,
tgt->eport = ini->fport;
if (proto == IPPROTO_TCP)
tgt->eport += c->tcp.fwd_out.delta[tgt->eport];
+ else if (proto == IPPROTO_UDP)
+ tgt->eport += c->udp.fwd_out.f.delta[tgt->eport];
/* Let the kernel pick a host side source port */
tgt->fport = 0;
+ if (proto == IPPROTO_UDP)
+ /* But for UDP preserve the source port */
+ tgt->fport = ini->eport;
return PIF_HOST;
}
@@ -257,9 +270,11 @@ uint8_t fwd_nat_from_host(const struct ctx *c, uint8_t proto,
tgt->eport = ini->fport;
if (proto == IPPROTO_TCP)
tgt->eport += c->tcp.fwd_in.delta[tgt->eport];
+ else if (proto == IPPROTO_UDP)
+ tgt->eport += c->udp.fwd_in.f.delta[tgt->eport];
if (c->mode == MODE_PASTA && inany_is_loopback(&ini->eaddr) &&
- proto == IPPROTO_TCP) {
+ (proto == IPPROTO_TCP || proto == IPPROTO_UDP)) {
/* spliceable */
/* Preserve the specific loopback adddress used, but let the
@@ -267,11 +282,15 @@ uint8_t fwd_nat_from_host(const struct ctx *c, uint8_t proto,
*/
tgt->faddr = ini->eaddr;
tgt->fport = 0;
+ if (proto == IPPROTO_UDP)
+ /* But for UDP preserve the source port */
+ tgt->fport = ini->eport;
if (inany_v4(&ini->eaddr))
tgt->eaddr = inany_loopback4;
else
tgt->eaddr = inany_loopback6;
+
return PIF_SPLICE;
}