Skip to content

Commit

Permalink
dhcp: Enable custom config for timeouts, thresholds, delays
Browse files Browse the repository at this point in the history
Also updates timeout type from u16 to u32

Co-Authored-By: David Cermak <cermak@espressif.com>
Co-Authored-By: ronghulin <ronghulin@espressif.com> (32b1aaf2)
Ref IDF-4817
  • Loading branch information
freakyxue authored and david-cermak committed Mar 24, 2022
1 parent 14bba8e commit 73a92e3
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 48 deletions.
7 changes: 5 additions & 2 deletions .github/workflows/ci-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
16 changes: 9 additions & 7 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand Down
60 changes: 30 additions & 30 deletions src/core/ipv4/dhcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
*/
Expand Down Expand Up @@ -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;
}
}
}
Expand All @@ -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;
}
}
}
Expand Down Expand Up @@ -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;
Expand All @@ -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;);
Expand All @@ -1064,43 +1085,22 @@ 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));
}

/* temporary DHCP lease? */
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;
}
Expand Down
19 changes: 11 additions & 8 deletions src/include/lwip/dhcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,18 @@ 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() */
#define DHCP_FINE_TIMER_MSECS 500

#define DHCP_BOOT_FILE_LEN 128U



/* AutoIP cooperation flags (struct dhcp.autoip_coop_state) */
typedef enum {
DHCP_AUTOIP_COOP_STATE_OFF = 0,
Expand All @@ -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;
Expand Down
4 changes: 4 additions & 0 deletions test/unit/dhcp/test_dhcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
}
Expand Down
29 changes: 28 additions & 1 deletion test/unit/lwipopts.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,22 +83,49 @@
/* 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 <stdint.h>
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
#define LWIP_RAND() (esp_random())
#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
#define IP_DEBUG LWIP_DBG_ON
#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 */

0 comments on commit 73a92e3

Please sign in to comment.