net/iface: Coalesce all RS timers through one
This reduces the size of struct net_if_ipv6 by 24 bytes by moving the k_delayed_work attribute into net_if core code. Then each net_if_ipv6 can be added to the timer handler via a slist. This does not make much gain if the system has only 1 network interface It starts to be interesting if it has 2+ network interfaces then. Fixes #8728 Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
parent
09e7262be8
commit
b5bcd25398
3 changed files with 91 additions and 29 deletions
|
@ -220,9 +220,6 @@ struct net_if_ipv6 {
|
||||||
/** Prefixes */
|
/** Prefixes */
|
||||||
struct net_if_ipv6_prefix prefix[NET_IF_MAX_IPV6_PREFIX];
|
struct net_if_ipv6_prefix prefix[NET_IF_MAX_IPV6_PREFIX];
|
||||||
|
|
||||||
/** Router solicitation timer */
|
|
||||||
struct k_delayed_work rs_timer;
|
|
||||||
|
|
||||||
/** Default reachable time (RFC 4861, page 52) */
|
/** Default reachable time (RFC 4861, page 52) */
|
||||||
u32_t base_reachable_time;
|
u32_t base_reachable_time;
|
||||||
|
|
||||||
|
@ -231,12 +228,19 @@ struct net_if_ipv6 {
|
||||||
|
|
||||||
/** Retransmit timer (RFC 4861, page 52) */
|
/** Retransmit timer (RFC 4861, page 52) */
|
||||||
u32_t retrans_timer;
|
u32_t retrans_timer;
|
||||||
|
#if defined(CONFIG_NET_IPV6_ND)
|
||||||
|
/** Router solicitation timer node */
|
||||||
|
sys_snode_t rs_node;
|
||||||
|
|
||||||
/** IPv6 hop limit */
|
/* RS start time */
|
||||||
u8_t hop_limit;
|
u32_t rs_start;
|
||||||
|
|
||||||
/** RS count */
|
/** RS count */
|
||||||
u8_t rs_count;
|
u8_t rs_count;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** IPv6 hop limit */
|
||||||
|
u8_t hop_limit;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** @cond INTERNAL_HIDDEN */
|
/** @cond INTERNAL_HIDDEN */
|
||||||
|
@ -659,6 +663,21 @@ static inline void net_if_start_dad(struct net_if *iface)
|
||||||
*/
|
*/
|
||||||
void net_if_start_rs(struct net_if *iface);
|
void net_if_start_rs(struct net_if *iface);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Stop neighbor discovery.
|
||||||
|
*
|
||||||
|
* @param iface Pointer to a network interface structure
|
||||||
|
*/
|
||||||
|
#if defined(CONFIG_NET_IPV6_ND)
|
||||||
|
void net_if_stop_rs(struct net_if *iface);
|
||||||
|
#else
|
||||||
|
static inline void net_if_stop_rs(struct net_if *iface)
|
||||||
|
{
|
||||||
|
ARG_UNUSED(iface);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_NET_IPV6_ND */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set a network interface's link address
|
* @brief Set a network interface's link address
|
||||||
*
|
*
|
||||||
|
|
|
@ -2429,7 +2429,7 @@ static enum net_verdict handle_ra_input(struct net_pkt *pkt,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cancel the RS timer on iface */
|
/* Cancel the RS timer on iface */
|
||||||
k_delayed_work_cancel(&net_pkt_iface(pkt)->config.ip.ipv6->rs_timer);
|
net_if_stop_rs(net_pkt_iface(pkt));
|
||||||
|
|
||||||
net_pkt_unref(pkt);
|
net_pkt_unref(pkt);
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,11 @@ static struct k_delayed_work dad_timer;
|
||||||
static sys_slist_t active_dad_timers;
|
static sys_slist_t active_dad_timers;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_NET_IPV6_ND)
|
||||||
|
static struct k_delayed_work rs_timer;
|
||||||
|
static sys_slist_t active_rs_timers;
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
struct net_if_ipv6 ipv6;
|
struct net_if_ipv6 ipv6;
|
||||||
struct net_if *iface;
|
struct net_if *iface;
|
||||||
|
@ -742,29 +747,48 @@ static inline void net_if_ipv6_start_dad(struct net_if *iface,
|
||||||
|
|
||||||
static void rs_timeout(struct k_work *work)
|
static void rs_timeout(struct k_work *work)
|
||||||
{
|
{
|
||||||
/* Did not receive RA yet. */
|
u32_t current_time = k_uptime_get_32();
|
||||||
struct net_if_ipv6 *ipv6 = CONTAINER_OF(work,
|
struct net_if_ipv6 *ipv6, *next;
|
||||||
struct net_if_ipv6,
|
|
||||||
rs_timer);
|
|
||||||
struct net_if *iface;
|
|
||||||
|
|
||||||
ipv6->rs_count++;
|
ARG_UNUSED(work);
|
||||||
|
|
||||||
for (iface = __net_if_start; iface != __net_if_end; iface++) {
|
SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&active_rs_timers,
|
||||||
if (iface->config.ip.ipv6 == ipv6) {
|
ipv6, next, rs_node) {
|
||||||
goto found;
|
struct net_if *iface;
|
||||||
|
|
||||||
|
if ((s32_t)(ipv6->rs_start + RS_TIMEOUT - current_time) > 0) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Removing the ipv6 from active_rs_timers list */
|
||||||
|
sys_slist_remove(&active_rs_timers, NULL, &ipv6->rs_node);
|
||||||
|
|
||||||
|
/* Did not receive RA yet. */
|
||||||
|
ipv6->rs_count++;
|
||||||
|
|
||||||
|
for (iface = __net_if_start; iface != __net_if_end; iface++) {
|
||||||
|
if (iface->config.ip.ipv6 == ipv6) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iface != __net_if_end) {
|
||||||
|
NET_DBG("RS no respond iface %p count %d",
|
||||||
|
iface, ipv6->rs_count);
|
||||||
|
if (ipv6->rs_count < RS_COUNT) {
|
||||||
|
net_if_start_rs(iface);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
NET_DBG("Interface IPv6 config %p not found", ipv6);
|
||||||
|
}
|
||||||
|
|
||||||
|
ipv6 = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
NET_DBG("Interface IPv6 config %p not found", ipv6);
|
if (ipv6) {
|
||||||
return;
|
k_delayed_work_submit(&rs_timer,
|
||||||
|
ipv6->rs_start +
|
||||||
found:
|
RS_TIMEOUT - current_time);
|
||||||
NET_DBG("RS no respond iface %p count %d", iface,
|
|
||||||
ipv6->rs_count);
|
|
||||||
|
|
||||||
if (ipv6->rs_count < RS_COUNT) {
|
|
||||||
net_if_start_rs(iface);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -779,17 +803,37 @@ void net_if_start_rs(struct net_if *iface)
|
||||||
NET_DBG("Starting ND/RS for iface %p", iface);
|
NET_DBG("Starting ND/RS for iface %p", iface);
|
||||||
|
|
||||||
if (!net_ipv6_start_rs(iface)) {
|
if (!net_ipv6_start_rs(iface)) {
|
||||||
k_delayed_work_submit(&ipv6->rs_timer, RS_TIMEOUT);
|
ipv6->rs_start = k_uptime_get_32();
|
||||||
|
sys_slist_append(&active_rs_timers, &ipv6->rs_node);
|
||||||
|
|
||||||
|
if (!k_delayed_work_remaining_get(&rs_timer)) {
|
||||||
|
k_delayed_work_submit(&rs_timer, RS_TIMEOUT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void iface_ipv6_nd_init(struct net_if_ipv6 *ipv6)
|
void net_if_stop_rs(struct net_if *iface)
|
||||||
{
|
{
|
||||||
k_delayed_work_init(&ipv6->rs_timer, rs_timeout);
|
struct net_if_ipv6 *ipv6 = iface->config.ip.ipv6;
|
||||||
|
|
||||||
|
if (!ipv6) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NET_DBG("Stopping ND/RS for iface %p", iface);
|
||||||
|
|
||||||
|
sys_slist_find_and_remove(&active_rs_timers, &ipv6->rs_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void iface_ipv6_nd_init(void)
|
||||||
|
{
|
||||||
|
k_delayed_work_init(&rs_timer, rs_timeout);
|
||||||
|
sys_slist_init(&active_rs_timers);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define net_if_start_rs(...)
|
#define net_if_start_rs(...)
|
||||||
|
#define net_if_stop_rs(...)
|
||||||
#define iface_ipv6_nd_init(...)
|
#define iface_ipv6_nd_init(...)
|
||||||
#endif /* CONFIG_NET_IPV6_ND */
|
#endif /* CONFIG_NET_IPV6_ND */
|
||||||
|
|
||||||
|
@ -2207,6 +2251,7 @@ static void iface_ipv6_init(int if_count)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
iface_ipv6_dad_init();
|
iface_ipv6_dad_init();
|
||||||
|
iface_ipv6_nd_init();
|
||||||
|
|
||||||
k_delayed_work_init(&address_lifetime_timer, address_lifetime_timeout);
|
k_delayed_work_init(&address_lifetime_timer, address_lifetime_timeout);
|
||||||
k_delayed_work_init(&prefix_lifetime_timer, prefix_lifetime_timeout);
|
k_delayed_work_init(&prefix_lifetime_timer, prefix_lifetime_timeout);
|
||||||
|
@ -2224,8 +2269,6 @@ static void iface_ipv6_init(int if_count)
|
||||||
ipv6_addresses[i].ipv6.base_reachable_time = REACHABLE_TIME;
|
ipv6_addresses[i].ipv6.base_reachable_time = REACHABLE_TIME;
|
||||||
|
|
||||||
net_if_ipv6_set_reachable_time(&ipv6_addresses[i].ipv6);
|
net_if_ipv6_set_reachable_time(&ipv6_addresses[i].ipv6);
|
||||||
|
|
||||||
iface_ipv6_nd_init(&ipv6_addresses[i].ipv6);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue