A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
olsr-routing-protocol.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2004 Francisco J. Ros
3 * Copyright (c) 2007 INESC Porto
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Authors: Francisco J. Ros <fjrm@dif.um.es>
19 * Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
20 */
21
22///
23/// \brief Implementation of OLSR agent and related classes.
24///
25/// This is the main file of this software because OLSR's behaviour is
26/// implemented here.
27///
28
29#define NS_LOG_APPEND_CONTEXT \
30 if (GetObject<Node>()) \
31 { \
32 std::clog << "[node " << GetObject<Node>()->GetId() << "] "; \
33 }
34
36
37#include "olsr-repositories.h"
38
39#include "ns3/boolean.h"
40#include "ns3/enum.h"
41#include "ns3/inet-socket-address.h"
42#include "ns3/ipv4-header.h"
43#include "ns3/ipv4-packet-info-tag.h"
44#include "ns3/ipv4-route.h"
45#include "ns3/ipv4-routing-protocol.h"
46#include "ns3/ipv4-routing-table-entry.h"
47#include "ns3/log.h"
48#include "ns3/names.h"
49#include "ns3/simulator.h"
50#include "ns3/socket-factory.h"
51#include "ns3/trace-source-accessor.h"
52#include "ns3/udp-socket-factory.h"
53#include "ns3/uinteger.h"
54
55#include <iomanip>
56#include <iostream>
57
58/********** Useful macros **********/
59
60///
61/// \brief Gets the delay between a given time and the current time.
62///
63/// If given time is previous to the current one, then this macro returns
64/// a number close to 0. This is used for scheduling events at a certain moment.
65///
66#define DELAY(time) \
67 (((time) < (Simulator::Now())) ? Seconds(0.000001) \
68 : (time - Simulator::Now() + Seconds(0.000001)))
69
70///
71/// \brief Period at which a node must cite every link and every neighbor.
72///
73/// We only use this value in order to define OLSR_NEIGHB_HOLD_TIME.
74///
75#define OLSR_REFRESH_INTERVAL m_helloInterval
76
77/********** Holding times **********/
78
79/// Neighbor holding time.
80#define OLSR_NEIGHB_HOLD_TIME Time(3 * OLSR_REFRESH_INTERVAL)
81/// Top holding time.
82#define OLSR_TOP_HOLD_TIME Time(3 * m_tcInterval)
83/// Dup holding time.
84#define OLSR_DUP_HOLD_TIME Seconds(30)
85/// MID holding time.
86#define OLSR_MID_HOLD_TIME Time(3 * m_midInterval)
87/// HNA holding time.
88#define OLSR_HNA_HOLD_TIME Time(3 * m_hnaInterval)
89
90/********** Miscellaneous constants **********/
91
92/// Maximum allowed jitter.
93#define OLSR_MAXJITTER (m_helloInterval.GetSeconds() / 4)
94/// Maximum allowed sequence number.
95#define OLSR_MAX_SEQ_NUM 65535
96/// Random number between [0-OLSR_MAXJITTER] used to jitter OLSR packet transmission.
97#define JITTER (Seconds(m_uniformRandomVariable->GetValue(0, OLSR_MAXJITTER)))
98
99/// Maximum number of messages per packet.
100#define OLSR_MAX_MSGS 64
101
102/// Maximum number of hellos per message (4 possible link types * 3 possible nb types).
103#define OLSR_MAX_HELLOS 12
104
105/// Maximum number of addresses advertised on a message.
106#define OLSR_MAX_ADDRS 64
107
108namespace ns3
109{
110
111NS_LOG_COMPONENT_DEFINE("OlsrRoutingProtocol");
112
113namespace olsr
114{
115
116/**
117 * \ingroup olsr
118 *
119 * OLSR link types.
120 * See \RFC{3626} section 18.5.
121 */
122enum class LinkType : uint8_t
123{
124 UNSPEC_LINK = 0, //!< Unspecified link type
125 ASYM_LINK = 1, //!< Asymmetric link type
126 SYM_LINK = 2, //!< Symmetric link type
127 LOST_LINK = 3, //!< Lost link type
128};
129
130/**
131 * Stream insertion operator for OLSR link type.
132 *
133 * \param os Output stream.
134 * \param linkType OLSR link type.
135 * \return A reference to the output stream.
136 */
137inline std::ostream&
138operator<<(std::ostream& os, LinkType linkType)
139{
140 switch (linkType)
141 {
143 return (os << "UNSPEC_LINK");
145 return (os << "ASYM_LINK");
147 return (os << "SYM_LINK");
149 return (os << "LOST_LINK");
150 default:
151 return (os << "Unknown link type");
152 }
153}
154
155/**
156 * \ingroup olsr
157 *
158 * OLSR neighbor types.
159 * See \RFC{3626} section 18.6.
160 */
161enum class NeighborType : uint8_t
162{
163 NOT_NEIGH = 0, //!< Not neighbor type
164 SYM_NEIGH = 1, //!< Symmetric neighbor type
165 MPR_NEIGH = 2, //!< Asymmetric neighbor type
166};
167
168/**
169 * Stream insertion operator for OLSR link type.
170 *
171 * \param os Output stream.
172 * \param neighborType OLSR neighbor type.
173 * \return A reference to the output stream.
174 */
175inline std::ostream&
176operator<<(std::ostream& os, NeighborType neighborType)
177{
178 switch (neighborType)
179 {
181 return (os << "NOT_NEIGH");
183 return (os << "SYM_NEIGH");
185 return (os << "MPR_NEIGH");
186 default:
187 return (os << "Unknown neighbor type");
188 }
189}
190
191/********** OLSR class **********/
192
193NS_OBJECT_ENSURE_REGISTERED(RoutingProtocol);
194
195/* see https://www.iana.org/assignments/service-names-port-numbers */
196const uint16_t RoutingProtocol::OLSR_PORT_NUMBER = 698;
197
198TypeId
200{
201 static TypeId tid =
202 TypeId("ns3::olsr::RoutingProtocol")
204 .SetGroupName("Olsr")
205 .AddConstructor<RoutingProtocol>()
206 .AddAttribute("HelloInterval",
207 "HELLO messages emission interval.",
208 TimeValue(Seconds(2)),
211 .AddAttribute("TcInterval",
212 "TC messages emission interval.",
213 TimeValue(Seconds(5)),
216 .AddAttribute("MidInterval",
217 "MID messages emission interval. Normally it is equal to TcInterval.",
218 TimeValue(Seconds(5)),
221 .AddAttribute("HnaInterval",
222 "HNA messages emission interval. Normally it is equal to TcInterval.",
223 TimeValue(Seconds(5)),
226 .AddAttribute("Willingness",
227 "Willingness of a node to carry and forward traffic for other nodes.",
229 MakeEnumAccessor<Willingness>(&RoutingProtocol::m_willingness),
231 "never",
233 "low",
235 "default",
237 "high",
239 "always"))
240 .AddTraceSource("Rx",
241 "Receive OLSR packet.",
243 "ns3::olsr::RoutingProtocol::PacketTxRxTracedCallback")
244 .AddTraceSource("Tx",
245 "Send OLSR packet.",
247 "ns3::olsr::RoutingProtocol::PacketTxRxTracedCallback")
248 .AddTraceSource("RoutingTableChanged",
249 "The OLSR routing table has changed.",
251 "ns3::olsr::RoutingProtocol::TableChangeTracedCallback");
252 return tid;
253}
254
256 : m_routingTableAssociation(nullptr),
257 m_ipv4(nullptr),
258 m_helloTimer(Timer::CANCEL_ON_DESTROY),
259 m_tcTimer(Timer::CANCEL_ON_DESTROY),
260 m_midTimer(Timer::CANCEL_ON_DESTROY),
261 m_hnaTimer(Timer::CANCEL_ON_DESTROY),
262 m_queuedMessagesTimer(Timer::CANCEL_ON_DESTROY)
263{
264 m_uniformRandomVariable = CreateObject<UniformRandomVariable>();
265
266 m_hnaRoutingTable = Create<Ipv4StaticRouting>();
267}
268
270{
271}
272
273void
275{
276 NS_ASSERT(ipv4);
278 NS_LOG_DEBUG("Created olsr::RoutingProtocol");
284
288
290
291 m_ipv4 = ipv4;
292
293 m_hnaRoutingTable->SetIpv4(ipv4);
294}
295
296void
298{
299 m_ipv4 = nullptr;
300 m_hnaRoutingTable = nullptr;
302
303 if (m_recvSocket)
304 {
306 m_recvSocket = nullptr;
307 }
308
309 for (auto iter = m_sendSockets.begin(); iter != m_sendSockets.end(); iter++)
310 {
311 iter->first->Close();
312 }
313 m_sendSockets.clear();
314 m_table.clear();
315
317}
318
319void
321{
322 std::ostream* os = stream->GetStream();
323 // Copy the current ostream state
324 std::ios oldState(nullptr);
325 oldState.copyfmt(*os);
326
327 *os << std::resetiosflags(std::ios::adjustfield) << std::setiosflags(std::ios::left);
328
329 *os << "Node: " << m_ipv4->GetObject<Node>()->GetId() << ", Time: " << Now().As(unit)
330 << ", Local time: " << m_ipv4->GetObject<Node>()->GetLocalTime().As(unit)
331 << ", OLSR Routing table" << std::endl;
332
333 *os << std::setw(16) << "Destination";
334 *os << std::setw(16) << "NextHop";
335 *os << std::setw(16) << "Interface";
336 *os << "Distance" << std::endl;
337
338 for (auto iter = m_table.begin(); iter != m_table.end(); iter++)
339 {
340 std::ostringstream dest;
341 std::ostringstream nextHop;
342 dest << iter->first;
343 nextHop << iter->second.nextAddr;
344 *os << std::setw(16) << dest.str();
345 *os << std::setw(16) << nextHop.str();
346 *os << std::setw(16);
347 if (!Names::FindName(m_ipv4->GetNetDevice(iter->second.interface)).empty())
348 {
349 *os << Names::FindName(m_ipv4->GetNetDevice(iter->second.interface));
350 }
351 else
352 {
353 *os << iter->second.interface;
354 }
355 *os << iter->second.distance << std::endl;
356 }
357 *os << std::endl;
358
359 // Also print the HNA routing table
360 if (m_hnaRoutingTable->GetNRoutes() > 0)
361 {
362 *os << "HNA Routing Table:" << std::endl;
363 m_hnaRoutingTable->PrintRoutingTable(stream, unit);
364 }
365 else
366 {
367 *os << "HNA Routing Table: empty" << std::endl << std::endl;
368 }
369 // Restore the previous ostream state
370 (*os).copyfmt(oldState);
371}
372
373void
375{
376 if (m_mainAddress == Ipv4Address())
377 {
378 Ipv4Address loopback("127.0.0.1");
379 for (uint32_t i = 0; i < m_ipv4->GetNInterfaces(); i++)
380 {
381 // Use primary address, if multiple
382 Ipv4Address addr = m_ipv4->GetAddress(i, 0).GetLocal();
383 if (addr != loopback)
384 {
385 m_mainAddress = addr;
386 break;
387 }
388 }
389
391 }
392
393 NS_LOG_DEBUG("Starting OLSR on node " << m_mainAddress);
394
395 Ipv4Address loopback("127.0.0.1");
396
397 bool canRunOlsr = false;
398 for (uint32_t i = 0; i < m_ipv4->GetNInterfaces(); i++)
399 {
400 Ipv4Address addr = m_ipv4->GetAddress(i, 0).GetLocal();
401 if (addr == loopback)
402 {
403 continue;
404 }
405
406 if (addr != m_mainAddress)
407 {
408 // Create never expiring interface association tuple entries for our
409 // own network interfaces, so that GetMainAddress () works to
410 // translate the node's own interface addresses into the main address.
411 IfaceAssocTuple tuple;
412 tuple.ifaceAddr = addr;
413 tuple.mainAddr = m_mainAddress;
414 AddIfaceAssocTuple(tuple);
416 }
417
418 if (m_interfaceExclusions.find(i) != m_interfaceExclusions.end())
419 {
420 continue;
421 }
422
423 // Create a socket to listen on all the interfaces
424 if (!m_recvSocket)
425 {
430 if (m_recvSocket->Bind(inetAddr))
431 {
432 NS_FATAL_ERROR("Failed to bind() OLSR socket");
433 }
436 }
437
438 // Create a socket to send packets from this specific interfaces
439 Ptr<Socket> socket = Socket::CreateSocket(GetObject<Node>(), UdpSocketFactory::GetTypeId());
440 socket->SetAllowBroadcast(true);
441 socket->SetIpTtl(1);
442 InetSocketAddress inetAddr(m_ipv4->GetAddress(i, 0).GetLocal(), OLSR_PORT_NUMBER);
443 socket->SetRecvCallback(MakeCallback(&RoutingProtocol::RecvOlsr, this));
444 socket->BindToNetDevice(m_ipv4->GetNetDevice(i));
445 if (socket->Bind(inetAddr))
446 {
447 NS_FATAL_ERROR("Failed to bind() OLSR socket");
448 }
449 socket->SetRecvPktInfo(true);
450 m_sendSockets[socket] = m_ipv4->GetAddress(i, 0);
451
452 canRunOlsr = true;
453 }
454
455 if (canRunOlsr)
456 {
461
462 NS_LOG_DEBUG("OLSR on node " << m_mainAddress << " started");
463 }
464}
465
466void
468{
469 m_mainAddress = m_ipv4->GetAddress(interface, 0).GetLocal();
470}
471
472void
473RoutingProtocol::SetInterfaceExclusions(std::set<uint32_t> exceptions)
474{
475 m_interfaceExclusions = exceptions;
476}
477
478//
479// \brief Processes an incoming %OLSR packet following \RFC{3626} specification.
480void
482{
483 Ptr<Packet> receivedPacket;
484 Address sourceAddress;
485 receivedPacket = socket->RecvFrom(sourceAddress);
486
487 Ipv4PacketInfoTag interfaceInfo;
488 if (!receivedPacket->RemovePacketTag(interfaceInfo))
489 {
490 NS_ABORT_MSG("No incoming interface on OLSR message, aborting.");
491 }
492 uint32_t incomingIf = interfaceInfo.GetRecvIf();
493 Ptr<Node> node = this->GetObject<Node>();
494 Ptr<NetDevice> dev = node->GetDevice(incomingIf);
495 uint32_t recvInterfaceIndex = m_ipv4->GetInterfaceForDevice(dev);
496
497 if (m_interfaceExclusions.find(recvInterfaceIndex) != m_interfaceExclusions.end())
498 {
499 return;
500 }
501
502 InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom(sourceAddress);
503 Ipv4Address senderIfaceAddr = inetSourceAddr.GetIpv4();
504
505 int32_t interfaceForAddress = m_ipv4->GetInterfaceForAddress(senderIfaceAddr);
506 if (interfaceForAddress != -1)
507 {
508 NS_LOG_LOGIC("Ignoring a packet sent by myself.");
509 return;
510 }
511
512 Ipv4Address receiverIfaceAddr = m_ipv4->GetAddress(recvInterfaceIndex, 0).GetLocal();
513 NS_ASSERT(receiverIfaceAddr != Ipv4Address());
514 NS_LOG_DEBUG("OLSR node " << m_mainAddress << " received a OLSR packet from " << senderIfaceAddr
515 << " to " << receiverIfaceAddr);
516
517 // All routing messages are sent from and to port RT_PORT,
518 // so we check it.
519 NS_ASSERT(inetSourceAddr.GetPort() == OLSR_PORT_NUMBER);
520
521 Ptr<Packet> packet = receivedPacket;
522
523 olsr::PacketHeader olsrPacketHeader;
524 packet->RemoveHeader(olsrPacketHeader);
525 NS_ASSERT(olsrPacketHeader.GetPacketLength() >= olsrPacketHeader.GetSerializedSize());
526 uint32_t sizeLeft = olsrPacketHeader.GetPacketLength() - olsrPacketHeader.GetSerializedSize();
527
528 MessageList messages;
529
530 while (sizeLeft)
531 {
532 MessageHeader messageHeader;
533 if (packet->RemoveHeader(messageHeader) == 0)
534 {
535 NS_ASSERT(false);
536 }
537
538 sizeLeft -= messageHeader.GetSerializedSize();
539
540 NS_LOG_DEBUG("Olsr Msg received with type "
541 << std::dec << int(messageHeader.GetMessageType())
542 << " TTL=" << int(messageHeader.GetTimeToLive())
543 << " origAddr=" << messageHeader.GetOriginatorAddress());
544 messages.push_back(messageHeader);
545 }
546
547 m_rxPacketTrace(olsrPacketHeader, messages);
548
549 for (auto messageIter = messages.begin(); messageIter != messages.end(); messageIter++)
550 {
551 const MessageHeader& messageHeader = *messageIter;
552 // If ttl is less than or equal to zero, or
553 // the receiver is the same as the originator,
554 // the message must be silently dropped
555 if (messageHeader.GetTimeToLive() == 0 ||
556 messageHeader.GetOriginatorAddress() == m_mainAddress)
557 {
558 packet->RemoveAtStart(messageHeader.GetSerializedSize() -
559 messageHeader.GetSerializedSize());
560 continue;
561 }
562
563 // If the message has been processed it must not be processed again
564 bool do_forwarding = true;
565 DuplicateTuple* duplicated =
567 messageHeader.GetMessageSequenceNumber());
568
569 // Get main address of the peer, which may be different from the packet source address
570 // const IfaceAssocTuple *ifaceAssoc = m_state.FindIfaceAssocTuple
571 // (inetSourceAddr.GetIpv4 ()); Ipv4Address peerMainAddress; if (ifaceAssoc != NULL)
572 // {
573 // peerMainAddress = ifaceAssoc->mainAddr;
574 // }
575 // else
576 // {
577 // peerMainAddress = inetSourceAddr.GetIpv4 () ;
578 // }
579
580 if (duplicated == nullptr)
581 {
582 switch (messageHeader.GetMessageType())
583 {
586 << " OLSR node " << m_mainAddress << " received HELLO message of size "
587 << messageHeader.GetSerializedSize());
588 ProcessHello(messageHeader, receiverIfaceAddr, senderIfaceAddr);
589 break;
590
593 << " OLSR node " << m_mainAddress << " received TC message of size "
594 << messageHeader.GetSerializedSize());
595 ProcessTc(messageHeader, senderIfaceAddr);
596 break;
597
600 << " OLSR node " << m_mainAddress << " received MID message of size "
601 << messageHeader.GetSerializedSize());
602 ProcessMid(messageHeader, senderIfaceAddr);
603 break;
606 << " OLSR node " << m_mainAddress << " received HNA message of size "
607 << messageHeader.GetSerializedSize());
608 ProcessHna(messageHeader, senderIfaceAddr);
609 break;
610
611 default:
612 NS_LOG_DEBUG("OLSR message type " << int(messageHeader.GetMessageType())
613 << " not implemented");
614 }
615 }
616 else
617 {
618 NS_LOG_DEBUG("OLSR message is duplicated, not reading it.");
619
620 // If the message has been considered for forwarding, it should
621 // not be retransmitted again
622 for (auto it = duplicated->ifaceList.begin(); it != duplicated->ifaceList.end(); it++)
623 {
624 if (*it == receiverIfaceAddr)
625 {
626 do_forwarding = false;
627 break;
628 }
629 }
630 }
631
632 if (do_forwarding)
633 {
634 // HELLO messages are never forwarded.
635 // TC and MID messages are forwarded using the default algorithm.
636 // Remaining messages are also forwarded using the default algorithm.
638 {
639 ForwardDefault(messageHeader,
640 duplicated,
641 receiverIfaceAddr,
642 inetSourceAddr.GetIpv4());
643 }
644 }
645 }
646
647 // After processing all OLSR messages, we must recompute the routing table
649}
650
651///
652/// \brief This auxiliary function (defined in \RFC{3626}) is used for calculating the MPR Set.
653///
654/// \param tuple the neighbor tuple which has the main address of the node we are going to calculate
655/// its degree to.
656/// \return the degree of the node.
657///
658int
660{
661 int degree = 0;
662 for (auto it = m_state.GetTwoHopNeighbors().begin(); it != m_state.GetTwoHopNeighbors().end();
663 it++)
664 {
665 const TwoHopNeighborTuple& nb2hop_tuple = *it;
666 if (nb2hop_tuple.neighborMainAddr == tuple.neighborMainAddr)
667 {
668 const NeighborTuple* nb_tuple =
670 if (nb_tuple == nullptr)
671 {
672 degree++;
673 }
674 }
675 }
676 return degree;
677}
678
679namespace
680{
681///
682/// \brief Remove all covered 2-hop neighbors from N2 set.
683/// This is a helper function used by MprComputation algorithm.
684///
685/// \param neighborMainAddr Neighbor main address.
686/// \param N2 Reference to the 2-hop neighbor set.
687///
688void
690{
691 // first gather all 2-hop neighbors to be removed
692 std::set<Ipv4Address> toRemove;
693 for (auto twoHopNeigh = N2.begin(); twoHopNeigh != N2.end(); twoHopNeigh++)
694 {
695 if (twoHopNeigh->neighborMainAddr == neighborMainAddr)
696 {
697 toRemove.insert(twoHopNeigh->twoHopNeighborAddr);
698 }
699 }
700 // Now remove all matching records from N2
701 for (auto twoHopNeigh = N2.begin(); twoHopNeigh != N2.end();)
702 {
703 if (toRemove.find(twoHopNeigh->twoHopNeighborAddr) != toRemove.end())
704 {
705 twoHopNeigh = N2.erase(twoHopNeigh);
706 }
707 else
708 {
709 twoHopNeigh++;
710 }
711 }
712}
713} // unnamed namespace
714
715void
717{
718 NS_LOG_FUNCTION(this);
719
720 // MPR computation should be done for each interface. See section 8.3.1
721 // (RFC 3626) for details.
722 MprSet mprSet;
723
724 // N is the subset of neighbors of the node, which are
725 // neighbor "of the interface I"
726 NeighborSet N;
727 for (auto neighbor = m_state.GetNeighbors().begin(); neighbor != m_state.GetNeighbors().end();
728 neighbor++)
729 {
730 if (neighbor->status == NeighborTuple::STATUS_SYM) // I think that we need this check
731 {
732 N.push_back(*neighbor);
733 }
734 }
735
736 // N2 is the set of 2-hop neighbors reachable from "the interface
737 // I", excluding:
738 // (i) the nodes only reachable by members of N with willingness Willingness::NEVER
739 // (ii) the node performing the computation
740 // (iii) all the symmetric neighbors: the nodes for which there exists a symmetric
741 // link to this node on some interface.
743 for (auto twoHopNeigh = m_state.GetTwoHopNeighbors().begin();
744 twoHopNeigh != m_state.GetTwoHopNeighbors().end();
745 twoHopNeigh++)
746 {
747 // excluding:
748 // (ii) the node performing the computation
749 if (twoHopNeigh->twoHopNeighborAddr == m_mainAddress)
750 {
751 continue;
752 }
753
754 // excluding:
755 // (i) the nodes only reachable by members of N with willingness Willingness::NEVER
756 bool ok = false;
757 for (auto neigh = N.begin(); neigh != N.end(); neigh++)
758 {
759 if (neigh->neighborMainAddr == twoHopNeigh->neighborMainAddr)
760 {
761 ok = (neigh->willingness != Willingness::NEVER);
762 break;
763 }
764 }
765 if (!ok)
766 {
767 continue;
768 }
769
770 // excluding:
771 // (iii) all the symmetric neighbors: the nodes for which there exists a symmetric
772 // link to this node on some interface.
773 for (auto neigh = N.begin(); neigh != N.end(); neigh++)
774 {
775 if (neigh->neighborMainAddr == twoHopNeigh->twoHopNeighborAddr)
776 {
777 ok = false;
778 break;
779 }
780 }
781
782 if (ok)
783 {
784 N2.push_back(*twoHopNeigh);
785 }
786 }
787
788#ifdef NS3_LOG_ENABLE
789 {
790 std::ostringstream os;
791 os << "[";
792 for (auto iter = N2.begin(); iter != N2.end(); iter++)
793 {
794 auto next = iter;
795 next++;
796 os << iter->neighborMainAddr << "->" << iter->twoHopNeighborAddr;
797 if (next != N2.end())
798 {
799 os << ", ";
800 }
801 }
802 os << "]";
803 NS_LOG_DEBUG("N2: " << os.str());
804 }
805#endif // NS3_LOG_ENABLE
806
807 // 1. Start with an MPR set made of all members of N with
808 // N_willingness equal to Willingness::ALWAYS
809 for (auto neighbor = N.begin(); neighbor != N.end(); neighbor++)
810 {
811 if (neighbor->willingness == Willingness::ALWAYS)
812 {
813 mprSet.insert(neighbor->neighborMainAddr);
814 // (not in RFC but I think is needed: remove the 2-hop
815 // neighbors reachable by the MPR from N2)
816 CoverTwoHopNeighbors(neighbor->neighborMainAddr, N2);
817 }
818 }
819
820 // 2. Calculate D(y), where y is a member of N, for all nodes in N.
821 // (we do this later)
822
823 // 3. Add to the MPR set those nodes in N, which are the *only*
824 // nodes to provide reachability to a node in N2.
825 std::set<Ipv4Address> coveredTwoHopNeighbors;
826 for (auto twoHopNeigh = N2.begin(); twoHopNeigh != N2.end(); twoHopNeigh++)
827 {
828 bool onlyOne = true;
829 // try to find another neighbor that can reach twoHopNeigh->twoHopNeighborAddr
830 for (auto otherTwoHopNeigh = N2.begin(); otherTwoHopNeigh != N2.end(); otherTwoHopNeigh++)
831 {
832 if (otherTwoHopNeigh->twoHopNeighborAddr == twoHopNeigh->twoHopNeighborAddr &&
833 otherTwoHopNeigh->neighborMainAddr != twoHopNeigh->neighborMainAddr)
834 {
835 onlyOne = false;
836 break;
837 }
838 }
839 if (onlyOne)
840 {
841 NS_LOG_LOGIC("Neighbor " << twoHopNeigh->neighborMainAddr
842 << " is the only that can reach 2-hop neigh. "
843 << twoHopNeigh->twoHopNeighborAddr << " => select as MPR.");
844
845 mprSet.insert(twoHopNeigh->neighborMainAddr);
846
847 // take note of all the 2-hop neighbors reachable by the newly elected MPR
848 for (auto otherTwoHopNeigh = N2.begin(); otherTwoHopNeigh != N2.end();
849 otherTwoHopNeigh++)
850 {
851 if (otherTwoHopNeigh->neighborMainAddr == twoHopNeigh->neighborMainAddr)
852 {
853 coveredTwoHopNeighbors.insert(otherTwoHopNeigh->twoHopNeighborAddr);
854 }
855 }
856 }
857 }
858 // Remove the nodes from N2 which are now covered by a node in the MPR set.
859 for (auto twoHopNeigh = N2.begin(); twoHopNeigh != N2.end();)
860 {
861 if (coveredTwoHopNeighbors.find(twoHopNeigh->twoHopNeighborAddr) !=
862 coveredTwoHopNeighbors.end())
863 {
864 // This works correctly only because it is known that twoHopNeigh is reachable by
865 // exactly one neighbor, so only one record in N2 exists for each of them. This record
866 // is erased here.
867 NS_LOG_LOGIC("2-hop neigh. " << twoHopNeigh->twoHopNeighborAddr
868 << " is already covered by an MPR.");
869 twoHopNeigh = N2.erase(twoHopNeigh);
870 }
871 else
872 {
873 twoHopNeigh++;
874 }
875 }
876
877 // 4. While there exist nodes in N2 which are not covered by at
878 // least one node in the MPR set:
879 while (N2.begin() != N2.end())
880 {
881#ifdef NS3_LOG_ENABLE
882 {
883 std::ostringstream os;
884 os << "[";
885 for (auto iter = N2.begin(); iter != N2.end(); iter++)
886 {
887 auto next = iter;
888 next++;
889 os << iter->neighborMainAddr << "->" << iter->twoHopNeighborAddr;
890 if (next != N2.end())
891 {
892 os << ", ";
893 }
894 }
895 os << "]";
896 NS_LOG_DEBUG("Step 4 iteration: N2=" << os.str());
897 }
898#endif // NS3_LOG_ENABLE
899
900 // 4.1. For each node in N, calculate the reachability, i.e., the
901 // number of nodes in N2 which are not yet covered by at
902 // least one node in the MPR set, and which are reachable
903 // through this 1-hop neighbor
904 std::map<int, std::vector<const NeighborTuple*>> reachability;
905 std::set<int> rs;
906 for (auto it = N.begin(); it != N.end(); it++)
907 {
908 const NeighborTuple& nb_tuple = *it;
909 int r = 0;
910 for (auto it2 = N2.begin(); it2 != N2.end(); it2++)
911 {
912 const TwoHopNeighborTuple& nb2hop_tuple = *it2;
913 if (nb_tuple.neighborMainAddr == nb2hop_tuple.neighborMainAddr)
914 {
915 r++;
916 }
917 }
918 rs.insert(r);
919 reachability[r].push_back(&nb_tuple);
920 }
921
922 // 4.2. Select as a MPR the node with highest N_willingness among
923 // the nodes in N with non-zero reachability. In case of
924 // multiple choice select the node which provides
925 // reachability to the maximum number of nodes in N2. In
926 // case of multiple nodes providing the same amount of
927 // reachability, select the node as MPR whose D(y) is
928 // greater. Remove the nodes from N2 which are now covered
929 // by a node in the MPR set.
930 const NeighborTuple* max = nullptr;
931 int max_r = 0;
932 for (auto it = rs.begin(); it != rs.end(); it++)
933 {
934 int r = *it;
935 if (r == 0)
936 {
937 continue;
938 }
939 for (auto it2 = reachability[r].begin(); it2 != reachability[r].end(); it2++)
940 {
941 const NeighborTuple* nb_tuple = *it2;
942 if (max == nullptr || nb_tuple->willingness > max->willingness)
943 {
944 max = nb_tuple;
945 max_r = r;
946 }
947 else if (nb_tuple->willingness == max->willingness)
948 {
949 if (r > max_r)
950 {
951 max = nb_tuple;
952 max_r = r;
953 }
954 else if (r == max_r)
955 {
956 if (Degree(*nb_tuple) > Degree(*max))
957 {
958 max = nb_tuple;
959 max_r = r;
960 }
961 }
962 }
963 }
964 }
965
966 if (max != nullptr)
967 {
968 mprSet.insert(max->neighborMainAddr);
969 CoverTwoHopNeighbors(max->neighborMainAddr, N2);
970 NS_LOG_LOGIC(N2.size() << " 2-hop neighbors left to cover!");
971 }
972 }
973
974#ifdef NS3_LOG_ENABLE
975 {
976 std::ostringstream os;
977 os << "[";
978 for (auto iter = mprSet.begin(); iter != mprSet.end(); iter++)
979 {
980 auto next = iter;
981 next++;
982 os << *iter;
983 if (next != mprSet.end())
984 {
985 os << ", ";
986 }
987 }
988 os << "]";
989 NS_LOG_DEBUG("Computed MPR set for node " << m_mainAddress << ": " << os.str());
990 }
991#endif // NS3_LOG_ENABLE
992
993 m_state.SetMprSet(mprSet);
994}
995
998{
999 const IfaceAssocTuple* tuple = m_state.FindIfaceAssocTuple(iface_addr);
1000
1001 if (tuple != nullptr)
1002 {
1003 return tuple->mainAddr;
1004 }
1005 else
1006 {
1007 return iface_addr;
1008 }
1009}
1010
1011void
1013{
1015 << " : Node " << m_mainAddress << ": RoutingTableComputation begin...");
1016
1017 // 1. All the entries from the routing table are removed.
1018 Clear();
1019
1020 // 2. The new routing entries are added starting with the
1021 // symmetric neighbors (h=1) as the destination nodes.
1022 const NeighborSet& neighborSet = m_state.GetNeighbors();
1023 for (auto it = neighborSet.begin(); it != neighborSet.end(); it++)
1024 {
1025 const NeighborTuple& nb_tuple = *it;
1026 NS_LOG_DEBUG("Looking at neighbor tuple: " << nb_tuple);
1027 if (nb_tuple.status == NeighborTuple::STATUS_SYM)
1028 {
1029 bool nb_main_addr = false;
1030 const LinkTuple* lt = nullptr;
1031 const LinkSet& linkSet = m_state.GetLinks();
1032 for (auto it2 = linkSet.begin(); it2 != linkSet.end(); it2++)
1033 {
1034 const LinkTuple& link_tuple = *it2;
1035 NS_LOG_DEBUG("Looking at link tuple: "
1036 << link_tuple
1037 << (link_tuple.time >= Simulator::Now() ? "" : " (expired)"));
1038 if ((GetMainAddress(link_tuple.neighborIfaceAddr) == nb_tuple.neighborMainAddr) &&
1039 link_tuple.time >= Simulator::Now())
1040 {
1041 NS_LOG_LOGIC("Link tuple matches neighbor "
1042 << nb_tuple.neighborMainAddr
1043 << " => adding routing table entry to neighbor");
1044 lt = &link_tuple;
1045 AddEntry(link_tuple.neighborIfaceAddr,
1046 link_tuple.neighborIfaceAddr,
1047 link_tuple.localIfaceAddr,
1048 1);
1049 if (link_tuple.neighborIfaceAddr == nb_tuple.neighborMainAddr)
1050 {
1051 nb_main_addr = true;
1052 }
1053 }
1054 else
1055 {
1056 NS_LOG_LOGIC("Link tuple: linkMainAddress= "
1057 << GetMainAddress(link_tuple.neighborIfaceAddr)
1058 << "; neighborMainAddr = " << nb_tuple.neighborMainAddr
1059 << "; expired=" << int(link_tuple.time < Simulator::Now())
1060 << " => IGNORE");
1061 }
1062 }
1063
1064 // If, in the above, no R_dest_addr is equal to the main
1065 // address of the neighbor, then another new routing entry
1066 // with MUST be added, with:
1067 // R_dest_addr = main address of the neighbor;
1068 // R_next_addr = L_neighbor_iface_addr of one of the
1069 // associated link tuple with L_time >= current time;
1070 // R_dist = 1;
1071 // R_iface_addr = L_local_iface_addr of the
1072 // associated link tuple.
1073 if (!nb_main_addr && lt != nullptr)
1074 {
1075 NS_LOG_LOGIC("no R_dest_addr is equal to the main address of the neighbor "
1076 "=> adding additional routing entry");
1078 }
1079 }
1080 }
1081
1082 // 3. for each node in N2, i.e., a 2-hop neighbor which is not a
1083 // neighbor node or the node itself, and such that there exist at
1084 // least one entry in the 2-hop neighbor set where
1085 // N_neighbor_main_addr correspond to a neighbor node with
1086 // willingness different of Willingness::NEVER,
1087 const TwoHopNeighborSet& twoHopNeighbors = m_state.GetTwoHopNeighbors();
1088 for (auto it = twoHopNeighbors.begin(); it != twoHopNeighbors.end(); it++)
1089 {
1090 const TwoHopNeighborTuple& nb2hop_tuple = *it;
1091
1092 NS_LOG_LOGIC("Looking at two-hop neighbor tuple: " << nb2hop_tuple);
1093
1094 // a 2-hop neighbor which is not a neighbor node or the node itself
1096 {
1097 NS_LOG_LOGIC("Two-hop neighbor tuple is also neighbor; skipped.");
1098 continue;
1099 }
1100
1101 if (nb2hop_tuple.twoHopNeighborAddr == m_mainAddress)
1102 {
1103 NS_LOG_LOGIC("Two-hop neighbor is self; skipped.");
1104 continue;
1105 }
1106
1107 // ...and such that there exist at least one entry in the 2-hop
1108 // neighbor set where N_neighbor_main_addr correspond to a
1109 // neighbor node with willingness different of Willingness::NEVER...
1110 bool nb2hopOk = false;
1111 for (auto neighbor = neighborSet.begin(); neighbor != neighborSet.end(); neighbor++)
1112 {
1113 if (neighbor->neighborMainAddr == nb2hop_tuple.neighborMainAddr &&
1114 neighbor->willingness != Willingness::NEVER)
1115 {
1116 nb2hopOk = true;
1117 break;
1118 }
1119 }
1120 if (!nb2hopOk)
1121 {
1122 NS_LOG_LOGIC("Two-hop neighbor tuple skipped: 2-hop neighbor "
1123 << nb2hop_tuple.twoHopNeighborAddr << " is attached to neighbor "
1124 << nb2hop_tuple.neighborMainAddr
1125 << ", which was not found in the Neighbor Set.");
1126 continue;
1127 }
1128
1129 // one selects one 2-hop tuple and creates one entry in the routing table with:
1130 // R_dest_addr = the main address of the 2-hop neighbor;
1131 // R_next_addr = the R_next_addr of the entry in the
1132 // routing table with:
1133 // R_dest_addr == N_neighbor_main_addr
1134 // of the 2-hop tuple;
1135 // R_dist = 2;
1136 // R_iface_addr = the R_iface_addr of the entry in the
1137 // routing table with:
1138 // R_dest_addr == N_neighbor_main_addr
1139 // of the 2-hop tuple;
1140 RoutingTableEntry entry;
1141 bool foundEntry = Lookup(nb2hop_tuple.neighborMainAddr, entry);
1142 if (foundEntry)
1143 {
1144 NS_LOG_LOGIC("Adding routing entry for two-hop neighbor.");
1145 AddEntry(nb2hop_tuple.twoHopNeighborAddr, entry.nextAddr, entry.interface, 2);
1146 }
1147 else
1148 {
1149 NS_LOG_LOGIC("NOT adding routing entry for two-hop neighbor ("
1150 << nb2hop_tuple.twoHopNeighborAddr << " not found in the routing table)");
1151 }
1152 }
1153
1154 for (uint32_t h = 2;; h++)
1155 {
1156 bool added = false;
1157
1158 // 3.1. For each topology entry in the topology table, if its
1159 // T_dest_addr does not correspond to R_dest_addr of any
1160 // route entry in the routing table AND its T_last_addr
1161 // corresponds to R_dest_addr of a route entry whose R_dist
1162 // is equal to h, then a new route entry MUST be recorded in
1163 // the routing table (if it does not already exist)
1164 const TopologySet& topology = m_state.GetTopologySet();
1165 for (auto it = topology.begin(); it != topology.end(); it++)
1166 {
1167 const TopologyTuple& topology_tuple = *it;
1168 NS_LOG_LOGIC("Looking at topology tuple: " << topology_tuple);
1169
1170 RoutingTableEntry destAddrEntry;
1171 RoutingTableEntry lastAddrEntry;
1172 bool have_destAddrEntry = Lookup(topology_tuple.destAddr, destAddrEntry);
1173 bool have_lastAddrEntry = Lookup(topology_tuple.lastAddr, lastAddrEntry);
1174 if (!have_destAddrEntry && have_lastAddrEntry && lastAddrEntry.distance == h)
1175 {
1176 NS_LOG_LOGIC("Adding routing table entry based on the topology tuple.");
1177 // then a new route entry MUST be recorded in
1178 // the routing table (if it does not already exist) where:
1179 // R_dest_addr = T_dest_addr;
1180 // R_next_addr = R_next_addr of the recorded
1181 // route entry where:
1182 // R_dest_addr == T_last_addr
1183 // R_dist = h+1; and
1184 // R_iface_addr = R_iface_addr of the recorded
1185 // route entry where:
1186 // R_dest_addr == T_last_addr.
1187 AddEntry(topology_tuple.destAddr,
1188 lastAddrEntry.nextAddr,
1189 lastAddrEntry.interface,
1190 h + 1);
1191 added = true;
1192 }
1193 else
1194 {
1195 NS_LOG_LOGIC("NOT adding routing table entry based on the topology tuple: "
1196 "have_destAddrEntry="
1197 << have_destAddrEntry << " have_lastAddrEntry=" << have_lastAddrEntry
1198 << " lastAddrEntry.distance=" << (int)lastAddrEntry.distance
1199 << " (h=" << h << ")");
1200 }
1201 }
1202
1203 if (!added)
1204 {
1205 break;
1206 }
1207 }
1208
1209 // 4. For each entry in the multiple interface association base
1210 // where there exists a routing entry such that:
1211 // R_dest_addr == I_main_addr (of the multiple interface association entry)
1212 // AND there is no routing entry such that:
1213 // R_dest_addr == I_iface_addr
1214 const IfaceAssocSet& ifaceAssocSet = m_state.GetIfaceAssocSet();
1215 for (auto it = ifaceAssocSet.begin(); it != ifaceAssocSet.end(); it++)
1216 {
1217 const IfaceAssocTuple& tuple = *it;
1218 RoutingTableEntry entry1;
1219 RoutingTableEntry entry2;
1220 bool have_entry1 = Lookup(tuple.mainAddr, entry1);
1221 bool have_entry2 = Lookup(tuple.ifaceAddr, entry2);
1222 if (have_entry1 && !have_entry2)
1223 {
1224 // then a route entry is created in the routing table with:
1225 // R_dest_addr = I_iface_addr (of the multiple interface
1226 // association entry)
1227 // R_next_addr = R_next_addr (of the recorded route entry)
1228 // R_dist = R_dist (of the recorded route entry)
1229 // R_iface_addr = R_iface_addr (of the recorded route entry).
1230 AddEntry(tuple.ifaceAddr, entry1.nextAddr, entry1.interface, entry1.distance);
1231 }
1232 }
1233
1234 // 5. For each tuple in the association set,
1235 // If there is no entry in the routing table with:
1236 // R_dest_addr == A_network_addr/A_netmask
1237 // and if the announced network is not announced by the node itself,
1238 // then a new routing entry is created.
1239 const AssociationSet& associationSet = m_state.GetAssociationSet();
1240
1241 // Clear HNA routing table
1242 for (uint32_t i = 0; i < m_hnaRoutingTable->GetNRoutes(); i++)
1243 {
1244 m_hnaRoutingTable->RemoveRoute(0);
1245 }
1246
1247 for (auto it = associationSet.begin(); it != associationSet.end(); it++)
1248 {
1249 const AssociationTuple& tuple = *it;
1250
1251 // Test if HNA associations received from other gateways
1252 // are also announced by this node. In such a case, no route
1253 // is created for this association tuple (go to the next one).
1254 bool goToNextAssociationTuple = false;
1255 const Associations& localHnaAssociations = m_state.GetAssociations();
1256 NS_LOG_DEBUG("Nb local associations: " << localHnaAssociations.size());
1257 for (auto assocIterator = localHnaAssociations.begin();
1258 assocIterator != localHnaAssociations.end();
1259 assocIterator++)
1260 {
1261 const Association& localHnaAssoc = *assocIterator;
1262 if (localHnaAssoc.networkAddr == tuple.networkAddr &&
1263 localHnaAssoc.netmask == tuple.netmask)
1264 {
1265 NS_LOG_DEBUG("HNA association received from another GW is part of local HNA "
1266 "associations: no route added for network "
1267 << tuple.networkAddr << "/" << tuple.netmask);
1268 goToNextAssociationTuple = true;
1269 }
1270 }
1271 if (goToNextAssociationTuple)
1272 {
1273 continue;
1274 }
1275
1276 RoutingTableEntry gatewayEntry;
1277
1278 bool gatewayEntryExists = Lookup(tuple.gatewayAddr, gatewayEntry);
1279 bool addRoute = false;
1280
1281 uint32_t routeIndex = 0;
1282
1283 for (routeIndex = 0; routeIndex < m_hnaRoutingTable->GetNRoutes(); routeIndex++)
1284 {
1285 Ipv4RoutingTableEntry route = m_hnaRoutingTable->GetRoute(routeIndex);
1286 if (route.GetDestNetwork() == tuple.networkAddr &&
1287 route.GetDestNetworkMask() == tuple.netmask)
1288 {
1289 break;
1290 }
1291 }
1292
1293 if (routeIndex == m_hnaRoutingTable->GetNRoutes())
1294 {
1295 addRoute = true;
1296 }
1297 else if (gatewayEntryExists &&
1298 m_hnaRoutingTable->GetMetric(routeIndex) > gatewayEntry.distance)
1299 {
1300 m_hnaRoutingTable->RemoveRoute(routeIndex);
1301 addRoute = true;
1302 }
1303
1304 if (addRoute && gatewayEntryExists)
1305 {
1306 m_hnaRoutingTable->AddNetworkRouteTo(tuple.networkAddr,
1307 tuple.netmask,
1308 gatewayEntry.nextAddr,
1309 gatewayEntry.interface,
1310 gatewayEntry.distance);
1311 }
1312 }
1313
1314 NS_LOG_DEBUG("Node " << m_mainAddress << ": RoutingTableComputation end.");
1316}
1317
1318void
1320 const Ipv4Address& receiverIface,
1321 const Ipv4Address& senderIface)
1322{
1323 NS_LOG_FUNCTION(msg << receiverIface << senderIface);
1324
1325 const olsr::MessageHeader::Hello& hello = msg.GetHello();
1326
1327 LinkSensing(msg, hello, receiverIface, senderIface);
1328
1329#ifdef NS3_LOG_ENABLE
1330 {
1331 const LinkSet& links = m_state.GetLinks();
1333 << " ** BEGIN dump Link Set for OLSR Node " << m_mainAddress);
1334 for (auto link = links.begin(); link != links.end(); link++)
1335 {
1336 NS_LOG_DEBUG(*link);
1337 }
1338 NS_LOG_DEBUG("** END dump Link Set for OLSR Node " << m_mainAddress);
1339
1340 const NeighborSet& neighbors = m_state.GetNeighbors();
1342 << " ** BEGIN dump Neighbor Set for OLSR Node " << m_mainAddress);
1343 for (auto neighbor = neighbors.begin(); neighbor != neighbors.end(); neighbor++)
1344 {
1345 NS_LOG_DEBUG(*neighbor);
1346 }
1347 NS_LOG_DEBUG("** END dump Neighbor Set for OLSR Node " << m_mainAddress);
1348 }
1349#endif // NS3_LOG_ENABLE
1350
1351 PopulateNeighborSet(msg, hello);
1352 PopulateTwoHopNeighborSet(msg, hello);
1353
1354#ifdef NS3_LOG_ENABLE
1355 {
1356 const TwoHopNeighborSet& twoHopNeighbors = m_state.GetTwoHopNeighbors();
1358 << " ** BEGIN dump TwoHopNeighbor Set for OLSR Node " << m_mainAddress);
1359 for (auto tuple = twoHopNeighbors.begin(); tuple != twoHopNeighbors.end(); tuple++)
1360 {
1361 NS_LOG_DEBUG(*tuple);
1362 }
1363 NS_LOG_DEBUG("** END dump TwoHopNeighbor Set for OLSR Node " << m_mainAddress);
1364 }
1365#endif // NS3_LOG_ENABLE
1366
1368 PopulateMprSelectorSet(msg, hello);
1369}
1370
1371void
1373{
1374 const olsr::MessageHeader::Tc& tc = msg.GetTc();
1375 Time now = Simulator::Now();
1376
1377 // 1. If the sender interface of this message is not in the symmetric
1378 // 1-hop neighborhood of this node, the message MUST be discarded.
1379 const LinkTuple* link_tuple = m_state.FindSymLinkTuple(senderIface, now);
1380 if (link_tuple == nullptr)
1381 {
1382 return;
1383 }
1384
1385 // 2. If there exist some tuple in the topology set where:
1386 // T_last_addr == originator address AND
1387 // T_seq > ANSN,
1388 // then further processing of this TC message MUST NOT be
1389 // performed.
1390 const TopologyTuple* topologyTuple =
1392 if (topologyTuple != nullptr)
1393 {
1394 return;
1395 }
1396
1397 // 3. All tuples in the topology set where:
1398 // T_last_addr == originator address AND
1399 // T_seq < ANSN
1400 // MUST be removed from the topology set.
1402
1403 // 4. For each of the advertised neighbor main address received in
1404 // the TC message:
1405 for (auto i = tc.neighborAddresses.begin(); i != tc.neighborAddresses.end(); i++)
1406 {
1407 const Ipv4Address& addr = *i;
1408 // 4.1. If there exist some tuple in the topology set where:
1409 // T_dest_addr == advertised neighbor main address, AND
1410 // T_last_addr == originator address,
1411 // then the holding time of that tuple MUST be set to:
1412 // T_time = current time + validity time.
1413 TopologyTuple* topologyTuple = m_state.FindTopologyTuple(addr, msg.GetOriginatorAddress());
1414
1415 if (topologyTuple != nullptr)
1416 {
1417 topologyTuple->expirationTime = now + msg.GetVTime();
1418 }
1419 else
1420 {
1421 // 4.2. Otherwise, a new tuple MUST be recorded in the topology
1422 // set where:
1423 // T_dest_addr = advertised neighbor main address,
1424 // T_last_addr = originator address,
1425 // T_seq = ANSN,
1426 // T_time = current time + validity time.
1427 TopologyTuple topologyTuple;
1428 topologyTuple.destAddr = addr;
1429 topologyTuple.lastAddr = msg.GetOriginatorAddress();
1430 topologyTuple.sequenceNumber = tc.ansn;
1431 topologyTuple.expirationTime = now + msg.GetVTime();
1432 AddTopologyTuple(topologyTuple);
1433
1434 // Schedules topology tuple deletion
1437 this,
1438 topologyTuple.destAddr,
1439 topologyTuple.lastAddr));
1440 }
1441 }
1442
1443#ifdef NS3_LOG_ENABLE
1444 {
1445 const TopologySet& topology = m_state.GetTopologySet();
1447 << " ** BEGIN dump TopologySet for OLSR Node " << m_mainAddress);
1448 for (auto tuple = topology.begin(); tuple != topology.end(); tuple++)
1449 {
1450 NS_LOG_DEBUG(*tuple);
1451 }
1452 NS_LOG_DEBUG("** END dump TopologySet Set for OLSR Node " << m_mainAddress);
1453 }
1454#endif // NS3_LOG_ENABLE
1455}
1456
1457void
1459{
1460 const olsr::MessageHeader::Mid& mid = msg.GetMid();
1461 Time now = Simulator::Now();
1462
1463 NS_LOG_DEBUG("Node " << m_mainAddress << " ProcessMid from " << senderIface);
1464 // 1. If the sender interface of this message is not in the symmetric
1465 // 1-hop neighborhood of this node, the message MUST be discarded.
1466 const LinkTuple* linkTuple = m_state.FindSymLinkTuple(senderIface, now);
1467 if (linkTuple == nullptr)
1468 {
1469 NS_LOG_LOGIC("Node " << m_mainAddress
1470 << ": the sender interface of this message is not in the "
1471 "symmetric 1-hop neighborhood of this node,"
1472 " the message MUST be discarded.");
1473 return;
1474 }
1475
1476 // 2. For each interface address listed in the MID message
1477 for (auto i = mid.interfaceAddresses.begin(); i != mid.interfaceAddresses.end(); i++)
1478 {
1479 bool updated = false;
1481 for (auto tuple = ifaceAssoc.begin(); tuple != ifaceAssoc.end(); tuple++)
1482 {
1483 if (tuple->ifaceAddr == *i && tuple->mainAddr == msg.GetOriginatorAddress())
1484 {
1485 NS_LOG_LOGIC("IfaceAssoc updated: " << *tuple);
1486 tuple->time = now + msg.GetVTime();
1487 updated = true;
1488 }
1489 }
1490 if (!updated)
1491 {
1492 IfaceAssocTuple tuple;
1493 tuple.ifaceAddr = *i;
1494 tuple.mainAddr = msg.GetOriginatorAddress();
1495 tuple.time = now + msg.GetVTime();
1496 AddIfaceAssocTuple(tuple);
1497 NS_LOG_LOGIC("New IfaceAssoc added: " << tuple);
1498 // Schedules iface association tuple deletion
1501 this,
1502 tuple.ifaceAddr);
1503 }
1504 }
1505
1506 // 3. (not part of the RFC) iterate over all NeighborTuple's and
1507 // TwoHopNeighborTuples, update the neighbor addresses taking into account
1508 // the new MID information.
1509 NeighborSet& neighbors = m_state.GetNeighbors();
1510 for (auto neighbor = neighbors.begin(); neighbor != neighbors.end(); neighbor++)
1511 {
1512 neighbor->neighborMainAddr = GetMainAddress(neighbor->neighborMainAddr);
1513 }
1514
1515 TwoHopNeighborSet& twoHopNeighbors = m_state.GetTwoHopNeighbors();
1516 for (auto twoHopNeighbor = twoHopNeighbors.begin(); twoHopNeighbor != twoHopNeighbors.end();
1517 twoHopNeighbor++)
1518 {
1519 twoHopNeighbor->neighborMainAddr = GetMainAddress(twoHopNeighbor->neighborMainAddr);
1520 twoHopNeighbor->twoHopNeighborAddr = GetMainAddress(twoHopNeighbor->twoHopNeighborAddr);
1521 }
1522 NS_LOG_DEBUG("Node " << m_mainAddress << " ProcessMid from " << senderIface << " -> END.");
1523}
1524
1525void
1527{
1528 const olsr::MessageHeader::Hna& hna = msg.GetHna();
1529 Time now = Simulator::Now();
1530
1531 // 1. If the sender interface of this message is not in the symmetric
1532 // 1-hop neighborhood of this node, the message MUST be discarded.
1533 const LinkTuple* link_tuple = m_state.FindSymLinkTuple(senderIface, now);
1534 if (link_tuple == nullptr)
1535 {
1536 return;
1537 }
1538
1539 // 2. Otherwise, for each (network address, netmask) pair in the
1540 // message:
1541
1542 for (auto it = hna.associations.begin(); it != hna.associations.end(); it++)
1543 {
1544 AssociationTuple* tuple =
1545 m_state.FindAssociationTuple(msg.GetOriginatorAddress(), it->address, it->mask);
1546
1547 // 2.1 if an entry in the association set already exists, where:
1548 // A_gateway_addr == originator address
1549 // A_network_addr == network address
1550 // A_netmask == netmask
1551 // then the holding time for that tuple MUST be set to:
1552 // A_time = current time + validity time
1553 if (tuple != nullptr)
1554 {
1555 tuple->expirationTime = now + msg.GetVTime();
1556 }
1557
1558 // 2.2 otherwise, a new tuple MUST be recorded with:
1559 // A_gateway_addr = originator address
1560 // A_network_addr = network address
1561 // A_netmask = netmask
1562 // A_time = current time + validity time
1563 else
1564 {
1565 AssociationTuple assocTuple = {msg.GetOriginatorAddress(),
1566 it->address,
1567 it->mask,
1568 now + msg.GetVTime()};
1569 AddAssociationTuple(assocTuple);
1570
1571 // Schedule Association Tuple deletion
1574 this,
1575 assocTuple.gatewayAddr,
1576 assocTuple.networkAddr,
1577 assocTuple.netmask);
1578 }
1579 }
1580}
1581
1582void
1584 DuplicateTuple* duplicated,
1585 const Ipv4Address& localIface,
1586 const Ipv4Address& senderAddress)
1587{
1588 Time now = Simulator::Now();
1589
1590 // If the sender interface address is not in the symmetric
1591 // 1-hop neighborhood the message must not be forwarded
1592 const LinkTuple* linkTuple = m_state.FindSymLinkTuple(senderAddress, now);
1593 if (linkTuple == nullptr)
1594 {
1595 return;
1596 }
1597
1598 // If the message has already been considered for forwarding,
1599 // it must not be retransmitted again
1600 if (duplicated != nullptr && duplicated->retransmitted)
1601 {
1603 << "Node " << m_mainAddress
1604 << " does not forward a message received"
1605 " from "
1606 << olsrMessage.GetOriginatorAddress() << " because it is duplicated");
1607 return;
1608 }
1609
1610 // If the sender interface address is an interface address
1611 // of a MPR selector of this node and ttl is greater than 1,
1612 // the message must be retransmitted
1613 bool retransmitted = false;
1614 if (olsrMessage.GetTimeToLive() > 1)
1615 {
1616 const MprSelectorTuple* mprselTuple =
1618 if (mprselTuple != nullptr)
1619 {
1620 olsrMessage.SetTimeToLive(olsrMessage.GetTimeToLive() - 1);
1621 olsrMessage.SetHopCount(olsrMessage.GetHopCount() + 1);
1622 // We have to introduce a random delay to avoid
1623 // synchronization with neighbors.
1624 QueueMessage(olsrMessage, JITTER);
1625 retransmitted = true;
1626 }
1627 }
1628
1629 // Update duplicate tuple...
1630 if (duplicated != nullptr)
1631 {
1632 duplicated->expirationTime = now + OLSR_DUP_HOLD_TIME;
1633 duplicated->retransmitted = retransmitted;
1634 duplicated->ifaceList.push_back(localIface);
1635 }
1636 // ...or create a new one
1637 else
1638 {
1639 DuplicateTuple newDup;
1640 newDup.address = olsrMessage.GetOriginatorAddress();
1641 newDup.sequenceNumber = olsrMessage.GetMessageSequenceNumber();
1642 newDup.expirationTime = now + OLSR_DUP_HOLD_TIME;
1643 newDup.retransmitted = retransmitted;
1644 newDup.ifaceList.push_back(localIface);
1645 AddDuplicateTuple(newDup);
1646 // Schedule dup tuple deletion
1649 this,
1650 newDup.address,
1651 newDup.sequenceNumber);
1652 }
1653}
1654
1655void
1657{
1658 m_queuedMessages.push_back(message);
1660 {
1663 }
1664}
1665
1666void
1667RoutingProtocol::SendPacket(Ptr<Packet> packet, const MessageList& containedMessages)
1668{
1669 NS_LOG_DEBUG("OLSR node " << m_mainAddress << " sending a OLSR packet");
1670
1671 // Add a header
1672 olsr::PacketHeader header;
1673 header.SetPacketLength(header.GetSerializedSize() + packet->GetSize());
1675 packet->AddHeader(header);
1676
1677 // Trace it
1678 m_txPacketTrace(header, containedMessages);
1679
1680 // Send it
1681 for (auto i = m_sendSockets.begin(); i != m_sendSockets.end(); i++)
1682 {
1683 Ptr<Packet> pkt = packet->Copy();
1684 Ipv4Address bcast = i->second.GetLocal().GetSubnetDirectedBroadcast(i->second.GetMask());
1685 i->first->SendTo(pkt, 0, InetSocketAddress(bcast, OLSR_PORT_NUMBER));
1686 }
1687}
1688
1689void
1691{
1692 Ptr<Packet> packet = Create<Packet>();
1693 int numMessages = 0;
1694
1695 NS_LOG_DEBUG("Olsr node " << m_mainAddress << ": SendQueuedMessages");
1696
1697 MessageList msglist;
1698
1699 for (auto message = m_queuedMessages.begin(); message != m_queuedMessages.end(); message++)
1700 {
1701 Ptr<Packet> p = Create<Packet>();
1702 p->AddHeader(*message);
1703 packet->AddAtEnd(p);
1704 msglist.push_back(*message);
1705 if (++numMessages == OLSR_MAX_MSGS)
1706 {
1707 SendPacket(packet, msglist);
1708 msglist.clear();
1709 // Reset variables for next packet
1710 numMessages = 0;
1711 packet = Create<Packet>();
1712 }
1713 }
1714
1715 if (packet->GetSize())
1716 {
1717 SendPacket(packet, msglist);
1718 }
1719
1720 m_queuedMessages.clear();
1721}
1722
1723void
1725{
1726 NS_LOG_FUNCTION(this);
1727
1729 Time now = Simulator::Now();
1730
1733 msg.SetTimeToLive(1);
1734 msg.SetHopCount(0);
1736 olsr::MessageHeader::Hello& hello = msg.GetHello();
1737
1739 hello.willingness = m_willingness;
1740
1741 std::vector<olsr::MessageHeader::Hello::LinkMessage>& linkMessages = hello.linkMessages;
1742
1743 const LinkSet& links = m_state.GetLinks();
1744 for (auto link_tuple = links.begin(); link_tuple != links.end(); link_tuple++)
1745 {
1746 if (!(GetMainAddress(link_tuple->localIfaceAddr) == m_mainAddress &&
1747 link_tuple->time >= now))
1748 {
1749 continue;
1750 }
1751
1752 LinkType linkType;
1753 NeighborType neighborType;
1754
1755 // Establishes link type
1756 if (link_tuple->symTime >= now)
1757 {
1758 linkType = LinkType::SYM_LINK;
1759 }
1760 else if (link_tuple->asymTime >= now)
1761 {
1762 linkType = LinkType::ASYM_LINK;
1763 }
1764 else
1765 {
1766 linkType = LinkType::LOST_LINK;
1767 }
1768 // Establishes neighbor type.
1769 if (m_state.FindMprAddress(GetMainAddress(link_tuple->neighborIfaceAddr)))
1770 {
1771 neighborType = NeighborType::MPR_NEIGH;
1772 NS_LOG_DEBUG("I consider neighbor " << GetMainAddress(link_tuple->neighborIfaceAddr)
1773 << " to be MPR_NEIGH.");
1774 }
1775 else
1776 {
1777 bool ok = false;
1778 for (auto nb_tuple = m_state.GetNeighbors().begin();
1779 nb_tuple != m_state.GetNeighbors().end();
1780 nb_tuple++)
1781 {
1782 if (nb_tuple->neighborMainAddr == GetMainAddress(link_tuple->neighborIfaceAddr))
1783 {
1784 if (nb_tuple->status == NeighborTuple::STATUS_SYM)
1785 {
1786 NS_LOG_DEBUG("I consider neighbor "
1787 << GetMainAddress(link_tuple->neighborIfaceAddr)
1788 << " to be SYM_NEIGH.");
1789 neighborType = NeighborType::SYM_NEIGH;
1790 }
1791 else if (nb_tuple->status == NeighborTuple::STATUS_NOT_SYM)
1792 {
1793 neighborType = NeighborType::NOT_NEIGH;
1794 NS_LOG_DEBUG("I consider neighbor "
1795 << GetMainAddress(link_tuple->neighborIfaceAddr)
1796 << " to be NOT_NEIGH.");
1797 }
1798 else
1799 {
1800 NS_FATAL_ERROR("There is a neighbor tuple with an unknown status!\n");
1801 }
1802 ok = true;
1803 break;
1804 }
1805 }
1806 if (!ok)
1807 {
1808 NS_LOG_WARN("I don't know the neighbor "
1809 << GetMainAddress(link_tuple->neighborIfaceAddr) << "!!!");
1810 continue;
1811 }
1812 }
1813
1815 linkMessage.linkCode = (static_cast<uint8_t>(linkType) & 0x03) |
1816 ((static_cast<uint8_t>(neighborType) << 2) & 0x0f);
1817 linkMessage.neighborInterfaceAddresses.push_back(link_tuple->neighborIfaceAddr);
1818
1819 std::vector<Ipv4Address> interfaces =
1820 m_state.FindNeighborInterfaces(link_tuple->neighborIfaceAddr);
1821
1822 linkMessage.neighborInterfaceAddresses.insert(linkMessage.neighborInterfaceAddresses.end(),
1823 interfaces.begin(),
1824 interfaces.end());
1825
1826 linkMessages.push_back(linkMessage);
1827 }
1828 NS_LOG_DEBUG("OLSR HELLO message size: " << int(msg.GetSerializedSize()) << " (with "
1829 << int(linkMessages.size()) << " link messages)");
1830 QueueMessage(msg, JITTER);
1831}
1832
1833void
1835{
1836 NS_LOG_FUNCTION(this);
1837
1839
1842 msg.SetTimeToLive(255);
1843 msg.SetHopCount(0);
1845
1846 olsr::MessageHeader::Tc& tc = msg.GetTc();
1847 tc.ansn = m_ansn;
1848
1849 for (auto mprsel_tuple = m_state.GetMprSelectors().begin();
1850 mprsel_tuple != m_state.GetMprSelectors().end();
1851 mprsel_tuple++)
1852 {
1853 tc.neighborAddresses.push_back(mprsel_tuple->mainAddr);
1854 }
1855 QueueMessage(msg, JITTER);
1856}
1857
1858void
1860{
1862 olsr::MessageHeader::Mid& mid = msg.GetMid();
1863
1864 // A node which has only a single interface address participating in
1865 // the MANET (i.e., running OLSR), MUST NOT generate any MID
1866 // message.
1867
1868 // A node with several interfaces, where only one is participating
1869 // in the MANET and running OLSR (e.g., a node is connected to a
1870 // wired network as well as to a MANET) MUST NOT generate any MID
1871 // messages.
1872
1873 // A node with several interfaces, where more than one is
1874 // participating in the MANET and running OLSR MUST generate MID
1875 // messages as specified.
1876
1877 // [ Note: assuming here that all interfaces participate in the
1878 // MANET; later we may want to make this configurable. ]
1879
1880 Ipv4Address loopback("127.0.0.1");
1881 for (uint32_t i = 0; i < m_ipv4->GetNInterfaces(); i++)
1882 {
1883 Ipv4Address addr = m_ipv4->GetAddress(i, 0).GetLocal();
1884 if (addr != m_mainAddress && addr != loopback &&
1886 {
1887 mid.interfaceAddresses.push_back(addr);
1888 }
1889 }
1890 if (mid.interfaceAddresses.empty())
1891 {
1892 return;
1893 }
1894
1897 msg.SetTimeToLive(255);
1898 msg.SetHopCount(0);
1900
1901 QueueMessage(msg, JITTER);
1902}
1903
1904void
1906{
1908
1911 msg.SetTimeToLive(255);
1912 msg.SetHopCount(0);
1914 olsr::MessageHeader::Hna& hna = msg.GetHna();
1915
1916 std::vector<olsr::MessageHeader::Hna::Association>& associations = hna.associations;
1917
1918 // Add all local HNA associations to the HNA message
1919 const Associations& localHnaAssociations = m_state.GetAssociations();
1920 for (auto it = localHnaAssociations.begin(); it != localHnaAssociations.end(); it++)
1921 {
1922 olsr::MessageHeader::Hna::Association assoc = {it->networkAddr, it->netmask};
1923 associations.push_back(assoc);
1924 }
1925 // If there is no HNA associations to send, return without queuing the message
1926 if (associations.empty())
1927 {
1928 return;
1929 }
1930
1931 // Else, queue the message to be sent later on
1932 QueueMessage(msg, JITTER);
1933}
1934
1935void
1937{
1938 // Check if the (networkAddr, netmask) tuple already exist
1939 // in the list of local HNA associations
1940 const Associations& localHnaAssociations = m_state.GetAssociations();
1941 for (auto assocIterator = localHnaAssociations.begin();
1942 assocIterator != localHnaAssociations.end();
1943 assocIterator++)
1944 {
1945 const Association& localHnaAssoc = *assocIterator;
1946 if (localHnaAssoc.networkAddr == networkAddr && localHnaAssoc.netmask == netmask)
1947 {
1948 NS_LOG_INFO("HNA association for network " << networkAddr << "/" << netmask
1949 << " already exists.");
1950 return;
1951 }
1952 }
1953 // If the tuple does not already exist, add it to the list of local HNA associations.
1954 NS_LOG_INFO("Adding HNA association for network " << networkAddr << "/" << netmask << ".");
1955 m_state.InsertAssociation(Association{networkAddr, netmask});
1956}
1957
1958void
1960{
1961 NS_LOG_INFO("Removing HNA association for network " << networkAddr << "/" << netmask << ".");
1962 m_state.EraseAssociation(Association{networkAddr, netmask});
1963}
1964
1965void
1967{
1968 // If a routing table has already been associated, remove
1969 // corresponding entries from the list of local HNA associations
1971 {
1972 NS_LOG_INFO("Removing HNA entries coming from the old routing table association.");
1973 for (uint32_t i = 0; i < m_routingTableAssociation->GetNRoutes(); i++)
1974 {
1976 // If the outgoing interface for this route is a non-olsr interface
1978 {
1979 // remove the corresponding entry
1981 }
1982 }
1983 }
1984
1985 // Sets the routingTableAssociation to its new value
1986 m_routingTableAssociation = routingTable;
1987
1988 // Iterate over entries of the associated routing table and
1989 // add the routes using non-olsr outgoing interfaces to the list
1990 // of local HNA associations
1991 NS_LOG_DEBUG("Nb local associations before adding some entries from"
1992 " the associated routing table: "
1993 << m_state.GetAssociations().size());
1994 for (uint32_t i = 0; i < m_routingTableAssociation->GetNRoutes(); i++)
1995 {
1997 Ipv4Address destNetworkAddress = route.GetDestNetwork();
1998 Ipv4Mask destNetmask = route.GetDestNetworkMask();
1999
2000 // If the outgoing interface for this route is a non-olsr interface,
2002 {
2003 // Add this entry's network address and netmask to the list of local HNA entries
2004 AddHostNetworkAssociation(destNetworkAddress, destNetmask);
2005 }
2006 }
2007 NS_LOG_DEBUG("Nb local associations after having added some entries from "
2008 "the associated routing table: "
2009 << m_state.GetAssociations().size());
2010}
2011
2012bool
2014{
2015 auto ci = m_interfaceExclusions.find(route.GetInterface());
2016 // The outgoing interface is a non-OLSR interface if a match is found
2017 // before reaching the end of the list of excluded interfaces
2018 return ci != m_interfaceExclusions.end();
2019}
2020
2021void
2023 const olsr::MessageHeader::Hello& hello,
2024 const Ipv4Address& receiverIface,
2025 const Ipv4Address& senderIface)
2026{
2027 Time now = Simulator::Now();
2028 bool updated = false;
2029 bool created = false;
2030 NS_LOG_DEBUG("@" << now.As(Time::S) << ": Olsr node " << m_mainAddress
2031 << ": LinkSensing(receiverIface=" << receiverIface
2032 << ", senderIface=" << senderIface << ") BEGIN");
2033
2034 NS_ASSERT(msg.GetVTime() > Seconds(0));
2035 LinkTuple* link_tuple = m_state.FindLinkTuple(senderIface);
2036 if (link_tuple == nullptr)
2037 {
2038 LinkTuple newLinkTuple;
2039 // We have to create a new tuple
2040 newLinkTuple.neighborIfaceAddr = senderIface;
2041 newLinkTuple.localIfaceAddr = receiverIface;
2042 newLinkTuple.symTime = now - Seconds(1);
2043 newLinkTuple.time = now + msg.GetVTime();
2044 link_tuple = &m_state.InsertLinkTuple(newLinkTuple);
2045 created = true;
2046 NS_LOG_LOGIC("Existing link tuple did not exist => creating new one");
2047 }
2048 else
2049 {
2050 NS_LOG_LOGIC("Existing link tuple already exists => will update it");
2051 updated = true;
2052 }
2053
2054 link_tuple->asymTime = now + msg.GetVTime();
2055 for (auto linkMessage = hello.linkMessages.begin(); linkMessage != hello.linkMessages.end();
2056 linkMessage++)
2057 {
2058 auto linkType = LinkType(linkMessage->linkCode & 0x03);
2059 auto neighborType = NeighborType((linkMessage->linkCode >> 2) & 0x03);
2060
2061 NS_LOG_DEBUG("Looking at HELLO link messages with Link Type "
2062 << linkType << " and Neighbor Type " << neighborType);
2063
2064 // We must not process invalid advertised links
2065 if ((linkType == LinkType::SYM_LINK && neighborType == NeighborType::NOT_NEIGH) ||
2066 (neighborType != NeighborType::SYM_NEIGH && neighborType != NeighborType::MPR_NEIGH &&
2067 neighborType != NeighborType::NOT_NEIGH))
2068 {
2069 NS_LOG_LOGIC("HELLO link code is invalid => IGNORING");
2070 continue;
2071 }
2072
2073 for (auto neighIfaceAddr = linkMessage->neighborInterfaceAddresses.begin();
2074 neighIfaceAddr != linkMessage->neighborInterfaceAddresses.end();
2075 neighIfaceAddr++)
2076 {
2077 NS_LOG_DEBUG(" -> Neighbor: " << *neighIfaceAddr);
2078 if (*neighIfaceAddr == receiverIface)
2079 {
2080 if (linkType == LinkType::LOST_LINK)
2081 {
2082 NS_LOG_LOGIC("link is LOST => expiring it");
2083 link_tuple->symTime = now - Seconds(1);
2084 updated = true;
2085 }
2086 else if (linkType == LinkType::SYM_LINK || linkType == LinkType::ASYM_LINK)
2087 {
2088 NS_LOG_DEBUG(*link_tuple << ": link is SYM or ASYM => should become SYM now"
2089 " (symTime being increased to "
2090 << now + msg.GetVTime());
2091 link_tuple->symTime = now + msg.GetVTime();
2092 link_tuple->time = link_tuple->symTime + OLSR_NEIGHB_HOLD_TIME;
2093 updated = true;
2094 }
2095 else
2096 {
2097 NS_FATAL_ERROR("bad link type");
2098 }
2099 break;
2100 }
2101 else
2102 {
2103 NS_LOG_DEBUG(" \\-> *neighIfaceAddr (" << *neighIfaceAddr
2104 << " != receiverIface (" << receiverIface
2105 << ") => IGNORING!");
2106 }
2107 }
2108 NS_LOG_DEBUG("Link tuple updated: " << int(updated));
2109 }
2110 link_tuple->time = std::max(link_tuple->time, link_tuple->asymTime);
2111
2112 if (updated)
2113 {
2114 LinkTupleUpdated(*link_tuple, hello.willingness);
2115 }
2116
2117 // Schedules link tuple deletion
2118 if (created)
2119 {
2120 LinkTupleAdded(*link_tuple, hello.willingness);
2121 m_events.Track(Simulator::Schedule(DELAY(std::min(link_tuple->time, link_tuple->symTime)),
2123 this,
2124 link_tuple->neighborIfaceAddr));
2125 }
2126 NS_LOG_DEBUG("@" << now.As(Time::S) << ": Olsr node " << m_mainAddress << ": LinkSensing END");
2127}
2128
2129void
2131 const olsr::MessageHeader::Hello& hello)
2132{
2134 if (nb_tuple != nullptr)
2135 {
2136 nb_tuple->willingness = hello.willingness;
2137 }
2138}
2139
2140void
2142 const olsr::MessageHeader::Hello& hello)
2143{
2144 Time now = Simulator::Now();
2145
2146 NS_LOG_DEBUG("Olsr node " << m_mainAddress << ": PopulateTwoHopNeighborSet BEGIN");
2147
2148 for (auto link_tuple = m_state.GetLinks().begin(); link_tuple != m_state.GetLinks().end();
2149 link_tuple++)
2150 {
2151 NS_LOG_LOGIC("Looking at link tuple: " << *link_tuple);
2152 if (GetMainAddress(link_tuple->neighborIfaceAddr) != msg.GetOriginatorAddress())
2153 {
2155 "Link tuple ignored: "
2156 "GetMainAddress (link_tuple->neighborIfaceAddr) != msg.GetOriginatorAddress ()");
2157 NS_LOG_LOGIC("(GetMainAddress("
2158 << link_tuple->neighborIfaceAddr
2159 << "): " << GetMainAddress(link_tuple->neighborIfaceAddr)
2160 << "; msg.GetOriginatorAddress (): " << msg.GetOriginatorAddress());
2161 continue;
2162 }
2163
2164 if (link_tuple->symTime < now)
2165 {
2166 NS_LOG_LOGIC("Link tuple ignored: expired.");
2167 continue;
2168 }
2169
2170 for (auto linkMessage = hello.linkMessages.begin(); linkMessage != hello.linkMessages.end();
2171 linkMessage++)
2172 {
2173 auto neighborType = NeighborType((linkMessage->linkCode >> 2) & 0x3);
2175 "Looking at Link Message from HELLO message: neighborType=" << neighborType);
2176
2177 for (auto nb2hop_addr_iter = linkMessage->neighborInterfaceAddresses.begin();
2178 nb2hop_addr_iter != linkMessage->neighborInterfaceAddresses.end();
2179 nb2hop_addr_iter++)
2180 {
2181 Ipv4Address nb2hop_addr = GetMainAddress(*nb2hop_addr_iter);
2182 NS_LOG_DEBUG("Looking at 2-hop neighbor address from HELLO message: "
2183 << *nb2hop_addr_iter << " (main address is " << nb2hop_addr << ")");
2184 if (neighborType == NeighborType::SYM_NEIGH ||
2185 neighborType == NeighborType::MPR_NEIGH)
2186 {
2187 // If the main address of the 2-hop neighbor address == main address
2188 // of the receiving node, silently discard the 2-hop
2189 // neighbor address.
2190 if (nb2hop_addr == m_mainAddress)
2191 {
2192 NS_LOG_LOGIC("Ignoring 2-hop neighbor (it is the node itself)");
2193 continue;
2194 }
2195
2196 // Otherwise, a 2-hop tuple is created
2197 TwoHopNeighborTuple* nb2hop_tuple =
2199 NS_LOG_LOGIC("Adding the 2-hop neighbor"
2200 << (nb2hop_tuple ? " (refreshing existing entry)" : ""));
2201 if (nb2hop_tuple == nullptr)
2202 {
2203 TwoHopNeighborTuple new_nb2hop_tuple;
2204 new_nb2hop_tuple.neighborMainAddr = msg.GetOriginatorAddress();
2205 new_nb2hop_tuple.twoHopNeighborAddr = nb2hop_addr;
2206 new_nb2hop_tuple.expirationTime = now + msg.GetVTime();
2207 AddTwoHopNeighborTuple(new_nb2hop_tuple);
2208 // Schedules nb2hop tuple deletion
2211 this,
2212 new_nb2hop_tuple.neighborMainAddr,
2213 new_nb2hop_tuple.twoHopNeighborAddr));
2214 }
2215 else
2216 {
2217 nb2hop_tuple->expirationTime = now + msg.GetVTime();
2218 }
2219 }
2220 else if (neighborType == NeighborType::NOT_NEIGH)
2221 {
2222 // For each 2-hop node listed in the HELLO message
2223 // with Neighbor Type equal to NOT_NEIGH all 2-hop
2224 // tuples where: N_neighbor_main_addr == Originator
2225 // Address AND N_2hop_addr == main address of the
2226 // 2-hop neighbor are deleted.
2228 "2-hop neighbor is NOT_NEIGH => deleting matching 2-hop neighbor state");
2230 }
2231 else
2232 {
2233 NS_LOG_LOGIC("*** WARNING *** Ignoring link message (inside HELLO) with bad"
2234 " neighbor type value: "
2235 << neighborType);
2236 }
2237 }
2238 }
2239 }
2240
2241 NS_LOG_DEBUG("Olsr node " << m_mainAddress << ": PopulateTwoHopNeighborSet END");
2242}
2243
2244void
2246 const olsr::MessageHeader::Hello& hello)
2247{
2248 NS_LOG_FUNCTION(this);
2249
2250 Time now = Simulator::Now();
2251
2252 for (auto linkMessage = hello.linkMessages.begin(); linkMessage != hello.linkMessages.end();
2253 linkMessage++)
2254 {
2255 auto neighborType = NeighborType(linkMessage->linkCode >> 2);
2256 if (neighborType == NeighborType::MPR_NEIGH)
2257 {
2258 NS_LOG_DEBUG("Processing a link message with neighbor type MPR_NEIGH");
2259
2260 for (auto nb_iface_addr = linkMessage->neighborInterfaceAddresses.begin();
2261 nb_iface_addr != linkMessage->neighborInterfaceAddresses.end();
2262 nb_iface_addr++)
2263 {
2264 if (GetMainAddress(*nb_iface_addr) == m_mainAddress)
2265 {
2266 NS_LOG_DEBUG("Adding entry to mpr selector set for neighbor "
2267 << *nb_iface_addr);
2268
2269 // We must create a new entry into the mpr selector set
2270 MprSelectorTuple* existing_mprsel_tuple =
2272 if (existing_mprsel_tuple == nullptr)
2273 {
2274 MprSelectorTuple mprsel_tuple;
2275
2276 mprsel_tuple.mainAddr = msg.GetOriginatorAddress();
2277 mprsel_tuple.expirationTime = now + msg.GetVTime();
2278 AddMprSelectorTuple(mprsel_tuple);
2279
2280 // Schedules mpr selector tuple deletion
2283 this,
2284 mprsel_tuple.mainAddr));
2285 }
2286 else
2287 {
2288 existing_mprsel_tuple->expirationTime = now + msg.GetVTime();
2289 }
2290 }
2291 }
2292 }
2293 }
2294 NS_LOG_DEBUG("Computed MPR selector set for node " << m_mainAddress << ": "
2296}
2297
2298#if 0
2299///
2300/// \brief Drops a given packet because it couldn't be delivered to the corresponding
2301/// destination by the MAC layer. This may cause a neighbor loss, and appropriate
2302/// actions are then taken.
2303///
2304/// \param p the packet which couldn't be delivered by the MAC layer.
2305///
2306void
2307OLSR::mac_failed(Ptr<Packet> p)
2308{
2309 double now = Simulator::Now ();
2310 struct hdr_ip* ih = HDR_IP (p);
2311 struct hdr_cmn* ch = HDR_CMN (p);
2312
2313 debug("%f: Node %d MAC Layer detects a breakage on link to %d\n",
2314 now,
2315 OLSR::node_id (ra_addr ()),
2316 OLSR::node_id (ch->next_hop ()));
2317
2318 if ((uint32_t)ih->daddr () == IP_BROADCAST)
2319 {
2320 drop (p, DROP_RTR_MAC_CALLBACK);
2321 return;
2322 }
2323
2324 OLSR_link_tuple* link_tuple = state_.find_link_tuple(ch->next_hop());
2325 if (link_tuple)
2326 {
2327 link_tuple->lost_time() = now + OLSR_NEIGHB_HOLD_TIME;
2328 link_tuple->time() = now + OLSR_NEIGHB_HOLD_TIME;
2329 nb_loss(link_tuple);
2330 }
2331 drop(p, DROP_RTR_MAC_CALLBACK);
2332}
2333#endif
2334
2335void
2337{
2338 NS_LOG_DEBUG(Simulator::Now().As(Time::S) << ": OLSR Node " << m_mainAddress << " LinkTuple "
2339 << tuple.neighborIfaceAddr << " -> neighbor loss.");
2343
2346}
2347
2348void
2350{
2351 /*debug("%f: Node %d adds dup tuple: addr = %d seq_num = %d\n",
2352 Simulator::Now (),
2353 OLSR::node_id(ra_addr()),
2354 OLSR::node_id(tuple->addr()),
2355 tuple->seq_num());*/
2357}
2358
2359void
2361{
2362 /*debug("%f: Node %d removes dup tuple: addr = %d seq_num = %d\n",
2363 Simulator::Now (),
2364 OLSR::node_id(ra_addr()),
2365 OLSR::node_id(tuple->addr()),
2366 tuple->seq_num());*/
2368}
2369
2370void
2372{
2373 // Creates associated neighbor tuple
2374 NeighborTuple nb_tuple;
2376 nb_tuple.willingness = willingness;
2377
2378 if (tuple.symTime >= Simulator::Now())
2379 {
2381 }
2382 else
2383 {
2385 }
2386
2387 AddNeighborTuple(nb_tuple);
2388}
2389
2390void
2392{
2394 << ": OLSR Node " << m_mainAddress << " LinkTuple " << tuple << " REMOVED.");
2395
2397 m_state.EraseLinkTuple(tuple);
2398}
2399
2400void
2402{
2403 // Each time a link tuple changes, the associated neighbor tuple must be recomputed
2404
2406 << ": OLSR Node " << m_mainAddress << " LinkTuple " << tuple << " UPDATED.");
2407
2409
2410 if (nb_tuple == nullptr)
2411 {
2412 LinkTupleAdded(tuple, willingness);
2414 }
2415
2416 if (nb_tuple != nullptr)
2417 {
2418 int statusBefore = nb_tuple->status;
2419
2420 bool hasSymmetricLink = false;
2421
2422 const LinkSet& linkSet = m_state.GetLinks();
2423 for (auto it = linkSet.begin(); it != linkSet.end(); it++)
2424 {
2425 const LinkTuple& link_tuple = *it;
2426 if (GetMainAddress(link_tuple.neighborIfaceAddr) == nb_tuple->neighborMainAddr &&
2427 link_tuple.symTime >= Simulator::Now())
2428 {
2429 hasSymmetricLink = true;
2430 break;
2431 }
2432 }
2433
2434 if (hasSymmetricLink)
2435 {
2437 NS_LOG_DEBUG(*nb_tuple << "->status = STATUS_SYM; changed:"
2438 << int(statusBefore != nb_tuple->status));
2439 }
2440 else
2441 {
2443 NS_LOG_DEBUG(*nb_tuple << "->status = STATUS_NOT_SYM; changed:"
2444 << int(statusBefore != nb_tuple->status));
2445 }
2446 }
2447 else
2448 {
2449 NS_LOG_WARN("ERROR! Wanted to update a NeighborTuple but none was found!");
2450 }
2451}
2452
2453void
2455{
2456 // debug("%f: Node %d adds neighbor tuple: nb_addr = %d status = %s\n",
2457 // Simulator::Now (),
2458 // OLSR::node_id(ra_addr()),
2459 // OLSR::node_id(tuple->neighborMainAddr),
2460 // ((tuple->status() == OLSR_STATUS_SYM) ? "sym" : "not_sym"));
2461
2463 IncrementAnsn();
2464}
2465
2466void
2468{
2469 // debug("%f: Node %d removes neighbor tuple: nb_addr = %d status = %s\n",
2470 // Simulator::Now (),
2471 // OLSR::node_id(ra_addr()),
2472 // OLSR::node_id(tuple->neighborMainAddr),
2473 // ((tuple->status() == OLSR_STATUS_SYM) ? "sym" : "not_sym"));
2474
2476 IncrementAnsn();
2477}
2478
2479void
2481{
2482 // debug("%f: Node %d adds 2-hop neighbor tuple: nb_addr = %d nb2hop_addr = %d\n",
2483 // Simulator::Now (),
2484 // OLSR::node_id(ra_addr()),
2485 // OLSR::node_id(tuple->neighborMainAddr),
2486 // OLSR::node_id(tuple->twoHopNeighborAddr));
2487
2489}
2490
2491void
2493{
2494 // debug("%f: Node %d removes 2-hop neighbor tuple: nb_addr = %d nb2hop_addr = %d\n",
2495 // Simulator::Now (),
2496 // OLSR::node_id(ra_addr()),
2497 // OLSR::node_id(tuple->neighborMainAddr),
2498 // OLSR::node_id(tuple->twoHopNeighborAddr));
2499
2501}
2502
2503void
2505{
2506 m_ansn = (m_ansn + 1) % (OLSR_MAX_SEQ_NUM + 1);
2507}
2508
2509void
2511{
2512 // debug("%f: Node %d adds MPR selector tuple: nb_addr = %d\n",
2513 // Simulator::Now (),
2514 // OLSR::node_id(ra_addr()),
2515 // OLSR::node_id(tuple->main_addr()));
2516
2518 IncrementAnsn();
2519}
2520
2521void
2523{
2524 // debug("%f: Node %d removes MPR selector tuple: nb_addr = %d\n",
2525 // Simulator::Now (),
2526 // OLSR::node_id(ra_addr()),
2527 // OLSR::node_id(tuple->main_addr()));
2528
2530 IncrementAnsn();
2531}
2532
2533void
2535{
2536 // debug("%f: Node %d adds topology tuple: dest_addr = %d last_addr = %d seq = %d\n",
2537 // Simulator::Now (),
2538 // OLSR::node_id(ra_addr()),
2539 // OLSR::node_id(tuple->dest_addr()),
2540 // OLSR::node_id(tuple->last_addr()),
2541 // tuple->seq());
2542
2544}
2545
2546void
2548{
2549 // debug("%f: Node %d removes topology tuple: dest_addr = %d last_addr = %d seq = %d\n",
2550 // Simulator::Now (),
2551 // OLSR::node_id(ra_addr()),
2552 // OLSR::node_id(tuple->dest_addr()),
2553 // OLSR::node_id(tuple->last_addr()),
2554 // tuple->seq());
2555
2557}
2558
2559void
2561{
2562 // debug("%f: Node %d adds iface association tuple: main_addr = %d iface_addr = %d\n",
2563 // Simulator::Now (),
2564 // OLSR::node_id(ra_addr()),
2565 // OLSR::node_id(tuple->main_addr()),
2566 // OLSR::node_id(tuple->iface_addr()));
2567
2569}
2570
2571void
2573{
2574 // debug("%f: Node %d removes iface association tuple: main_addr = %d iface_addr = %d\n",
2575 // Simulator::Now (),
2576 // OLSR::node_id(ra_addr()),
2577 // OLSR::node_id(tuple->main_addr()),
2578 // OLSR::node_id(tuple->iface_addr()));
2579
2581}
2582
2583void
2585{
2587}
2588
2589void
2591{
2593}
2594
2595uint16_t
2597{
2600}
2601
2602uint16_t
2604{
2607}
2608
2609void
2611{
2612 SendHello();
2614}
2615
2616void
2618{
2619 if (!m_state.GetMprSelectors().empty())
2620 {
2621 SendTc();
2622 }
2623 else
2624 {
2625 NS_LOG_DEBUG("Not sending any TC, no one selected me as MPR.");
2626 }
2628}
2629
2630void
2632{
2633 SendMid();
2635}
2636
2637void
2639{
2640 if (!m_state.GetAssociations().empty())
2641 {
2642 SendHna();
2643 }
2644 else
2645 {
2646 NS_LOG_DEBUG("Not sending any HNA, no associations to advertise.");
2647 }
2649}
2650
2651void
2652RoutingProtocol::DupTupleTimerExpire(Ipv4Address address, uint16_t sequenceNumber)
2653{
2654 DuplicateTuple* tuple = m_state.FindDuplicateTuple(address, sequenceNumber);
2655 if (tuple == nullptr)
2656 {
2657 return;
2658 }
2659 if (tuple->expirationTime < Simulator::Now())
2660 {
2661 RemoveDuplicateTuple(*tuple);
2662 }
2663 else
2664 {
2667 this,
2668 address,
2669 sequenceNumber));
2670 }
2671}
2672
2673void
2675{
2676 Time now = Simulator::Now();
2677
2678 // the tuple parameter may be a stale copy; get a newer version from m_state
2679 LinkTuple* tuple = m_state.FindLinkTuple(neighborIfaceAddr);
2680 if (tuple == nullptr)
2681 {
2682 return;
2683 }
2684 if (tuple->time < now)
2685 {
2686 RemoveLinkTuple(*tuple);
2687 }
2688 else if (tuple->symTime < now)
2689 {
2691 {
2693 }
2694 else
2695 {
2696 NeighborLoss(*tuple);
2697 }
2698
2701 this,
2702 neighborIfaceAddr));
2703 }
2704 else
2705 {
2706 m_events.Track(Simulator::Schedule(DELAY(std::min(tuple->time, tuple->symTime)),
2708 this,
2709 neighborIfaceAddr));
2710 }
2711}
2712
2713void
2715 Ipv4Address twoHopNeighborAddr)
2716{
2717 TwoHopNeighborTuple* tuple;
2718 tuple = m_state.FindTwoHopNeighborTuple(neighborMainAddr, twoHopNeighborAddr);
2719 if (tuple == nullptr)
2720 {
2721 return;
2722 }
2723 if (tuple->expirationTime < Simulator::Now())
2724 {
2726 }
2727 else
2728 {
2731 this,
2732 neighborMainAddr,
2733 twoHopNeighborAddr));
2734 }
2735}
2736
2737void
2739{
2741 if (tuple == nullptr)
2742 {
2743 return;
2744 }
2745 if (tuple->expirationTime < Simulator::Now())
2746 {
2747 RemoveMprSelectorTuple(*tuple);
2748 }
2749 else
2750 {
2753 this,
2754 mainAddr));
2755 }
2756}
2757
2758void
2760{
2761 TopologyTuple* tuple = m_state.FindTopologyTuple(destAddr, lastAddr);
2762 if (tuple == nullptr)
2763 {
2764 return;
2765 }
2766 if (tuple->expirationTime < Simulator::Now())
2767 {
2768 RemoveTopologyTuple(*tuple);
2769 }
2770 else
2771 {
2774 this,
2775 tuple->destAddr,
2776 tuple->lastAddr));
2777 }
2778}
2779
2780void
2782{
2783 IfaceAssocTuple* tuple = m_state.FindIfaceAssocTuple(ifaceAddr);
2784 if (tuple == nullptr)
2785 {
2786 return;
2787 }
2788 if (tuple->time < Simulator::Now())
2789 {
2790 RemoveIfaceAssocTuple(*tuple);
2791 }
2792 else
2793 {
2796 this,
2797 ifaceAddr));
2798 }
2799}
2800
2801void
2803 Ipv4Address networkAddr,
2804 Ipv4Mask netmask)
2805{
2806 AssociationTuple* tuple = m_state.FindAssociationTuple(gatewayAddr, networkAddr, netmask);
2807 if (tuple == nullptr)
2808 {
2809 return;
2810 }
2811 if (tuple->expirationTime < Simulator::Now())
2812 {
2813 RemoveAssociationTuple(*tuple);
2814 }
2815 else
2816 {
2819 this,
2820 gatewayAddr,
2821 networkAddr,
2822 netmask));
2823 }
2824}
2825
2826void
2828{
2830 m_table.clear();
2831}
2832
2833void
2835{
2836 m_table.erase(dest);
2837}
2838
2839bool
2841{
2842 // Get the iterator at "dest" position
2843 auto it = m_table.find(dest);
2844 // If there is no route to "dest", return NULL
2845 if (it == m_table.end())
2846 {
2847 return false;
2848 }
2849 outEntry = it->second;
2850 return true;
2851}
2852
2853bool
2855{
2856 outEntry = entry;
2857 while (outEntry.destAddr != outEntry.nextAddr)
2858 {
2859 if (not Lookup(outEntry.nextAddr, outEntry))
2860 {
2861 return false;
2862 }
2863 }
2864 return true;
2865}
2866
2869 const Ipv4Header& header,
2870 Ptr<NetDevice> oif,
2871 Socket::SocketErrno& sockerr)
2872{
2873 NS_LOG_FUNCTION(this << " " << m_ipv4->GetObject<Node>()->GetId() << " "
2874 << header.GetDestination() << " " << oif);
2875 Ptr<Ipv4Route> rtentry;
2876 RoutingTableEntry entry1;
2877 RoutingTableEntry entry2;
2878 bool found = false;
2879
2880 if (Lookup(header.GetDestination(), entry1))
2881 {
2882 bool foundSendEntry = FindSendEntry(entry1, entry2);
2883 if (!foundSendEntry)
2884 {
2885 NS_FATAL_ERROR("FindSendEntry failure");
2886 }
2887 uint32_t interfaceIdx = entry2.interface;
2888 if (oif && m_ipv4->GetInterfaceForDevice(oif) != static_cast<int>(interfaceIdx))
2889 {
2890 // We do not attempt to perform a constrained routing search
2891 // if the caller specifies the oif; we just enforce that
2892 // that the found route matches the requested outbound interface
2893 NS_LOG_DEBUG("Olsr node " << m_mainAddress
2894 << ": RouteOutput for dest=" << header.GetDestination()
2895 << " Route interface " << interfaceIdx
2896 << " does not match requested output interface "
2897 << m_ipv4->GetInterfaceForDevice(oif));
2899 return rtentry;
2900 }
2901 rtentry = Create<Ipv4Route>();
2902 rtentry->SetDestination(header.GetDestination());
2903 // the source address is the interface address that matches
2904 // the destination address (when multiple are present on the
2905 // outgoing interface, one is selected via scoping rules)
2907 uint32_t numOifAddresses = m_ipv4->GetNAddresses(interfaceIdx);
2908 NS_ASSERT(numOifAddresses > 0);
2909 Ipv4InterfaceAddress ifAddr;
2910 if (numOifAddresses == 1)
2911 {
2912 ifAddr = m_ipv4->GetAddress(interfaceIdx, 0);
2913 }
2914 else
2915 {
2916 /// \todo Implement IP aliasing and OLSR
2917 NS_FATAL_ERROR("XXX Not implemented yet: IP aliasing and OLSR");
2918 }
2919 rtentry->SetSource(ifAddr.GetLocal());
2920 rtentry->SetGateway(entry2.nextAddr);
2921 rtentry->SetOutputDevice(m_ipv4->GetNetDevice(interfaceIdx));
2922 sockerr = Socket::ERROR_NOTERROR;
2923 NS_LOG_DEBUG("Olsr node " << m_mainAddress << ": RouteOutput for dest="
2924 << header.GetDestination() << " --> nextHop=" << entry2.nextAddr
2925 << " interface=" << entry2.interface);
2926 NS_LOG_DEBUG("Found route to " << rtentry->GetDestination() << " via nh "
2927 << rtentry->GetGateway() << " with source addr "
2928 << rtentry->GetSource() << " and output dev "
2929 << rtentry->GetOutputDevice());
2930 found = true;
2931 }
2932 else
2933 {
2934 rtentry = m_hnaRoutingTable->RouteOutput(p, header, oif, sockerr);
2935
2936 if (rtentry)
2937 {
2938 found = true;
2939 NS_LOG_DEBUG("Found route to " << rtentry->GetDestination() << " via nh "
2940 << rtentry->GetGateway() << " with source addr "
2941 << rtentry->GetSource() << " and output dev "
2942 << rtentry->GetOutputDevice());
2943 }
2944 }
2945
2946 if (!found)
2947 {
2948 NS_LOG_DEBUG("Olsr node " << m_mainAddress << ": RouteOutput for dest="
2949 << header.GetDestination() << " No route to host");
2951 }
2952 return rtentry;
2953}
2954
2955bool
2957 const Ipv4Header& header,
2959 const UnicastForwardCallback& ucb,
2960 const MulticastForwardCallback& mcb,
2961 const LocalDeliverCallback& lcb,
2962 const ErrorCallback& ecb)
2963{
2964 NS_LOG_FUNCTION(this << " " << m_ipv4->GetObject<Node>()->GetId() << " "
2965 << header.GetDestination());
2966
2967 Ipv4Address dst = header.GetDestination();
2968 Ipv4Address origin = header.GetSource();
2969
2970 // Consume self-originated packets
2971 if (IsMyOwnAddress(origin))
2972 {
2973 return true;
2974 }
2975
2976 // Local delivery
2977 NS_ASSERT(m_ipv4->GetInterfaceForDevice(idev) >= 0);
2978 uint32_t iif = m_ipv4->GetInterfaceForDevice(idev);
2979 if (m_ipv4->IsDestinationAddress(dst, iif))
2980 {
2981 if (!lcb.IsNull())
2982 {
2983 NS_LOG_LOGIC("Local delivery to " << dst);
2984 lcb(p, header, iif);
2985 return true;
2986 }
2987 else
2988 {
2989 // The local delivery callback is null. This may be a multicast
2990 // or broadcast packet, so return false so that another
2991 // multicast routing protocol can handle it. It should be possible
2992 // to extend this to explicitly check whether it is a unicast
2993 // packet, and invoke the error callback if so
2994 NS_LOG_LOGIC("Null local delivery callback");
2995 return false;
2996 }
2997 }
2998
2999 NS_LOG_LOGIC("Forward packet");
3000 // Forwarding
3001 Ptr<Ipv4Route> rtentry;
3002 RoutingTableEntry entry1;
3003 RoutingTableEntry entry2;
3004 if (Lookup(header.GetDestination(), entry1))
3005 {
3006 bool foundSendEntry = FindSendEntry(entry1, entry2);
3007 if (!foundSendEntry)
3008 {
3009 NS_FATAL_ERROR("FindSendEntry failure");
3010 }
3011 rtentry = Create<Ipv4Route>();
3012 rtentry->SetDestination(header.GetDestination());
3013 uint32_t interfaceIdx = entry2.interface;
3014 // the source address is the interface address that matches
3015 // the destination address (when multiple are present on the
3016 // outgoing interface, one is selected via scoping rules)
3018 uint32_t numOifAddresses = m_ipv4->GetNAddresses(interfaceIdx);
3019 NS_ASSERT(numOifAddresses > 0);
3020 Ipv4InterfaceAddress ifAddr;
3021 if (numOifAddresses == 1)
3022 {
3023 ifAddr = m_ipv4->GetAddress(interfaceIdx, 0);
3024 }
3025 else
3026 {
3027 /// \todo Implement IP aliasing and OLSR
3028 NS_FATAL_ERROR("XXX Not implemented yet: IP aliasing and OLSR");
3029 }
3030 rtentry->SetSource(ifAddr.GetLocal());
3031 rtentry->SetGateway(entry2.nextAddr);
3032 rtentry->SetOutputDevice(m_ipv4->GetNetDevice(interfaceIdx));
3033
3034 NS_LOG_DEBUG("Olsr node " << m_mainAddress << ": RouteInput for dest="
3035 << header.GetDestination() << " --> nextHop=" << entry2.nextAddr
3036 << " interface=" << entry2.interface);
3037
3038 ucb(rtentry, p, header);
3039 return true;
3040 }
3041 else
3042 {
3043 NS_LOG_LOGIC("No dynamic route, check network routes");
3044 if (m_hnaRoutingTable->RouteInput(p, header, idev, ucb, mcb, lcb, ecb))
3045 {
3046 return true;
3047 }
3048 else
3049 {
3050#ifdef NS3_LOG_ENABLE
3051 NS_LOG_DEBUG("Olsr node " << m_mainAddress
3052 << ": RouteInput for dest=" << header.GetDestination()
3053 << " --> NOT FOUND; ** Dumping routing table...");
3054
3055 for (auto iter = m_table.begin(); iter != m_table.end(); iter++)
3056 {
3057 NS_LOG_DEBUG("dest=" << iter->first << " --> next=" << iter->second.nextAddr
3058 << " via interface " << iter->second.interface);
3059 }
3060
3061 NS_LOG_DEBUG("** Routing table dump end.");
3062#endif // NS3_LOG_ENABLE
3063
3064 return false;
3065 }
3066 }
3067}
3068
3069void
3071{
3072}
3073
3074void
3076{
3077}
3078
3079void
3081{
3082}
3083
3084void
3086{
3087}
3088
3089void
3091 const Ipv4Address& next,
3092 uint32_t interface,
3093 uint32_t distance)
3094{
3095 NS_LOG_FUNCTION(this << dest << next << interface << distance << m_mainAddress);
3096
3097 NS_ASSERT(distance > 0);
3098
3099 // Creates a new rt entry with specified values
3100 RoutingTableEntry& entry = m_table[dest];
3101
3102 entry.destAddr = dest;
3103 entry.nextAddr = next;
3104 entry.interface = interface;
3105 entry.distance = distance;
3106}
3107
3108void
3110 const Ipv4Address& next,
3111 const Ipv4Address& interfaceAddress,
3112 uint32_t distance)
3113{
3114 NS_LOG_FUNCTION(this << dest << next << interfaceAddress << distance << m_mainAddress);
3115
3116 NS_ASSERT(distance > 0);
3118
3119 RoutingTableEntry entry;
3120 for (uint32_t i = 0; i < m_ipv4->GetNInterfaces(); i++)
3121 {
3122 for (uint32_t j = 0; j < m_ipv4->GetNAddresses(i); j++)
3123 {
3124 if (m_ipv4->GetAddress(i, j).GetLocal() == interfaceAddress)
3125 {
3126 AddEntry(dest, next, i, distance);
3127 return;
3128 }
3129 }
3130 }
3131 NS_ASSERT(false); // should not be reached
3132 AddEntry(dest, next, 0, distance);
3133}
3134
3135std::vector<RoutingTableEntry>
3137{
3138 std::vector<RoutingTableEntry> retval;
3139 for (auto iter = m_table.begin(); iter != m_table.end(); iter++)
3140 {
3141 retval.push_back(iter->second);
3142 }
3143 return retval;
3144}
3145
3146MprSet
3148{
3149 return m_state.GetMprSet();
3150}
3151
3152const MprSelectorSet&
3154{
3155 return m_state.GetMprSelectors();
3156}
3157
3158const NeighborSet&
3160{
3161 return m_state.GetNeighbors();
3162}
3163
3164const TwoHopNeighborSet&
3166{
3167 return m_state.GetTwoHopNeighbors();
3168}
3169
3170const TopologySet&
3172{
3173 return m_state.GetTopologySet();
3174}
3175
3176const OlsrState&
3178{
3179 return m_state;
3180}
3181
3182int64_t
3184{
3185 NS_LOG_FUNCTION(this << stream);
3187 return 1;
3188}
3189
3190bool
3192{
3193 for (auto j = m_sendSockets.begin(); j != m_sendSockets.end(); ++j)
3194 {
3195 Ipv4InterfaceAddress iface = j->second;
3196 if (a == iface.GetLocal())
3197 {
3198 return true;
3199 }
3200 }
3201 return false;
3202}
3203
3204void
3206{
3207#ifdef NS3_LOG_ENABLE
3208 Time now = Simulator::Now();
3209 NS_LOG_DEBUG("Dumping for node with main address " << m_mainAddress);
3210 NS_LOG_DEBUG(" Neighbor set");
3211 for (auto iter = m_state.GetNeighbors().begin(); iter != m_state.GetNeighbors().end(); iter++)
3212 {
3213 NS_LOG_DEBUG(" " << *iter);
3214 }
3215 NS_LOG_DEBUG(" Two-hop neighbor set");
3216 for (auto iter = m_state.GetTwoHopNeighbors().begin();
3217 iter != m_state.GetTwoHopNeighbors().end();
3218 iter++)
3219 {
3220 if (now < iter->expirationTime)
3221 {
3222 NS_LOG_DEBUG(" " << *iter);
3223 }
3224 }
3225 NS_LOG_DEBUG(" Routing table");
3226 for (auto iter = m_table.begin(); iter != m_table.end(); iter++)
3227 {
3228 NS_LOG_DEBUG(" dest=" << iter->first << " --> next=" << iter->second.nextAddr
3229 << " via interface " << iter->second.interface);
3230 }
3231 NS_LOG_DEBUG("");
3232#endif // NS3_LOG_ENABLE
3233}
3234
3237{
3238 return m_hnaRoutingTable;
3239}
3240
3241} // namespace olsr
3242} // namespace ns3
a polymophic address class
Definition: address.h:101
bool IsNull() const
Check for null implementation.
Definition: callback.h:571
Hold variables of type enum.
Definition: enum.h:62
void Track(EventId event)
Tracks a new event.
an Inet address class
Ipv4Address GetIpv4() const
static InetSocketAddress ConvertFrom(const Address &address)
Returns an InetSocketAddress which corresponds to the input Address.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:42
Ipv4Address GetSubnetDirectedBroadcast(const Ipv4Mask &mask) const
Generate subnet-directed broadcast address corresponding to mask.
static Ipv4Address GetAny()
Packet header for IPv4.
Definition: ipv4-header.h:34
Ipv4Address GetSource() const
Definition: ipv4-header.cc:302
Ipv4Address GetDestination() const
Definition: ipv4-header.cc:316
a class to store IPv4 address information on an interface
Ipv4Address GetLocal() const
Get the local address.
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:257
This class implements Linux struct pktinfo in order to deliver ancillary information to the socket in...
uint32_t GetRecvIf() const
Get the tag's receiving interface.
Abstract base class for IPv4 routing protocols.
A record of an IPv4 routing table entry for Ipv4GlobalRouting and Ipv4StaticRouting.
Ipv4Address GetDestNetwork() const
uint32_t GetInterface() const
Ipv4Mask GetDestNetworkMask() const
static std::string FindName(Ptr< Object > object)
Given a pointer to an object, look to see if that object has a name associated with it and,...
Definition: names.cc:829
A network Node.
Definition: node.h:57
uint32_t GetId() const
Definition: node.cc:117
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:444
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
virtual bool SetAllowBroadcast(bool allowBroadcast)=0
Configure whether broadcast datagram transmissions are allowed.
void SetRecvPktInfo(bool flag)
Enable/Disable receive packet information to socket.
Definition: socket.cc:354
virtual int ShutdownSend()=0
void SetRecvCallback(Callback< void, Ptr< Socket > > receivedData)
Notify application when new data is available to be read.
Definition: socket.cc:128
static Ptr< Socket > CreateSocket(Ptr< Node > node, TypeId tid)
This method wraps the creation of sockets that is performed on a given node by a SocketFactory specif...
Definition: socket.cc:72
virtual int Close()=0
Close a socket.
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:84
@ ERROR_NOROUTETOHOST
Definition: socket.h:95
@ ERROR_NOTERROR
Definition: socket.h:85
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:415
Unit
The unit to use to interpret a number representing time.
Definition: nstime.h:111
@ S
second
Definition: nstime.h:116
AttributeValue implementation for Time.
Definition: nstime.h:1406
A simple virtual Timer class.
Definition: timer.h:78
void SetDelay(const Time &delay)
Definition: timer.cc:76
void SetFunction(FN fn)
Definition: timer.h:279
void Schedule()
Schedule a new event using the currently-configured delay, function, and arguments.
Definition: timer.cc:162
bool IsRunning() const
Definition: timer.cc:129
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
static TypeId GetTypeId()
Get the type ID.
This header can store HELP, TC, MID and HNA messages.
Definition: olsr-header.h:161
void SetOriginatorAddress(Ipv4Address originatorAddress)
Set the originator address.
Definition: olsr-header.h:217
Ipv4Address GetOriginatorAddress() const
Get the originator address.
Definition: olsr-header.h:226
void SetHopCount(uint8_t hopCount)
Set the hop count.
Definition: olsr-header.h:253
Mid & GetMid()
Set the message type to MID and return the message content.
Definition: olsr-header.h:584
Tc & GetTc()
Set the message type to TC and return the message content.
Definition: olsr-header.h:618
Hello & GetHello()
Set the message type to HELLO and return the message content.
Definition: olsr-header.h:601
uint8_t GetTimeToLive() const
Get the time to live.
Definition: olsr-header.h:244
void SetMessageSequenceNumber(uint16_t messageSequenceNumber)
Set the message sequence number.
Definition: olsr-header.h:271
uint8_t GetHopCount() const
Get the hop count.
Definition: olsr-header.h:262
MessageType GetMessageType() const
Get the message type.
Definition: olsr-header.h:190
Hna & GetHna()
Set the message type to HNA and return the message content.
Definition: olsr-header.h:635
Time GetVTime() const
Get the validity time.
Definition: olsr-header.h:208
void SetTimeToLive(uint8_t timeToLive)
Set the time to live.
Definition: olsr-header.h:235
uint32_t GetSerializedSize() const override
Definition: olsr-header.cc:187
uint16_t GetMessageSequenceNumber() const
Get the message sequence number.
Definition: olsr-header.h:280
void SetVTime(Time time)
Set the validity time.
Definition: olsr-header.h:199
This class encapsulates all data structures needed for maintaining internal state of an OLSR node.
Definition: olsr-state.h:36
MprSet GetMprSet() const
Gets the MPR set.
Definition: olsr-state.cc:272
void EraseAssociation(const Association &tuple)
Erases an association.
Definition: olsr-state.cc:528
const NeighborSet & GetNeighbors() const
Gets the neighbor set.
Definition: olsr-state.h:106
void EraseIfaceAssocTuple(const IfaceAssocTuple &tuple)
Erases a interface association tuple.
Definition: olsr-state.cc:458
void InsertTopologyTuple(const TopologyTuple &tuple)
Inserts a topology tuple.
Definition: olsr-state.cc:424
IfaceAssocTuple * FindIfaceAssocTuple(const Ipv4Address &ifaceAddr)
Finds a interface association tuple.
Definition: olsr-state.cc:432
std::string PrintMprSelectorSet() const
Prints the MPR selector sets.
Definition: olsr-state.cc:86
TwoHopNeighborTuple * FindTwoHopNeighborTuple(const Ipv4Address &neighbor, const Ipv4Address &twoHopNeighbor)
Finds a 2-hop neighbor tuple.
Definition: olsr-state.cc:189
void EraseTwoHopNeighborTuples(const Ipv4Address &neighbor)
Erases the 2-hop neighbor tuples with the same 1-hop neighbor.
Definition: olsr-state.cc:235
void InsertAssociation(const Association &tuple)
Inserts an association tuple.
Definition: olsr-state.cc:541
LinkTuple * FindSymLinkTuple(const Ipv4Address &ifaceAddr, Time time)
Finds a symmetrical link tuple.
Definition: olsr-state.cc:327
const NeighborTuple * FindSymNeighborTuple(const Ipv4Address &mainAddr) const
Finds a symmetrical neighbor tuple.
Definition: olsr-state.cc:120
IfaceAssocSet & GetIfaceAssocSetMutable()
Gets a mutable reference to the interface association set.
Definition: olsr-state.h:345
void EraseNeighborTuple(const NeighborTuple &neighborTuple)
Erases a neighbor tuple.
Definition: olsr-state.cc:146
TopologyTuple * FindNewerTopologyTuple(const Ipv4Address &lastAddr, uint16_t ansn)
Finds a topology tuple.
Definition: olsr-state.cc:382
void InsertDuplicateTuple(const DuplicateTuple &tuple)
Inserts a duplicate tuple.
Definition: olsr-state.cc:306
const TopologySet & GetTopologySet() const
Gets the topology set.
Definition: olsr-state.h:294
const LinkSet & GetLinks() const
Gets the Link set.
Definition: olsr-state.h:258
void EraseMprSelectorTuples(const Ipv4Address &mainAddr)
Erases all MPR selector tuples belonging to the same address.
Definition: olsr-state.cc:64
const TwoHopNeighborSet & GetTwoHopNeighbors() const
Gets the 2-hop neighbor set.
Definition: olsr-state.h:165
MprSelectorTuple * FindMprSelectorTuple(const Ipv4Address &mainAddr)
Finds a MPR selector tuple.
Definition: olsr-state.cc:38
void SetMprSet(MprSet mprSet)
Sets the MPR set to the one specified.
Definition: olsr-state.cc:266
void EraseAssociationTuple(const AssociationTuple &tuple)
Erases a known association tuple.
Definition: olsr-state.cc:509
void InsertNeighborTuple(const NeighborTuple &tuple)
Inserts a neighbor tuple.
Definition: olsr-state.cc:172
TopologyTuple * FindTopologyTuple(const Ipv4Address &destAddr, const Ipv4Address &lastAddr)
Finds a topology tuple.
Definition: olsr-state.cc:369
AssociationTuple * FindAssociationTuple(const Ipv4Address &gatewayAddr, const Ipv4Address &networkAddr, const Ipv4Mask &netmask)
Finds an association tuple.
Definition: olsr-state.cc:493
std::vector< Ipv4Address > FindNeighborInterfaces(const Ipv4Address &neighborMainAddr) const
Returns a vector of all interfaces of a given neighbor, with the exception of the "main" one.
Definition: olsr-state.cc:477
bool FindMprAddress(const Ipv4Address &address)
Checks if there's an MPR with a specific address.
Definition: olsr-state.cc:259
void EraseLinkTuple(const LinkTuple &tuple)
Erases a link tuple.
Definition: olsr-state.cc:347
DuplicateTuple * FindDuplicateTuple(const Ipv4Address &address, uint16_t sequenceNumber)
Finds a duplicate tuple.
Definition: olsr-state.cc:280
void InsertTwoHopNeighborTuple(const TwoHopNeighborTuple &tuple)
Inserts a 2-hop neighbor tuple.
Definition: olsr-state.cc:251
const AssociationSet & GetAssociationSet() const
Gets the association set known to the node.
Definition: olsr-state.h:378
LinkTuple * FindLinkTuple(const Ipv4Address &ifaceAddr)
Finds a link tuple.
Definition: olsr-state.cc:314
const IfaceAssocSet & GetIfaceAssocSet() const
Gets the interface association set.
Definition: olsr-state.h:336
const Associations & GetAssociations() const
Gets the association set the node has.
Definition: olsr-state.h:387
void InsertAssociationTuple(const AssociationTuple &tuple)
Inserts a known association tuple.
Definition: olsr-state.cc:522
void InsertMprSelectorTuple(const MprSelectorTuple &tuple)
Inserts a MPR selector tuple.
Definition: olsr-state.cc:80
LinkTuple & InsertLinkTuple(const LinkTuple &tuple)
Inserts a link tuple.
Definition: olsr-state.cc:360
void EraseTwoHopNeighborTuple(const TwoHopNeighborTuple &tuple)
Erases a 2-hop neighbor tuple.
Definition: olsr-state.cc:204
void InsertIfaceAssocTuple(const IfaceAssocTuple &tuple)
Inserts a interface association tuple.
Definition: olsr-state.cc:471
void EraseTopologyTuple(const TopologyTuple &tuple)
Erases a topology tuple.
Definition: olsr-state.cc:395
NeighborTuple * FindNeighborTuple(const Ipv4Address &mainAddr)
Finds a neighbor tuple.
Definition: olsr-state.cc:107
void EraseOlderTopologyTuples(const Ipv4Address &lastAddr, uint16_t ansn)
Erases a topology tuple.
Definition: olsr-state.cc:408
void EraseDuplicateTuple(const DuplicateTuple &tuple)
Erases a duplicate tuple.
Definition: olsr-state.cc:293
const MprSelectorSet & GetMprSelectors() const
Gets the MPR selectors.
Definition: olsr-state.h:64
void EraseMprSelectorTuple(const MprSelectorTuple &tuple)
Erases a MPR selector tuple.
Definition: olsr-state.cc:51
The basic layout of any packet in OLSR is as follows (omitting IP and UDP headers):
Definition: olsr-header.h:79
void SetPacketSequenceNumber(uint16_t seqnum)
Set the packet sequence number.
Definition: olsr-header.h:106
void SetPacketLength(uint16_t length)
Set the packet total length.
Definition: olsr-header.h:88
uint32_t GetSerializedSize() const override
Definition: olsr-header.cc:129
uint16_t GetPacketLength() const
Get the packet total length.
Definition: olsr-header.h:97
OLSR routing protocol for IPv4.
void SendHna()
Creates a new OLSR HNA message which is buffered for being sent later on.
void RemoveHostNetworkAssociation(Ipv4Address networkAddr, Ipv4Mask netmask)
Removes the specified (networkAddr, netmask) tuple from the list of local HNA associations to be sent...
OlsrState m_state
Internal state with all needed data structs.
void AddTwoHopNeighborTuple(const TwoHopNeighborTuple &tuple)
Adds a 2-hop neighbor tuple to the 2-hop Neighbor Set.
Time m_hnaInterval
HNA messages' emission interval.
const MprSelectorSet & GetMprSelectors() const
Gets the MPR selectors.
void SendQueuedMessages()
Creates as many OLSR packets as needed in order to send all buffered OLSR messages.
uint16_t m_messageSequenceNumber
Messages sequence number counter.
const TwoHopNeighborSet & GetTwoHopNeighbors() const
Get the two hop neighbors.
olsr::MessageList m_queuedMessages
A list of pending messages which are buffered awaiting for being sent.
void RemoveLinkTuple(const LinkTuple &tuple)
Removes a link tuple from the Link Set.
void NotifyRemoveAddress(uint32_t interface, Ipv4InterfaceAddress address) override
void NotifyInterfaceUp(uint32_t interface) override
TracedCallback< uint32_t > m_routingTableChanged
Routing table changes callback.
void QueueMessage(const olsr::MessageHeader &message, Time delay)
Enqueues an OLSR message which will be sent with a delay of (0, delay].
void LinkTupleAdded(const LinkTuple &tuple, Willingness willingness)
Adds a link tuple.
void AddNeighborTuple(const NeighborTuple &tuple)
Adds a neighbor tuple to the Neighbor Set.
std::map< Ptr< Socket >, Ipv4InterfaceAddress > m_sendSockets
Container of sockets and the interfaces they are opened onto.
void LinkSensing(const olsr::MessageHeader &msg, const olsr::MessageHeader::Hello &hello, const Ipv4Address &receiverIface, const Ipv4Address &senderIface)
Updates Link Set according to a new received HELLO message (following RFC 3626 specification).
void SendPacket(Ptr< Packet > packet, const MessageList &containedMessages)
Send an OLSR message.
Timer m_tcTimer
Timer for the TC message.
void AddHostNetworkAssociation(Ipv4Address networkAddr, Ipv4Mask netmask)
Injects the specified (networkAddr, netmask) tuple in the list of local HNA associations to be sent b...
const NeighborSet & GetNeighbors() const
Get the one hop neighbors.
Ptr< Ipv4StaticRouting > m_hnaRoutingTable
Routing table for HNA routes.
void SendHello()
Creates a new OLSR HELLO message which is buffered for being sent later on.
void DoDispose() override
Destructor implementation.
bool IsMyOwnAddress(const Ipv4Address &a) const
Check that address is one of my interfaces.
bool FindSendEntry(const RoutingTableEntry &entry, RoutingTableEntry &outEntry) const
Finds the appropriate entry which must be used in order to forward a data packet to a next hop (given...
bool RouteInput(Ptr< const Packet > p, const Ipv4Header &header, Ptr< const NetDevice > idev, const UnicastForwardCallback &ucb, const MulticastForwardCallback &mcb, const LocalDeliverCallback &lcb, const ErrorCallback &ecb) override
Route an input packet (to be forwarded or locally delivered)
void LinkTupleTimerExpire(Ipv4Address neighborIfaceAddr)
Removes tuple_ if expired.
void MprSelTupleTimerExpire(Ipv4Address mainAddr)
Removes MPR selector tuple_ if expired.
void RemoveTopologyTuple(const TopologyTuple &tuple)
Removes a topology tuple to the Topology Set.
void PopulateTwoHopNeighborSet(const olsr::MessageHeader &msg, const olsr::MessageHeader::Hello &hello)
Updates the 2-hop Neighbor Set according to the information contained in a new received HELLO message...
void AddTopologyTuple(const TopologyTuple &tuple)
Adds a topology tuple to the Topology Set.
void ProcessTc(const olsr::MessageHeader &msg, const Ipv4Address &senderIface)
Processes a TC message following RFC 3626 specification.
void SetRoutingTableAssociation(Ptr< Ipv4StaticRouting > routingTable)
Associates the specified Ipv4StaticRouting routing table to the OLSR routing protocol.
void PopulateMprSelectorSet(const olsr::MessageHeader &msg, const olsr::MessageHeader::Hello &hello)
Updates the MPR Selector Set according to the information contained in a new received HELLO message (...
MprSet GetMprSet() const
Gets the MPR set.
Ipv4Address m_mainAddress
the node main address.
Ptr< UniformRandomVariable > m_uniformRandomVariable
Provides uniform random variables.
void Nb2hopTupleTimerExpire(Ipv4Address neighborMainAddr, Ipv4Address twoHopNeighborAddr)
Removes 2_hop neighbor tuple_ if expired.
void HelloTimerExpire()
Sends a HELLO message and reschedules the HELLO timer.
void AssociationTupleTimerExpire(Ipv4Address gatewayAddr, Ipv4Address networkAddr, Ipv4Mask netmask)
Removes association tuple_ if expired.
static const uint16_t OLSR_PORT_NUMBER
port number (698)
uint32_t GetSize() const
Returns the routing table size.
void SetMainInterface(uint32_t interface)
Set the OLSR main address to the first address on the indicated interface.
void RoutingTableComputation()
Creates the routing table of the node following RFC 3626 hints.
void SendMid()
Creates a new OLSR MID message which is buffered for being sent later on.
void AddEntry(const Ipv4Address &dest, const Ipv4Address &next, uint32_t interface, uint32_t distance)
Adds a new entry into the routing table.
void HnaTimerExpire()
Sends an HNA message (if the node has associated hosts/networks) and reschedules the HNA timer.
void AddIfaceAssocTuple(const IfaceAssocTuple &tuple)
Adds an interface association tuple to the Interface Association Set.
void RemoveDuplicateTuple(const DuplicateTuple &tuple)
Removes a duplicate tuple from the Duplicate Set.
const TopologySet & GetTopologySet() const
Gets the topology set.
void SendTc()
Creates a new OLSR TC message which is buffered for being sent later on.
void DupTupleTimerExpire(Ipv4Address address, uint16_t sequenceNumber)
Removes tuple if expired.
Ipv4Address GetMainAddress(Ipv4Address iface_addr) const
Gets the main address associated with a given interface address.
Timer m_midTimer
Timer for the MID message.
EventGarbageCollector m_events
Running events.
void SetIpv4(Ptr< Ipv4 > ipv4) override
bool Lookup(const Ipv4Address &dest, RoutingTableEntry &outEntry) const
Looks up an entry for the specified destination address.
void ProcessMid(const olsr::MessageHeader &msg, const Ipv4Address &senderIface)
Processes a MID message following RFC 3626 specification.
Ptr< const Ipv4StaticRouting > GetRoutingTableAssociation() const
Returns the internal HNA table.
Timer m_queuedMessagesTimer
timer for throttling outgoing messages
Willingness m_willingness
Willingness for forwarding packets on behalf of other nodes.
uint16_t m_ansn
Advertised Neighbor Set sequence number.
void RemoveIfaceAssocTuple(const IfaceAssocTuple &tuple)
Removed an interface association tuple to the Interface Association Set.
void NotifyInterfaceDown(uint32_t interface) override
void NotifyAddAddress(uint32_t interface, Ipv4InterfaceAddress address) override
Time m_midInterval
MID messages' emission interval.
void Clear()
Clears the routing table and frees the memory assigned to each one of its entries.
void TopologyTupleTimerExpire(Ipv4Address destAddr, Ipv4Address lastAddr)
Removes topology tuple_ if expired.
void MprComputation()
Computes MPR set of a node following RFC 3626 hints.
void ProcessHello(const olsr::MessageHeader &msg, const Ipv4Address &receiverIface, const Ipv4Address &senderIface)
Processes a HELLO message following RFC 3626 specification.
static TypeId GetTypeId()
Get the type ID.
std::map< Ipv4Address, RoutingTableEntry > m_table
Data structure for the routing table.
void RemoveEntry(const Ipv4Address &dest)
Deletes the entry whose destination address is given.
void PopulateNeighborSet(const olsr::MessageHeader &msg, const olsr::MessageHeader::Hello &hello)
Updates the Neighbor Set according to the information contained in a new received HELLO message (foll...
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
uint16_t m_packetSequenceNumber
Packets sequence number counter.
Timer m_helloTimer
Timer for the HELLO message.
void PrintRoutingTable(Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S) const override
Print the Routing Table entries.
int Degree(const NeighborTuple &tuple)
This auxiliary function (defined in RFC 3626) is used for calculating the MPR Set.
void RemoveMprSelectorTuple(const MprSelectorTuple &tuple)
Removes an MPR selector tuple from the MPR Selector Set.
void ProcessHna(const olsr::MessageHeader &msg, const Ipv4Address &senderIface)
Processes a HNA message following RFC 3626 specification.
Ptr< Socket > m_recvSocket
Receiving socket.
uint16_t GetPacketSequenceNumber()
Increments packet sequence number and returns the new value.
void DoInitialize() override
Initialize() implementation.
TracedCallback< const PacketHeader &, const MessageList & > m_txPacketTrace
Tx packet trace.
void IncrementAnsn()
Increments the ANSN counter.
Ptr< Ipv4Route > RouteOutput(Ptr< Packet > p, const Ipv4Header &header, Ptr< NetDevice > oif, Socket::SocketErrno &sockerr) override
Query routing cache for an existing route, for an outbound packet.
void SetInterfaceExclusions(std::set< uint32_t > exceptions)
Set the interfaces to be excluded.
void ForwardDefault(olsr::MessageHeader olsrMessage, DuplicateTuple *duplicated, const Ipv4Address &localIface, const Ipv4Address &senderAddress)
OLSR's default forwarding algorithm.
Time m_helloInterval
HELLO messages' emission interval.
Timer m_hnaTimer
Timer for the HNA message.
std::vector< RoutingTableEntry > GetRoutingTableEntries() const
Get the routing table entries.
void LinkTupleUpdated(const LinkTuple &tuple, Willingness willingness)
This function is invoked when a link tuple is updated.
void AddAssociationTuple(const AssociationTuple &tuple)
Adds a host network association tuple to the Association Set.
void AddDuplicateTuple(const DuplicateTuple &tuple)
Adds a duplicate tuple to the Duplicate Set.
void TcTimerExpire()
Sends a TC message (if there exists any MPR selector) and reschedules the TC timer.
TracedCallback< const PacketHeader &, const MessageList & > m_rxPacketTrace
Rx packet trace.
void Dump()
Dump the neighbor table, two-hop neighbor table, and routing table to logging output (NS_LOG_DEBUG lo...
void MidTimerExpire()
Sends a MID message (if the node has more than one interface) and resets the MID timer.
void RemoveTwoHopNeighborTuple(const TwoHopNeighborTuple &tuple)
Removes a 2-hop neighbor tuple from the 2-hop Neighbor Set.
void RemoveAssociationTuple(const AssociationTuple &tuple)
Removes a host network association tuple to the Association Set.
Time m_tcInterval
TC messages' emission interval.
bool UsesNonOlsrOutgoingInterface(const Ipv4RoutingTableEntry &route)
Tests whether or not the specified route uses a non-OLSR outgoing interface.
Ptr< Ipv4StaticRouting > m_routingTableAssociation
Associations from an Ipv4StaticRouting instance.
bool m_linkTupleTimerFirstTime
Flag to indicate if it is the first time the LinkTupleTimer fires.
const OlsrState & GetOlsrState() const
Gets the underlying OLSR state object.
uint16_t GetMessageSequenceNumber()
Increments message sequence number and returns the new value.
void RemoveNeighborTuple(const NeighborTuple &tuple)
Removes a neighbor tuple from the Neighbor Set.
void IfaceAssocTupleTimerExpire(Ipv4Address ifaceAddr)
Removes interface association tuple_ if expired.
void RecvOlsr(Ptr< Socket > socket)
Receive an OLSR message.
std::set< uint32_t > m_interfaceExclusions
Set of interfaces excluded by OSLR.
void NeighborLoss(const LinkTuple &tuple)
Performs all actions needed when a neighbor loss occurs.
Ptr< Ipv4 > m_ipv4
IPv4 object the routing is linked to.
void AddMprSelectorTuple(const MprSelectorTuple &tuple)
Adds an MPR selector tuple to the MPR Selector Set.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition: nstime.h:1427
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1407
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:49
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:261
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
LinkType
OLSR link types.
NeighborType
OLSR neighbor types.
Willingness
Willingness for forwarding packets from other nodes.
@ UNSPEC_LINK
Unspecified link type.
@ LOST_LINK
Lost link type.
@ ASYM_LINK
Asymmetric link type.
@ SYM_LINK
Symmetric link type.
@ SYM_NEIGH
Symmetric neighbor type.
@ NOT_NEIGH
Not neighbor type.
@ MPR_NEIGH
Asymmetric neighbor type.
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:305
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1319
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
void CoverTwoHopNeighbors(Ipv4Address neighborMainAddr, TwoHopNeighborSet &N2)
Remove all covered 2-hop neighbors from N2 set.
std::ostream & operator<<(std::ostream &os, const PacketHeader &packet)
Definition: olsr-header.h:690
std::vector< MprSelectorTuple > MprSelectorSet
MPR Selector Set type.
std::vector< AssociationTuple > AssociationSet
Association Set type.
std::vector< TwoHopNeighborTuple > TwoHopNeighborSet
2-hop Neighbor Set type.
std::vector< LinkTuple > LinkSet
Link Set type.
std::vector< Association > Associations
Association Set type.
std::vector< TopologyTuple > TopologySet
Topology Set type.
std::set< Ipv4Address > MprSet
MPR Set type.
std::vector< NeighborTuple > NeighborSet
Neighbor Set type.
std::vector< MessageHeader > MessageList
Definition: olsr-header.h:703
std::vector< IfaceAssocTuple > IfaceAssocSet
Interface Association Set type.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:706
Ptr< const AttributeChecker > MakeEnumChecker(T v, std::string n, Ts... args)
Make an EnumChecker pre-configured with a set of allowed values by name.
Definition: enum.h:189
Definition: olsr.py:1
#define JITTER
Random number between [0-OLSR_MAXJITTER] used to jitter OLSR packet transmission.
#define OLSR_HNA_HOLD_TIME
HNA holding time.
#define OLSR_NEIGHB_HOLD_TIME
Neighbor holding time.
#define OLSR_MAX_SEQ_NUM
Maximum allowed sequence number.
#define OLSR_TOP_HOLD_TIME
Top holding time.
#define OLSR_MID_HOLD_TIME
MID holding time.
#define OLSR_DUP_HOLD_TIME
Dup holding time.
#define OLSR_MAX_MSGS
Maximum number of messages per packet.
#define DELAY(time)
Gets the delay between a given time and the current time.
Ipv4Address networkAddr
IPv4 Network address.
Ipv4Mask netmask
IPv4 Network mask.
Ipv4Address networkAddr
Network Address of network reachable through gatewayAddr.
Ipv4Mask netmask
Netmask of network reachable through gatewayAddr.
Time expirationTime
Time at which this tuple expires and must be removed.
Ipv4Address gatewayAddr
Main address of the gateway.
std::vector< Ipv4Address > ifaceList
List of interfaces which the message has been received on.
Ipv4Address address
Originator address of the message.
uint16_t sequenceNumber
Message sequence number.
bool retransmitted
Indicates whether the message has been retransmitted or not.
Time expirationTime
Time at which this tuple expires and must be removed.
An Interface Association Tuple.
Ipv4Address ifaceAddr
Interface address of a node.
Time time
Time at which this tuple expires and must be removed.
Ipv4Address mainAddr
Main address of the node.
HELLO Message Format.
Definition: olsr-header.h:386
void SetHTime(Time time)
Set the HELLO emission interval.
Definition: olsr-header.h:403
Willingness willingness
The willingness of a node to carry and forward traffic for other nodes.
Definition: olsr-header.h:417
std::vector< LinkMessage > linkMessages
Link messages container.
Definition: olsr-header.h:419
HNA (Host Network Association) Message Format.
Definition: olsr-header.h:525
std::vector< Association > associations
Association container.
Definition: olsr-header.h:535
MID Message Format.
Definition: olsr-header.h:323
std::vector< Ipv4Address > interfaceAddresses
Interface Address container.
Definition: olsr-header.h:324
TC Message Format.
Definition: olsr-header.h:470
uint16_t ansn
Advertised Neighbor Sequence Number.
Definition: olsr-header.h:472
std::vector< Ipv4Address > neighborAddresses
Neighbor address container.
Definition: olsr-header.h:471
An MPR-Selector Tuple.
Ipv4Address mainAddr
Main address of a node which have selected this node as a MPR.
Time expirationTime
Time at which this tuple expires and must be removed.
Ipv4Address neighborMainAddr
Main address of a neighbor node.
Willingness willingness
A value between 0 and 7 specifying the node's willingness to carry traffic on behalf of other nodes.
Status status
Status of the link.
An OLSR's routing table entry.
uint32_t distance
Distance in hops to the destination.
Ipv4Address nextAddr
Address of the next hop.
uint32_t interface
Interface index.
Ipv4Address destAddr
Address of the destination node.
Ipv4Address destAddr
Main address of the destination.
Ipv4Address lastAddr
Main address of a node which is a neighbor of the destination.
uint16_t sequenceNumber
Sequence number.
Time expirationTime
Time at which this tuple expires and must be removed.
Ipv4Address twoHopNeighborAddr
Main address of a 2-hop neighbor with a symmetric link to nb_main_addr.
Ipv4Address neighborMainAddr
Main address of a neighbor.
Time expirationTime
Time at which this tuple expires and must be removed.