/*
 *
 *    Copyright (c) 2013-2017 Nest Labs, Inc.
 *    All rights reserved.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

/**
 *    @file
 *      This file implements an InetLayer-portable object for an IPv6
 *      RFC4861-compliant Router Advertisement daemon.
 *
 */

#include <string.h>//memcpy

#include <InetLayer/InetLayer.h>
#include <Weave/Core/WeaveEncoding.h>
#include "RADaemon.h"

#if WEAVE_SYSTEM_CONFIG_USE_LWIP
#else
#include <errno.h>
#include <string.h>
#include <stdlib.h> //rand(), srand()
#include <arpa/inet.h>
#endif

//Width of the fuzzy factor
#define RAD_FUZZY_FACTOR                        (3U * 1000U)        //3 seconds

//Immediately after a link's prefix info is updated, freuently send RAs.
#define RAD_UNSOLICITED_STARTUP_PERIOD          (15U * 1000U)       //15 seconds
#define RAD_SHORT_UNSOLICITED_STARTUP_PERIOD    (RAD_UNSOLICITED_STARTUP_PERIOD - RAD_FUZZY_FACTOR)
//NOTE: the above is done only few times after a link's prefix info is updated.
#define RAD_MAX_UNSOLICITED_STARTUP_PERIODS     (4U)

//Every 100 secs send an RA (long after the last prefix info has been updated.)
#define RAD_UNSOLICITED_PERIOD                  (100U * 1000U)       //100 seconds
#define RAD_SHORT_UNSOLICITED_PERIOD            (RAD_UNSOLICITED_PERIOD - RAD_FUZZY_FACTOR)

//Try a previous failed attempt to send a periodic multicast RA.
#define RAD_UNSOLICITED_RETRY_PERIOD            (RAD_UNSOLICITED_STARTUP_PERIOD / 3)

//At most reply to 4 RSes per minute.
#define RAD_MAX_RSES_PER_TIME_FRAME             (4U)
#define RAD_MAX_RSES_PER_TIME_FRAME_PERIOD      (60U * 1000U)       //60 seconds

extern void DumpMemory(const uint8_t *mem, uint32_t len, const char *prefix, uint32_t rowWidth);

namespace nl {
namespace Inet {

using namespace nl::Weave::Encoding;

#define RAD_IPV6_ADDR_LEN                       (16U)

#define RAD_ICMP6_TYPE_RS   133
#define RAD_ICMP6_TYPE_RA   134
uint8_t RADaemon::ICMP6Types[]          = { RAD_ICMP6_TYPE_RA };
uint8_t RADaemon::ICMP6TypesListen[]    = { RAD_ICMP6_TYPE_RS };
uint8_t RADaemon::PeriodicRAsWorked;

void RADaemon::Init(Weave::System::Layer& aSystemLayer, InetLayer& aInetLayer)
{
    SystemLayer         = &aSystemLayer;
    Inet                = &aInetLayer;
    PeriodicRAsWorked   = 0;
    memset(LinkInfo, 0, RAD_MAX_ADVERTISING_LINKS * sizeof(RADaemon::LinkInformation));
    for (int j = 0; j < RAD_MAX_ADVERTISING_LINKS; ++j)     { LinkInfo[j].Self = this; }
}

//Return a Standard Internet Checksum as described in RFC 1071.
//Code adapted from Section 4.0 "Implementation Examples", Subsection 4.1 "C".
//Verified correct behavior comparing to <http://ask.wireshark.org/questions/11061/icmp-checksum>
//And also comparing with <http://www.erg.abdn.ac.uk/~gorry/course/inet-pages/packet-dec2.html>
uint16_t RADaemon::CalculateChecksum(uint16_t *startpos, uint16_t checklen)
{
    uint32_t sum    = 0;
    uint16_t answer = 0;

    while (checklen > 1)
    {
        sum += *startpos++;
        checklen -= 2;
    }

    if (checklen == 1)
    {
        *(uint8_t *)(&answer) = *(uint8_t *)startpos;
        sum += answer;
    }

    sum = (sum >> 16) + (sum & 0xffff);
    sum += (sum >> 16);
    answer = ~sum;

    return answer;
}

struct PrefixInfoOption
{
    uint8_t     Type;
    uint8_t     Length;
    uint8_t     PrefixLength;
    uint8_t     L_A_Reserved1;
    uint32_t    ValidLifetime;
    uint32_t    PreferredLifetime;
    uint32_t    Reserved2;
    uint8_t     Prefix[RAD_IPV6_ADDR_LEN];
};

struct RouterAdvertisementHeader
{
    uint8_t             Type;
    uint8_t             Code;
    uint16_t            Checksum;
    uint8_t             CurHopLimit;
    uint8_t             M_O_Reserved;
    uint16_t            RouterLifetime;
    uint32_t            ReacheableTime;
    uint32_t            RetransTimer;
    PrefixInfoOption    PrefixInfoOpt[RAD_MAX_PREFIXES_PER_LINK];
};

struct half
{
  uint64_t first;
  uint64_t second;
};

//ipv6_addr is IPAddr part of the IPPrefix.
//prefix is the length part of the IPPrefix.
//masked is like ipv6_addr but without the (128-prefix) less significant bits.
void mask_ipv6_address (const uint8_t *ipv6_addr, uint8_t prefix, uint8_t *masked)
{
  struct half halves;
  uint64_t mask = 0;
  unsigned char *p = masked;

  memset(masked, 0, RAD_IPV6_ADDR_LEN);
  memcpy(&halves, ipv6_addr, sizeof(halves));

  if (prefix <= 64)
  {
    mask = nl::Weave::Encoding::Swap64(nl::Weave::Encoding::Swap64(halves.first) & ((uint64_t) (~0) << (64 - prefix)));
    memcpy(masked, &mask, sizeof(uint64_t));
    return;
  }

  prefix -= 64;

  memcpy(masked, &(halves.first), sizeof(uint64_t));
  p += sizeof(uint64_t);
  mask = nl::Weave::Encoding::Swap64(nl::Weave::Encoding::Swap64(halves.second) & (uint64_t) (~0) << (64 - prefix));
  memcpy(p, &mask, sizeof(uint64_t));
}

struct PseudoHeader {
    uint16_t    PayloadLength;
    uint16_t    NextHeader;
    uint8_t     SrcAddr[16];
    uint8_t     DstAddr[16];
};

void RADaemon::BuildRA(PacketBuffer *RAPacket, RADaemon::LinkInformation *linkInfo, const IPAddress &destAddr)
{
    uint8_t     index = 0;

    RouterAdvertisementHeader *icmp6payload  = (RouterAdvertisementHeader*)RAPacket->Start();

    //Fill up the ICMPv6 header fields.
    icmp6payload->Type           = RAD_ICMP6_TYPE_RA;
    icmp6payload->Code           = 0;
    icmp6payload->Checksum       = 0;
    icmp6payload->CurHopLimit    = 0;
    icmp6payload->M_O_Reserved   = 0;
    icmp6payload->RouterLifetime = BigEndian::HostSwap16(0);
    icmp6payload->ReacheableTime = BigEndian::HostSwap32(0);
    icmp6payload->RetransTimer   = BigEndian::HostSwap32(0);

    //Fill up the prefix options, if any.
    for (int k = 0; k < RAD_MAX_PREFIXES_PER_LINK; ++k)
    {
        if (linkInfo->IPPrefixInfo[k].IPPrefx != IPPrefix::Zero)
        {
            PrefixInfoOption *prefixInfoOpt     = &icmp6payload->PrefixInfoOpt[index];
            prefixInfoOpt->Type                 = 3;
            prefixInfoOpt->Length               = 4;
            prefixInfoOpt->PrefixLength         = linkInfo->IPPrefixInfo[k].IPPrefx.Length;
            prefixInfoOpt->L_A_Reserved1        = 0xC0; //L == 1, A == 1
            prefixInfoOpt->ValidLifetime        = BigEndian::HostSwap32(linkInfo->IPPrefixInfo[k].ValidLifetime);
            prefixInfoOpt->PreferredLifetime    = BigEndian::HostSwap32(linkInfo->IPPrefixInfo[k].PreferredLifetime);
            prefixInfoOpt->Reserved2            = BigEndian::HostSwap32(0);
            memcpy(prefixInfoOpt->Prefix, linkInfo->IPPrefixInfo[k].IPPrefx.IPAddr.Addr, RAD_IPV6_ADDR_LEN);
            index++;
        }
    }//for k

    uint16_t reqSize = sizeof(RouterAdvertisementHeader) - (RAD_MAX_PREFIXES_PER_LINK - index) * sizeof(PrefixInfoOption);

    //Fill up IPv6 fields belonging to the pseudo header necessary to calculate the checksum.
    PseudoHeader *ip6payload = (PseudoHeader *)((uint8_t *)icmp6payload - sizeof(PseudoHeader));
    ip6payload->PayloadLength   = BigEndian::HostSwap16(reqSize);
    ip6payload->NextHeader      = BigEndian::HostSwap16(kIPProtocol_ICMPv6);
    memcpy(ip6payload->SrcAddr, &linkInfo->LLAddr, sizeof(ip6payload->SrcAddr));
    memcpy(ip6payload->DstAddr, &destAddr, sizeof(ip6payload->DstAddr));

    //NOTE: because the fields in the packets are already converted to BigEndian order,
    //      there is no need to convert the final result of the checksumming to such order.
    icmp6payload->Checksum = CalculateChecksum((uint16_t*)ip6payload, sizeof(PseudoHeader) + reqSize);

    //Tell the PacketBuffer about the length of the ICMP6 message.
    RAPacket->SetDataLength(reqSize);

//    Debugging
//    ::DumpMemory((const uint8_t*)ip6payload, sizeof(PseudoHeader), "", 16);
//    ::DumpMemory((const uint8_t*)icmp6payload, reqSize, "", 16);
}

void RADaemon::MulticastRA(InetLayer* inet, void* appState, INET_ERROR err)
{
    if ( (inet == NULL) || (appState == NULL) || (err != INET_NO_ERROR) )
    {
        return;
    }

    RADaemon::LinkInformation  *linkInfo    = (RADaemon::LinkInformation*)appState;

    IPAddress destAddr;
    IPAddress::FromString("FF02::1", destAddr);

    PacketBuffer *RAPacket = PacketBuffer::New();
    if (RAPacket == NULL)
        return;

    PeriodicRAsWorked = RAPacket ? 1: 0;
    if (PeriodicRAsWorked)
    {
        BuildRA(RAPacket, linkInfo, destAddr);
        linkInfo->RawEP->SendTo(destAddr, RAPacket);
    }
}

void RADaemon::MulticastPeriodicRA(Weave::System::Layer* aSystemLayer, void* aAppState, Weave::System::Error aError)
{
    RADaemon::LinkInformation*  lLinkInfo   = reinterpret_cast<RADaemon::LinkInformation*>(aAppState);
    INET_ERROR                  lError      = static_cast<INET_ERROR>(aError);
    uint32_t                    lTimeout    = RAD_UNSOLICITED_RETRY_PERIOD;
    uint32_t                    lFuzz       = 0;

    if (lError != INET_NO_ERROR)
    {
        return;
    }

    MulticastRA(lLinkInfo->Self->Inet, aAppState, lError);

    //Reschedule a new periodic mcast of RAs.
    if (PeriodicRAsWorked)
    {
        lFuzz       = rand() % (RAD_FUZZY_FACTOR * 2);
        lTimeout    = RAD_SHORT_UNSOLICITED_PERIOD;

        if (lLinkInfo->NumRAsSentSoFar++ < RAD_MAX_UNSOLICITED_STARTUP_PERIODS)
        {
            lTimeout = RAD_SHORT_UNSOLICITED_STARTUP_PERIOD;
        }
    }

    aSystemLayer->StartTimer(lTimeout + lFuzz, MulticastPeriodicRA, lLinkInfo);
}

void RADaemon::TrackRSes(Weave::System::Layer* aSystemLayer, void* aAppState, Weave::System::Error aError)
{
    RADaemon::LinkInformation*  lLinkInfo   = reinterpret_cast<RADaemon::LinkInformation*>(aAppState);
    INET_ERROR                  lError      = static_cast<INET_ERROR>(aError);

    if (lError != INET_NO_ERROR)
    {
        return;
    }

    lLinkInfo->RSesDownCounter = RAD_MAX_RSES_PER_TIME_FRAME;
    lLinkInfo->Self->SystemLayer->StartTimer(RAD_MAX_RSES_PER_TIME_FRAME_PERIOD, TrackRSes, lLinkInfo);
}

void RADaemon::UpdateLinkLocalAddr(RADaemon::LinkInformation *linkInfo, IPAddress *llAddr)
{
    //Multicast an RA with the current Link Local Address.
    MulticastRA(linkInfo->Self->Inet, linkInfo, INET_NO_ERROR);

    //Update the Link Local address of this link
    linkInfo->LLAddr = *llAddr;

    //Multicast an RA with the new Link Local Address.
    MulticastRA(linkInfo->Self->Inet, linkInfo, INET_NO_ERROR);

    linkInfo->NumRAsSentSoFar = 0;
}

void RADaemon::McastAllPrefixes(RADaemon::LinkInformation *linkInfo)
{
    //Multicast an RA.
    MulticastRA(linkInfo->Self->Inet, linkInfo, INET_NO_ERROR);

    linkInfo->NumRAsSentSoFar = 0;
}

void RADaemon::HandleReceiveError2(RawEndPoint *endPoint, INET_ERROR err, IPAddress senderAddr)
{
}

void RADaemon::HandleReceiveError(RawEndPoint *endPoint, INET_ERROR err, IPAddress senderAddr)
{
}

struct RSPacketHdr
{
    uint8_t     Type;
    uint8_t     Code;
    uint16_t    Checksum;
    uint32_t    Reserved;
};

struct RSOpt
{
    uint8_t     OptType;
    uint8_t     OptLen;
};

void RADaemon::HandleMessageReceived2(RawEndPoint *RawEPListen, PacketBuffer *msg, IPAddress senderAddr)
{
}

void RADaemon::HandleMessageReceived(RawEndPoint *RawEPListen, PacketBuffer *msg, IPAddress senderAddr)
{
    uint8_t             msgDataLen      = msg->DataLength();
    RSPacketHdr        *RSPacket        = (RSPacketHdr *)msg->Start();
    RSPacketHdr        *RSPacketEnd     = (RSPacketHdr *)((uint8_t *)RSPacket + msgDataLen);
    LinkInformation    *currLinkInfo    = NULL;
    PacketBuffer       *RAPacket        = NULL;

//    Debugging
//    char senderAddrStr[64];
//    senderAddr.ToString(senderAddrStr, sizeof(senderAddrStr));
//    printf("Raw message received from %s (%ld bytes)\n", senderAddrStr, msgDataLen);
//    ::DumpMemory((const uint8_t *)RSPacket, msgDataLen, "  ", 16);

    //Error checks
    if (
            (RSPacket->Type != RAD_ICMP6_TYPE_RS) ||
            (RSPacket->Code != 0)
            //TODO: verify checksum
       )
    {
        goto finalize;
    }

    currLinkInfo = (RADaemon::LinkInformation *)RawEPListen->AppState;
    if (currLinkInfo->RSesDownCounter-- == 0)
    {
        currLinkInfo->RSesDownCounter = 0;
        goto finalize;
    }

    if (msgDataLen <= sizeof(RSPacketHdr))
    {
        //No options present
    }
    else
    {
        RSOpt *rsOpt = (RSOpt *)((uint8_t *)RSPacket + sizeof(RSPacketHdr));
        while (((uint8_t *)rsOpt < (uint8_t *)RSPacketEnd) && (rsOpt->OptType != 1))
        {
            rsOpt = (RSOpt *)((uint8_t *)rsOpt + rsOpt->OptLen);
        }
        if (((uint8_t *)rsOpt < (uint8_t *)RSPacketEnd) && (rsOpt->OptType == 1))
        {
//            For the time being the Mac addr is not used to decide how to send
//            the RA, but it is printed here, to prove that its parsing works.
//            printf("Source Link Layer Address Option: %x:%x:%x:%x:%x:%x\n",
//                    (&rsOpt->OptType+2)[0], (&rsOpt->OptType+2)[1], (&rsOpt->OptType+2)[2],
//                    (&rsOpt->OptType+2)[3], (&rsOpt->OptType+2)[4], (&rsOpt->OptType+2)[5]);
        }
        else
        {
            //No 'Source Link Layer Address' found.
        }
    }

    RAPacket = PacketBuffer::New();
    if (RAPacket == NULL)
        goto finalize;

    if (senderAddr == IPAddress::Any)
    {
        uint32_t lTimeout = RAD_SHORT_UNSOLICITED_PERIOD;
        const uint32_t lFuzz = rand() % (RAD_FUZZY_FACTOR * 2);
        IPAddress mcastAddr;
        IPAddress::FromString("FF02::1", mcastAddr);
        RADaemon::BuildRA(RAPacket, currLinkInfo, mcastAddr);
        currLinkInfo->RawEP->SendTo(mcastAddr, RAPacket);

        //Since mcast has been used to reply to this RS, reschedule a new periodic mcast of RAs.
        RADaemon *self = currLinkInfo->Self;
        Weave::System::Layer* lSystemLayer = self->SystemLayer;

        if (currLinkInfo->NumRAsSentSoFar < RAD_MAX_UNSOLICITED_STARTUP_PERIODS)
        {
            lTimeout = RAD_SHORT_UNSOLICITED_STARTUP_PERIOD;
        }

        lSystemLayer->StartTimer(lTimeout + lFuzz, MulticastPeriodicRA, currLinkInfo);
    }
    else
    {
        RADaemon::BuildRA(RAPacket, currLinkInfo, senderAddr);
        currLinkInfo->RawEP->SendTo(senderAddr, RAPacket);
    }

finalize:
    PacketBuffer::Free(msg);
}

INET_ERROR  RADaemon::SetPrefixInfo(InterfaceId link, IPAddress llAddr, IPPrefix ipPrefix, uint32_t validLifetime,
    uint32_t preferredLifetime)
{
//    char buf[IFNAMSIZE];
    IPPrefixInformation            *currIPPrefixInfo;
    IPPrefixInformation            *freeIPPrefixInfo    = NULL;
    RADaemon::LinkInformation      *currLinkInfo;
    RADaemon::LinkInformation      *freeLinkInfo        = NULL;
    INET_ERROR                      err                 = INET_NO_ERROR;

    if ( !IsInterfaceIdPresent(link) || (ipPrefix == IPPrefix::Zero) )
    {
        return INET_ERROR_BAD_ARGS;
    }

    if (llAddr == IPAddress::Any)
    {
        err = Inet->GetLinkLocalAddr(link, &llAddr);
        if (err != INET_NO_ERROR)
        {
            return err;
        }
    }

    //Reset the bits in the ipPrefix that fall outside its length.
    IPAddress tmpPrefix;
    mask_ipv6_address((const uint8_t *)&ipPrefix.IPAddr, ipPrefix.Length, (uint8_t *)&tmpPrefix);
    ipPrefix.IPAddr = tmpPrefix;

    for (int j = 0; j < RAD_MAX_ADVERTISING_LINKS; ++j)
    {//Try updating an EXISTING entry
        currLinkInfo = &LinkInfo[j];
        if (currLinkInfo->FSMState != FSM_NO_PREFIX)
        {
            if ( link == currLinkInfo->Link )
            {
                if (currLinkInfo->LLAddr != llAddr)
                {
                    //RFC 4861, Section 6.2.8. 'Link Local Address Change':
                    // "If a router changes the link-local address for one of its interfaces,
                    //  it SHOULD inform hosts of this change.  The router SHOULD multicast a
                    //  few Router Advertisements from the old link-local address with the
                    //  Router Lifetime field set to zero and also multicast a few Router
                    //  Advertisements from the new link-local address."
                    UpdateLinkLocalAddr(currLinkInfo, &llAddr);
                }
                for (int k = 0; k < RAD_MAX_PREFIXES_PER_LINK; ++k)
                {//Look for the passed prefix
                    currIPPrefixInfo = &currLinkInfo->IPPrefixInfo[k];
                    if (currIPPrefixInfo->IPPrefx == ipPrefix)
                    {//Update existing prefix with latest info
                        currIPPrefixInfo->ValidLifetime     = validLifetime;
                        currIPPrefixInfo->PreferredLifetime = preferredLifetime;
                        //RFC 4861, Section 4.2 'Router Advertisement Message Format', Subsection 'Prefix Information':
                        // "A router SHOULD include all its on-link prefixes (except the link-local prefix) so
                        //  that multihomed hosts have complete prefix information about on-link destinations for the
                        //  links to which they attach."
                        McastAllPrefixes(currLinkInfo);
                        goto out;
                    }
                    else if (freeIPPrefixInfo == NULL && currIPPrefixInfo->IPPrefx == IPPrefix::Zero)
                    {//Keep track of the first free prefix, in case is needed later
                        freeIPPrefixInfo = currIPPrefixInfo;
                    }
                }//for k

                if (freeIPPrefixInfo == NULL)
                {//No free space to store passed prefix info
                    err = INET_ERROR_NO_MEMORY;
                }
                else
                {//Save passed prefix with its associated info
                    freeIPPrefixInfo->IPPrefx           = ipPrefix;
                    freeIPPrefixInfo->ValidLifetime     = validLifetime;
                    freeIPPrefixInfo->PreferredLifetime = preferredLifetime;
                    McastAllPrefixes(currLinkInfo);
                }
                goto out;
            }
        }
        else if (freeLinkInfo == NULL)
        {//Keep track of the first free entry, in case is needed later
            freeLinkInfo = currLinkInfo;
        }
    }//for j

    if (freeLinkInfo == NULL)
    {//No free space for passed interface
        err = INET_ERROR_NO_MEMORY;
        goto out;
    }

    //Use free space to store passed information.
    err = Inet->NewRawEndPoint(kIPVersion_6, kIPProtocol_ICMPv6, &freeLinkInfo->RawEP);
    if (err != INET_NO_ERROR)
    {
        goto out;
    }

    err = Inet->NewRawEndPoint(kIPVersion_6, kIPProtocol_ICMPv6, &freeLinkInfo->RawEPListen);
    if (err != INET_NO_ERROR)
    {
        goto release_first_rawep;
    }

    freeLinkInfo->RawEP->AppState                   = freeLinkInfo;
    freeLinkInfo->RawEP->OnMessageReceived          = RADaemon::HandleMessageReceived2;
    freeLinkInfo->RawEP->OnReceiveError             = RADaemon::HandleReceiveError2;
    freeLinkInfo->RawEPListen->AppState             = freeLinkInfo;
    freeLinkInfo->RawEPListen->OnMessageReceived    = RADaemon::HandleMessageReceived;
    freeLinkInfo->RawEPListen->OnReceiveError       = RADaemon::HandleReceiveError;

    err = freeLinkInfo->RawEP->BindIPv6LinkLocal(link, llAddr);
    if (err != INET_NO_ERROR)
    {
        goto release_both_raweps;
    }

    err = freeLinkInfo->RawEP->SetICMPFilter(sizeof(ICMP6Types) / sizeof(uint8_t), ICMP6Types);
    if (err != INET_NO_ERROR)
    {
        goto release_both_raweps;
    }

    err = freeLinkInfo->RawEPListen->BindIPv6LinkLocal(link, llAddr);
    if (err != INET_NO_ERROR)
    {
        goto release_both_raweps;
    }

    err = freeLinkInfo->RawEPListen->SetICMPFilter(sizeof(ICMP6TypesListen) / sizeof(uint8_t), ICMP6TypesListen);
    if (err != INET_NO_ERROR)
    {
        goto release_both_raweps;
    }

    err = freeLinkInfo->RawEPListen->Listen();
    if (err != INET_NO_ERROR)
    {
        goto release_both_raweps;
    }

    freeLinkInfo->FSMState                              = FSM_ADVERTISING;
    freeLinkInfo->Link                                  = link;
    freeLinkInfo->LLAddr                                = llAddr;
    freeLinkInfo->IPPrefixInfo[0].IPPrefx               = ipPrefix;
    freeLinkInfo->IPPrefixInfo[0].ValidLifetime         = validLifetime;
    freeLinkInfo->IPPrefixInfo[0].PreferredLifetime     = preferredLifetime;
    freeLinkInfo->NumRAsSentSoFar = 0;
    MulticastPeriodicRA(SystemLayer, freeLinkInfo, WEAVE_SYSTEM_NO_ERROR);
    TrackRSes(SystemLayer, freeLinkInfo, WEAVE_SYSTEM_NO_ERROR);
    goto out;

release_both_raweps:
    freeLinkInfo->RawEPListen->Free();
    freeLinkInfo->RawEPListen = NULL;

release_first_rawep:
    freeLinkInfo->RawEP->Free();
    freeLinkInfo->RawEP = NULL;

out:
    return err;
}

//Delete the prefix associated with the passed interface.
void RADaemon::DelPrefixInfo(InterfaceId link, IPPrefix ipPrefix)
{
    IPPrefixInformation        *currIPPrefixInfo;
    RADaemon::LinkInformation  *currLinkInfo;
    uint8_t                     num_free_prefixes   = 0;
    uint8_t                     prefix_removed      = 0;

    if ( !IsInterfaceIdPresent(link) || (ipPrefix == IPPrefix::Zero) )
    {
        return;
    }

    for (int j = 0; j < RAD_MAX_ADVERTISING_LINKS; ++j)
    {
        currLinkInfo = &LinkInfo[j];
        if ( link == currLinkInfo->Link )
        {
            for (int k = 0; k < RAD_MAX_PREFIXES_PER_LINK; ++k)
            {
                currIPPrefixInfo = &currLinkInfo->IPPrefixInfo[k];
                if (currIPPrefixInfo->IPPrefx == ipPrefix)
                {
                    memset(&currIPPrefixInfo->IPPrefx, 0, sizeof(IPPrefix));
                    prefix_removed = 1;
                    num_free_prefixes++;
                }
                else if (LinkInfo[j].IPPrefixInfo[k].IPPrefx == IPPrefix::Zero)
                {
                    num_free_prefixes++;
                }
            }//for k

            if (num_free_prefixes == RAD_MAX_PREFIXES_PER_LINK)
            {
                DelLinkInfo(link);
            }
            break;//from for j
        }
    }//for j

    if (prefix_removed == 1 && num_free_prefixes != RAD_MAX_PREFIXES_PER_LINK)
    {
        McastAllPrefixes(currLinkInfo);
    }
}

//Free all the information associated with the passed interface.
void RADaemon::DelLinkInfo(InterfaceId link)
{
    if ( !IsInterfaceIdPresent(link) )
    {
        return;
    }

    for (int j = 0; j < RAD_MAX_ADVERTISING_LINKS; ++j)
    {
        if ( link == LinkInfo[j].Link )
        {
            RADaemon::LinkInformation *currLinkInfo = &LinkInfo[j];
            currLinkInfo->RawEPListen->Free();
            currLinkInfo->RawEPListen = NULL;
            currLinkInfo->RawEP->Free();
            currLinkInfo->RawEP = NULL;
            SystemLayer->CancelTimer(MulticastPeriodicRA, currLinkInfo);
            SystemLayer->CancelTimer(TrackRSes, currLinkInfo);
            memset(currLinkInfo, 0, sizeof(RADaemon::LinkInformation));
            currLinkInfo->Self = this;
            break;
        }
    }
}


} /* namespace Inet */
} /* namespace nl */
