diff --git a/components/lwip/Kconfig b/components/lwip/Kconfig index c8c5bc03..2b41620b 100644 --- a/components/lwip/Kconfig +++ b/components/lwip/Kconfig @@ -46,6 +46,23 @@ config LWIP_ARP_MAXAGE range 100 65535 default 300 +config LWIP_ESP_GRATUITOUS_ARP + bool "Send gratuitous ARP periodically" + default n + help + Enable this option allows to send gratuitous ARP periodically. + + This option solve the compatibility issues.If the ARP table of the AP is old, and the AP + doesn't send ARP request to update it's ARP table, this will lead to the STA sending IP packet fail. + Thus we send gratuitous ARP periodically to let AP update it's ARP table. + +config LWIP_GARP_TMR_INTERVAL + int "GARP timer interval(seconds)" + default 60 + depends on LWIP_ESP_GRATUITOUS_ARP + help + Set the timer interval for gratuitous ARP. The default value is 60s + endmenu # LWIP ARP menu "SOCKET" diff --git a/components/lwip/lwip/src/core/ipv4/etharp.c b/components/lwip/lwip/src/core/ipv4/etharp.c index 3f48a997..270c15a8 100644 --- a/components/lwip/lwip/src/core/ipv4/etharp.c +++ b/components/lwip/lwip/src/core/ipv4/etharp.c @@ -138,6 +138,20 @@ static err_t etharp_raw(struct netif *netif, const struct eth_addr *hwdst_addr, const ip4_addr_t *ipdst_addr, const u16_t opcode); +#if ESP_GRATUITOUS_ARP +void garp_tmr(void) +{ + struct netif* garp_netif = NULL; + for (garp_netif = netif_list; garp_netif != NULL; garp_netif = garp_netif->next) { + if (netif_is_up(garp_netif) && netif_is_link_up(garp_netif) && !ip4_addr_isany_val(*netif_ip4_addr(garp_netif))) { + if ((garp_netif->flags & NETIF_FLAG_ETHARP) && (garp_netif->flags & NETIF_FLAG_GARP)) { + etharp_gratuitous(garp_netif); + } + } + } +} +#endif + #if ARP_QUEUEING /** * Free a complete queue of etharp entries diff --git a/components/lwip/lwip/src/core/netif.c b/components/lwip/lwip/src/core/netif.c index 64446546..44883d0b 100644 --- a/components/lwip/lwip/src/core/netif.c +++ b/components/lwip/lwip/src/core/netif.c @@ -367,6 +367,16 @@ netif_set_addr(struct netif *netif, const ip4_addr_t *ipaddr, const ip4_addr_t * } #endif /* LWIP_IPV4*/ +/** + * Set the netif flags for GARP + */ +#if ESP_GRATUITOUS_ARP +void netif_set_garp_flag(struct netif *netif) +{ + netif->flags |= NETIF_FLAG_GARP; +} +#endif + /** * @ingroup netif * Remove a network interface from the list of lwIP netifs. diff --git a/components/lwip/lwip/src/core/timeouts.c b/components/lwip/lwip/src/core/timeouts.c index 4981803d..f356620b 100644 --- a/components/lwip/lwip/src/core/timeouts.c +++ b/components/lwip/lwip/src/core/timeouts.c @@ -80,6 +80,9 @@ const struct lwip_cyclic_timer lwip_cyclic_timers[] = { #endif /* IP_REASSEMBLY */ #if LWIP_ARP {ARP_TMR_INTERVAL, HANDLER(etharp_tmr)}, +#if ESP_GRATUITOUS_ARP + {GARP_TMR_INTERVAL, HANDLER(garp_tmr)}, +#endif /* ESP_GRATUITOUS_ARP */ #endif /* LWIP_ARP */ #if LWIP_DHCP {DHCP_COARSE_TIMER_MSECS, HANDLER(dhcp_coarse_tmr)}, diff --git a/components/lwip/lwip/src/include/lwip/etharp.h b/components/lwip/lwip/src/include/lwip/etharp.h index 7080a19d..2aa63920 100644 --- a/components/lwip/lwip/src/include/lwip/etharp.h +++ b/components/lwip/lwip/src/include/lwip/etharp.h @@ -73,6 +73,15 @@ struct etharp_q_entry { }; #endif /* ARP_QUEUEING */ +#if ESP_GRATUITOUS_ARP +#ifdef CONFIG_LWIP_GARP_TMR_INTERVAL +#define GARP_TMR_INTERVAL (CONFIG_LWIP_GARP_TMR_INTERVAL*1000UL) +#else +#define GARP_TMR_INTERVAL 60000 +#endif +void garp_tmr(void); +#endif + #define etharp_init() /* Compatibility define, no init needed. */ void etharp_tmr(void); s8_t etharp_find_addr(struct netif *netif, const ip4_addr_t *ipaddr, diff --git a/components/lwip/lwip/src/include/lwip/netif.h b/components/lwip/lwip/src/include/lwip/netif.h index ecff65ad..ff014274 100644 --- a/components/lwip/lwip/src/include/lwip/netif.h +++ b/components/lwip/lwip/src/include/lwip/netif.h @@ -100,6 +100,11 @@ extern "C" { * Set by the netif driver in its init function. */ #define NETIF_FLAG_MLD6 0x40U +#if ESP_GRATUITOUS_ARP +/** If set, the netif will send gratuitous ARP periodically */ +#define NETIF_FLAG_GARP 0x80U +#endif + /** * @} */ @@ -369,6 +374,11 @@ struct netif *netif_add(struct netif *netif, void netif_set_addr(struct netif *netif, const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw); #endif /* LWIP_IPV4 */ + +#if ESP_GRATUITOUS_ARP +void netif_set_garp_flag(struct netif *netif); +#endif + void netif_remove(struct netif * netif); /* Returns a network interface given its name. The name is of the form diff --git a/components/lwip/lwip/src/include/lwip/opt.h b/components/lwip/lwip/src/include/lwip/opt.h index 7fe984c4..8f8b0777 100644 --- a/components/lwip/lwip/src/include/lwip/opt.h +++ b/components/lwip/lwip/src/include/lwip/opt.h @@ -435,8 +435,12 @@ * The formula expects settings to be either '0' or '1'. */ #if !defined MEMP_NUM_SYS_TIMEOUT || defined __DOXYGEN__ +#if ESP_LWIP +#define MEMP_NUM_SYS_TIMEOUT (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_IGMP + LWIP_DNS + (PPP_SUPPORT*6*MEMP_NUM_PPP_PCB) + (LWIP_IPV6 ? (1 + LWIP_IPV6_REASS + LWIP_IPV6_MLD) : 0)) + (ESP_GRATUITOUS_ARP ? 1 : 0) +#else #define MEMP_NUM_SYS_TIMEOUT (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_IGMP + LWIP_DNS + (PPP_SUPPORT*6*MEMP_NUM_PPP_PCB) + (LWIP_IPV6 ? (1 + LWIP_IPV6_REASS + LWIP_IPV6_MLD) : 0)) #endif +#endif /** * MEMP_NUM_NETBUF: the number of struct netbufs. diff --git a/components/lwip/port/esp8266/include/lwipopts.h b/components/lwip/port/esp8266/include/lwipopts.h index 07db6ed5..5de56236 100644 --- a/components/lwip/port/esp8266/include/lwipopts.h +++ b/components/lwip/port/esp8266/include/lwipopts.h @@ -372,7 +372,11 @@ size_t memp_malloc_get_size(size_t type); * The default number of timeouts is calculated here for all enabled modules. * The formula expects settings to be either '0' or '1'. */ +#if ESP_LWIP +#define MEMP_NUM_SYS_TIMEOUT (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_IGMP + LWIP_DNS + (PPP_SUPPORT*6*MEMP_NUM_PPP_PCB) + (LWIP_IPV6 ? (1 + LWIP_IPV6_REASS + LWIP_IPV6_MLD) : 0)) + (ESP_GRATUITOUS_ARP ? 1 : 0) +#else #define MEMP_NUM_SYS_TIMEOUT (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_IGMP + LWIP_DNS + (PPP_SUPPORT*6*MEMP_NUM_PPP_PCB) + (LWIP_IPV6 ? (1 + LWIP_IPV6_REASS + LWIP_IPV6_MLD) : 0)) +#endif /** * MEMP_NUM_NETBUF: the number of struct netbufs. @@ -2281,6 +2285,7 @@ size_t memp_malloc_get_size(size_t type); #endif #endif +#define ESP_GRATUITOUS_ARP CONFIG_LWIP_ESP_GRATUITOUS_ARP #define ESP_PING 1 #endif /* __LWIP_HDR_LWIPOPTS_H__ */ diff --git a/components/tcpip_adapter/tcpip_adapter_lwip.c b/components/tcpip_adapter/tcpip_adapter_lwip.c index 80e92490..08b18af1 100644 --- a/components/tcpip_adapter/tcpip_adapter_lwip.c +++ b/components/tcpip_adapter/tcpip_adapter_lwip.c @@ -374,6 +374,11 @@ esp_err_t tcpip_adapter_start(tcpip_adapter_if_t tcpip_if, uint8_t *mac, tcpip_a } } netif_add(esp_netif[tcpip_if], &ip_info->ip, &ip_info->netmask, &ip_info->gw, (void *)tcpip_if, ethernetif_init, tcpip_input); +#if ESP_GRATUITOUS_ARP + if (tcpip_if == TCPIP_ADAPTER_IF_STA || tcpip_if == TCPIP_ADAPTER_IF_ETH) { + netif_set_garp_flag(esp_netif[tcpip_if]); + } +#endif } if (tcpip_if == TCPIP_ADAPTER_IF_AP) {