Merge branch 'bufix/Backport_some_lwip_bugs_for_4.4_0315' into 'release/v4.4'

bugfix/Backport_some_lwip_bugs_for_4.4_0315

See merge request espressif/esp-idf!22762
This commit is contained in:
Jiang Jiang Jian
2023-03-16 10:31:13 +08:00
9 changed files with 138 additions and 9 deletions

View File

@ -550,6 +550,9 @@ static const esp_err_msg_t esp_err_msg_table[] = {
# endif
# ifdef ESP_ERR_ESP_NETIF_IP6_ADDR_FAILED
ERR_TBL_IT(ESP_ERR_ESP_NETIF_IP6_ADDR_FAILED), /* 20492 0x500c */
# endif
# ifdef ESP_ERR_ESP_NETIF_DHCPS_START_FAILED
ERR_TBL_IT(ESP_ERR_ESP_NETIF_DHCPS_START_FAILED), /* 20493 0x500d */
# endif
// components/esp_common/include/esp_err.h
# ifdef ESP_ERR_FLASH_BASE

View File

@ -17,9 +17,15 @@ extern "C" {
// Macros to assemble master configs with partial configs from netif, stack and driver
//
#ifdef CONFIG_LWIP_ESP_MLDV6_REPORT
#define ESP_NETIF_DEFAULT_MLDV6_REPORT_FLAGS (ESP_NETIF_FLAG_MLDV6_REPORT)
#else
#define ESP_NETIF_DEFAULT_MLDV6_REPORT_FLAGS (0)
#endif
#define ESP_NETIF_INHERENT_DEFAULT_WIFI_STA() \
{ \
.flags = (esp_netif_flags_t)(ESP_NETIF_DHCP_CLIENT | ESP_NETIF_FLAG_GARP | ESP_NETIF_FLAG_EVENT_IP_MODIFIED), \
.flags = (esp_netif_flags_t)(ESP_NETIF_DHCP_CLIENT | ESP_NETIF_FLAG_GARP | ESP_NETIF_DEFAULT_MLDV6_REPORT_FLAGS | ESP_NETIF_FLAG_EVENT_IP_MODIFIED), \
ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_EMPTY(mac) \
ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_EMPTY(ip_info) \
.get_ip_event = IP_EVENT_STA_GOT_IP, \

View File

@ -33,6 +33,7 @@ extern "C" {
#define ESP_ERR_ESP_NETIF_DNS_NOT_CONFIGURED ESP_ERR_ESP_NETIF_BASE + 0x0A
#define ESP_ERR_ESP_NETIF_MLD6_FAILED ESP_ERR_ESP_NETIF_BASE + 0x0B
#define ESP_ERR_ESP_NETIF_IP6_ADDR_FAILED ESP_ERR_ESP_NETIF_BASE + 0x0C
#define ESP_ERR_ESP_NETIF_DHCPS_START_FAILED ESP_ERR_ESP_NETIF_BASE + 0x0D
/** @brief Type of esp_netif_object server */
@ -154,6 +155,7 @@ typedef enum esp_netif_flags {
ESP_NETIF_FLAG_EVENT_IP_MODIFIED = 1 << 4,
ESP_NETIF_FLAG_IS_PPP = 1 << 5,
ESP_NETIF_FLAG_IS_SLIP = 1 << 6,
ESP_NETIF_FLAG_MLDV6_REPORT = 1 << 7,
} esp_netif_flags_t;
typedef enum esp_netif_ip_event_type {

View File

@ -21,6 +21,7 @@
#include "lwip/ip_addr.h"
#include "lwip/ip6_addr.h"
#include "lwip/mld6.h"
#include "lwip/prot/mld6.h"
#include "lwip/nd6.h"
#include "lwip/priv/tcpip_priv.h"
#include "lwip/netif.h"
@ -120,6 +121,12 @@ static void esp_netif_api_cb(void *api_msg)
}
#endif
#if LWIP_IPV6
static void netif_set_mldv6_flag(struct netif *netif);
static void netif_unset_mldv6_flag(struct netif *netif);
#endif /* LWIP_IPV6 */
/**
* @brief Initiates a tcpip remote call if called from another task
* or calls the function directly if executed from lwip task
@ -527,6 +534,11 @@ static void esp_netif_lwip_remove(esp_netif_t *esp_netif)
if (netif_is_up(esp_netif->lwip_netif)) {
netif_set_down(esp_netif->lwip_netif);
}
#if ESP_MLDV6_REPORT && LWIP_IPV6
if (esp_netif->flags & ESP_NETIF_FLAG_MLDV6_REPORT) {
netif_unset_mldv6_flag(esp_netif->lwip_netif);
}
#endif
netif_remove(esp_netif->lwip_netif);
}
}
@ -734,7 +746,11 @@ static esp_err_t esp_netif_start_api(esp_netif_api_msg_t *msg)
memcpy(&lwip_netmask, &default_ip->netmask, sizeof(struct ip4_addr));
dhcps_set_new_lease_cb(esp_netif_dhcps_cb);
dhcps_set_option_info(SUBNET_MASK, (void*)&lwip_netmask, sizeof(lwip_netmask));
dhcps_start(p_netif, lwip_ip);
if (dhcps_start(p_netif, lwip_ip) != ERR_OK) {
ESP_LOGE(TAG, "DHCP server cannot be started");
esp_netif->dhcps_status = ESP_NETIF_DHCP_INIT;
return ESP_ERR_ESP_NETIF_DHCPS_START_FAILED;
}
esp_netif->dhcps_status = ESP_NETIF_DHCP_STARTED;
ESP_LOGD(TAG, "DHCP server started successfully");
esp_netif_update_default_netif(esp_netif, ESP_NETIF_STARTED);
@ -1146,7 +1162,11 @@ static esp_err_t esp_netif_dhcps_start_api(esp_netif_api_msg_t *msg)
memcpy(&lwip_netmask, &default_ip->netmask, sizeof(struct ip4_addr));
dhcps_set_new_lease_cb(esp_netif_dhcps_cb);
dhcps_set_option_info(SUBNET_MASK, (void*)&lwip_netmask, sizeof(lwip_netmask));
dhcps_start(p_netif, lwip_ip);
if (dhcps_start(p_netif, lwip_ip) != ERR_OK) {
ESP_LOGE(TAG, "DHCP server cannot be started");
esp_netif->dhcps_status = ESP_NETIF_DHCP_INIT;
return ESP_ERR_ESP_NETIF_DHCPS_START_FAILED;
}
esp_netif->dhcps_status = ESP_NETIF_DHCP_STARTED;
ESP_LOGD(TAG, "DHCP server started successfully");
return ESP_OK;
@ -1295,6 +1315,11 @@ static esp_err_t esp_netif_down_api(esp_netif_api_msg_t *msg)
esp_netif_reset_ip_info(esp_netif);
}
#if CONFIG_LWIP_IPV6
#if ESP_MLDV6_REPORT
if (esp_netif->flags & ESP_NETIF_FLAG_MLDV6_REPORT) {
netif_unset_mldv6_flag(esp_netif->lwip_netif);
}
#endif
for(int8_t i = 0 ;i < LWIP_IPV6_NUM_ADDRESSES ;i++) {
netif_ip6_addr_set(lwip_netif, i, IP6_ADDR_ANY6);
netif_ip6_addr_set_valid_life(lwip_netif, i, 0);
@ -1570,6 +1595,34 @@ esp_err_t esp_netif_get_dns_info(esp_netif_t *esp_netif, esp_netif_dns_type_t ty
}
#if CONFIG_LWIP_IPV6
#ifdef CONFIG_LWIP_MLDV6_TMR_INTERVAL
static void netif_send_mldv6(void *arg)
{
struct netif *netif = arg;
if (!netif_is_up(netif)) {
return;
}
mld6_report_groups(netif);
sys_timeout(CONFIG_LWIP_MLDV6_TMR_INTERVAL*1000, netif_send_mldv6, netif);
}
static void netif_set_mldv6_flag(struct netif *netif)
{
if (!netif_is_up(netif)) {
return;
}
sys_timeout(CONFIG_LWIP_MLDV6_TMR_INTERVAL*1000, netif_send_mldv6, netif);
}
static void netif_unset_mldv6_flag(struct netif *netif)
{
sys_untimeout(netif_send_mldv6, netif);
}
#endif
esp_ip6_addr_type_t esp_netif_ip6_get_addr_type(esp_ip6_addr_t* ip6_addr)
{
ip6_addr_t* lwip_ip6_info = (ip6_addr_t*)ip6_addr;
@ -1599,6 +1652,7 @@ static void esp_netif_nd6_cb(struct netif *p_netif, uint8_t ip_index)
esp_netif_ip6_info_t ip6_info;
ip6_addr_t lwip_ip6_info;
esp_netif_t *esp_netif = p_netif->state;
//notify event
ip_event_got_ip6_t evt = { .esp_netif = p_netif->state, .if_index = -1, .ip_index = ip_index };
@ -1610,6 +1664,14 @@ static void esp_netif_nd6_cb(struct netif *p_netif, uint8_t ip_index)
ip6_info.ip.zone = 0; // zero out zone, as not used in lwip
#endif /* LWIP_IPV6_SCOPES */
if (esp_netif->flags&ESP_NETIF_FLAG_MLDV6_REPORT) {
#if ESP_MLDV6_REPORT
netif_set_mldv6_flag(p_netif);
#else
ESP_LOGW(TAG,"CONFIG_LWIP_ESP_MLDV6_REPORT not enabled, but esp-netif configured with ESP_NETIF_FLAG_MLDV6_REPORT");
#endif
}
memcpy(&evt.ip6_info, &ip6_info, sizeof(esp_netif_ip6_info_t));
int ret = esp_event_send_internal(IP_EVENT, IP_EVENT_GOT_IP6, &evt, sizeof(evt), 0);
if (ESP_OK != ret) {

View File

@ -233,6 +233,24 @@ menu "LWIP"
help
Set the timer interval for gratuitous ARP. The default value is 60s
config LWIP_ESP_MLDV6_REPORT
bool "Send mldv6 report periodically"
depends on LWIP_IPV6
default y
help
Enable this option allows to send mldv6 report periodically.
This option solve the issue that failed to receive multicast data.
Some routers fail to forward multicast packets.
To solve this problem, send multicast mdlv6 report to routers regularly.
config LWIP_MLDV6_TMR_INTERVAL
int "mldv6 report timer interval(seconds)"
default 40
depends on LWIP_ESP_MLDV6_REPORT
help
Set the timer interval for mldv6 report. The default value is 40s
config LWIP_TCPIP_RECVMBOX_SIZE
int "TCPIP task receive mail box size"
default 32

View File

@ -63,6 +63,21 @@
#define DHCPS_DEBUG 0
#define DHCPS_LOG printf
#define IS_INVALID_SUBNET_MASK(x) (((x-1) | x) != 0xFFFFFFFF)
/* Notes:
* CIDR eliminates the traditional Class A, Class B and Class C addresses.
*/
#define IP_CLASS_HOST_NUM(mask) (0xffffffff & ~mask)
#define DHCP_CHECK_SUBNET_MASK_IP(mask) \
do { \
if (IS_INVALID_SUBNET_MASK(mask)) { \
DHCPS_LOG("dhcps: Illegal subnet mask.\n"); \
return ERR_ARG; \
} \
} while (0)
#define MAX_STATION_NUM CONFIG_LWIP_DHCPS_MAX_STATION_NUM
#define DHCPS_STATE_OFFER 1
@ -1079,6 +1094,8 @@ static void dhcps_poll_set(u32_t ip)
u32_t softap_ip = 0, local_ip = 0;
u32_t start_ip = 0;
u32_t end_ip = 0;
u32_t temp_local_ip = 0;
u32_t host_num = 0;
if (dhcps_poll.enable == true) {
softap_ip = htonl(ip);
@ -1102,17 +1119,22 @@ static void dhcps_poll_set(u32_t ip)
if (dhcps_poll.enable == false) {
local_ip = softap_ip = htonl(ip);
softap_ip &= 0xFFFFFF00;
local_ip &= 0xFF;
temp_local_ip = local_ip &= 0xFF;
if (local_ip >= 0x80) {
local_ip -= DHCPS_MAX_LEASE;
temp_local_ip -= DHCPS_MAX_LEASE;
} else {
local_ip ++;
}
bzero(&dhcps_poll, sizeof(dhcps_poll));
host_num = IP_CLASS_HOST_NUM(htonl(s_dhcps_mask.addr));
if (host_num > DHCPS_MAX_LEASE) {
host_num = DHCPS_MAX_LEASE;
}
dhcps_poll.start_ip.addr = softap_ip | local_ip;
dhcps_poll.end_ip.addr = softap_ip | (local_ip + DHCPS_MAX_LEASE - 1);
dhcps_poll.end_ip.addr = softap_ip | (temp_local_ip + host_num - 1);
dhcps_poll.start_ip.addr = htonl(dhcps_poll.start_ip.addr);
dhcps_poll.end_ip.addr = htonl(dhcps_poll.end_ip.addr);
}
@ -1139,8 +1161,11 @@ void dhcps_set_new_lease_cb(dhcps_cb_t cb)
* : info -- The current ip info
* Returns : none
*******************************************************************************/
void dhcps_start(struct netif *netif, ip4_addr_t ip)
err_t dhcps_start(struct netif *netif, ip4_addr_t ip)
{
if (netif == NULL) {
return ERR_ARG;
}
dhcps_netif = netif;
if (dhcps_netif->dhcps_pcb != NULL) {
@ -1152,6 +1177,7 @@ void dhcps_start(struct netif *netif, ip4_addr_t ip)
if (pcb_dhcps == NULL || ip4_addr_isany_val(ip)) {
printf("dhcps_start(): could not obtain pcb\n");
return ERR_ARG;
}
dhcps_netif->dhcps_pcb = pcb_dhcps;
@ -1159,6 +1185,7 @@ void dhcps_start(struct netif *netif, ip4_addr_t ip)
IP4_ADDR(&broadcast_dhcps, 255, 255, 255, 255);
server_address.addr = ip.addr;
DHCP_CHECK_SUBNET_MASK_IP(htonl(s_dhcps_mask.addr));
dhcps_poll_set(server_address.addr);
client_address_plus.addr = dhcps_poll.start_ip.addr;
@ -1168,7 +1195,7 @@ void dhcps_start(struct netif *netif, ip4_addr_t ip)
#if DHCPS_DEBUG
DHCPS_LOG("dhcps:dhcps_start->udp_recv function Set a receive callback handle_dhcp for UDP_PCB pcb_dhcps\n");
#endif
return ERR_OK;
}
/******************************************************************************

View File

@ -16,6 +16,7 @@
#include "sdkconfig.h"
#include "lwip/ip_addr.h"
#include "lwip/err.h"
#ifdef __cplusplus
extern "C" {
@ -86,7 +87,7 @@ static inline bool dhcps_dns_enabled (dhcps_offer_t offer)
return (offer & OFFER_DNS) != 0;
}
void dhcps_start(struct netif *netif, ip4_addr_t ip);
err_t dhcps_start(struct netif *netif, ip4_addr_t ip);
void dhcps_stop(struct netif *netif);
void *dhcps_option_info(u8_t op_id, u32_t opt_len);
void dhcps_set_option_info(u8_t op_id, void *opt_info, u32_t opt_len);

View File

@ -822,6 +822,16 @@ static inline uint32_t timeout_from_offered(uint32_t lease, uint32_t min)
*/
#define LWIP_ND6_NUM_NEIGHBORS CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS
/**
* ESP_MLDV6_REPORT==1: This option allows to send mldv6 report periodically.
*/
#ifdef CONFIG_LWIP_ESP_MLDV6_REPORT
#define ESP_MLDV6_REPORT 1
#else
#define ESP_MLDV6_REPORT 0
#endif
/*
---------------------------------------
---------- Hook options ---------------