|
INET Framework for OMNeT++/OMNEST
|
Ipv6 implementation.
More...
#include <Ipv6.h>
|
| | Ipv6 () |
| |
| | ~Ipv6 () |
| |
| virtual void | handleRegisterService (const Protocol &protocol, cGate *gate, ServicePrimitive servicePrimitive) override |
| |
| virtual void | handleRegisterProtocol (const Protocol &protocol, cGate *gate, ServicePrimitive servicePrimitive) override |
| |
| virtual void | registerHook (int priority, IHook *hook) override |
| | Adds the provided hook to the list of registered hooks that will be called by the network layer when it processes datagrams. More...
|
| |
| virtual void | unregisterHook (IHook *hook) override |
| | Removes the provided hook from the list of registered hooks. More...
|
| |
| virtual void | dropQueuedDatagram (const Packet *packet) override |
| | Requests the network layer to drop the datagram, because it's no longer needed. More...
|
| |
| virtual void | reinjectQueuedDatagram (const Packet *packet) override |
| | Requests the network layer to restart the processing of the datagram. More...
|
| |
| virtual | ~NetfilterBase () |
| |
| virtual | ~INetfilter () |
| |
| virtual bool | handleOperationStage (LifecycleOperation *operation, IDoneCallback *doneCallback) override |
| | Perform one stage of a lifecycle operation. More...
|
| |
| virtual | ~ILifecycle () |
| |
| virtual | ~INetworkProtocol () |
| |
| virtual void | handleRegisterServiceGroup (const ProtocolGroup &protocolGroup, cGate *gate, ServicePrimitive servicePrimitive) override |
| |
| virtual void | handleRegisterProtocolGroup (const ProtocolGroup &protocolGroup, cGate *gate, ServicePrimitive servicePrimitive) override |
| |
| virtual void | handleRegisterAnyService (cGate *gate, ServicePrimitive servicePrimitive) override |
| |
| virtual void | handleRegisterAnyProtocol (cGate *gate, ServicePrimitive servicePrimitive) override |
| |
|
| virtual NetworkInterface * | getSourceInterfaceFrom (Packet *msg) |
| |
| virtual void | refreshDisplay () const override |
| |
| virtual void | encapsulate (Packet *transportPacket) |
| | Encapsulate packet coming from higher layers into IPv6Datagram. More...
|
| |
| virtual void | preroutingFinish (Packet *packet, const NetworkInterface *fromIE, const NetworkInterface *destIE, Ipv6Address nextHopAddr) |
| |
| virtual void | handleMessage (cMessage *msg) override |
| |
| virtual void | handleRequest (Request *request) |
| |
| virtual void | handleMessageFromHL (Packet *msg) |
| | Handle messages (typically packets to be send in Ipv6) from transport or ICMP. More...
|
| |
| virtual void | datagramLocalOut (Packet *packet, const NetworkInterface *destIE, Ipv6Address requestedNextHopAddress) |
| |
| virtual void | handleReceivedIcmp (Packet *msg) |
| | Handle incoming ICMP messages. More...
|
| |
| virtual void | routePacket (Packet *packet, const NetworkInterface *destIE, const NetworkInterface *fromIE, Ipv6Address requestedNextHopAddress, bool fromHL) |
| | Performs routing. More...
|
| |
| virtual void | resolveMACAddressAndSendPacket (Packet *packet, int interfaceID, Ipv6Address nextHop, bool fromHL) |
| |
| virtual void | routeMulticastPacket (Packet *packet, const NetworkInterface *destIE, const NetworkInterface *fromIE, bool fromHL) |
| | Forwards packets to all multicast destinations, using fragmentAndSend(). More...
|
| |
| virtual void | fragmentPostRouting (Packet *packet, const NetworkInterface *ie, const MacAddress &nextHopAddr, bool fromHL) |
| |
| virtual void | fragmentAndSend (Packet *packet, const NetworkInterface *destIE, const MacAddress &nextHopAddr, bool fromHL) |
| | Performs fragmentation if needed, and sends the original datagram or the fragments through the specified interface. More...
|
| |
| virtual void | localDeliver (Packet *packet, const NetworkInterface *fromIE) |
| | Perform reassembly of fragmented datagrams, then send them up to the higher layers using sendToHL(). More...
|
| |
| virtual void | decapsulate (Packet *packet) |
| | Decapsulate packet. More...
|
| |
| virtual void | sendDatagramToOutput (Packet *packet, const NetworkInterface *destIE, const MacAddress &macAddr) |
| | Last hoplimit check, then send datagram on the given interface. More...
|
| |
| void | sendIcmpError (Packet *origPacket, Icmpv6Type type, int code) |
| |
| IHook::Result | datagramPreRoutingHook (Packet *packet) |
| | called before a packet arriving from the network is routed More...
|
| |
| IHook::Result | datagramForwardHook (Packet *packet) |
| | called before a packet arriving from the network is delivered via the network More...
|
| |
| IHook::Result | datagramPostRoutingHook (Packet *packet, const NetworkInterface *inIE, const NetworkInterface *&outIE, L3Address &nextHopAddr) |
| | called before a packet is delivered via the network More...
|
| |
| IHook::Result | datagramLocalInHook (Packet *packet, const NetworkInterface *inIE) |
| | called before a packet arriving from the network is delivered locally More...
|
| |
| IHook::Result | datagramLocalOutHook (Packet *packet) |
| | called before a packet arriving locally is delivered More...
|
| |
| virtual void | initialize (int stage) override |
| | Initialization. More...
|
| |
| virtual int | numInitStages () const override |
| |
| bool | determineOutputInterface (const Ipv6Address &destAddress, Ipv6Address &nextHop, int &interfaceId, Packet *packet, bool fromHL) |
| | Determines the correct interface for the specified destination address. More...
|
| |
◆ DatagramQueueForHooks
◆ Ipv6()
◆ ~Ipv6()
◆ datagramForwardHook()
called before a packet arriving from the network is delivered via the network
1157 for (
auto& elem :
hooks) {
1175 throw cRuntimeError(
"Unknown Hook::Result value: %d", (
int)r);
◆ datagramLocalInHook()
called before a packet arriving from the network is delivered locally
1209 for (
auto& elem :
hooks) {
1227 throw cRuntimeError(
"Unknown Hook::Result value: %d", (
int)r);
◆ datagramLocalOut()
◆ datagramLocalOutHook()
called before a packet arriving locally is delivered
1235 for (
auto& elem :
hooks) {
1236 IHook::Result r = elem.second->datagramLocalOutHook(packet);
1253 throw cRuntimeError(
"Unknown Hook::Result value: %d", (
int)r);
Referenced by handleMessage(), and handleMessageFromHL().
◆ datagramPostRoutingHook()
called before a packet is delivered via the network
1183 for (
auto& elem :
hooks) {
1184 IHook::Result r = elem.second->datagramPostRoutingHook(packet);
1201 throw cRuntimeError(
"Unknown Hook::Result value: %d", (
int)r);
Referenced by fragmentPostRouting().
◆ datagramPreRoutingHook()
called before a packet arriving from the network is routed
1131 for (
auto& elem :
hooks) {
1132 IHook::Result r = elem.second->datagramPreRoutingHook(packet);
1149 throw cRuntimeError(
"Unknown Hook::Result value: %d", (
int)r);
Referenced by handleMessage().
◆ decapsulate()
| void inet::Ipv6::decapsulate |
( |
Packet * |
packet | ) |
|
|
protectedvirtual |
Decapsulate packet.
760 auto ipv6Header = packet->popAtFront<Ipv6Header>();
762 B payloadLength = ipv6Header->getPayloadLength();
763 if (payloadLength !=
B(0)) {
764 ASSERT(payloadLength <= packet->getDataLength());
766 if (payloadLength < packet->getDataLength())
767 packet->setBackOffset(packet->getFrontOffset() + payloadLength);
771 packet->addTagIfAbsent<TosInd>()->setTos(ipv6Header->getTrafficClass());
772 packet->addTagIfAbsent<DscpInd>()->setDifferentiatedServicesCodePoint(ipv6Header->getDscp());
773 packet->addTagIfAbsent<EcnInd>()->setExplicitCongestionNotification(ipv6Header->getEcn());
774 packet->addTagIfAbsent<DispatchProtocolInd>()->setProtocol(&
Protocol::ipv6);
775 auto payloadProtocol = ipv6Header->getProtocol();
778 auto networkProtocolInd = packet->addTagIfAbsent<NetworkProtocolInd>();
780 networkProtocolInd->setNetworkProtocolHeader(ipv6Header);
781 auto l3AddressInd = packet->addTagIfAbsent<
L3AddressInd>();
782 l3AddressInd->setSrcAddress(ipv6Header->getSrcAddress());
783 l3AddressInd->setDestAddress(ipv6Header->getDestAddress());
784 packet->addTagIfAbsent<HopLimitInd>()->setHopLimit(ipv6Header->getHopLimit());
Referenced by localDeliver().
◆ determineOutputInterface()
| bool inet::Ipv6::determineOutputInterface |
( |
const Ipv6Address & |
destAddress, |
|
|
Ipv6Address & |
nextHop, |
|
|
int & |
interfaceId, |
|
|
Packet * |
packet, |
|
|
bool |
fromHL |
|
) |
| |
|
protected |
Determines the correct interface for the specified destination address.
The nextHop and interfaceId are output parameter.
975 nextHop =
rt->lookupDestCache(destAddress, interfaceId);
977 if (interfaceId == -1) {
979 EV_INFO <<
"do longest prefix match in routing table" << endl;
980 const Ipv6Route *route =
rt->doLongestPrefixMatch(destAddress);
981 EV_INFO <<
"finished longest prefix match in routing table" << endl;
983 if (
rt->isRouter()) {
984 EV_INFO <<
"unroutable, sending ICMPv6_DESTINATION_UNREACHABLE\n";
989 EV_INFO <<
"no match in routing table, passing datagram to Neighbour Discovery module for default router selection\n";
990 Ipv6NdControlInfo *
ctrl =
new Ipv6NdControlInfo();
991 ctrl->setFromHL(fromHL);
992 ctrl->setNextHop(nextHop);
993 ctrl->setInterfaceId(interfaceId);
994 packet->cMessage::setControlInfo(
ctrl);
995 send(packet,
"ndOut");
999 interfaceId = route->getInterface() ? route->getInterface()->getInterfaceId() : -1;
1000 nextHop = route->getNextHop();
1001 if (nextHop.isUnspecified())
1002 nextHop = destAddress;
1005 rt->updateDestCache(destAddress, nextHop, interfaceId, route->getExpiryTime());
Referenced by routePacket().
◆ dropQueuedDatagram()
| void inet::Ipv6::dropQueuedDatagram |
( |
const Packet * |
daragram | ) |
|
|
overridevirtual |
Requests the network layer to drop the datagram, because it's no longer needed.
This function may be used by a reactive routing protocol when it cancels the route discovery process.
Implements inet::INetfilter.
1082 if (iter->packet == packet) {
◆ encapsulate()
| void inet::Ipv6::encapsulate |
( |
Packet * |
transportPacket | ) |
|
|
protectedvirtual |
Encapsulate packet coming from higher layers into IPv6Datagram.
789 auto ipv6Header = makeShared<Ipv6Header>();
791 auto& addresses = transportPacket->removeTag<L3AddressReq>();
792 Ipv6Address src = addresses->getSrcAddress().toIpv6();
793 Ipv6Address dest = addresses->getDestAddress().toIpv6();
795 auto hopLimitReq = transportPacket->removeTagIfPresent<
HopLimitReq>();
796 short ttl = (hopLimitReq !=
nullptr) ? hopLimitReq->getHopLimit() : -1;
798 ipv6Header->setPayloadLength(transportPacket->getDataLength());
801 ipv6Header->setDestAddress(dest);
802 ipv6Header->setSrcAddress(src);
805 if (
auto& tosReq = transportPacket->removeTagIfPresent<TosReq>()) {
806 ipv6Header->setTrafficClass(tosReq->getTos());
807 if (transportPacket->findTag<
DscpReq>())
808 throw cRuntimeError(
"TosReq and DscpReq found together");
809 if (transportPacket->findTag<EcnReq>())
810 throw cRuntimeError(
"TosReq and EcnReq found together");
812 if (
auto& dscpReq = transportPacket->removeTagIfPresent<
DscpReq>())
813 ipv6Header->setDscp(dscpReq->getDifferentiatedServicesCodePoint());
814 if (
auto& ecnReq = transportPacket->removeTagIfPresent<EcnReq>())
815 ipv6Header->setEcn(ecnReq->getExplicitCongestionNotification());
817 ipv6Header->setHopLimit(ttl != -1 ? ttl : 32);
818 ASSERT(ipv6Header->getHopLimit() > 0);
822 auto extHeadersTag = transportPacket->removeTagIfPresent<Ipv6ExtHeaderReq>();
823 while (extHeadersTag && 0 < extHeadersTag->getExtensionHeaderArraySize()) {
824 Ipv6ExtensionHeader *extHeader = extHeadersTag->removeFirstExtensionHeader();
825 ipv6Header->addExtensionHeader(extHeader);
829 ipv6Header->setChunkLength(
B(ipv6Header->calculateHeaderByteLength()));
830 transportPacket->trimFront();
Referenced by handleMessageFromHL().
◆ fragmentAndSend()
Performs fragmentation if needed, and sends the original datagram or the fragments through the specified interface.
863 auto ipv6Header = packet->peekAtFront<Ipv6Header>();
865 if (ipv6Header->getHopLimit() <= 0) {
867 EV_INFO <<
"datagram hopLimit reached zero, sending ICMPv6_TIME_EXCEEDED\n";
873 if (fromHL && ipv6Header->getSrcAddress().isUnspecified() &&
874 !ipv6Header->getDestAddress().isSolicitedNodeMulticastAddress())
877 const Ipv6Address& srcAddr = ie->getProtocolData<Ipv6InterfaceData>()->getPreferredAddress();
878 ASSERT(!srcAddr.isUnspecified());
881 packet->eraseAtFront(ipv6Header->getChunkLength());
882 auto ipv6HeaderCopy = staticPtrCast<Ipv6Header>(ipv6Header->dupShared());
884 ipv6HeaderCopy->setSrcAddress(srcAddr);
885 packet->insertAtFront(ipv6HeaderCopy);
886 ipv6Header = ipv6HeaderCopy;
888 #ifdef INET_WITH_xMIPv6
891 if (ie->getProtocolData<Ipv6InterfaceData>()->isTentativeAddress(srcAddr)) {
892 EV_INFO <<
"Source address is tentative - enqueueing datagram for later resubmission." << endl;
893 ScheduledDatagram *sDgram =
new ScheduledDatagram(packet, ipv6Header.get(), ie, nextHopAddr, fromHL);
895 scheduleAfter(1.0, sDgram);
901 int mtu = ie->getMtu();
904 if (packet->getTotalLength() <=
B(mtu)) {
917 ipv6Header = packet->popAtFront<Ipv6Header>();
918 B headerLength = ipv6Header->calculateUnfragmentableHeaderByteLength();
919 B payloadLength = packet->getDataLength();
921 ASSERT(fragmentLength >
B(0));
923 int noOfFragments =
B(payloadLength + fragmentLength -
B(1)).get() /
B(fragmentLength).get();
924 EV_INFO <<
"Breaking datagram into " << noOfFragments <<
" fragments\n";
925 std::string fragMsgName = packet->getName();
926 fragMsgName +=
"-frag-";
931 for (
B offset =
B(0); offset < payloadLength; offset += fragmentLength) {
932 bool lastFragment = (offset + fragmentLength >= payloadLength);
933 B thisFragmentLength = lastFragment ? payloadLength - offset : fragmentLength;
935 std::string curFragName = fragMsgName + std::to_string(offset.get());
937 curFragName +=
"-last";
938 Packet *fragPk =
new Packet(curFragName.c_str());
939 const auto& fragHdr = staticPtrCast<Ipv6Header>(ipv6Header->dupShared());
940 auto *fh =
new Ipv6FragmentHeader();
941 fh->setIdentification(identification);
942 fh->setFragmentOffset(offset.get());
943 fh->setMoreFragments(!lastFragment);
944 fragHdr->addExtensionHeader(fh);
945 fragHdr->setChunkLength(headerLength + fh->getByteLength());
946 fragPk->insertAtFront(fragHdr);
947 fragPk->insertAtBack(packet->peekDataAt(offset, thisFragmentLength));
949 ASSERT(fragPk->getDataLength() == headerLength + fh->getByteLength() + thisFragmentLength);
Referenced by fragmentPostRouting().
◆ fragmentPostRouting()
838 auto ipv6Header = packet->peekAtFront<Ipv6Header>();
840 if (fromHL && ipv6Header->getSrcAddress().isUnspecified() &&
841 !ipv6Header->getDestAddress().isSolicitedNodeMulticastAddress())
844 const Ipv6Address& srcAddr = ie->getProtocolData<Ipv6InterfaceData>()->getPreferredAddress();
845 ASSERT(!srcAddr.isUnspecified());
848 ipv6Header =
nullptr;
849 auto newIpv6Header = removeNetworkProtocolHeader<Ipv6Header>(packet);
850 newIpv6Header->setSrcAddress(srcAddr);
852 ipv6Header = newIpv6Header;
854 const NetworkInterface *fromIe = fromHL ? nullptr :
ift->getInterfaceById(packet->getTag<InterfaceInd>()->getInterfaceId());
855 L3Address nextHopAddr_(nextHopAddr);
Referenced by datagramLocalOut(), handleMessage(), resolveMACAddressAndSendPacket(), and routeMulticastPacket().
◆ getSourceInterfaceFrom()
278 const auto& interfaceInd = packet->findTag<InterfaceInd>();
279 return interfaceInd !=
nullptr ?
ift->getInterfaceById(interfaceInd->getInterfaceId()) :
nullptr;
Referenced by handleMessage().
◆ handleMessage()
| void inet::Ipv6::handleMessage |
( |
cMessage * |
msg | ) |
|
|
overrideprotectedvirtual |
189 auto&
tags = check_and_cast<ITaggedObject *>(msg)->getTags();
191 #ifdef INET_WITH_xMIPv6
195 if (msg->isSelfMessage()) {
196 ScheduledDatagram *sDgram = check_and_cast<ScheduledDatagram *>(msg);
199 if (sDgram->getIE()->getProtocolData<Ipv6InterfaceData>()->isTentativeAddress(sDgram->getSrcAddress())) {
202 scheduleAfter(1.0, sDgram);
207 fragmentPostRouting(sDgram->removeDatagram(), sDgram->getIE(), sDgram->getMacAddress(), sDgram->getFromHL());
214 if (
auto request =
dynamic_cast<Request *
>(msg))
216 else if (msg->getArrivalGate()->isName(
"transportIn")
218 || (msg->arrivedOn(
"upperTunnelingIn"))
228 auto packet = check_and_cast<Packet *>(msg);
229 Ipv6NdControlInfo *
ctrl = check_and_cast<Ipv6NdControlInfo *>(msg->removeControlInfo());
230 bool fromHL =
ctrl->getFromHL();
231 Ipv6Address nextHop =
ctrl->getNextHop();
232 int interfaceId =
ctrl->getInterfaceId();
238 auto packet = check_and_cast<Packet *>(msg);
239 auto ipv6Header = packet->peekAtFront<Ipv6Header>();
240 packet->addTagIfAbsent<NetworkProtocolInd>()->setProtocol(&
Protocol::ipv6);
241 packet->addTagIfAbsent<NetworkProtocolInd>()->setNetworkProtocolHeader(ipv6Header);
243 if (packet->getArrivalGate()->isName(
"ndIn")) {
244 Ipv6NdControlInfo *
ctrl = check_and_cast<Ipv6NdControlInfo *>(msg->removeControlInfo());
245 fromHL =
ctrl->getFromHL();
246 Ipv6Address nextHop =
ctrl->getNextHop();
247 int interfaceId =
ctrl->getInterfaceId();
258 ASSERT(!packet->hasBitError());
261 const NetworkInterface *destIE =
nullptr;
265 delete packet->removeControlInfo();
◆ handleMessageFromHL()
| void inet::Ipv6::handleMessageFromHL |
( |
Packet * |
msg | ) |
|
|
protectedvirtual |
Handle messages (typically packets to be send in Ipv6) from transport or ICMP.
Invokes encapsulate(), then routePacket().
301 if (
ift->getNumInterfaces() == 0) {
302 EV_WARN <<
"No interfaces exist, dropping packet\n";
303 PacketDropDetails details;
311 const NetworkInterface *destIE = ifTag ?
ift->getInterfaceById(ifTag->getInterfaceId()) :
nullptr;
315 Ipv6Address src = packet->getTag<L3AddressReq>()->getSrcAddress().toIpv6();
316 if (!src.isUnspecified()) {
318 if (
rt->getInterfaceByAddress(src) ==
nullptr) {
319 #ifdef INET_WITH_xMIPv6
320 EV_WARN <<
"Encapsulation failed - dropping packet." << endl;
321 PacketDropDetails details;
327 throw cRuntimeError(
"Wrong source address %s in (%s)%s: no interface with such address",
328 src.str().c_str(), packet->getClassName(), packet->getFullName());
336 auto ipv6Header = packet->peekAtFront<Ipv6Header>();
337 Ipv6Address destAddress = ipv6Header->getDestAddress();
340 if (!destAddress.isMulticast() &&
rt->isLocalAddress(destAddress)) {
341 EV_INFO <<
"local delivery\n";
342 if (ipv6Header->getSrcAddress().isUnspecified()) {
345 ipv6Header =
nullptr;
346 const auto& newIpv6Header = removeNetworkProtocolHeader<Ipv6Header>(packet);
347 newIpv6Header->setSrcAddress(destAddress);
349 ipv6Header = newIpv6Header;
352 if (destIE && !destIE->isLoopback()) {
353 EV_INFO <<
"datagram destination address is local, ignoring destination interface specified in the control info\n";
357 destIE =
ift->findFirstLoopbackInterface();
Referenced by handleMessage().
◆ handleReceivedIcmp()
| void inet::Ipv6::handleReceivedIcmp |
( |
Packet * |
msg | ) |
|
|
protectedvirtual |
Handle incoming ICMP messages.
746 const auto& icmpHeader = msg->peekAtFront<Icmpv6Header>();
747 if (dynamicPtrCast<const Ipv6NdMessage>(icmpHeader) !=
nullptr) {
748 EV_INFO <<
"Neighbour Discovery packet: passing it to ND module\n";
752 EV_INFO <<
"ICMPv6 packet: passing it to ICMPv6 module\n";
753 send(msg,
"transportOut");
Referenced by localDeliver().
◆ handleRegisterProtocol()
◆ handleRegisterService()
◆ handleRequest()
| void inet::Ipv6::handleRequest |
( |
Request * |
request | ) |
|
|
protectedvirtual |
126 auto ctrl = request->getControlInfo();
128 throw cRuntimeError(
"Request '%s' arrived without controlinfo", request->getName());
129 if (
auto *command =
dynamic_cast<Ipv6SocketBindCommand *
>(
ctrl)) {
130 int socketId = request->getTag<SocketReq>()->getSocketId();
131 SocketDescriptor *descriptor =
new SocketDescriptor(socketId, command->getProtocol()->getId(), command->getLocalAddress());
135 else if (
auto *command =
dynamic_cast<Ipv6SocketConnectCommand *
>(
ctrl)) {
136 int socketId = request->getTag<SocketReq>()->getSocketId();
138 throw cRuntimeError(
"Ipv6Socket: should use bind() before connect()");
142 else if (
dynamic_cast<Ipv6SocketCloseCommand *
>(
ctrl) !=
nullptr) {
144 request->getTag<SocketReq>()->getSocketId();
150 auto ctrl =
new Ipv6SocketClosedIndication();
151 indication->setControlInfo(
ctrl);
152 indication->addTag<SocketInd>()->setSocketId(socketId);
153 send(indication,
"transportOut");
157 else if (
dynamic_cast<Ipv6SocketDestroyCommand *
>(
ctrl) !=
nullptr) {
159 request->getTag<SocketReq>()->getSocketId();
168 throw cRuntimeError(
"Unknown command: '%s' with %s", request->getName(),
ctrl->getClassName());
Referenced by handleMessage().
◆ initialize()
| void inet::Ipv6::initialize |
( |
int |
stage | ) |
|
|
overrideprotectedvirtual |
Initialization.
78 ift.reference(
this,
"interfaceTableModule",
true);
79 rt.reference(
this,
"routingTableModule",
true);
80 nd.reference(
this,
"ipv6NeighbourDiscoveryModule",
true);
81 icmp.reference(
this,
"icmpv6Module",
true);
82 tunneling.reference(
this,
"ipv6TunnelingModule",
true);
102 NodeStatus *nodeStatus = node ? check_and_cast_nullable<NodeStatus *>(node->getSubmodule(
"status")) : nullptr;
103 bool isOperational = (!nodeStatus) || nodeStatus->getState() ==
NodeStatus::UP;
105 throw cRuntimeError(
"This module doesn't support starting in node DOWN state");
◆ localDeliver()
Perform reassembly of fragmented datagrams, then send them up to the higher layers using sendToHL().
649 const auto& ipv6Header = packet->peekAtFront<Ipv6Header>();
652 const Ipv6FragmentHeader *fh =
dynamic_cast<const Ipv6FragmentHeader *
>(ipv6Header->findExtensionHeaderByType(
IP_PROT_IPv6EXT_FRAGMENT));
654 EV_DETAIL <<
"Datagram fragment: offset=" << fh->getFragmentOffset()
655 <<
", MORE=" << (fh->getMoreFragments() ?
"true" :
"false") <<
".\n";
665 EV_DETAIL <<
"No complete datagram yet.\n";
668 EV_DETAIL <<
"This fragment completes the datagram.\n";
671 #ifdef INET_WITH_xMIPv6
674 if (!processExtensionHeaders(packet, ipv6Header.get())) {
683 auto origPacket = packet->
dup();
684 const Protocol *
protocol = ipv6Header->getProtocol();
685 auto remoteAddress(ipv6Header->getSrcAddress());
686 auto localAddress(ipv6Header->getDestAddress());
688 bool hasSocket =
false;
690 if (elem.second->protocolId ==
protocol->getId()
691 && (elem.second->localAddress.isUnspecified() || elem.second->localAddress == localAddress)
692 && (elem.second->remoteAddress.isUnspecified() || elem.second->remoteAddress == remoteAddress))
694 auto *packetCopy = packet->dup();
696 packetCopy->addTagIfAbsent<SocketInd>()->setSocketId(elem.second->socketId);
697 EV_INFO <<
"Passing up to socket " << elem.second->socketId <<
"\n";
699 send(packetCopy,
"transportOut");
707 #ifdef INET_WITH_xMIPv6
711 if (
rt->hasMipv6Support()) {
712 EV_INFO <<
"MIPv6 packet: passing it to xMIPv6 module\n";
713 send(packet,
"xMIPv6Out");
720 EV_INFO <<
"No MIPv6 support on this node!\n";
726 EV_INFO <<
"Tunnelled IP datagram\n";
727 send(packet,
"upperTunnelingOut");
730 EV_INFO <<
"Passing up to protocol " << *
protocol <<
"\n";
732 send(packet,
"transportOut");
734 else if (!hasSocket) {
736 EV_INFO <<
"Transport layer gate not connected - dropping packet!\n";
738 origPacket =
nullptr;
Referenced by routeMulticastPacket(), and routePacket().
◆ numInitStages()
| virtual int inet::Ipv6::numInitStages |
( |
| ) |
const |
|
inlineoverrideprotectedvirtual |
◆ preroutingFinish()
284 const auto& ipv6Header = packet->peekAtFront<Ipv6Header>();
285 Ipv6Address destAddr = ipv6Header->getDestAddress();
287 delete packet->removeControlInfo();
290 if (!destAddr.isMulticast())
291 routePacket(packet, destIE, fromIE, nextHopAddr,
false);
Referenced by handleMessage(), and reinjectQueuedDatagram().
◆ refreshDisplay()
| void inet::Ipv6::refreshDisplay |
( |
| ) |
const |
|
overrideprotectedvirtual |
181 sprintf(buf + strlen(buf),
"DROP:%d ",
numDropped);
184 getDisplayString().setTagArg(
"t", 0, buf);
◆ registerHook()
| void inet::Ipv6::registerHook |
( |
int |
priority, |
|
|
IHook * |
hook |
|
) |
| |
|
overridevirtual |
Adds the provided hook to the list of registered hooks that will be called by the network layer when it processes datagrams.
Reimplemented from inet::NetfilterBase.
◆ reinjectQueuedDatagram()
| void inet::Ipv6::reinjectQueuedDatagram |
( |
const Packet * |
datagram | ) |
|
|
overridevirtual |
Requests the network layer to restart the processing of the datagram.
This function may be used by a reactive routing protocol when it completes the route discovery process.
Implements inet::INetfilter.
1094 if (iter->packet == packet) {
1095 Packet *datagram = iter->packet;
1096 switch (iter->hookType) {
1107 throw cRuntimeError(
"Re-injection of datagram queued for POSTROUTING hook not implemented");
1112 throw cRuntimeError(
"Re-injection of datagram queued for LOCALIN hook not implemented");
1116 throw cRuntimeError(
"Re-injection of datagram queued for FORWARD hook not implemented");
1120 throw cRuntimeError(
"Unknown hook ID: %d", (
int)(iter->hookType));
◆ resolveMACAddressAndSendPacket()
| void inet::Ipv6::resolveMACAddressAndSendPacket |
( |
Packet * |
packet, |
|
|
int |
interfaceID, |
|
|
Ipv6Address |
nextHop, |
|
|
bool |
fromHL |
|
) |
| |
|
protectedvirtual |
478 const auto& ipv6Header = packet->peekAtFront<Ipv6Header>();
479 NetworkInterface *ie =
ift->getInterfaceById(interfaceId);
480 ASSERT(ie !=
nullptr);
481 ASSERT(!nextHop.isUnspecified());
482 Ipv6Address destAddress = ipv6Header->getDestAddress();
483 EV_INFO <<
"next hop for " << destAddress <<
" is " << nextHop <<
", interface " << ie->getInterfaceName() <<
"\n";
485 #ifdef INET_WITH_xMIPv6
486 if (
rt->isMobileNode()) {
489 if (ipv6Header->getSrcAddress() == ie->getProtocolData<Ipv6InterfaceData>()->getMNHomeAddress()
490 && !ie->getProtocolData<Ipv6InterfaceData>()->getGlobalAddress(Ipv6InterfaceData::CoA).isUnspecified())
492 EV_WARN <<
"Using HoA instead of CoA... dropping datagram" << endl;
500 MacAddress macAddr =
nd->resolveNeighbour(nextHop, interfaceId);
501 if (macAddr.isUnspecified()) {
502 if (!ie->isPointToPoint()) {
503 EV_INFO <<
"no link-layer address for next hop yet, passing datagram to Neighbour Discovery module\n";
504 Ipv6NdControlInfo *
ctrl =
new Ipv6NdControlInfo();
505 ctrl->setFromHL(fromHL);
506 ctrl->setNextHop(nextHop);
507 ctrl->setInterfaceId(interfaceId);
508 packet->cMessage::setControlInfo(
ctrl);
509 send(packet,
"ndOut");
514 EV_DETAIL <<
"link-layer address: " << macAddr <<
"\n";
Referenced by handleMessage(), and routePacket().
◆ routeMulticastPacket()
Forwards packets to all multicast destinations, using fragmentAndSend().
523 auto ipv6Header = packet->peekAtFront<Ipv6Header>();
524 const Ipv6Address& destAddr = ipv6Header->getDestAddress();
526 EV_INFO <<
"destination address " << destAddr <<
" is multicast, doing multicast routing\n";
530 if (fromIE !=
nullptr) {
533 if (
rt->isLocalAddress(destAddr)) {
534 EV_INFO <<
"local delivery of multicast packet\n";
540 if (!
rt->isRouter()) {
541 EV_INFO <<
"forwarding is off\n";
547 if (destAddr.getMulticastScope() <= 2) {
548 EV_INFO <<
"multicast dest address is link-local (or smaller) scope\n";
557 ipv6Header =
nullptr;
558 const auto& newIpv6Header = removeNetworkProtocolHeader<Ipv6Header>(packet);
559 newIpv6Header->setHopLimit(ipv6Header->getHopLimit() - 1);
561 ipv6Header = newIpv6Header;
565 EV_INFO <<
"sending out datagram on every interface (except incoming one)\n";
566 for (
int i = 0; i <
ift->getNumInterfaces(); i++) {
567 NetworkInterface *ie =
ift->getInterface(i);
568 if (fromIE != ie && !ie->isLoopback())
Referenced by datagramLocalOut(), and preroutingFinish().
◆ routePacket()
Performs routing.
Based on the routing decision, it dispatches to localDeliver() for local packets, to fragmentAndSend() for forwarded packets, to routeMulticastPacket() for multicast packets, or drops the packet if it's unroutable or forwarding is off.
379 auto ipv6Header = packet->peekAtFront<Ipv6Header>();
381 Ipv6Address destAddress = ipv6Header->getDestAddress();
383 EV_INFO <<
"Routing datagram `" << ipv6Header->getName() <<
"' with dest=" << destAddress <<
", requested nexthop is " << requestedNextHopAddress <<
" on " << (destIE ? destIE->getFullName() :
"unspec") <<
" interface: \n";
386 if (
rt->isLocalAddress(destAddress)) {
388 throw cRuntimeError(
"model error: local unicast packet arrived from HL, but handleMessageFromHL() not detected it");
389 EV_INFO <<
"local delivery\n";
402 if (!
rt->isRouter() && !(packet->getArrivalGate()->isName(
"ndIn"))) {
403 EV_INFO <<
"forwarding is off, dropping packet\n";
410 if (destAddress.isLinkLocal() || destAddress.isLoopback()) {
411 EV_INFO <<
"dest address is link-local (or weaker) scope, doesn't get forwarded\n";
421 ipv6Header =
nullptr;
422 const auto& newIpv6Header = removeNetworkProtocolHeader<Ipv6Header>(packet);
423 newIpv6Header->setHopLimit(newIpv6Header->getHopLimit() - 1);
425 ipv6Header = newIpv6Header;
429 int interfaceId = -1;
430 Ipv6Address nextHop(requestedNextHopAddress);
432 #ifdef INET_WITH_xMIPv6
436 (ipv6Header->getExtensionHeaderArraySize() == 0) &&
437 ((
rt->isMobileNode() &&
rt->isHomeAddress(ipv6Header->getSrcAddress())) ||
439 !
rt->isMobileNode()))
448 interfaceId =
tunneling->getVIfIndexForDest(destAddress);
450 #else // ifdef INET_WITH_xMIPv6
456 if (interfaceId == -1 && destIE !=
nullptr)
457 interfaceId = destIE->getInterfaceId();
459 if (interfaceId >
ift->getBiggestInterfaceId()) {
461 EV_INFO <<
"tunneling: src addr=" << ipv6Header->getSrcAddress() <<
", dest addr=" << destAddress << std::endl;
462 send(packet,
"lowerTunnelingOut");
466 if (interfaceId == -1)
Referenced by datagramLocalOut(), and preroutingFinish().
◆ sendDatagramToOutput()
Last hoplimit check, then send datagram on the given interface.
959 packet->addTagIfAbsent<MacAddressReq>()->setDestAddress(macAddr);
960 packet->addTagIfAbsent<
InterfaceReq>()->setInterfaceId(destIE->getInterfaceId());
962 packet->addTagIfAbsent<DispatchProtocolInd>()->setProtocol(&
Protocol::ipv6);
963 auto protocol = destIE->getProtocol();
968 send(packet,
"queueOut");
Referenced by fragmentAndSend().
◆ sendIcmpError()
| void inet::Ipv6::sendIcmpError |
( |
Packet * |
origPacket, |
|
|
Icmpv6Type |
type, |
|
|
int |
code |
|
) |
| |
|
protected |
◆ unregisterHook()
| void inet::Ipv6::unregisterHook |
( |
IHook * |
hook | ) |
|
|
overridevirtual |
Removes the provided hook from the list of registered hooks.
Reimplemented from inet::NetfilterBase.
◆ curFragmentId
| unsigned int inet::Ipv6::curFragmentId = -1 |
|
protected |
◆ fragbuf
◆ icmp
◆ ift
◆ lastCheckTime
| simtime_t inet::Ipv6::lastCheckTime |
|
protected |
◆ nd
◆ numDropped
| int inet::Ipv6::numDropped = 0 |
|
protected |
◆ numForwarded
| int inet::Ipv6::numForwarded = 0 |
|
protected |
◆ numLocalDeliver
| int inet::Ipv6::numLocalDeliver = 0 |
|
protected |
◆ numMulticast
| int inet::Ipv6::numMulticast = 0 |
|
protected |
◆ numUnroutable
| int inet::Ipv6::numUnroutable = 0 |
|
protected |
◆ queuedDatagramsForHooks
◆ rt
◆ socketIdToSocketDescriptor
◆ tunneling
◆ upperProtocols
| std::set<const Protocol *> inet::Ipv6::upperProtocols |
|
protected |
The documentation for this class was generated from the following files:
cModule * findContainingNode(const cModule *from)
Find the node containing the given module.
Definition: ModuleAccess.cc:31
Ipv6FragBuf fragbuf
Definition: Ipv6.h:72
void init(Icmpv6 *icmp)
Initialize fragmentation buffer.
Definition: Ipv6FragBuf.cc:32
ModuleRefByPar< IInterfaceTable > ift
Definition: Ipv6.h:64
removed DscpReq Ipv4ControlInfo Ipv6ControlInfo up L3AddressInd DispatchProtocolReq L4PortInd Ipv4ControlInfo Ipv6ControlInfo down protocol
Definition: IUdp-gates.txt:25
@ NO_INTERFACE_FOUND
Definition: Simsignals_m.h:74
int numMulticast
Definition: Ipv6.h:78
#define INET_WITH_xMIPv6
Definition: features.h:221
removed DscpReq Ipv4ControlInfo Ipv6ControlInfo up L3AddressInd DispatchProtocolReq L4PortInd Ipv4ControlInfo Ipv6ControlInfo down DscpReq
Definition: IUdp-gates.txt:25
ModuleRefByPar< Icmpv6 > icmp
Definition: Ipv6.h:67
static const Protocol ipv4
Definition: Protocol.h:93
static const Protocol ipv6
Definition: Protocol.h:94
virtual void encapsulate(Packet *transportPacket)
Encapsulate packet coming from higher layers into IPv6Datagram.
Definition: Ipv6.cc:787
simsignal_t packetReceivedFromUpperSignal
Definition: Simsignals.cc:88
@ STOLEN
doesn't allow datagram to pass to next hook, but won't be deleted
Definition: INetfilter.h:43
removed InterfaceReq
Definition: IUdp-gates.txt:11
IHook::Result datagramLocalOutHook(Packet *packet)
called before a packet arriving locally is delivered
Definition: Ipv6.cc:1233
removed DscpReq Ipv4ControlInfo Ipv6ControlInfo up L3AddressInd DispatchProtocolReq L4PortInd Ipv4ControlInfo Ipv6ControlInfo down DispatchProtocolReq
Definition: IUdp-gates.txt:25
INET_API InitStage INITSTAGE_NETWORK_LAYER
Initialization of network layer protocols.
IHook::Result datagramPostRoutingHook(Packet *packet, const NetworkInterface *inIE, const NetworkInterface *&outIE, L3Address &nextHopAddr)
called before a packet is delivered via the network
Definition: Ipv6.cc:1181
removed DscpReq Ipv4ControlInfo Ipv6ControlInfo up L3AddressInd L3AddressInd
Definition: IUdp-gates.txt:20
@ FORWARD
Definition: INetfilter.h:34
virtual void registerHook(int priority, INetfilter::IHook *hook) override
Adds the provided hook to the list of registered hooks that will be called by the network layer when ...
Definition: INetfilter.h:137
DatagramQueueForHooks queuedDatagramsForHooks
Definition: Ipv6.h:109
virtual void handleRequest(Request *request)
Definition: Ipv6.cc:124
virtual void sendDatagramToOutput(Packet *packet, const NetworkInterface *destIE, const MacAddress &macAddr)
Last hoplimit check, then send datagram on the given interface.
Definition: Ipv6.cc:957
std::set< const Protocol * > upperProtocols
Definition: Ipv6.h:74
int numUnroutable
Definition: Ipv6.h:81
Packet * addFragment(Packet *packet, const Ipv6Header *dg, const Ipv6FragmentHeader *fh, simtime_t now)
Takes a fragment and inserts it into the reassembly buffer.
Definition: Ipv6FragBuf.cc:37
std::map< int, SocketDescriptor * > socketIdToSocketDescriptor
Definition: Ipv6.h:75
virtual void fragmentAndSend(Packet *packet, const NetworkInterface *destIE, const MacAddress &nextHopAddr, bool fromHL)
Performs fragmentation if needed, and sends the original datagram or the fragments through the specif...
Definition: Ipv6.cc:861
void registerService(const Protocol &protocol, cGate *gate, ServicePrimitive servicePrimitive)
Registers a service primitive (SDU processing) at the given gate.
Definition: IProtocolRegistrationListener.cc:14
simtime_t lastCheckTime
Definition: Ipv6.h:73
virtual void handleMessageFromHL(Packet *msg)
Handle messages (typically packets to be send in Ipv6) from transport or ICMP.
Definition: Ipv6.cc:296
void insertNetworkProtocolHeader(Packet *packet, const Protocol &protocol, const Ptr< NetworkHeaderBase > &header)
Definition: L3Tools.cc:70
simsignal_t packetDroppedSignal
Definition: Simsignals.cc:85
@ IPv6_I_DATA
Definition: Ipv6SocketCommand_m.h:84
removed DscpReq Ipv4ControlInfo Ipv6ControlInfo up L3AddressInd DispatchProtocolReq L4PortInd Ipv4ControlInfo Ipv6ControlInfo down PacketProtocolTag
Definition: IUdp-gates.txt:25
unsigned int curFragmentId
Definition: Ipv6.h:71
@ IP_PROT_IPv6EXT_FRAGMENT
Definition: IpProtocolId_m.h:114
removed ctrl
Definition: IUdp-gates.txt:7
intscale< b, 1, 8 > B
Definition: Units.h:1168
virtual Packet * dup() const override
Definition: Packet.h:171
ModuleRefByPar< Ipv6Tunneling > tunneling
Definition: Ipv6.h:68
@ ICMPv6_PARAMETER_PROBLEM
Definition: Icmpv6Header_m.h:88
#define FRAGMENT_TIMEOUT
Definition: Ipv6.cc:39
@ QUEUE
queues the datagram for later re-injection (e.g. when route discovery completes)
Definition: INetfilter.h:42
static const Ipv6Address UNSPECIFIED_ADDRESS
The unspecified address.
Definition: Ipv6Address.h:54
int numLocalDeliver
Definition: Ipv6.h:79
Result
Definition: INetfilter.h:39
bool contains(const std::vector< T > &v, const Tk &a)
Definition: stlutils.h:65
virtual void unregisterHook(INetfilter::IHook *hook) override
Removes the provided hook from the list of registered hooks.
Definition: INetfilter.h:142
@ ICMPv6_TIME_EXCEEDED
Definition: Icmpv6Header_m.h:87
removed HopLimitReq
Definition: IUdp-gates.txt:11
removed type
Definition: IUdp-gates.txt:7
INET_API InitStage INITSTAGE_LOCAL
Initialization of local state that don't use or affect other modules includes:
#define NUM_INIT_STAGES
Definition: InitStageRegistry.h:73
ModuleRefByPar< Ipv6RoutingTable > rt
Definition: Ipv6.h:65
simsignal_t packetReceivedFromLowerSignal
Definition: Simsignals.cc:91
virtual void preroutingFinish(Packet *packet, const NetworkInterface *fromIE, const NetworkInterface *destIE, Ipv6Address nextHopAddr)
Definition: Ipv6.cc:282
@ PREROUTING
Definition: INetfilter.h:32
static const Protocol mobileipv6
Definition: Protocol.h:100
virtual void handleReceivedIcmp(Packet *msg)
Handle incoming ICMP messages.
Definition: Ipv6.cc:744
static const Protocol icmpv6
Definition: Protocol.h:72
bool determineOutputInterface(const Ipv6Address &destAddress, Ipv6Address &nextHop, int &interfaceId, Packet *packet, bool fromHL)
Determines the correct interface for the specified destination address.
Definition: Ipv6.cc:971
ModuleRefByPar< Ipv6NeighbourDiscovery > nd
Definition: Ipv6.h:66
@ UP
Definition: NodeStatus.h:28
@ UNRECOGNIZED_NEXT_HDR_TYPE
Definition: Icmpv6Header_m.h:169
std::multimap< int, IHook * > hooks
Definition: INetfilter.h:129
@ DROP
doesn't allow the datagram to pass to the next hook, will be deleted
Definition: INetfilter.h:41
#define Enter_Method(...)
Definition: SelfDoc.h:71
virtual void routeMulticastPacket(Packet *packet, const NetworkInterface *destIE, const NetworkInterface *fromIE, bool fromHL)
Forwards packets to all multicast destinations, using fragmentAndSend().
Definition: Ipv6.cc:521
@ NORMAL
Definition: Ipv6Tunneling.h:44
* tags
Definition: IUdp-gates.txt:3
virtual void decapsulate(Packet *packet)
Decapsulate packet.
Definition: Ipv6.cc:757
IHook::Result datagramPreRoutingHook(Packet *packet)
called before a packet arriving from the network is routed
Definition: Ipv6.cc:1129
static const MacAddress BROADCAST_ADDRESS
The broadcast MAC address, ff:ff:ff:ff:ff:ff.
Definition: MacAddress.h:34
@ ACCEPT
allows the datagram to pass to the next hook
Definition: INetfilter.h:40
@ IP_PROT_IPv6
Definition: IpProtocolId_m.h:99
int numDropped
Definition: Ipv6.h:80
static ProtocolGroup ipprotocol
Definition: ProtocolGroup.h:42
simsignal_t packetSentToUpperSignal
Definition: Simsignals.cc:87
void purgeStaleFragments(simtime_t lastupdate)
Throws out all fragments which are incomplete and their last update (last fragment arrival) was befor...
Definition: Ipv6FragBuf.cc:143
@ ICMPv6_PACKET_TOO_BIG
Definition: Icmpv6Header_m.h:86
virtual void fragmentPostRouting(Packet *packet, const NetworkInterface *ie, const MacAddress &nextHopAddr, bool fromHL)
Definition: Ipv6.cc:835
virtual void resolveMACAddressAndSendPacket(Packet *packet, int interfaceID, Ipv6Address nextHop, bool fromHL)
Definition: Ipv6.cc:476
IpProtocolId
Enum generated from inet/networklayer/common/IpProtocolId.msg:17 by opp_msgtool.
Definition: IpProtocolId_m.h:90
void registerProtocol(const Protocol &protocol, cGate *gate, ServicePrimitive servicePrimitive)
Registers a protocol primitive (PDU processing) at the given gate.
Definition: IProtocolRegistrationListener.cc:83
void sendIcmpError(Packet *origPacket, Icmpv6Type type, int code)
Definition: Ipv6.cc:1259
const B IPv6_FRAGMENT_HEADER_LENGTH
Definition: Ipv6ExtensionHeaders_m.h:62
@ IP_PROT_IPv6EXT_MOB
Definition: IpProtocolId_m.h:117
int numForwarded
Definition: Ipv6.h:82
@ IPv6_I_SOCKET_CLOSED
Definition: Ipv6SocketCommand_m.h:85
@ LOCALIN
Definition: INetfilter.h:33
@ ICMPv6_DESTINATION_UNREACHABLE
Definition: Icmpv6Header_m.h:85
virtual void routePacket(Packet *packet, const NetworkInterface *destIE, const NetworkInterface *fromIE, Ipv6Address requestedNextHopAddress, bool fromHL)
Performs routing.
Definition: Ipv6.cc:377
@ POSTROUTING
Definition: INetfilter.h:35
@ LOCALOUT
Definition: INetfilter.h:36
bool containsKey(const std::map< K, V, _C > &m, const Tk &a)
Definition: stlutils.h:80
virtual void datagramLocalOut(Packet *packet, const NetworkInterface *destIE, Ipv6Address requestedNextHopAddress)
Definition: Ipv6.cc:365
virtual void localDeliver(Packet *packet, const NetworkInterface *fromIE)
Perform reassembly of fragmented datagrams, then send them up to the higher layers using sendToHL().
Definition: Ipv6.cc:647
virtual NetworkInterface * getSourceInterfaceFrom(Packet *msg)
Definition: Ipv6.cc:276