From 4e8aa70379a35ec9deb11d76513e7f6c4123b667 Mon Sep 17 00:00:00 2001 From: Stefano Brivio Date: Wed, 22 Jul 2026 23:41:50 +0200 Subject: conf: Honour --address, --gateway, --netmask in local mode as well 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 Reviewed-by: David Gibson --- conf.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/conf.c b/conf.c index 2223604..8205dbf 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; } -- cgit v1.2.3