net/dhcpv4: Introduce start/stop API and disabled state.
Change-Id: Iae3b96dd91325ecf51b33b8c58f65aa5ec2b40c9 Signed-off-by: Marcus Shawcroft <marcus.shawcroft@arm.com>
This commit is contained in:
parent
c4f4cb17db
commit
3726bb98bd
3 changed files with 79 additions and 47 deletions
|
@ -26,6 +26,7 @@
|
|||
* reflected within corresponding changes to net_dhcpv4_state_name.
|
||||
*/
|
||||
enum net_dhcpv4_state {
|
||||
NET_DHCPV4_DISABLED,
|
||||
NET_DHCPV4_INIT,
|
||||
NET_DHCPV4_SELECTING,
|
||||
NET_DHCPV4_REQUESTING,
|
||||
|
@ -34,7 +35,7 @@ enum net_dhcpv4_state {
|
|||
};
|
||||
|
||||
/**
|
||||
* @brief Start DHCPv4 client
|
||||
* @brief Start DHCPv4 client on an iface
|
||||
*
|
||||
* @details Start DHCPv4 client on a given interface. DHCPv4 client
|
||||
* will start negotiation for IPv4 address. Once the negotiation is
|
||||
|
@ -44,6 +45,17 @@ enum net_dhcpv4_state {
|
|||
*/
|
||||
void net_dhcpv4_start(struct net_if *iface);
|
||||
|
||||
/**
|
||||
* @brief Stop DHCPv4 client on an iface
|
||||
*
|
||||
* @details Stop DHCPv4 client on a given interface. DHCPv4 client
|
||||
* will remove all configuration obtained from a DHCP server from the
|
||||
* interface and stop any further negotiation with the server.
|
||||
*
|
||||
* @param iface A valid pointer on an interface
|
||||
*/
|
||||
void net_dhcpv4_stop(struct net_if *iface);
|
||||
|
||||
/**
|
||||
* @brief DHCPv4 state name
|
||||
*
|
||||
|
|
|
@ -1135,7 +1135,7 @@ struct net_if_api {
|
|||
};
|
||||
|
||||
#if defined(CONFIG_NET_DHCPV4)
|
||||
#define NET_IF_DHCPV4_INIT .dhcpv4.state = NET_DHCPV4_INIT,
|
||||
#define NET_IF_DHCPV4_INIT .dhcpv4.state = NET_DHCPV4_DISABLED,
|
||||
#else
|
||||
#define NET_IF_DHCPV4_INIT
|
||||
#endif
|
||||
|
|
|
@ -122,6 +122,7 @@ net_dhcpv4_msg_type_name(enum dhcpv4_msg_type msg_type) __attribute__((unused));
|
|||
const char *net_dhcpv4_state_name(enum net_dhcpv4_state state)
|
||||
{
|
||||
static const char * const name[] = {
|
||||
"disabled",
|
||||
"init",
|
||||
"selecting",
|
||||
"requesting",
|
||||
|
@ -157,26 +158,6 @@ static inline uint32_t get_dhcpv4_renewal_time(struct net_if *iface)
|
|||
iface->dhcpv4.lease_time / 2);
|
||||
}
|
||||
|
||||
static inline void unset_dhcpv4_on_iface(struct net_if *iface)
|
||||
{
|
||||
if (!iface) {
|
||||
return;
|
||||
}
|
||||
|
||||
iface->dhcpv4.state = NET_DHCPV4_INIT;
|
||||
NET_DBG("state=%s", net_dhcpv4_state_name(iface->dhcpv4.state));
|
||||
|
||||
iface->dhcpv4.attempts = 0;
|
||||
iface->dhcpv4.lease_time = 0;
|
||||
iface->dhcpv4.renewal_time = 0;
|
||||
|
||||
memset(iface->dhcpv4.server_id.s4_addr, 0, 4);
|
||||
memset(iface->dhcpv4.server_id.s4_addr, 0, 4);
|
||||
memset(iface->dhcpv4.requested_ip.s4_addr, 0, 4);
|
||||
k_delayed_work_cancel(&iface->dhcpv4.timer);
|
||||
k_delayed_work_cancel(&iface->dhcpv4.t1_timer);
|
||||
}
|
||||
|
||||
/* Add magic cookie to DCHPv4 messages */
|
||||
static inline bool add_cookie(struct net_buf *buf)
|
||||
{
|
||||
|
@ -488,6 +469,8 @@ static void dhcpv4_timeout(struct k_work *work)
|
|||
}
|
||||
|
||||
switch (iface->dhcpv4.state) {
|
||||
case NET_DHCPV4_DISABLED:
|
||||
break;
|
||||
case NET_DHCPV4_INIT:
|
||||
enter_selecting(iface);
|
||||
break;
|
||||
|
@ -700,6 +683,7 @@ static enum net_verdict parse_options(struct net_if *iface, struct net_buf *buf,
|
|||
static inline void handle_offer(struct net_if *iface)
|
||||
{
|
||||
switch (iface->dhcpv4.state) {
|
||||
case NET_DHCPV4_DISABLED:
|
||||
case NET_DHCPV4_INIT:
|
||||
case NET_DHCPV4_REQUESTING:
|
||||
case NET_DHCPV4_RENEWING:
|
||||
|
@ -717,6 +701,7 @@ static void handle_ack(struct net_if *iface)
|
|||
uint32_t timeout;
|
||||
|
||||
switch (iface->dhcpv4.state) {
|
||||
case NET_DHCPV4_DISABLED:
|
||||
case NET_DHCPV4_INIT:
|
||||
case NET_DHCPV4_SELECTING:
|
||||
case NET_DHCPV4_BOUND:
|
||||
|
@ -762,6 +747,7 @@ static void handle_ack(struct net_if *iface)
|
|||
static void handle_nak(struct net_if *iface)
|
||||
{
|
||||
switch (iface->dhcpv4.state) {
|
||||
case NET_DHCPV4_DISABLED:
|
||||
case NET_DHCPV4_INIT:
|
||||
case NET_DHCPV4_SELECTING:
|
||||
case NET_DHCPV4_RENEWING:
|
||||
|
@ -896,38 +882,72 @@ void net_dhcpv4_start(struct net_if *iface)
|
|||
uint32_t timeout;
|
||||
uint32_t entropy;
|
||||
|
||||
iface->dhcpv4.state = NET_DHCPV4_INIT;
|
||||
NET_DBG("state=%s", net_dhcpv4_state_name(iface->dhcpv4.state));
|
||||
switch (iface->dhcpv4.state) {
|
||||
case NET_DHCPV4_DISABLED:
|
||||
iface->dhcpv4.state = NET_DHCPV4_INIT;
|
||||
NET_DBG("state=%s", net_dhcpv4_state_name(iface->dhcpv4.state));
|
||||
|
||||
iface->dhcpv4.attempts = 0;
|
||||
iface->dhcpv4.lease_time = 0;
|
||||
iface->dhcpv4.renewal_time = 0;
|
||||
iface->dhcpv4.attempts = 0;
|
||||
iface->dhcpv4.lease_time = 0;
|
||||
iface->dhcpv4.renewal_time = 0;
|
||||
|
||||
/* We need entropy for both an XID and a random delay before
|
||||
* sending the initial discover message.
|
||||
*/
|
||||
entropy = sys_rand32_get();
|
||||
iface->dhcpv4.server_id.s_addr[0] = 0;
|
||||
iface->dhcpv4.requested_ip.s_addr[0] = 0;
|
||||
|
||||
/* A DHCP client MUST choose xid's in such a way as to
|
||||
* minimize the change of using and xid identical to one used
|
||||
* by another client. Choose a random xid st startup and
|
||||
* increment it on each new request.
|
||||
*/
|
||||
iface->dhcpv4.xid = entropy;
|
||||
/* We need entropy for both an XID and a random delay
|
||||
* before sending the initial discover message.
|
||||
*/
|
||||
entropy = sys_rand32_get();
|
||||
|
||||
/* A DHCP client MUST choose xid's in such a way as to
|
||||
* minimize the change of using and xid identical to
|
||||
* one used by another client. Choose a random xid st
|
||||
* startup and increment it on each new request.
|
||||
*/
|
||||
iface->dhcpv4.xid = entropy;
|
||||
|
||||
|
||||
/* RFC2131 4.1.1 requires we wait a random period between 1
|
||||
* and 10 seconds before sending the initial discover.
|
||||
*/
|
||||
timeout = entropy %
|
||||
(DHCPV4_INITIAL_DELAY_MAX - DHCPV4_INITIAL_DELAY_MIN) +
|
||||
DHCPV4_INITIAL_DELAY_MIN;
|
||||
/* RFC2131 4.1.1 requires we wait a random period
|
||||
* between 1 and 10 seconds before sending the initial
|
||||
* discover.
|
||||
*/
|
||||
timeout = entropy %
|
||||
(DHCPV4_INITIAL_DELAY_MAX - DHCPV4_INITIAL_DELAY_MIN) +
|
||||
DHCPV4_INITIAL_DELAY_MIN;
|
||||
|
||||
NET_DBG("enter state=%s timeout=%"PRIu32"s",
|
||||
net_dhcpv4_state_name(iface->dhcpv4.state), timeout);
|
||||
NET_DBG("wait timeout=%"PRIu32"s", timeout);
|
||||
|
||||
k_delayed_work_init(&iface->dhcpv4.timer, dhcpv4_timeout);
|
||||
k_delayed_work_submit(&iface->dhcpv4.timer, timeout * MSEC_PER_SEC);
|
||||
k_delayed_work_init(&iface->dhcpv4.timer, dhcpv4_timeout);
|
||||
k_delayed_work_submit(&iface->dhcpv4.timer,
|
||||
timeout * MSEC_PER_SEC);
|
||||
break;
|
||||
case NET_DHCPV4_INIT:
|
||||
case NET_DHCPV4_SELECTING:
|
||||
case NET_DHCPV4_REQUESTING:
|
||||
case NET_DHCPV4_RENEWING:
|
||||
case NET_DHCPV4_BOUND:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void net_dhcpv4_stop(struct net_if *iface)
|
||||
{
|
||||
switch (iface->dhcpv4.state) {
|
||||
case NET_DHCPV4_DISABLED:
|
||||
break;
|
||||
|
||||
case NET_DHCPV4_INIT:
|
||||
case NET_DHCPV4_SELECTING:
|
||||
case NET_DHCPV4_REQUESTING:
|
||||
case NET_DHCPV4_RENEWING:
|
||||
case NET_DHCPV4_BOUND:
|
||||
iface->dhcpv4.state = NET_DHCPV4_DISABLED;
|
||||
NET_DBG("state=%s", net_dhcpv4_state_name(iface->dhcpv4.state));
|
||||
|
||||
k_delayed_work_cancel(&iface->dhcpv4.timer);
|
||||
k_delayed_work_cancel(&iface->dhcpv4.t1_timer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int dhcpv4_init(void)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue