Link: https://github.com/containers/podman/issues/24614 Signed-off-by: Stefano Brivio <sbrivio(a)redhat.com> --- conf.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 66 insertions(+), 11 deletions(-) diff --git a/conf.c b/conf.c index 86566db..4c81aaf 100644 --- a/conf.c +++ b/conf.c @@ -48,6 +48,23 @@ #define NETNS_RUN_DIR "/run/netns" +#define IP4_LL_GUEST_ADDR (struct in_addr){ htonl_constant(0xa9fe0a02) } + /* 169.254.10.2 */ + +#define IP4_LL_GUEST_GW (struct in_addr){ htonl_constant(0xa9fe0a01) } + /* 169.254.10.1 */ + +#define IP4_LL_PREFIX_LEN 16 + +#define IP6_LL_GUEST_ADDR (struct in6_addr) \ + {{{ 0xfe, 0x80, 0, 0, 0, 0, 0, 0, \ + 0, 0, 0, 0, 0, 0, 0, 0x02 }}} +#define IP6_LL_GUEST_GW (struct in6_addr) \ + {{{ 0xfe, 0x80, 0, 0, 0, 0, 0, 0, \ + 0, 0, 0, 0, 0, 0, 0, 0x01 }}} + +const char *pasta_default_ifn = "tap0"; + /** * next_chunk - Return the next piece of a string delimited by a character * @s: String to search @@ -631,7 +648,7 @@ static unsigned int conf_ip4(unsigned int ifi, struct ip4_ctx *ip4) ifi = nl_get_ext_if(nl_sock, AF_INET); if (!ifi) { - info("Couldn't pick external interface: disabling IPv4"); + debug("Failed to detect external interface for IPv4"); return 0; } @@ -639,8 +656,8 @@ static unsigned int conf_ip4(unsigned int ifi, struct ip4_ctx *ip4) int rc = nl_route_get_def(nl_sock, ifi, AF_INET, &ip4->guest_gw); if (rc < 0) { - err("Couldn't discover IPv4 gateway address: %s", - strerror(-rc)); + debug("Couldn't discover IPv4 gateway address: %s", + strerror(-rc)); return 0; } } @@ -649,8 +666,8 @@ static unsigned int conf_ip4(unsigned int ifi, struct ip4_ctx *ip4) int rc = nl_addr_get(nl_sock, ifi, AF_INET, &ip4->addr, &ip4->prefix_len, NULL); if (rc < 0) { - err("Couldn't discover IPv4 address: %s", - strerror(-rc)); + debug("Couldn't discover IPv4 address: %s", + strerror(-rc)); return 0; } } @@ -677,6 +694,19 @@ static unsigned int conf_ip4(unsigned int ifi, struct ip4_ctx *ip4) return ifi; } +/** + * conf_ip4_local() - Configure IPv4 link-local addresses for local mode + * @ip4: IPv4 context (will be written) + */ +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; + + ip4->no_copy_addrs = ip4->no_copy_routes = true; +} + /** * conf_ip6() - Verify or detect IPv6 support, get relevant addresses * @ifi: Host interface to attempt (0 to determine one) @@ -693,15 +723,15 @@ static unsigned int conf_ip6(unsigned int ifi, struct ip6_ctx *ip6) ifi = nl_get_ext_if(nl_sock, AF_INET6); if (!ifi) { - info("Couldn't pick external interface: disabling IPv6"); + debug("Failed to detect external interface for IPv6"); return 0; } if (IN6_IS_ADDR_UNSPECIFIED(&ip6->guest_gw)) { rc = nl_route_get_def(nl_sock, ifi, AF_INET6, &ip6->guest_gw); if (rc < 0) { - err("Couldn't discover IPv6 gateway address: %s", - strerror(-rc)); + debug("Couldn't discover IPv6 gateway address: %s", + strerror(-rc)); return 0; } } @@ -710,7 +740,7 @@ static unsigned int conf_ip6(unsigned int ifi, struct ip6_ctx *ip6) IN6_IS_ADDR_UNSPECIFIED(&ip6->addr) ? &ip6->addr : NULL, &prefix_len, &ip6->our_tap_ll); if (rc < 0) { - err("Couldn't discover IPv6 address: %s", strerror(-rc)); + debug("Couldn't discover IPv6 address: %s", strerror(-rc)); return 0; } @@ -726,6 +756,18 @@ static unsigned int conf_ip6(unsigned int ifi, struct ip6_ctx *ip6) return ifi; } +/** + * conf_ip6_local() - Configure IPv6 link-local addresses for local mode + * @ip6: IPv6 context (will be written) + */ +static void conf_ip6_local(struct ip6_ctx *ip6) +{ + ip6->addr_seen = ip6->addr = IP6_LL_GUEST_ADDR; + ip6->our_tap_ll = ip6->guest_gw = IP6_LL_GUEST_GW; + + ip6->no_copy_addrs = ip6->no_copy_routes = true; +} + /** * usage() - Print usage, exit with given status code * @name: Executable name @@ -1735,8 +1777,21 @@ void conf(struct ctx *c, int argc, char **argv) c->ifi6 = conf_ip6(ifi6, &c->ip6); if ((!c->ifi4 && !c->ifi6) || (*c->ip4.ifname_out && !c->ifi4) || - (*c->ip6.ifname_out && !c->ifi6)) - die("External interface not usable"); + (*c->ip6.ifname_out && !c->ifi6)) { + /* Switch to local mode */ + info("No external interface as template, switch to local mode"); + + conf_ip4_local(&c->ip4); + c->ifi4 = -1; + + conf_ip6_local(&c->ip6); + c->ifi6 = -1; + + if (!*c->pasta_ifn) { + strncpy(c->pasta_ifn, pasta_default_ifn, + sizeof(c->pasta_ifn) - 1); + } + } if (c->ifi4 && !no_map_gw && IN4_IS_ADDR_UNSPECIFIED(&c->ip4.map_host_loopback)) -- 2.43.0