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