From 8b2e2268744449db0c7fb6fd1db4704f6daaaf3d Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Thu, 24 Aug 2017 11:24:14 -0700 Subject: [PATCH] [netif] add linklocal/realmlocal allnodes/allrouters multicast addresses to list (#2121) Certain multicast addresses like "ff02::01" (Link-Local All-Nodes) are fixed and will not change. The commit defines them as constant entries which are then appended into the `mMulticastAddresses` linked-list. --- include/openthread/types.h | 4 +- src/core/net/netif.cpp | 127 +++++++++++++++++++++++++++++++++---- src/core/net/netif.hpp | 27 ++++++-- 3 files changed, 138 insertions(+), 20 deletions(-) diff --git a/include/openthread/types.h b/include/openthread/types.h index a95becb5d..acd14c7b1 100644 --- a/include/openthread/types.h +++ b/include/openthread/types.h @@ -1030,8 +1030,8 @@ typedef struct otNetifAddress */ typedef struct otNetifMulticastAddress { - otIp6Address mAddress; ///< The IPv6 multicast address. - struct otNetifMulticastAddress *mNext; ///< A pointer to the next network interface multicast address. + otIp6Address mAddress; ///< The IPv6 multicast address. + const struct otNetifMulticastAddress *mNext; ///< A pointer to the next network interface multicast address. } otNetifMulticastAddress; /** diff --git a/src/core/net/netif.cpp b/src/core/net/netif.cpp index b8a9fa641..57b628ec5 100644 --- a/src/core/net/netif.cpp +++ b/src/core/net/netif.cpp @@ -43,13 +43,60 @@ namespace ot { namespace Ip6 { +/* + * Certain fixed multicast addresses are defined as a set of chained (linked-list) constant `otNetifMulticastAddress` + * entries: + * + * LinkLocalAllRouters -> RealmLocalAllRouters -> LinkLocalAll -> RealmLocalAll -> RealmLocalAllMplForwarders -> NULL + * + * All or a portion of the chain is appended to the end of `mMulticastAddresses` linked-list. If the interface is + * subscribed to all-routers multicast addresses (using `SubscribeAllRoutersMulticast()`) then all the five entries + * are appended. Otherwise only the last three are appended. + * + */ + +// "ff03::fc" +const otNetifMulticastAddress Netif::kRealmLocalAllMplForwardersMulticastAddress = +{ + {{{ 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc }}}, + NULL +}; + +// "ff03::01" +const otNetifMulticastAddress Netif::kRealmLocalAllNodesMulticastAddress = +{ + {{{ 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}}, + &Netif::kRealmLocalAllMplForwardersMulticastAddress +}; + +// "ff02::01" +const otNetifMulticastAddress Netif::kLinkLocalAllNodesMulticastAddress = +{ + {{{ 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}}, + &Netif::kRealmLocalAllNodesMulticastAddress +}; + +// "ff03:02" +const otNetifMulticastAddress Netif::kRealmLocalAllRoutersMulticastAddress = +{ + {{{ 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }}}, + &Netif::kLinkLocalAllNodesMulticastAddress +}; + +// "ff02:02" +const otNetifMulticastAddress Netif::kLinkLocalAllRoutersMulticastAddress = +{ + {{{ 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }}}, + &Netif::kRealmLocalAllRoutersMulticastAddress +}; + + Netif::Netif(Ip6 &aIp6, int8_t aInterfaceId): Ip6Locator(aIp6), mCallbacks(NULL), mUnicastAddresses(NULL), mMulticastAddresses(NULL), mInterfaceId(aInterfaceId), - mAllRoutersSubscribed(false), mMulticastPromiscuous(false), mStateChangedTask(aIp6.GetInstance(), &Netif::HandleStateChangedTask, this), mNext(NULL), @@ -66,6 +113,9 @@ Netif::Netif(Ip6 &aIp6, int8_t aInterfaceId): // To mark the address as unused/available, set the `mNext` to point back to itself. mExtMulticastAddresses[i].mNext = &mExtMulticastAddresses[i]; } + + mMulticastAddresses = static_cast( + const_cast(&kLinkLocalAllNodesMulticastAddress)); } otError Netif::RegisterCallback(NetifCallback &aCallback) @@ -120,16 +170,6 @@ bool Netif::IsMulticastSubscribed(const Address &aAddress) const { bool rval = false; - if (aAddress.IsLinkLocalAllNodesMulticast() || aAddress.IsRealmLocalAllNodesMulticast() || - aAddress.IsRealmLocalAllMplForwarders()) - { - ExitNow(rval = true); - } - else if (aAddress.IsLinkLocalAllRoutersMulticast() || aAddress.IsRealmLocalAllRoutersMulticast()) - { - ExitNow(rval = mAllRoutersSubscribed); - } - for (NetifMulticastAddress *cur = mMulticastAddresses; cur; cur = cur->GetNext()) { if (memcmp(&cur->mAddress, &aAddress, sizeof(cur->mAddress)) == 0) @@ -142,6 +182,71 @@ exit: return rval; } +otError Netif::SubscribeAllRoutersMulticast(void) +{ + otError error = OT_ERROR_NONE; + + if (mMulticastAddresses == &kLinkLocalAllNodesMulticastAddress) + { + mMulticastAddresses = static_cast( + const_cast(&kLinkLocalAllRoutersMulticastAddress)); + } + else + { + for (NetifMulticastAddress *cur = mMulticastAddresses; cur; cur = cur->GetNext()) + { + if (cur == &kLinkLocalAllRoutersMulticastAddress) + { + ExitNow(error = OT_ERROR_ALREADY); + } + + if (cur->mNext == &kLinkLocalAllNodesMulticastAddress) + { + cur->mNext = &kLinkLocalAllRoutersMulticastAddress; + break; + } + } + } + + SetStateChangedFlags(OT_CHANGED_IP6_MULTICAST_SUBSRCRIBED); + +exit: + return error; +} + +otError Netif::UnsubscribeAllRoutersMulticast(void) +{ + otError error = OT_ERROR_NONE; + + if (mMulticastAddresses == &kLinkLocalAllRoutersMulticastAddress) + { + mMulticastAddresses = static_cast( + const_cast(&kLinkLocalAllNodesMulticastAddress)); + ExitNow(); + } + + for (NetifMulticastAddress *cur = mMulticastAddresses; cur; cur = cur->GetNext()) + { + if (cur->mNext == &kLinkLocalAllRoutersMulticastAddress) + { + cur->mNext = &kLinkLocalAllNodesMulticastAddress; + ExitNow(); + } + } + + error = OT_ERROR_NOT_FOUND; + +exit: + + if (error != OT_ERROR_NOT_FOUND) + { + SetStateChangedFlags(OT_CHANGED_IP6_MULTICAST_UNSUBSRCRIBED); + } + + return error; +} + + otError Netif::SubscribeMulticast(NetifMulticastAddress &aAddress) { otError error = OT_ERROR_NONE; diff --git a/src/core/net/netif.hpp b/src/core/net/netif.hpp index c865c9fff..8d46bf402 100644 --- a/src/core/net/netif.hpp +++ b/src/core/net/netif.hpp @@ -159,7 +159,7 @@ public: * @returns A pointer to the next multicast address. * */ - const NetifMulticastAddress *GetNext(void) const { return static_cast(mNext); } + const NetifMulticastAddress *GetNext(void) const { return static_cast(mNext); } /** * This method returns the next multicast address subscribed to the interface. @@ -167,7 +167,9 @@ public: * @returns A pointer to the next multicast address. * */ - NetifMulticastAddress *GetNext(void) { return static_cast(mNext); } + NetifMulticastAddress *GetNext(void) { + return static_cast(const_cast(mNext)); + } }; /** @@ -362,14 +364,20 @@ public: /** * This method subscribes the network interface to the link-local and realm-local all routers address. * + * @retval OT_ERROR_NONE Successfully subscribed to the link-local and realm-local all routers address + * @retval OT_ERROR_ALREADY The multicast addresses are already subscribed. + * */ - void SubscribeAllRoutersMulticast(void) { mAllRoutersSubscribed = true; } + otError SubscribeAllRoutersMulticast(void); /** * This method unsubscribes the network interface to the link-local and realm-local all routers address. * + * @retval OT_ERROR_NONE Successfully unsubscribed from the link-local and realm-local all routers address + * @retval OT_ERROR_NOT_FOUND The multicast addresses were not found. + * */ - void UnsubscribeAllRoutersMulticast(void) { mAllRoutersSubscribed = false; } + otError UnsubscribeAllRoutersMulticast(void); /** * This method returns a pointer to the list of multicast addresses. @@ -395,8 +403,8 @@ public: * * @param[in] aAddress A reference to the multicast address. * - * @retval OT_ERROR_NONE Successfully unsubscribed to @p aAddress. - * @retval OT_ERROR_ALREADY The multicast address is already unsubscribed. + * @retval OT_ERROR_NONE Successfully unsubscribed @p aAddress. + * @retval OT_ERROR_NOT_FOUND The multicast address was not found. * */ otError UnsubscribeMulticast(const NetifMulticastAddress &aAddress); @@ -529,7 +537,6 @@ private: NetifUnicastAddress *mUnicastAddresses; NetifMulticastAddress *mMulticastAddresses; int8_t mInterfaceId; - bool mAllRoutersSubscribed; bool mMulticastPromiscuous; Tasklet mStateChangedTask; Netif *mNext; @@ -538,6 +545,12 @@ private: NetifUnicastAddress mExtUnicastAddresses[OPENTHREAD_CONFIG_MAX_EXT_IP_ADDRS]; NetifMulticastAddress mExtMulticastAddresses[OPENTHREAD_CONFIG_MAX_EXT_MULTICAST_IP_ADDRS]; + + static const otNetifMulticastAddress kRealmLocalAllMplForwardersMulticastAddress; + static const otNetifMulticastAddress kLinkLocalAllNodesMulticastAddress; + static const otNetifMulticastAddress kRealmLocalAllNodesMulticastAddress; + static const otNetifMulticastAddress kLinkLocalAllRoutersMulticastAddress; + static const otNetifMulticastAddress kRealmLocalAllRoutersMulticastAddress; }; /**