[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.
This commit is contained in:
Abtin Keshavarzian
2017-08-24 11:24:14 -07:00
committed by Jonathan Hui
parent e937542990
commit 8b2e226874
3 changed files with 138 additions and 20 deletions
+2 -2
View File
@@ -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;
/**
+116 -11
View File
@@ -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<NetifMulticastAddress *>(
const_cast<otNetifMulticastAddress *>(&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<NetifMulticastAddress *>(
const_cast<otNetifMulticastAddress *>(&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<NetifMulticastAddress *>(
const_cast<otNetifMulticastAddress *>(&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;
+20 -7
View File
@@ -159,7 +159,7 @@ public:
* @returns A pointer to the next multicast address.
*
*/
const NetifMulticastAddress *GetNext(void) const { return static_cast<NetifMulticastAddress *>(mNext); }
const NetifMulticastAddress *GetNext(void) const { return static_cast<const NetifMulticastAddress *>(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<NetifMulticastAddress *>(mNext); }
NetifMulticastAddress *GetNext(void) {
return static_cast<NetifMulticastAddress *>(const_cast<otNetifMulticastAddress *>(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;
};
/**