This documentation is not the Latest Release.
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 "olsr-routing-protocol.h"
36 #include "ns3/socket-factory.h"
37 #include "ns3/udp-socket-factory.h"
38 #include "ns3/simulator.h"
39 #include "ns3/log.h"
40 #include "ns3/names.h"
41 #include "ns3/inet-socket-address.h"
42 #include "ns3/ipv4-routing-protocol.h"
43 #include "ns3/ipv4-routing-table-entry.h"
44 #include "ns3/ipv4-route.h"
45 #include "ns3/boolean.h"
46 #include "ns3/uinteger.h"
47 #include "ns3/enum.h"
48 #include "ns3/trace-source-accessor.h"
49 #include "ns3/ipv4-header.h"
50 
51 /********** Useful macros **********/
52 
59 #define DELAY(time) (((time) < (Simulator::Now ())) ? Seconds (0.000001) : \
60  (time - Simulator::Now () + Seconds (0.000001)))
61 
62 
63 
69 #define OLSR_REFRESH_INTERVAL m_helloInterval
70 
71 
72 /********** Holding times **********/
73 
75 #define OLSR_NEIGHB_HOLD_TIME Time (3 * OLSR_REFRESH_INTERVAL)
76 #define OLSR_TOP_HOLD_TIME Time (3 * m_tcInterval)
78 #define OLSR_DUP_HOLD_TIME Seconds (30)
80 #define OLSR_MID_HOLD_TIME Time (3 * m_midInterval)
82 #define OLSR_HNA_HOLD_TIME Time (3 * m_hnaInterval)
84 
85 /********** Link types **********/
86 
88 #define OLSR_UNSPEC_LINK 0
89 #define OLSR_ASYM_LINK 1
91 #define OLSR_SYM_LINK 2
93 #define OLSR_LOST_LINK 3
95 
96 /********** Neighbor types **********/
97 
99 #define OLSR_NOT_NEIGH 0
100 #define OLSR_SYM_NEIGH 1
102 #define OLSR_MPR_NEIGH 2
104 
105 
106 /********** Willingness **********/
107 
109 #define OLSR_WILL_NEVER 0
110 #define OLSR_WILL_LOW 1
112 #define OLSR_WILL_DEFAULT 3
114 #define OLSR_WILL_HIGH 6
116 #define OLSR_WILL_ALWAYS 7
118 
119 
120 /********** Miscellaneous constants **********/
121 
123 #define OLSR_MAXJITTER (m_helloInterval.GetSeconds () / 4)
124 #define OLSR_MAX_SEQ_NUM 65535
126 #define JITTER (Seconds (m_uniformRandomVariable->GetValue (0, OLSR_MAXJITTER)))
128 
129 
130 #define OLSR_PORT_NUMBER 698
131 #define OLSR_MAX_MSGS 64
133 
135 #define OLSR_MAX_HELLOS 12
136 
138 #define OLSR_MAX_ADDRS 64
139 
140 
141 namespace ns3 {
142 
143 NS_LOG_COMPONENT_DEFINE ("OlsrRoutingProtocol");
144 
145 namespace olsr {
146 
147 /********** OLSR class **********/
148 
149 NS_OBJECT_ENSURE_REGISTERED (RoutingProtocol);
150 
151 TypeId
153 {
154  static TypeId tid = TypeId ("ns3::olsr::RoutingProtocol")
156  .SetGroupName ("Olsr")
157  .AddConstructor<RoutingProtocol> ()
158  .AddAttribute ("HelloInterval", "HELLO messages emission interval.",
159  TimeValue (Seconds (2)),
161  MakeTimeChecker ())
162  .AddAttribute ("TcInterval", "TC messages emission interval.",
163  TimeValue (Seconds (5)),
165  MakeTimeChecker ())
166  .AddAttribute ("MidInterval", "MID messages emission interval. Normally it is equal to TcInterval.",
167  TimeValue (Seconds (5)),
169  MakeTimeChecker ())
170  .AddAttribute ("HnaInterval", "HNA messages emission interval. Normally it is equal to TcInterval.",
171  TimeValue (Seconds (5)),
173  MakeTimeChecker ())
174  .AddAttribute ("Willingness", "Willingness of a node to carry and forward traffic for other nodes.",
178  OLSR_WILL_LOW, "low",
179  OLSR_WILL_DEFAULT, "default",
180  OLSR_WILL_HIGH, "high",
181  OLSR_WILL_ALWAYS, "always"))
182  .AddTraceSource ("Rx", "Receive OLSR packet.",
184  "ns3::olsr::RoutingProtocol::PacketTxRxTracedCallback")
185  .AddTraceSource ("Tx", "Send OLSR packet.",
187  "ns3::olsr::RoutingProtocol::PacketTxRxTracedCallback")
188  .AddTraceSource ("RoutingTableChanged", "The OLSR routing table has changed.",
190  "ns3::olsr::RoutingProtocol::TableChangeTracedCallback")
191  ;
192  return tid;
193 }
194 
195 
197  : m_routingTableAssociation (0),
198  m_ipv4 (0),
199  m_helloTimer (Timer::CANCEL_ON_DESTROY),
200  m_tcTimer (Timer::CANCEL_ON_DESTROY),
201  m_midTimer (Timer::CANCEL_ON_DESTROY),
202  m_hnaTimer (Timer::CANCEL_ON_DESTROY),
203  m_queuedMessagesTimer (Timer::CANCEL_ON_DESTROY)
204 {
205  m_uniformRandomVariable = CreateObject<UniformRandomVariable> ();
206 
207  m_hnaRoutingTable = Create<Ipv4StaticRouting> ();
208 }
209 
211 {
212 }
213 
214 void
216 {
217  NS_ASSERT (ipv4 != 0);
218  NS_ASSERT (m_ipv4 == 0);
219  NS_LOG_DEBUG ("Created olsr::RoutingProtocol");
225 
229 
231 
232  m_ipv4 = ipv4;
233 
234  m_hnaRoutingTable->SetIpv4 (ipv4);
235 }
236 
238 {
239  m_ipv4 = 0;
240  m_hnaRoutingTable = 0;
242 
243  for (std::map< Ptr<Socket>, Ipv4InterfaceAddress >::iterator iter = m_socketAddresses.begin ();
244  iter != m_socketAddresses.end (); iter++)
245  {
246  iter->first->Close ();
247  }
248  m_socketAddresses.clear ();
249 
251 }
252 
253 void
255 {
256  std::ostream* os = stream->GetStream ();
257 
258  *os << "Node: " << m_ipv4->GetObject<Node> ()->GetId ()
259  << ", Time: " << Now().As (Time::S)
260  << ", Local time: " << GetObject<Node> ()->GetLocalTime ().As (Time::S)
261  << ", OLSR Routing table" << std::endl;
262 
263  *os << "Destination\t\tNextHop\t\tInterface\tDistance\n";
264 
265  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin ();
266  iter != m_table.end (); iter++)
267  {
268  *os << iter->first << "\t\t";
269  *os << iter->second.nextAddr << "\t\t";
270  if (Names::FindName (m_ipv4->GetNetDevice (iter->second.interface)) != "")
271  {
272  *os << Names::FindName (m_ipv4->GetNetDevice (iter->second.interface)) << "\t\t";
273  }
274  else
275  {
276  *os << iter->second.interface << "\t\t";
277  }
278  *os << iter->second.distance << "\t";
279  *os << "\n";
280  }
281 
282  // Also print the HNA routing table
283  if (m_hnaRoutingTable->GetNRoutes () > 0)
284  {
285  *os << " HNA Routing Table: ";
286  m_hnaRoutingTable->PrintRoutingTable (stream);
287  }
288  else
289  {
290  *os << " HNA Routing Table: empty" << std::endl;
291  }
292 }
293 
295 {
296  if (m_mainAddress == Ipv4Address ())
297  {
298  Ipv4Address loopback ("127.0.0.1");
299  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
300  {
301  // Use primary address, if multiple
302  Ipv4Address addr = m_ipv4->GetAddress (i, 0).GetLocal ();
303  if (addr != loopback)
304  {
305  m_mainAddress = addr;
306  break;
307  }
308  }
309 
311  }
312 
313  NS_LOG_DEBUG ("Starting OLSR on node " << m_mainAddress);
314 
315  Ipv4Address loopback ("127.0.0.1");
316 
317  bool canRunOlsr = false;
318  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
319  {
320  Ipv4Address addr = m_ipv4->GetAddress (i, 0).GetLocal ();
321  if (addr == loopback)
322  continue;
323 
324  if (addr != m_mainAddress)
325  {
326  // Create never expiring interface association tuple entries for our
327  // own network interfaces, so that GetMainAddress () works to
328  // translate the node's own interface addresses into the main address.
329  IfaceAssocTuple tuple;
330  tuple.ifaceAddr = addr;
331  tuple.mainAddr = m_mainAddress;
332  AddIfaceAssocTuple (tuple);
334  }
335 
336  if(m_interfaceExclusions.find (i) != m_interfaceExclusions.end ())
337  continue;
338 
339  // Create a socket to listen only on this interface
340  Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
342  socket->SetAllowBroadcast (true);
343  InetSocketAddress inetAddr (m_ipv4->GetAddress (i, 0).GetLocal (), OLSR_PORT_NUMBER);
345  if (socket->Bind (inetAddr))
346  {
347  NS_FATAL_ERROR ("Failed to bind() OLSR socket");
348  }
349  socket->BindToNetDevice (m_ipv4->GetNetDevice (i));
350  m_socketAddresses[socket] = m_ipv4->GetAddress (i, 0);
351 
352  canRunOlsr = true;
353  }
354 
355  if(canRunOlsr)
356  {
357  HelloTimerExpire ();
358  TcTimerExpire ();
359  MidTimerExpire ();
360  HnaTimerExpire ();
361 
362  NS_LOG_DEBUG ("OLSR on node " << m_mainAddress << " started");
363  }
364 }
365 
366 void RoutingProtocol::SetMainInterface (uint32_t interface)
367 {
368  m_mainAddress = m_ipv4->GetAddress (interface, 0).GetLocal ();
369 }
370 
371 void RoutingProtocol::SetInterfaceExclusions (std::set<uint32_t> exceptions)
372 {
373  m_interfaceExclusions = exceptions;
374 }
375 
376 //
377 // \brief Processes an incoming %OLSR packet following \RFC{3626} specification.
378 void
380 {
381  Ptr<Packet> receivedPacket;
382  Address sourceAddress;
383  receivedPacket = socket->RecvFrom (sourceAddress);
384 
385  InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom (sourceAddress);
386  Ipv4Address senderIfaceAddr = inetSourceAddr.GetIpv4 ();
387  Ipv4Address receiverIfaceAddr = m_socketAddresses[socket].GetLocal ();
388  NS_ASSERT (receiverIfaceAddr != Ipv4Address ());
389  NS_LOG_DEBUG ("OLSR node " << m_mainAddress << " received a OLSR packet from "
390  << senderIfaceAddr << " to " << receiverIfaceAddr);
391 
392  // All routing messages are sent from and to port RT_PORT,
393  // so we check it.
394  NS_ASSERT (inetSourceAddr.GetPort () == OLSR_PORT_NUMBER);
395 
396  Ptr<Packet> packet = receivedPacket;
397 
398  olsr::PacketHeader olsrPacketHeader;
399  packet->RemoveHeader (olsrPacketHeader);
400  NS_ASSERT (olsrPacketHeader.GetPacketLength () >= olsrPacketHeader.GetSerializedSize ());
401  uint32_t sizeLeft = olsrPacketHeader.GetPacketLength () - olsrPacketHeader.GetSerializedSize ();
402 
403  MessageList messages;
404 
405  while (sizeLeft)
406  {
407  MessageHeader messageHeader;
408  if (packet->RemoveHeader (messageHeader) == 0)
409  NS_ASSERT (false);
410 
411  sizeLeft -= messageHeader.GetSerializedSize ();
412 
413  NS_LOG_DEBUG ("Olsr Msg received with type "
414  << std::dec << int (messageHeader.GetMessageType ())
415  << " TTL=" << int (messageHeader.GetTimeToLive ())
416  << " origAddr=" << messageHeader.GetOriginatorAddress ());
417  messages.push_back (messageHeader);
418  }
419 
420  m_rxPacketTrace (olsrPacketHeader, messages);
421 
422  for (MessageList::const_iterator messageIter = messages.begin ();
423  messageIter != messages.end (); messageIter++)
424  {
425  const MessageHeader &messageHeader = *messageIter;
426  // If ttl is less than or equal to zero, or
427  // the receiver is the same as the originator,
428  // the message must be silently dropped
429  if (messageHeader.GetTimeToLive () == 0
430  || messageHeader.GetOriginatorAddress () == m_mainAddress)
431  {
432  packet->RemoveAtStart (messageHeader.GetSerializedSize ()
433  - messageHeader.GetSerializedSize ());
434  continue;
435  }
436 
437  // If the message has been processed it must not be processed again
438  bool do_forwarding = true;
440  (messageHeader.GetOriginatorAddress (),
441  messageHeader.GetMessageSequenceNumber ());
442 
443  // Get main address of the peer, which may be different from the packet source address
444 // const IfaceAssocTuple *ifaceAssoc = m_state.FindIfaceAssocTuple (inetSourceAddr.GetIpv4 ());
445 // Ipv4Address peerMainAddress;
446 // if (ifaceAssoc != NULL)
447 // {
448 // peerMainAddress = ifaceAssoc->mainAddr;
449 // }
450 // else
451 // {
452 // peerMainAddress = inetSourceAddr.GetIpv4 () ;
453 // }
454 
455  if (duplicated == NULL)
456  {
457  switch (messageHeader.GetMessageType ())
458  {
460  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
461  << "s OLSR node " << m_mainAddress
462  << " received HELLO message of size " << messageHeader.GetSerializedSize ());
463  ProcessHello (messageHeader, receiverIfaceAddr, senderIfaceAddr);
464  break;
465 
467  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
468  << "s OLSR node " << m_mainAddress
469  << " received TC message of size " << messageHeader.GetSerializedSize ());
470  ProcessTc (messageHeader, senderIfaceAddr);
471  break;
472 
474  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
475  << "s OLSR node " << m_mainAddress
476  << " received MID message of size " << messageHeader.GetSerializedSize ());
477  ProcessMid (messageHeader, senderIfaceAddr);
478  break;
480  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
481  << "s OLSR node " << m_mainAddress
482  << " received HNA message of size " << messageHeader.GetSerializedSize ());
483  ProcessHna (messageHeader, senderIfaceAddr);
484  break;
485 
486  default:
487  NS_LOG_DEBUG ("OLSR message type " <<
488  int (messageHeader.GetMessageType ()) <<
489  " not implemented");
490  }
491  }
492  else
493  {
494  NS_LOG_DEBUG ("OLSR message is duplicated, not reading it.");
495 
496  // If the message has been considered for forwarding, it should
497  // not be retransmitted again
498  for (std::vector<Ipv4Address>::const_iterator it = duplicated->ifaceList.begin ();
499  it != duplicated->ifaceList.end (); it++)
500  {
501  if (*it == receiverIfaceAddr)
502  {
503  do_forwarding = false;
504  break;
505  }
506  }
507  }
508 
509  if (do_forwarding)
510  {
511  // HELLO messages are never forwarded.
512  // TC and MID messages are forwarded using the default algorithm.
513  // Remaining messages are also forwarded using the default algorithm.
514  if (messageHeader.GetMessageType () != olsr::MessageHeader::HELLO_MESSAGE)
515  {
516  ForwardDefault (messageHeader, duplicated,
517  receiverIfaceAddr, inetSourceAddr.GetIpv4 ());
518  }
519  }
520  }
521 
522  // After processing all OLSR messages, we must recompute the routing table
524 }
525 
532 int
534 {
535  int degree = 0;
536  for (TwoHopNeighborSet::const_iterator it = m_state.GetTwoHopNeighbors ().begin ();
537  it != m_state.GetTwoHopNeighbors ().end (); it++)
538  {
539  TwoHopNeighborTuple const &nb2hop_tuple = *it;
540  if (nb2hop_tuple.neighborMainAddr == tuple.neighborMainAddr)
541  {
542  const NeighborTuple *nb_tuple =
544  if (nb_tuple == NULL)
545  degree++;
546  }
547  }
548  return degree;
549 }
550 
551 namespace {
555 void
557 {
558  // first gather all 2-hop neighbors to be removed
559  std::set<Ipv4Address> toRemove;
560  for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin (); twoHopNeigh != N2.end (); twoHopNeigh++)
561  {
562  if (twoHopNeigh->neighborMainAddr == neighborMainAddr)
563  {
564  toRemove.insert (twoHopNeigh->twoHopNeighborAddr);
565  }
566  }
567  // Now remove all matching records from N2
568  for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin (); twoHopNeigh != N2.end (); )
569  {
570  if (toRemove.find (twoHopNeigh->twoHopNeighborAddr) != toRemove.end ())
571  {
572  twoHopNeigh = N2.erase (twoHopNeigh);
573  }
574  else
575  {
576  twoHopNeigh++;
577  }
578  }
579 }
580 } // anonymous namespace
581 
585 void
587 {
588  NS_LOG_FUNCTION (this);
589 
590  // MPR computation should be done for each interface. See section 8.3.1
591  // (RFC 3626) for details.
592  MprSet mprSet;
593 
594  // N is the subset of neighbors of the node, which are
595  // neighbor "of the interface I"
596  NeighborSet N;
597  for (NeighborSet::const_iterator neighbor = m_state.GetNeighbors ().begin ();
598  neighbor != m_state.GetNeighbors ().end (); neighbor++)
599  {
600  if (neighbor->status == NeighborTuple::STATUS_SYM) // I think that we need this check
601  {
602  N.push_back (*neighbor);
603  }
604  }
605 
606  // N2 is the set of 2-hop neighbors reachable from "the interface
607  // I", excluding:
608  // (i) the nodes only reachable by members of N with willingness WILL_NEVER
609  // (ii) the node performing the computation
610  // (iii) all the symmetric neighbors: the nodes for which there exists a symmetric
611  // link to this node on some interface.
613  for (TwoHopNeighborSet::const_iterator twoHopNeigh = m_state.GetTwoHopNeighbors ().begin ();
614  twoHopNeigh != m_state.GetTwoHopNeighbors ().end (); twoHopNeigh++)
615  {
616  // excluding:
617  // (ii) the node performing the computation
618  if (twoHopNeigh->twoHopNeighborAddr == m_mainAddress)
619  {
620  continue;
621  }
622 
623  // excluding:
624  // (i) the nodes only reachable by members of N with willingness WILL_NEVER
625  bool ok = false;
626  for (NeighborSet::const_iterator neigh = N.begin ();
627  neigh != N.end (); neigh++)
628  {
629  if (neigh->neighborMainAddr == twoHopNeigh->neighborMainAddr)
630  {
631  if (neigh->willingness == OLSR_WILL_NEVER)
632  {
633  ok = false;
634  break;
635  }
636  else
637  {
638  ok = true;
639  break;
640  }
641  }
642  }
643  if (!ok)
644  {
645  continue;
646  }
647 
648  // excluding:
649  // (iii) all the symmetric neighbors: the nodes for which there exists a symmetric
650  // link to this node on some interface.
651  for (NeighborSet::const_iterator neigh = N.begin ();
652  neigh != N.end (); neigh++)
653  {
654  if (neigh->neighborMainAddr == twoHopNeigh->twoHopNeighborAddr)
655  {
656  ok = false;
657  break;
658  }
659  }
660 
661  if (ok)
662  {
663  N2.push_back (*twoHopNeigh);
664  }
665  }
666 
667 #ifdef NS3_LOG_ENABLE
668  {
669  std::ostringstream os;
670  os << "[";
671  for (TwoHopNeighborSet::const_iterator iter = N2.begin ();
672  iter != N2.end (); iter++)
673  {
674  TwoHopNeighborSet::const_iterator next = iter;
675  next++;
676  os << iter->neighborMainAddr << "->" << iter->twoHopNeighborAddr;
677  if (next != N2.end ())
678  os << ", ";
679  }
680  os << "]";
681  NS_LOG_DEBUG ("N2: " << os.str ());
682  }
683 #endif //NS3_LOG_ENABLE
684 
685  // 1. Start with an MPR set made of all members of N with
686  // N_willingness equal to WILL_ALWAYS
687  for (NeighborSet::const_iterator neighbor = N.begin (); neighbor != N.end (); neighbor++)
688  {
689  if (neighbor->willingness == OLSR_WILL_ALWAYS)
690  {
691  mprSet.insert (neighbor->neighborMainAddr);
692  // (not in RFC but I think is needed: remove the 2-hop
693  // neighbors reachable by the MPR from N2)
694  CoverTwoHopNeighbors (neighbor->neighborMainAddr, N2);
695  }
696  }
697 
698  // 2. Calculate D(y), where y is a member of N, for all nodes in N.
699  // (we do this later)
700 
701  // 3. Add to the MPR set those nodes in N, which are the *only*
702  // nodes to provide reachability to a node in N2.
703  std::set<Ipv4Address> coveredTwoHopNeighbors;
704  for (TwoHopNeighborSet::const_iterator twoHopNeigh = N2.begin (); twoHopNeigh != N2.end (); twoHopNeigh++)
705  {
706  bool onlyOne = true;
707  // try to find another neighbor that can reach twoHopNeigh->twoHopNeighborAddr
708  for (TwoHopNeighborSet::const_iterator otherTwoHopNeigh = N2.begin (); otherTwoHopNeigh != N2.end (); otherTwoHopNeigh++)
709  {
710  if (otherTwoHopNeigh->twoHopNeighborAddr == twoHopNeigh->twoHopNeighborAddr
711  && otherTwoHopNeigh->neighborMainAddr != twoHopNeigh->neighborMainAddr)
712  {
713  onlyOne = false;
714  break;
715  }
716  }
717  if (onlyOne)
718  {
719  NS_LOG_LOGIC ("Neighbor " << twoHopNeigh->neighborMainAddr
720  << " is the only that can reach 2-hop neigh. "
721  << twoHopNeigh->twoHopNeighborAddr
722  << " => select as MPR.");
723 
724  mprSet.insert (twoHopNeigh->neighborMainAddr);
725 
726  // take note of all the 2-hop neighbors reachable by the newly elected MPR
727  for (TwoHopNeighborSet::const_iterator otherTwoHopNeigh = N2.begin ();
728  otherTwoHopNeigh != N2.end (); otherTwoHopNeigh++)
729  {
730  if (otherTwoHopNeigh->neighborMainAddr == twoHopNeigh->neighborMainAddr)
731  {
732  coveredTwoHopNeighbors.insert (otherTwoHopNeigh->twoHopNeighborAddr);
733  }
734  }
735  }
736  }
737  // Remove the nodes from N2 which are now covered by a node in the MPR set.
738  for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin ();
739  twoHopNeigh != N2.end (); )
740  {
741  if (coveredTwoHopNeighbors.find (twoHopNeigh->twoHopNeighborAddr) != coveredTwoHopNeighbors.end ())
742  {
743  // This works correctly only because it is known that twoHopNeigh is reachable by exactly one neighbor,
744  // so only one record in N2 exists for each of them. This record is erased here.
745  NS_LOG_LOGIC ("2-hop neigh. " << twoHopNeigh->twoHopNeighborAddr << " is already covered by an MPR.");
746  twoHopNeigh = N2.erase (twoHopNeigh);
747  }
748  else
749  {
750  twoHopNeigh++;
751  }
752  }
753 
754  // 4. While there exist nodes in N2 which are not covered by at
755  // least one node in the MPR set:
756  while (N2.begin () != N2.end ())
757  {
758 
759 #ifdef NS3_LOG_ENABLE
760  {
761  std::ostringstream os;
762  os << "[";
763  for (TwoHopNeighborSet::const_iterator iter = N2.begin ();
764  iter != N2.end (); iter++)
765  {
766  TwoHopNeighborSet::const_iterator next = iter;
767  next++;
768  os << iter->neighborMainAddr << "->" << iter->twoHopNeighborAddr;
769  if (next != N2.end ())
770  os << ", ";
771  }
772  os << "]";
773  NS_LOG_DEBUG ("Step 4 iteration: N2=" << os.str ());
774  }
775 #endif //NS3_LOG_ENABLE
776 
777 
778  // 4.1. For each node in N, calculate the reachability, i.e., the
779  // number of nodes in N2 which are not yet covered by at
780  // least one node in the MPR set, and which are reachable
781  // through this 1-hop neighbor
782  std::map<int, std::vector<const NeighborTuple *> > reachability;
783  std::set<int> rs;
784  for (NeighborSet::iterator it = N.begin (); it != N.end (); it++)
785  {
786  NeighborTuple const &nb_tuple = *it;
787  int r = 0;
788  for (TwoHopNeighborSet::iterator it2 = N2.begin (); it2 != N2.end (); it2++)
789  {
790  TwoHopNeighborTuple const &nb2hop_tuple = *it2;
791  if (nb_tuple.neighborMainAddr == nb2hop_tuple.neighborMainAddr)
792  r++;
793  }
794  rs.insert (r);
795  reachability[r].push_back (&nb_tuple);
796  }
797 
798  // 4.2. Select as a MPR the node with highest N_willingness among
799  // the nodes in N with non-zero reachability. In case of
800  // multiple choice select the node which provides
801  // reachability to the maximum number of nodes in N2. In
802  // case of multiple nodes providing the same amount of
803  // reachability, select the node as MPR whose D(y) is
804  // greater. Remove the nodes from N2 which are now covered
805  // by a node in the MPR set.
806  NeighborTuple const *max = NULL;
807  int max_r = 0;
808  for (std::set<int>::iterator it = rs.begin (); it != rs.end (); it++)
809  {
810  int r = *it;
811  if (r == 0)
812  {
813  continue;
814  }
815  for (std::vector<const NeighborTuple *>::iterator it2 = reachability[r].begin ();
816  it2 != reachability[r].end (); it2++)
817  {
818  const NeighborTuple *nb_tuple = *it2;
819  if (max == NULL || nb_tuple->willingness > max->willingness)
820  {
821  max = nb_tuple;
822  max_r = r;
823  }
824  else if (nb_tuple->willingness == max->willingness)
825  {
826  if (r > max_r)
827  {
828  max = nb_tuple;
829  max_r = r;
830  }
831  else if (r == max_r)
832  {
833  if (Degree (*nb_tuple) > Degree (*max))
834  {
835  max = nb_tuple;
836  max_r = r;
837  }
838  }
839  }
840  }
841  }
842 
843  if (max != NULL)
844  {
845  mprSet.insert (max->neighborMainAddr);
847  NS_LOG_LOGIC (N2.size () << " 2-hop neighbors left to cover!");
848  }
849  }
850 
851 #ifdef NS3_LOG_ENABLE
852  {
853  std::ostringstream os;
854  os << "[";
855  for (MprSet::const_iterator iter = mprSet.begin ();
856  iter != mprSet.end (); iter++)
857  {
858  MprSet::const_iterator next = iter;
859  next++;
860  os << *iter;
861  if (next != mprSet.end ())
862  os << ", ";
863  }
864  os << "]";
865  NS_LOG_DEBUG ("Computed MPR set for node " << m_mainAddress << ": " << os.str ());
866  }
867 #endif //NS3_LOG_ENABLE
868 
869  m_state.SetMprSet (mprSet);
870 }
871 
880 {
881  const IfaceAssocTuple *tuple =
882  m_state.FindIfaceAssocTuple (iface_addr);
883 
884  if (tuple != NULL)
885  return tuple->mainAddr;
886  else
887  return iface_addr;
888 }
889 
893 void
895 {
896  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " s: Node " << m_mainAddress
897  << ": RoutingTableComputation begin...");
898 
899  // 1. All the entries from the routing table are removed.
900  Clear ();
901 
902  // 2. The new routing entries are added starting with the
903  // symmetric neighbors (h=1) as the destination nodes.
904  const NeighborSet &neighborSet = m_state.GetNeighbors ();
905  for (NeighborSet::const_iterator it = neighborSet.begin ();
906  it != neighborSet.end (); it++)
907  {
908  NeighborTuple const &nb_tuple = *it;
909  NS_LOG_DEBUG ("Looking at neighbor tuple: " << nb_tuple);
910  if (nb_tuple.status == NeighborTuple::STATUS_SYM)
911  {
912  bool nb_main_addr = false;
913  const LinkTuple *lt = NULL;
914  const LinkSet &linkSet = m_state.GetLinks ();
915  for (LinkSet::const_iterator it2 = linkSet.begin ();
916  it2 != linkSet.end (); it2++)
917  {
918  LinkTuple const &link_tuple = *it2;
919  NS_LOG_DEBUG ("Looking at link tuple: " << link_tuple
920  << (link_tuple.time >= Simulator::Now () ? "" : " (expired)"));
921  if ((GetMainAddress (link_tuple.neighborIfaceAddr) == nb_tuple.neighborMainAddr)
922  && link_tuple.time >= Simulator::Now ())
923  {
924  NS_LOG_LOGIC ("Link tuple matches neighbor " << nb_tuple.neighborMainAddr
925  << " => adding routing table entry to neighbor");
926  lt = &link_tuple;
927  AddEntry (link_tuple.neighborIfaceAddr,
928  link_tuple.neighborIfaceAddr,
929  link_tuple.localIfaceAddr,
930  1);
931  if (link_tuple.neighborIfaceAddr == nb_tuple.neighborMainAddr)
932  {
933  nb_main_addr = true;
934  }
935  }
936  else
937  {
938  NS_LOG_LOGIC ("Link tuple: linkMainAddress= " << GetMainAddress (link_tuple.neighborIfaceAddr)
939  << "; neighborMainAddr = " << nb_tuple.neighborMainAddr
940  << "; expired=" << int (link_tuple.time < Simulator::Now ())
941  << " => IGNORE");
942  }
943  }
944 
945  // If, in the above, no R_dest_addr is equal to the main
946  // address of the neighbor, then another new routing entry
947  // with MUST be added, with:
948  // R_dest_addr = main address of the neighbor;
949  // R_next_addr = L_neighbor_iface_addr of one of the
950  // associated link tuple with L_time >= current time;
951  // R_dist = 1;
952  // R_iface_addr = L_local_iface_addr of the
953  // associated link tuple.
954  if (!nb_main_addr && lt != NULL)
955  {
956  NS_LOG_LOGIC ("no R_dest_addr is equal to the main address of the neighbor "
957  "=> adding additional routing entry");
958  AddEntry (nb_tuple.neighborMainAddr,
959  lt->neighborIfaceAddr,
960  lt->localIfaceAddr,
961  1);
962  }
963  }
964  }
965 
966  // 3. for each node in N2, i.e., a 2-hop neighbor which is not a
967  // neighbor node or the node itself, and such that there exist at
968  // least one entry in the 2-hop neighbor set where
969  // N_neighbor_main_addr correspond to a neighbor node with
970  // willingness different of WILL_NEVER,
971  const TwoHopNeighborSet &twoHopNeighbors = m_state.GetTwoHopNeighbors ();
972  for (TwoHopNeighborSet::const_iterator it = twoHopNeighbors.begin ();
973  it != twoHopNeighbors.end (); it++)
974  {
975  TwoHopNeighborTuple const &nb2hop_tuple = *it;
976 
977  NS_LOG_LOGIC ("Looking at two-hop neighbor tuple: " << nb2hop_tuple);
978 
979  // a 2-hop neighbor which is not a neighbor node or the node itself
981  {
982  NS_LOG_LOGIC ("Two-hop neighbor tuple is also neighbor; skipped.");
983  continue;
984  }
985 
986  if (nb2hop_tuple.twoHopNeighborAddr == m_mainAddress)
987  {
988  NS_LOG_LOGIC ("Two-hop neighbor is self; skipped.");
989  continue;
990  }
991 
992  // ...and such that there exist at least one entry in the 2-hop
993  // neighbor set where N_neighbor_main_addr correspond to a
994  // neighbor node with willingness different of WILL_NEVER...
995  bool nb2hopOk = false;
996  for (NeighborSet::const_iterator neighbor = neighborSet.begin ();
997  neighbor != neighborSet.end (); neighbor++)
998  {
999  if (neighbor->neighborMainAddr == nb2hop_tuple.neighborMainAddr
1000  && neighbor->willingness != OLSR_WILL_NEVER)
1001  {
1002  nb2hopOk = true;
1003  break;
1004  }
1005  }
1006  if (!nb2hopOk)
1007  {
1008  NS_LOG_LOGIC ("Two-hop neighbor tuple skipped: 2-hop neighbor "
1009  << nb2hop_tuple.twoHopNeighborAddr
1010  << " is attached to neighbor " << nb2hop_tuple.neighborMainAddr
1011  << ", which was not found in the Neighbor Set.");
1012  continue;
1013  }
1014 
1015  // one selects one 2-hop tuple and creates one entry in the routing table with:
1016  // R_dest_addr = the main address of the 2-hop neighbor;
1017  // R_next_addr = the R_next_addr of the entry in the
1018  // routing table with:
1019  // R_dest_addr == N_neighbor_main_addr
1020  // of the 2-hop tuple;
1021  // R_dist = 2;
1022  // R_iface_addr = the R_iface_addr of the entry in the
1023  // routing table with:
1024  // R_dest_addr == N_neighbor_main_addr
1025  // of the 2-hop tuple;
1026  RoutingTableEntry entry;
1027  bool foundEntry = Lookup (nb2hop_tuple.neighborMainAddr, entry);
1028  if (foundEntry)
1029  {
1030  NS_LOG_LOGIC ("Adding routing entry for two-hop neighbor.");
1031  AddEntry (nb2hop_tuple.twoHopNeighborAddr,
1032  entry.nextAddr,
1033  entry.interface,
1034  2);
1035  }
1036  else
1037  {
1038  NS_LOG_LOGIC ("NOT adding routing entry for two-hop neighbor ("
1039  << nb2hop_tuple.twoHopNeighborAddr
1040  << " not found in the routing table)");
1041  }
1042  }
1043 
1044  for (uint32_t h = 2;; h++)
1045  {
1046  bool added = false;
1047 
1048  // 3.1. For each topology entry in the topology table, if its
1049  // T_dest_addr does not correspond to R_dest_addr of any
1050  // route entry in the routing table AND its T_last_addr
1051  // corresponds to R_dest_addr of a route entry whose R_dist
1052  // is equal to h, then a new route entry MUST be recorded in
1053  // the routing table (if it does not already exist)
1054  const TopologySet &topology = m_state.GetTopologySet ();
1055  for (TopologySet::const_iterator it = topology.begin ();
1056  it != topology.end (); it++)
1057  {
1058  const TopologyTuple &topology_tuple = *it;
1059  NS_LOG_LOGIC ("Looking at topology tuple: " << topology_tuple);
1060 
1061  RoutingTableEntry destAddrEntry, lastAddrEntry;
1062  bool have_destAddrEntry = Lookup (topology_tuple.destAddr, destAddrEntry);
1063  bool have_lastAddrEntry = Lookup (topology_tuple.lastAddr, lastAddrEntry);
1064  if (!have_destAddrEntry && have_lastAddrEntry && lastAddrEntry.distance == h)
1065  {
1066  NS_LOG_LOGIC ("Adding routing table entry based on the topology tuple.");
1067  // then a new route entry MUST be recorded in
1068  // the routing table (if it does not already exist) where:
1069  // R_dest_addr = T_dest_addr;
1070  // R_next_addr = R_next_addr of the recorded
1071  // route entry where:
1072  // R_dest_addr == T_last_addr
1073  // R_dist = h+1; and
1074  // R_iface_addr = R_iface_addr of the recorded
1075  // route entry where:
1076  // R_dest_addr == T_last_addr.
1077  AddEntry (topology_tuple.destAddr,
1078  lastAddrEntry.nextAddr,
1079  lastAddrEntry.interface,
1080  h + 1);
1081  added = true;
1082  }
1083  else
1084  {
1085  NS_LOG_LOGIC ("NOT adding routing table entry based on the topology tuple: "
1086  "have_destAddrEntry=" << have_destAddrEntry
1087  << " have_lastAddrEntry=" << have_lastAddrEntry
1088  << " lastAddrEntry.distance=" << (int) lastAddrEntry.distance
1089  << " (h=" << h << ")");
1090  }
1091  }
1092 
1093  if (!added)
1094  break;
1095  }
1096 
1097  // 4. For each entry in the multiple interface association base
1098  // where there exists a routing entry such that:
1099  // R_dest_addr == I_main_addr (of the multiple interface association entry)
1100  // AND there is no routing entry such that:
1101  // R_dest_addr == I_iface_addr
1102  const IfaceAssocSet &ifaceAssocSet = m_state.GetIfaceAssocSet ();
1103  for (IfaceAssocSet::const_iterator it = ifaceAssocSet.begin ();
1104  it != ifaceAssocSet.end (); it++)
1105  {
1106  IfaceAssocTuple const &tuple = *it;
1107  RoutingTableEntry entry1, entry2;
1108  bool have_entry1 = Lookup (tuple.mainAddr, entry1);
1109  bool have_entry2 = Lookup (tuple.ifaceAddr, entry2);
1110  if (have_entry1 && !have_entry2)
1111  {
1112  // then a route entry is created in the routing table with:
1113  // R_dest_addr = I_iface_addr (of the multiple interface
1114  // association entry)
1115  // R_next_addr = R_next_addr (of the recorded route entry)
1116  // R_dist = R_dist (of the recorded route entry)
1117  // R_iface_addr = R_iface_addr (of the recorded route entry).
1118  AddEntry (tuple.ifaceAddr,
1119  entry1.nextAddr,
1120  entry1.interface,
1121  entry1.distance);
1122  }
1123  }
1124 
1125  // 5. For each tuple in the association set,
1126  // If there is no entry in the routing table with:
1127  // R_dest_addr == A_network_addr/A_netmask
1128  // and if the announced network is not announced by the node itself,
1129  // then a new routing entry is created.
1130  const AssociationSet &associationSet = m_state.GetAssociationSet ();
1131 
1132  // Clear HNA routing table
1133  for (uint32_t i = 0; i < m_hnaRoutingTable->GetNRoutes (); i++)
1134  {
1135  m_hnaRoutingTable->RemoveRoute (0);
1136  }
1137 
1138  for (AssociationSet::const_iterator it = associationSet.begin ();
1139  it != associationSet.end (); it++)
1140  {
1141  AssociationTuple const &tuple = *it;
1142 
1143  // Test if HNA associations received from other gateways
1144  // are also announced by this node. In such a case, no route
1145  // is created for this association tuple (go to the next one).
1146  bool goToNextAssociationTuple = false;
1147  const Associations &localHnaAssociations = m_state.GetAssociations ();
1148  NS_LOG_DEBUG ("Nb local associations: " << localHnaAssociations.size ());
1149  for (Associations::const_iterator assocIterator = localHnaAssociations.begin ();
1150  assocIterator != localHnaAssociations.end (); assocIterator++)
1151  {
1152  Association const &localHnaAssoc = *assocIterator;
1153  if (localHnaAssoc.networkAddr == tuple.networkAddr && localHnaAssoc.netmask == tuple.netmask)
1154  {
1155  NS_LOG_DEBUG ("HNA association received from another GW is part of local HNA associations: no route added for network "
1156  << tuple.networkAddr << "/" << tuple.netmask);
1157  goToNextAssociationTuple = true;
1158  }
1159  }
1160  if (goToNextAssociationTuple)
1161  {
1162  continue;
1163  }
1164 
1165  RoutingTableEntry gatewayEntry;
1166 
1167  bool gatewayEntryExists = Lookup (tuple.gatewayAddr, gatewayEntry);
1168  bool addRoute = false;
1169 
1170  uint32_t routeIndex = 0;
1171 
1172  for (routeIndex = 0; routeIndex < m_hnaRoutingTable->GetNRoutes (); routeIndex++)
1173  {
1174  Ipv4RoutingTableEntry route = m_hnaRoutingTable->GetRoute (routeIndex);
1175  if (route.GetDestNetwork () == tuple.networkAddr &&
1176  route.GetDestNetworkMask () == tuple.netmask)
1177  {
1178  break;
1179  }
1180  }
1181 
1182  if (routeIndex == m_hnaRoutingTable->GetNRoutes ())
1183  {
1184  addRoute = true;
1185  }
1186  else if(gatewayEntryExists && m_hnaRoutingTable->GetMetric (routeIndex) > gatewayEntry.distance)
1187  {
1188  m_hnaRoutingTable->RemoveRoute (routeIndex);
1189  addRoute = true;
1190  }
1191 
1192  if(addRoute && gatewayEntryExists)
1193  {
1194  m_hnaRoutingTable->AddNetworkRouteTo (tuple.networkAddr,
1195  tuple.netmask,
1196  gatewayEntry.nextAddr,
1197  gatewayEntry.interface,
1198  gatewayEntry.distance);
1199 
1200  }
1201  }
1202 
1203  NS_LOG_DEBUG ("Node " << m_mainAddress << ": RoutingTableComputation end.");
1205 }
1206 
1207 
1218 void
1220  const Ipv4Address &receiverIface,
1221  const Ipv4Address &senderIface)
1222 {
1223  NS_LOG_FUNCTION (msg << receiverIface << senderIface);
1224 
1225  const olsr::MessageHeader::Hello &hello = msg.GetHello ();
1226 
1227  LinkSensing (msg, hello, receiverIface, senderIface);
1228 
1229 #ifdef NS3_LOG_ENABLE
1230  {
1231  const LinkSet &links = m_state.GetLinks ();
1232  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
1233  << "s ** BEGIN dump Link Set for OLSR Node " << m_mainAddress);
1234  for (LinkSet::const_iterator link = links.begin (); link != links.end (); link++)
1235  {
1236  NS_LOG_DEBUG (*link);
1237  }
1238  NS_LOG_DEBUG ("** END dump Link Set for OLSR Node " << m_mainAddress);
1239 
1240  const NeighborSet &neighbors = m_state.GetNeighbors ();
1241  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
1242  << "s ** BEGIN dump Neighbor Set for OLSR Node " << m_mainAddress);
1243  for (NeighborSet::const_iterator neighbor = neighbors.begin (); neighbor != neighbors.end (); neighbor++)
1244  {
1245  NS_LOG_DEBUG (*neighbor);
1246  }
1247  NS_LOG_DEBUG ("** END dump Neighbor Set for OLSR Node " << m_mainAddress);
1248  }
1249 #endif // NS3_LOG_ENABLE
1250 
1251  PopulateNeighborSet (msg, hello);
1252  PopulateTwoHopNeighborSet (msg, hello);
1253 
1254 #ifdef NS3_LOG_ENABLE
1255  {
1256  const TwoHopNeighborSet &twoHopNeighbors = m_state.GetTwoHopNeighbors ();
1257  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
1258  << "s ** BEGIN dump TwoHopNeighbor Set for OLSR Node " << m_mainAddress);
1259  for (TwoHopNeighborSet::const_iterator tuple = twoHopNeighbors.begin ();
1260  tuple != twoHopNeighbors.end (); tuple++)
1261  {
1262  NS_LOG_DEBUG (*tuple);
1263  }
1264  NS_LOG_DEBUG ("** END dump TwoHopNeighbor Set for OLSR Node " << m_mainAddress);
1265  }
1266 #endif // NS3_LOG_ENABLE
1267 
1268  MprComputation ();
1269  PopulateMprSelectorSet (msg, hello);
1270 }
1271 
1281 void
1283  const Ipv4Address &senderIface)
1284 {
1285  const olsr::MessageHeader::Tc &tc = msg.GetTc ();
1286  Time now = Simulator::Now ();
1287 
1288  // 1. If the sender interface of this message is not in the symmetric
1289  // 1-hop neighborhood of this node, the message MUST be discarded.
1290  const LinkTuple *link_tuple = m_state.FindSymLinkTuple (senderIface, now);
1291  if (link_tuple == NULL)
1292  return;
1293 
1294  // 2. If there exist some tuple in the topology set where:
1295  // T_last_addr == originator address AND
1296  // T_seq > ANSN,
1297  // then further processing of this TC message MUST NOT be
1298  // performed.
1299  const TopologyTuple *topologyTuple =
1301  if (topologyTuple != NULL)
1302  return;
1303 
1304  // 3. All tuples in the topology set where:
1305  // T_last_addr == originator address AND
1306  // T_seq < ANSN
1307  // MUST be removed from the topology set.
1309 
1310  // 4. For each of the advertised neighbor main address received in
1311  // the TC message:
1312  for (std::vector<Ipv4Address>::const_iterator i = tc.neighborAddresses.begin ();
1313  i != tc.neighborAddresses.end (); i++)
1314  {
1315  const Ipv4Address &addr = *i;
1316  // 4.1. If there exist some tuple in the topology set where:
1317  // T_dest_addr == advertised neighbor main address, AND
1318  // T_last_addr == originator address,
1319  // then the holding time of that tuple MUST be set to:
1320  // T_time = current time + validity time.
1321  TopologyTuple *topologyTuple =
1323 
1324  if (topologyTuple != NULL)
1325  {
1326  topologyTuple->expirationTime = now + msg.GetVTime ();
1327  }
1328  else
1329  {
1330  // 4.2. Otherwise, a new tuple MUST be recorded in the topology
1331  // set where:
1332  // T_dest_addr = advertised neighbor main address,
1333  // T_last_addr = originator address,
1334  // T_seq = ANSN,
1335  // T_time = current time + validity time.
1336  TopologyTuple topologyTuple;;
1337  topologyTuple.destAddr = addr;
1338  topologyTuple.lastAddr = msg.GetOriginatorAddress ();
1339  topologyTuple.sequenceNumber = tc.ansn;
1340  topologyTuple.expirationTime = now + msg.GetVTime ();
1341  AddTopologyTuple (topologyTuple);
1342 
1343  // Schedules topology tuple deletion
1346  this,
1347  topologyTuple.destAddr,
1348  topologyTuple.lastAddr));
1349  }
1350  }
1351 
1352 #ifdef NS3_LOG_ENABLE
1353  {
1354  const TopologySet &topology = m_state.GetTopologySet ();
1355  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
1356  << "s ** BEGIN dump TopologySet for OLSR Node " << m_mainAddress);
1357  for (TopologySet::const_iterator tuple = topology.begin ();
1358  tuple != topology.end (); tuple++)
1359  {
1360  NS_LOG_DEBUG (*tuple);
1361  }
1362  NS_LOG_DEBUG ("** END dump TopologySet Set for OLSR Node " << m_mainAddress);
1363  }
1364 #endif // NS3_LOG_ENABLE
1365 }
1366 
1376 void
1378  const Ipv4Address &senderIface)
1379 {
1380  const olsr::MessageHeader::Mid &mid = msg.GetMid ();
1381  Time now = Simulator::Now ();
1382 
1383  NS_LOG_DEBUG ("Node " << m_mainAddress << " ProcessMid from " << senderIface);
1384  // 1. If the sender interface of this message is not in the symmetric
1385  // 1-hop neighborhood of this node, the message MUST be discarded.
1386  const LinkTuple *linkTuple = m_state.FindSymLinkTuple (senderIface, now);
1387  if (linkTuple == NULL)
1388  {
1389  NS_LOG_LOGIC ("Node " << m_mainAddress <<
1390  ": the sender interface of this message is not in the "
1391  "symmetric 1-hop neighborhood of this node,"
1392  " the message MUST be discarded.");
1393  return;
1394  }
1395 
1396  // 2. For each interface address listed in the MID message
1397  for (std::vector<Ipv4Address>::const_iterator i = mid.interfaceAddresses.begin ();
1398  i != mid.interfaceAddresses.end (); i++)
1399  {
1400  bool updated = false;
1402  for (IfaceAssocSet::iterator tuple = ifaceAssoc.begin ();
1403  tuple != ifaceAssoc.end (); tuple++)
1404  {
1405  if (tuple->ifaceAddr == *i
1406  && tuple->mainAddr == msg.GetOriginatorAddress ())
1407  {
1408  NS_LOG_LOGIC ("IfaceAssoc updated: " << *tuple);
1409  tuple->time = now + msg.GetVTime ();
1410  updated = true;
1411  }
1412  }
1413  if (!updated)
1414  {
1415  IfaceAssocTuple tuple;
1416  tuple.ifaceAddr = *i;
1417  tuple.mainAddr = msg.GetOriginatorAddress ();
1418  tuple.time = now + msg.GetVTime ();
1419  AddIfaceAssocTuple (tuple);
1420  NS_LOG_LOGIC ("New IfaceAssoc added: " << tuple);
1421  // Schedules iface association tuple deletion
1422  Simulator::Schedule (DELAY (tuple.time),
1424  }
1425  }
1426 
1427  // 3. (not part of the RFC) iterate over all NeighborTuple's and
1428  // TwoHopNeighborTuples, update the neighbor addresses taking into account
1429  // the new MID information.
1430  NeighborSet &neighbors = m_state.GetNeighbors ();
1431  for (NeighborSet::iterator neighbor = neighbors.begin (); neighbor != neighbors.end (); neighbor++)
1432  {
1433  neighbor->neighborMainAddr = GetMainAddress (neighbor->neighborMainAddr);
1434  }
1435 
1436  TwoHopNeighborSet &twoHopNeighbors = m_state.GetTwoHopNeighbors ();
1437  for (TwoHopNeighborSet::iterator twoHopNeighbor = twoHopNeighbors.begin ();
1438  twoHopNeighbor != twoHopNeighbors.end (); twoHopNeighbor++)
1439  {
1440  twoHopNeighbor->neighborMainAddr = GetMainAddress (twoHopNeighbor->neighborMainAddr);
1441  twoHopNeighbor->twoHopNeighborAddr = GetMainAddress (twoHopNeighbor->twoHopNeighborAddr);
1442  }
1443  NS_LOG_DEBUG ("Node " << m_mainAddress << " ProcessMid from " << senderIface << " -> END.");
1444 }
1445 
1455 void
1457  const Ipv4Address &senderIface)
1458 {
1459 
1460  const olsr::MessageHeader::Hna &hna = msg.GetHna ();
1461  Time now = Simulator::Now ();
1462 
1463  // 1. If the sender interface of this message is not in the symmetric
1464  // 1-hop neighborhood of this node, the message MUST be discarded.
1465  const LinkTuple *link_tuple = m_state.FindSymLinkTuple (senderIface, now);
1466  if (link_tuple == NULL)
1467  return;
1468 
1469  // 2. Otherwise, for each (network address, netmask) pair in the
1470  // message:
1471 
1472  for (std::vector<olsr::MessageHeader::Hna::Association>::const_iterator it = hna.associations.begin ();
1473  it != hna.associations.end (); it++)
1474  {
1475  AssociationTuple *tuple = m_state.FindAssociationTuple (msg.GetOriginatorAddress (),it->address,it->mask);
1476 
1477  // 2.1 if an entry in the association set already exists, where:
1478  // A_gateway_addr == originator address
1479  // A_network_addr == network address
1480  // A_netmask == netmask
1481  // then the holding time for that tuple MUST be set to:
1482  // A_time = current time + validity time
1483  if(tuple != NULL)
1484  {
1485  tuple->expirationTime = now + msg.GetVTime ();
1486  }
1487 
1488  // 2.2 otherwise, a new tuple MUST be recorded with:
1489  // A_gateway_addr = originator address
1490  // A_network_addr = network address
1491  // A_netmask = netmask
1492  // A_time = current time + validity time
1493  else
1494  {
1495  AssociationTuple assocTuple = {
1496  msg.GetOriginatorAddress (),
1497  it->address,
1498  it->mask,
1499  now + msg.GetVTime ()
1500  };
1501  AddAssociationTuple (assocTuple);
1502 
1503  //Schedule Association Tuple deletion
1506  assocTuple.gatewayAddr,assocTuple.networkAddr,assocTuple.netmask);
1507  }
1508 
1509  }
1510 }
1511 
1523 void
1525  DuplicateTuple *duplicated,
1526  const Ipv4Address &localIface,
1527  const Ipv4Address &senderAddress)
1528 {
1529  Time now = Simulator::Now ();
1530 
1531  // If the sender interface address is not in the symmetric
1532  // 1-hop neighborhood the message must not be forwarded
1533  const LinkTuple *linkTuple = m_state.FindSymLinkTuple (senderAddress, now);
1534  if (linkTuple == NULL)
1535  return;
1536 
1537  // If the message has already been considered for forwarding,
1538  // it must not be retransmitted again
1539  if (duplicated != NULL && duplicated->retransmitted)
1540  {
1541  NS_LOG_LOGIC (Simulator::Now () << "Node " << m_mainAddress << " does not forward a message received"
1542  " from " << olsrMessage.GetOriginatorAddress () << " because it is duplicated");
1543  return;
1544  }
1545 
1546  // If the sender interface address is an interface address
1547  // of a MPR selector of this node and ttl is greater than 1,
1548  // the message must be retransmitted
1549  bool retransmitted = false;
1550  if (olsrMessage.GetTimeToLive () > 1)
1551  {
1552  const MprSelectorTuple *mprselTuple =
1553  m_state.FindMprSelectorTuple (GetMainAddress (senderAddress));
1554  if (mprselTuple != NULL)
1555  {
1556  olsrMessage.SetTimeToLive (olsrMessage.GetTimeToLive () - 1);
1557  olsrMessage.SetHopCount (olsrMessage.GetHopCount () + 1);
1558  // We have to introduce a random delay to avoid
1559  // synchronization with neighbors.
1560  QueueMessage (olsrMessage, JITTER);
1561  retransmitted = true;
1562  }
1563  }
1564 
1565  // Update duplicate tuple...
1566  if (duplicated != NULL)
1567  {
1568  duplicated->expirationTime = now + OLSR_DUP_HOLD_TIME;
1569  duplicated->retransmitted = retransmitted;
1570  duplicated->ifaceList.push_back (localIface);
1571  }
1572  // ...or create a new one
1573  else
1574  {
1575  DuplicateTuple newDup;
1576  newDup.address = olsrMessage.GetOriginatorAddress ();
1577  newDup.sequenceNumber = olsrMessage.GetMessageSequenceNumber ();
1578  newDup.expirationTime = now + OLSR_DUP_HOLD_TIME;
1579  newDup.retransmitted = retransmitted;
1580  newDup.ifaceList.push_back (localIface);
1581  AddDuplicateTuple (newDup);
1582  // Schedule dup tuple deletion
1583  Simulator::Schedule (OLSR_DUP_HOLD_TIME,
1585  newDup.address, newDup.sequenceNumber);
1586  }
1587 }
1588 
1598 void
1600 {
1601  m_queuedMessages.push_back (message);
1602  if (not m_queuedMessagesTimer.IsRunning ())
1603  {
1606  }
1607 }
1608 
1609 void
1611  const MessageList &containedMessages)
1612 {
1613  NS_LOG_DEBUG ("OLSR node " << m_mainAddress << " sending a OLSR packet");
1614 
1615  // Add a header
1616  olsr::PacketHeader header;
1617  header.SetPacketLength (header.GetSerializedSize () + packet->GetSize ());
1619  packet->AddHeader (header);
1620 
1621  // Trace it
1622  m_txPacketTrace (header, containedMessages);
1623 
1624  // Send it
1625  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator i =
1626  m_socketAddresses.begin (); i != m_socketAddresses.end (); i++)
1627  {
1628  Ipv4Address bcast = i->second.GetLocal ().GetSubnetDirectedBroadcast (i->second.GetMask ());
1629  i->first->SendTo (packet, 0, InetSocketAddress (bcast, OLSR_PORT_NUMBER));
1630  }
1631 }
1632 
1640 void
1642 {
1643  Ptr<Packet> packet = Create<Packet> ();
1644  int numMessages = 0;
1645 
1646  NS_LOG_DEBUG ("Olsr node " << m_mainAddress << ": SendQueuedMessages");
1647 
1648  MessageList msglist;
1649 
1650  for (std::vector<olsr::MessageHeader>::const_iterator message = m_queuedMessages.begin ();
1651  message != m_queuedMessages.end ();
1652  message++)
1653  {
1654  Ptr<Packet> p = Create<Packet> ();
1655  p->AddHeader (*message);
1656  packet->AddAtEnd (p);
1657  msglist.push_back (*message);
1658  if (++numMessages == OLSR_MAX_MSGS)
1659  {
1660  SendPacket (packet, msglist);
1661  msglist.clear ();
1662  // Reset variables for next packet
1663  numMessages = 0;
1664  packet = Create<Packet> ();
1665  }
1666  }
1667 
1668  if (packet->GetSize ())
1669  {
1670  SendPacket (packet, msglist);
1671  }
1672 
1673  m_queuedMessages.clear ();
1674 }
1675 
1679 void
1681 {
1682  NS_LOG_FUNCTION (this);
1683 
1684  olsr::MessageHeader msg;
1685  Time now = Simulator::Now ();
1686 
1689  msg.SetTimeToLive (1);
1690  msg.SetHopCount (0);
1692  olsr::MessageHeader::Hello &hello = msg.GetHello ();
1693 
1694  hello.SetHTime (m_helloInterval);
1695  hello.willingness = m_willingness;
1696 
1697  std::vector<olsr::MessageHeader::Hello::LinkMessage>
1698  &linkMessages = hello.linkMessages;
1699 
1700  const LinkSet &links = m_state.GetLinks ();
1701  for (LinkSet::const_iterator link_tuple = links.begin ();
1702  link_tuple != links.end (); link_tuple++)
1703  {
1704  if (!(GetMainAddress (link_tuple->localIfaceAddr) == m_mainAddress
1705  && link_tuple->time >= now))
1706  {
1707  continue;
1708  }
1709 
1710  uint8_t link_type, nb_type = 0xff;
1711 
1712  // Establishes link type
1713  if (link_tuple->symTime >= now)
1714  {
1715  link_type = OLSR_SYM_LINK;
1716  }
1717  else if (link_tuple->asymTime >= now)
1718  {
1719  link_type = OLSR_ASYM_LINK;
1720  }
1721  else
1722  {
1723  link_type = OLSR_LOST_LINK;
1724  }
1725  // Establishes neighbor type.
1726  if (m_state.FindMprAddress (GetMainAddress (link_tuple->neighborIfaceAddr)))
1727  {
1728  nb_type = OLSR_MPR_NEIGH;
1729  NS_LOG_DEBUG ("I consider neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr)
1730  << " to be MPR_NEIGH.");
1731  }
1732  else
1733  {
1734  bool ok = false;
1735  for (NeighborSet::const_iterator nb_tuple = m_state.GetNeighbors ().begin ();
1736  nb_tuple != m_state.GetNeighbors ().end ();
1737  nb_tuple++)
1738  {
1739  if (nb_tuple->neighborMainAddr == GetMainAddress (link_tuple->neighborIfaceAddr))
1740  {
1741  if (nb_tuple->status == NeighborTuple::STATUS_SYM)
1742  {
1743  NS_LOG_DEBUG ("I consider neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr)
1744  << " to be SYM_NEIGH.");
1745  nb_type = OLSR_SYM_NEIGH;
1746  }
1747  else if (nb_tuple->status == NeighborTuple::STATUS_NOT_SYM)
1748  {
1749  nb_type = OLSR_NOT_NEIGH;
1750  NS_LOG_DEBUG ("I consider neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr)
1751  << " to be NOT_NEIGH.");
1752  }
1753  else
1754  {
1755  NS_FATAL_ERROR ("There is a neighbor tuple with an unknown status!\n");
1756  }
1757  ok = true;
1758  break;
1759  }
1760  }
1761  if (!ok)
1762  {
1763  NS_LOG_WARN ("I don't know the neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr) << "!!!");
1764  continue;
1765  }
1766  }
1767 
1769  linkMessage.linkCode = (link_type & 0x03) | ((nb_type << 2) & 0x0f);
1770  linkMessage.neighborInterfaceAddresses.push_back
1771  (link_tuple->neighborIfaceAddr);
1772 
1773  std::vector<Ipv4Address> interfaces =
1774  m_state.FindNeighborInterfaces (link_tuple->neighborIfaceAddr);
1775 
1776  linkMessage.neighborInterfaceAddresses.insert
1777  (linkMessage.neighborInterfaceAddresses.end (),
1778  interfaces.begin (), interfaces.end ());
1779 
1780  linkMessages.push_back (linkMessage);
1781  }
1782  NS_LOG_DEBUG ("OLSR HELLO message size: " << int (msg.GetSerializedSize ())
1783  << " (with " << int (linkMessages.size ()) << " link messages)");
1784  QueueMessage (msg, JITTER);
1785 }
1786 
1790 void
1792 {
1793  NS_LOG_FUNCTION (this);
1794 
1795  olsr::MessageHeader msg;
1796 
1799  msg.SetTimeToLive (255);
1800  msg.SetHopCount (0);
1802 
1803  olsr::MessageHeader::Tc &tc = msg.GetTc ();
1804  tc.ansn = m_ansn;
1805 
1806  for (MprSelectorSet::const_iterator mprsel_tuple = m_state.GetMprSelectors ().begin ();
1807  mprsel_tuple != m_state.GetMprSelectors ().end (); mprsel_tuple++)
1808  {
1809  tc.neighborAddresses.push_back (mprsel_tuple->mainAddr);
1810  }
1811  QueueMessage (msg, JITTER);
1812 }
1813 
1817 void
1819 {
1820  olsr::MessageHeader msg;
1821  olsr::MessageHeader::Mid &mid = msg.GetMid ();
1822 
1823  // A node which has only a single interface address participating in
1824  // the MANET (i.e., running OLSR), MUST NOT generate any MID
1825  // message.
1826 
1827  // A node with several interfaces, where only one is participating
1828  // in the MANET and running OLSR (e.g., a node is connected to a
1829  // wired network as well as to a MANET) MUST NOT generate any MID
1830  // messages.
1831 
1832  // A node with several interfaces, where more than one is
1833  // participating in the MANET and running OLSR MUST generate MID
1834  // messages as specified.
1835 
1836  // [ Note: assuming here that all interfaces participate in the
1837  // MANET; later we may want to make this configurable. ]
1838 
1839  Ipv4Address loopback ("127.0.0.1");
1840  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
1841  {
1842  Ipv4Address addr = m_ipv4->GetAddress (i, 0).GetLocal ();
1843  if (addr != m_mainAddress && addr != loopback && m_interfaceExclusions.find (i) == m_interfaceExclusions.end ())
1844  mid.interfaceAddresses.push_back (addr);
1845  }
1846  if (mid.interfaceAddresses.size () == 0)
1847  return;
1848 
1851  msg.SetTimeToLive (255);
1852  msg.SetHopCount (0);
1854 
1855  QueueMessage (msg, JITTER);
1856 }
1857 
1861 void
1863 {
1864 
1865  olsr::MessageHeader msg;
1866 
1869  msg.SetTimeToLive (255);
1870  msg.SetHopCount (0);
1872  olsr::MessageHeader::Hna &hna = msg.GetHna ();
1873 
1874  std::vector<olsr::MessageHeader::Hna::Association> &associations = hna.associations;
1875 
1876  // Add all local HNA associations to the HNA message
1877  const Associations &localHnaAssociations = m_state.GetAssociations ();
1878  for (Associations::const_iterator it = localHnaAssociations.begin ();
1879  it != localHnaAssociations.end (); it++)
1880  {
1881  olsr::MessageHeader::Hna::Association assoc = { it->networkAddr, it->netmask};
1882  associations.push_back (assoc);
1883  }
1884  // If there is no HNA associations to send, return without queuing the message
1885  if (associations.size () == 0)
1886  {
1887  return;
1888  }
1889 
1890  // Else, queue the message to be sent later on
1891  QueueMessage (msg, JITTER);
1892 }
1893 
1899 void
1901 {
1902  // Check if the (networkAddr, netmask) tuple already exist
1903  // in the list of local HNA associations
1904  const Associations &localHnaAssociations = m_state.GetAssociations ();
1905  for (Associations::const_iterator assocIterator = localHnaAssociations.begin ();
1906  assocIterator != localHnaAssociations.end (); assocIterator++)
1907  {
1908  Association const &localHnaAssoc = *assocIterator;
1909  if (localHnaAssoc.networkAddr == networkAddr && localHnaAssoc.netmask == netmask)
1910  {
1911  NS_LOG_INFO ("HNA association for network " << networkAddr << "/" << netmask << " already exists.");
1912  return;
1913  }
1914  }
1915  // If the tuple does not already exist, add it to the list of local HNA associations.
1916  NS_LOG_INFO ("Adding HNA association for network " << networkAddr << "/" << netmask << ".");
1917  m_state.InsertAssociation ( (Association) { networkAddr, netmask} );
1918 }
1919 
1925 void
1927 {
1928  NS_LOG_INFO ("Removing HNA association for network " << networkAddr << "/" << netmask << ".");
1929  m_state.EraseAssociation ( (Association) { networkAddr, netmask} );
1930 }
1931 
1942 void
1944 {
1945  // If a routing table has already been associated, remove
1946  // corresponding entries from the list of local HNA associations
1947  if (m_routingTableAssociation != 0)
1948  {
1949  NS_LOG_INFO ("Removing HNA entries coming from the old routing table association.");
1950  for (uint32_t i = 0; i < m_routingTableAssociation->GetNRoutes (); i++)
1951  {
1952  Ipv4RoutingTableEntry route = m_routingTableAssociation->GetRoute (i);
1953  // If the outgoing interface for this route is a non-olsr interface
1954  if (UsesNonOlsrOutgoingInterface (route))
1955  {
1956  // remove the corresponding entry
1958  }
1959  }
1960  }
1961 
1962  // Sets the routingTableAssociation to its new value
1963  m_routingTableAssociation = routingTable;
1964 
1965  // Iterate over entries of the associated routing table and
1966  // add the routes using non-olsr outgoing interfaces to the list
1967  // of local HNA associations
1968  NS_LOG_DEBUG ("Nb local associations before adding some entries from"
1969  " the associated routing table: " << m_state.GetAssociations ().size ());
1970  for (uint32_t i = 0; i < m_routingTableAssociation->GetNRoutes (); i++)
1971  {
1972  Ipv4RoutingTableEntry route = m_routingTableAssociation->GetRoute (i);
1973  Ipv4Address destNetworkAddress = route.GetDestNetwork ();
1974  Ipv4Mask destNetmask = route.GetDestNetworkMask ();
1975 
1976  // If the outgoing interface for this route is a non-olsr interface,
1977  if (UsesNonOlsrOutgoingInterface (route))
1978  {
1979  // Add this entry's network address and netmask to the list of local HNA entries
1980  AddHostNetworkAssociation (destNetworkAddress, destNetmask);
1981  }
1982  }
1983  NS_LOG_DEBUG ("Nb local associations after having added some entries from "
1984  "the associated routing table: " << m_state.GetAssociations ().size ());
1985 }
1986 
1992 bool
1994 {
1995  std::set<uint32_t>::const_iterator ci = m_interfaceExclusions.find (route.GetInterface ());
1996  // The outgoing interface is a non-OLSR interface if a match is found
1997  // before reaching the end of the list of excluded interfaces
1998  return ci != m_interfaceExclusions.end ();
1999 }
2000 
2004 void
2006  const olsr::MessageHeader::Hello &hello,
2007  const Ipv4Address &receiverIface,
2008  const Ipv4Address &senderIface)
2009 {
2010  Time now = Simulator::Now ();
2011  bool updated = false;
2012  bool created = false;
2013  NS_LOG_DEBUG ("@" << now.GetSeconds () << ": Olsr node " << m_mainAddress
2014  << ": LinkSensing(receiverIface=" << receiverIface
2015  << ", senderIface=" << senderIface << ") BEGIN");
2016 
2017  NS_ASSERT (msg.GetVTime () > Seconds (0));
2018  LinkTuple *link_tuple = m_state.FindLinkTuple (senderIface);
2019  if (link_tuple == NULL)
2020  {
2021  LinkTuple newLinkTuple;
2022  // We have to create a new tuple
2023  newLinkTuple.neighborIfaceAddr = senderIface;
2024  newLinkTuple.localIfaceAddr = receiverIface;
2025  newLinkTuple.symTime = now - Seconds (1);
2026  newLinkTuple.time = now + msg.GetVTime ();
2027  link_tuple = &m_state.InsertLinkTuple (newLinkTuple);
2028  created = true;
2029  NS_LOG_LOGIC ("Existing link tuple did not exist => creating new one");
2030  }
2031  else
2032  {
2033  NS_LOG_LOGIC ("Existing link tuple already exists => will update it");
2034  updated = true;
2035  }
2036 
2037  link_tuple->asymTime = now + msg.GetVTime ();
2038  for (std::vector<olsr::MessageHeader::Hello::LinkMessage>::const_iterator linkMessage =
2039  hello.linkMessages.begin ();
2040  linkMessage != hello.linkMessages.end ();
2041  linkMessage++)
2042  {
2043  int lt = linkMessage->linkCode & 0x03; // Link Type
2044  int nt = (linkMessage->linkCode >> 2) & 0x03; // Neighbor Type
2045 
2046 #ifdef NS3_LOG_ENABLE
2047  const char *linkTypeName;
2048  switch (lt)
2049  {
2050  case OLSR_UNSPEC_LINK: linkTypeName = "UNSPEC_LINK"; break;
2051  case OLSR_ASYM_LINK: linkTypeName = "ASYM_LINK"; break;
2052  case OLSR_SYM_LINK: linkTypeName = "SYM_LINK"; break;
2053  case OLSR_LOST_LINK: linkTypeName = "LOST_LINK"; break;
2054  /* no default, since lt must be in 0..3, covered above
2055  default: linkTypeName = "(invalid value!)";
2056  */
2057  }
2058 
2059  const char *neighborTypeName;
2060  switch (nt)
2061  {
2062  case OLSR_NOT_NEIGH: neighborTypeName = "NOT_NEIGH"; break;
2063  case OLSR_SYM_NEIGH: neighborTypeName = "SYM_NEIGH"; break;
2064  case OLSR_MPR_NEIGH: neighborTypeName = "MPR_NEIGH"; break;
2065  default: neighborTypeName = "(invalid value!)";
2066  }
2067 
2068  NS_LOG_DEBUG ("Looking at HELLO link messages with Link Type "
2069  << lt << " (" << linkTypeName
2070  << ") and Neighbor Type " << nt
2071  << " (" << neighborTypeName << ")");
2072 #endif // NS3_LOG_ENABLE
2073 
2074  // We must not process invalid advertised links
2075  if ((lt == OLSR_SYM_LINK && nt == OLSR_NOT_NEIGH) ||
2076  (nt != OLSR_SYM_NEIGH && nt != OLSR_MPR_NEIGH
2077  && nt != OLSR_NOT_NEIGH))
2078  {
2079  NS_LOG_LOGIC ("HELLO link code is invalid => IGNORING");
2080  continue;
2081  }
2082 
2083  for (std::vector<Ipv4Address>::const_iterator neighIfaceAddr =
2084  linkMessage->neighborInterfaceAddresses.begin ();
2085  neighIfaceAddr != linkMessage->neighborInterfaceAddresses.end ();
2086  neighIfaceAddr++)
2087  {
2088  NS_LOG_DEBUG (" -> Neighbor: " << *neighIfaceAddr);
2089  if (*neighIfaceAddr == receiverIface)
2090  {
2091  if (lt == OLSR_LOST_LINK)
2092  {
2093  NS_LOG_LOGIC ("link is LOST => expiring it");
2094  link_tuple->symTime = now - Seconds (1);
2095  updated = true;
2096  }
2097  else if (lt == OLSR_SYM_LINK || lt == OLSR_ASYM_LINK)
2098  {
2099  NS_LOG_DEBUG (*link_tuple << ": link is SYM or ASYM => should become SYM now"
2100  " (symTime being increased to " << now + msg.GetVTime ());
2101  link_tuple->symTime = now + msg.GetVTime ();
2102  link_tuple->time = link_tuple->symTime + OLSR_NEIGHB_HOLD_TIME;
2103  updated = true;
2104  }
2105  else
2106  {
2107  NS_FATAL_ERROR ("bad link type");
2108  }
2109  break;
2110  }
2111  else
2112  {
2113  NS_LOG_DEBUG (" \\-> *neighIfaceAddr (" << *neighIfaceAddr
2114  << " != receiverIface (" << receiverIface << ") => IGNORING!");
2115  }
2116  }
2117  NS_LOG_DEBUG ("Link tuple updated: " << int (updated));
2118  }
2119  link_tuple->time = std::max (link_tuple->time, link_tuple->asymTime);
2120 
2121  if (updated)
2122  {
2123  LinkTupleUpdated (*link_tuple, hello.willingness);
2124  }
2125 
2126  // Schedules link tuple deletion
2127  if (created)
2128  {
2129  LinkTupleAdded (*link_tuple, hello.willingness);
2130  m_events.Track (Simulator::Schedule (DELAY (std::min (link_tuple->time, link_tuple->symTime)),
2132  link_tuple->neighborIfaceAddr));
2133  }
2134  NS_LOG_DEBUG ("@" << now.GetSeconds () << ": Olsr node " << m_mainAddress
2135  << ": LinkSensing END");
2136 }
2137 
2141 void
2143  const olsr::MessageHeader::Hello &hello)
2144 {
2146  if (nb_tuple != NULL)
2147  {
2148  nb_tuple->willingness = hello.willingness;
2149  }
2150 }
2151 
2152 
2156 void
2158  const olsr::MessageHeader::Hello &hello)
2159 {
2160  Time now = Simulator::Now ();
2161 
2162  NS_LOG_DEBUG ("Olsr node " << m_mainAddress << ": PopulateTwoHopNeighborSet BEGIN");
2163 
2164  for (LinkSet::const_iterator link_tuple = m_state.GetLinks ().begin ();
2165  link_tuple != m_state.GetLinks ().end (); link_tuple++)
2166  {
2167  NS_LOG_LOGIC ("Looking at link tuple: " << *link_tuple);
2168  if (GetMainAddress (link_tuple->neighborIfaceAddr) != msg.GetOriginatorAddress ())
2169  {
2170  NS_LOG_LOGIC ("Link tuple ignored: "
2171  "GetMainAddress (link_tuple->neighborIfaceAddr) != msg.GetOriginatorAddress ()");
2172  NS_LOG_LOGIC ("(GetMainAddress(" << link_tuple->neighborIfaceAddr << "): "
2173  << GetMainAddress (link_tuple->neighborIfaceAddr)
2174  << "; msg.GetOriginatorAddress (): " << msg.GetOriginatorAddress ());
2175  continue;
2176  }
2177 
2178  if (link_tuple->symTime < now)
2179  {
2180  NS_LOG_LOGIC ("Link tuple ignored: expired.");
2181  continue;
2182  }
2183 
2184  typedef std::vector<olsr::MessageHeader::Hello::LinkMessage> LinkMessageVec;
2185  for (LinkMessageVec::const_iterator linkMessage = hello.linkMessages.begin ();
2186  linkMessage != hello.linkMessages.end (); linkMessage++)
2187  {
2188  int neighborType = (linkMessage->linkCode >> 2) & 0x3;
2189 #ifdef NS3_LOG_ENABLE
2190  const char *neighborTypeNames[3] = { "NOT_NEIGH", "SYM_NEIGH", "MPR_NEIGH" };
2191  const char *neighborTypeName = ((neighborType < 3) ?
2192  neighborTypeNames[neighborType]
2193  : "(invalid value)");
2194  NS_LOG_DEBUG ("Looking at Link Message from HELLO message: neighborType="
2195  << neighborType << " (" << neighborTypeName << ")");
2196 #endif // NS3_LOG_ENABLE
2197 
2198  for (std::vector<Ipv4Address>::const_iterator nb2hop_addr_iter =
2199  linkMessage->neighborInterfaceAddresses.begin ();
2200  nb2hop_addr_iter != linkMessage->neighborInterfaceAddresses.end ();
2201  nb2hop_addr_iter++)
2202  {
2203  Ipv4Address nb2hop_addr = GetMainAddress (*nb2hop_addr_iter);
2204  NS_LOG_DEBUG ("Looking at 2-hop neighbor address from HELLO message: "
2205  << *nb2hop_addr_iter
2206  << " (main address is " << nb2hop_addr << ")");
2207  if (neighborType == OLSR_SYM_NEIGH || neighborType == OLSR_MPR_NEIGH)
2208  {
2209  // If the main address of the 2-hop neighbor address == main address
2210  // of the receiving node, silently discard the 2-hop
2211  // neighbor address.
2212  if (nb2hop_addr == m_mainAddress)
2213  {
2214  NS_LOG_LOGIC ("Ignoring 2-hop neighbor (it is the node itself)");
2215  continue;
2216  }
2217 
2218  // Otherwise, a 2-hop tuple is created
2219  TwoHopNeighborTuple *nb2hop_tuple =
2221  NS_LOG_LOGIC ("Adding the 2-hop neighbor"
2222  << (nb2hop_tuple ? " (refreshing existing entry)" : ""));
2223  if (nb2hop_tuple == NULL)
2224  {
2225  TwoHopNeighborTuple new_nb2hop_tuple;
2226  new_nb2hop_tuple.neighborMainAddr = msg.GetOriginatorAddress ();
2227  new_nb2hop_tuple.twoHopNeighborAddr = nb2hop_addr;
2228  new_nb2hop_tuple.expirationTime = now + msg.GetVTime ();
2229  AddTwoHopNeighborTuple (new_nb2hop_tuple);
2230  // Schedules nb2hop tuple deletion
2231  m_events.Track (Simulator::Schedule (DELAY (new_nb2hop_tuple.expirationTime),
2233  new_nb2hop_tuple.neighborMainAddr,
2234  new_nb2hop_tuple.twoHopNeighborAddr));
2235  }
2236  else
2237  {
2238  nb2hop_tuple->expirationTime = now + msg.GetVTime ();
2239  }
2240  }
2241  else if (neighborType == OLSR_NOT_NEIGH)
2242  {
2243  // For each 2-hop node listed in the HELLO message
2244  // with Neighbor Type equal to NOT_NEIGH all 2-hop
2245  // tuples where: N_neighbor_main_addr == Originator
2246  // Address AND N_2hop_addr == main address of the
2247  // 2-hop neighbor are deleted.
2248  NS_LOG_LOGIC ("2-hop neighbor is NOT_NEIGH => deleting matching 2-hop neighbor state");
2250  }
2251  else
2252  {
2253  NS_LOG_LOGIC ("*** WARNING *** Ignoring link message (inside HELLO) with bad"
2254  " neighbor type value: " << neighborType);
2255  }
2256  }
2257  }
2258  }
2259 
2260  NS_LOG_DEBUG ("Olsr node " << m_mainAddress << ": PopulateTwoHopNeighborSet END");
2261 }
2262 
2263 
2264 
2268 void
2270  const olsr::MessageHeader::Hello &hello)
2271 {
2272  NS_LOG_FUNCTION (this);
2273 
2274  Time now = Simulator::Now ();
2275 
2276  typedef std::vector<olsr::MessageHeader::Hello::LinkMessage> LinkMessageVec;
2277  for (LinkMessageVec::const_iterator linkMessage = hello.linkMessages.begin ();
2278  linkMessage != hello.linkMessages.end ();
2279  linkMessage++)
2280  {
2281  int nt = linkMessage->linkCode >> 2;
2282  if (nt == OLSR_MPR_NEIGH)
2283  {
2284  NS_LOG_DEBUG ("Processing a link message with neighbor type MPR_NEIGH");
2285 
2286  for (std::vector<Ipv4Address>::const_iterator nb_iface_addr =
2287  linkMessage->neighborInterfaceAddresses.begin ();
2288  nb_iface_addr != linkMessage->neighborInterfaceAddresses.end ();
2289  nb_iface_addr++)
2290  {
2291  if (GetMainAddress (*nb_iface_addr) == m_mainAddress)
2292  {
2293  NS_LOG_DEBUG ("Adding entry to mpr selector set for neighbor " << *nb_iface_addr);
2294 
2295  // We must create a new entry into the mpr selector set
2296  MprSelectorTuple *existing_mprsel_tuple =
2298  if (existing_mprsel_tuple == NULL)
2299  {
2300  MprSelectorTuple mprsel_tuple;
2301 
2302  mprsel_tuple.mainAddr = msg.GetOriginatorAddress ();
2303  mprsel_tuple.expirationTime = now + msg.GetVTime ();
2304  AddMprSelectorTuple (mprsel_tuple);
2305 
2306  // Schedules mpr selector tuple deletion
2308  (DELAY (mprsel_tuple.expirationTime),
2310  mprsel_tuple.mainAddr));
2311  }
2312  else
2313  {
2314  existing_mprsel_tuple->expirationTime = now + msg.GetVTime ();
2315  }
2316  }
2317  }
2318  }
2319  }
2320  NS_LOG_DEBUG ("Computed MPR selector set for node " << m_mainAddress << ": " << m_state.PrintMprSelectorSet ());
2321 }
2322 
2323 
2324 #if 0
2325 void
2333 OLSR::mac_failed (Ptr<Packet> p) {
2334  double now = Simulator::Now ();
2335  struct hdr_ip* ih = HDR_IP (p);
2336  struct hdr_cmn* ch = HDR_CMN (p);
2337 
2338  debug ("%f: Node %d MAC Layer detects a breakage on link to %d\n",
2339  now,
2340  OLSR::node_id (ra_addr ()),
2341  OLSR::node_id (ch->next_hop ()));
2342 
2343  if ((u_int32_t)ih->daddr () == IP_BROADCAST) {
2344  drop (p, DROP_RTR_MAC_CALLBACK);
2345  return;
2346  }
2347 
2348  OLSR_link_tuple* link_tuple = state_.find_link_tuple (ch->next_hop ());
2349  if (link_tuple != NULL) {
2350  link_tuple->lost_time () = now + OLSR_NEIGHB_HOLD_TIME;
2351  link_tuple->time () = now + OLSR_NEIGHB_HOLD_TIME;
2352  nb_loss (link_tuple);
2353  }
2354  drop (p, DROP_RTR_MAC_CALLBACK);
2355 }
2356 #endif
2357 
2358 
2359 
2360 
2368 void
2370 {
2371  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
2372  << "s: OLSR Node " << m_mainAddress
2373  << " LinkTuple " << tuple.neighborIfaceAddr << " -> neighbor loss.");
2377 
2378  MprComputation ();
2380 }
2381 
2387 void
2389 {
2390  /*debug("%f: Node %d adds dup tuple: addr = %d seq_num = %d\n",
2391  Simulator::Now (),
2392  OLSR::node_id(ra_addr()),
2393  OLSR::node_id(tuple->addr()),
2394  tuple->seq_num());*/
2395  m_state.InsertDuplicateTuple (tuple);
2396 }
2397 
2403 void
2405 {
2406  /*debug("%f: Node %d removes dup tuple: addr = %d seq_num = %d\n",
2407  Simulator::Now (),
2408  OLSR::node_id(ra_addr()),
2409  OLSR::node_id(tuple->addr()),
2410  tuple->seq_num());*/
2411  m_state.EraseDuplicateTuple (tuple);
2412 }
2413 
2414 void
2415 RoutingProtocol::LinkTupleAdded (const LinkTuple &tuple, uint8_t willingness)
2416 {
2417  // Creates associated neighbor tuple
2418  NeighborTuple nb_tuple;
2420  nb_tuple.willingness = willingness;
2421 
2422  if (tuple.symTime >= Simulator::Now ())
2423  {
2424  nb_tuple.status = NeighborTuple::STATUS_SYM;
2425  }
2426  else
2427  {
2429  }
2430 
2431  AddNeighborTuple (nb_tuple);
2432 }
2433 
2439 void
2441 {
2442  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
2443  << "s: OLSR Node " << m_mainAddress
2444  << " LinkTuple " << tuple << " REMOVED.");
2445 
2447  m_state.EraseLinkTuple (tuple);
2448 }
2449 
2456 void
2457 RoutingProtocol::LinkTupleUpdated (const LinkTuple &tuple, uint8_t willingness)
2458 {
2459  // Each time a link tuple changes, the associated neighbor tuple must be recomputed
2460 
2461  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
2462  << "s: OLSR Node " << m_mainAddress
2463  << " LinkTuple " << tuple << " UPDATED.");
2464 
2465  NeighborTuple *nb_tuple =
2467 
2468  if (nb_tuple == NULL)
2469  {
2470  LinkTupleAdded (tuple, willingness);
2472  }
2473 
2474  if (nb_tuple != NULL)
2475  {
2476  int statusBefore = nb_tuple->status;
2477 
2478  bool hasSymmetricLink = false;
2479 
2480  const LinkSet &linkSet = m_state.GetLinks ();
2481  for (LinkSet::const_iterator it = linkSet.begin ();
2482  it != linkSet.end (); it++)
2483  {
2484  const LinkTuple &link_tuple = *it;
2485  if (GetMainAddress (link_tuple.neighborIfaceAddr) == nb_tuple->neighborMainAddr
2486  && link_tuple.symTime >= Simulator::Now ())
2487  {
2488  hasSymmetricLink = true;
2489  break;
2490  }
2491  }
2492 
2493  if (hasSymmetricLink)
2494  {
2495  nb_tuple->status = NeighborTuple::STATUS_SYM;
2496  NS_LOG_DEBUG (*nb_tuple << "->status = STATUS_SYM; changed:"
2497  << int (statusBefore != nb_tuple->status));
2498  }
2499  else
2500  {
2502  NS_LOG_DEBUG (*nb_tuple << "->status = STATUS_NOT_SYM; changed:"
2503  << int (statusBefore != nb_tuple->status));
2504  }
2505  }
2506  else
2507  {
2508  NS_LOG_WARN ("ERROR! Wanted to update a NeighborTuple but none was found!");
2509  }
2510 }
2511 
2517 void
2519 {
2520 // debug("%f: Node %d adds neighbor tuple: nb_addr = %d status = %s\n",
2521 // Simulator::Now (),
2522 // OLSR::node_id(ra_addr()),
2523 // OLSR::node_id(tuple->neighborMainAddr),
2524 // ((tuple->status() == OLSR_STATUS_SYM) ? "sym" : "not_sym"));
2525 
2526  m_state.InsertNeighborTuple (tuple);
2527  IncrementAnsn ();
2528 }
2529 
2535 void
2537 {
2538 // debug("%f: Node %d removes neighbor tuple: nb_addr = %d status = %s\n",
2539 // Simulator::Now (),
2540 // OLSR::node_id(ra_addr()),
2541 // OLSR::node_id(tuple->neighborMainAddr),
2542 // ((tuple->status() == OLSR_STATUS_SYM) ? "sym" : "not_sym"));
2543 
2544  m_state.EraseNeighborTuple (tuple);
2545  IncrementAnsn ();
2546 }
2547 
2553 void
2555 {
2556 // debug("%f: Node %d adds 2-hop neighbor tuple: nb_addr = %d nb2hop_addr = %d\n",
2557 // Simulator::Now (),
2558 // OLSR::node_id(ra_addr()),
2559 // OLSR::node_id(tuple->neighborMainAddr),
2560 // OLSR::node_id(tuple->twoHopNeighborAddr));
2561 
2563 }
2564 
2570 void
2572 {
2573 // debug("%f: Node %d removes 2-hop neighbor tuple: nb_addr = %d nb2hop_addr = %d\n",
2574 // Simulator::Now (),
2575 // OLSR::node_id(ra_addr()),
2576 // OLSR::node_id(tuple->neighborMainAddr),
2577 // OLSR::node_id(tuple->twoHopNeighborAddr));
2578 
2580 }
2581 
2582 void
2584 {
2585  m_ansn = (m_ansn + 1) % (OLSR_MAX_SEQ_NUM + 1);
2586 }
2587 
2595 void
2597 {
2598 // debug("%f: Node %d adds MPR selector tuple: nb_addr = %d\n",
2599 // Simulator::Now (),
2600 // OLSR::node_id(ra_addr()),
2601 // OLSR::node_id(tuple->main_addr()));
2602 
2604  IncrementAnsn ();
2605 }
2606 
2614 void
2616 {
2617 // debug("%f: Node %d removes MPR selector tuple: nb_addr = %d\n",
2618 // Simulator::Now (),
2619 // OLSR::node_id(ra_addr()),
2620 // OLSR::node_id(tuple->main_addr()));
2621 
2623  IncrementAnsn ();
2624 }
2625 
2631 void
2633 {
2634 // debug("%f: Node %d adds topology tuple: dest_addr = %d last_addr = %d seq = %d\n",
2635 // Simulator::Now (),
2636 // OLSR::node_id(ra_addr()),
2637 // OLSR::node_id(tuple->dest_addr()),
2638 // OLSR::node_id(tuple->last_addr()),
2639 // tuple->seq());
2640 
2641  m_state.InsertTopologyTuple (tuple);
2642 }
2643 
2649 void
2651 {
2652 // debug("%f: Node %d removes topology tuple: dest_addr = %d last_addr = %d seq = %d\n",
2653 // Simulator::Now (),
2654 // OLSR::node_id(ra_addr()),
2655 // OLSR::node_id(tuple->dest_addr()),
2656 // OLSR::node_id(tuple->last_addr()),
2657 // tuple->seq());
2658 
2659  m_state.EraseTopologyTuple (tuple);
2660 }
2661 
2667 void
2669 {
2670 // debug("%f: Node %d adds iface association tuple: main_addr = %d iface_addr = %d\n",
2671 // Simulator::Now (),
2672 // OLSR::node_id(ra_addr()),
2673 // OLSR::node_id(tuple->main_addr()),
2674 // OLSR::node_id(tuple->iface_addr()));
2675 
2677 }
2678 
2684 void
2686 {
2687 // debug("%f: Node %d removes iface association tuple: main_addr = %d iface_addr = %d\n",
2688 // Simulator::Now (),
2689 // OLSR::node_id(ra_addr()),
2690 // OLSR::node_id(tuple->main_addr()),
2691 // OLSR::node_id(tuple->iface_addr()));
2692 
2693  m_state.EraseIfaceAssocTuple (tuple);
2694 }
2695 
2701 void
2703 {
2705 }
2706 
2712 void
2714 {
2716 }
2717 
2718 
2719 
2721 {
2723  return m_packetSequenceNumber;
2724 }
2725 
2728 {
2730  return m_messageSequenceNumber;
2731 }
2732 
2733 
2738 void
2740 {
2741  SendHello ();
2743 }
2744 
2749 void
2751 {
2752  if (m_state.GetMprSelectors ().size () > 0)
2753  {
2754  SendTc ();
2755  }
2756  else
2757  {
2758  NS_LOG_DEBUG ("Not sending any TC, no one selected me as MPR.");
2759  }
2761 }
2762 
2767 void
2769 {
2770  SendMid ();
2772 }
2773 
2777 void
2779 {
2780  if (m_state.GetAssociations ().size () > 0)
2781  {
2782  SendHna ();
2783  }
2784  else
2785  {
2786  NS_LOG_DEBUG ("Not sending any HNA, no associations to advertise.");
2787  }
2789 }
2790 
2798 void
2800 {
2801  DuplicateTuple *tuple =
2802  m_state.FindDuplicateTuple (address, sequenceNumber);
2803  if (tuple == NULL)
2804  {
2805  return;
2806  }
2807  if (tuple->expirationTime < Simulator::Now ())
2808  {
2809  RemoveDuplicateTuple (*tuple);
2810  }
2811  else
2812  {
2815  address, sequenceNumber));
2816  }
2817 }
2818 
2830 void
2832 {
2833  Time now = Simulator::Now ();
2834 
2835  // the tuple parameter may be a stale copy; get a newer version from m_state
2836  LinkTuple *tuple = m_state.FindLinkTuple (neighborIfaceAddr);
2837  if (tuple == NULL)
2838  {
2839  return;
2840  }
2841  if (tuple->time < now)
2842  {
2843  RemoveLinkTuple (*tuple);
2844  }
2845  else if (tuple->symTime < now)
2846  {
2848  m_linkTupleTimerFirstTime = false;
2849  else
2850  NeighborLoss (*tuple);
2851 
2854  neighborIfaceAddr));
2855  }
2856  else
2857  {
2858  m_events.Track (Simulator::Schedule (DELAY (std::min (tuple->time, tuple->symTime)),
2860  neighborIfaceAddr));
2861  }
2862 }
2863 
2871 void
2873 {
2874  TwoHopNeighborTuple *tuple;
2875  tuple = m_state.FindTwoHopNeighborTuple (neighborMainAddr, twoHopNeighborAddr);
2876  if (tuple == NULL)
2877  {
2878  return;
2879  }
2880  if (tuple->expirationTime < Simulator::Now ())
2881  {
2882  RemoveTwoHopNeighborTuple (*tuple);
2883  }
2884  else
2885  {
2888  this, neighborMainAddr, twoHopNeighborAddr));
2889  }
2890 }
2891 
2899 void
2901 {
2902  MprSelectorTuple *tuple = m_state.FindMprSelectorTuple (mainAddr);
2903  if (tuple == NULL)
2904  {
2905  return;
2906  }
2907  if (tuple->expirationTime < Simulator::Now ())
2908  {
2909  RemoveMprSelectorTuple (*tuple);
2910  }
2911  else
2912  {
2915  this, mainAddr));
2916  }
2917 }
2918 
2926 void
2928 {
2929  TopologyTuple *tuple = m_state.FindTopologyTuple (destAddr, lastAddr);
2930  if (tuple == NULL)
2931  {
2932  return;
2933  }
2934  if (tuple->expirationTime < Simulator::Now ())
2935  {
2936  RemoveTopologyTuple (*tuple);
2937  }
2938  else
2939  {
2942  this, tuple->destAddr, tuple->lastAddr));
2943  }
2944 }
2945 
2950 void
2952 {
2953  IfaceAssocTuple *tuple = m_state.FindIfaceAssocTuple (ifaceAddr);
2954  if (tuple == NULL)
2955  {
2956  return;
2957  }
2958  if (tuple->time < Simulator::Now ())
2959  {
2960  RemoveIfaceAssocTuple (*tuple);
2961  }
2962  else
2963  {
2966  this, ifaceAddr));
2967  }
2968 }
2969 
2973 void
2975 {
2976  AssociationTuple *tuple = m_state.FindAssociationTuple (gatewayAddr, networkAddr, netmask);
2977  if (tuple == NULL)
2978  {
2979  return;
2980  }
2981  if (tuple->expirationTime < Simulator::Now ())
2982  {
2983  RemoveAssociationTuple (*tuple);
2984  }
2985  else
2986  {
2989  this, gatewayAddr, networkAddr, netmask));
2990  }
2991 }
2992 
2996 void
2998 {
3000  m_table.clear ();
3001 }
3002 
3007 void
3009 {
3010  m_table.erase (dest);
3011 }
3012 
3019 bool
3021  RoutingTableEntry &outEntry) const
3022 {
3023  // Get the iterator at "dest" position
3024  std::map<Ipv4Address, RoutingTableEntry>::const_iterator it =
3025  m_table.find (dest);
3026  // If there is no route to "dest", return NULL
3027  if (it == m_table.end ())
3028  return false;
3029  outEntry = it->second;
3030  return true;
3031 }
3032 
3049 bool
3051  RoutingTableEntry &outEntry) const
3052 {
3053  outEntry = entry;
3054  while (outEntry.destAddr != outEntry.nextAddr)
3055  {
3056  if (not Lookup (outEntry.nextAddr, outEntry))
3057  return false;
3058  }
3059  return true;
3060 }
3061 
3064 {
3065  NS_LOG_FUNCTION (this << " " << m_ipv4->GetObject<Node> ()->GetId () << " " << header.GetDestination () << " " << oif);
3066  Ptr<Ipv4Route> rtentry;
3067  RoutingTableEntry entry1, entry2;
3068  bool found = false;
3069 
3070  if (Lookup (header.GetDestination (), entry1) != 0)
3071  {
3072  bool foundSendEntry = FindSendEntry (entry1, entry2);
3073  if (!foundSendEntry)
3074  {
3075  NS_FATAL_ERROR ("FindSendEntry failure");
3076  }
3077  uint32_t interfaceIdx = entry2.interface;
3078  if (oif && m_ipv4->GetInterfaceForDevice (oif) != static_cast<int> (interfaceIdx))
3079  {
3080  // We do not attempt to perform a constrained routing search
3081  // if the caller specifies the oif; we just enforce that
3082  // that the found route matches the requested outbound interface
3083  NS_LOG_DEBUG ("Olsr node " << m_mainAddress
3084  << ": RouteOutput for dest=" << header.GetDestination ()
3085  << " Route interface " << interfaceIdx
3086  << " does not match requested output interface "
3087  << m_ipv4->GetInterfaceForDevice (oif));
3088  sockerr = Socket::ERROR_NOROUTETOHOST;
3089  return rtentry;
3090  }
3091  rtentry = Create<Ipv4Route> ();
3092  rtentry->SetDestination (header.GetDestination ());
3093  // the source address is the interface address that matches
3094  // the destination address (when multiple are present on the
3095  // outgoing interface, one is selected via scoping rules)
3096  NS_ASSERT (m_ipv4);
3097  uint32_t numOifAddresses = m_ipv4->GetNAddresses (interfaceIdx);
3098  NS_ASSERT (numOifAddresses > 0);
3099  Ipv4InterfaceAddress ifAddr;
3100  if (numOifAddresses == 1) {
3101  ifAddr = m_ipv4->GetAddress (interfaceIdx, 0);
3102  } else {
3104  NS_FATAL_ERROR ("XXX Not implemented yet: IP aliasing and OLSR");
3105  }
3106  rtentry->SetSource (ifAddr.GetLocal ());
3107  rtentry->SetGateway (entry2.nextAddr);
3108  rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIdx));
3109  sockerr = Socket::ERROR_NOTERROR;
3110  NS_LOG_DEBUG ("Olsr node " << m_mainAddress
3111  << ": RouteOutput for dest=" << header.GetDestination ()
3112  << " --> nextHop=" << entry2.nextAddr
3113  << " interface=" << entry2.interface);
3114  NS_LOG_DEBUG ("Found route to " << rtentry->GetDestination () << " via nh " << rtentry->GetGateway () << " with source addr " << rtentry->GetSource () << " and output dev " << rtentry->GetOutputDevice ());
3115  found = true;
3116  }
3117  else
3118  {
3119  rtentry = m_hnaRoutingTable->RouteOutput (p, header, oif, sockerr);
3120 
3121  if (rtentry)
3122  {
3123  found = true;
3124  NS_LOG_DEBUG ("Found route to " << rtentry->GetDestination () << " via nh " << rtentry->GetGateway () << " with source addr " << rtentry->GetSource () << " and output dev " << rtentry->GetOutputDevice ());
3125  }
3126  }
3127 
3128  if (!found)
3129  {
3130  NS_LOG_DEBUG ("Olsr node " << m_mainAddress
3131  << ": RouteOutput for dest=" << header.GetDestination ()
3132  << " No route to host");
3133  sockerr = Socket::ERROR_NOROUTETOHOST;
3134  }
3135  return rtentry;
3136 }
3137 
3139  const Ipv4Header &header, Ptr<const NetDevice> idev,
3142 {
3143  NS_LOG_FUNCTION (this << " " << m_ipv4->GetObject<Node> ()->GetId () << " " << header.GetDestination ());
3144 
3145  Ipv4Address dst = header.GetDestination ();
3146  Ipv4Address origin = header.GetSource ();
3147 
3148  // Consume self-originated packets
3149  if (IsMyOwnAddress (origin) == true)
3150  {
3151  return true;
3152  }
3153 
3154  // Local delivery
3155  NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
3156  uint32_t iif = m_ipv4->GetInterfaceForDevice (idev);
3157  if (m_ipv4->IsDestinationAddress (dst, iif))
3158  {
3159  if (!lcb.IsNull ())
3160  {
3161  NS_LOG_LOGIC ("Local delivery to " << dst);
3162  lcb (p, header, iif);
3163  return true;
3164  }
3165  else
3166  {
3167  // The local delivery callback is null. This may be a multicast
3168  // or broadcast packet, so return false so that another
3169  // multicast routing protocol can handle it. It should be possible
3170  // to extend this to explicitly check whether it is a unicast
3171  // packet, and invoke the error callback if so
3172  return false;
3173  }
3174  }
3175 
3176  // Forwarding
3177  Ptr<Ipv4Route> rtentry;
3178  RoutingTableEntry entry1, entry2;
3179  if (Lookup (header.GetDestination (), entry1))
3180  {
3181  bool foundSendEntry = FindSendEntry (entry1, entry2);
3182  if (!foundSendEntry)
3183  NS_FATAL_ERROR ("FindSendEntry failure");
3184  rtentry = Create<Ipv4Route> ();
3185  rtentry->SetDestination (header.GetDestination ());
3186  uint32_t interfaceIdx = entry2.interface;
3187  // the source address is the interface address that matches
3188  // the destination address (when multiple are present on the
3189  // outgoing interface, one is selected via scoping rules)
3190  NS_ASSERT (m_ipv4);
3191  uint32_t numOifAddresses = m_ipv4->GetNAddresses (interfaceIdx);
3192  NS_ASSERT (numOifAddresses > 0);
3193  Ipv4InterfaceAddress ifAddr;
3194  if (numOifAddresses == 1) {
3195  ifAddr = m_ipv4->GetAddress (interfaceIdx, 0);
3196  } else {
3198  NS_FATAL_ERROR ("XXX Not implemented yet: IP aliasing and OLSR");
3199  }
3200  rtentry->SetSource (ifAddr.GetLocal ());
3201  rtentry->SetGateway (entry2.nextAddr);
3202  rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIdx));
3203 
3204  NS_LOG_DEBUG ("Olsr node " << m_mainAddress
3205  << ": RouteInput for dest=" << header.GetDestination ()
3206  << " --> nextHop=" << entry2.nextAddr
3207  << " interface=" << entry2.interface);
3208 
3209  ucb (rtentry, p, header);
3210  return true;
3211  }
3212  else
3213  {
3214  if(m_hnaRoutingTable->RouteInput (p, header, idev, ucb, mcb, lcb, ecb))
3215  {
3216  return true;
3217  }
3218  else
3219  {
3220 
3221 #ifdef NS3_LOG_ENABLE
3222  NS_LOG_DEBUG ("Olsr node " << m_mainAddress
3223  << ": RouteInput for dest=" << header.GetDestination ()
3224  << " --> NOT FOUND; ** Dumping routing table...");
3225 
3226  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin ();
3227  iter != m_table.end (); iter++)
3228  {
3229  NS_LOG_DEBUG ("dest=" << iter->first << " --> next=" << iter->second.nextAddr
3230  << " via interface " << iter->second.interface);
3231  }
3232 
3233  NS_LOG_DEBUG ("** Routing table dump end.");
3234 #endif // NS3_LOG_ENABLE
3235 
3236  return false;
3237  }
3238  }
3239 }
3240 void
3242 {}
3243 void
3245 {}
3246 void
3248 {}
3249 void
3251 {}
3252 
3253 
3264 void
3266  Ipv4Address const &next,
3267  uint32_t interface,
3268  uint32_t distance)
3269 {
3270  NS_LOG_FUNCTION (this << dest << next << interface << distance << m_mainAddress);
3271 
3272  NS_ASSERT (distance > 0);
3273 
3274  // Creates a new rt entry with specified values
3275  RoutingTableEntry &entry = m_table[dest];
3276 
3277  entry.destAddr = dest;
3278  entry.nextAddr = next;
3279  entry.interface = interface;
3280  entry.distance = distance;
3281 }
3282 
3283 void
3285  Ipv4Address const &next,
3286  Ipv4Address const &interfaceAddress,
3287  uint32_t distance)
3288 {
3289  NS_LOG_FUNCTION (this << dest << next << interfaceAddress << distance << m_mainAddress);
3290 
3291  NS_ASSERT (distance > 0);
3292  NS_ASSERT (m_ipv4);
3293 
3294  RoutingTableEntry entry;
3295  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
3296  {
3297  for (uint32_t j = 0; j < m_ipv4->GetNAddresses (i); j++)
3298  {
3299  if (m_ipv4->GetAddress (i,j).GetLocal () == interfaceAddress)
3300  {
3301  AddEntry (dest, next, i, distance);
3302  return;
3303  }
3304  }
3305  }
3306  NS_ASSERT (false); // should not be reached
3307  AddEntry (dest, next, 0, distance);
3308 }
3309 
3310 
3311 std::vector<RoutingTableEntry>
3313 {
3314  std::vector<RoutingTableEntry> retval;
3315  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin ();
3316  iter != m_table.end (); iter++)
3317  {
3318  retval.push_back (iter->second);
3319  }
3320  return retval;
3321 }
3322 
3323 int64_t
3325 {
3326  NS_LOG_FUNCTION (this << stream);
3328  return 1;
3329 }
3330 
3331 bool
3333 {
3334  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
3335  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
3336  {
3337  Ipv4InterfaceAddress iface = j->second;
3338  if (a == iface.GetLocal ())
3339  {
3340  return true;
3341  }
3342  }
3343  return false;
3344 }
3345 
3346 void
3348 {
3349 #ifdef NS3_LOG_ENABLE
3350  Time now = Simulator::Now ();
3351  NS_LOG_DEBUG ("Dumping for node with main address " << m_mainAddress);
3352  NS_LOG_DEBUG (" Neighbor set");
3353  for (NeighborSet::const_iterator iter = m_state.GetNeighbors ().begin ();
3354  iter != m_state.GetNeighbors ().end (); iter++)
3355  {
3356  NS_LOG_DEBUG (" " << *iter);
3357  }
3358  NS_LOG_DEBUG (" Two-hop neighbor set");
3359  for (TwoHopNeighborSet::const_iterator iter = m_state.GetTwoHopNeighbors ().begin ();
3360  iter != m_state.GetTwoHopNeighbors ().end (); iter++)
3361  {
3362  if (now < iter->expirationTime)
3363  {
3364  NS_LOG_DEBUG (" " << *iter);
3365  }
3366  }
3367  NS_LOG_DEBUG (" Routing table");
3368  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin (); iter != m_table.end (); iter++)
3369  {
3370  NS_LOG_DEBUG (" dest=" << iter->first << " --> next=" << iter->second.nextAddr << " via interface " << iter->second.interface);
3371  }
3372  NS_LOG_DEBUG ("");
3373 #endif //NS3_LOG_ENABLE
3374 }
3375 
3378 {
3379  return m_hnaRoutingTable;
3380 }
3381 
3382 } // namespace olsr
3383 } // namespace ns3
3384 
3385 
std::vector< TopologyTuple > TopologySet
Topology Set type.
An MPR-Selector Tuple.
Ipv4Address networkAddr
Network Address of network reachable through gatewayAddr.
static TypeId GetTypeId(void)
Get the type ID.
#define OLSR_PORT_NUMBER
std::set< uint32_t > m_interfaceExclusions
const MprSelectorSet & GetMprSelectors() const
Definition: olsr-state.h:56
#define JITTER
Random number between [0-OLSR_MAXJITTER] used to jitter OLSR packet transmission. ...
An OLSR's routing table entry.
uint32_t distance
Distance in hops to the destination.
#define OLSR_MPR_NEIGH
Asymmetric neighbor type.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
IfaceAssocSet & GetIfaceAssocSetMutable()
Definition: olsr-state.h:142
void HelloTimerExpire()
Sends a HELLO message and reschedules the HELLO timer.
an Inet address class
void AddTopologyTuple(const TopologyTuple &tuple)
Adds a topology tuple to the Topology Set.
Ipv4Address GetIpv4(void) const
#define OLSR_MAX_SEQ_NUM
Maximum allowed sequence number.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
void DoDispose()
Destructor implementation.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
Ipv4Address GetOriginatorAddress() const
Definition: olsr-header.h:152
void SetStream(int64_t stream)
Specifies the stream number for this RNG stream.
TwoHopNeighborTuple * FindTwoHopNeighborTuple(const Ipv4Address &neighbor, const Ipv4Address &twoHopNeighbor)
Definition: olsr-state.cc:190
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
void IfaceAssocTupleTimerExpire(Ipv4Address ifaceAddr)
Removes tuple_ if expired.
uint16_t sequenceNumber
Sequence number.
void RemoveMprSelectorTuple(const MprSelectorTuple &tuple)
Removes an MPR selector tuple from the MPR Selector Set.
Callback template class.
Definition: callback.h:1164
#define OLSR_WILL_DEFAULT
Willingness for forwarding packets from other nodes: medium.
uint16_t GetPacketSequenceNumber()
Increments packet sequence number and returns the new value.
std::vector< Association > Associations
Association Set type.
Time m_midInterval
MID messages' emission interval.
A simple Timer class.
Definition: timer.h:73
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:44
#define OLSR_DUP_HOLD_TIME
Dup holding time.
void EraseMprSelectorTuples(const Ipv4Address &mainAddr)
Definition: olsr-state.cc:64
Introspection did not find any typical Config paths.
Definition: olsr-header.h:116
void Clear()
Clears the routing table and frees the memory assigned to each one of its entries.
virtual uint32_t GetSerializedSize(void) const
Definition: olsr-header.cc:127
Ipv4Address GetLocal(void) const
Get the local address.
uint16_t m_messageSequenceNumber
Messages sequence number counter.
virtual bool SetAllowBroadcast(bool allowBroadcast)=0
Configure whether broadcast datagram transmissions are allowed.
void InsertAssociationTuple(const AssociationTuple &tuple)
Definition: olsr-state.cc:521
const Associations & GetAssociations() const
Definition: olsr-state.h:157
Ipv4Address destAddr
Address of the destination node.
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:226
const NeighborTuple * FindSymNeighborTuple(const Ipv4Address &mainAddr) const
Definition: olsr-state.cc:120
std::string PrintMprSelectorSet() const
Definition: olsr-state.cc:87
void HnaTimerExpire()
Sends an HNA message (if the node has associated hosts/networks) and reschedules the HNA timer...
#define OLSR_TOP_HOLD_TIME
Top holding time.
void LinkTupleUpdated(const LinkTuple &tuple, uint8_t willingness)
This function is invoked when a link tuple is updated.
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:209
void InsertNeighborTuple(const NeighborTuple &tuple)
Definition: olsr-state.cc:172
std::vector< Ipv4Address > FindNeighborInterfaces(const Ipv4Address &neighborMainAddr) const
Definition: olsr-state.cc:478
void SetPacketSequenceNumber(uint16_t seqnum)
Definition: olsr-header.h:84
void LinkSensing(const olsr::MessageHeader &msg, const olsr::MessageHeader::Hello &hello, const Ipv4Address &receiverIface, const Ipv4Address &sender_iface)
Updates Link Set according to a new received HELLO message (following RFC 3626 specification).
uint16_t m_ansn
Advertised Neighbor Set sequence number.
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:304
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1258
#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
Ipv4Address GetDestNetwork(void) const
#define OLSR_WILL_ALWAYS
Willingness for forwarding packets from other nodes: always.
void SetMprSet(MprSet mprSet)
MprSet is set by routing protocol after MprCompute.
Definition: olsr-state.cc:271
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
void AddEntry(const Ipv4Address &dest, const Ipv4Address &next, uint32_t interface, uint32_t distance)
Adds a new entry into the routing table.
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:786
second
Definition: nstime.h:114
virtual void NotifyInterfaceUp(uint32_t interface)
void SendTc()
Creates a new OLSR TC message which is buffered for being sent later on.
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model...
void DupTupleTimerExpire(Ipv4Address address, uint16_t sequenceNumber)
Removes tuple if expired.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:244
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:145
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:291
bool FindMprAddress(const Ipv4Address &address)
Definition: olsr-state.cc:264
enum ns3::olsr::NeighborTuple::Status status
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:339
void InsertMprSelectorTuple(const MprSelectorTuple &tuple)
Definition: olsr-state.cc:81
void AddHostNetworkAssociation(Ipv4Address networkAddr, Ipv4Mask netmask)
Inject Association to be sent in HNA message.
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
std::vector< LinkMessage > linkMessages
Definition: olsr-header.h:276
uint16_t GetMessageSequenceNumber() const
Definition: olsr-header.h:179
Time expirationTime
Time at which this tuple expires and must be removed.
NeighborTuple * FindNeighborTuple(const Ipv4Address &mainAddr)
Definition: olsr-state.cc:108
#define OLSR_WILL_LOW
Willingness for forwarding packets from other nodes: low.
void LinkTupleTimerExpire(Ipv4Address neighborIfaceAddr)
Removes tuple_ if expired.
void EraseIfaceAssocTuple(const IfaceAssocTuple &tuple)
Definition: olsr-state.cc:458
void SetMainInterface(uint32_t interface)
Set the OLSR main address to the first address on the indicated interface.
Ipv4Mask netmask
Netmask of network reachable through gatewayAddr.
void SetHopCount(uint8_t hopCount)
Definition: olsr-header.h:166
MessageType GetMessageType() const
Definition: olsr-header.h:134
Time GetVTime() const
Definition: olsr-header.h:143
void Nb2hopTupleTimerExpire(Ipv4Address neighborMainAddr, Ipv4Address twoHopNeighborAddr)
Removes tuple_ if expired.
void RemoveAssociationTuple(const AssociationTuple &tuple)
Removes a host network association tuple from the Association Set.
void ProcessTc(const olsr::MessageHeader &msg, const Ipv4Address &senderIface)
Processes a TC message following RFC 3626 specification.
Ipv4Address GetSubnetDirectedBroadcast(Ipv4Mask const &mask) const
Generate subnet-directed broadcast address corresponding to mask.
#define OLSR_NEIGHB_HOLD_TIME
Neighbor holding time.
LinkTuple * FindSymLinkTuple(const Ipv4Address &ifaceAddr, Time time)
Definition: olsr-state.cc:330
a polymophic address class
Definition: address.h:90
LinkTuple * FindLinkTuple(const Ipv4Address &ifaceAddr)
Definition: olsr-state.cc:318
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
bool IsRunning(void) const
Definition: timer.cc:127
void SetVTime(Time time)
Definition: olsr-header.h:139
void EraseDuplicateTuple(const DuplicateTuple &tuple)
Definition: olsr-state.cc:296
void EraseTopologyTuple(const TopologyTuple &tuple)
Definition: olsr-state.cc:395
void MprSelTupleTimerExpire(Ipv4Address mainAddr)
Removes tuple_ if expired.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:446
#define OLSR_SYM_LINK
Symmetric link type.
void SetSource(Ipv4Address src)
Definition: ipv4-route.cc:49
std::map< Ipv4Address, RoutingTableEntry > m_table
Data structure for the routing table.
std::vector< Ipv4Address > interfaceAddresses
Definition: olsr-header.h:225
std::vector< Ipv4Address > neighborAddresses
Definition: olsr-header.h:302
void SetTimeToLive(uint8_t timeToLive)
Definition: olsr-header.h:157
TracedCallback< const PacketHeader &, const MessageList & > m_rxPacketTrace
void RemoveIfaceAssocTuple(const IfaceAssocTuple &tuple)
Removes an interface association tuple from the Interface Association Set.
uint32_t GetInterface(void) const
Packet header for IPv4.
Definition: ipv4-header.h:31
EventGarbageCollector m_events
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:341
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
Definition: packet.cc:311
Ipv4Address lastAddr
Main address of a node which is a neighbor of the destination.
A record of an IPv4 routing table entry for Ipv4GlobalRouting and Ipv4StaticRouting.
uint8_t m_willingness
Willingness for forwarding packets on behalf of other nodes.
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...
Time expirationTime
Time at which this tuple expires and must be removed.
void EraseOlderTopologyTuples(const Ipv4Address &lastAddr, uint16_t ansn)
Definition: olsr-state.cc:409
void RemoveHostNetworkAssociation(Ipv4Address networkAddr, Ipv4Mask netmask)
Removes Association sent in HNA message.
Hold variables of type enum.
Definition: enum.h:54
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1216
const TopologySet & GetTopologySet() const
Definition: olsr-state.h:124
Ipv4Address mainAddr
Main address of the node.
TopologyTuple * FindTopologyTuple(const Ipv4Address &destAddr, const Ipv4Address &lastAddr)
Definition: olsr-state.cc:370
void AddIfaceAssocTuple(const IfaceAssocTuple &tuple)
Adds an interface association tuple to the Interface Association Set.
void QueueMessage(const olsr::MessageHeader &message, Time delay)
Enques an OLSR message which will be sent with a delay of (0, delay].
AttributeValue implementation for Time.
Definition: nstime.h:957
Ipv4Address mainAddr
Main address of a node which have selected this node as a MPR.
void SendPacket(Ptr< Packet > packet, const MessageList &containedMessages)
void Schedule(void)
Schedule a new event using the currently-configured delay, function, and arguments.
Definition: timer.cc:158
const AssociationSet & GetAssociationSet() const
Definition: olsr-state.h:152
void SetGateway(Ipv4Address gw)
Definition: ipv4-route.cc:63
OLSR routing protocol for IPv4.
void SetFunction(FN fn)
Definition: timer.h:309
An Association Tuple.
void ProcessHello(const olsr::MessageHeader &msg, const Ipv4Address &receiverIface, const Ipv4Address &senderIface)
Processes a HELLO message following RFC 3626 specification.
#define DELAY(time)
Gets the delay between a given time and the current time.
tuple interfaces
Definition: first.py:41
IfaceAssocTuple * FindIfaceAssocTuple(const Ipv4Address &ifaceAddr)
Definition: olsr-state.cc:434
void AddAssociationTuple(const AssociationTuple &tuple)
Adds a host network association tuple to the Association Set.
void SetPacketLength(uint16_t length)
Definition: olsr-header.h:75
Ptr< Ipv4StaticRouting > m_hnaRoutingTable
Time expirationTime
Time at which this tuple expires and must be removed.
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)
uint8_t GetHopCount() const
Definition: olsr-header.h:170
void MprComputation()
Computates MPR set of a node following RFC 3626 hints.
void InsertDuplicateTuple(const DuplicateTuple &tuple)
Definition: olsr-state.cc:310
std::vector< LinkTuple > LinkSet
Link Set type.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1480
void RemoveDuplicateTuple(const DuplicateTuple &tuple)
Removes a duplicate tuple from the Duplicate Set.
void SetRecvCallback(Callback< void, Ptr< Socket > >)
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
virtual void NotifyAddAddress(uint32_t interface, Ipv4InterfaceAddress address)
void EraseLinkTuple(const LinkTuple &tuple)
Definition: olsr-state.cc:347
uint8_t GetTimeToLive() const
Definition: olsr-header.h:161
void CoverTwoHopNeighbors(Ipv4Address neighborMainAddr, TwoHopNeighborSet &N2)
Remove all covered 2-hop neighbors from N2 set.
Time m_helloInterval
HELLO messages' emission interval.
void SetDelay(const Time &delay)
Definition: timer.cc:75
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:252
#define OLSR_UNSPEC_LINK
Unspecified link type.
#define OLSR_NOT_NEIGH
Not neighbor type.
#define OLSR_ASYM_LINK
Asymmetric link type.
void SetRoutingTableAssociation(Ptr< Ipv4StaticRouting > routingTable)
Inject Associations from an Ipv4StaticRouting instance.
Ipv4Address destAddr
Main address of the destination.
std::vector< IfaceAssocTuple > IfaceAssocSet
Interface Association Set type.
std::map< Ptr< Socket >, Ipv4InterfaceAddress > m_socketAddresses
AssociationTuple * FindAssociationTuple(const Ipv4Address &gatewayAddr, const Ipv4Address &networkAddr, const Ipv4Mask &netmask)
Definition: olsr-state.cc:493
void TopologyTupleTimerExpire(Ipv4Address destAddr, Ipv4Address lastAddr)
Removes tuple_ if expired.
Time m_tcInterval
TC messages' emission interval.
void AddTwoHopNeighborTuple(const TwoHopNeighborTuple &tuple)
Adds a 2-hop neighbor tuple to the 2-hop Neighbor Set.
void AssociationTupleTimerExpire(Ipv4Address gatewayAddr, Ipv4Address networkAddr, Ipv4Mask netmask)
Removes tuple_ if expired.
virtual void PrintRoutingTable(Ptr< OutputStreamWrapper > stream) const
Print the Routing Table entries.
void NeighborLoss(const LinkTuple &tuple)
Performs all actions needed when a neighbor loss occurs.
void SetOriginatorAddress(Ipv4Address originatorAddress)
Definition: olsr-header.h:148
void RemoveTopologyTuple(const TopologyTuple &tuple)
Removes a topology tuple from the Topology Set.
uint8_t willingness
A value between 0 and 7 specifying the node's willingness to carry traffic on behalf of other nodes...
Time expirationTime
Time at which this tuple expires and must be removed.
void SendMid()
Creates a new OLSR MID message which is buffered for being sent later on.
void InsertIfaceAssocTuple(const IfaceAssocTuple &tuple)
Definition: olsr-state.cc:472
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static InetSocketAddress ConvertFrom(const Address &address)
Returns an InetSocketAddress which corresponds to the input Address.
void RecvOlsr(Ptr< Socket > socket)
Ipv4Address neighborMainAddr
Main address of a neighbor node.
const NeighborSet & GetNeighbors() const
Definition: olsr-state.h:67
std::vector< Association > associations
Definition: olsr-header.h:338
Ipv4Address twoHopNeighborAddr
Main address of a 2-hop neighbor with a symmetric link to nb_main_addr.
void MidTimerExpire()
Sends a MID message (if the node has more than one interface) and resets the MID timer.
Ptr< Ipv4StaticRouting > m_routingTableAssociation
Ptr< const Ipv4StaticRouting > GetRoutingTableAssociation() const
Returns the internal HNA table.
void AddNeighborTuple(const NeighborTuple &tuple)
Adds a neighbor tuple to the Neighbor Set.
void SendHello()
Creates a new OLSR HELLO message which is buffered for being sent later on.
MprSelectorTuple * FindMprSelectorTuple(const Ipv4Address &mainAddr)
Definition: olsr-state.cc:38
void RemoveLinkTuple(const LinkTuple &tuple)
Removes a link tuple from the Link Set.
bool UsesNonOlsrOutgoingInterface(const Ipv4RoutingTableEntry &route)
Tests whether or not the specified route uses a non-OLSR outgoing interface.
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:958
bool Lookup(const Ipv4Address &dest, RoutingTableEntry &outEntry) const
Looks up an entry for the specified destination address.
std::vector< MessageHeader > MessageList
Definition: olsr-header.h:450
Definition: olsr.py:1
void EraseAssociationTuple(const AssociationTuple &tuple)
Definition: olsr-state.cc:507
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:223
void SetOutputDevice(Ptr< NetDevice > outputDevice)
Equivalent in Linux to dst_entry.dev.
Definition: ipv4-route.cc:77
Time time
Time at which this tuple expires and must be removed.
virtual void NotifyInterfaceDown(uint32_t interface)
Introspection did not find any typical Config paths.
Definition: olsr-header.h:69
uint16_t m_packetSequenceNumber
Packets sequence number counter.
virtual void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
Definition: socket.cc:330
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...
Ipv4Address GetMainAddress(Ipv4Address iface_addr) const
Gets the main address associated with a given interface address.
void RoutingTableComputation()
Creates the routing table of the node following RFC 3626 hints.
void RemoveTwoHopNeighborTuple(const TwoHopNeighborTuple &tuple)
Removes a 2-hop neighbor tuple from the 2-hop Neighbor Set.
void RemoveEntry(const Ipv4Address &dest)
Deletes the entry whose destination address is given.
void ForwardDefault(olsr::MessageHeader olsrMessage, DuplicateTuple *duplicated, const Ipv4Address &localIface, const Ipv4Address &senderAddress)
OLSR's default forwarding algorithm.
void ProcessHna(const olsr::MessageHeader &msg, const Ipv4Address &senderIface)
Processes a HNA message following RFC 3626 specification.
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.
int Degree(NeighborTuple const &tuple)
This auxiliary function (defined in RFC 3626) is used for calculating the MPR Set.
Ptr< const AttributeChecker > MakeEnumChecker(int v1, std::string n1, int v2, std::string n2, int v3, std::string n3, int v4, std::string n4, int v5, std::string n5, int v6, std::string n6, int v7, std::string n7, int v8, std::string n8, int v9, std::string n9, int v10, std::string n10, int v11, std::string n11, int v12, std::string n12, int v13, std::string n13, int v14, std::string n14, int v15, std::string n15, int v16, std::string n16, int v17, std::string n17, int v18, std::string n18, int v19, std::string n19, int v20, std::string n20, int v21, std::string n21, int v22, std::string n22)
Make an EnumChecker pre-configured with a set of allowed values by name.
Definition: enum.cc:184
#define OLSR_WILL_HIGH
Willingness for forwarding packets from other nodes: high.
uint32_t interface
Interface index.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:40
std::vector< NeighborTuple > NeighborSet
Neighbor Set type.
bool IsMyOwnAddress(const Ipv4Address &a) const
Check that address is one of my interfaces.
void EraseAssociation(const Association &tuple)
Definition: olsr-state.cc:527
TimeWithUnit As(const enum Unit unit) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:388
uint32_t GetId(void) const
Definition: node.cc:107
a class to store IPv4 address information on an interface
virtual void SetIpv4(Ptr< Ipv4 > ipv4)
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 (...
void SendQueuedMessages()
Creates as many OLSR packets as needed in order to send all buffered OLSR messages.
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:228
DuplicateTuple * FindDuplicateTuple(const Ipv4Address &address, uint16_t sequenceNumber)
Definition: olsr-state.cc:284
void InsertTwoHopNeighborTuple(const TwoHopNeighborTuple &tuple)
Definition: olsr-state.cc:256
Ipv4Address ifaceAddr
Interface address of a node.
const IfaceAssocSet & GetIfaceAssocSet() const
Definition: olsr-state.h:138
#define OLSR_LOST_LINK
Lost link type.
Ipv4Address nextAddr
Address of the next hop.
TracedCallback< const PacketHeader &, const MessageList & > m_txPacketTrace
std::set< Ipv4Address > MprSet
MPR Set type.
A network Node.
Definition: node.h:56
#define OLSR_SYM_NEIGH
Symmetric neighbor type.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:236
const LinkSet & GetLinks() const
Definition: olsr-state.h:114
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:895
void SendHna()
Creates a new OLSR HNA message which is buffered for being sent later on.
#define OLSR_MID_HOLD_TIME
MID holding time.
std::vector< TwoHopNeighborTuple > TwoHopNeighborSet
2-hop Neighbor Set type.
void EraseTwoHopNeighborTuple(const TwoHopNeighborTuple &tuple)
Definition: olsr-state.cc:206
void Track(EventId event)
Tracks a new event.
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:743
Abstract base class for IPv4 routing protocols.
#define OLSR_WILL_NEVER
Willingness for forwarding packets from other nodes: never.
#define OLSR_MAX_MSGS
Maximum number of messages per packet.
void LinkTupleAdded(const LinkTuple &tuple, uint8_t willingness)
void SetInterfaceExclusions(std::set< uint32_t > exceptions)
LinkTuple & InsertLinkTuple(const LinkTuple &tuple)
Definition: olsr-state.cc:361
Time m_hnaInterval
HNA messages' emission interval.
void Dump(void)
Dump the neighbor table, two-hop neighbor table, and routing table to logging output (NS_LOG_DEBUG lo...
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:330
uint16_t GetPort(void) const
Ipv4Address neighborMainAddr
Main address of a neighbor.
virtual void DoInitialize(void)
Initialize() implementation.
std::vector< RoutingTableEntry > GetRoutingTableEntries() const
Return the list of routing table entries discovered by OLSR.
void EraseNeighborTuple(const NeighborTuple &neighborTuple)
Definition: olsr-state.cc:144
tuple address
Definition: first.py:37
const TwoHopNeighborSet & GetTwoHopNeighbors() const
Definition: olsr-state.h:84
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.
void AddDuplicateTuple(const DuplicateTuple &tuple)
Adds a duplicate tuple to the Duplicate Set.
void SetMessageSequenceNumber(uint16_t messageSequenceNumber)
Definition: olsr-header.h:175
void TcTimerExpire()
Sends a TC message (if there exists any MPR selector) and reschedules the TC timer.
Ipv4Address address
Originator address of the message.
TopologyTuple * FindNewerTopologyTuple(const Ipv4Address &lastAddr, uint16_t ansn)
Definition: olsr-state.cc:383
void RemoveNeighborTuple(const NeighborTuple &tuple)
Removes a neighbor tuple from the Neighbor Set.
uint16_t GetMessageSequenceNumber()
Increments message sequence number and returns the new value.
virtual uint32_t GetSerializedSize(void) const
Definition: olsr-header.cc:186
Ipv4Address gatewayAddr
Main address of the gateway.
OlsrState m_state
Internal state with all needed data structs.
void AddMprSelectorTuple(const MprSelectorTuple &tuple)
Adds an MPR selector tuple to the MPR Selector Set.
TracedCallback< uint32_t > m_routingTableChanged
#define OLSR_HNA_HOLD_TIME
HNA holding time.
Ipv4Mask GetDestNetworkMask(void) const
a unique identifier for an interface.
Definition: type-id.h:58
An Interface Association Tuple.
bool retransmitted
Indicates whether the message has been retransmitted or not.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:826
The type "list of interface addresses".
virtual void NotifyRemoveAddress(uint32_t interface, Ipv4InterfaceAddress address)
void EraseMprSelectorTuple(const MprSelectorTuple &tuple)
Definition: olsr-state.cc:50
std::ostream * GetStream(void)
Return a pointer to an ostream previously set in the wrapper.
void InsertAssociation(const Association &tuple)
Definition: olsr-state.cc:541
uint16_t sequenceNumber
Message sequence number.
std::vector< AssociationTuple > AssociationSet
Association Set type.
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:255
olsr::MessageList m_queuedMessages
A list of pending messages which are buffered awaiting for being sent.
Ptr< UniformRandomVariable > m_uniformRandomVariable
Provides uniform random variables.
void SetDestination(Ipv4Address dest)
Definition: ipv4-route.cc:35
bool FindSendEntry(const RoutingTableEntry &entry, RoutingTableEntry &outEntry) const
Finds the appropiate entry which must be used in order to forward a data packet to a next hop (given ...
uint16_t GetPacketLength() const
Definition: olsr-header.h:79
Time expirationTime
Time at which this tuple expires and must be removed.
void EraseTwoHopNeighborTuples(const Ipv4Address &neighbor)
Definition: olsr-state.cc:239
void InsertTopologyTuple(const TopologyTuple &tuple)
Definition: olsr-state.cc:426
std::vector< Ipv4Address > ifaceList
List of interfaces which the message has been received on.
void ProcessMid(const olsr::MessageHeader &msg, const Ipv4Address &senderIface)
Processes a MID message following RFC 3626 specification.