treewide: Use "our address" instead of "forwarding address"
The term "forwarding address" to indicate the local-to-passt address was well-intentioned, but ends up being kinda confusing. As discussed on a recent call, let's try "our" instead. (While we're there correct an error in flow_initiate_af()s comments where we referred to parameters by the wrong name). Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
parent
32c386834d
commit
e6feb5a892
7 changed files with 106 additions and 105 deletions
72
flow.c
72
flow.c
|
@ -127,18 +127,18 @@ static struct timespec flow_timer_run;
|
||||||
* @af: Address family (AF_INET or AF_INET6)
|
* @af: Address family (AF_INET or AF_INET6)
|
||||||
* @eaddr: Endpoint address (pointer to in_addr or in6_addr)
|
* @eaddr: Endpoint address (pointer to in_addr or in6_addr)
|
||||||
* @eport: Endpoint port
|
* @eport: Endpoint port
|
||||||
* @faddr: Forwarding address (pointer to in_addr or in6_addr)
|
* @oaddr: Our address (pointer to in_addr or in6_addr)
|
||||||
* @fport: Forwarding port
|
* @oport: Our port
|
||||||
*/
|
*/
|
||||||
static void flowside_from_af(struct flowside *side, sa_family_t af,
|
static void flowside_from_af(struct flowside *side, sa_family_t af,
|
||||||
const void *eaddr, in_port_t eport,
|
const void *eaddr, in_port_t eport,
|
||||||
const void *faddr, in_port_t fport)
|
const void *oaddr, in_port_t oport)
|
||||||
{
|
{
|
||||||
if (faddr)
|
if (oaddr)
|
||||||
inany_from_af(&side->faddr, af, faddr);
|
inany_from_af(&side->oaddr, af, oaddr);
|
||||||
else
|
else
|
||||||
side->faddr = inany_any6;
|
side->oaddr = inany_any6;
|
||||||
side->fport = fport;
|
side->oport = oport;
|
||||||
|
|
||||||
if (eaddr)
|
if (eaddr)
|
||||||
inany_from_af(&side->eaddr, af, eaddr);
|
inany_from_af(&side->eaddr, af, eaddr);
|
||||||
|
@ -193,8 +193,8 @@ static int flowside_sock_splice(void *arg)
|
||||||
* @tgt: Target flowside
|
* @tgt: Target flowside
|
||||||
* @data: epoll reference portion for protocol handlers
|
* @data: epoll reference portion for protocol handlers
|
||||||
*
|
*
|
||||||
* Return: socket fd of protocol @proto bound to the forwarding address and port
|
* Return: socket fd of protocol @proto bound to our address and port from @tgt
|
||||||
* from @tgt (if specified).
|
* (if specified).
|
||||||
*/
|
*/
|
||||||
int flowside_sock_l4(const struct ctx *c, enum epoll_type type, uint8_t pif,
|
int flowside_sock_l4(const struct ctx *c, enum epoll_type type, uint8_t pif,
|
||||||
const struct flowside *tgt, uint32_t data)
|
const struct flowside *tgt, uint32_t data)
|
||||||
|
@ -205,11 +205,11 @@ int flowside_sock_l4(const struct ctx *c, enum epoll_type type, uint8_t pif,
|
||||||
|
|
||||||
ASSERT(pif_is_socket(pif));
|
ASSERT(pif_is_socket(pif));
|
||||||
|
|
||||||
pif_sockaddr(c, &sa, &sl, pif, &tgt->faddr, tgt->fport);
|
pif_sockaddr(c, &sa, &sl, pif, &tgt->oaddr, tgt->oport);
|
||||||
|
|
||||||
switch (pif) {
|
switch (pif) {
|
||||||
case PIF_HOST:
|
case PIF_HOST:
|
||||||
if (inany_is_loopback(&tgt->faddr))
|
if (inany_is_loopback(&tgt->oaddr))
|
||||||
ifname = NULL;
|
ifname = NULL;
|
||||||
else if (sa.sa_family == AF_INET)
|
else if (sa.sa_family == AF_INET)
|
||||||
ifname = c->ip4.ifname_out;
|
ifname = c->ip4.ifname_out;
|
||||||
|
@ -309,11 +309,11 @@ static void flow_set_state(struct flow_common *f, enum flow_state state)
|
||||||
pif_name(f->pif[INISIDE]),
|
pif_name(f->pif[INISIDE]),
|
||||||
inany_ntop(&ini->eaddr, estr0, sizeof(estr0)),
|
inany_ntop(&ini->eaddr, estr0, sizeof(estr0)),
|
||||||
ini->eport,
|
ini->eport,
|
||||||
inany_ntop(&ini->faddr, fstr0, sizeof(fstr0)),
|
inany_ntop(&ini->oaddr, fstr0, sizeof(fstr0)),
|
||||||
ini->fport,
|
ini->oport,
|
||||||
pif_name(f->pif[TGTSIDE]),
|
pif_name(f->pif[TGTSIDE]),
|
||||||
inany_ntop(&tgt->faddr, fstr1, sizeof(fstr1)),
|
inany_ntop(&tgt->oaddr, fstr1, sizeof(fstr1)),
|
||||||
tgt->fport,
|
tgt->oport,
|
||||||
inany_ntop(&tgt->eaddr, estr1, sizeof(estr1)),
|
inany_ntop(&tgt->eaddr, estr1, sizeof(estr1)),
|
||||||
tgt->eport);
|
tgt->eport);
|
||||||
else if (MAX(state, oldstate) >= FLOW_STATE_INI)
|
else if (MAX(state, oldstate) >= FLOW_STATE_INI)
|
||||||
|
@ -321,8 +321,8 @@ static void flow_set_state(struct flow_common *f, enum flow_state state)
|
||||||
pif_name(f->pif[INISIDE]),
|
pif_name(f->pif[INISIDE]),
|
||||||
inany_ntop(&ini->eaddr, estr0, sizeof(estr0)),
|
inany_ntop(&ini->eaddr, estr0, sizeof(estr0)),
|
||||||
ini->eport,
|
ini->eport,
|
||||||
inany_ntop(&ini->faddr, fstr0, sizeof(fstr0)),
|
inany_ntop(&ini->oaddr, fstr0, sizeof(fstr0)),
|
||||||
ini->fport);
|
ini->oport);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -347,7 +347,7 @@ static void flow_initiate_(union flow *flow, uint8_t pif)
|
||||||
* flow_initiate_af() - Move flow to INI, setting INISIDE details
|
* flow_initiate_af() - Move flow to INI, setting INISIDE details
|
||||||
* @flow: Flow to change state
|
* @flow: Flow to change state
|
||||||
* @pif: pif of the initiating side
|
* @pif: pif of the initiating side
|
||||||
* @af: Address family of @eaddr and @faddr
|
* @af: Address family of @saddr and @daddr
|
||||||
* @saddr: Source address (pointer to in_addr or in6_addr)
|
* @saddr: Source address (pointer to in_addr or in6_addr)
|
||||||
* @sport: Endpoint port
|
* @sport: Endpoint port
|
||||||
* @daddr: Destination address (pointer to in_addr or in6_addr)
|
* @daddr: Destination address (pointer to in_addr or in6_addr)
|
||||||
|
@ -384,10 +384,10 @@ const struct flowside *flow_initiate_sa(union flow *flow, uint8_t pif,
|
||||||
|
|
||||||
inany_from_sockaddr(&ini->eaddr, &ini->eport, ssa);
|
inany_from_sockaddr(&ini->eaddr, &ini->eport, ssa);
|
||||||
if (inany_v4(&ini->eaddr))
|
if (inany_v4(&ini->eaddr))
|
||||||
ini->faddr = inany_any4;
|
ini->oaddr = inany_any4;
|
||||||
else
|
else
|
||||||
ini->faddr = inany_any6;
|
ini->oaddr = inany_any6;
|
||||||
ini->fport = dport;
|
ini->oport = dport;
|
||||||
flow_initiate_(flow, pif);
|
flow_initiate_(flow, pif);
|
||||||
return ini;
|
return ini;
|
||||||
}
|
}
|
||||||
|
@ -432,8 +432,8 @@ const struct flowside *flow_target(const struct ctx *c, union flow *flow,
|
||||||
pif_name(f->pif[INISIDE]),
|
pif_name(f->pif[INISIDE]),
|
||||||
inany_ntop(&ini->eaddr, estr, sizeof(estr)),
|
inany_ntop(&ini->eaddr, estr, sizeof(estr)),
|
||||||
ini->eport,
|
ini->eport,
|
||||||
inany_ntop(&ini->faddr, fstr, sizeof(fstr)),
|
inany_ntop(&ini->oaddr, fstr, sizeof(fstr)),
|
||||||
ini->fport);
|
ini->oport);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tgtpif == PIF_NONE)
|
if (tgtpif == PIF_NONE)
|
||||||
|
@ -561,12 +561,12 @@ static uint64_t flow_hash(const struct ctx *c, uint8_t proto, uint8_t pif,
|
||||||
{
|
{
|
||||||
struct siphash_state state = SIPHASH_INIT(c->hash_secret);
|
struct siphash_state state = SIPHASH_INIT(c->hash_secret);
|
||||||
|
|
||||||
inany_siphash_feed(&state, &side->faddr);
|
inany_siphash_feed(&state, &side->oaddr);
|
||||||
inany_siphash_feed(&state, &side->eaddr);
|
inany_siphash_feed(&state, &side->eaddr);
|
||||||
|
|
||||||
return siphash_final(&state, 38, (uint64_t)proto << 40 |
|
return siphash_final(&state, 38, (uint64_t)proto << 40 |
|
||||||
(uint64_t)pif << 32 |
|
(uint64_t)pif << 32 |
|
||||||
(uint64_t)side->fport << 16 |
|
(uint64_t)side->oport << 16 |
|
||||||
(uint64_t)side->eport);
|
(uint64_t)side->eport);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -587,7 +587,7 @@ static uint64_t flow_sidx_hash(const struct ctx *c, flow_sidx_t sidx)
|
||||||
* information, and at least a forwarding port.
|
* information, and at least a forwarding port.
|
||||||
*/
|
*/
|
||||||
ASSERT(pif != PIF_NONE && !inany_is_unspecified(&side->eaddr) &&
|
ASSERT(pif != PIF_NONE && !inany_is_unspecified(&side->eaddr) &&
|
||||||
side->eport != 0 && side->fport != 0);
|
side->eport != 0 && side->oport != 0);
|
||||||
|
|
||||||
return flow_hash(c, FLOW_PROTO(f), pif, side);
|
return flow_hash(c, FLOW_PROTO(f), pif, side);
|
||||||
}
|
}
|
||||||
|
@ -709,20 +709,20 @@ static flow_sidx_t flowside_lookup(const struct ctx *c, uint8_t proto,
|
||||||
* @pif: Interface of the flow
|
* @pif: Interface of the flow
|
||||||
* @af: Address family, AF_INET or AF_INET6
|
* @af: Address family, AF_INET or AF_INET6
|
||||||
* @eaddr: Guest side endpoint address (guest local address)
|
* @eaddr: Guest side endpoint address (guest local address)
|
||||||
* @faddr: Guest side forwarding address (guest remote address)
|
* @oaddr: Our guest side address (guest remote address)
|
||||||
* @eport: Guest side endpoint port (guest local port)
|
* @eport: Guest side endpoint port (guest local port)
|
||||||
* @fport: Guest side forwarding port (guest remote port)
|
* @oport: Our guest side port (guest remote port)
|
||||||
*
|
*
|
||||||
* Return: sidx of the matching flow & side, FLOW_SIDX_NONE if not found
|
* Return: sidx of the matching flow & side, FLOW_SIDX_NONE if not found
|
||||||
*/
|
*/
|
||||||
flow_sidx_t flow_lookup_af(const struct ctx *c,
|
flow_sidx_t flow_lookup_af(const struct ctx *c,
|
||||||
uint8_t proto, uint8_t pif, sa_family_t af,
|
uint8_t proto, uint8_t pif, sa_family_t af,
|
||||||
const void *eaddr, const void *faddr,
|
const void *eaddr, const void *oaddr,
|
||||||
in_port_t eport, in_port_t fport)
|
in_port_t eport, in_port_t oport)
|
||||||
{
|
{
|
||||||
struct flowside side;
|
struct flowside side;
|
||||||
|
|
||||||
flowside_from_af(&side, af, eaddr, eport, faddr, fport);
|
flowside_from_af(&side, af, eaddr, eport, oaddr, oport);
|
||||||
return flowside_lookup(c, proto, pif, &side);
|
return flowside_lookup(c, proto, pif, &side);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -732,22 +732,22 @@ flow_sidx_t flow_lookup_af(const struct ctx *c,
|
||||||
* @proto: Protocol of the flow (IP L4 protocol number)
|
* @proto: Protocol of the flow (IP L4 protocol number)
|
||||||
* @pif: Interface of the flow
|
* @pif: Interface of the flow
|
||||||
* @esa: Socket address of the endpoint
|
* @esa: Socket address of the endpoint
|
||||||
* @fport: Forwarding port number
|
* @oport: Our port number
|
||||||
*
|
*
|
||||||
* Return: sidx of the matching flow & side, FLOW_SIDX_NONE if not found
|
* Return: sidx of the matching flow & side, FLOW_SIDX_NONE if not found
|
||||||
*/
|
*/
|
||||||
flow_sidx_t flow_lookup_sa(const struct ctx *c, uint8_t proto, uint8_t pif,
|
flow_sidx_t flow_lookup_sa(const struct ctx *c, uint8_t proto, uint8_t pif,
|
||||||
const void *esa, in_port_t fport)
|
const void *esa, in_port_t oport)
|
||||||
{
|
{
|
||||||
struct flowside side = {
|
struct flowside side = {
|
||||||
.fport = fport,
|
.oport = oport,
|
||||||
};
|
};
|
||||||
|
|
||||||
inany_from_sockaddr(&side.eaddr, &side.eport, esa);
|
inany_from_sockaddr(&side.eaddr, &side.eport, esa);
|
||||||
if (inany_v4(&side.eaddr))
|
if (inany_v4(&side.eaddr))
|
||||||
side.faddr = inany_any4;
|
side.oaddr = inany_any4;
|
||||||
else
|
else
|
||||||
side.faddr = inany_any6;
|
side.oaddr = inany_any6;
|
||||||
|
|
||||||
return flowside_lookup(c, proto, pif, &side);
|
return flowside_lookup(c, proto, pif, &side);
|
||||||
}
|
}
|
||||||
|
|
18
flow.h
18
flow.h
|
@ -140,14 +140,14 @@ extern const uint8_t flow_proto[];
|
||||||
/**
|
/**
|
||||||
* struct flowside - Address information for one side of a flow
|
* struct flowside - Address information for one side of a flow
|
||||||
* @eaddr: Endpoint address (remote address from passt's PoV)
|
* @eaddr: Endpoint address (remote address from passt's PoV)
|
||||||
* @faddr: Forwarding address (local address from passt's PoV)
|
* @oaddr: Our address (local address from passt's PoV)
|
||||||
* @eport: Endpoint port
|
* @eport: Endpoint port
|
||||||
* @fport: Forwarding port
|
* @oport: Our port
|
||||||
*/
|
*/
|
||||||
struct flowside {
|
struct flowside {
|
||||||
union inany_addr faddr;
|
union inany_addr oaddr;
|
||||||
union inany_addr eaddr;
|
union inany_addr eaddr;
|
||||||
in_port_t fport;
|
in_port_t oport;
|
||||||
in_port_t eport;
|
in_port_t eport;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -162,8 +162,8 @@ static inline bool flowside_eq(const struct flowside *left,
|
||||||
{
|
{
|
||||||
return inany_equals(&left->eaddr, &right->eaddr) &&
|
return inany_equals(&left->eaddr, &right->eaddr) &&
|
||||||
left->eport == right->eport &&
|
left->eport == right->eport &&
|
||||||
inany_equals(&left->faddr, &right->faddr) &&
|
inany_equals(&left->oaddr, &right->oaddr) &&
|
||||||
left->fport == right->fport;
|
left->oport == right->oport;
|
||||||
}
|
}
|
||||||
|
|
||||||
int flowside_sock_l4(const struct ctx *c, enum epoll_type type, uint8_t pif,
|
int flowside_sock_l4(const struct ctx *c, enum epoll_type type, uint8_t pif,
|
||||||
|
@ -240,10 +240,10 @@ uint64_t flow_hash_insert(const struct ctx *c, flow_sidx_t sidx);
|
||||||
void flow_hash_remove(const struct ctx *c, flow_sidx_t sidx);
|
void flow_hash_remove(const struct ctx *c, flow_sidx_t sidx);
|
||||||
flow_sidx_t flow_lookup_af(const struct ctx *c,
|
flow_sidx_t flow_lookup_af(const struct ctx *c,
|
||||||
uint8_t proto, uint8_t pif, sa_family_t af,
|
uint8_t proto, uint8_t pif, sa_family_t af,
|
||||||
const void *eaddr, const void *faddr,
|
const void *eaddr, const void *oaddr,
|
||||||
in_port_t eport, in_port_t fport);
|
in_port_t eport, in_port_t oport);
|
||||||
flow_sidx_t flow_lookup_sa(const struct ctx *c, uint8_t proto, uint8_t pif,
|
flow_sidx_t flow_lookup_sa(const struct ctx *c, uint8_t proto, uint8_t pif,
|
||||||
const void *esa, in_port_t fport);
|
const void *esa, in_port_t oport);
|
||||||
|
|
||||||
union flow;
|
union flow;
|
||||||
|
|
||||||
|
|
70
fwd.c
70
fwd.c
|
@ -167,7 +167,7 @@ void fwd_scan_ports_init(struct ctx *c)
|
||||||
static bool is_dns_flow(uint8_t proto, const struct flowside *ini)
|
static bool is_dns_flow(uint8_t proto, const struct flowside *ini)
|
||||||
{
|
{
|
||||||
return ((proto == IPPROTO_UDP) || (proto == IPPROTO_TCP)) &&
|
return ((proto == IPPROTO_UDP) || (proto == IPPROTO_TCP)) &&
|
||||||
((ini->fport == 53) || (ini->fport == 853));
|
((ini->oport == 53) || (ini->oport == 853));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -184,33 +184,33 @@ uint8_t fwd_nat_from_tap(const struct ctx *c, uint8_t proto,
|
||||||
const struct flowside *ini, struct flowside *tgt)
|
const struct flowside *ini, struct flowside *tgt)
|
||||||
{
|
{
|
||||||
if (is_dns_flow(proto, ini) &&
|
if (is_dns_flow(proto, ini) &&
|
||||||
inany_equals4(&ini->faddr, &c->ip4.dns_match))
|
inany_equals4(&ini->oaddr, &c->ip4.dns_match))
|
||||||
tgt->eaddr = inany_from_v4(c->ip4.dns_host);
|
tgt->eaddr = inany_from_v4(c->ip4.dns_host);
|
||||||
else if (is_dns_flow(proto, ini) &&
|
else if (is_dns_flow(proto, ini) &&
|
||||||
inany_equals6(&ini->faddr, &c->ip6.dns_match))
|
inany_equals6(&ini->oaddr, &c->ip6.dns_match))
|
||||||
tgt->eaddr.a6 = c->ip6.dns_host;
|
tgt->eaddr.a6 = c->ip6.dns_host;
|
||||||
else if (!c->no_map_gw && inany_equals4(&ini->faddr, &c->ip4.gw))
|
else if (!c->no_map_gw && inany_equals4(&ini->oaddr, &c->ip4.gw))
|
||||||
tgt->eaddr = inany_loopback4;
|
tgt->eaddr = inany_loopback4;
|
||||||
else if (!c->no_map_gw && inany_equals6(&ini->faddr, &c->ip6.gw))
|
else if (!c->no_map_gw && inany_equals6(&ini->oaddr, &c->ip6.gw))
|
||||||
tgt->eaddr = inany_loopback6;
|
tgt->eaddr = inany_loopback6;
|
||||||
else
|
else
|
||||||
tgt->eaddr = ini->faddr;
|
tgt->eaddr = ini->oaddr;
|
||||||
|
|
||||||
tgt->eport = ini->fport;
|
tgt->eport = ini->oport;
|
||||||
|
|
||||||
/* The relevant addr_out controls the host side source address. This
|
/* The relevant addr_out controls the host side source address. This
|
||||||
* may be unspecified, which allows the kernel to pick an address.
|
* may be unspecified, which allows the kernel to pick an address.
|
||||||
*/
|
*/
|
||||||
if (inany_v4(&tgt->eaddr))
|
if (inany_v4(&tgt->eaddr))
|
||||||
tgt->faddr = inany_from_v4(c->ip4.addr_out);
|
tgt->oaddr = inany_from_v4(c->ip4.addr_out);
|
||||||
else
|
else
|
||||||
tgt->faddr.a6 = c->ip6.addr_out;
|
tgt->oaddr.a6 = c->ip6.addr_out;
|
||||||
|
|
||||||
/* Let the kernel pick a host side source port */
|
/* Let the kernel pick a host side source port */
|
||||||
tgt->fport = 0;
|
tgt->oport = 0;
|
||||||
if (proto == IPPROTO_UDP) {
|
if (proto == IPPROTO_UDP) {
|
||||||
/* But for UDP we preserve the source port */
|
/* But for UDP we preserve the source port */
|
||||||
tgt->fport = ini->eport;
|
tgt->oport = ini->eport;
|
||||||
}
|
}
|
||||||
|
|
||||||
return PIF_HOST;
|
return PIF_HOST;
|
||||||
|
@ -230,13 +230,13 @@ uint8_t fwd_nat_from_splice(const struct ctx *c, uint8_t proto,
|
||||||
const struct flowside *ini, struct flowside *tgt)
|
const struct flowside *ini, struct flowside *tgt)
|
||||||
{
|
{
|
||||||
if (!inany_is_loopback(&ini->eaddr) ||
|
if (!inany_is_loopback(&ini->eaddr) ||
|
||||||
(!inany_is_loopback(&ini->faddr) && !inany_is_unspecified(&ini->faddr))) {
|
(!inany_is_loopback(&ini->oaddr) && !inany_is_unspecified(&ini->oaddr))) {
|
||||||
char estr[INANY_ADDRSTRLEN], fstr[INANY_ADDRSTRLEN];
|
char estr[INANY_ADDRSTRLEN], fstr[INANY_ADDRSTRLEN];
|
||||||
|
|
||||||
debug("Non loopback address on %s: [%s]:%hu -> [%s]:%hu",
|
debug("Non loopback address on %s: [%s]:%hu -> [%s]:%hu",
|
||||||
pif_name(PIF_SPLICE),
|
pif_name(PIF_SPLICE),
|
||||||
inany_ntop(&ini->eaddr, estr, sizeof(estr)), ini->eport,
|
inany_ntop(&ini->eaddr, estr, sizeof(estr)), ini->eport,
|
||||||
inany_ntop(&ini->faddr, fstr, sizeof(fstr)), ini->fport);
|
inany_ntop(&ini->oaddr, fstr, sizeof(fstr)), ini->oport);
|
||||||
return PIF_NONE;
|
return PIF_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,20 +248,20 @@ uint8_t fwd_nat_from_splice(const struct ctx *c, uint8_t proto,
|
||||||
/* Preserve the specific loopback adddress used, but let the kernel pick
|
/* Preserve the specific loopback adddress used, but let the kernel pick
|
||||||
* a source port on the target side
|
* a source port on the target side
|
||||||
*/
|
*/
|
||||||
tgt->faddr = ini->eaddr;
|
tgt->oaddr = ini->eaddr;
|
||||||
tgt->fport = 0;
|
tgt->oport = 0;
|
||||||
|
|
||||||
tgt->eport = ini->fport;
|
tgt->eport = ini->oport;
|
||||||
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.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->oport = 0;
|
||||||
if (proto == IPPROTO_UDP)
|
if (proto == IPPROTO_UDP)
|
||||||
/* But for UDP preserve the source port */
|
/* But for UDP preserve the source port */
|
||||||
tgt->fport = ini->eport;
|
tgt->oport = ini->eport;
|
||||||
|
|
||||||
return PIF_HOST;
|
return PIF_HOST;
|
||||||
}
|
}
|
||||||
|
@ -280,7 +280,7 @@ uint8_t fwd_nat_from_host(const struct ctx *c, uint8_t proto,
|
||||||
const struct flowside *ini, struct flowside *tgt)
|
const struct flowside *ini, struct flowside *tgt)
|
||||||
{
|
{
|
||||||
/* Common for spliced and non-spliced cases */
|
/* Common for spliced and non-spliced cases */
|
||||||
tgt->eport = ini->fport;
|
tgt->eport = ini->oport;
|
||||||
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)
|
||||||
|
@ -293,11 +293,11 @@ uint8_t fwd_nat_from_host(const struct ctx *c, uint8_t proto,
|
||||||
/* Preserve the specific loopback adddress used, but let the
|
/* Preserve the specific loopback adddress used, but let the
|
||||||
* kernel pick a source port on the target side
|
* kernel pick a source port on the target side
|
||||||
*/
|
*/
|
||||||
tgt->faddr = ini->eaddr;
|
tgt->oaddr = ini->eaddr;
|
||||||
tgt->fport = 0;
|
tgt->oport = 0;
|
||||||
if (proto == IPPROTO_UDP)
|
if (proto == IPPROTO_UDP)
|
||||||
/* But for UDP preserve the source port */
|
/* But for UDP preserve the source port */
|
||||||
tgt->fport = ini->eport;
|
tgt->oport = ini->eport;
|
||||||
|
|
||||||
if (inany_v4(&ini->eaddr))
|
if (inany_v4(&ini->eaddr))
|
||||||
tgt->eaddr = inany_loopback4;
|
tgt->eaddr = inany_loopback4;
|
||||||
|
@ -307,26 +307,26 @@ uint8_t fwd_nat_from_host(const struct ctx *c, uint8_t proto,
|
||||||
return PIF_SPLICE;
|
return PIF_SPLICE;
|
||||||
}
|
}
|
||||||
|
|
||||||
tgt->faddr = ini->eaddr;
|
tgt->oaddr = ini->eaddr;
|
||||||
tgt->fport = ini->eport;
|
tgt->oport = ini->eport;
|
||||||
|
|
||||||
if (inany_is_loopback4(&tgt->faddr) ||
|
if (inany_is_loopback4(&tgt->oaddr) ||
|
||||||
inany_is_unspecified4(&tgt->faddr) ||
|
inany_is_unspecified4(&tgt->oaddr) ||
|
||||||
inany_equals4(&tgt->faddr, &c->ip4.addr_seen)) {
|
inany_equals4(&tgt->oaddr, &c->ip4.addr_seen)) {
|
||||||
tgt->faddr = inany_from_v4(c->ip4.gw);
|
tgt->oaddr = inany_from_v4(c->ip4.gw);
|
||||||
} else if (inany_is_loopback6(&tgt->faddr) ||
|
} else if (inany_is_loopback6(&tgt->oaddr) ||
|
||||||
inany_equals6(&tgt->faddr, &c->ip6.addr_seen) ||
|
inany_equals6(&tgt->oaddr, &c->ip6.addr_seen) ||
|
||||||
inany_equals6(&tgt->faddr, &c->ip6.addr)) {
|
inany_equals6(&tgt->oaddr, &c->ip6.addr)) {
|
||||||
if (IN6_IS_ADDR_LINKLOCAL(&c->ip6.gw))
|
if (IN6_IS_ADDR_LINKLOCAL(&c->ip6.gw))
|
||||||
tgt->faddr.a6 = c->ip6.gw;
|
tgt->oaddr.a6 = c->ip6.gw;
|
||||||
else
|
else
|
||||||
tgt->faddr.a6 = c->ip6.addr_ll;
|
tgt->oaddr.a6 = c->ip6.addr_ll;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inany_v4(&tgt->faddr)) {
|
if (inany_v4(&tgt->oaddr)) {
|
||||||
tgt->eaddr = inany_from_v4(c->ip4.addr_seen);
|
tgt->eaddr = inany_from_v4(c->ip4.addr_seen);
|
||||||
} else {
|
} else {
|
||||||
if (inany_is_linklocal6(&tgt->faddr))
|
if (inany_is_linklocal6(&tgt->oaddr))
|
||||||
tgt->eaddr.a6 = c->ip6.addr_ll_seen;
|
tgt->eaddr.a6 = c->ip6.addr_ll_seen;
|
||||||
else
|
else
|
||||||
tgt->eaddr.a6 = c->ip6.addr_seen;
|
tgt->eaddr.a6 = c->ip6.addr_seen;
|
||||||
|
|
4
icmp.c
4
icmp.c
|
@ -125,13 +125,13 @@ void icmp_sock_handler(const struct ctx *c, union epoll_ref ref)
|
||||||
ini->eport, seq);
|
ini->eport, seq);
|
||||||
|
|
||||||
if (pingf->f.type == FLOW_PING4) {
|
if (pingf->f.type == FLOW_PING4) {
|
||||||
const struct in_addr *saddr = inany_v4(&ini->faddr);
|
const struct in_addr *saddr = inany_v4(&ini->oaddr);
|
||||||
const struct in_addr *daddr = inany_v4(&ini->eaddr);
|
const struct in_addr *daddr = inany_v4(&ini->eaddr);
|
||||||
|
|
||||||
ASSERT(saddr && daddr); /* Must have IPv4 addresses */
|
ASSERT(saddr && daddr); /* Must have IPv4 addresses */
|
||||||
tap_icmp4_send(c, *saddr, *daddr, buf, n);
|
tap_icmp4_send(c, *saddr, *daddr, buf, n);
|
||||||
} else if (pingf->f.type == FLOW_PING6) {
|
} else if (pingf->f.type == FLOW_PING6) {
|
||||||
const struct in6_addr *saddr = &ini->faddr.a6;
|
const struct in6_addr *saddr = &ini->oaddr.a6;
|
||||||
const struct in6_addr *daddr = &ini->eaddr.a6;
|
const struct in6_addr *daddr = &ini->eaddr.a6;
|
||||||
|
|
||||||
tap_icmp6_send(c, saddr, daddr, buf, n);
|
tap_icmp6_send(c, saddr, daddr, buf, n);
|
||||||
|
|
33
tcp.c
33
tcp.c
|
@ -361,8 +361,8 @@ static const char *tcp_flag_str[] __attribute((__unused__)) = {
|
||||||
static int tcp_sock_init_ext [NUM_PORTS][IP_VERSIONS];
|
static int tcp_sock_init_ext [NUM_PORTS][IP_VERSIONS];
|
||||||
static int tcp_sock_ns [NUM_PORTS][IP_VERSIONS];
|
static int tcp_sock_ns [NUM_PORTS][IP_VERSIONS];
|
||||||
|
|
||||||
/* Table of guest side forwarding addresses with very low RTT (assumed
|
/* Table of our guest side addresses with very low RTT (assumed to be local to
|
||||||
* to be local to the host), LRU
|
* the host), LRU
|
||||||
*/
|
*/
|
||||||
static union inany_addr low_rtt_dst[LOW_RTT_TABLE_SIZE];
|
static union inany_addr low_rtt_dst[LOW_RTT_TABLE_SIZE];
|
||||||
|
|
||||||
|
@ -663,7 +663,7 @@ static int tcp_rtt_dst_low(const struct tcp_tap_conn *conn)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < LOW_RTT_TABLE_SIZE; i++)
|
for (i = 0; i < LOW_RTT_TABLE_SIZE; i++)
|
||||||
if (inany_equals(&tapside->faddr, low_rtt_dst + i))
|
if (inany_equals(&tapside->oaddr, low_rtt_dst + i))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -686,7 +686,7 @@ static void tcp_rtt_dst_check(const struct tcp_tap_conn *conn,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < LOW_RTT_TABLE_SIZE; i++) {
|
for (i = 0; i < LOW_RTT_TABLE_SIZE; i++) {
|
||||||
if (inany_equals(&tapside->faddr, low_rtt_dst + i))
|
if (inany_equals(&tapside->oaddr, low_rtt_dst + i))
|
||||||
return;
|
return;
|
||||||
if (hole == -1 && IN6_IS_ADDR_UNSPECIFIED(low_rtt_dst + i))
|
if (hole == -1 && IN6_IS_ADDR_UNSPECIFIED(low_rtt_dst + i))
|
||||||
hole = i;
|
hole = i;
|
||||||
|
@ -698,7 +698,7 @@ static void tcp_rtt_dst_check(const struct tcp_tap_conn *conn,
|
||||||
if (hole == -1)
|
if (hole == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
low_rtt_dst[hole++] = tapside->faddr;
|
low_rtt_dst[hole++] = tapside->oaddr;
|
||||||
if (hole == LOW_RTT_TABLE_SIZE)
|
if (hole == LOW_RTT_TABLE_SIZE)
|
||||||
hole = 0;
|
hole = 0;
|
||||||
inany_from_af(low_rtt_dst + hole, AF_INET6, &in6addr_any);
|
inany_from_af(low_rtt_dst + hole, AF_INET6, &in6addr_any);
|
||||||
|
@ -881,7 +881,7 @@ static void tcp_fill_header(struct tcphdr *th,
|
||||||
{
|
{
|
||||||
const struct flowside *tapside = TAPFLOW(conn);
|
const struct flowside *tapside = TAPFLOW(conn);
|
||||||
|
|
||||||
th->source = htons(tapside->fport);
|
th->source = htons(tapside->oport);
|
||||||
th->dest = htons(tapside->eport);
|
th->dest = htons(tapside->eport);
|
||||||
th->seq = htonl(seq);
|
th->seq = htonl(seq);
|
||||||
th->ack_seq = htonl(conn->seq_ack_to_tap);
|
th->ack_seq = htonl(conn->seq_ack_to_tap);
|
||||||
|
@ -913,7 +913,7 @@ static size_t tcp_fill_headers4(const struct tcp_tap_conn *conn,
|
||||||
uint32_t seq)
|
uint32_t seq)
|
||||||
{
|
{
|
||||||
const struct flowside *tapside = TAPFLOW(conn);
|
const struct flowside *tapside = TAPFLOW(conn);
|
||||||
const struct in_addr *src4 = inany_v4(&tapside->faddr);
|
const struct in_addr *src4 = inany_v4(&tapside->oaddr);
|
||||||
const struct in_addr *dst4 = inany_v4(&tapside->eaddr);
|
const struct in_addr *dst4 = inany_v4(&tapside->eaddr);
|
||||||
size_t l4len = dlen + sizeof(*th);
|
size_t l4len = dlen + sizeof(*th);
|
||||||
size_t l3len = l4len + sizeof(*iph);
|
size_t l3len = l4len + sizeof(*iph);
|
||||||
|
@ -957,7 +957,7 @@ static size_t tcp_fill_headers6(const struct tcp_tap_conn *conn,
|
||||||
size_t l4len = dlen + sizeof(*th);
|
size_t l4len = dlen + sizeof(*th);
|
||||||
|
|
||||||
ip6h->payload_len = htons(l4len);
|
ip6h->payload_len = htons(l4len);
|
||||||
ip6h->saddr = tapside->faddr.a6;
|
ip6h->saddr = tapside->oaddr.a6;
|
||||||
ip6h->daddr = tapside->eaddr.a6;
|
ip6h->daddr = tapside->eaddr.a6;
|
||||||
|
|
||||||
ip6h->hop_limit = 255;
|
ip6h->hop_limit = 255;
|
||||||
|
@ -992,7 +992,7 @@ size_t tcp_l2_buf_fill_headers(const struct tcp_tap_conn *conn,
|
||||||
const uint16_t *check, uint32_t seq)
|
const uint16_t *check, uint32_t seq)
|
||||||
{
|
{
|
||||||
const struct flowside *tapside = TAPFLOW(conn);
|
const struct flowside *tapside = TAPFLOW(conn);
|
||||||
const struct in_addr *a4 = inany_v4(&tapside->faddr);
|
const struct in_addr *a4 = inany_v4(&tapside->oaddr);
|
||||||
|
|
||||||
if (a4) {
|
if (a4) {
|
||||||
return tcp_fill_headers4(conn, iov[TCP_IOV_TAP].iov_base,
|
return tcp_fill_headers4(conn, iov[TCP_IOV_TAP].iov_base,
|
||||||
|
@ -1417,15 +1417,15 @@ static void tcp_bind_outbound(const struct ctx *c,
|
||||||
socklen_t sl;
|
socklen_t sl;
|
||||||
|
|
||||||
|
|
||||||
pif_sockaddr(c, &bind_sa, &sl, PIF_HOST, &tgt->faddr, tgt->fport);
|
pif_sockaddr(c, &bind_sa, &sl, PIF_HOST, &tgt->oaddr, tgt->oport);
|
||||||
if (!inany_is_unspecified(&tgt->faddr) || tgt->fport) {
|
if (!inany_is_unspecified(&tgt->oaddr) || tgt->oport) {
|
||||||
if (bind(s, &bind_sa.sa, sl)) {
|
if (bind(s, &bind_sa.sa, sl)) {
|
||||||
char sstr[INANY_ADDRSTRLEN];
|
char sstr[INANY_ADDRSTRLEN];
|
||||||
|
|
||||||
flow_dbg(conn,
|
flow_dbg(conn,
|
||||||
"Can't bind TCP outbound socket to %s:%hu: %s",
|
"Can't bind TCP outbound socket to %s:%hu: %s",
|
||||||
inany_ntop(&tgt->faddr, sstr, sizeof(sstr)),
|
inany_ntop(&tgt->oaddr, sstr, sizeof(sstr)),
|
||||||
tgt->fport, strerror(errno));
|
tgt->oport, strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1497,12 +1497,12 @@ static void tcp_conn_from_tap(struct ctx *c, sa_family_t af,
|
||||||
conn = FLOW_SET_TYPE(flow, FLOW_TCP, tcp);
|
conn = FLOW_SET_TYPE(flow, FLOW_TCP, tcp);
|
||||||
|
|
||||||
if (!inany_is_unicast(&ini->eaddr) || ini->eport == 0 ||
|
if (!inany_is_unicast(&ini->eaddr) || ini->eport == 0 ||
|
||||||
!inany_is_unicast(&ini->faddr) || ini->fport == 0) {
|
!inany_is_unicast(&ini->oaddr) || ini->oport == 0) {
|
||||||
char sstr[INANY_ADDRSTRLEN], dstr[INANY_ADDRSTRLEN];
|
char sstr[INANY_ADDRSTRLEN], dstr[INANY_ADDRSTRLEN];
|
||||||
|
|
||||||
debug("Invalid endpoint in TCP SYN: %s:%hu -> %s:%hu",
|
debug("Invalid endpoint in TCP SYN: %s:%hu -> %s:%hu",
|
||||||
inany_ntop(&ini->eaddr, sstr, sizeof(sstr)), ini->eport,
|
inany_ntop(&ini->eaddr, sstr, sizeof(sstr)), ini->eport,
|
||||||
inany_ntop(&ini->faddr, dstr, sizeof(dstr)), ini->fport);
|
inany_ntop(&ini->oaddr, dstr, sizeof(dstr)), ini->oport);
|
||||||
goto cancel;
|
goto cancel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2100,7 +2100,8 @@ void tcp_listen_handler(struct ctx *c, union epoll_ref ref,
|
||||||
goto cancel;
|
goto cancel;
|
||||||
|
|
||||||
/* FIXME: When listening port has a specific bound address, record that
|
/* FIXME: When listening port has a specific bound address, record that
|
||||||
* as the forwarding address */
|
* as our address
|
||||||
|
*/
|
||||||
ini = flow_initiate_sa(flow, ref.tcp_listen.pif, &sa,
|
ini = flow_initiate_sa(flow, ref.tcp_listen.pif, &sa,
|
||||||
ref.tcp_listen.port);
|
ref.tcp_listen.port);
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
#define TAPFLOW(conn_) (&((conn_)->f.side[TAPSIDE(conn_)]))
|
#define TAPFLOW(conn_) (&((conn_)->f.side[TAPSIDE(conn_)]))
|
||||||
#define TAP_SIDX(conn_) (FLOW_SIDX((conn_), TAPSIDE(conn_)))
|
#define TAP_SIDX(conn_) (FLOW_SIDX((conn_), TAPSIDE(conn_)))
|
||||||
|
|
||||||
#define CONN_V4(conn) (!!inany_v4(&TAPFLOW(conn)->faddr))
|
#define CONN_V4(conn) (!!inany_v4(&TAPFLOW(conn)->oaddr))
|
||||||
#define CONN_V6(conn) (!CONN_V4(conn))
|
#define CONN_V6(conn) (!CONN_V4(conn))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
12
udp.c
12
udp.c
|
@ -321,7 +321,7 @@ static void udp_splice_send(const struct ctx *c, size_t start, size_t n,
|
||||||
static size_t udp_update_hdr4(struct iphdr *ip4h, struct udp_payload_t *bp,
|
static size_t udp_update_hdr4(struct iphdr *ip4h, struct udp_payload_t *bp,
|
||||||
const struct flowside *toside, size_t dlen)
|
const struct flowside *toside, size_t dlen)
|
||||||
{
|
{
|
||||||
const struct in_addr *src = inany_v4(&toside->faddr);
|
const struct in_addr *src = inany_v4(&toside->oaddr);
|
||||||
const struct in_addr *dst = inany_v4(&toside->eaddr);
|
const struct in_addr *dst = inany_v4(&toside->eaddr);
|
||||||
size_t l4len = dlen + sizeof(bp->uh);
|
size_t l4len = dlen + sizeof(bp->uh);
|
||||||
size_t l3len = l4len + sizeof(*ip4h);
|
size_t l3len = l4len + sizeof(*ip4h);
|
||||||
|
@ -333,7 +333,7 @@ static size_t udp_update_hdr4(struct iphdr *ip4h, struct udp_payload_t *bp,
|
||||||
ip4h->saddr = src->s_addr;
|
ip4h->saddr = src->s_addr;
|
||||||
ip4h->check = csum_ip4_header(l3len, IPPROTO_UDP, *src, *dst);
|
ip4h->check = csum_ip4_header(l3len, IPPROTO_UDP, *src, *dst);
|
||||||
|
|
||||||
bp->uh.source = htons(toside->fport);
|
bp->uh.source = htons(toside->oport);
|
||||||
bp->uh.dest = htons(toside->eport);
|
bp->uh.dest = htons(toside->eport);
|
||||||
bp->uh.len = htons(l4len);
|
bp->uh.len = htons(l4len);
|
||||||
csum_udp4(&bp->uh, *src, *dst, bp->data, dlen);
|
csum_udp4(&bp->uh, *src, *dst, bp->data, dlen);
|
||||||
|
@ -357,15 +357,15 @@ static size_t udp_update_hdr6(struct ipv6hdr *ip6h, struct udp_payload_t *bp,
|
||||||
|
|
||||||
ip6h->payload_len = htons(l4len);
|
ip6h->payload_len = htons(l4len);
|
||||||
ip6h->daddr = toside->eaddr.a6;
|
ip6h->daddr = toside->eaddr.a6;
|
||||||
ip6h->saddr = toside->faddr.a6;
|
ip6h->saddr = toside->oaddr.a6;
|
||||||
ip6h->version = 6;
|
ip6h->version = 6;
|
||||||
ip6h->nexthdr = IPPROTO_UDP;
|
ip6h->nexthdr = IPPROTO_UDP;
|
||||||
ip6h->hop_limit = 255;
|
ip6h->hop_limit = 255;
|
||||||
|
|
||||||
bp->uh.source = htons(toside->fport);
|
bp->uh.source = htons(toside->oport);
|
||||||
bp->uh.dest = htons(toside->eport);
|
bp->uh.dest = htons(toside->eport);
|
||||||
bp->uh.len = ip6h->payload_len;
|
bp->uh.len = ip6h->payload_len;
|
||||||
csum_udp6(&bp->uh, &toside->faddr.a6, &toside->eaddr.a6, bp->data, dlen);
|
csum_udp6(&bp->uh, &toside->oaddr.a6, &toside->eaddr.a6, bp->data, dlen);
|
||||||
|
|
||||||
return l4len;
|
return l4len;
|
||||||
}
|
}
|
||||||
|
@ -384,7 +384,7 @@ static void udp_tap_prepare(const struct mmsghdr *mmh, unsigned idx,
|
||||||
struct udp_meta_t *bm = &udp_meta[idx];
|
struct udp_meta_t *bm = &udp_meta[idx];
|
||||||
size_t l4len;
|
size_t l4len;
|
||||||
|
|
||||||
if (!inany_v4(&toside->eaddr) || !inany_v4(&toside->faddr)) {
|
if (!inany_v4(&toside->eaddr) || !inany_v4(&toside->oaddr)) {
|
||||||
l4len = udp_update_hdr6(&bm->ip6h, bp, toside, mmh[idx].msg_len);
|
l4len = udp_update_hdr6(&bm->ip6h, bp, toside, mmh[idx].msg_len);
|
||||||
tap_hdr_update(&bm->taph, l4len + sizeof(bm->ip6h) +
|
tap_hdr_update(&bm->taph, l4len + sizeof(bm->ip6h) +
|
||||||
sizeof(udp6_eth_hdr));
|
sizeof(udp6_eth_hdr));
|
||||||
|
|
Loading…
Reference in a new issue