Merge branch 'feat/lwip_2.2.0' into 'master'

feat(lwip): Support for new lwip release 2.2.0

Closes IDFGH-11237

See merge request espressif/esp-idf!30388
This commit is contained in:
David Čermák 2024-09-13 15:38:23 +08:00
commit d4f60febdd
11 changed files with 202 additions and 39 deletions

View File

@ -1154,25 +1154,13 @@ static esp_err_t esp_netif_start_api(esp_netif_api_msg_t *msg)
#else
LOG_NETIF_DISABLED_AND_DO("DHCP Server", return ESP_ERR_NOT_SUPPORTED);
#endif
} else if (esp_netif->flags & ESP_NETIF_DHCP_CLIENT) {
#if CONFIG_LWIP_IPV4
if (esp_netif->dhcpc_status != ESP_NETIF_DHCP_STARTED) {
if (p_netif != NULL) {
struct dhcp *dhcp_data = NULL;
dhcp_data = netif_dhcp_data(p_netif);
if (dhcp_data == NULL) {
dhcp_data = (struct dhcp *)malloc(sizeof(struct dhcp));
if (dhcp_data == NULL) {
return ESP_ERR_NO_MEM;
}
dhcp_set_struct(p_netif, dhcp_data);
}
}
}
#else
#ifndef CONFIG_LWIP_IPV4
else if (esp_netif->flags & ESP_NETIF_DHCP_CLIENT) {
LOG_NETIF_DISABLED_AND_DO("IPv4's DHCP Client", return ESP_ERR_NOT_SUPPORTED);
#endif
}
#endif
// For netifs with (active) DHCP client: we update the default netif after getting a valid IP
if (!((esp_netif->flags & ESP_NETIF_DHCP_CLIENT) && esp_netif->dhcpc_status != ESP_NETIF_DHCP_STOPPED)) {
esp_netif_update_default_netif(esp_netif, ESP_NETIF_STARTED);

View File

@ -175,9 +175,9 @@ static void on_ppp_notify_phase(ppp_pcb *pcb, u8_t phase, void *ctx)
*
* @return uint32_t Length of data successfully sent
*/
static uint32_t pppos_low_level_output(ppp_pcb *pcb, uint8_t *data, uint32_t len, void *netif)
static uint32_t pppos_low_level_output(ppp_pcb *pcb, const void *data, uint32_t len, void *netif)
{
esp_err_t ret = esp_netif_transmit(netif, data, len);
esp_err_t ret = esp_netif_transmit(netif, (void*)data, len);
if (ret == ESP_OK) {
return len;
}

View File

@ -135,7 +135,13 @@ if(CONFIG_LWIP_ENABLE)
"lwip/src/netif/ppp/vj.c")
endif()
if(NOT ${target} STREQUAL "linux")
if(CONFIG_LWIP_DHCP_DOES_ARP_CHECK)
list(APPEND srcs "port/acd_dhcp_check.c")
elseif(CONFIG_LWIP_DHCP_DOES_ACD_CHECK)
list(APPEND srcs "lwip/src/core/ipv4/acd.c")
endif()
if(NOT ${target} STREQUAL "linux")
# Support for vfs and linker fragments only for target builds
set(linker_fragments linker.lf)
if(CONFIG_VFS_SUPPORT_IO)

View File

@ -318,13 +318,29 @@ menu "LWIP"
Set TCPIP task receive mail box size. Generally bigger value means higher throughput
but more memory. The value should be bigger than UDP/TCP mail box size.
config LWIP_DHCP_DOES_ARP_CHECK
bool "DHCP: Perform ARP check on any offered address"
default y
choice LWIP_DHCP_CHECKS_OFFERED_ADDRESS
prompt "Choose how DHCP validates offered IP"
default LWIP_DHCP_DOES_ARP_CHECK
depends on LWIP_IPV4
help
Enabling this option performs a check (via ARP request) if the offered IP address
is not already in use by another host on the network.
Choose the preferred way of DHCP client to check if the offered address
is available:
* Using Address Conflict Detection (ACD) module assures that the offered IP address
is properly probed and announced before binding in DHCP. This conforms to RFC5227,
but takes several seconds.
* Using ARP check, we only send two ARP requests to check for replies. This process
lasts 1 - 2 seconds.
* No conflict detection: We directly bind the offered address.
config LWIP_DHCP_DOES_ARP_CHECK
bool "DHCP provides simple ARP check"
depends on !LWIP_AUTOIP
config LWIP_DHCP_DOES_ACD_CHECK
bool "DHCP provides Address Conflict Detection (ACD)"
config LWIP_DHCP_DOES_NOT_CHECK_OFFERED_IP
bool "DHCP does not detect conflict on the offered IP"
endchoice
config LWIP_DHCP_DISABLE_CLIENT_ID
bool "DHCP: Disable Use of HW address as client identification"

View File

@ -112,7 +112,7 @@ entries:
tcp_out:tcp_rexmit_rto_prepare (noflash_text)
tcp_out:tcp_rexmit (noflash_text)
tcp_out:tcp_rexmit_fast (noflash_text)
tcp_out:tcp_output_control_segment (noflash_text)
tcp_out:tcp_output_control_segment_netif (noflash_text)
tcp_out:tcp_rst (noflash_text)
tcp_out:tcp_send_empty_ack (noflash_text)
sys_arch:sys_arch_protect (noflash_text)

@ -1 +1 @@
Subproject commit 0606eed9d8b98a797514fdf6eabb4daf1c8c8cd9
Subproject commit f150e2321ac09bb0fd35a7fcbc1b116fbf93434e

View File

@ -0,0 +1,138 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "lwip/opt.h"
/* don't build if not configured for use in lwipopts.h */
#if LWIP_IPV4 && DHCP_DOES_ARP_CHECK
#include "lwip/acd.h"
#include "lwip/dhcp.h"
#include "lwip/prot/dhcp.h"
#include "lwip/timeouts.h"
#define ACD_DHCP_ARP_REPLY_TIMEOUT_MS 500
static void
acd_dhcp_check_timeout_cb(void *arg);
static void
acd_suspend(struct netif *netif)
{
struct dhcp *dhcp;
struct acd *acd;
if (netif == NULL || (dhcp = netif_dhcp_data(netif)) == NULL) {
return;
}
acd = &dhcp->acd;
acd->state = ACD_STATE_OFF;
sys_untimeout(acd_dhcp_check_timeout_cb, (void *)netif);
}
void
acd_remove(struct netif *netif, struct acd *acd)
{
acd_suspend(netif);
acd->acd_conflict_callback = NULL;
}
void
acd_netif_ip_addr_changed(struct netif *netif, const ip_addr_t *old_addr,
const ip_addr_t *new_addr)
{
acd_suspend(netif);
}
void
acd_network_changed_link_down(struct netif *netif)
{
acd_suspend(netif);
}
void
acd_arp_reply(struct netif *netif, struct etharp_hdr *hdr)
{
struct dhcp *dhcp;
ip4_addr_t sipaddr;
struct eth_addr netifaddr;
struct acd *acd;
if (netif == NULL || (dhcp = netif_dhcp_data(netif)) == NULL) {
return;
}
acd = &dhcp->acd;
// Check that we're looking for ARP reply in ACD_PROBING state and DHCP_CHECKING state
if (hdr->opcode != PP_HTONS(ARP_REPLY) || dhcp->state != DHCP_STATE_CHECKING ||
acd->state != ACD_STATE_PROBING || acd->acd_conflict_callback == NULL) {
return;
}
SMEMCPY(netifaddr.addr, netif->hwaddr, ETH_HWADDR_LEN);
IPADDR_WORDALIGNED_COPY_TO_IP4_ADDR_T(&sipaddr, &hdr->sipaddr);
LWIP_DEBUGF(ACD_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("acd_arp_reply(): CHECKING, arp reply for 0x%08"X32_F"\n",
ip4_addr_get_u32(&sipaddr)));
/* did another host (not our mac addr) respond with the address we were offered by the DHCP server? */
if (ip4_addr_eq(&sipaddr, &dhcp->offered_ip_addr) &&
!eth_addr_eq(&netifaddr, &hdr->shwaddr)) {
LWIP_DEBUGF(ACD_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING,
("acd_arp_reply(): arp reply matched with offered address, declining\n"));
dhcp->acd.acd_conflict_callback(netif, ACD_DECLINE);
}
}
err_t
acd_add(struct netif *netif, struct acd *acd,
acd_conflict_callback_t acd_conflict_callback)
{
acd->acd_conflict_callback = acd_conflict_callback;
return ERR_OK;
}
static void send_probe_once(struct netif *netif)
{
struct dhcp *dhcp = netif_dhcp_data(netif);
if (etharp_query(netif, &dhcp->offered_ip_addr, NULL) != ERR_OK) {
LWIP_DEBUGF(ACD_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("acd_send_probe_once(): could not perform ARP query\n"));
return;
}
if (dhcp->tries < 255) {
dhcp->tries++;
}
LWIP_DEBUGF(ACD_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("acd_send_probe_once(): set request timeout %"U16_F" msecs\n", ACD_DHCP_ARP_REPLY_TIMEOUT_MS));
sys_timeout(ACD_DHCP_ARP_REPLY_TIMEOUT_MS, acd_dhcp_check_timeout_cb, (void *)netif);
}
static void
acd_dhcp_check_timeout_cb(void *arg)
{
struct netif *netif = (struct netif *)arg;
struct dhcp *dhcp;
struct acd *acd;
if (netif == NULL || (dhcp = netif_dhcp_data(netif)) == NULL) {
return;
}
acd = &dhcp->acd;
if (acd->state != ACD_STATE_PROBING || acd->acd_conflict_callback == NULL || dhcp->state != DHCP_STATE_CHECKING) {
return;
}
LWIP_DEBUGF(ACD_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("acd_dhcp_check_timeout_cb(): CHECKING, ARP request timed out\n"));
if (dhcp->tries <= 1) {
send_probe_once(netif);
} else {
// No conflict detected
dhcp->acd.acd_conflict_callback(netif, ACD_IP_OK);
}
}
err_t
acd_start(struct netif *netif, struct acd *acd, ip4_addr_t ipaddr)
{
if (netif == NULL || netif_dhcp_data(netif) == NULL) {
return ERR_ARG;
}
acd->state = ACD_STATE_PROBING;
send_probe_once(netif);
return ERR_OK;
}
#endif /* LWIP_IPV4 && DHCP_DOES_ARP_CHECK */

View File

@ -308,12 +308,23 @@ extern "C" {
#define LWIP_DHCP 1
/**
* DHCP_DOES_ARP_CHECK==1: Do an ARP check on the offered address.
* LWIP_DHCP_CHECKS_OFFERED_ADDRESS:
* - Using Address Conflict Detection (ACD) module assures that the offered IP address
* is properly probed and announced before binding in DHCP. This conforms to RFC5227,
* but takes several seconds.
* - Using ARP check, we only send two ARP requests to check for replies. This process
* lasts 1 - 2 seconds.
* - No conflict detection: We directly bind the offered address.
*/
#ifdef CONFIG_LWIP_DHCP_DOES_ARP_CHECK
#define DHCP_DOES_ARP_CHECK 1
#define LWIP_DHCP_DOES_ACD_CHECK 1
#elif CONFIG_LWIP_DHCP_DOES_ACD_CHECK
#define DHCP_DOES_ARP_CHECK 0
#define LWIP_DHCP_DOES_ACD_CHECK 1
#else
#define DHCP_DOES_ARP_CHECK 0
#define LWIP_DHCP_DOES_ACD_CHECK 0
#endif
/**
@ -381,7 +392,7 @@ extern "C" {
/* Since for embedded devices it's not that hard to miss a discover packet, so lower
* the discover and request retry backoff time from (2,4,8,16,32,60,60)s to (500m,1,2,4,4,4,4)s.
*/
#define DHCP_REQUEST_TIMEOUT_SEQUENCE(tries) ((uint16_t)(((tries) < 5 ? 1 << (tries) : 16) * 250))
#define DHCP_REQUEST_BACKOFF_SEQUENCE(state, tries) ((uint16_t)(((tries) < 5 ? 1 << (tries) : 16) * 250))
static inline uint32_t timeout_from_offered(uint32_t lease, uint32_t min)
{
@ -393,12 +404,12 @@ static inline uint32_t timeout_from_offered(uint32_t lease, uint32_t min)
return timeout;
}
#define DHCP_CALC_TIMEOUT_FROM_OFFERED_T0_LEASE(dhcp) \
timeout_from_offered((dhcp)->offered_t0_lease, 120)
#define DHCP_CALC_TIMEOUT_FROM_OFFERED_T1_RENEW(dhcp) \
timeout_from_offered((dhcp)->offered_t1_renew, (dhcp)->t0_timeout>>1 /* 50% */ )
#define DHCP_CALC_TIMEOUT_FROM_OFFERED_T2_REBIND(dhcp) \
timeout_from_offered((dhcp)->offered_t2_rebind, ((dhcp)->t0_timeout/8)*7 /* 87.5% */ )
#define DHCP_SET_TIMEOUT_FROM_OFFERED_T0_LEASE(tout, dhcp) do { \
(tout) = timeout_from_offered((dhcp)->offered_t0_lease, 120); } while(0)
#define DHCP_SET_TIMEOUT_FROM_OFFERED_T1_RENEW(tout, dhcp) do { \
(tout) = timeout_from_offered((dhcp)->offered_t1_renew, (dhcp)->t0_timeout>>1 /* 50% */ ); } while(0)
#define DHCP_SET_TIMEOUT_FROM_OFFERED_T2_REBIND(tout, dhcp) do { \
(tout) = timeout_from_offered((dhcp)->offered_t2_rebind, ((dhcp)->t0_timeout/8)*7 /* 87.5% */ ); } while(0)
#define LWIP_HOOK_DHCP_PARSE_OPTION(netif, dhcp, state, msg, msg_type, option, len, pbuf, offset) \
do { LWIP_UNUSED_ARG(msg); \
@ -692,8 +703,12 @@ static inline uint32_t timeout_from_offered(uint32_t lease, uint32_t min)
/**
* LWIP_NETIF_HOSTNAME==1: use DHCP_OPTION_HOSTNAME with netif's hostname
* field.
* LWIP_DHCP_DISCOVER_ADD_HOSTNAME==1: include hostname opt in discover packets.
* If the hostname is not set in the DISCOVER packet, then some servers might issue
* an OFFER with hostname configured and consequently reject the REQUEST with any other hostname.
*/
#define LWIP_NETIF_HOSTNAME 1
#define LWIP_DHCP_DISCOVER_ADD_HOSTNAME 1
/**
* LWIP_NETIF_API==1: Support netif api (in netifapi.c)

View File

@ -9,6 +9,4 @@
#include "lwip/inet.h"
#define IN6_IS_ADDR_MULTICAST(a) IN_MULTICAST(a)
#endif /* IN_H_ */

@ -1 +1 @@
Subproject commit b1d2a662b872a73f6de3c581fc3c2c7aaa01ad83
Subproject commit 56af58057c259405aa90c478e294f6216cc2f6db

View File

@ -24,6 +24,8 @@ components/lwip/lwip/src/include/lwip/priv/memp_std.h
components/lwip/include/lwip/sockets.h
components/lwip/lwip/src/include/lwip/prot/nd6.h
components/lwip/lwip/src/include/netif/ppp/
components/lwip/lwip/src/include/lwip/apps/tftp_server.h
components/lwip/lwip/src/include/lwip/apps/tftp_client.h
components/spi_flash/include/spi_flash_chip_issi.h
components/spi_flash/include/spi_flash_chip_mxic.h