From 65f5692a12caadf375677414e633c955c9bec0a0 Mon Sep 17 00:00:00 2001 From: Leo Ruan <tingquan.ruan@cn.bosch.com> Date: Thu, 25 Jul 2024 16:37:11 +0800 Subject: [PATCH] IPv4LL: Restart ARP probling on address conflict (#340) * IPv4LL: Restart ARP probling on address conflict When IPv4LL address conflict is detected, it is failed to restart IPv4LL since IPv4LL is running. The commit fixes the problem by restarting ARP probing instead of restarting IPv4LL. --------- Co-authored-by: Roy Marples <roy@marples.name> --- src/ipv4ll.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/ipv4ll.c b/src/ipv4ll.c index 89b3dce6..43974a80 100644 --- a/src/ipv4ll.c +++ b/src/ipv4ll.c @@ -50,6 +50,8 @@ #include "sa.h" #include "script.h" +static void ipv4ll_start_arp(void *arg); + static const struct in_addr inaddr_llmask = { .s_addr = HTONL(LINKLOCAL_MASK) }; @@ -275,7 +277,7 @@ ipv4ll_found(struct interface *ifp) eloop_timeout_add_sec(ifp->ctx->eloop, state->conflicts >= MAX_CONFLICTS ? RATE_LIMIT_INTERVAL : PROBE_WAIT, - ipv4ll_start, ifp); + ipv4ll_start_arp, ifp); } static void @@ -290,7 +292,7 @@ ipv4ll_defend_failed(struct interface *ifp) rt_build(ifp->ctx, AF_INET); script_runreason(ifp, "IPV4LL"); ipv4ll_pickaddr(ifp); - ipv4ll_start(ifp); + ipv4ll_start_arp(ifp); } #ifndef KERNEL_RFC5227 @@ -323,9 +325,6 @@ ipv4ll_start(void *arg) struct ipv4ll_state *state; struct ipv4_addr *ia; bool repick; -#ifndef KERNEL_RFC5227 - struct arp_state *astate; -#endif if ((state = IPV4LL_STATE(ifp)) == NULL) { ifp->if_data[IF_DATA_IPV4LL] = calloc(1, sizeof(*state)); @@ -407,9 +406,21 @@ ipv4ll_start(void *arg) ipv4ll_pickaddr(ifp); } + ipv4ll_start_arp(ifp); +} + +static void +ipv4ll_start_arp(void *arg) +{ + struct interface *ifp = arg; #ifdef KERNEL_RFC5227 ipv4ll_not_found(ifp); #else + struct ipv4ll_state *state; + struct arp_state *astate; + + state = IPV4LL_STATE(ifp); + ipv4ll_freearp(ifp); state->arp = astate = arp_new(ifp, &state->pickedaddr); if (state->arp == NULL)