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