When communicating with remote hosts on the local network, some guest
applications want to see the real MAC address of that host instead
of PASST/PASTA's own tap address. The flow_common structure is a
convenient location for storing that address, so we do that in this
commit.
Note that we don“t add actual usage of this address here, that will
be done in later commits.
Signed-off-by: Jon Maloy
---
flow.c | 19 ++++++++++++++++++-
flow.h | 2 ++
2 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/flow.c b/flow.c
index feefda3..d7b3fd1 100644
--- a/flow.c
+++ b/flow.c
@@ -20,6 +20,7 @@
#include "flow.h"
#include "flow_table.h"
#include "repair.h"
+#include "netlink.h"
const char *flow_state_str[] = {
[FLOW_STATE_FREE] = "FREE",
@@ -438,18 +439,27 @@ struct flowside *flow_target(const struct ctx *c, union flow *flow,
{
char estr[INANY_ADDRSTRLEN], fstr[INANY_ADDRSTRLEN];
struct flow_common *f = &flow->f;
- const struct flowside *ini = &f->side[INISIDE];
+ struct flowside *ini = &f->side[INISIDE];
struct flowside *tgt = &f->side[TGTSIDE];
uint8_t tgtpif = PIF_NONE;
+ int ifi;
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);
+ memcpy(f->tap_omac, c->our_tap_mac, ETH_ALEN);
switch (f->pif[INISIDE]) {
case PIF_TAP:
tgtpif = fwd_nat_from_tap(c, proto, ini, tgt);
+
+ /* If there is no NAT, the remote host might be on the template
+ * interface's local network segment. If so, insert its MAC address
+ */
+ ifi = inany_v4(&ini->oaddr) ? c->ifi4 : c->ifi6;
+ if (!fwd_inany_nat(c, &ini->oaddr))
+ nl_neigh_mac_get(nl_sock, &ini->oaddr, ifi, f->tap_omac);
break;
case PIF_SPLICE:
@@ -458,6 +468,13 @@ struct flowside *flow_target(const struct ctx *c, union flow *flow,
case PIF_HOST:
tgtpif = fwd_nat_from_host(c, proto, ini, tgt);
+
+ /* If there is no NAT, the remote host might be on the template
+ * interface's local network segment. If so, insert its MAC address
+ */
+ ifi = inany_v4(&ini->eaddr) ? c->ifi4 : c->ifi6;
+ if (!fwd_inany_nat(c, &ini->eaddr))
+ nl_neigh_mac_get(nl_sock, &ini->eaddr, ifi, f->tap_omac);
break;
default:
diff --git a/flow.h b/flow.h
index cac618a..29c8bc6 100644
--- a/flow.h
+++ b/flow.h
@@ -177,6 +177,7 @@ int flowside_connect(const struct ctx *c, int s,
* @type: Type of packet flow
* @pif[]: Interface for each side of the flow
* @side[]: Information for each side of the flow
+ * @tap_omac: MAC address of remote endpoint as seen from the guest
*/
struct flow_common {
#ifdef __GNUC__
@@ -192,6 +193,7 @@ struct flow_common {
#endif
uint8_t pif[SIDES];
struct flowside side[SIDES];
+ unsigned char tap_omac[6];
};
#define FLOW_INDEX_BITS 17 /* 128k - 1 */
--
2.50.1