#include <IPv6NeighbourDiscovery.h>
Classes | |
| struct | AdvIfEntry |
| struct | DADEntry |
| struct | RDEntry |
Public Types | |
| typedef std::vector< cMessage * > | MsgPtrVector |
| typedef IPv6NeighbourCache::Key | Key |
| typedef IPv6NeighbourCache::Neighbour | Neighbour |
Public Member Functions | |
| IPv6NeighbourDiscovery () | |
| virtual | ~IPv6NeighbourDiscovery () |
| const MACAddress & | resolveNeighbour (const IPv6Address &nextHop, int interfaceId) |
| virtual void | reachabilityConfirmed (const IPv6Address &neighbour, int interfaceId) |
Protected Types | |
| typedef std::set< cMessage * > | RATimerList |
| typedef std::set< DADEntry * > | DADList |
| typedef std::set< RDEntry * > | RDList |
| typedef std::set< AdvIfEntry * > | AdvIfList |
Protected Member Functions | |
| virtual int | numInitStages () const |
| virtual void | initialize (int stage) |
| virtual void | handleMessage (cMessage *msg) |
| virtual void | processNDMessage (ICMPv6Message *msg, IPv6ControlInfo *ctrlInfo) |
| virtual void | finish () |
| virtual void | processIPv6Datagram (IPv6Datagram *datagram) |
| virtual IPv6NeighbourDiscovery::AdvIfEntry * | fetchAdvIfEntry (InterfaceEntry *ie) |
| virtual IPv6NeighbourDiscovery::RDEntry * | fetchRDEntry (InterfaceEntry *ie) |
| virtual IPv6Address | determineNextHop (const IPv6Address &destAddr, int &outIfID) |
| virtual void | initiateNeighbourUnreachabilityDetection (Neighbour *neighbour) |
| virtual void | processNUDTimeout (cMessage *timeoutMsg) |
| virtual IPv6Address | selectDefaultRouter (int &outIfID) |
| virtual void | timeoutPrefixEntry (const IPv6Address &destPrefix, int prefixLength) |
| virtual void | timeoutDefaultRouter (const IPv6Address &addr, int interfaceID) |
| virtual void | initiateAddressResolution (const IPv6Address &dgSrcAddr, Neighbour *nce) |
| virtual void | processARTimeout (cMessage *arTimeoutMsg) |
| virtual void | dropQueuedPacketsAwaitingAR (Neighbour *nce) |
| virtual void | sendPacketToIPv6Module (cMessage *msg, const IPv6Address &destAddr, const IPv6Address &srcAddr, int interfaceId) |
| virtual void | sendQueuedPacketsToIPv6Module (Neighbour *nce) |
| virtual void | initiateDAD (const IPv6Address &tentativeAddr, InterfaceEntry *ie) |
| virtual void | processDADTimeout (cMessage *msg) |
| virtual void | assignLinkLocalAddress (cMessage *timerMsg) |
| virtual IPv6RouterSolicitation * | createAndSendRSPacket (InterfaceEntry *ie) |
| virtual void | initiateRouterDiscovery (cMessage *msg) |
| virtual void | cancelRouterDiscovery (InterfaceEntry *ie) |
| virtual void | processRDTimeout (cMessage *msg) |
| virtual void | processRSPacket (IPv6RouterSolicitation *rs, IPv6ControlInfo *rsCtrlInfo) |
| virtual bool | validateRSPacket (IPv6RouterSolicitation *rs, IPv6ControlInfo *rsCtrlInfo) |
| virtual IPv6RouterAdvertisement * | createAndSendRAPacket (const IPv6Address &destAddr, InterfaceEntry *ie) |
| virtual void | processRAPacket (IPv6RouterAdvertisement *ra, IPv6ControlInfo *raCtrlInfo) |
| virtual void | processRAForRouterUpdates (IPv6RouterAdvertisement *ra, IPv6ControlInfo *raCtrlInfo) |
| virtual void | processRAPrefixInfo (IPv6RouterAdvertisement *ra, InterfaceEntry *ie) |
| virtual void | processRAPrefixInfoForAddrAutoConf (IPv6NDPrefixInformation &prefixInfo, InterfaceEntry *ie) |
| virtual void | createRATimer (InterfaceEntry *ie) |
| virtual void | resetRATimer (InterfaceEntry *ie) |
| virtual void | sendPeriodicRA (cMessage *msg) |
| virtual void | sendSolicitedRA (cMessage *msg) |
| virtual bool | validateRAPacket (IPv6RouterAdvertisement *ra, IPv6ControlInfo *raCtrlInfo) |
| virtual IPv6NeighbourSolicitation * | createAndSendNSPacket (const IPv6Address &nsTargetAddr, const IPv6Address &dgDestAddr, const IPv6Address &dgSrcAddr, InterfaceEntry *ie) |
| virtual void | processNSPacket (IPv6NeighbourSolicitation *ns, IPv6ControlInfo *naCtrlInfo) |
| virtual bool | validateNSPacket (IPv6NeighbourSolicitation *ns, IPv6ControlInfo *nsCtrlInfo) |
| virtual void | processNSForTentativeAddress (IPv6NeighbourSolicitation *ns, IPv6ControlInfo *ctrlInfo) |
| virtual void | processNSForNonTentativeAddress (IPv6NeighbourSolicitation *ns, IPv6ControlInfo *ctrlInfo, InterfaceEntry *ie) |
| virtual void | processNSWithSpecifiedSrcAddr (IPv6NeighbourSolicitation *ns, IPv6ControlInfo *ctrlInfo, InterfaceEntry *ie) |
| virtual void | sendSolicitedNA (IPv6NeighbourSolicitation *ns, IPv6ControlInfo *nsCtrlInfo, InterfaceEntry *ie) |
| virtual void | sendUnsolicitedNA (InterfaceEntry *ie) |
| virtual void | processNAPacket (IPv6NeighbourAdvertisement *na, IPv6ControlInfo *naCtrlInfo) |
| virtual bool | validateNAPacket (IPv6NeighbourAdvertisement *na, IPv6ControlInfo *naCtrlInfo) |
| virtual void | processNAForIncompleteNCEState (IPv6NeighbourAdvertisement *na, IPv6NeighbourCache::Neighbour *nce) |
| virtual void | processNAForOtherNCEStates (IPv6NeighbourAdvertisement *na, IPv6NeighbourCache::Neighbour *nce) |
| virtual IPv6Redirect * | createAndSendRedirectPacket (InterfaceEntry *ie) |
| virtual void | processRedirectPacket (IPv6Redirect *redirect, IPv6ControlInfo *ctrlInfo) |
Protected Attributes | |
| cQueue | pendingQueue |
| IInterfaceTable * | ift |
| RoutingTable6 * | rt6 |
| ICMPv6 * | icmpv6 |
| IPv6NeighbourCache | neighbourCache |
| RATimerList | raTimerList |
| DADList | dadList |
| RDList | rdList |
| AdvIfList | advIfList |
Copyright (C) 2005 Andras Varga Copyright (C) 2005 Wei Yang, Ng
This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with this program; if not, see <http://www.gnu.org/licenses/>. Implements RFC 2461 Neighbor Discovery for IPv6.
Definition at line 44 of file IPv6NeighbourDiscovery.h.
typedef std::set<AdvIfEntry*> IPv6NeighbourDiscovery::AdvIfList [protected] |
Definition at line 121 of file IPv6NeighbourDiscovery.h.
typedef std::set<DADEntry*> IPv6NeighbourDiscovery::DADList [protected] |
Definition at line 104 of file IPv6NeighbourDiscovery.h.
Definition at line 48 of file IPv6NeighbourDiscovery.h.
| typedef std::vector<cMessage*> IPv6NeighbourDiscovery::MsgPtrVector |
Definition at line 47 of file IPv6NeighbourDiscovery.h.
Definition at line 49 of file IPv6NeighbourDiscovery.h.
typedef std::set<cMessage*> IPv6NeighbourDiscovery::RATimerList [protected] |
Definition at line 94 of file IPv6NeighbourDiscovery.h.
typedef std::set<RDEntry*> IPv6NeighbourDiscovery::RDList [protected] |
Definition at line 112 of file IPv6NeighbourDiscovery.h.
| IPv6NeighbourDiscovery::IPv6NeighbourDiscovery | ( | ) |
Definition at line 34 of file IPv6NeighbourDiscovery.cc.
{
}
| IPv6NeighbourDiscovery::~IPv6NeighbourDiscovery | ( | ) | [virtual] |
Definition at line 38 of file IPv6NeighbourDiscovery.cc.
{
// FIXME delete the following data structures, cancelAndDelete timers in them etc.
// Deleting the data structures my become unnecessary if the lists store the
// structs themselves and not pointers.
// RATimerList raTimerList;
// DADList dadList;
// RDList rdList;
// AdvIfList advIfList;
}
| void IPv6NeighbourDiscovery::assignLinkLocalAddress | ( | cMessage * | timerMsg | ) | [protected, virtual] |
as it is not possbile to explicitly define RFC 2462. ND is the next best place to do this.
RFC 2462-IPv6 Stateless Address Autoconfiguration: Section 1 The autoconfiguration process specified in this document applies only to hosts and not routers. Since host autoconfiguration uses information advertised by routers, routers will need to be configured by some other means. However, it is expected that routers will generate link-local addresses using the mechanism described in this document. In addition, routers are expected to successfully pass the Duplicate Address Detection procedure described in this document on all addresses prior to assigning them to an interface.
Definition at line 730 of file IPv6NeighbourDiscovery.cc.
Referenced by handleMessage().
{
//Node has booted up. Start assigning a link-local address for each
//interface in this node.
for (int i=0; i < ift->getNumInterfaces(); i++)
{
InterfaceEntry *ie = ift->getInterface(i);
//Skip the loopback interface.
if (ie->isLoopback()) continue;
IPv6Address linkLocalAddr = ie->ipv6Data()->getLinkLocalAddress();
if (linkLocalAddr.isUnspecified())
{
//if no link local address exists for this interface, we assign one to it.
EV << "No link local address exists. Forming one" << endl;
linkLocalAddr = IPv6Address().formLinkLocalAddress(ie->getInterfaceToken());
ie->ipv6Data()->assignAddress(linkLocalAddr, true, 0, 0);
}
//Before we can use this address, we MUST initiate DAD first.
initiateDAD(linkLocalAddr, ie);
}
delete timerMsg;
}
| void IPv6NeighbourDiscovery::cancelRouterDiscovery | ( | InterfaceEntry * | ie | ) | [protected, virtual] |
RFC 2461: Section 6.3.7 4th paragraph Once the host sends a Router Solicitation, and receives a valid Router Advertisement with a non-zero Router Lifetime, the host MUST desist from sending additional solicitations on that interface,
Cancel Router Discovery on the Interface where a RA was received with the given Interface Entry.
Definition at line 889 of file IPv6NeighbourDiscovery.cc.
Referenced by processRAPacket().
{
//Next we retrieve the rdEntry with the Interface Entry.
RDEntry *rdEntry = fetchRDEntry(ie);
if (rdEntry != NULL)
{
EV << "rdEntry is not NULL, RD cancelled!" << endl;
cancelEvent(rdEntry->timeoutMsg);
rdList.erase(rdEntry);
delete rdEntry;
}
else
EV << "rdEntry is NULL, not cancelling RD!" << endl;
}
| IPv6NeighbourSolicitation * IPv6NeighbourDiscovery::createAndSendNSPacket | ( | const IPv6Address & | nsTargetAddr, | |
| const IPv6Address & | dgDestAddr, | |||
| const IPv6Address & | dgSrcAddr, | |||
| InterfaceEntry * | ie | |||
| ) | [protected, virtual] |
Definition at line 1566 of file IPv6NeighbourDiscovery.cc.
Referenced by initiateAddressResolution(), initiateDAD(), processARTimeout(), processDADTimeout(), and processNUDTimeout().
{
MACAddress myMacAddr = ie->getMacAddress();
//Construct a Neighbour Solicitation message
IPv6NeighbourSolicitation *ns = new IPv6NeighbourSolicitation("NSpacket");
ns->setType(ICMPv6_NEIGHBOUR_SOL);
//Neighbour Solicitation Specific Information
ns->setTargetAddress(nsTargetAddr);
/*If the solicitation is being sent to a solicited-node multicast
address, the sender MUST include its link-layer address (if it has
one) as a Source Link-Layer Address option.*/
if (dgDestAddr.matches(IPv6Address("FF02::1:FF00:0"),104) && // FIXME what's this? make constant...
!dgSrcAddr.isUnspecified())
ns->setSourceLinkLayerAddress(myMacAddr);
sendPacketToIPv6Module(ns, dgDestAddr, dgSrcAddr, ie->getInterfaceId());
return ns;
}
| IPv6RouterAdvertisement * IPv6NeighbourDiscovery::createAndSendRAPacket | ( | const IPv6Address & | destAddr, | |
| InterfaceEntry * | ie | |||
| ) | [protected, virtual] |
Definition at line 1044 of file IPv6NeighbourDiscovery.cc.
Referenced by sendPeriodicRA(), and sendSolicitedRA().
{
EV << "Create and send RA invoked!\n";
//Must use link-local addr. See: RFC2461 Section 6.1.2
IPv6Address sourceAddr = ie->ipv6Data()->getLinkLocalAddress();
//This operation includes all options, regardless whether it is solicited or unsolicited.
if (ie->ipv6Data()->getAdvSendAdvertisements()) //if this is an advertising interface
{
//Construct a Router Advertisment message
IPv6RouterAdvertisement *ra = new IPv6RouterAdvertisement("RApacket");
ra->setType(ICMPv6_ROUTER_AD);
//RFC 2461: Section 6.2.3 Router Advertisment Message Content
/*A router sends periodic as well as solicited Router Advertisements out
its advertising interfaces. Outgoing Router Advertisements are filled
with the following values consistent with the message format given in
Section 4.2:*/
//- In the Router Lifetime field: the interface's configured AdvDefaultLifetime.
ra->setRouterLifetime(SIMTIME_DBL(ie->ipv6Data()->getAdvDefaultLifetime()));
//- In the M and O flags: the interface's configured AdvManagedFlag and
//AdvOtherConfigFlag, respectively. See [ADDRCONF].
ra->setManagedAddrConfFlag(ie->ipv6Data()->getAdvManagedFlag());
ra->setOtherStatefulConfFlag(ie->ipv6Data()->getAdvOtherConfigFlag());
//- In the Cur Hop Limit field: the interface's configured CurHopLimit.
ra->setCurHopLimit(ie->ipv6Data()->getAdvCurHopLimit());
//- In the Reachable Time field: the interface's configured AdvReachableTime.
ra->setReachableTime(ie->ipv6Data()->getAdvReachableTime());
//- In the Retrans Timer field: the interface's configured AdvRetransTimer.
ra->setRetransTimer(ie->ipv6Data()->getAdvRetransTimer());
//- In the options:
/*o Source Link-Layer Address option: link-layer address of the sending
interface. (Assumption: We always send this)*/
ra->setSourceLinkLayerAddress(ie->getMacAddress());
ra->setMTU(ie->ipv6Data()->getAdvLinkMTU());
//Add all Advertising Prefixes to the RA
int numAdvPrefixes = ie->ipv6Data()->getNumAdvPrefixes();
EV << "Number of Adv Prefixes: " << numAdvPrefixes << endl;
ra->setPrefixInformationArraySize(numAdvPrefixes);
for (int i = 0; i < numAdvPrefixes; i++)
{
IPv6InterfaceData::AdvPrefix advPrefix = ie->ipv6Data()->getAdvPrefix(i);
IPv6NDPrefixInformation prefixInfo;
prefixInfo.setPrefix(advPrefix.prefix);
prefixInfo.setPrefixLength(advPrefix.prefixLength);
//- In the "on-link" flag: the entry's AdvOnLinkFlag.
prefixInfo.setOnlinkFlag(advPrefix.advOnLinkFlag);
//- In the Valid Lifetime field: the entry's AdvValidLifetime.
prefixInfo.setValidLifetime(SIMTIME_DBL(advPrefix.advValidLifetime));
//- In the "Autonomous address configuration" flag: the entry's
//AdvAutonomousFlag.
prefixInfo.setAutoAddressConfFlag(advPrefix.advAutonomousFlag);
//- In the Preferred Lifetime field: the entry's AdvPreferredLifetime.
prefixInfo.setPreferredLifetime(SIMTIME_DBL(advPrefix.advPreferredLifetime));
//Now we pop the prefix info into the RA.
ra->setPrefixInformation(i, prefixInfo);
}
sendPacketToIPv6Module(ra, destAddr, sourceAddr, ie->getInterfaceId());
return ra;
}
return NULL; //XXX is this OK?
}
| IPv6Redirect * IPv6NeighbourDiscovery::createAndSendRedirectPacket | ( | InterfaceEntry * | ie | ) | [protected, virtual] |
Definition at line 2125 of file IPv6NeighbourDiscovery.cc.
{
//Construct a Redirect message
IPv6Redirect *redirect = new IPv6Redirect("redirectMsg");
redirect->setType(ICMPv6_REDIRECT);
//Redirect Message Specific Information
//redirect->setTargetAddress();
//redirect->setDestinationAddress();
//Possible Option
//redirect->setTargetLinkLayerAddress();
return redirect;
}
| IPv6RouterSolicitation * IPv6NeighbourDiscovery::createAndSendRSPacket | ( | InterfaceEntry * | ie | ) | [protected, virtual] |
Definition at line 828 of file IPv6NeighbourDiscovery.cc.
Referenced by initiateRouterDiscovery(), and processRDTimeout().
{
ASSERT(ie->ipv6Data()->getAdvSendAdvertisements() == false);
//RFC 2461: Section 6.3.7 Sending Router Solicitations
//A host sends Router Solicitations to the All-Routers multicast address. The
//IP source address is set to either one of the interface's unicast addresses
//or the unspecified address.
IPv6Address myIPv6Address = ie->ipv6Data()->getPreferredAddress();
if (myIPv6Address.isUnspecified())
myIPv6Address = ie->ipv6Data()->getLinkLocalAddress();//so we use the link local address instead
if (ie->ipv6Data()->isTentativeAddress(myIPv6Address))
myIPv6Address = IPv6Address::UNSPECIFIED_ADDRESS;//set my IPv6 address to unspecified.
IPv6Address destAddr = IPv6Address::ALL_ROUTERS_2;//all_routers multicast
IPv6RouterSolicitation *rs = new IPv6RouterSolicitation("RSpacket");
rs->setType(ICMPv6_ROUTER_SOL);
//The Source Link-Layer Address option SHOULD be set to the host's link-layer
//address, if the IP source address is not the unspecified address.
if (!myIPv6Address.isUnspecified())
rs->setSourceLinkLayerAddress(ie->getMacAddress());
//Construct a Router Solicitation message
sendPacketToIPv6Module(rs, destAddr, myIPv6Address, ie->getInterfaceId());
return rs;
}
| void IPv6NeighbourDiscovery::createRATimer | ( | InterfaceEntry * | ie | ) | [protected, virtual] |
Create a timer for the given interface entry that sends periodic Router Advertisements
Definition at line 1440 of file IPv6NeighbourDiscovery.cc.
Referenced by initialize().
{
cMessage *msg = new cMessage("sendPeriodicRA", MK_SEND_PERIODIC_RTRADV);
msg->setContextPointer(ie);
AdvIfEntry *advIfEntry = new AdvIfEntry();
advIfEntry->interfaceId = ie->getInterfaceId();
advIfEntry->numRASent = 0;
simtime_t interval = uniform(ie->ipv6Data()->getMinRtrAdvInterval(), ie->ipv6Data()->getMaxRtrAdvInterval());
advIfEntry->raTimeoutMsg = msg;
simtime_t nextScheduledTime = simTime() + interval;
advIfEntry->nextScheduledRATime = nextScheduledTime;
advIfList.insert(advIfEntry);
EV << "Interval: " << interval << endl;
EV << "Next scheduled time: " << nextScheduledTime << endl;
//now we schedule the msg for whatever time that was derived
scheduleAt(nextScheduledTime, msg);
}
| IPv6Address IPv6NeighbourDiscovery::determineNextHop | ( | const IPv6Address & | destAddr, | |
| int & | outIfID | |||
| ) | [protected, virtual] |
This function accepts the datagram's destination address and attempts to determine the destination's next hop address and interface ID by: (1) looking up the destination cache, (2)looking up the routing table, or (3) selecting a default router. It then updates the destination cache. If no default router can be selected than we assume the destination address to be onlink and simply return any available interface.
Definition at line 381 of file IPv6NeighbourDiscovery.cc.
Referenced by processIPv6Datagram().
{
IPv6Address nextHopAddr;
//RFC 2461 Section 5.2
//Next-hop determination for a given unicast destination operates as follows.
//The sender performs a longest prefix match against the Prefix List to
//determine whether the packet's destination is on- or off-link.
EV << "Find out if supplied dest addr is on-link or off-link.\n";
const IPv6Route *route = rt6->doLongestPrefixMatch(destAddr);
if (route != NULL)
{
//If the destination is on-link, the next-hop address is the same as the
//packet's destination address.
if (route->getNextHop().isUnspecified())
{
EV << "Dest is on-link, next-hop addr is same as dest addr.\n";
outIfID = route->getInterfaceId();
nextHopAddr = destAddr;
}
else
{
EV << "A next-hop address was found with the route, dest is off-link\n";
EV << "Assume next-hop address as the selected default router.\n";
outIfID = route->getInterfaceId();
nextHopAddr = route->getNextHop();
}
}
else
{
//Otherwise, the sender selects a router from the Default Router List
//(following the rules described in Section 6.3.6).
EV << "No routes were found, Dest addr is off-link.\n";
nextHopAddr = selectDefaultRouter(outIfID);
if (outIfID == -1) EV << "No Default Routers were found.";
else EV << "Default router found.\n";
}
/*the results of next-hop determination computations are saved in the Destination
Cache (which also contains updates learned from Redirect messages).*/
rt6->updateDestCache(destAddr, nextHopAddr, outIfID);
return nextHopAddr;
}
| void IPv6NeighbourDiscovery::dropQueuedPacketsAwaitingAR | ( | Neighbour * | nce | ) | [protected, virtual] |
Drops specific queued packets for a specific NCE AR-timeout. TODO: Not implemented yet!
Definition at line 670 of file IPv6NeighbourDiscovery.cc.
Referenced by processARTimeout().
{
const Key *nceKey = nce->nceKey;
//RFC 2461: Section 7.2.2
/*If no Neighbor Advertisement is received after MAX_MULTICAST_SOLICIT
solicitations, address resolution has failed. The sender MUST return ICMP
destination unreachable indications with code 3 (Address Unreachable) for
each packet queued awaiting address resolution.*/
MsgPtrVector pendingPackets = nce->pendingPackets;
EV << "Pending Packets empty:" << pendingPackets.empty() << endl;
while (!pendingPackets.empty())
{
MsgPtrVector::iterator i = pendingPackets.begin();
cMessage *msg = (*i);
IPv6Datagram *ipv6Msg = (IPv6Datagram *)msg;
//Assume msg is the packet itself. I need the datagram's source addr.
//The datagram's src addr will be the destination of the unreachable msg.
EV << "Sending ICMP unreachable destination." << endl;
pendingPackets.erase(i);
pendingQueue.remove(msg);
icmpv6->sendErrorMessage(ipv6Msg, ICMPv6_DESTINATION_UNREACHABLE, ADDRESS_UNREACHABLE);
}
//RFC 2461: Section 7.3.3
/*If address resolution fails, the entry SHOULD be deleted, so that subsequent
traffic to that neighbor invokes the next-hop determination procedure again.*/
EV << "Removing neighbour cache entry" << endl;
neighbourCache.remove(nceKey->address, nceKey->interfaceID);
}
| IPv6NeighbourDiscovery::AdvIfEntry * IPv6NeighbourDiscovery::fetchAdvIfEntry | ( | InterfaceEntry * | ie | ) | [protected, virtual] |
Definition at line 260 of file IPv6NeighbourDiscovery.cc.
Referenced by processRSPacket(), and sendPeriodicRA().
{
for (AdvIfList::iterator it=advIfList.begin(); it!=advIfList.end(); it++)
{
AdvIfEntry *advIfEntry = (*it);
if (advIfEntry->interfaceId == ie->getInterfaceId())
{
return advIfEntry;
}
}
return NULL;
}
| IPv6NeighbourDiscovery::RDEntry * IPv6NeighbourDiscovery::fetchRDEntry | ( | InterfaceEntry * | ie | ) | [protected, virtual] |
Definition at line 273 of file IPv6NeighbourDiscovery.cc.
Referenced by cancelRouterDiscovery(), and processRDTimeout().
{
for (RDList::iterator it=rdList.begin(); it!=rdList.end(); it++)
{
RDEntry *rdEntry = (*it);
if (rdEntry->interfaceId == ie->getInterfaceId())
{
return rdEntry;
}
}
return NULL;
}
| void IPv6NeighbourDiscovery::finish | ( | ) | [protected, virtual] |
Definition at line 181 of file IPv6NeighbourDiscovery.cc.
{
}
| void IPv6NeighbourDiscovery::handleMessage | ( | cMessage * | msg | ) | [protected, virtual] |
Definition at line 81 of file IPv6NeighbourDiscovery.cc.
{
if (msg->isSelfMessage())
{
EV << "Self message received!\n";
if (msg->getKind()==MK_SEND_PERIODIC_RTRADV)
{
EV << "Sending periodic RA\n";
sendPeriodicRA(msg);
}
else if (msg->getKind()==MK_SEND_SOL_RTRADV)
{
EV << "Sending solicited RA\n";
sendSolicitedRA(msg);
}
else if (msg->getKind()==MK_ASSIGN_LINKLOCAL_ADDRESS)
{
EV << "Assigning Link Local Address\n";
assignLinkLocalAddress(msg);
}
else if (msg->getKind()==MK_DAD_TIMEOUT)
{
EV << "DAD Timeout message received\n";
processDADTimeout(msg);
}
else if (msg->getKind()==MK_RD_TIMEOUT)
{
EV << "Router Discovery message received\n";
processRDTimeout(msg);
}
else if (msg->getKind()==MK_INITIATE_RTRDIS)
{
EV << "initiate router discovery.\n";
initiateRouterDiscovery(msg);
}
else if (msg->getKind()==MK_NUD_TIMEOUT)
{
EV << "NUD Timeout message received\n";
processNUDTimeout(msg);
}
else if (msg->getKind()==MK_AR_TIMEOUT)
{
EV << "Address Resolution Timeout message received\n";
processARTimeout(msg);
}
else
error("Unrecognized Timer");//stops sim w/ error msg.
}
else if (dynamic_cast<ICMPv6Message *>(msg))
{
//This information will serve as input parameters to various processors.
IPv6ControlInfo *ctrlInfo
= check_and_cast<IPv6ControlInfo*>(msg->removeControlInfo());
ICMPv6Message *ndMsg = (ICMPv6Message *)msg;
processNDMessage(ndMsg, ctrlInfo);
}
else if (dynamic_cast<IPv6Datagram *>(msg))// not ND message
{
IPv6Datagram *datagram = (IPv6Datagram *)msg;
processIPv6Datagram(datagram);
}
else
error("Unknown message type received.\n");
}
| void IPv6NeighbourDiscovery::initialize | ( | int | stage | ) | [protected, virtual] |
Definition at line 49 of file IPv6NeighbourDiscovery.cc.
{
// We have to wait until the 3rd stage (stage 2) with scheduling messages,
// because interface registration and IPv6 configuration takes places
// in the first two stages.
if (stage==3)
{
ift = InterfaceTableAccess().get();
rt6 = RoutingTable6Access().get();
icmpv6 = ICMPv6Access().get();
pendingQueue.setName("pendingQueue");
for (int i=0; i < ift->getNumInterfaces(); i++)
{
InterfaceEntry *ie = ift->getInterface(i);
if (ie->ipv6Data()->getAdvSendAdvertisements() && !(ie->isLoopback()))
{
createRATimer(ie);
}
}
//This simulates random node bootup time. Link local address assignment
//takes place during this time.
cMessage *msg = new cMessage("assignLinkLocalAddr", MK_ASSIGN_LINKLOCAL_ADDRESS);
//We want routers to boot up faster!
if (rt6->isRouter())
scheduleAt(uniform(0,0.3), msg);//Random Router bootup time
else
scheduleAt(uniform(0.4,1), msg);//Random Host bootup time
}
}
| void IPv6NeighbourDiscovery::initiateAddressResolution | ( | const IPv6Address & | dgSrcAddr, | |
| Neighbour * | nce | |||
| ) | [protected, virtual] |
This method attempts to resolve the given neighbour's link-layer address. The source address of the packet prompting address resolution is also given in order to decide the source address of the NS to be sent. nceKey stores 2 pieces of information (Neighbour address and Interface ID) which is needed for addr resolution and access to the corresponding nce.
Definition at line 593 of file IPv6NeighbourDiscovery.cc.
Referenced by processIPv6Datagram().
{
const Key *nceKey = nce->nceKey;
InterfaceEntry *ie = ift->getInterfaceById(nceKey->interfaceID);
IPv6Address neighbourAddr = nceKey->address;
int ifID = nceKey->interfaceID;
//RFC2461: Section 7.2.2
//When a node has a unicast packet to send to a neighbor, but does not
//know the neighbor's link-layer address, it performs address
//resolution. For multicast-capable interfaces this entails creating a
//Neighbor Cache entry in the INCOMPLETE state(already created if not done yet)
//WEI-If entry already exists, we still have to ensure that its state is INCOMPLETE.
nce->reachabilityState = IPv6NeighbourCache::INCOMPLETE;
//and transmitting a Neighbor Solicitation message targeted at the
//neighbor. The solicitation is sent to the solicited-node multicast
//address "corresponding to"(or "derived from") the target address.
//(in this case, the target address is the address we are trying to resolve)
EV << "Preparing to send NS to solicited-node multicast group\n";
EV << "on the next hop interface\n";
IPv6Address nsDestAddr = neighbourAddr.formSolicitedNodeMulticastAddress();//for NS datagram
IPv6Address nsTargetAddr = neighbourAddr;//for the field within the NS
IPv6Address nsSrcAddr;
/*If the source address of the packet prompting the solicitation is the
same as one of the addresses assigned to the outgoing interface,*/
if (ie->ipv6Data()->hasAddress(dgSrcAddr))
/*that address SHOULD be placed in the IP Source Address of the outgoing
solicitation.*/
nsSrcAddr = dgSrcAddr;
else
/*Otherwise, any one of the addresses assigned to the interface
should be used.*/
nsSrcAddr = ie->ipv6Data()->getPreferredAddress();
ASSERT(ifID != -1);
//Sending NS on specified interface.
createAndSendNSPacket(nsTargetAddr, nsDestAddr, nsSrcAddr, ie);
nce->numOfARNSSent = 1;
nce->nsSrcAddr = nsSrcAddr;
/*While awaiting a response, the sender SHOULD retransmit Neighbor Solicitation
messages approximately every RetransTimer milliseconds, even in the absence
of additional traffic to the neighbor. Retransmissions MUST be rate-limited
to at most one solicitation per neighbor every RetransTimer milliseconds.*/
cMessage *msg = new cMessage("arTimeout", MK_AR_TIMEOUT);//AR msg timer
nce->arTimer = msg;
msg->setContextPointer(nce);
scheduleAt(simTime()+ie->ipv6Data()->_getRetransTimer(), msg);
}
| void IPv6NeighbourDiscovery::initiateDAD | ( | const IPv6Address & | tentativeAddr, | |
| InterfaceEntry * | ie | |||
| ) | [protected, virtual] |
Initiating DAD means to send off a Neighbour Solicitation with its target address set as this node's tentative link-local address.
Definition at line 756 of file IPv6NeighbourDiscovery.cc.
Referenced by assignLinkLocalAddress().
{
DADEntry *dadEntry = new DADEntry();
dadEntry->interfaceId = ie->getInterfaceId();
dadEntry->address = tentativeAddr;
dadEntry->numNSSent = 0;
dadList.insert(dadEntry);
/*
RFC2462: Section 5.4.2
To check an address, a node sends DupAddrDetectTransmits Neighbor
Solicitations, each separated by RetransTimer milliseconds. The
solicitation's Target Address is set to the address being checked,
the IP source is set to the unspecified address and the IP
destination is set to the solicited-node multicast address of the
target address.*/
IPv6Address destAddr = tentativeAddr.formSolicitedNodeMulticastAddress();
//Send a NS
createAndSendNSPacket(tentativeAddr, destAddr,
IPv6Address::UNSPECIFIED_ADDRESS, ie);
dadEntry->numNSSent++;
cMessage *msg = new cMessage("dadTimeout", MK_DAD_TIMEOUT);
msg->setContextPointer(dadEntry);
scheduleAt(simTime()+ie->ipv6Data()->getRetransTimer(), msg);
}
| void IPv6NeighbourDiscovery::initiateNeighbourUnreachabilityDetection | ( | Neighbour * | neighbour | ) | [protected, virtual] |
Definition at line 430 of file IPv6NeighbourDiscovery.cc.
Referenced by processIPv6Datagram(), and resolveNeighbour().
{
ASSERT(nce->reachabilityState==IPv6NeighbourCache::STALE);
const Key *nceKey = nce->nceKey;
EV << "Initiating Neighbour Unreachability Detection";
InterfaceEntry *ie = ift->getInterfaceById(nceKey->interfaceID);
EV << "Setting NCE state to DELAY.\n";
/*The first time a node sends a packet to a neighbor whose entry is
STALE, the sender changes the state to DELAY*/
nce->reachabilityState = IPv6NeighbourCache::DELAY;
/*and sets a timer to expire in DELAY_FIRST_PROBE_TIME seconds.*/
cMessage *msg = new cMessage("NUDTimeout", MK_NUD_TIMEOUT);
msg->setContextPointer(nce);
nce->nudTimeoutEvent = msg;
scheduleAt(simTime()+ie->ipv6Data()->_getDelayFirstProbeTime(), msg);
}
| void IPv6NeighbourDiscovery::initiateRouterDiscovery | ( | cMessage * | msg | ) | [protected, virtual] |
Definition at line 854 of file IPv6NeighbourDiscovery.cc.
Referenced by handleMessage().
{
EV << "Initiating Router Discovery" << endl;
InterfaceEntry *ie = (InterfaceEntry *)msg->getContextPointer();
delete msg;
//RFC2461: Section 6.3.7
/*When an interface becomes enabled, a host may be unwilling to wait for the
next unsolicited Router Advertisement to locate default routers or learn
prefixes. To obtain Router Advertisements quickly, a host SHOULD transmit up
to MAX_RTR_SOLICITATIONS Router Solicitation messages each separated by at
least RTR_SOLICITATION_INTERVAL seconds.(FIXME:Therefore this should be invoked
at the beginning of the simulation-WEI)*/
RDEntry *rdEntry = new RDEntry();
rdEntry->interfaceId = ie->getInterfaceId();
rdEntry->numRSSent = 0;
createAndSendRSPacket(ie);
rdEntry->numRSSent++;
//Create and schedule a message for retransmission to this module
cMessage *rdTimeoutMsg = new cMessage("processRDTimeout", MK_RD_TIMEOUT);
rdTimeoutMsg->setContextPointer(ie);
rdEntry->timeoutMsg = rdTimeoutMsg;
rdList.insert(rdEntry);
/*Before a host sends an initial solicitation, it SHOULD delay the
transmission for a random amount of time between 0 and
MAX_RTR_SOLICITATION_DELAY. This serves to alleviate congestion when
many hosts start up on a link at the same time, such as might happen
after recovery from a power failure. If a host has already performed
a random delay since the interface became (re)enabled (e.g., as part
of Duplicate Address Detection [ADDRCONF]) there is no need to delay
again before sending the first Router Solicitation message.*/
//simtime_t rndInterval = uniform(0, ie->ipv6Data()->_getMaxRtrSolicitationDelay());
scheduleAt(simTime()+ie->ipv6Data()->_getRtrSolicitationInterval(), rdTimeoutMsg);
}
| virtual int IPv6NeighbourDiscovery::numInitStages | ( | ) | const [inline, protected, virtual] |
Definition at line 134 of file IPv6NeighbourDiscovery.h.
{return 4;}
| void IPv6NeighbourDiscovery::processARTimeout | ( | cMessage * | arTimeoutMsg | ) | [protected, virtual] |
Resends a NS packet to the address intended for address resolution. TODO: Not implemented yet!
Definition at line 646 of file IPv6NeighbourDiscovery.cc.
Referenced by handleMessage().
{
//AR timeouts are cancelled when a valid solicited NA is received.
Neighbour *nce = (Neighbour *)arTimeoutMsg->getContextPointer();
const Key *nceKey = nce->nceKey;
IPv6Address nsTargetAddr = nceKey->address;
InterfaceEntry *ie = ift->getInterfaceById(nceKey->interfaceID);
EV << "Num Of NS Sent:" << nce->numOfARNSSent << endl;
EV << "Max Multicast Solicitation:" << ie->ipv6Data()->_getMaxMulticastSolicit() << endl;
if (nce->numOfARNSSent < ie->ipv6Data()->_getMaxMulticastSolicit())
{
EV << "Sending another Address Resolution NS message" << endl;
IPv6Address nsDestAddr = nsTargetAddr.formSolicitedNodeMulticastAddress();
createAndSendNSPacket(nsTargetAddr, nsDestAddr, nce->nsSrcAddr, ie);
nce->numOfARNSSent++;
scheduleAt(simTime()+ie->ipv6Data()->_getRetransTimer(), arTimeoutMsg);
return;
}
EV << "Address Resolution has failed." << endl;
dropQueuedPacketsAwaitingAR(nce);
EV << "Deleting AR timeout msg\n";
delete arTimeoutMsg;
}
| void IPv6NeighbourDiscovery::processDADTimeout | ( | cMessage * | msg | ) | [protected, virtual] |
Sends a scheduled DAD NS packet. If number of sends is equals or more than dupAddrDetectTransmits, then permantly assign target link local address as permanent address for given interface entry.
Definition at line 783 of file IPv6NeighbourDiscovery.cc.
Referenced by handleMessage().
{
DADEntry *dadEntry = (DADEntry *)msg->getContextPointer();
InterfaceEntry *ie = (InterfaceEntry *)ift->getInterfaceById(dadEntry->interfaceId);
IPv6Address tentativeAddr = dadEntry->address;
//Here, we need to check how many DAD messages for the interface entry were
//sent vs. DupAddrDetectTransmits
EV << "numOfDADMessagesSent is: " << dadEntry->numNSSent << endl;
EV << "dupAddrDetectTrans is: " << ie->ipv6Data()->dupAddrDetectTransmits() << endl;
if (dadEntry->numNSSent < ie->ipv6Data()->dupAddrDetectTransmits())
{
bubble("Sending another DAD NS message.");
IPv6Address destAddr = tentativeAddr.formSolicitedNodeMulticastAddress();
createAndSendNSPacket(dadEntry->address, destAddr, IPv6Address::UNSPECIFIED_ADDRESS, ie);
dadEntry->numNSSent++;
//Reuse the received msg
scheduleAt(simTime()+ie->ipv6Data()->getRetransTimer(), msg);
}
else
{
bubble("Max number of DAD messages for interface sent. Address is unique.");
ie->ipv6Data()->permanentlyAssign(tentativeAddr);
dadList.erase(dadEntry);
EV << "delete dadEntry and msg\n";
delete dadEntry;
delete msg;
/*RFC 2461: Section 6.3.7 2nd Paragraph
Before a host sends an initial solicitation, it SHOULD delay the
transmission for a random amount of time between 0 and
MAX_RTR_SOLICITATION_DELAY. This serves to alleviate congestion when
many hosts start up on a link at the same time, such as might happen
after recovery from a power failure.*/
//TODO: Placing these operations here means fast router solicitation is
//not adopted. Will relocate.
if (ie->ipv6Data()->getAdvSendAdvertisements() == false)
{
EV << "creating router discovery message timer\n";
cMessage *rtrDisMsg = new cMessage("initiateRTRDIS",MK_INITIATE_RTRDIS);
rtrDisMsg->setContextPointer(ie);
simtime_t interval = uniform(0, ie->ipv6Data()->_getMaxRtrSolicitationDelay()); // random delay
scheduleAt(simTime()+interval, rtrDisMsg);
}
}
}
| void IPv6NeighbourDiscovery::processIPv6Datagram | ( | IPv6Datagram * | datagram | ) | [protected, virtual] |
Definition at line 185 of file IPv6NeighbourDiscovery.cc.
Referenced by handleMessage().
{
EV << "Packet " << msg << " arrived from IPv6 module.\n";
int nextHopIfID;
EV << "Determining Next Hop" << endl;
IPv6Address nextHopAddr = determineNextHop(msg->getDestAddress(), nextHopIfID);
if (nextHopIfID == -1)
{
//draft-ietf-ipv6-2461bis-04 has omitted on-link assumption.
//draft-ietf-v6ops-onlinkassumption-03 explains why.
icmpv6->sendErrorMessage(msg, ICMPv6_DESTINATION_UNREACHABLE, NO_ROUTE_TO_DEST);
return;
}
EV << "Next Hop Address is: " << nextHopAddr << " on interface: " << nextHopIfID << endl;
//RFC2461: Section 5.2 Conceptual Sending Algorithm
//Once the IP address of the next-hop node is known, the sender examines the
//Neighbor Cache for link-layer information about that neighbor.
Neighbour *nce = neighbourCache.lookup(nextHopAddr, nextHopIfID);
if (nce==NULL)
{
//If no entry exists,
EV << "No Entry exists in the Neighbour Cache.\n";
//the sender creates one, sets its state to INCOMPLETE,
EV << "Creating an INCOMPLETE entry in the neighbour cache.\n";
nce = neighbourCache.addNeighbour(nextHopAddr, nextHopIfID);
//initiates Address Resolution,
EV << "Initiating Address Resolution for:" << nextHopAddr
<< " on Interface:" << nextHopIfID << endl;
initiateAddressResolution(msg->getSrcAddress(), nce);
//and then queues the data packet pending completion of address resolution.
EV << "Add packet to entry's queue until Address Resolution is complete.\n";
nce->pendingPackets.push_back(msg);
pendingQueue.insert(msg);
}
else if (nce->reachabilityState == IPv6NeighbourCache::INCOMPLETE)
{
EV << "Reachability State is INCOMPLETE.Address Resolution already initiated.\n";
bubble("Packet added to queue until Address Resolution is complete.");
nce->pendingPackets.push_back(msg);
pendingQueue.insert(msg);
}
else if (nce->macAddress.isUnspecified())
{
EV << "NCE's MAC address is unspecified.\n";
EV << "Initiate Address Resolution and add packet to queue.\n";
initiateAddressResolution(msg->getSrcAddress(), nce);
nce->pendingPackets.push_back(msg);
pendingQueue.insert(msg);
}
else if (nce->reachabilityState == IPv6NeighbourCache::STALE)
{
EV << "Reachability State is STALE.\n";
send(msg,"ipv6Out");
initiateNeighbourUnreachabilityDetection(nce);
}
else if (nce->reachabilityState == IPv6NeighbourCache::REACHABLE)
{
EV << "Next hop is REACHABLE, sending packet to next-hop address.";
sendPacketToIPv6Module(msg, nextHopAddr, msg->getSrcAddress(), nextHopIfID);
}
else if (nce->reachabilityState == IPv6NeighbourCache::DELAY)//TODO: What if NCE is in PROBE state?
{
EV << "Next hop is in DELAY state, sending packet to next-hop address.";
sendPacketToIPv6Module(msg, nextHopAddr, msg->getSrcAddress(), nextHopIfID);
}
else
error("Unknown Neighbour cache entry state.");
}
| void IPv6NeighbourDiscovery::processNAForIncompleteNCEState | ( | IPv6NeighbourAdvertisement * | na, | |
| IPv6NeighbourCache::Neighbour * | nce | |||
| ) | [protected, virtual] |
Definition at line 1974 of file IPv6NeighbourDiscovery.cc.
Referenced by processNAPacket().
{
MACAddress naMacAddr = na->getTargetLinkLayerAddress();
bool naRouterFlag = na->getRouterFlag();
bool naSolicitedFlag = na->getSolicitedFlag();
const Key *nceKey = nce->nceKey;
InterfaceEntry *ie = ift->getInterfaceById(nceKey->interfaceID);
/*If the target's neighbour Cache entry is in the INCOMPLETE state when the
advertisement is received, one of two things happens.*/
if (naMacAddr.isUnspecified())
{
/*If the link layer has addresses and no Target Link-Layer address option
is included, the receiving node SHOULD silently discard the received
advertisement.*/
EV << "No MAC Address specified in NA. Ignoring NA\n";
return;
}
else
{
//Otherwise, the receiving node performs the following steps:
//- It records the link-layer address in the neighbour Cache entry.
EV << "ND is updating Neighbour Cache Entry.\n";
nce->macAddress = naMacAddr;
//- If the advertisement's Solicited flag is set, the state of the
// entry is set to REACHABLE, otherwise it is set to STALE.
if (naSolicitedFlag == true)
{
nce->reachabilityState = IPv6NeighbourCache::REACHABLE;
EV << "Reachability confirmed through successful Addr Resolution.\n";
nce->reachabilityExpires = simTime() + ie->ipv6Data()->_getReachableTime();
}
else
nce->reachabilityState = IPv6NeighbourCache::STALE;
//- It sets the IsRouter flag in the cache entry based on the Router
// flag in the received advertisement.
nce->isRouter = naRouterFlag;
//- It sends any packets queued for the neighbour awaiting address
// resolution.
sendQueuedPacketsToIPv6Module(nce);
cancelEvent(nce->arTimer);
}
}
| void IPv6NeighbourDiscovery::processNAForOtherNCEStates | ( | IPv6NeighbourAdvertisement * | na, | |
| IPv6NeighbourCache::Neighbour * | nce | |||
| ) | [protected, virtual] |
Definition at line 2022 of file IPv6NeighbourDiscovery.cc.
Referenced by processNAPacket().
{
bool naRouterFlag = na->getRouterFlag();
bool naSolicitedFlag = na->getSolicitedFlag();
bool naOverrideFlag = na->getOverrideFlag();
MACAddress naMacAddr = na->getTargetLinkLayerAddress();
const Key *nceKey = nce->nceKey;
InterfaceEntry *ie = ift->getInterfaceById(nceKey->interfaceID);
/*draft-ietf-ipv6-2461bis-04
Section 7.2.5: Receipt of Neighbour Advertisements
If the target's Neighbor Cache entry is in any state other than INCOMPLETE
when the advertisement is received, the following actions take place:*/
if (naOverrideFlag == false && !(naMacAddr.equals(nce->macAddress))
&& !(naMacAddr.isUnspecified()))
{
EV << "NA override is FALSE and NA MAC addr is different.\n";
//I. If the Override flag is clear and the supplied link-layer address
// differs from that in the cache, then one of two actions takes place:
//(Note: An unspecified MAC should not be compared with the NCE's mac!)
//a. If the state of the entry is REACHABLE,
if (nce->reachabilityState == IPv6NeighbourCache::REACHABLE)
{
EV << "NA mac is different. Change NCE state from REACHABLE to STALE\n";
//set it to STALE, but do not update the entry in any other way.
nce->reachabilityState = IPv6NeighbourCache::STALE;
}
else
//b. Otherwise, the received advertisement should be ignored and
//MUST NOT update the cache.
EV << "NCE is not in REACHABLE state. Ignore NA.\n";
}
else if (naOverrideFlag == true || naMacAddr.equals(nce->macAddress)
|| naMacAddr.isUnspecified())
{
EV << "NA override flag is TRUE. or Advertised MAC is same as NCE's. or"
<< " NA MAC is not specified.\n";
/*II. If the Override flag is set, or the supplied link-layer address
is the same as that in the cache, or no Target Link-layer address
option was supplied, the received advertisement MUST update the
Neighbor Cache entry as follows:*/
/*- The link-layer address in the Target Link-Layer Address option
MUST be inserted in the cache (if one is supplied and is
Different than the already recorded address).*/
if (!(naMacAddr.isUnspecified()) &&
!(naMacAddr.equals(nce->macAddress)))
{
EV << "Updating NCE's MAC addr with NA's.\n";
nce->macAddress = naMacAddr;
}
//- If the Solicited flag is set,
if (naSolicitedFlag == true)
{
EV << "Solicited Flag is TRUE. Set NCE state to REACHABLE.\n";
//the state of the entry MUST be set to REACHABLE.
nce->reachabilityState = IPv6NeighbourCache::REACHABLE;
//We have to cancel the NUD self timer message if there is one.
cMessage *msg = nce->nudTimeoutEvent;
if (msg != NULL)
{
EV << "NUD in progress. Cancelling NUD Timer\n";
bubble("Reachability Confirmed via NUD.");
nce->reachabilityExpires = simTime() + ie->ipv6Data()->_getReachableTime();
cancelEvent(msg);
delete msg;
}
}
else
{
//If the Solicited flag is zero
EV << "Solicited Flag is FALSE.\n";
//and the link layer address was updated with a different address
if (!(naMacAddr.equals(nce->macAddress)))
{
EV << "NA's MAC is different from NCE's.Set NCE state to STALE\n";
//the state MUST be set to STALE.
nce->reachabilityState = IPv6NeighbourCache::STALE;
}
else
//Otherwise, the entry's state remains unchanged.
EV << "NA's MAC is the same as NCE's. State remains unchanged.\n";
}
//(Next paragraph with explanation is omitted.-WEI)
/*- The IsRouter flag in the cache entry MUST be set based on the
Router flag in the received advertisement.*/
EV << "Updating NCE's router flag to " << naRouterFlag << endl;
nce->isRouter = naRouterFlag;
//TODO: To be implemented
/*In those cases where the IsRouter flag changes from TRUE to FALSE as a
result of this update, the node MUST remove that router from the Default
Router List and update the Destination Cache entries for all destinations
using that neighbor as a router as specified in Section 7.3.3. This is
needed to detect when a node that is used as a router stops forwarding
packets due to being configured as a host.*/
}
}
| void IPv6NeighbourDiscovery::processNAPacket | ( | IPv6NeighbourAdvertisement * | na, | |
| IPv6ControlInfo * | naCtrlInfo | |||
| ) | [protected, virtual] |
Definition at line 1891 of file IPv6NeighbourDiscovery.cc.
Referenced by processNDMessage().
{
if (validateNAPacket(na, naCtrlInfo) == false)
{
delete naCtrlInfo;
delete na;
return;
}
//Neighbour Advertisement Information
IPv6Address naTargetAddr = na->getTargetAddress();
//First, we check if the target address in NA is found in the interface it
//was received on is tentative.
InterfaceEntry *ie = ift->getInterfaceById(naCtrlInfo->getInterfaceId());
if (ie->ipv6Data()->isTentativeAddress(naTargetAddr))
{
error("Duplicate Address Detected! Manual attention needed!");
}
//Logic as defined in Section 7.2.5
Neighbour *neighbourEntry = neighbourCache.lookup(naTargetAddr, ie->getInterfaceId());
if (neighbourEntry == NULL)
{
EV << "NA received. Target Address not found in Neighbour Cache\n";
EV << "Dropping NA packet.\n";
delete naCtrlInfo;
delete na;
return;
}
//Target Address has entry in Neighbour Cache
EV << "NA received. Target Address found in Neighbour Cache\n";
if (neighbourEntry->reachabilityState == IPv6NeighbourCache::INCOMPLETE)
processNAForIncompleteNCEState(na, neighbourEntry);
else
processNAForOtherNCEStates(na, neighbourEntry);
delete naCtrlInfo;
delete na;
}
| void IPv6NeighbourDiscovery::processNDMessage | ( | ICMPv6Message * | msg, | |
| IPv6ControlInfo * | ctrlInfo | |||
| ) | [protected, virtual] |
Definition at line 146 of file IPv6NeighbourDiscovery.cc.
Referenced by handleMessage().
{
if (dynamic_cast<IPv6RouterSolicitation *>(msg))
{
IPv6RouterSolicitation *rs = (IPv6RouterSolicitation *)msg;
processRSPacket(rs, ctrlInfo);
}
else if (dynamic_cast<IPv6RouterAdvertisement *>(msg))
{
IPv6RouterAdvertisement *ra = (IPv6RouterAdvertisement *)msg;
processRAPacket(ra, ctrlInfo);
}
else if (dynamic_cast<IPv6NeighbourSolicitation *>(msg))
{
IPv6NeighbourSolicitation *ns = (IPv6NeighbourSolicitation *)msg;
processNSPacket(ns, ctrlInfo);
}
else if (dynamic_cast<IPv6NeighbourAdvertisement *>(msg))
{
IPv6NeighbourAdvertisement *na = (IPv6NeighbourAdvertisement *)msg;
processNAPacket(na, ctrlInfo);
}
else if (dynamic_cast<IPv6Redirect *>(msg))
{
IPv6Redirect *redirect = (IPv6Redirect *)msg;
processRedirectPacket(redirect, ctrlInfo);
}
else
{
error("Unrecognized ND message!");
}
}
| void IPv6NeighbourDiscovery::processNSForNonTentativeAddress | ( | IPv6NeighbourSolicitation * | ns, | |
| IPv6ControlInfo * | ctrlInfo, | |||
| InterfaceEntry * | ie | |||
| ) | [protected, virtual] |
Definition at line 1699 of file IPv6NeighbourDiscovery.cc.
Referenced by processNSPacket().
{
//Neighbour Solicitation Information
MACAddress nsMacAddr = ns->getSourceLinkLayerAddress();
int ifID = ie->getInterfaceId();
//target addr is not tentative addr
//solicitation processed as described in RFC2461:section 7.2.3
if (nsCtrlInfo->getSrcAddr().isUnspecified())
{
EV << "Address is duplicate! Inform Sender of duplicate address!\n";
sendSolicitedNA(ns, nsCtrlInfo, ie);
}
else
{
processNSWithSpecifiedSrcAddr(ns, nsCtrlInfo, ie);
}
}
| void IPv6NeighbourDiscovery::processNSForTentativeAddress | ( | IPv6NeighbourSolicitation * | ns, | |
| IPv6ControlInfo * | ctrlInfo | |||
| ) | [protected, virtual] |
Definition at line 1671 of file IPv6NeighbourDiscovery.cc.
Referenced by processNSPacket().
{
//Control Information
IPv6Address nsSrcAddr = nsCtrlInfo->getSrcAddr();
IPv6Address nsDestAddr = nsCtrlInfo->getDestAddr();
ASSERT(nsSrcAddr.isUnicast() || nsSrcAddr.isUnspecified());
//solicitation is processed as described in RFC2462:section 5.4.3
if (nsSrcAddr.isUnspecified())
{
EV << "Source Address is UNSPECIFIED. Sender is performing DAD\n";
//Sender performing Duplicate Address Detection
if (rt6->isLocalAddress(nsSrcAddr))
EV << "NS comes from myself. Ignoring NS\n";
else
EV << "NS comes from another node. Address is duplicate!\n";
error("Duplicate Address Detected! Manual Attention Required!");
}
else if (nsSrcAddr.isUnicast())
{
//Sender performing address resolution
EV << "Sender is performing Address Resolution\n";
EV << "Target Address is tentative. Ignoring NS.\n";
}
}
| void IPv6NeighbourDiscovery::processNSPacket | ( | IPv6NeighbourSolicitation * | ns, | |
| IPv6ControlInfo * | naCtrlInfo | |||
| ) | [protected, virtual] |
Definition at line 1591 of file IPv6NeighbourDiscovery.cc.
Referenced by processNDMessage().
{
//Control Information
InterfaceEntry *ie = ift->getInterfaceById(nsCtrlInfo->getInterfaceId());
IPv6Address nsTargetAddr = ns->getTargetAddress();
//RFC 2461:Section 7.2.3
//If target address is not a valid "unicast" or anycast address assigned to the
//receiving interface, we should silently discard the packet.
if (validateNSPacket(ns, nsCtrlInfo) == false
|| ie->ipv6Data()->hasAddress(nsTargetAddr) == false)
{
bubble("NS validation failed\n");
delete nsCtrlInfo;
delete ns;
return;
}
bubble("NS validation passed.\n");
if (ie->ipv6Data()->isTentativeAddress(nsTargetAddr))
{
//If the Target Address is tentative, the Neighbor Solicitation should
//be processed as described in [ADDRCONF].
EV << "Process NS for Tentative target address.\n";
processNSForTentativeAddress(ns, nsCtrlInfo);
}
else
{
//Otherwise, the following description applies.
EV << "Process NS for Non-Tentative target address.\n";
processNSForNonTentativeAddress(ns, nsCtrlInfo, ie);
}
delete nsCtrlInfo;
delete ns;
}
| void IPv6NeighbourDiscovery::processNSWithSpecifiedSrcAddr | ( | IPv6NeighbourSolicitation * | ns, | |
| IPv6ControlInfo * | ctrlInfo, | |||
| InterfaceEntry * | ie | |||
| ) | [protected, virtual] |
Definition at line 1720 of file IPv6NeighbourDiscovery.cc.
Referenced by processNSForNonTentativeAddress().
{
//RFC 2461, Section 7.2.3
/*If the Source Address is not the unspecified address and, on link layers
that have addresses, the solicitation includes a Source Link-Layer Address
option, then the recipient SHOULD create or update the Neighbor Cache entry
for the IP Source Address of the solicitation.*/
//Neighbour Solicitation Information
MACAddress nsMacAddr = ns->getSourceLinkLayerAddress();
int ifID = ie->getInterfaceId();
//Look for the Neighbour Cache Entry
Neighbour *entry = neighbourCache.lookup(nsCtrlInfo->getSrcAddr(), ifID);
if (entry == NULL)
{
/*If an entry does not already exist, the node SHOULD create a new one
and set its reachability state to STALE as specified in Section 7.3.3.*/
EV << "Neighbour Entry not found. Create a Neighbour Cache Entry.\n";
neighbourCache.addNeighbour(nsCtrlInfo->getSrcAddr(), ifID, nsMacAddr);
}
else
{
/*If an entry already exists, and the cached link-layer address differs from
the one in the received Source Link-Layer option,*/
if (!(entry->macAddress.equals(nsMacAddr)) && !nsMacAddr.isUnspecified())
{
//the cached address should be replaced by the received address
entry->macAddress = nsMacAddr;
//and the entry's reachability state MUST be set to STALE.
entry->reachabilityState = IPv6NeighbourCache::STALE;
}
}
/*After any updates to the Neighbor Cache, the node sends a Neighbor
Advertisement response as described in the next section.*/
sendSolicitedNA(ns, nsCtrlInfo, ie);
}
| void IPv6NeighbourDiscovery::processNUDTimeout | ( | cMessage * | timeoutMsg | ) | [protected, virtual] |
Definition at line 449 of file IPv6NeighbourDiscovery.cc.
Referenced by handleMessage().
{
EV << "NUD has timed out\n";
Neighbour *nce = (Neighbour *) timeoutMsg->getContextPointer();
const Key *nceKey = nce->nceKey;
InterfaceEntry *ie = ift->getInterfaceById(nceKey->interfaceID);
if (nce->reachabilityState == IPv6NeighbourCache::DELAY)
{
/*If the entry is still in the DELAY state when the timer expires, the
entry's state changes to PROBE. If reachability confirmation is received,
the entry's state changes to REACHABLE.*/
EV << "Neighbour Entry is still in DELAY state.\n";
EV << "Entering PROBE state. Sending NS probe.\n";
nce->reachabilityState = IPv6NeighbourCache::PROBE;
nce->numProbesSent = 0;
}
/*If no response is received after waiting RetransTimer milliseconds
after sending the MAX_UNICAST_SOLICIT solicitations, retransmissions cease
and the entry SHOULD be deleted. Subsequent traffic to that neighbor will
recreate the entry and performs address resolution again.*/
if (nce->numProbesSent == (int)ie->ipv6Data()->_getMaxUnicastSolicit())
{
EV << "Max number of probes have been sent." << endl;
EV << "Neighbour is Unreachable, removing NCE." << endl;
neighbourCache.remove(nceKey->address, nceKey->interfaceID);
return;
}
/*Upon entering the PROBE state, a node sends a unicast Neighbor Solicitation
message to the neighbor using the cached link-layer address.*/
createAndSendNSPacket(nceKey->address, nceKey->address,
ie->ipv6Data()->getPreferredAddress(), ie);
nce->numProbesSent++;
/*While in the PROBE state, a node retransmits Neighbor Solicitation messages
every RetransTimer milliseconds until reachability confirmation is obtained.
Probes are retransmitted even if no additional packets are sent to the
neighbor.*/
scheduleAt(simTime()+ie->ipv6Data()->_getRetransTimer(), timeoutMsg);
}
| void IPv6NeighbourDiscovery::processRAForRouterUpdates | ( | IPv6RouterAdvertisement * | ra, | |
| IPv6ControlInfo * | raCtrlInfo | |||
| ) | [protected, virtual] |
Definition at line 1153 of file IPv6NeighbourDiscovery.cc.
Referenced by processRAPacket().
{
EV << "Processing RA for Router Updates\n";
//RFC2461: Section 6.3.4
//Paragraphs 1 and 2 omitted.
//On receipt of a valid Router Advertisement, a host extracts the source
//address of the packet and does the following:
IPv6Address raSrcAddr = raCtrlInfo->getSrcAddr();
InterfaceEntry *ie = ift->getInterfaceById(raCtrlInfo->getInterfaceId());
int ifID = ie->getInterfaceId();
/*- If the address is not already present in the host's Default Router List,
and the advertisement's Router Lifetime is non-zero, create a new entry in
the list, and initialize its invalidation timer value from the advertisement's
Router Lifetime field.*/
Neighbour *neighbour = neighbourCache.lookup(raSrcAddr, ifID);
if (neighbour == NULL)
{
EV << "Neighbour Cache Entry does not contain RA's source address\n";
if (ra->getRouterLifetime() != 0)
{
EV << "RA's router lifetime is non-zero, creating an entry in the "
<< "Host's default router list.\n" << ra->getRouterLifetime();
//If a Neighbor Cache entry is created for the router its reachability
//state MUST be set to STALE as specified in Section 7.3.3.
if (ra->getSourceLinkLayerAddress().isUnspecified())
{
neighbour = neighbourCache.addRouter(raSrcAddr, ifID,
simTime()+ra->getRouterLifetime());
//Note:invalidation timers are not explicitly defined.
}
else
{
neighbour = neighbourCache.addRouter(raSrcAddr, ifID,
ra->getSourceLinkLayerAddress(), simTime()+ra->getRouterLifetime());
//According to Greg, we should add a default route for hosts as well!
rt6->addDefaultRoute(raSrcAddr, ifID, simTime()+ra->getRouterLifetime());
}
}
else
{
EV << "Router Lifetime is 0, adding NON-default router.\n";
//WEI-The router is advertising itself, BUT not as a default router.
if (ra->getSourceLinkLayerAddress().isUnspecified())
neighbour = neighbourCache.addNeighbour(raSrcAddr, ifID);
else
neighbour = neighbourCache.addNeighbour(raSrcAddr, ifID,
ra->getSourceLinkLayerAddress());
neighbour->isRouter = true;
}
}
else
{
//If no Source Link-Layer Address is included, but a corresponding Neighbor
//Cache entry exists, its IsRouter flag MUST be set to TRUE.
neighbour->isRouter = true;
//If a cache entry already exists and is updated with a different link-
//layer address the reachability state MUST also be set to STALE.
if (ra->getSourceLinkLayerAddress().isUnspecified() == false &&
neighbour->macAddress.equals(ra->getSourceLinkLayerAddress()) == false)
neighbour->macAddress = ra->getSourceLinkLayerAddress();
/*- If the address is already present in the host's Default Router List
as a result of a previously-received advertisement, reset its invalidation
timer to the Router Lifetime value in the newly-received advertisement.*/
neighbour->routerExpiryTime = simTime()+ra->getRouterLifetime();
/*- If the address is already present in the host's Default Router List
and the received Router Lifetime value is zero, immediately time-out the
entry as specified in Section 6.3.5.*/
if (ra->getRouterLifetime() == 0)
{
EV << "RA's router lifetime is ZERO. Timing-out entry.\n";
timeoutDefaultRouter(raSrcAddr, ifID);
}
}
//Paragraph Omitted.
//If the received Cur Hop Limit value is non-zero the host SHOULD set
//its CurHopLimit variable to the received value.
if (ra->getCurHopLimit() != 0)
{
EV << "RA's Cur Hop Limit is non-zero. Setting host's Cur Hop Limit to "
<< "received value.\n";
ie->ipv6Data()->setCurHopLimit(ra->getCurHopLimit());
}
//If the received Reachable Time value is non-zero the host SHOULD set its
//BaseReachableTime variable to the received value.
if (ra->getReachableTime() != 0)
{
EV << "RA's reachable time is non-zero ";
if (ra->getReachableTime() != SIMTIME_DBL(ie->ipv6Data()->getReachableTime()))
{
EV << " and RA's and Host's reachable time differ, \nsetting host's base"
<< " reachable time to received value.\n";
ie->ipv6Data()->setBaseReachableTime(ra->getReachableTime());
//If the new value differs from the previous value, the host SHOULD
//recompute a new random ReachableTime value.
ie->ipv6Data()->setReachableTime(ie->ipv6Data()->generateReachableTime());
}
EV << endl;
}
//The RetransTimer variable SHOULD be copied from the Retrans Timer field,
//if the received value is non-zero.
if (ra->getRetransTimer() != 0)
{
EV << "RA's retrans timer is non-zero, copying retrans timer variable.\n";
ie->ipv6Data()->setRetransTimer(ra->getRetransTimer());
}
/*If the MTU option is present, hosts SHOULD copy the option's value into
LinkMTU so long as the value is greater than or equal to the minimum link MTU
[IPv6] and does not exceed the default LinkMTU value specified in the link
type specific document (e.g., [IPv6-ETHER]).*/
//TODO: not done yet
processRAPrefixInfo(ra, ie);
}
| void IPv6NeighbourDiscovery::processRAPacket | ( | IPv6RouterAdvertisement * | ra, | |
| IPv6ControlInfo * | raCtrlInfo | |||
| ) | [protected, virtual] |
Definition at line 1116 of file IPv6NeighbourDiscovery.cc.
Referenced by processNDMessage().
{
InterfaceEntry *ie = ift->getInterfaceById(raCtrlInfo->getInterfaceId());
if (ie->ipv6Data()->getAdvSendAdvertisements())
{
EV << "Interface is an advertising interface, dropping RA message.\n";
delete ra;
return;
}
else
{
if (validateRAPacket(ra, raCtrlInfo) == false)
{
delete ra;
return;
}
cancelRouterDiscovery(ie);//Cancel router discovery if it is in progress.
EV << "Interface is a host, processing RA.\n";
processRAForRouterUpdates(ra, raCtrlInfo);//See RFC2461: Section 6.3.4
//Possible options
MACAddress macAddress = ra->getSourceLinkLayerAddress();
uint mtu = ra->getMTU();
for (int i = 0; i < (int)ra->getPrefixInformationArraySize(); i++)
{
IPv6NDPrefixInformation& prefixInfo = ra->getPrefixInformation(i);
if (prefixInfo.getAutoAddressConfFlag() == true)//If auto addr conf is set
processRAPrefixInfoForAddrAutoConf(prefixInfo, ie);//We process prefix Info and form an addr
}
}
delete raCtrlInfo;
delete ra;
}
| void IPv6NeighbourDiscovery::processRAPrefixInfo | ( | IPv6RouterAdvertisement * | ra, | |
| InterfaceEntry * | ie | |||
| ) | [protected, virtual] |
Definition at line 1278 of file IPv6NeighbourDiscovery.cc.
Referenced by processRAForRouterUpdates().
{
//Continued from section 6.3.4
/*Prefix Information options that have the "on-link" (L) flag set indicate a
prefix identifying a range of addresses that should be considered on-link.
Note, however, that a Prefix Information option with the on-link flag set to
zero conveys no information concerning on-link determination and MUST NOT be
interpreted to mean that addresses covered by the prefix are off-link. The
only way to cancel a previous on-link indication is to advertise that prefix
with the L-bit set and the Lifetime set to zero. The default behavior (see
Section 5.2) when sending a packet to an address for which no information is
known about the on-link status of the address is to forward the packet to a
default router; the reception of a Prefix Information option with the "on-link "
(L) flag set to zero does not change this behavior. The reasons for an address
being treated as on-link is specified in the definition of "on-link" in
Section 2.1. Prefixes with the on-link flag set to zero would normally have
the autonomous flag set and be used by [ADDRCONF].*/
IPv6NDPrefixInformation prefixInfo;
//For each Prefix Information option
for (int i = 0; i < (int)ra->getPrefixInformationArraySize(); i++)
{
prefixInfo = ra->getPrefixInformation(i);
if (!prefixInfo.getOnlinkFlag()) break;//skip to next prefix option
//with the on-link flag set, a host does the following:
EV << "Fetching Prefix Information:" << i+1 << " of "
<< ra->getPrefixInformationArraySize() << endl;
uint prefixLength = prefixInfo.getPrefixLength();
simtime_t validLifetime = prefixInfo.getValidLifetime();
uint preferredLifetime = prefixInfo.getPreferredLifetime();
IPv6Address prefix = prefixInfo.getPrefix();
//- If the prefix is the link-local prefix, silently ignore the Prefix
//Information option.
if (prefix.isLinkLocal())
{
EV << "Prefix is link-local, ignoring prefix.\n";
return;
}
//- If the prefix is not already present in the Prefix List,
if (!rt6->isPrefixPresent(prefix)) {
//and the Prefix Information option's Valid Lifetime field is non-zero,
if (validLifetime != 0)
{
/*create a new entry for the prefix and initialize its invalidation
timer to the Valid Lifetime value in the Prefix Information option.*/
rt6->addOrUpdateOnLinkPrefix(prefix, prefixLength, ie->getInterfaceId(),
simTime()+validLifetime);
}
/*- If the Prefix Information option's Valid Lifetime field is zero,
and the prefix is not present in the host's Prefix List,
silently ignore the option.*/
}
else
{
/* If the new Lifetime value is zero, time-out the prefix immediately
(see Section 6.3.5).*/
if (validLifetime == 0)
{
EV << "Prefix Info's valid lifetime is 0, time-out prefix\n";
rt6->removeOnLinkPrefix(prefix, prefixLength);
return;
}
/*- If the prefix is already present in the host's Prefix List as
the result of a previously-received advertisement, reset its
invalidation timer to the Valid Lifetime value in the Prefix
Information option.*/
rt6->addOrUpdateOnLinkPrefix(prefix, prefixLength, ie->getInterfaceId(),
simTime()+validLifetime);
}
/*Stateless address autoconfiguration [ADDRCONF] may in some
circumstances increase the Valid Lifetime of a prefix or ignore it
completely in order to prevent a particular denial of service attack.
However, since the effect of the same denial of service targeted at
the on-link prefix list is not catastrophic (hosts would send packets
to a default router and receive a redirect rather than sending
packets directly to a neighbor) the Neighbor Discovery protocol does
not impose such a check on the prefix lifetime values.*/
}
}
| void IPv6NeighbourDiscovery::processRAPrefixInfoForAddrAutoConf | ( | IPv6NDPrefixInformation & | prefixInfo, | |
| InterfaceEntry * | ie | |||
| ) | [protected, virtual] |
Definition at line 1362 of file IPv6NeighbourDiscovery.cc.
Referenced by processRAPacket().
{
EV << "Processing Prefix Info for address auto-configuration.\n";
IPv6Address prefix = prefixInfo.getPrefix();
uint prefixLength = prefixInfo.getPrefixLength();
simtime_t preferredLifetime = prefixInfo.getPreferredLifetime();
simtime_t validLifetime = prefixInfo.getValidLifetime();
//RFC 2461: Section 5.5.3
//First condition tested, the autonomous flag is already set
//b) If the prefix is the link-local prefix, silently ignore the Prefix
//Information option.
if (prefixInfo.getPrefix().isLinkLocal() == true)
{
EV << "Prefix is link-local, ignore Prefix Information Option\n";
return;
}
//c) If the preferred lifetime is greater than the valid lifetime, silently
//ignore the Prefix Information option. A node MAY wish to log a system
//management error in this case.
if (preferredLifetime > validLifetime)
{
EV << "Preferred lifetime is greater than valid lifetime, ignore Prefix Information\n";
return;
}
bool isPrefixAssignedToInterface = false;
for (int i = 0; i < ie->ipv6Data()->getNumAddresses(); i++)
{
if (ie->ipv6Data()->getAddress(i).matches(prefix, prefixLength) == true)
isPrefixAssignedToInterface = true;
}
/*d) If the prefix advertised does not match the prefix of an address already
in the list, and the Valid Lifetime is not 0, form an address (and add
it to the list) by combining the advertised prefix with the link’s
interface identifier as follows:*/
if (isPrefixAssignedToInterface == false && validLifetime != 0)
{
IPv6Address linkLocalAddress = ie->ipv6Data()->getLinkLocalAddress();
ASSERT(linkLocalAddress.isUnspecified() == false);
IPv6Address newAddr = linkLocalAddress.setPrefix(prefix, prefixLength);
//TODO: for now we leave the newly formed address as not tentative,
//according to Greg, we have to always perform DAD for a newly formed address.
EV << "Assigning new address to: " << ie->getName() << endl;
ie->ipv6Data()->assignAddress(newAddr, false, simTime()+validLifetime,
simTime()+preferredLifetime);
}
//TODO: this is the simplified version.
/*e) If the advertised prefix matches the prefix of an autoconfigured
address (i.e., one obtained via stateless or stateful address
autoconfiguration) in the list of addresses associated with the
interface, the specific action to perform depends on the Valid
Lifetime in the received advertisement and the Lifetime
associated with the previously autoconfigured address (which we
call StoredLifetime in the discussion that follows):
1) If the received Lifetime is greater than 2 hours or greater
than StoredLifetime, update the stored Lifetime of the
corresponding address.
2) If the StoredLifetime is less than or equal to 2 hours and the
received Lifetime is less than or equal to StoredLifetime,
ignore the prefix, unless the Router Advertisement from which
this Prefix Information option was obtained has been
authenticated (e.g., via IPSec [RFC2402]). If the Router
Advertisment was authenticated, the StoredLifetime should be
set to the Lifetime in the received option.
3) Otherwise, reset the stored Lifetime in the corresponding
address to two hours.*/
}
| void IPv6NeighbourDiscovery::processRDTimeout | ( | cMessage * | msg | ) | [protected, virtual] |
Definition at line 904 of file IPv6NeighbourDiscovery.cc.
Referenced by handleMessage().
{
InterfaceEntry *ie = (InterfaceEntry *)msg->getContextPointer();
RDEntry *rdEntry = fetchRDEntry(ie);
if (rdEntry->numRSSent < ie->ipv6Data()->_getMaxRtrSolicitations())
{
bubble("Sending another RS message.");
createAndSendRSPacket(ie);
rdEntry->numRSSent++;
//Need to find out if this is the last RS we are sending out.
if (rdEntry->numRSSent == ie->ipv6Data()->_getMaxRtrSolicitations())
scheduleAt(simTime()+ie->ipv6Data()->_getMaxRtrSolicitationDelay(), msg);
else
scheduleAt(simTime()+ie->ipv6Data()->_getRtrSolicitationInterval(), msg);
}
else
{
//RFC 2461, Section 6.3.7
/*If a host sends MAX_RTR_SOLICITATIONS solicitations, and receives no Router
Advertisements after having waited MAX_RTR_SOLICITATION_DELAY seconds after
sending the last solicitation, the host concludes that there are no routers
on the link for the purpose of [ADDRCONF]. However, the host continues to
receive and process Router Advertisements messages in the event that routers
appear on the link.*/
bubble("Max number of RS messages sent");
EV << "No RA messages were received. Assume no routers are on-link";
delete rdEntry;
delete msg;
}
}
| void IPv6NeighbourDiscovery::processRedirectPacket | ( | IPv6Redirect * | redirect, | |
| IPv6ControlInfo * | ctrlInfo | |||
| ) | [protected, virtual] |
Definition at line 2141 of file IPv6NeighbourDiscovery.cc.
Referenced by processNDMessage().
{
//First we need to extract information from the redirect message
IPv6Address targetAddr = redirect->getTargetAddress();//Addressed to me
IPv6Address destAddr = redirect->getDestinationAddress();//new dest addr
//Optional
MACAddress macAddr = redirect->getTargetLinkLayerAddress();
}
| void IPv6NeighbourDiscovery::processRSPacket | ( | IPv6RouterSolicitation * | rs, | |
| IPv6ControlInfo * | rsCtrlInfo | |||
| ) | [protected, virtual] |
Definition at line 935 of file IPv6NeighbourDiscovery.cc.
Referenced by processNDMessage().
{
if (validateRSPacket(rs, rsCtrlInfo) == false) return;
//Find out which interface the RS message arrived on.
InterfaceEntry *ie = ift->getInterfaceById(rsCtrlInfo->getInterfaceId());
AdvIfEntry *advIfEntry = fetchAdvIfEntry(ie);//fetch advertising interface entry.
//RFC 2461: Section 6.2.6
//A host MUST silently discard any received Router Solicitation messages.
if (ie->ipv6Data()->getAdvSendAdvertisements())
{
EV << "This is an advertising interface, processing RS\n";
if (validateRSPacket(rs, rsCtrlInfo) == false) return;
EV << "RS message validated\n";
//First we extract RS specific information from the received message
MACAddress macAddr = rs->getSourceLinkLayerAddress();
EV << "MAC Address extracted\n";
delete rs;
/*A router MAY choose to unicast the response directly to the soliciting
host's address (if the solicitation's source address is not the unspecified
address), but the usual case is to multicast the response to the
all-nodes group. In the latter case, the interface's interval timer is
reset to a new random value, as if an unsolicited advertisement had just
been sent(see Section 6.2.4).*/
/*In all cases, Router Advertisements sent in response to a Router
Solicitation MUST be delayed by a random time between 0 and
MAX_RA_DELAY_TIME seconds. (If a single advertisement is sent in
response to multiple solicitations, the delay is relative to the
first solicitation.) In addition, consecutive Router Advertisements
sent to the all-nodes multicast address MUST be rate limited to no
more than one advertisement every MIN_DELAY_BETWEEN_RAS seconds.*/
/*A router might process Router Solicitations as follows:
- Upon receipt of a Router Solicitation, compute a random delay
within the range 0 through MAX_RA_DELAY_TIME. If the computed
value corresponds to a time later than the time the next multicast
Router Advertisement is scheduled to be sent, ignore the random
delay and send the advertisement at the already-scheduled time.*/
cMessage *msg = new cMessage("sendSolicitedRA", MK_SEND_SOL_RTRADV);
msg->setContextPointer(ie);
simtime_t interval = uniform(0, ie->ipv6Data()->_getMaxRADelayTime());
if (interval < advIfEntry->nextScheduledRATime)
{
simtime_t nextScheduledTime;
nextScheduledTime = simTime()+interval;
scheduleAt(nextScheduledTime, msg);
advIfEntry->nextScheduledRATime = nextScheduledTime;
}
//else we ignore the generate interval and send it at the next scheduled time.
//We need to keep a log here each time an RA is sent. Not implemented yet.
//Assume the first course of action.
/*- If the router sent a multicast Router Advertisement (solicited or
unsolicited) within the last MIN_DELAY_BETWEEN_RAS seconds,
schedule the advertisement to be sent at a time corresponding to
MIN_DELAY_BETWEEN_RAS plus the random value after the previous
advertisement was sent. This ensures that the multicast Router
Advertisements are rate limited.
- Otherwise, schedule the sending of a Router Advertisement at the
time given by the random value.*/
}
else
{
EV << "This interface is a host, discarding RA message\n";
delete rs;
}
}
| void IPv6NeighbourDiscovery::reachabilityConfirmed | ( | const IPv6Address & | neighbour, | |
| int | interfaceId | |||
| ) | [virtual] |
Public method, it can be invoked from the IPv6 module or any other module to let Neighbour Discovery know that the reachability of the given neighbor has just been confirmed (e.g. TCP received ACK of new data from it). Neighbour Discovery can then update the neighbour cache with this information, and cancel the Neighbour Unreachability Detection procedure if it is currently running.
Definition at line 314 of file IPv6NeighbourDiscovery.cc.
{
Enter_Method("reachabilityConfirmed(%s,if=%d)", neighbour.str().c_str(), interfaceId);
//hmmm... this should only be invoked if a TCP ACK was received and NUD is
//currently being performed on the neighbour where the TCP ACK was received from.
Neighbour *nce = neighbourCache.lookup(neighbour, interfaceId);
cMessage *msg = nce->nudTimeoutEvent;
if (msg != NULL)
{
EV << "NUD in progress. Cancelling NUD Timer\n";
bubble("Reachability Confirmed via NUD.");
cancelEvent(msg);
delete msg;
}
// TODO (see header file for description)
/*A neighbor is considered reachable if the node has recently received
a confirmation that packets sent recently to the neighbor were
received by its IP layer. Positive confirmation can be gathered in
two ways: hints from upper layer protocols that indicate a connection
is making "forward progress", or receipt of a Neighbor Advertisement
message that is a response to a Neighbor Solicitation message.
A connection makes "forward progress" if the packets received from a
remote peer can only be arriving if recent packets sent to that peer
are actually reaching it. In TCP, for example, receipt of a (new)
acknowledgement indicates that previously sent data reached the peer.
Likewise, the arrival of new (non-duplicate) data indicates that
earlier acknowledgements are being delivered to the remote peer. If
packets are reaching the peer, they must also be reaching the
sender's next-hop neighbor; thus "forward progress" is a confirmation
that the next-hop neighbor is reachable. For off-link destinations,
forward progress implies that the first-hop router is reachable.
When available, this upper-layer information SHOULD be used.
In some cases (e.g., UDP-based protocols and routers forwarding
packets to hosts) such reachability information may not be readily
available from upper-layer protocols. When no hints are available
and a node is sending packets to a neighbor, the node actively probes
the neighbor using unicast Neighbor Solicitation messages to verify
that the forward path is still working.
The receipt of a solicited Neighbor Advertisement serves as
reachability confirmation, since advertisements with the Solicited
flag set to one are sent only in response to a Neighbor Solicitation.
Receipt of other Neighbor Discovery messages such as Router
Advertisements and Neighbor Advertisement with the Solicited flag set
to zero MUST NOT be treated as a reachability confirmation. Receipt
of unsolicited messages only confirm the one-way path from the sender
to the recipient node. In contrast, Neighbor Unreachability
Detection requires that a node keep track of the reachability of the
forward path to a neighbor from the its perspective, not the
neighbor's perspective. Note that receipt of a solicited
advertisement indicates that a path is working in both directions.
The solicitation must have reached the neighbor, prompting it to
generate an advertisement. Likewise, receipt of an advertisement
indicates that the path from the sender to the recipient is working.
However, the latter fact is known only to the recipient; the
advertisement's sender has no direct way of knowing that the
advertisement it sent actually reached a neighbor. From the
perspective of Neighbor Unreachability Detection, only the
reachability of the forward path is of interest.*/
}
| void IPv6NeighbourDiscovery::resetRATimer | ( | InterfaceEntry * | ie | ) | [protected, virtual] |
Reset the given interface entry's Router Advertisement timer. This is usually done when a router interface responds (by replying with a Router Advertisement sent to the All-Node multicast group)to a router solicitation Also see: RFC 2461, Section 6.2.6
Definition at line 1459 of file IPv6NeighbourDiscovery.cc.
{//Not used yet but could be useful later on.-WEI
//Iterate through all RA timers within the Neighbour Discovery module.
/*
for (RATimerList::iterator it=raTimerList.begin(); it != raTimerList.end(); it++)
{
cMessage *msg = (*it);
InterfaceEntry *msgIE = (InterfaceEntry *)msg->getContextPointer();
//Find the timer that matches the given Interface Entry.
if (msgIE->outputPort() == ie->outputPort())
{
EV << "Resetting RA timer for port: " << ie->outputPort();
cancelEvent(msg);//Cancel the next scheduled msg.
simtime_t interval
= uniform(ie->ipv6Data()->getMinRtrAdvInterval(),ie->ipv6Data()->getMaxRtrAdvInterval());
scheduleAt(simTime()+interval, msg);
}
}
*/
}
| const MACAddress & IPv6NeighbourDiscovery::resolveNeighbour | ( | const IPv6Address & | nextHop, | |
| int | interfaceId | |||
| ) |
Public method, to be invoked from the IPv6 module to determine link-layer address and the output interface of the next hop.
If the neighbor cache does not contain this address or it's in the state INCOMPLETE, this method will return the NULL address, and the IPv6 module should then send the datagram here to IPv6NeighbourDiscovery where it will be stored until neighbour resolution completes.
If the neighbour cache entry is STALE (or REACHABLE but more than reachableTime elapsed since reachability was last confirmed), the link-layer address is still returned and IPv6 can send the datagram, but simultaneously, this call should trigger the Neighbour Unreachability Detection procedure to start in the IPv6NeighbourDiscovery module.
Definition at line 286 of file IPv6NeighbourDiscovery.cc.
Referenced by IPv6::routePacket().
{
Enter_Method("resolveNeighbor(%s,if=%d)", nextHop.str().c_str(), interfaceId);
Neighbour *nce = neighbourCache.lookup(nextHop, interfaceId);
//InterfaceEntry *ie = ift->getInterfaceById(interfaceId);
if (!nce || nce->reachabilityState==IPv6NeighbourCache::INCOMPLETE)
return MACAddress::UNSPECIFIED_ADDRESS;
else if (nce->reachabilityState==IPv6NeighbourCache::STALE)
initiateNeighbourUnreachabilityDetection(nce);
else if (nce->reachabilityState==IPv6NeighbourCache::REACHABLE &&
simTime() > nce->reachabilityExpires)
{
nce->reachabilityState = IPv6NeighbourCache::STALE;
initiateNeighbourUnreachabilityDetection(nce);
}
else if (nce->reachabilityState!=IPv6NeighbourCache::REACHABLE)
{
//reachability state must be either in DELAY or PROBE
ASSERT(nce->reachabilityState==IPv6NeighbourCache::DELAY ||
nce->reachabilityState==IPv6NeighbourCache::PROBE);
EV << "NUD in progress.\n";
}
//else the entry is REACHABLE and no further action is required here.
return nce->macAddress;
}
| IPv6Address IPv6NeighbourDiscovery::selectDefaultRouter | ( | int & | outIfID | ) | [protected, virtual] |
Definition at line 491 of file IPv6NeighbourDiscovery.cc.
Referenced by determineNextHop().
{
EV << "Selecting default router...\n";
//draft-ietf-ipv6-2461bis-04.txt Section 6.3.6
/*The algorithm for selecting a router depends in part on whether or not a
router is known to be reachable. The exact details of how a node keeps track
of a neighbor's reachability state are covered in Section 7.3. The algorithm
for selecting a default router is invoked during next-hop determination when
no Destination Cache entry exists for an off-link destination or when
communication through an existing router appears to be failing. Under normal
conditions, a router would be selected the first time traffic is sent to a
destination, with subsequent traffic for that destination using the same router
as indicated in the Destination Cache modulo any changes to the Destination
Cache caused by Redirect messages.
The policy for selecting routers from the Default Router List is as
follows:*/
IPv6Address routerAddr;
//Cycle through all entries in the neighbour cache entry.
for(IPv6NeighbourCache::iterator it=neighbourCache.begin(); it != neighbourCache.end(); it++)
{
Key key = it->first;
Neighbour nce = it->second;
bool routerExpired = false;
if (nce.isDefaultRouter)
{
if (simTime()>nce.routerExpiryTime)
{
EV << "Found an expired default router. Deleting entry...\n";
neighbourCache.remove(key.address,key.interfaceID);
routerExpired = true;
}
}
if (routerExpired == false)
{
if (nce.reachabilityState == IPv6NeighbourCache::REACHABLE ||
nce.reachabilityState == IPv6NeighbourCache::STALE ||
nce.reachabilityState == IPv6NeighbourCache::DELAY)//TODO: Need to improve this algorithm!
{
EV << "Found a router in the neighbour cache(default router list).\n";
outIfID = key.interfaceID;
if (routerExpired == false) return key.address;
}
}
}
EV << "No suitable routers found.\n";
/*1) Routers that are reachable or probably reachable (i.e., in any state
other than INCOMPLETE) SHOULD be preferred over routers whose reachability
is unknown or suspect (i.e., in the INCOMPLETE state, or for which no Neighbor
Cache entry exists). An implementation may choose to always return the same
router or cycle through the router list in a round-robin fashion as long as
it always returns a reachable or a probably reachable router when one is
available.*/
/*2) When no routers on the list are known to be reachable or probably
reachable, routers SHOULD be selected in a round-robin fashion, so that
subsequent requests for a default router do not return the same router until
all other routers have been selected.
Cycling through the router list in this case ensures that all available
routers are actively probed by the Neighbor Unreachability Detection algorithm.
A request for a default router is made in conjunction with the sending of a
packet to a router, and the selected router will be probed for reachability
as a side effect.*/
outIfID = -1;//nothing found yet
return IPv6Address();
}
| void IPv6NeighbourDiscovery::sendPacketToIPv6Module | ( | cMessage * | msg, | |
| const IPv6Address & | destAddr, | |||
| const IPv6Address & | srcAddr, | |||
| int | interfaceId | |||
| ) | [protected, virtual] |
Create control info and assigns it to a msg. Returns a copy of the msg with the control info.
Definition at line 700 of file IPv6NeighbourDiscovery.cc.
Referenced by createAndSendNSPacket(), createAndSendRAPacket(), createAndSendRSPacket(), processIPv6Datagram(), and sendSolicitedNA().
{
IPv6ControlInfo *controlInfo = new IPv6ControlInfo();
controlInfo->setProtocol(IP_PROT_IPv6_ICMP);
controlInfo->setDestAddr(destAddr);
controlInfo->setSrcAddr(srcAddr);
controlInfo->setHopLimit(255);
controlInfo->setInterfaceId(interfaceId);
msg->setControlInfo(controlInfo);
send(msg,"ipv6Out");
}
| void IPv6NeighbourDiscovery::sendPeriodicRA | ( | cMessage * | msg | ) | [protected, virtual] |
Definition at line 1480 of file IPv6NeighbourDiscovery.cc.
Referenced by handleMessage().
{
InterfaceEntry *ie = (InterfaceEntry *)msg->getContextPointer();
AdvIfEntry *advIfEntry = fetchAdvIfEntry(ie);
IPv6Address destAddr = IPv6Address("FF02::1");
createAndSendRAPacket(destAddr, ie);
advIfEntry->numRASent++;
simtime_t nextScheduledTime;
//RFC 2461, Section 6.2.4
/*Whenever a multicast advertisement is sent from an interface, the timer is
reset to a uniformly-distributed random value between the interface's
configured MinRtrAdvInterval and MaxRtrAdvInterval; expiration of the timer
causes the next advertisement to be sent and a new random value to be chosen.*/
simtime_t interval = uniform(ie->ipv6Data()->getMinRtrAdvInterval(), ie->ipv6Data()->getMaxRtrAdvInterval());
nextScheduledTime = simTime() + interval;
/*For the first few advertisements (up to MAX_INITIAL_RTR_ADVERTISEMENTS)
sent from an interface when it becomes an advertising interface,*/
EV << "Num RA sent is: " << advIfEntry->numRASent << endl;
EV << "maxInitialRtrAdvertisements is: " << ie->ipv6Data()->_getMaxInitialRtrAdvertisements() << endl;
if(advIfEntry->numRASent <= ie->ipv6Data()->_getMaxInitialRtrAdvertisements())
{
if (interval > ie->ipv6Data()->_getMaxInitialRtrAdvertInterval())
{
//if the randomly chosen interval is greater than MAX_INITIAL_RTR_ADVERT_INTERVAL,
//the timer SHOULD be set to MAX_INITIAL_RTR_ADVERT_INTERVAL instead.
nextScheduledTime = simTime() + ie->ipv6Data()->_getMaxInitialRtrAdvertInterval();
EV << "Sending initial RA but interval is too long. Using default value." << endl;
}
else
EV << "Sending initial RA. Using randomly generated interval." << endl;
}
EV << "Next scheduled time: " << nextScheduledTime << endl;
advIfEntry->nextScheduledRATime = nextScheduledTime;
ASSERT(nextScheduledTime > simTime());
scheduleAt(nextScheduledTime, msg);
}
| void IPv6NeighbourDiscovery::sendQueuedPacketsToIPv6Module | ( | Neighbour * | nce | ) | [protected, virtual] |
Send off any queued packets within the Neighbour Discovery module awaiting address resolution.
Not used yet-unsure if we really need it. --DELETED, Andras
Definition at line 716 of file IPv6NeighbourDiscovery.cc.
Referenced by processNAForIncompleteNCEState().
{
MsgPtrVector& pendingPackets = nce->pendingPackets;
while(!pendingPackets.empty())//FIXME: pendingPackets are always empty!!!!
{
MsgPtrVector::iterator i = pendingPackets.begin();
cMessage *msg = (*i);
pendingPackets.erase(i);
pendingQueue.remove(msg);
EV << "Sending queued packet " << msg << endl;
send(msg,"ipv6Out");
}
}
| void IPv6NeighbourDiscovery::sendSolicitedNA | ( | IPv6NeighbourSolicitation * | ns, | |
| IPv6ControlInfo * | nsCtrlInfo, | |||
| InterfaceEntry * | ie | |||
| ) | [protected, virtual] |
Definition at line 1761 of file IPv6NeighbourDiscovery.cc.
Referenced by processNSForNonTentativeAddress(), and processNSWithSpecifiedSrcAddr().
{
IPv6NeighbourAdvertisement *na = new IPv6NeighbourAdvertisement("NApacket");
//RFC 2461: Section 7.2.4
/*A node sends a Neighbor Advertisement in response to a valid Neighbor
Solicitation targeting one of the node's assigned addresses. The
Target Address of the advertisement is copied from the Target Address
of the solicitation.*/
na->setTargetAddress(ns->getTargetAddress());
/*If the solicitation's IP Destination Address is not a multicast address,
the Target Link-Layer Address option MAY be omitted; the neighboring node's
cached value must already be current in order for the solicitation to have
been received. If the solicitation's IP Destination Address is a multicast
address, the Target Link-Layer option MUST be included in the advertisement.*/
na->setTargetLinkLayerAddress(ie->getMacAddress());//here, we always include the MAC addr.
/*Furthermore, if the node is a router, it MUST set the Router flag to one;
otherwise it MUST set the flag to zero.*/
na->setRouterFlag(rt6->isRouter());
/*If the (NS)Target Address is either an anycast address or a unicast
address for which the node is providing proxy service, or the Target
Link-Layer Address option is not included,*/
//TODO:ANYCAST will not be implemented here!
if (ns->getSourceLinkLayerAddress().isUnspecified())
//the Override flag SHOULD be set to zero.
na->setOverrideFlag(false);
else
//Otherwise, the Override flag SHOULD be set to one.
na->setOverrideFlag(true);
/*Proper setting of the Override flag ensures that nodes give preference to
non-proxy advertisements, even when received after proxy advertisements, and
also ensures that the first advertisement for an anycast address "wins".*/
IPv6Address naDestAddr;
//If the source of the solicitation is the unspecified address,
if(nsCtrlInfo->getSrcAddr().isUnspecified())
{
/*the node MUST set the Solicited flag to zero and multicast the advertisement
to the all-nodes address.*/
na->setSolicitedFlag(false);
naDestAddr = IPv6Address::ALL_NODES_2;
}
else
{
/*Otherwise, the node MUST set the Solicited flag to one and unicast
the advertisement to the Source Address of the solicitation.*/
na->setSolicitedFlag(true);
naDestAddr = nsCtrlInfo->getSrcAddr();
}
/*If the Target Address is an anycast address the sender SHOULD delay sending
a response for a random time between 0 and MAX_ANYCAST_DELAY_TIME seconds.*/
/*TODO: More associated complexity for this one. We will have to delay
sending off the solicitation. Perhaps the self message could have a context
pointer pointing to a struct with enough info to create and send a NA packet.*/
/*Because unicast Neighbor Solicitations are not required to include a
Source Link-Layer Address, it is possible that a node sending a
solicited Neighbor Advertisement does not have a corresponding link-
layer address for its neighbor in its Neighbor Cache. In such
situations, a node will first have to use Neighbor Discovery to
determine the link-layer address of its neighbor (i.e, send out a
multicast Neighbor Solicitation).*/
//TODO: if above mentioned happens, can addr resolution be performed for ND messages?
//if no link-layer addr exists for unicast addr when sending solicited NA, we should
//add the NA to the list of queued packets. What if we have a list of queued
//packets for different unicast solicitations? each time addr resolution is
//done we should check the destinations of the list of queued packets and send
//off the respective ones.
IPv6Address myIPv6Addr = ie->ipv6Data()->getPreferredAddress();
sendPacketToIPv6Module(na, naDestAddr, myIPv6Addr, ie->getInterfaceId());
}
| void IPv6NeighbourDiscovery::sendSolicitedRA | ( | cMessage * | msg | ) | [protected, virtual] |
Definition at line 1519 of file IPv6NeighbourDiscovery.cc.
Referenced by handleMessage().
{
EV << "Send Solicited RA invoked!\n";
InterfaceEntry *ie = (InterfaceEntry *)msg->getContextPointer();
IPv6Address destAddr = IPv6Address("FF02::1");
EV << "Testing condition!\n";
createAndSendRAPacket(destAddr, ie);
delete msg;
}
| void IPv6NeighbourDiscovery::sendUnsolicitedNA | ( | InterfaceEntry * | ie | ) | [protected, virtual] |
Definition at line 1837 of file IPv6NeighbourDiscovery.cc.
{
//RFC 2461
//Section 7.2.6: Sending Unsolicited Neighbor Advertisements
/*In some cases a node may be able to determine that its link-layer
address has changed (e.g., hot-swap of an interface card) and may
wish to inform its neighbors of the new link-layer address quickly.
In such cases a node MAY send up to MAX_NEIGHBOR_ADVERTISEMENT
unsolicited Neighbor Advertisement messages to the all-nodes
multicast address. These advertisements MUST be separated by at
least RetransTimer seconds.
The Target Address field in the unsolicited advertisement is set to
an IP address of the interface, and the Target Link-Layer Address
option is filled with the new link-layer address. The Solicited flag
MUST be set to zero, in order to avoid confusing the Neighbor
Unreachability Detection algorithm. If the node is a router, it MUST
set the Router flag to one; otherwise it MUST set it to zero. The
Override flag MAY be set to either zero or one. In either case,
neighboring nodes will immediately change the state of their Neighbor
Cache entries for the Target Address to STALE, prompting them to
verify the path for reachability. If the Override flag is set to
one, neighboring nodes will install the new link-layer address in
their caches. Otherwise, they will ignore the new link-layer
address, choosing instead to probe the cached address.
A node that has multiple IP addresses assigned to an interface MAY
multicast a separate Neighbor Advertisement for each address. In
such a case the node SHOULD introduce a small delay between the
sending of each advertisement to reduce the probability of the
advertisements being lost due to congestion.
A proxy MAY multicast Neighbor Advertisements when its link-layer
address changes or when it is configured (by system management or
other mechanisms) to proxy for an address. If there are multiple
nodes that are providing proxy services for the same set of addresses
the proxies SHOULD provide a mechanism that prevents multiple proxies
from multicasting advertisements for any one address, in order to
reduce the risk of excessive multicast traffic.
Also, a node belonging to an anycast address MAY multicast
unsolicited Neighbor Advertisements for the anycast address when the
node's link-layer address changes.
Note that because unsolicited Neighbor Advertisements do not reliably
update caches in all nodes (the advertisements might not be received
by all nodes), they should only be viewed as a performance
optimization to quickly update the caches in most neighbors. The
Neighbor Unreachability Detection algorithm ensures that all nodes
obtain a reachable link-layer address, though the delay may be
slightly longer.*/
}
| void IPv6NeighbourDiscovery::timeoutDefaultRouter | ( | const IPv6Address & | addr, | |
| int | interfaceID | |||
| ) | [protected, virtual] |
RFC 2461: Section 6.3.5 Whenever the Lifetime of an entry in the Default Router List expires, that entry is discarded. When removing a router from the Default Router list, the node MUST update the Destination Cache in such a way that all entries using the router perform next-hop determination again rather than continue sending traffic to the (deleted) router.
Definition at line 578 of file IPv6NeighbourDiscovery.cc.
Referenced by processRAForRouterUpdates().
{
//RFC 2461: Section 6.3.5
/*Whenever the Lifetime of an entry in the Default Router List expires,
that entry is discarded.*/
neighbourCache.remove(addr, interfaceID);
/*When removing a router from the Default Router list, the node MUST update
the Destination Cache in such a way that all entries using the router perform
next-hop determination again rather than continue sending traffic to the
(deleted) router.*/
rt6->purgeDestCacheEntriesToNeighbour(addr, interfaceID);
}
| void IPv6NeighbourDiscovery::timeoutPrefixEntry | ( | const IPv6Address & | destPrefix, | |
| int | prefixLength | |||
| ) | [protected, virtual] |
RFC 2461: Section 6.3.5 Whenever the invalidation timer expires for a Prefix List entry, that entry is discarded. No existing Destination Cache entries need be updated, however. Should a reachability problem arise with an existing Neighbor Cache entry, Neighbor Unreachability Detection will perform any needed recovery.
Definition at line 563 of file IPv6NeighbourDiscovery.cc.
{
//RFC 2461: Section 6.3.5
/*Whenever the invalidation timer expires for a Prefix List entry, that
entry is discarded.*/
rt6->removeOnLinkPrefix(destPrefix, prefixLength);
//hmmm... should the unicast address associated with this prefix be deleted
//as well?-TODO: The address should be timeout/deleted as well!!
/*No existing Destination Cache entries need be updated, however. Should a
reachability problem arise with an existing Neighbor Cache entry, Neighbor
Unreachability Detection will perform any needed recovery.*/
}
| bool IPv6NeighbourDiscovery::validateNAPacket | ( | IPv6NeighbourAdvertisement * | na, | |
| IPv6ControlInfo * | naCtrlInfo | |||
| ) | [protected, virtual] |
Definition at line 1934 of file IPv6NeighbourDiscovery.cc.
Referenced by processNAPacket().
{
bool result = true;//adopt optimistic approach
//RFC 2461:7.1.2 Validation of Neighbor Advertisments(some checks are omitted)
//A node MUST silently discard any received Neighbor Advertisment messages
//that do not satisfy all of the following validity checks:
//- The IP Hop Limit field has a value of 255, i.e., the packet
// could not possibly have been forwarded by a router.
if (naCtrlInfo->getHopLimit() != 255)
{
EV << "Hop Limit is not 255! NA validation failed!\n";
result = false;
}
//- Target Address is not a multicast address.
if (na->getTargetAddress().isMulticast() == true)
{
EV << "Target Address is a multicast address! NA validation failed!\n";
result = false;
}
//- If the IP Destination Address is a multicast address the Solicited flag
// is zero.
if (naCtrlInfo->getDestAddr().isMulticast())
{
if (na->getSolicitedFlag() == true)
{
EV << "Dest Address is multicast address but solicted flag is 0!\n";
result = false;
}
}
if (result == true) bubble("NA validation passed.");
else bubble("NA validation failed.");
return result;
}
| bool IPv6NeighbourDiscovery::validateNSPacket | ( | IPv6NeighbourSolicitation * | ns, | |
| IPv6ControlInfo * | nsCtrlInfo | |||
| ) | [protected, virtual] |
Definition at line 1628 of file IPv6NeighbourDiscovery.cc.
Referenced by processNSPacket().
{
bool result = true;
/*RFC 2461:7.1.1. Validation of Neighbor Solicitations(some checks are omitted)
A node MUST silently discard any received Neighbor Solicitation
messages that do not satisfy all of the following validity checks:*/
//- The IP Hop Limit field has a value of 255, i.e., the packet
//could not possibly have been forwarded by a router.
if (nsCtrlInfo->getHopLimit() != 255)
{
EV << "Hop limit is not 255! NS validation failed!\n";
result = false;
}
//- Target Address is not a multicast address.
if (ns->getTargetAddress().isMulticast() == true)
{
EV << "Target address is a multicast address! NS validation failed!\n";
result = false;
}
//- If the IP source address is the unspecified address,
if (nsCtrlInfo->getSrcAddr().isUnspecified())
{
EV << "Source Address is unspecified\n";
//the IP destination address is a solicited-node multicast address.
if (nsCtrlInfo->getDestAddr().matches(IPv6Address::SOLICITED_NODE_PREFIX,104) == false)
{
EV << " but IP dest address is not a solicited-node multicast address! NS validation failed!\n";
result = false;
}
//there is no source link-layer address option in the message.
else if (ns->getSourceLinkLayerAddress().isUnspecified() == false)
{
EV << " but Source link-layer address is not empty! NS validation failed!\n";
result = false;
}
else
EV << "NS Validation Passed\n";
}
return result;
}
| bool IPv6NeighbourDiscovery::validateRAPacket | ( | IPv6RouterAdvertisement * | ra, | |
| IPv6ControlInfo * | raCtrlInfo | |||
| ) | [protected, virtual] |
Definition at line 1529 of file IPv6NeighbourDiscovery.cc.
Referenced by processRAPacket().
{
bool result = true;
//RFC 2461: Section 6.1.2 Validation of Router Advertisement Messages
/*A node MUST silently discard any received Router Advertisement
messages that do not satisfy all of the following validity checks:*/
raCtrlInfo->getSrcAddr();
//- IP Source Address is a link-local address. Routers must use
// their link-local address as the source for Router Advertisement
// and Redirect messages so that hosts can uniquely identify
// routers.
if (raCtrlInfo->getSrcAddr().isLinkLocal() == false)
{
EV << "RA source address is not link-local. RA validation failed!\n";
result = false;
}
//- The IP Hop Limit field has a value of 255, i.e., the packet
// could not possibly have been forwarded by a router.
if (raCtrlInfo->getHopLimit() != 255)
{
EV << "Hop limit is not 255! RA validation failed!\n";
result = false;
}
//- ICMP Code is 0.
if (raCtrlInfo->getProtocol() != IP_PROT_IPv6_ICMP)
{
EV << "ICMP Code is not 0! RA validation failed!\n";
result = false;
}
return result;
}
| bool IPv6NeighbourDiscovery::validateRSPacket | ( | IPv6RouterSolicitation * | rs, | |
| IPv6ControlInfo * | rsCtrlInfo | |||
| ) | [protected, virtual] |
Definition at line 1010 of file IPv6NeighbourDiscovery.cc.
Referenced by processRSPacket().
{
bool result = true;
/*6.1.1. Validation of Router Solicitation Messages
A router MUST silently discard any received Router Solicitation
messages that do not satisfy all of the following validity checks:
- The IP Hop Limit field has a value of 255, i.e., the packet
could not possibly have been forwarded by a router.*/
if (rsCtrlInfo->getHopLimit() != 255)
{
EV << "Hop limit is not 255! RS validation failed!\n";
result = false;
}
//- ICMP Code is 0.
if (rsCtrlInfo->getProtocol() != IP_PROT_IPv6_ICMP)
{
EV << "ICMP Code is not 0! RS validation failed!\n";
result = false;
}
//- If the IP source address is the unspecified address, there is no
//source link-layer address option in the message.
if (rsCtrlInfo->getSrcAddr().isUnspecified())
{
EV << "IP source address is unspecified\n";
if (rs->getSourceLinkLayerAddress().isUnspecified() == false)
{
EV << " but source link layer address is provided. RS validation failed!\n";
}
}
return result;
}
AdvIfList IPv6NeighbourDiscovery::advIfList [protected] |
Definition at line 130 of file IPv6NeighbourDiscovery.h.
Referenced by createRATimer(), and fetchAdvIfEntry().
DADList IPv6NeighbourDiscovery::dadList [protected] |
Definition at line 126 of file IPv6NeighbourDiscovery.h.
Referenced by initiateDAD(), and processDADTimeout().
ICMPv6* IPv6NeighbourDiscovery::icmpv6 [protected] |
Definition at line 92 of file IPv6NeighbourDiscovery.h.
Referenced by dropQueuedPacketsAwaitingAR(), initialize(), and processIPv6Datagram().
IInterfaceTable* IPv6NeighbourDiscovery::ift [protected] |
Definition at line 90 of file IPv6NeighbourDiscovery.h.
Referenced by assignLinkLocalAddress(), initialize(), initiateAddressResolution(), initiateNeighbourUnreachabilityDetection(), processARTimeout(), processDADTimeout(), processNAForIncompleteNCEState(), processNAForOtherNCEStates(), processNAPacket(), processNSPacket(), processNUDTimeout(), processRAForRouterUpdates(), processRAPacket(), and processRSPacket().
Definition at line 93 of file IPv6NeighbourDiscovery.h.
Referenced by dropQueuedPacketsAwaitingAR(), processIPv6Datagram(), processNAPacket(), processNSWithSpecifiedSrcAddr(), processNUDTimeout(), processRAForRouterUpdates(), reachabilityConfirmed(), resolveNeighbour(), selectDefaultRouter(), and timeoutDefaultRouter().
cQueue IPv6NeighbourDiscovery::pendingQueue [protected] |
Definition at line 88 of file IPv6NeighbourDiscovery.h.
Referenced by dropQueuedPacketsAwaitingAR(), initialize(), processIPv6Datagram(), and sendQueuedPacketsToIPv6Module().
RATimerList IPv6NeighbourDiscovery::raTimerList [protected] |
Definition at line 124 of file IPv6NeighbourDiscovery.h.
RDList IPv6NeighbourDiscovery::rdList [protected] |
Definition at line 128 of file IPv6NeighbourDiscovery.h.
Referenced by cancelRouterDiscovery(), fetchRDEntry(), and initiateRouterDiscovery().
RoutingTable6* IPv6NeighbourDiscovery::rt6 [protected] |
Definition at line 91 of file IPv6NeighbourDiscovery.h.
Referenced by determineNextHop(), initialize(), processNSForTentativeAddress(), processRAForRouterUpdates(), processRAPrefixInfo(), sendSolicitedNA(), timeoutDefaultRouter(), and timeoutPrefixEntry().
1.7.1