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