From 776a092cccee073961904cc5386dd8ed6d335f77 Mon Sep 17 00:00:00 2001 From: Leo Ruan Date: Fri, 12 Jul 2024 15:02:22 +0800 Subject: [PATCH] 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. --- src/ipv4ll.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/src/ipv4ll.c b/src/ipv4ll.c index 89b3dce6..c0c4e5cf 100644 --- a/src/ipv4ll.c +++ b/src/ipv4ll.c @@ -50,6 +50,12 @@ #include "sa.h" #include "script.h" +#ifndef KERNEL_RFC5227 +static void ipv4ll_start_arp(void *arg); +#else +static void ipv4ll_start_arp(void *arg) { (void)arg; }; +#endif + static const struct in_addr inaddr_llmask = { .s_addr = HTONL(LINKLOCAL_MASK) }; @@ -275,7 +281,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 +296,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 +329,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)); @@ -410,6 +413,20 @@ ipv4ll_start(void *arg) #ifdef KERNEL_RFC5227 ipv4ll_not_found(ifp); #else + ipv4ll_start_arp(ifp); +#endif +} + +#ifndef KERNEL_RFC5227 +static void +ipv4ll_start_arp(void *arg) +{ + struct interface *ifp = arg; + 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) @@ -421,8 +438,8 @@ ipv4ll_start(void *arg) astate->defend_failed_cb = ipv4ll_defend_failed_arp; astate->free_cb = ipv4ll_free_arp; arp_probe(astate); -#endif } +#endif void ipv4ll_drop(struct interface *ifp)