dhcp: remove acd handle when stopping dhcp

see bug #57706
This commit is contained in:
Simon Goldschmidt 2021-05-12 21:04:46 +02:00
parent fa5ca55c9d
commit 3a788b6e8b
3 changed files with 37 additions and 6 deletions

View File

@ -141,6 +141,34 @@ acd_add(struct netif *netif, struct acd *acd,
return ERR_OK; return ERR_OK;
} }
/**
* @ingroup acd
* Remvoe ACD client from the client list
*
* @param netif network interface from which to remove the acd client
* @param acd acd module to be removed from the list
*/
void
acd_remove(struct netif *netif, struct acd *acd)
{
struct acd *acd2, *prev = NULL;
LWIP_ASSERT_CORE_LOCKED();
for (acd2 = netif->acd_list; acd2 != NULL; acd2 = acd2->next) {
if (acd2 == acd) {
if (prev) {
prev->next = acd->next;
} else {
netif->acd_list = acd->next;
}
return;
}
}
LWIP_ASSERT(0, ("acd_remove(): acd not on list\n"));
}
/** /**
* @ingroup acd * @ingroup acd
* Start ACD client * Start ACD client

View File

@ -308,6 +308,9 @@ dhcp_conflict_callback(struct netif *netif, acd_callback_enum_t state)
struct dhcp *dhcp = netif_dhcp_data(netif); struct dhcp *dhcp = netif_dhcp_data(netif);
u16_t msecs; u16_t msecs;
LWIP_ASSERT("DHCP should be enabled at this point, but it is not!",
(dhcp != NULL) && (dhcp->state != DHCP_STATE_OFF));
switch (state) { switch (state) {
case ACD_IP_OK: case ACD_IP_OK:
dhcp_bind(netif); dhcp_bind(netif);
@ -1361,6 +1364,11 @@ dhcp_release_and_stop(struct netif *netif)
dhcp_set_state(dhcp, DHCP_STATE_OFF); dhcp_set_state(dhcp, DHCP_STATE_OFF);
} }
#if LWIP_DHCP_DOES_ACD_CHECK
/* stop acd because we may be in checking state and the callback would trigger a bind */
acd_remove(netif, &dhcp->acd);
#endif
if (dhcp->pcb_allocated != 0) { if (dhcp->pcb_allocated != 0) {
dhcp_dec_pcb_refcount(); /* free DHCP PCB if not needed any more */ dhcp_dec_pcb_refcount(); /* free DHCP PCB if not needed any more */
dhcp->pcb_allocated = 0; dhcp->pcb_allocated = 0;

View File

@ -91,17 +91,12 @@ struct acd
err_t acd_add(struct netif *netif, struct acd *acd, err_t acd_add(struct netif *netif, struct acd *acd,
acd_conflict_callback_t acd_conflict_callback); acd_conflict_callback_t acd_conflict_callback);
void acd_remove(struct netif *netif, struct acd *acd);
err_t acd_start(struct netif *netif, struct acd *acd, ip4_addr_t ipaddr); err_t acd_start(struct netif *netif, struct acd *acd, ip4_addr_t ipaddr);
err_t acd_stop(struct acd *acd); err_t acd_stop(struct acd *acd);
void acd_arp_reply(struct netif *netif, struct etharp_hdr *hdr); void acd_arp_reply(struct netif *netif, struct etharp_hdr *hdr);
void acd_tmr(void); void acd_tmr(void);
void acd_network_changed_link_down(struct netif *netif); void acd_network_changed_link_down(struct netif *netif);
void acd_netif_ip_addr_changed(struct netif *netif, const ip_addr_t *old_addr, void acd_netif_ip_addr_changed(struct netif *netif, const ip_addr_t *old_addr,
const ip_addr_t *new_addr); const ip_addr_t *new_addr);