diff --git a/src/network/networkd-ipv4ll.c b/src/network/networkd-ipv4ll.c index 7398cefe77..9682d0d874 100644 --- a/src/network/networkd-ipv4ll.c +++ b/src/network/networkd-ipv4ll.c @@ -175,6 +175,8 @@ static int ipv4ll_check_mac(sd_ipv4ll *ll, const struct ether_addr *mac, void *u } static int ipv4ll_set_address(Link *link) { + int r; + assert(link); assert(link->network); assert(link->ipv4ll); @@ -193,6 +195,27 @@ static int ipv4ll_set_address(Link *link) { if (in4_addr_is_set(&link->network->ipv4ll_start_address)) return sd_ipv4ll_set_address(link->ipv4ll, &link->network->ipv4ll_start_address); + /* 3. If KeepConfiguration=dhcp, use a foreign IPv4LL address. */ + if (!FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP)) + return 0; + + SET_FOREACH(a, link->addresses) { + if (a->source != NETWORK_CONFIG_SOURCE_FOREIGN) + continue; + if (a->family != AF_INET) + continue; + if (!in4_addr_is_link_local_dynamic(&a->in_addr.in)) + continue; + + r = sd_ipv4ll_set_address(link->ipv4ll, &a->in_addr.in); + if (r < 0) + return r; + + /* Make sure the address is not removed by link_drop_unmanaged_addresses(). */ + a->source = NETWORK_CONFIG_SOURCE_IPV4LL; + return 0; + } + return 0; }