lwip: solve some routers do not forward multicast packet issue

This commit is contained in:
xueyunfei
2023-03-14 19:00:08 +08:00
parent 9403854bed
commit 8331ae8586
5 changed files with 90 additions and 1 deletions

View File

@ -17,9 +17,15 @@ extern "C" {
// Macros to assemble master configs with partial configs from netif, stack and driver // 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() \ #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(mac) \
ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_EMPTY(ip_info) \ ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_EMPTY(ip_info) \
.get_ip_event = IP_EVENT_STA_GOT_IP, \ .get_ip_event = IP_EVENT_STA_GOT_IP, \

View File

@ -155,6 +155,7 @@ typedef enum esp_netif_flags {
ESP_NETIF_FLAG_EVENT_IP_MODIFIED = 1 << 4, ESP_NETIF_FLAG_EVENT_IP_MODIFIED = 1 << 4,
ESP_NETIF_FLAG_IS_PPP = 1 << 5, ESP_NETIF_FLAG_IS_PPP = 1 << 5,
ESP_NETIF_FLAG_IS_SLIP = 1 << 6, ESP_NETIF_FLAG_IS_SLIP = 1 << 6,
ESP_NETIF_FLAG_MLDV6_REPORT = 1 << 7,
} esp_netif_flags_t; } esp_netif_flags_t;
typedef enum esp_netif_ip_event_type { typedef enum esp_netif_ip_event_type {

View File

@ -21,6 +21,7 @@
#include "lwip/ip_addr.h" #include "lwip/ip_addr.h"
#include "lwip/ip6_addr.h" #include "lwip/ip6_addr.h"
#include "lwip/mld6.h" #include "lwip/mld6.h"
#include "lwip/prot/mld6.h"
#include "lwip/nd6.h" #include "lwip/nd6.h"
#include "lwip/priv/tcpip_priv.h" #include "lwip/priv/tcpip_priv.h"
#include "lwip/netif.h" #include "lwip/netif.h"
@ -120,6 +121,12 @@ static void esp_netif_api_cb(void *api_msg)
} }
#endif #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 * @brief Initiates a tcpip remote call if called from another task
* or calls the function directly if executed from lwip 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)) { if (netif_is_up(esp_netif->lwip_netif)) {
netif_set_down(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); netif_remove(esp_netif->lwip_netif);
} }
} }
@ -1303,6 +1315,11 @@ static esp_err_t esp_netif_down_api(esp_netif_api_msg_t *msg)
esp_netif_reset_ip_info(esp_netif); esp_netif_reset_ip_info(esp_netif);
} }
#if CONFIG_LWIP_IPV6 #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++) { 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(lwip_netif, i, IP6_ADDR_ANY6);
netif_ip6_addr_set_valid_life(lwip_netif, i, 0); netif_ip6_addr_set_valid_life(lwip_netif, i, 0);
@ -1578,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 #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) 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; ip6_addr_t* lwip_ip6_info = (ip6_addr_t*)ip6_addr;
@ -1607,6 +1652,7 @@ static void esp_netif_nd6_cb(struct netif *p_netif, uint8_t ip_index)
esp_netif_ip6_info_t ip6_info; esp_netif_ip6_info_t ip6_info;
ip6_addr_t lwip_ip6_info; ip6_addr_t lwip_ip6_info;
esp_netif_t *esp_netif = p_netif->state;
//notify event //notify event
ip_event_got_ip6_t evt = { .esp_netif = p_netif->state, .if_index = -1, .ip_index = ip_index }; ip_event_got_ip6_t evt = { .esp_netif = p_netif->state, .if_index = -1, .ip_index = ip_index };
@ -1618,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 ip6_info.ip.zone = 0; // zero out zone, as not used in lwip
#endif /* LWIP_IPV6_SCOPES */ #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)); 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); int ret = esp_event_send_internal(IP_EVENT, IP_EVENT_GOT_IP6, &evt, sizeof(evt), 0);
if (ESP_OK != ret) { if (ESP_OK != ret) {

View File

@ -233,6 +233,24 @@ menu "LWIP"
help help
Set the timer interval for gratuitous ARP. The default value is 60s 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 config LWIP_TCPIP_RECVMBOX_SIZE
int "TCPIP task receive mail box size" int "TCPIP task receive mail box size"
default 32 default 32

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 #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 --------------- ---------- Hook options ---------------