net: if: Make sure k_delayed_work_init is only called once

k_delayed_work_init shall only be called once per work and not every
time before as that can trash the workqueue list if the work is pending.

Change-Id: Ib6398a6a843dd4d820529487ad76a9dc9d9e152e
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
Luiz Augusto von Dentz 2017-03-15 11:25:27 +02:00 committed by Jukka Rissanen
commit 1b19e16d40

View file

@ -425,7 +425,6 @@ static void net_if_ipv6_start_dad(struct net_if *iface,
net_sprint_ipv6_addr(&ifaddr->address.in6_addr));
if (!net_ipv6_start_dad(iface, ifaddr)) {
k_delayed_work_init(&ifaddr->dad_timer, dad_timeout);
k_delayed_work_submit(&ifaddr->dad_timer, DAD_TIMEOUT);
}
}
@ -470,7 +469,6 @@ void net_if_start_rs(struct net_if *iface)
NET_DBG("Interface %p", iface);
if (!net_ipv6_start_rs(iface)) {
k_delayed_work_init(&iface->rs_timer, rs_timeout);
k_delayed_work_submit(&iface->rs_timer, RS_TIMEOUT);
}
}
@ -548,6 +546,36 @@ static struct net_if_addr *ipv6_addr_find(struct net_if *iface,
return NULL;
}
static inline void net_if_addr_init(struct net_if_addr *ifaddr,
struct in6_addr *addr,
enum net_addr_type addr_type,
uint32_t vlifetime)
{
ifaddr->is_used = true;
ifaddr->address.family = AF_INET6;
ifaddr->addr_type = addr_type;
net_ipaddr_copy(&ifaddr->address.in6_addr, addr);
#if defined(CONFIG_NET_IPV6_DAD)
k_delayed_work_init(&ifaddr->dad_timer, dad_timeout);
#endif
/* FIXME - set the mcast addr for this node */
if (vlifetime) {
ifaddr->is_infinite = false;
k_delayed_work_init(&ifaddr->lifetime, ipv6_addr_expired);
NET_DBG("Expiring %s in %u secs", net_sprint_ipv6_addr(addr),
vlifetime);
net_if_ipv6_addr_update_lifetime(ifaddr, vlifetime);
} else {
ifaddr->is_infinite = true;
}
}
struct net_if_addr *net_if_ipv6_addr_add(struct net_if *iface,
struct in6_addr *addr,
enum net_addr_type addr_type,
@ -566,28 +594,8 @@ struct net_if_addr *net_if_ipv6_addr_add(struct net_if *iface,
continue;
}
iface->ipv6.unicast[i].is_used = true;
iface->ipv6.unicast[i].address.family = AF_INET6;
iface->ipv6.unicast[i].addr_type = addr_type;
memcpy(&iface->ipv6.unicast[i].address.in6_addr, addr, 16);
/* FIXME - set the mcast addr for this node */
if (vlifetime) {
iface->ipv6.unicast[i].is_infinite = false;
k_delayed_work_init(
&iface->ipv6.unicast[i].lifetime,
ipv6_addr_expired);
NET_DBG("Expiring %s in %u secs",
net_sprint_ipv6_addr(addr), vlifetime);
net_if_ipv6_addr_update_lifetime(
&iface->ipv6.unicast[i], vlifetime);
} else {
iface->ipv6.unicast[i].is_infinite = true;
}
net_if_addr_init(&iface->ipv6.unicast[i], addr, addr_type,
vlifetime);
NET_DBG("[%d] interface %p address %s type %s added", i, iface,
net_sprint_ipv6_addr(addr),
@ -754,6 +762,33 @@ static struct net_if_ipv6_prefix *ipv6_prefix_find(struct net_if *iface,
return NULL;
}
static inline void prefix_lf_timeout(struct k_work *work)
{
struct net_if_ipv6_prefix *prefix =
CONTAINER_OF(work, struct net_if_ipv6_prefix, lifetime);
NET_DBG("Prefix %s/%d expired",
net_sprint_ipv6_addr(&prefix->prefix), prefix->len);
prefix->is_used = false;
}
static void net_if_ipv6_prefix_init(struct net_if_ipv6_prefix *prefix,
struct in6_addr *addr, uint8_t len,
uint32_t lifetime)
{
prefix->is_used = true;
prefix->len = len;
net_ipaddr_copy(&prefix->prefix, addr);
k_delayed_work_init(&prefix->lifetime, prefix_lf_timeout);
if (lifetime == NET_IPV6_ND_INFINITE_LIFETIME) {
prefix->is_infinite = true;
} else {
prefix->is_infinite = false;
}
}
struct net_if_ipv6_prefix *net_if_ipv6_prefix_add(struct net_if *iface,
struct in6_addr *prefix,
uint8_t len,
@ -772,17 +807,8 @@ struct net_if_ipv6_prefix *net_if_ipv6_prefix_add(struct net_if *iface,
continue;
}
iface->ipv6.prefix[i].is_used = true;
iface->ipv6.prefix[i].len = len;
if (lifetime == NET_IPV6_ND_INFINITE_LIFETIME) {
iface->ipv6.prefix[i].is_infinite = true;
} else {
iface->ipv6.prefix[i].is_infinite = false;
}
memcpy(&iface->ipv6.prefix[i].prefix, prefix,
sizeof(struct in6_addr));
net_if_ipv6_prefix_init(&iface->ipv6.prefix[i], prefix, len,
lifetime);
NET_DBG("[%d] interface %p prefix %s/%d added", i, iface,
net_sprint_ipv6_addr(prefix), len);
@ -871,17 +897,6 @@ bool net_if_ipv6_addr_onlink(struct net_if **iface, struct in6_addr *addr)
return false;
}
static inline void prefix_lf_timeout(struct k_work *work)
{
struct net_if_ipv6_prefix *prefix =
CONTAINER_OF(work, struct net_if_ipv6_prefix, lifetime);
NET_DBG("Prefix %s/%d expired",
net_sprint_ipv6_addr(&prefix->prefix), prefix->len);
prefix->is_used = false;
}
void net_if_ipv6_prefix_set_timer(struct net_if_ipv6_prefix *prefix,
uint32_t lifetime)
{
@ -907,9 +922,6 @@ void net_if_ipv6_prefix_set_timer(struct net_if_ipv6_prefix *prefix,
NET_DBG("Prefix lifetime %u ms", timeout);
net_if_ipv6_prefix_unset_timer(prefix);
k_delayed_work_init(&prefix->lifetime, prefix_lf_timeout);
k_delayed_work_submit(&prefix->lifetime, timeout);
}
@ -987,6 +999,32 @@ void net_if_ipv6_router_update_lifetime(struct net_if_router *router,
lifetime * MSEC_PER_SEC);
}
static inline void net_if_router_init(struct net_if_router *router,
struct net_if *iface,
struct in6_addr *addr, uint16_t lifetime)
{
router->is_used = true;
router->iface = iface;
router->address.family = AF_INET6;
net_ipaddr_copy(&router->address.in6_addr, addr);
if (lifetime) {
/* This is a default router. RFC 4861 page 43
* AdvDefaultLifetime variable
*/
router->is_default = true;
router->is_infinite = false;
k_delayed_work_init(&router->lifetime, ipv6_router_expired);
NET_DBG("Expiring %s in %u secs", net_sprint_ipv6_addr(addr),
lifetime);
} else {
router->is_default = false;
router->is_infinite = true;
}
}
struct net_if_router *net_if_ipv6_router_add(struct net_if *iface,
struct in6_addr *addr,
uint16_t lifetime)
@ -998,28 +1036,7 @@ struct net_if_router *net_if_ipv6_router_add(struct net_if *iface,
continue;
}
routers[i].is_used = true;
routers[i].iface = iface;
routers[i].address.family = AF_INET6;
if (lifetime) {
/* This is a default router. RFC 4861 page 43
* AdvDefaultLifetime variable
*/
routers[i].is_default = true;
routers[i].is_infinite = false;
k_delayed_work_init(&routers[i].lifetime,
ipv6_router_expired);
NET_DBG("Expiring %s in %u secs",
net_sprint_ipv6_addr(addr), lifetime);
} else {
routers[i].is_default = false;
routers[i].is_infinite = true;
}
net_ipaddr_copy(&routers[i].address.in6_addr, addr);
net_if_router_init(&routers[i], iface, addr, lifetime);
NET_DBG("[%d] interface %p router %s lifetime %u default %d "
"added",
@ -1616,6 +1633,10 @@ void net_if_init(struct k_sem *startup_sync)
iface->base_reachable_time = REACHABLE_TIME;
net_if_ipv6_set_reachable_time(iface);
#if defined(CONFIG_NET_IPV6_ND)
k_delayed_work_init(&iface->rs_timer, rs_timeout);
#endif
#endif
}