diff --git a/.github/workflows/ci-linux.yml b/.github/workflows/ci-linux.yml index 1c78f835..a170a76c 100644 --- a/.github/workflows/ci-linux.yml +++ b/.github/workflows/ci-linux.yml @@ -28,10 +28,13 @@ jobs: export LWIPDIR=../../../../src && cd ${CONTRIB}/ports/unix/check make -j 4 check make clean - export EXTRA_CFLAGS="-DIP_FORWARD=1" && export CC="cc $EXTRA_CFLAGS" + export EXTRA_CFLAGS="-DESP_LWIP=1" && export CC="${CC} $EXTRA_CFLAGS" make -j 4 check make clean - export EXTRA_CFLAGS="-DIP_FORWARD=1 -DIP_NAPT=1 -DLWIP_ARCH_CC_H -include cc_esp_platform.h" && export CC="cc $EXTRA_CFLAGS" + export EXTRA_CFLAGS="-DESP_LWIP=1 -DIP_FORWARD=1" && export CC="${CC} $EXTRA_CFLAGS" + make -j 4 check + make clean + export EXTRA_CFLAGS="-DESP_LWIP=1 -DIP_FORWARD=1 -DIP_NAPT=1 -DLWIP_ARCH_CC_H -include cc_esp_platform.h" && export CC="${CC} $EXTRA_CFLAGS" make -j 4 check - name: Run cmake diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index df8fe987..3e71427c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -5,12 +5,10 @@ stages: image: ${CI_DOCKER_REGISTRY}/esp-env-v5.0:2 variables: -# tag in lwip-contrib repo, which supports our esp-lwip branch (and it's cherry-picked commits from release branches) LWIP_CONTRIB_TAG: STABLE-2_1_0_RELEASE -# test timeout is seconds - TEST_TIMEOUT: 200 CONTRIB: contrib-2.1.0 CMAKE_SH: cmake-3.22.3-linux-x86_64.sh + CC: cc before_script: # Use CI Tools @@ -40,19 +38,23 @@ run_unittests: script: - *get_contrib - export LWIPDIR=../../../../src && cd ${CONTRIB}/ports/unix/check - # build and run default lwip tests + # build and run default lwip tests (ESP_LWIP=0!) + - make -j 4 check + # retest with ESP_LWIP patches + - make clean + - export EXTRA_CFLAGS="-DESP_LWIP=1" && export CC="${CC} $EXTRA_CFLAGS" - make -j 4 check # retest with IP_FORWARD enabled - make clean - - export EXTRA_CFLAGS="-DIP_FORWARD=1" && export CC="cc $EXTRA_CFLAGS" + - export EXTRA_CFLAGS="-DESP_LWIP=1 -DIP_FORWARD=1" && export CC="${CC} $EXTRA_CFLAGS" - make -j 4 check # retest with IP_FORWARD and IP_NAPT enabled - make clean - - export EXTRA_CFLAGS="-DIP_FORWARD=1 -DIP_NAPT=1 -DLWIP_ARCH_CC_H -include cc_esp_platform.h" && export CC="cc $EXTRA_CFLAGS" + - export EXTRA_CFLAGS="-DESP_LWIP=1 -DIP_FORWARD=1 -DIP_NAPT=1 -DLWIP_ARCH_CC_H -include cc_esp_platform.h" && export CC="${CC} $EXTRA_CFLAGS" - make -j 4 check # Please uncomment the below to test IP_FORWARD/IP_NAPT tests with debug output (only ip4_route test suite will be executed) #- make clean - #- export EXTRA_CFLAGS="-DIP_FORWARD=1 -DESP_TEST_DEBUG=1 -DIP_NAPT=1 -DLWIP_ARCH_CC_H -include cc_esp_platform.h" && export CC="cc $EXTRA_CFLAGS" + #- export EXTRA_CFLAGS="-DESP_LWIP=1 -DIP_FORWARD=1 -DESP_TEST_DEBUG=1 -DIP_NAPT=1 -DLWIP_ARCH_CC_H -include cc_esp_platform.h" && export CC="${CC} $EXTRA_CFLAGS" #- make -j 4 check run_unittests_cmake: diff --git a/src/core/ipv4/dhcp.c b/src/core/ipv4/dhcp.c index 503ceea9..d6f62c2f 100644 --- a/src/core/ipv4/dhcp.c +++ b/src/core/ipv4/dhcp.c @@ -92,6 +92,28 @@ #define LWIP_HOOK_DHCP_PARSE_OPTION(netif, dhcp, state, msg, msg_type, option, len, pbuf, offset) do { LWIP_UNUSED_ARG(msg); } while(0) #endif +#ifndef DHCP_DEFINE_CUSTOM_TIMEOUTS +static inline u32_t timeout_from_offered(u32_t lease, u32_t min, u32_t max) +{ + u32_t timeout = (lease + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS; + if (timeout > max) { + timeout = max; + } + if (timeout == min) { + timeout = 1; + } + return timeout; +} + +#define DHCP_CALC_TIMEOUT_FROM_OFFERED_T0_LEASE(dhcp) timeout_from_offered((dhcp)->offered_t0_lease, 0, 0xffff) +#define DHCP_CALC_TIMEOUT_FROM_OFFERED_T1_RENEW(dhcp) timeout_from_offered((dhcp)->offered_t1_renew, 0, 0xffff) +#define DHCP_CALC_TIMEOUT_FROM_OFFERED_T2_REBIND(dhcp) timeout_from_offered((dhcp)->offered_t2_rebind, 0, 0xffff) + +#define DHCP_NEXT_TIMEOUT_THRESHOLD ((60 + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS) +#define DHCP_REQUEST_TIMEOUT_SEQUENCE(tries) (u16_t)(( (tries) < 6 ? 1 << (tries) : 60) * 1000) + +#endif /* DHCP_DEFINE_CUSTOM_TIMEOUTS */ + /** DHCP_CREATE_RAND_XID: if this is set to 1, the xid is created using * LWIP_RAND() (this overrides DHCP_GLOBAL_XID) */ @@ -563,8 +585,8 @@ dhcp_t1_timeout(struct netif *netif) DHCP_STATE_RENEWING, not DHCP_STATE_BOUND */ dhcp_renew(netif); /* Calculate next timeout */ - if (((dhcp->t2_timeout - dhcp->lease_used) / 2) >= ((60 + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS)) { - dhcp->t1_renew_time = (u16_t)((dhcp->t2_timeout - dhcp->lease_used) / 2); + if (((dhcp->t2_timeout - dhcp->lease_used) / 2) >= DHCP_NEXT_TIMEOUT_THRESHOLD) { + dhcp->t1_renew_time = (dhcp->t2_timeout - dhcp->lease_used) / 2; } } } @@ -589,8 +611,8 @@ dhcp_t2_timeout(struct netif *netif) DHCP_STATE_REBINDING, not DHCP_STATE_BOUND */ dhcp_rebind(netif); /* Calculate next timeout */ - if (((dhcp->t0_timeout - dhcp->lease_used) / 2) >= ((60 + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS)) { - dhcp->t2_rebind_time = (u16_t)((dhcp->t0_timeout - dhcp->lease_used) / 2); + if (((dhcp->t0_timeout - dhcp->lease_used) / 2) >= DHCP_NEXT_TIMEOUT_THRESHOLD) { + dhcp->t2_rebind_time = (dhcp->t0_timeout - dhcp->lease_used) / 2; } } } @@ -1035,7 +1057,7 @@ dhcp_discover(struct netif *netif) autoip_start(netif); } #endif /* LWIP_DHCP_AUTOIP_COOP */ - msecs = (u16_t)((dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000); + msecs = DHCP_REQUEST_TIMEOUT_SEQUENCE(dhcp->tries); dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_discover(): set request timeout %"U16_F" msecs\n", msecs)); return result; @@ -1050,7 +1072,6 @@ dhcp_discover(struct netif *netif) static void dhcp_bind(struct netif *netif) { - u32_t timeout; struct dhcp *dhcp; ip4_addr_t sn_mask, gw_addr; LWIP_ERROR("dhcp_bind: netif != NULL", (netif != NULL), return;); @@ -1064,14 +1085,7 @@ dhcp_bind(struct netif *netif) if (dhcp->offered_t0_lease != 0xffffffffUL) { /* set renewal period timer */ LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t0 renewal timer %"U32_F" secs\n", dhcp->offered_t0_lease)); - timeout = (dhcp->offered_t0_lease + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS; - if (timeout > 0xffff) { - timeout = 0xffff; - } - dhcp->t0_timeout = (u16_t)timeout; - if (dhcp->t0_timeout == 0) { - dhcp->t0_timeout = 1; - } + dhcp->t0_timeout = DHCP_CALC_TIMEOUT_FROM_OFFERED_T0_LEASE(dhcp); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t0_lease * 1000)); } @@ -1079,28 +1093,14 @@ dhcp_bind(struct netif *netif) if (dhcp->offered_t1_renew != 0xffffffffUL) { /* set renewal period timer */ LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t1 renewal timer %"U32_F" secs\n", dhcp->offered_t1_renew)); - timeout = (dhcp->offered_t1_renew + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS; - if (timeout > 0xffff) { - timeout = 0xffff; - } - dhcp->t1_timeout = (u16_t)timeout; - if (dhcp->t1_timeout == 0) { - dhcp->t1_timeout = 1; - } + dhcp->t1_timeout = DHCP_CALC_TIMEOUT_FROM_OFFERED_T1_RENEW(dhcp); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t1_renew * 1000)); dhcp->t1_renew_time = dhcp->t1_timeout; } /* set renewal period timer */ if (dhcp->offered_t2_rebind != 0xffffffffUL) { LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t2 rebind timer %"U32_F" secs\n", dhcp->offered_t2_rebind)); - timeout = (dhcp->offered_t2_rebind + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS; - if (timeout > 0xffff) { - timeout = 0xffff; - } - dhcp->t2_timeout = (u16_t)timeout; - if (dhcp->t2_timeout == 0) { - dhcp->t2_timeout = 1; - } + dhcp->t2_timeout = DHCP_CALC_TIMEOUT_FROM_OFFERED_T2_REBIND(dhcp); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t2_rebind * 1000)); dhcp->t2_rebind_time = dhcp->t2_timeout; } diff --git a/src/include/lwip/dhcp.h b/src/include/lwip/dhcp.h index c78aa0ba..70a0f4fc 100644 --- a/src/include/lwip/dhcp.h +++ b/src/include/lwip/dhcp.h @@ -50,7 +50,9 @@ extern "C" { #endif /** period (in seconds) of the application calling dhcp_coarse_tmr() */ -#define DHCP_COARSE_TIMER_SECS 60 +#ifndef DHCP_COARSE_TIMER_SECS +#define DHCP_COARSE_TIMER_SECS 60 +#endif /* DHCP_COARSE_TIMER_SECS */ /** period (in milliseconds) of the application calling dhcp_coarse_tmr() */ #define DHCP_COARSE_TIMER_MSECS (DHCP_COARSE_TIMER_SECS * 1000UL) /** period (in milliseconds) of the application calling dhcp_fine_tmr() */ @@ -58,6 +60,8 @@ extern "C" { #define DHCP_BOOT_FILE_LEN 128U + + /* AutoIP cooperation flags (struct dhcp.autoip_coop_state) */ typedef enum { DHCP_AUTOIP_COOP_STATE_OFF = 0, @@ -78,14 +82,13 @@ struct dhcp u8_t autoip_coop_state; #endif u8_t subnet_mask_given; - u16_t request_timeout; /* #ticks with period DHCP_FINE_TIMER_SECS for request timeout */ - u16_t t1_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for renewal time */ - u16_t t2_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for rebind time */ - u16_t t1_renew_time; /* #ticks with period DHCP_COARSE_TIMER_SECS until next renew try */ - u16_t t2_rebind_time; /* #ticks with period DHCP_COARSE_TIMER_SECS until next rebind try */ - u16_t lease_used; /* #ticks with period DHCP_COARSE_TIMER_SECS since last received DHCP ack */ - u16_t t0_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for lease time */ + u32_t t1_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for renewal time */ + u32_t t2_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for rebind time */ + u32_t t1_renew_time; /* #ticks with period DHCP_COARSE_TIMER_SECS until next renew try */ + u32_t t2_rebind_time; /* #ticks with period DHCP_COARSE_TIMER_SECS until next rebind try */ + u32_t lease_used; /* #ticks with period DHCP_COARSE_TIMER_SECS since last received DHCP ack */ + u32_t t0_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for lease time */ ip_addr_t server_ip_addr; /* dhcp server address that offered this lease (ip_addr_t because passed to UDP) */ ip4_addr_t offered_ip_addr; ip4_addr_t offered_sn_mask; diff --git a/test/unit/dhcp/test_dhcp.c b/test/unit/dhcp/test_dhcp.c index d84900de..e1cedb1b 100644 --- a/test/unit/dhcp/test_dhcp.c +++ b/test/unit/dhcp/test_dhcp.c @@ -135,7 +135,11 @@ static void tick_lwip(void) if (tick % 5 == 0) { dhcp_fine_tmr(); } +#if ESP_LWIP + if (tick % 10 == 0) { +#else if (tick % 600 == 0) { +#endif dhcp_coarse_tmr(); } } diff --git a/test/unit/lwipopts.h b/test/unit/lwipopts.h index 449e88c0..d910fbd5 100644 --- a/test/unit/lwipopts.h +++ b/test/unit/lwipopts.h @@ -83,9 +83,32 @@ /* Check lwip_stats.mem.illegal instead of asserting */ #define LWIP_MEM_ILLEGAL_FREE(msg) /* to nothing */ +#ifdef ESP_LWIP /* Enable Espressif specific options */ -#define ESP_LWIP 1 +/* DHCP options*/ +#define DHCP_DEFINE_CUSTOM_TIMEOUTS 1 +#define DHCP_COARSE_TIMER_SECS (1) +#define DHCP_NEXT_TIMEOUT_THRESHOLD (3) +#define DHCP_REQUEST_TIMEOUT_SEQUENCE(tries) (( (tries) < 6 ? 1 << (tries) : 60) * 250) + +#include +static inline uint32_t timeout_from_offered(uint32_t lease, uint32_t min) +{ + uint32_t timeout = lease; + if (timeout == 0) { + timeout = 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% */ ) + +/* NAPT options */ #ifdef IP_NAPT #define IP_NAPT_MAX 16 #undef LWIP_RAND @@ -93,6 +116,7 @@ #include "lwip/arch.h" u32_t esp_random(void); #endif /* IP_NAPT */ + /* ESP debug options */ #ifdef ESP_TEST_DEBUG #define NAPT_DEBUG LWIP_DBG_ON @@ -100,5 +124,8 @@ u32_t esp_random(void); #define UDP_DEBUG LWIP_DBG_ON #define TCP_DEBUG LWIP_DBG_ON #endif /* ESP_TEST_DEBUG */ +#else +#define ESP_LWIP 0 +#endif /* ESP_LWIP */ #endif /* LWIP_HDR_LWIPOPTS_H */