When I implemented local mode in 14b84a7f077e ("treewide: Introduce
'local mode' for disconnected setups"), I didn't consider the
possibility that, also in that case, the user might want to override
addresses, default gateway or netmask, even though I expressly
mentioned this in the man page:
In this case, **unless configured otherwise**, they will assign the
IPv4 link-local address 169.254.2.1 to the guest or target
namespace, and no IPv6 address.
Fix this by checking if an address, gateway, or netmask length was
explicitly set by the user, before overriding them with the default
parameters for local mode.
This might lead to invalid configurations where we won't be able to
set the default gateway passed by the user, but we print a warning
message, and we assume users know what they're doing in that case.
Link: https://bugs.passt.top/show_bug.cgi?id=217
Fixes: 14b84a7f077e ("treewide: Introduce 'local mode' for disconnected setups")
Signed-off-by: Stefano Brivio
---
conf.c | 21 +++++++++++++++++----
1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/conf.c b/conf.c
index 0fcba5c..7908123 100644
--- a/conf.c
+++ b/conf.c
@@ -435,9 +435,16 @@ static unsigned int conf_ip4(unsigned int ifi, struct ip4_ctx *ip4)
*/
static void conf_ip4_local(struct ip4_ctx *ip4)
{
- ip4->addr_seen = ip4->addr = IP4_LL_GUEST_ADDR;
- ip4->our_tap_addr = ip4->guest_gw = IP4_LL_GUEST_GW;
- ip4->prefix_len = IP4_LL_PREFIX_LEN;
+ if (IN4_IS_ADDR_UNSPECIFIED(&ip4->addr))
+ ip4->addr = IP4_LL_GUEST_ADDR;
+ ip4->addr_seen = ip4->addr;
+
+ if (IN4_IS_ADDR_UNSPECIFIED(&ip4->guest_gw))
+ ip4->guest_gw = IP4_LL_GUEST_GW;
+ ip4->our_tap_addr = ip4->guest_gw;
+
+ if (!ip4->prefix_len)
+ ip4->prefix_len = IP4_LL_PREFIX_LEN;
ip4->no_copy_addrs = ip4->no_copy_routes = true;
}
@@ -497,7 +504,13 @@ static unsigned int conf_ip6(unsigned int ifi, struct ip6_ctx *ip6)
*/
static void conf_ip6_local(struct ip6_ctx *ip6)
{
- ip6->our_tap_ll = ip6->guest_gw = IP6_LL_GUEST_GW;
+ if (IN6_IS_ADDR_UNSPECIFIED(&ip6->guest_gw))
+ ip6->guest_gw = IP6_LL_GUEST_GW;
+
+ if (IN6_IS_ADDR_LINKLOCAL(&ip6->guest_gw))
+ ip6->our_tap_ll = ip6->guest_gw;
+ else
+ ip6->our_tap_ll = IP6_LL_GUEST_GW;
ip6->no_copy_addrs = ip6->no_copy_routes = true;
}
--
2.43.0