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