We add a new context flag 'guest_gw_from_ns' to track if the gateway
was configured from the guest side, something that might have happened
either via the -g option or by a namespace-side netlink event. When set,
host side route events will not be permitted to overwrite the guest's
gateway configuration.
This gives any gateway setting from the guest side precedence over any
ditto coming from the host side.
Signed-off-by: Jon Maloy
---
conf.c | 2 ++
netlink.c | 15 +++++++++++++--
passt.h | 4 ++++
3 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/conf.c b/conf.c
index 0a4a28a..f26637c 100644
--- a/conf.c
+++ b/conf.c
@@ -1891,6 +1891,7 @@ void conf(struct ctx *c, int argc, char **argv)
!IN6_IS_ADDR_LOOPBACK(&c->ip6.guest_gw)) {
if (c->mode == MODE_PASTA)
c->ip6.no_copy_routes = true;
+ c->ip6.guest_gw_from_ns = true;
break;
}
@@ -1900,6 +1901,7 @@ void conf(struct ctx *c, int argc, char **argv)
!IN4_IS_ADDR_LOOPBACK(&c->ip4.guest_gw)) {
if (c->mode == MODE_PASTA)
c->ip4.no_copy_routes = true;
+ c->ip4.guest_gw_from_ns = true;
break;
}
diff --git a/netlink.c b/netlink.c
index d049239..de04fb7 100644
--- a/netlink.c
+++ b/netlink.c
@@ -490,6 +490,9 @@ static void nl_linkaddr_host_msg_read(struct ctx *c, const struct nlmsghdr *nh)
if (rtm->rtm_family == AF_INET) {
char buf[INET_ADDRSTRLEN];
+ if (c->ip4.guest_gw_from_ns)
+ return;
+
if (!is_new) {
c->ip4.guest_gw = (struct in_addr){ 0 };
c->ip4.our_tap_addr = (struct in_addr){ 0 };
@@ -503,6 +506,9 @@ static void nl_linkaddr_host_msg_read(struct ctx *c, const struct nlmsghdr *nh)
} else if (rtm->rtm_family == AF_INET6) {
char buf[INET6_ADDRSTRLEN];
+ if (c->ip6.guest_gw_from_ns)
+ return;
+
if (!is_new) {
c->ip6.guest_gw = (struct in6_addr){ 0 };
return;
@@ -658,15 +664,20 @@ static void nl_linkaddr_msg_read(struct ctx *c, const struct nlmsghdr *nh)
if (is_new) {
c->ip4.guest_gw = *(struct in_addr *)gw;
c->ip4.our_tap_addr = c->ip4.guest_gw;
+ c->ip4.guest_gw_from_ns = true;
} else {
c->ip4.guest_gw = (struct in_addr){ 0 };
c->ip4.our_tap_addr = (struct in_addr){ 0 };
+ c->ip4.guest_gw_from_ns = false;
}
} else if (rtm->rtm_family == AF_INET6) {
- if (is_new)
+ if (is_new) {
c->ip6.guest_gw = *(struct in6_addr *)gw;
- else
+ c->ip6.guest_gw_from_ns = true;
+ } else {
c->ip6.guest_gw = (struct in6_addr){ 0 };
+ c->ip6.guest_gw_from_ns = false;
+ }
}
}
}
diff --git a/passt.h b/passt.h
index 70ccaf1..5e7bc99 100644
--- a/passt.h
+++ b/passt.h
@@ -82,6 +82,7 @@ enum passt_modes {
* @ifname_out: Optional interface name to bind outbound sockets to
* @no_copy_routes: Don't copy all routes when configuring target namespace
* @no_copy_addrs: Don't copy all addresses when configuring namespace
+ * @guest_gw_from_ns: Gateway was set from namespace (config or ns event)
*/
struct ip4_ctx {
/* PIF_TAP addresses */
@@ -104,6 +105,7 @@ struct ip4_ctx {
bool no_copy_routes;
bool no_copy_addrs;
+ bool guest_gw_from_ns;
};
/**
@@ -125,6 +127,7 @@ struct ip4_ctx {
* @ifname_out: Optional interface name to bind outbound sockets to
* @no_copy_routes: Don't copy all routes when configuring target namespace
* @no_copy_addrs: Don't copy all addresses when configuring namespace
+ * @guest_gw_from_ns: Gateway was set from namespace (config or ns event)
*/
struct ip6_ctx {
/* PIF_TAP addresses */
@@ -148,6 +151,7 @@ struct ip6_ctx {
bool no_copy_routes;
bool no_copy_addrs;
+ bool guest_gw_from_ns;
};
#include
--
2.51.1