Skip to content

Commit d510f1f

Browse files
pabigotjukkar
authored andcommitted
net: if: tweak DAD and RS timeout handling
Both RS and DAD timeouts are simplified because the delay is a constant, and by construction the list of timeouts is in increasing time remaining. Refactor to avoid repeating the expression that represents the time until DAD state expires. Uniformly use unsigned operands in deadline calculation. Note a case where the racy idiom for retaining an existing timeout is required in the current work API, but can be replaced with a robust solution in the proposed new API (the reschedule API replaces any existing pending update, but the schedule API will leave an existing scheduled submission in place). Signed-off-by: Peter Bigot <[email protected]>
1 parent 4882dd6 commit d510f1f

File tree

1 file changed

+20
-10
lines changed

1 file changed

+20
-10
lines changed

subsys/net/ip/net_if.c

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -982,12 +982,13 @@ static void join_mcast_nodes(struct net_if *iface, struct in6_addr *addr)
982982
#endif /* CONFIG_NET_IPV6_MLD */
983983

984984
#if defined(CONFIG_NET_IPV6_DAD)
985-
#define DAD_TIMEOUT 100 /* ms */
985+
#define DAD_TIMEOUT 100U /* ms */
986986

987987
static void dad_timeout(struct k_work *work)
988988
{
989989
uint32_t current_time = k_uptime_get_32();
990990
struct net_if_addr *ifaddr, *next;
991+
int32_t delay = -1;
991992

992993
ARG_UNUSED(work);
993994

@@ -996,8 +997,12 @@ static void dad_timeout(struct k_work *work)
996997
struct net_if_addr *tmp;
997998
struct net_if *iface;
998999

999-
if ((int32_t)(ifaddr->dad_start +
1000-
DAD_TIMEOUT - current_time) > 0) {
1000+
/* DAD entries are ordered by construction. Stop when
1001+
* we find one that hasn't expired.
1002+
*/
1003+
delay = (int32_t)(ifaddr->dad_start +
1004+
DAD_TIMEOUT - current_time);
1005+
if (delay > 0) {
10011006
break;
10021007
}
10031008

@@ -1031,10 +1036,8 @@ static void dad_timeout(struct k_work *work)
10311036
ifaddr = NULL;
10321037
}
10331038

1034-
if (ifaddr) {
1035-
k_delayed_work_submit(&dad_timer,
1036-
K_MSEC(ifaddr->dad_start +
1037-
DAD_TIMEOUT - current_time));
1039+
if ((ifaddr != NULL) && (delay > 0)) {
1040+
k_delayed_work_submit(&dad_timer, K_MSEC((uint32_t)delay));
10381041
}
10391042
}
10401043

@@ -1058,6 +1061,7 @@ static void net_if_ipv6_start_dad(struct net_if *iface,
10581061
ifaddr->dad_start = k_uptime_get_32();
10591062
sys_slist_append(&active_dad_timers, &ifaddr->dad_node);
10601063

1064+
/* FUTURE: use schedule, not reschedule. */
10611065
if (!k_delayed_work_remaining_get(&dad_timer)) {
10621066
k_delayed_work_submit(&dad_timer,
10631067
K_MSEC(DAD_TIMEOUT));
@@ -1148,21 +1152,26 @@ static inline void net_if_ipv6_start_dad(struct net_if *iface,
11481152
#endif /* CONFIG_NET_IPV6_DAD */
11491153

11501154
#if defined(CONFIG_NET_IPV6_ND)
1151-
#define RS_TIMEOUT (1 * MSEC_PER_SEC)
1155+
#define RS_TIMEOUT (1U * MSEC_PER_SEC)
11521156
#define RS_COUNT 3
11531157

11541158
static void rs_timeout(struct k_work *work)
11551159
{
11561160
uint32_t current_time = k_uptime_get_32();
11571161
struct net_if_ipv6 *ipv6, *next;
1162+
int32_t delay = -1;
11581163

11591164
ARG_UNUSED(work);
11601165

11611166
SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&active_rs_timers,
11621167
ipv6, next, rs_node) {
11631168
struct net_if *iface = NULL;
11641169

1165-
if ((int32_t)(ipv6->rs_start + RS_TIMEOUT - current_time) > 0) {
1170+
/* RS entries are ordered by construction. Stop when
1171+
* we find one that hasn't expired.
1172+
*/
1173+
delay = (int32_t)(ipv6->rs_start + RS_TIMEOUT - current_time);
1174+
if (delay > 0) {
11661175
break;
11671176
}
11681177

@@ -1192,7 +1201,7 @@ static void rs_timeout(struct k_work *work)
11921201
ipv6 = NULL;
11931202
}
11941203

1195-
if (ipv6) {
1204+
if ((ipv6 != NULL) && (delay > 0)) {
11961205
k_delayed_work_submit(&rs_timer,
11971206
K_MSEC(ipv6->rs_start +
11981207
RS_TIMEOUT - current_time));
@@ -1213,6 +1222,7 @@ void net_if_start_rs(struct net_if *iface)
12131222
ipv6->rs_start = k_uptime_get_32();
12141223
sys_slist_append(&active_rs_timers, &ipv6->rs_node);
12151224

1225+
/* FUTURE: use schedule, not reschedule. */
12161226
if (!k_delayed_work_remaining_get(&rs_timer)) {
12171227
k_delayed_work_submit(&rs_timer, K_MSEC(RS_TIMEOUT));
12181228
}

0 commit comments

Comments
 (0)