7acafda858
There is a risk of deadlock in case net_if APIs are used from within net_mgmt handlers as both module APIs are protected with their own mutexes. The scenario observed with OpenThread happend when NET_EVENT_IPV6_ADDR_ADD/NET_EVENT_IPV6_MADDR_ADD events were processed. The net_mgmt mutex is locked when both, an event handler is being processed (from a separate net_mgmt thread) and when an event is raised (for example when a new address is added on an interface). In case a net_mgmt handler tried to use some mutex-protected net_if API, we could end up in a deadlock situation - the net_mgmt would wait for the net_if mutex to release, while some other thread (in this case main during initialization) could wait within some net_if function, pending on net_mgmt mutex to be released to notify the event. Fix this, by preventing net_if APIs from being used from within OT net_mgmt handlers. Additionally, simplify the net_mgmt handlers logic, by making use of additional info provided with an event. Instead of blindy assuming that recently added address was the last on the list (which might not always be the case, if addresses are added/removed dynamically), read the actual address being added from the net_mgmt_event_callback structure. Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
46 lines
1.3 KiB
C
46 lines
1.3 KiB
C
/*
|
|
* Copyright (c) 2018 Nordic Semiconductor ASA
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#ifndef __OPENTHREAD_UTILS_H__
|
|
#define __OPENTHREAD_UTILS_H__
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#if defined(CONFIG_OPENTHREAD_L2_DEBUG_DUMP_15_4) || \
|
|
defined(CONFIG_OPENTHREAD_L2_DEBUG_DUMP_IPV6)
|
|
|
|
void dump_pkt(const char *str, struct net_pkt *pkt);
|
|
#else
|
|
#define dump_pkt(...)
|
|
#endif
|
|
|
|
void add_ipv6_addr_to_zephyr(struct openthread_context *context);
|
|
void add_ipv6_addr_to_ot(struct openthread_context *context,
|
|
const struct in6_addr *addr6);
|
|
void add_ipv6_maddr_to_ot(struct openthread_context *context,
|
|
const struct in6_addr *addr6);
|
|
void add_ipv6_maddr_to_zephyr(struct openthread_context *context);
|
|
void rm_ipv6_addr_from_zephyr(struct openthread_context *context);
|
|
void rm_ipv6_maddr_from_zephyr(struct openthread_context *context);
|
|
|
|
int pkt_list_add(struct openthread_context *context, struct net_pkt *pkt);
|
|
struct net_pkt *pkt_list_peek(struct openthread_context *context);
|
|
void pkt_list_remove_last(struct openthread_context *context);
|
|
void pkt_list_remove_first(struct openthread_context *context);
|
|
|
|
static inline int pkt_list_is_full(struct openthread_context *context)
|
|
{
|
|
return context->pkt_list_full;
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* __OPENTHREAD_UTILS_H__ */
|