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