From bba3fccd74b1c2275c02c2870aba26fdb2d5beaf Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 2 Feb 2015 14:50:16 -0600 Subject: [PATCH] Networking: Apply the same ARP fix for the Neighbor Solicitation logic --- net/icmpv6/icmpv6.h | 7 ++++--- net/icmpv6/icmpv6_neighbor.c | 12 ++++++++++++ net/icmpv6/icmpv6_notify.c | 7 ++++--- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/net/icmpv6/icmpv6.h b/net/icmpv6/icmpv6.h index bf4322aa00..b4fe411465 100644 --- a/net/icmpv6/icmpv6.h +++ b/net/icmpv6/icmpv6.h @@ -261,8 +261,9 @@ int icmpv6_wait_cancel(FAR struct icmpv6_notify_s *notify); * received, or (2) a timeout occurs. * * Assumptions: - * This function is called from icmpv6_neighbor() and executes in the normal - * tasking environment. + * This function is called from icmpv6_neighbor() and must execute with + * the network un-locked (interrupts may be disabled to keep the things + * stable). * ****************************************************************************/ @@ -283,7 +284,7 @@ int icmpv6_wait(FAR struct icmpv6_notify_s *notify, * * Assumptions: * This function is called from the MAC device driver indirectly through - * icmpv6_icmpv6in() and may be execute from the interrupt level. + * icmpv6_icmpv6in() will execute with the network locked. * ****************************************************************************/ diff --git a/net/icmpv6/icmpv6_neighbor.c b/net/icmpv6/icmpv6_neighbor.c index d81614db23..7b61c71b59 100644 --- a/net/icmpv6/icmpv6_neighbor.c +++ b/net/icmpv6/icmpv6_neighbor.c @@ -210,6 +210,9 @@ int icmpv6_neighbor(const net_ipv6addr_t ipaddr) struct timespec delay; struct icmpv6_neighbor_s state; FAR const uint16_t *lookup; +#ifdef CONFIG_NET_NOINTS + irqstate_t flags; +#endif net_lock_t save; int ret; @@ -376,12 +379,21 @@ int icmpv6_neighbor(const net_ipv6addr_t ipaddr) /* Now wait for response to the ARP response to be received. The * optimal delay would be the work case round trip time. + * NOTE: The network is locked. */ delay.tv_sec = CONFIG_ICMPv6_NEIGHBOR_DELAYSEC; delay.tv_nsec = CONFIG_ICMPv6_NEIGHBOR_DELAYNSEC; +#ifdef CONFIG_NET_NOINTS + flags = irqsave(); /* Keep things stable */ + net_unlock(save); /* Unlock the network with interrupts disabled */ +#endif ret = icmpv6_wait(¬ify, &delay); +#ifdef CONFIG_NET_NOINTS + save = net_lock(); /* Re-lock the network with interrupts disabled */ + irqrestore(flags); +#endif /* icmpv6_wait will return OK if and only if the matching ARP response * is received. Otherwise, it will return -ETIMEDOUT. diff --git a/net/icmpv6/icmpv6_notify.c b/net/icmpv6/icmpv6_notify.c index ad5a7c07b9..a5c0bd3077 100644 --- a/net/icmpv6/icmpv6_notify.c +++ b/net/icmpv6/icmpv6_notify.c @@ -169,8 +169,9 @@ int icmpv6_wait_cancel(FAR struct icmpv6_notify_s *notify) * received, or (2) a timeout occurs. * * Assumptions: - * This function is called from icmpv6_neighbor() and executes in the normal - * tasking environment. + * This function is called from icmpv6_neighbor() and must execute with + * the network un-locked (interrupts may be disabled to keep the things + * stable). * ****************************************************************************/ @@ -225,7 +226,7 @@ int icmpv6_wait(FAR struct icmpv6_notify_s *notify, * * Assumptions: * This function is called from the MAC device driver indirectly through - * icmpv6_icmpv6in() and may be execute from the interrupt level. + * icmpv6_icmpv6in() will execute with the network locked. * ****************************************************************************/