Exemplo n.º 1
0
int8_t Routes::Lookup(const Address &aSource, const Address &aDestination)
{
    int8_t maxPrefixMatch = -1;
    uint8_t prefixMatch;
    int8_t rval = -1;

    for (Route *cur = mRoutes; cur; cur = cur->mNext)
    {
        prefixMatch = cur->mPrefix.PrefixMatch(aDestination);

        if (prefixMatch < cur->mPrefixLength)
        {
            continue;
        }

        if (prefixMatch > cur->mPrefixLength)
        {
            prefixMatch = cur->mPrefixLength;
        }

        if (maxPrefixMatch > static_cast<int8_t>(prefixMatch))
        {
            continue;
        }

        maxPrefixMatch = static_cast<int8_t>(prefixMatch);
        rval = cur->mInterfaceId;
    }

    for (Netif *netif = GetIp6().GetNetifList(); netif; netif = netif->GetNext())
    {
        if (netif->RouteLookup(aSource, aDestination, &prefixMatch) == OT_ERROR_NONE &&
            static_cast<int8_t>(prefixMatch) > maxPrefixMatch)
        {
            maxPrefixMatch = static_cast<int8_t>(prefixMatch);
            rval = netif->GetInterfaceId();
        }
    }

    return rval;
}
Exemplo n.º 2
0
const NetifUnicastAddress *Netif::SelectSourceAddress(MessageInfo &aMessageInfo)
{
    Address *destination = &aMessageInfo.GetPeerAddr();
    int interfaceId = aMessageInfo.mInterfaceId;
    const NetifUnicastAddress *rvalAddr = NULL;
    const Address *candidateAddr;
    uint8_t candidateId;
    uint8_t rvalIface = 0;

    for (Netif *netif = GetNetifList(); netif; netif = netif->mNext)
    {
        candidateId = netif->GetInterfaceId();

        for (const NetifUnicastAddress *addr = netif->GetUnicastAddresses(); addr; addr = addr->GetNext())
        {
            candidateAddr = &addr->GetAddress();

            if (destination->IsLinkLocal() || destination->IsMulticast())
            {
                if (interfaceId != candidateId)
                {
                    continue;
                }
            }

            if (rvalAddr == NULL)
            {
                // Rule 0: Prefer any address
                rvalAddr = addr;
                rvalIface = candidateId;
            }
            else if (*candidateAddr == *destination)
            {
                // Rule 1: Prefer same address
                rvalAddr = addr;
                rvalIface = candidateId;
                goto exit;
            }
            else if (candidateAddr->GetScope() < rvalAddr->GetAddress().GetScope())
            {
                // Rule 2: Prefer appropriate scope
                if (candidateAddr->GetScope() >= destination->GetScope())
                {
                    rvalAddr = addr;
                    rvalIface = candidateId;
                }
            }
            else if (candidateAddr->GetScope() > rvalAddr->GetAddress().GetScope())
            {
                if (rvalAddr->GetAddress().GetScope() < destination->GetScope())
                {
                    rvalAddr = addr;
                    rvalIface = candidateId;
                }
            }
            else if (addr->mPreferredLifetime != 0 && rvalAddr->mPreferredLifetime == 0)
            {
                // Rule 3: Avoid deprecated addresses
                rvalAddr = addr;
                rvalIface = candidateId;
            }
            else if (aMessageInfo.mInterfaceId != 0 && aMessageInfo.mInterfaceId == candidateId &&
                     rvalIface != candidateId)
            {
                // Rule 4: Prefer home address
                // Rule 5: Prefer outgoing interface
                rvalAddr = addr;
                rvalIface = candidateId;
            }
            else if (destination->PrefixMatch(*candidateAddr) > destination->PrefixMatch(rvalAddr->GetAddress()))
            {
                // Rule 6: Prefer matching label
                // Rule 7: Prefer public address
                // Rule 8: Use longest prefix matching
                rvalAddr = addr;
                rvalIface = candidateId;
            }
        }
    }

exit:
    aMessageInfo.mInterfaceId = rvalIface;
    return rvalAddr;
}