diff options
author | David Gibson <david@gibson.dropbear.id.au> | 2024-07-18 15:26:43 +1000 |
---|---|---|
committer | Stefano Brivio <sbrivio@redhat.com> | 2024-07-19 18:33:29 +0200 |
commit | 060f24e310b71f8813dbbc561a2e5a59d21feae0 (patch) | |
tree | 0b2d8532c057f97ec5f51840c1a4daeb12f79f23 /flow.c | |
parent | 4cd753e65c591732b84c455b8eb9af44d09155cd (diff) | |
download | passt-060f24e310b71f8813dbbc561a2e5a59d21feae0.tar passt-060f24e310b71f8813dbbc561a2e5a59d21feae0.tar.gz passt-060f24e310b71f8813dbbc561a2e5a59d21feae0.tar.bz2 passt-060f24e310b71f8813dbbc561a2e5a59d21feae0.tar.lz passt-060f24e310b71f8813dbbc561a2e5a59d21feae0.tar.xz passt-060f24e310b71f8813dbbc561a2e5a59d21feae0.tar.zst passt-060f24e310b71f8813dbbc561a2e5a59d21feae0.zip |
flow, tcp: Flow based NAT and port forwarding for TCP
Currently the code to translate host side addresses and ports to guest side
addresses and ports, and vice versa, is scattered across the TCP code.
This includes both port redirection as controlled by the -t and -T options,
and our special case NAT controlled by the --no-map-gw option.
Gather this logic into fwd_nat_from_*() functions for each input
interface in fwd.c which take protocol and address information for the
initiating side and generates the pif and address information for the
forwarded side. This performs any NAT or port forwarding needed.
We create a flow_target() helper which applies those forwarding functions
as needed to automatically move a flow from INI to TGT state.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Diffstat (limited to 'flow.c')
-rw-r--r-- | flow.c | 53 |
1 files changed, 53 insertions, 0 deletions
@@ -400,6 +400,59 @@ const struct flowside *flow_target_af(union flow *flow, uint8_t pif, return tgt; } + +/** + * flow_target() - Determine where flow should forward to, and move to TGT + * @c: Execution context + * @flow: Flow to forward + * @proto: Protocol + * + * Return: pointer to the target flowside information + */ +const struct flowside *flow_target(const struct ctx *c, union flow *flow, + uint8_t proto) +{ + char estr[INANY_ADDRSTRLEN], fstr[INANY_ADDRSTRLEN]; + struct flow_common *f = &flow->f; + const struct flowside *ini = &f->side[INISIDE]; + struct flowside *tgt = &f->side[TGTSIDE]; + uint8_t tgtpif = PIF_NONE; + + ASSERT(flow_new_entry == flow && f->state == FLOW_STATE_INI); + ASSERT(f->type == FLOW_TYPE_NONE); + ASSERT(f->pif[INISIDE] != PIF_NONE && f->pif[TGTSIDE] == PIF_NONE); + ASSERT(flow->f.state == FLOW_STATE_INI); + + switch (f->pif[INISIDE]) { + case PIF_TAP: + tgtpif = fwd_nat_from_tap(c, proto, ini, tgt); + break; + + case PIF_SPLICE: + tgtpif = fwd_nat_from_splice(c, proto, ini, tgt); + break; + + case PIF_HOST: + tgtpif = fwd_nat_from_host(c, proto, ini, tgt); + break; + + default: + flow_err(flow, "No rules to forward %s [%s]:%hu -> [%s]:%hu", + pif_name(f->pif[INISIDE]), + inany_ntop(&ini->eaddr, estr, sizeof(estr)), + ini->eport, + inany_ntop(&ini->faddr, fstr, sizeof(fstr)), + ini->fport); + } + + if (tgtpif == PIF_NONE) + return NULL; + + f->pif[TGTSIDE] = tgtpif; + flow_set_state(f, FLOW_STATE_TGT); + return tgt; +} + /** * flow_set_type() - Set type and move to TYPED * @flow: Flow to change state |