From a9172f575b44b2ee6deb93a04af65aeee7fe7893 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Mon, 9 Jun 2025 13:43:49 +0300 Subject: [PATCH 1/2] net: if: Do not start ACD for localhost or point2point links When adding IPv4 address to the network interface, there is no need to start ACD procedure for localhost or point-to-point links. The ACD start function would mark the IP address like 127.0.0.1 as tentative and never make it preferred which would then cause issues when selecting the network address for sending. As the ACD start is also called when the network interface comes up, add the localhost and point-to-point link check to ACD start function so that we will avoid ACD checks in this case. Signed-off-by: Jukka Rissanen (cherry picked from commit 902c95ab951b5fca2de0880d7c80bf5165bd4123) --- subsys/net/ip/net_if.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/subsys/net/ip/net_if.c b/subsys/net/ip/net_if.c index cc81fc140415f..1f3ce886a2c19 100644 --- a/subsys/net/ip/net_if.c +++ b/subsys/net/ip/net_if.c @@ -4277,6 +4277,11 @@ void net_if_ipv4_acd_failed(struct net_if *iface, struct net_if_addr *ifaddr) void net_if_ipv4_start_acd(struct net_if *iface, struct net_if_addr *ifaddr) { + if ((l2_flags_get(iface) & NET_L2_POINT_TO_POINT) || + net_ipv4_is_addr_loopback(&ifaddr->address.in_addr)) { + return; + } + ifaddr->addr_state = NET_ADDR_TENTATIVE; if (net_if_is_up(iface)) { @@ -4374,6 +4379,7 @@ struct net_if_addr *net_if_ipv4_addr_add(struct net_if *iface, struct net_if_addr *ifaddr = NULL; struct net_if_addr_ipv4 *cur; struct net_if_ipv4 *ipv4; + bool do_acd = false; int idx; net_if_lock(iface); @@ -4446,7 +4452,7 @@ struct net_if_addr *net_if_ipv4_addr_add(struct net_if *iface, !(l2_flags_get(iface) & NET_L2_POINT_TO_POINT) && !net_ipv4_is_addr_loopback(addr)) { /* ACD is started after the lock is released. */ - ; + do_acd = true; } else { ifaddr->addr_state = NET_ADDR_PREFERRED; } @@ -4459,7 +4465,9 @@ struct net_if_addr *net_if_ipv4_addr_add(struct net_if *iface, net_if_unlock(iface); - net_if_ipv4_start_acd(iface, ifaddr); + if (do_acd) { + net_if_ipv4_start_acd(iface, ifaddr); + } return ifaddr; } From fc6509937001c80cec13900f6aaa375eabca70c0 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Mon, 9 Jun 2025 13:47:45 +0300 Subject: [PATCH 2/2] net: acd: Avoid removing auto IPv4 address twice When the network interface goes down, we call net_ipv4_autoconf_reset() which removes the autoaddress from the network interface. The net_ipv4_autoconf_reset() is also called when ACD is started in which case we could see this error message net_if_start_acd: Starting ACD for iface 2 net_if: iface 2 addr 169.254.174.230 (net_if_ipv4_addr_rm():4625) net_if_ipv4_addr_rm: Address 169.254.174.230 not found (-22) This error is superfluous and not needed. So before trying to remove the address, check if the interface already has it set and only then remove it. Signed-off-by: Jukka Rissanen (cherry picked from commit bd4c0b746c12a39a324d28bfce13bf6ac8442098) --- subsys/net/ip/ipv4_autoconf.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/subsys/net/ip/ipv4_autoconf.c b/subsys/net/ip/ipv4_autoconf.c index f08608f3b7e25..057bd6f41a6eb 100644 --- a/subsys/net/ip/ipv4_autoconf.c +++ b/subsys/net/ip/ipv4_autoconf.c @@ -138,13 +138,18 @@ void net_ipv4_autoconf_start(struct net_if *iface) void net_ipv4_autoconf_reset(struct net_if *iface) { struct net_if_config *cfg; + struct net_if_addr *ifaddr; + struct net_if *ret; cfg = net_if_get_config(iface); if (!cfg) { return; } - net_if_ipv4_addr_rm(iface, &cfg->ipv4auto.requested_ip); + ifaddr = net_if_ipv4_addr_lookup(&cfg->ipv4auto.requested_ip, &ret); + if (ifaddr != NULL && ret == iface) { + net_if_ipv4_addr_rm(iface, &cfg->ipv4auto.requested_ip); + } NET_DBG("Autoconf reset for %p", iface); }