From deb36032cfcd64f3b487d26fba364609b9e4ef69 Mon Sep 17 00:00:00 2001 From: Yakun Xu Date: Sat, 24 Oct 2020 01:26:54 +0800 Subject: [PATCH] [posix] ignore unexpected host netif state notification (#5691) --- src/posix/platform/netif.cpp | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/src/posix/platform/netif.cpp b/src/posix/platform/netif.cpp index 6bd0026bd..179dbc506 100644 --- a/src/posix/platform/netif.cpp +++ b/src/posix/platform/netif.cpp @@ -276,6 +276,9 @@ enum #endif static constexpr size_t kMaxIp6Size = OPENTHREAD_CONFIG_IP6_MAX_DATAGRAM_LENGTH; +#if defined(RTM_NEWLINK) && defined(RTM_DELLINK) +static bool sIsSyncingState = false; +#endif #define OPENTHREAD_POSIX_LOG_TUN_PACKETS 0 @@ -494,12 +497,16 @@ static void UpdateLink(otInstance *aInstance) ifState = ((ifr.ifr_flags & IFF_UP) == IFF_UP) ? true : false; otState = otIp6IsEnabled(aInstance); - otLogNotePlat("changing interface state to %s%s.", otState ? "UP" : "DOWN", + otLogNotePlat("changing interface state to %s%s.", otState ? "up" : "down", (ifState == otState) ? " (already done, ignoring)" : ""); if (ifState != otState) { ifr.ifr_flags = otState ? (ifr.ifr_flags | IFF_UP) : (ifr.ifr_flags & ~IFF_UP); VerifyOrExit(ioctl(sIpFd, SIOCSIFFLAGS, &ifr) == 0, perror("ioctl"); error = OT_ERROR_FAILED); +#if defined(RTM_NEWLINK) && defined(RTM_DELLINK) + // wait for RTM_NEWLINK event before processing notification from kernel to avoid infinite loop + sIsSyncingState = true; +#endif } exit: @@ -768,18 +775,33 @@ static void processNetifLinkEvent(otInstance *aInstance, struct nlmsghdr *aNetli { struct ifinfomsg *ifinfo = reinterpret_cast(NLMSG_DATA(aNetlinkMessage)); otError error = OT_ERROR_NONE; + bool isUp; - VerifyOrExit(ifinfo->ifi_index == static_cast(gNetifIndex)); - SuccessOrExit(error = otIp6SetEnabled(aInstance, ifinfo->ifi_flags & IFF_UP)); + VerifyOrExit(ifinfo->ifi_index == static_cast(gNetifIndex) && (ifinfo->ifi_change & IFF_UP)); -exit: - if (error == OT_ERROR_NONE) + isUp = ((ifinfo->ifi_flags & IFF_UP) != 0); + + otLogInfoPlat("Host netif is %s", isUp ? "up" : "down"); + +#if defined(RTM_NEWLINK) && defined(RTM_DELLINK) + if (sIsSyncingState) { - otLogInfoPlat("%s: %s", __func__, otThreadErrorToString(error)); + VerifyOrExit(isUp == otIp6IsEnabled(aInstance), + otLogWarnPlat("Host netif state notification is unexpected (ignore)")); + sIsSyncingState = false; } else +#endif + if (isUp != otIp6IsEnabled(aInstance)) { - otLogWarnPlat("%s: %s", __func__, otThreadErrorToString(error)); + SuccessOrExit(error = otIp6SetEnabled(aInstance, isUp)); + otLogInfoPlat("Succeeded to sync netif state with host"); + } + +exit: + if (error != OT_ERROR_NONE) + { + otLogWarnPlat("Failed to sync netif state with host: %s", otThreadErrorToString(error)); } } #endif