A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 namespace olsr {
143 
144 NS_LOG_COMPONENT_DEFINE ("OlsrRoutingProtocol");
145 
146 
147 /********** OLSR class **********/
148 
149 NS_OBJECT_ENSURE_REGISTERED (RoutingProtocol);
150 
151 TypeId
153 {
154  static TypeId tid = TypeId ("ns3::olsr::RoutingProtocol")
156  .AddConstructor<RoutingProtocol> ()
157  .AddAttribute ("HelloInterval", "HELLO messages emission interval.",
158  TimeValue (Seconds (2)),
159  MakeTimeAccessor (&RoutingProtocol::m_helloInterval),
160  MakeTimeChecker ())
161  .AddAttribute ("TcInterval", "TC messages emission interval.",
162  TimeValue (Seconds (5)),
163  MakeTimeAccessor (&RoutingProtocol::m_tcInterval),
164  MakeTimeChecker ())
165  .AddAttribute ("MidInterval", "MID messages emission interval. Normally it is equal to TcInterval.",
166  TimeValue (Seconds (5)),
167  MakeTimeAccessor (&RoutingProtocol::m_midInterval),
168  MakeTimeChecker ())
169  .AddAttribute ("HnaInterval", "HNA messages emission interval. Normally it is equal to TcInterval.",
170  TimeValue (Seconds (5)),
171  MakeTimeAccessor (&RoutingProtocol::m_hnaInterval),
172  MakeTimeChecker ())
173  .AddAttribute ("Willingness", "Willingness of a node to carry and forward traffic for other nodes.",
177  OLSR_WILL_LOW, "low",
178  OLSR_WILL_DEFAULT, "default",
179  OLSR_WILL_HIGH, "high",
180  OLSR_WILL_ALWAYS, "always"))
181  .AddTraceSource ("Rx", "Receive OLSR packet.",
183  .AddTraceSource ("Tx", "Send OLSR packet.",
185  .AddTraceSource ("RoutingTableChanged", "The OLSR routing table has changed.",
187  ;
188  return tid;
189 }
190 
191 
193  : m_routingTableAssociation (0),
194  m_ipv4 (0),
195  m_helloTimer (Timer::CANCEL_ON_DESTROY),
196  m_tcTimer (Timer::CANCEL_ON_DESTROY),
197  m_midTimer (Timer::CANCEL_ON_DESTROY),
198  m_hnaTimer (Timer::CANCEL_ON_DESTROY),
199  m_queuedMessagesTimer (Timer::CANCEL_ON_DESTROY)
200 {
201  m_uniformRandomVariable = CreateObject<UniformRandomVariable> ();
202 
203  m_hnaRoutingTable = Create<Ipv4StaticRouting> ();
204 }
205 
207 {
208 }
209 
210 void
212 {
213  NS_ASSERT (ipv4 != 0);
214  NS_ASSERT (m_ipv4 == 0);
215  NS_LOG_DEBUG ("Created olsr::RoutingProtocol");
221 
225 
227 
228  m_ipv4 = ipv4;
229 
230  m_hnaRoutingTable->SetIpv4 (ipv4);
231 }
232 
234 {
235  m_ipv4 = 0;
236  m_hnaRoutingTable = 0;
238 
239  for (std::map< Ptr<Socket>, Ipv4InterfaceAddress >::iterator iter = m_socketAddresses.begin ();
240  iter != m_socketAddresses.end (); iter++)
241  {
242  iter->first->Close ();
243  }
244  m_socketAddresses.clear ();
245 
247 }
248 
249 void
251 {
252  std::ostream* os = stream->GetStream ();
253  *os << "Destination\t\tNextHop\t\tInterface\tDistance\n";
254 
255  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin ();
256  iter != m_table.end (); iter++)
257  {
258  *os << iter->first << "\t\t";
259  *os << iter->second.nextAddr << "\t\t";
260  if (Names::FindName (m_ipv4->GetNetDevice (iter->second.interface)) != "")
261  {
262  *os << Names::FindName (m_ipv4->GetNetDevice (iter->second.interface)) << "\t\t";
263  }
264  else
265  {
266  *os << iter->second.interface << "\t\t";
267  }
268  *os << iter->second.distance << "\t";
269  *os << "\n";
270  }
271  // Also print the HNA routing table
272  *os << " HNA Routing Table:\n";
273  m_hnaRoutingTable->PrintRoutingTable (stream);
274 }
275 
277 {
278  if (m_mainAddress == Ipv4Address ())
279  {
280  Ipv4Address loopback ("127.0.0.1");
281  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
282  {
283  // Use primary address, if multiple
284  Ipv4Address addr = m_ipv4->GetAddress (i, 0).GetLocal ();
285  if (addr != loopback)
286  {
287  m_mainAddress = addr;
288  break;
289  }
290  }
291 
293  }
294 
295  NS_LOG_DEBUG ("Starting OLSR on node " << m_mainAddress);
296 
297  Ipv4Address loopback ("127.0.0.1");
298 
299  bool canRunOlsr = false;
300  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
301  {
302  Ipv4Address addr = m_ipv4->GetAddress (i, 0).GetLocal ();
303  if (addr == loopback)
304  continue;
305 
306  if (addr != m_mainAddress)
307  {
308  // Create never expiring interface association tuple entries for our
309  // own network interfaces, so that GetMainAddress () works to
310  // translate the node's own interface addresses into the main address.
311  IfaceAssocTuple tuple;
312  tuple.ifaceAddr = addr;
313  tuple.mainAddr = m_mainAddress;
314  AddIfaceAssocTuple (tuple);
316  }
317 
318  if(m_interfaceExclusions.find (i) != m_interfaceExclusions.end ())
319  continue;
320 
321  // Create a socket to listen only on this interface
322  Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
324  socket->SetAllowBroadcast (true);
325  InetSocketAddress inetAddr (m_ipv4->GetAddress (i, 0).GetLocal (), OLSR_PORT_NUMBER);
327  if (socket->Bind (inetAddr))
328  {
329  NS_FATAL_ERROR ("Failed to bind() OLSR socket");
330  }
331  socket->BindToNetDevice (m_ipv4->GetNetDevice (i));
332  m_socketAddresses[socket] = m_ipv4->GetAddress (i, 0);
333 
334  canRunOlsr = true;
335  }
336 
337  if(canRunOlsr)
338  {
339  HelloTimerExpire ();
340  TcTimerExpire ();
341  MidTimerExpire ();
342  HnaTimerExpire ();
343 
344  NS_LOG_DEBUG ("OLSR on node " << m_mainAddress << " started");
345  }
346 }
347 
348 void RoutingProtocol::SetMainInterface (uint32_t interface)
349 {
350  m_mainAddress = m_ipv4->GetAddress (interface, 0).GetLocal ();
351 }
352 
353 void RoutingProtocol::SetInterfaceExclusions (std::set<uint32_t> exceptions)
354 {
355  m_interfaceExclusions = exceptions;
356 }
357 
358 //
359 // \brief Processes an incoming %OLSR packet following \RFC{3626} specification.
360 void
362 {
363  Ptr<Packet> receivedPacket;
364  Address sourceAddress;
365  receivedPacket = socket->RecvFrom (sourceAddress);
366 
367  InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom (sourceAddress);
368  Ipv4Address senderIfaceAddr = inetSourceAddr.GetIpv4 ();
369  Ipv4Address receiverIfaceAddr = m_socketAddresses[socket].GetLocal ();
370  NS_ASSERT (receiverIfaceAddr != Ipv4Address ());
371  NS_LOG_DEBUG ("OLSR node " << m_mainAddress << " received a OLSR packet from "
372  << senderIfaceAddr << " to " << receiverIfaceAddr);
373 
374  // All routing messages are sent from and to port RT_PORT,
375  // so we check it.
376  NS_ASSERT (inetSourceAddr.GetPort () == OLSR_PORT_NUMBER);
377 
378  Ptr<Packet> packet = receivedPacket;
379 
380  olsr::PacketHeader olsrPacketHeader;
381  packet->RemoveHeader (olsrPacketHeader);
382  NS_ASSERT (olsrPacketHeader.GetPacketLength () >= olsrPacketHeader.GetSerializedSize ());
383  uint32_t sizeLeft = olsrPacketHeader.GetPacketLength () - olsrPacketHeader.GetSerializedSize ();
384 
385  MessageList messages;
386 
387  while (sizeLeft)
388  {
389  MessageHeader messageHeader;
390  if (packet->RemoveHeader (messageHeader) == 0)
391  NS_ASSERT (false);
392 
393  sizeLeft -= messageHeader.GetSerializedSize ();
394 
395  NS_LOG_DEBUG ("Olsr Msg received with type "
396  << std::dec << int (messageHeader.GetMessageType ())
397  << " TTL=" << int (messageHeader.GetTimeToLive ())
398  << " origAddr=" << messageHeader.GetOriginatorAddress ());
399  messages.push_back (messageHeader);
400  }
401 
402  m_rxPacketTrace (olsrPacketHeader, messages);
403 
404  for (MessageList::const_iterator messageIter = messages.begin ();
405  messageIter != messages.end (); messageIter++)
406  {
407  const MessageHeader &messageHeader = *messageIter;
408  // If ttl is less than or equal to zero, or
409  // the receiver is the same as the originator,
410  // the message must be silently dropped
411  if (messageHeader.GetTimeToLive () == 0
412  || messageHeader.GetOriginatorAddress () == m_mainAddress)
413  {
414  packet->RemoveAtStart (messageHeader.GetSerializedSize ()
415  - messageHeader.GetSerializedSize ());
416  continue;
417  }
418 
419  // If the message has been processed it must not be processed again
420  bool do_forwarding = true;
422  (messageHeader.GetOriginatorAddress (),
423  messageHeader.GetMessageSequenceNumber ());
424 
425  // Get main address of the peer, which may be different from the packet source address
426 // const IfaceAssocTuple *ifaceAssoc = m_state.FindIfaceAssocTuple (inetSourceAddr.GetIpv4 ());
427 // Ipv4Address peerMainAddress;
428 // if (ifaceAssoc != NULL)
429 // {
430 // peerMainAddress = ifaceAssoc->mainAddr;
431 // }
432 // else
433 // {
434 // peerMainAddress = inetSourceAddr.GetIpv4 () ;
435 // }
436 
437  if (duplicated == NULL)
438  {
439  switch (messageHeader.GetMessageType ())
440  {
442  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
443  << "s OLSR node " << m_mainAddress
444  << " received HELLO message of size " << messageHeader.GetSerializedSize ());
445  ProcessHello (messageHeader, receiverIfaceAddr, senderIfaceAddr);
446  break;
447 
449  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
450  << "s OLSR node " << m_mainAddress
451  << " received TC message of size " << messageHeader.GetSerializedSize ());
452  ProcessTc (messageHeader, senderIfaceAddr);
453  break;
454 
456  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
457  << "s OLSR node " << m_mainAddress
458  << " received MID message of size " << messageHeader.GetSerializedSize ());
459  ProcessMid (messageHeader, senderIfaceAddr);
460  break;
462  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
463  << "s OLSR node " << m_mainAddress
464  << " received HNA message of size " << messageHeader.GetSerializedSize ());
465  ProcessHna (messageHeader, senderIfaceAddr);
466  break;
467 
468  default:
469  NS_LOG_DEBUG ("OLSR message type " <<
470  int (messageHeader.GetMessageType ()) <<
471  " not implemented");
472  }
473  }
474  else
475  {
476  NS_LOG_DEBUG ("OLSR message is duplicated, not reading it.");
477 
478  // If the message has been considered for forwarding, it should
479  // not be retransmitted again
480  for (std::vector<Ipv4Address>::const_iterator it = duplicated->ifaceList.begin ();
481  it != duplicated->ifaceList.end (); it++)
482  {
483  if (*it == receiverIfaceAddr)
484  {
485  do_forwarding = false;
486  break;
487  }
488  }
489  }
490 
491  if (do_forwarding)
492  {
493  // HELLO messages are never forwarded.
494  // TC and MID messages are forwarded using the default algorithm.
495  // Remaining messages are also forwarded using the default algorithm.
496  if (messageHeader.GetMessageType () != olsr::MessageHeader::HELLO_MESSAGE)
497  {
498  ForwardDefault (messageHeader, duplicated,
499  receiverIfaceAddr, inetSourceAddr.GetIpv4 ());
500  }
501  }
502  }
503 
504  // After processing all OLSR messages, we must recompute the routing table
506 }
507 
514 int
516 {
517  int degree = 0;
518  for (TwoHopNeighborSet::const_iterator it = m_state.GetTwoHopNeighbors ().begin ();
519  it != m_state.GetTwoHopNeighbors ().end (); it++)
520  {
521  TwoHopNeighborTuple const &nb2hop_tuple = *it;
522  if (nb2hop_tuple.neighborMainAddr == tuple.neighborMainAddr)
523  {
524  const NeighborTuple *nb_tuple =
526  if (nb_tuple == NULL)
527  degree++;
528  }
529  }
530  return degree;
531 }
532 
533 namespace {
537 void
539 {
540  // first gather all 2-hop neighbors to be removed
541  std::set<Ipv4Address> toRemove;
542  for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin (); twoHopNeigh != N2.end (); twoHopNeigh++)
543  {
544  if (twoHopNeigh->neighborMainAddr == neighborMainAddr)
545  {
546  toRemove.insert (twoHopNeigh->twoHopNeighborAddr);
547  }
548  }
549  // Now remove all matching records from N2
550  for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin (); twoHopNeigh != N2.end (); )
551  {
552  if (toRemove.find (twoHopNeigh->twoHopNeighborAddr) != toRemove.end ())
553  {
554  twoHopNeigh = N2.erase (twoHopNeigh);
555  }
556  else
557  {
558  twoHopNeigh++;
559  }
560  }
561 }
562 } // anonymous namespace
563 
567 void
569 {
570  NS_LOG_FUNCTION (this);
571 
572  // MPR computation should be done for each interface. See section 8.3.1
573  // (RFC 3626) for details.
574  MprSet mprSet;
575 
576  // N is the subset of neighbors of the node, which are
577  // neighbor "of the interface I"
578  NeighborSet N;
579  for (NeighborSet::const_iterator neighbor = m_state.GetNeighbors ().begin ();
580  neighbor != m_state.GetNeighbors ().end (); neighbor++)
581  {
582  if (neighbor->status == NeighborTuple::STATUS_SYM) // I think that we need this check
583  {
584  N.push_back (*neighbor);
585  }
586  }
587 
588  // N2 is the set of 2-hop neighbors reachable from "the interface
589  // I", excluding:
590  // (i) the nodes only reachable by members of N with willingness WILL_NEVER
591  // (ii) the node performing the computation
592  // (iii) all the symmetric neighbors: the nodes for which there exists a symmetric
593  // link to this node on some interface.
595  for (TwoHopNeighborSet::const_iterator twoHopNeigh = m_state.GetTwoHopNeighbors ().begin ();
596  twoHopNeigh != m_state.GetTwoHopNeighbors ().end (); twoHopNeigh++)
597  {
598  // excluding:
599  // (ii) the node performing the computation
600  if (twoHopNeigh->twoHopNeighborAddr == m_mainAddress)
601  {
602  continue;
603  }
604 
605  // excluding:
606  // (i) the nodes only reachable by members of N with willingness WILL_NEVER
607  bool ok = false;
608  for (NeighborSet::const_iterator neigh = N.begin ();
609  neigh != N.end (); neigh++)
610  {
611  if (neigh->neighborMainAddr == twoHopNeigh->neighborMainAddr)
612  {
613  if (neigh->willingness == OLSR_WILL_NEVER)
614  {
615  ok = false;
616  break;
617  }
618  else
619  {
620  ok = true;
621  break;
622  }
623  }
624  }
625  if (!ok)
626  {
627  continue;
628  }
629 
630  // excluding:
631  // (iii) all the symmetric neighbors: the nodes for which there exists a symmetric
632  // link to this node on some interface.
633  for (NeighborSet::const_iterator neigh = N.begin ();
634  neigh != N.end (); neigh++)
635  {
636  if (neigh->neighborMainAddr == twoHopNeigh->twoHopNeighborAddr)
637  {
638  ok = false;
639  break;
640  }
641  }
642 
643  if (ok)
644  {
645  N2.push_back (*twoHopNeigh);
646  }
647  }
648 
649 #ifdef NS3_LOG_ENABLE
650  {
651  std::ostringstream os;
652  os << "[";
653  for (TwoHopNeighborSet::const_iterator iter = N2.begin ();
654  iter != N2.end (); iter++)
655  {
656  TwoHopNeighborSet::const_iterator next = iter;
657  next++;
658  os << iter->neighborMainAddr << "->" << iter->twoHopNeighborAddr;
659  if (next != N2.end ())
660  os << ", ";
661  }
662  os << "]";
663  NS_LOG_DEBUG ("N2: " << os.str ());
664  }
665 #endif //NS3_LOG_ENABLE
666 
667  // 1. Start with an MPR set made of all members of N with
668  // N_willingness equal to WILL_ALWAYS
669  for (NeighborSet::const_iterator neighbor = N.begin (); neighbor != N.end (); neighbor++)
670  {
671  if (neighbor->willingness == OLSR_WILL_ALWAYS)
672  {
673  mprSet.insert (neighbor->neighborMainAddr);
674  // (not in RFC but I think is needed: remove the 2-hop
675  // neighbors reachable by the MPR from N2)
676  CoverTwoHopNeighbors (neighbor->neighborMainAddr, N2);
677  }
678  }
679 
680  // 2. Calculate D(y), where y is a member of N, for all nodes in N.
681  // (we do this later)
682 
683  // 3. Add to the MPR set those nodes in N, which are the *only*
684  // nodes to provide reachability to a node in N2.
685  std::set<Ipv4Address> coveredTwoHopNeighbors;
686  for (TwoHopNeighborSet::const_iterator twoHopNeigh = N2.begin (); twoHopNeigh != N2.end (); twoHopNeigh++)
687  {
688  bool onlyOne = true;
689  // try to find another neighbor that can reach twoHopNeigh->twoHopNeighborAddr
690  for (TwoHopNeighborSet::const_iterator otherTwoHopNeigh = N2.begin (); otherTwoHopNeigh != N2.end (); otherTwoHopNeigh++)
691  {
692  if (otherTwoHopNeigh->twoHopNeighborAddr == twoHopNeigh->twoHopNeighborAddr
693  && otherTwoHopNeigh->neighborMainAddr != twoHopNeigh->neighborMainAddr)
694  {
695  onlyOne = false;
696  break;
697  }
698  }
699  if (onlyOne)
700  {
701  NS_LOG_LOGIC ("Neighbor " << twoHopNeigh->neighborMainAddr
702  << " is the only that can reach 2-hop neigh. "
703  << twoHopNeigh->twoHopNeighborAddr
704  << " => select as MPR.");
705 
706  mprSet.insert (twoHopNeigh->neighborMainAddr);
707 
708  // take note of all the 2-hop neighbors reachable by the newly elected MPR
709  for (TwoHopNeighborSet::const_iterator otherTwoHopNeigh = N2.begin ();
710  otherTwoHopNeigh != N2.end (); otherTwoHopNeigh++)
711  {
712  if (otherTwoHopNeigh->neighborMainAddr == twoHopNeigh->neighborMainAddr)
713  {
714  coveredTwoHopNeighbors.insert (otherTwoHopNeigh->twoHopNeighborAddr);
715  }
716  }
717  }
718  }
719  // Remove the nodes from N2 which are now covered by a node in the MPR set.
720  for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin ();
721  twoHopNeigh != N2.end (); )
722  {
723  if (coveredTwoHopNeighbors.find (twoHopNeigh->twoHopNeighborAddr) != coveredTwoHopNeighbors.end ())
724  {
725  // This works correctly only because it is known that twoHopNeigh is reachable by exactly one neighbor,
726  // so only one record in N2 exists for each of them. This record is erased here.
727  NS_LOG_LOGIC ("2-hop neigh. " << twoHopNeigh->twoHopNeighborAddr << " is already covered by an MPR.");
728  twoHopNeigh = N2.erase (twoHopNeigh);
729  }
730  else
731  {
732  twoHopNeigh++;
733  }
734  }
735 
736  // 4. While there exist nodes in N2 which are not covered by at
737  // least one node in the MPR set:
738  while (N2.begin () != N2.end ())
739  {
740 
741 #ifdef NS3_LOG_ENABLE
742  {
743  std::ostringstream os;
744  os << "[";
745  for (TwoHopNeighborSet::const_iterator iter = N2.begin ();
746  iter != N2.end (); iter++)
747  {
748  TwoHopNeighborSet::const_iterator next = iter;
749  next++;
750  os << iter->neighborMainAddr << "->" << iter->twoHopNeighborAddr;
751  if (next != N2.end ())
752  os << ", ";
753  }
754  os << "]";
755  NS_LOG_DEBUG ("Step 4 iteration: N2=" << os.str ());
756  }
757 #endif //NS3_LOG_ENABLE
758 
759 
760  // 4.1. For each node in N, calculate the reachability, i.e., the
761  // number of nodes in N2 which are not yet covered by at
762  // least one node in the MPR set, and which are reachable
763  // through this 1-hop neighbor
764  std::map<int, std::vector<const NeighborTuple *> > reachability;
765  std::set<int> rs;
766  for (NeighborSet::iterator it = N.begin (); it != N.end (); it++)
767  {
768  NeighborTuple const &nb_tuple = *it;
769  int r = 0;
770  for (TwoHopNeighborSet::iterator it2 = N2.begin (); it2 != N2.end (); it2++)
771  {
772  TwoHopNeighborTuple const &nb2hop_tuple = *it2;
773  if (nb_tuple.neighborMainAddr == nb2hop_tuple.neighborMainAddr)
774  r++;
775  }
776  rs.insert (r);
777  reachability[r].push_back (&nb_tuple);
778  }
779 
780  // 4.2. Select as a MPR the node with highest N_willingness among
781  // the nodes in N with non-zero reachability. In case of
782  // multiple choice select the node which provides
783  // reachability to the maximum number of nodes in N2. In
784  // case of multiple nodes providing the same amount of
785  // reachability, select the node as MPR whose D(y) is
786  // greater. Remove the nodes from N2 which are now covered
787  // by a node in the MPR set.
788  NeighborTuple const *max = NULL;
789  int max_r = 0;
790  for (std::set<int>::iterator it = rs.begin (); it != rs.end (); it++)
791  {
792  int r = *it;
793  if (r == 0)
794  {
795  continue;
796  }
797  for (std::vector<const NeighborTuple *>::iterator it2 = reachability[r].begin ();
798  it2 != reachability[r].end (); it2++)
799  {
800  const NeighborTuple *nb_tuple = *it2;
801  if (max == NULL || nb_tuple->willingness > max->willingness)
802  {
803  max = nb_tuple;
804  max_r = r;
805  }
806  else if (nb_tuple->willingness == max->willingness)
807  {
808  if (r > max_r)
809  {
810  max = nb_tuple;
811  max_r = r;
812  }
813  else if (r == max_r)
814  {
815  if (Degree (*nb_tuple) > Degree (*max))
816  {
817  max = nb_tuple;
818  max_r = r;
819  }
820  }
821  }
822  }
823  }
824 
825  if (max != NULL)
826  {
827  mprSet.insert (max->neighborMainAddr);
829  NS_LOG_LOGIC (N2.size () << " 2-hop neighbors left to cover!");
830  }
831  }
832 
833 #ifdef NS3_LOG_ENABLE
834  {
835  std::ostringstream os;
836  os << "[";
837  for (MprSet::const_iterator iter = mprSet.begin ();
838  iter != mprSet.end (); iter++)
839  {
840  MprSet::const_iterator next = iter;
841  next++;
842  os << *iter;
843  if (next != mprSet.end ())
844  os << ", ";
845  }
846  os << "]";
847  NS_LOG_DEBUG ("Computed MPR set for node " << m_mainAddress << ": " << os.str ());
848  }
849 #endif //NS3_LOG_ENABLE
850 
851  m_state.SetMprSet (mprSet);
852 }
853 
862 {
863  const IfaceAssocTuple *tuple =
864  m_state.FindIfaceAssocTuple (iface_addr);
865 
866  if (tuple != NULL)
867  return tuple->mainAddr;
868  else
869  return iface_addr;
870 }
871 
875 void
877 {
878  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " s: Node " << m_mainAddress
879  << ": RoutingTableComputation begin...");
880 
881  // 1. All the entries from the routing table are removed.
882  Clear ();
883 
884  // 2. The new routing entries are added starting with the
885  // symmetric neighbors (h=1) as the destination nodes.
886  const NeighborSet &neighborSet = m_state.GetNeighbors ();
887  for (NeighborSet::const_iterator it = neighborSet.begin ();
888  it != neighborSet.end (); it++)
889  {
890  NeighborTuple const &nb_tuple = *it;
891  NS_LOG_DEBUG ("Looking at neighbor tuple: " << nb_tuple);
892  if (nb_tuple.status == NeighborTuple::STATUS_SYM)
893  {
894  bool nb_main_addr = false;
895  const LinkTuple *lt = NULL;
896  const LinkSet &linkSet = m_state.GetLinks ();
897  for (LinkSet::const_iterator it2 = linkSet.begin ();
898  it2 != linkSet.end (); it2++)
899  {
900  LinkTuple const &link_tuple = *it2;
901  NS_LOG_DEBUG ("Looking at link tuple: " << link_tuple
902  << (link_tuple.time >= Simulator::Now () ? "" : " (expired)"));
903  if ((GetMainAddress (link_tuple.neighborIfaceAddr) == nb_tuple.neighborMainAddr)
904  && link_tuple.time >= Simulator::Now ())
905  {
906  NS_LOG_LOGIC ("Link tuple matches neighbor " << nb_tuple.neighborMainAddr
907  << " => adding routing table entry to neighbor");
908  lt = &link_tuple;
909  AddEntry (link_tuple.neighborIfaceAddr,
910  link_tuple.neighborIfaceAddr,
911  link_tuple.localIfaceAddr,
912  1);
913  if (link_tuple.neighborIfaceAddr == nb_tuple.neighborMainAddr)
914  {
915  nb_main_addr = true;
916  }
917  }
918  else
919  {
920  NS_LOG_LOGIC ("Link tuple: linkMainAddress= " << GetMainAddress (link_tuple.neighborIfaceAddr)
921  << "; neighborMainAddr = " << nb_tuple.neighborMainAddr
922  << "; expired=" << int (link_tuple.time < Simulator::Now ())
923  << " => IGNORE");
924  }
925  }
926 
927  // If, in the above, no R_dest_addr is equal to the main
928  // address of the neighbor, then another new routing entry
929  // with MUST be added, with:
930  // R_dest_addr = main address of the neighbor;
931  // R_next_addr = L_neighbor_iface_addr of one of the
932  // associated link tuple with L_time >= current time;
933  // R_dist = 1;
934  // R_iface_addr = L_local_iface_addr of the
935  // associated link tuple.
936  if (!nb_main_addr && lt != NULL)
937  {
938  NS_LOG_LOGIC ("no R_dest_addr is equal to the main address of the neighbor "
939  "=> adding additional routing entry");
940  AddEntry (nb_tuple.neighborMainAddr,
941  lt->neighborIfaceAddr,
942  lt->localIfaceAddr,
943  1);
944  }
945  }
946  }
947 
948  // 3. for each node in N2, i.e., a 2-hop neighbor which is not a
949  // neighbor node or the node itself, and such that there exist at
950  // least one entry in the 2-hop neighbor set where
951  // N_neighbor_main_addr correspond to a neighbor node with
952  // willingness different of WILL_NEVER,
953  const TwoHopNeighborSet &twoHopNeighbors = m_state.GetTwoHopNeighbors ();
954  for (TwoHopNeighborSet::const_iterator it = twoHopNeighbors.begin ();
955  it != twoHopNeighbors.end (); it++)
956  {
957  TwoHopNeighborTuple const &nb2hop_tuple = *it;
958 
959  NS_LOG_LOGIC ("Looking at two-hop neighbor tuple: " << nb2hop_tuple);
960 
961  // a 2-hop neighbor which is not a neighbor node or the node itself
963  {
964  NS_LOG_LOGIC ("Two-hop neighbor tuple is also neighbor; skipped.");
965  continue;
966  }
967 
968  if (nb2hop_tuple.twoHopNeighborAddr == m_mainAddress)
969  {
970  NS_LOG_LOGIC ("Two-hop neighbor is self; skipped.");
971  continue;
972  }
973 
974  // ...and such that there exist at least one entry in the 2-hop
975  // neighbor set where N_neighbor_main_addr correspond to a
976  // neighbor node with willingness different of WILL_NEVER...
977  bool nb2hopOk = false;
978  for (NeighborSet::const_iterator neighbor = neighborSet.begin ();
979  neighbor != neighborSet.end (); neighbor++)
980  {
981  if (neighbor->neighborMainAddr == nb2hop_tuple.neighborMainAddr
982  && neighbor->willingness != OLSR_WILL_NEVER)
983  {
984  nb2hopOk = true;
985  break;
986  }
987  }
988  if (!nb2hopOk)
989  {
990  NS_LOG_LOGIC ("Two-hop neighbor tuple skipped: 2-hop neighbor "
991  << nb2hop_tuple.twoHopNeighborAddr
992  << " is attached to neighbor " << nb2hop_tuple.neighborMainAddr
993  << ", which was not found in the Neighbor Set.");
994  continue;
995  }
996 
997  // one selects one 2-hop tuple and creates one entry in the routing table with:
998  // R_dest_addr = the main address of the 2-hop neighbor;
999  // R_next_addr = the R_next_addr of the entry in the
1000  // routing table with:
1001  // R_dest_addr == N_neighbor_main_addr
1002  // of the 2-hop tuple;
1003  // R_dist = 2;
1004  // R_iface_addr = the R_iface_addr of the entry in the
1005  // routing table with:
1006  // R_dest_addr == N_neighbor_main_addr
1007  // of the 2-hop tuple;
1008  RoutingTableEntry entry;
1009  bool foundEntry = Lookup (nb2hop_tuple.neighborMainAddr, entry);
1010  if (foundEntry)
1011  {
1012  NS_LOG_LOGIC ("Adding routing entry for two-hop neighbor.");
1013  AddEntry (nb2hop_tuple.twoHopNeighborAddr,
1014  entry.nextAddr,
1015  entry.interface,
1016  2);
1017  }
1018  else
1019  {
1020  NS_LOG_LOGIC ("NOT adding routing entry for two-hop neighbor ("
1021  << nb2hop_tuple.twoHopNeighborAddr
1022  << " not found in the routing table)");
1023  }
1024  }
1025 
1026  for (uint32_t h = 2;; h++)
1027  {
1028  bool added = false;
1029 
1030  // 3.1. For each topology entry in the topology table, if its
1031  // T_dest_addr does not correspond to R_dest_addr of any
1032  // route entry in the routing table AND its T_last_addr
1033  // corresponds to R_dest_addr of a route entry whose R_dist
1034  // is equal to h, then a new route entry MUST be recorded in
1035  // the routing table (if it does not already exist)
1036  const TopologySet &topology = m_state.GetTopologySet ();
1037  for (TopologySet::const_iterator it = topology.begin ();
1038  it != topology.end (); it++)
1039  {
1040  const TopologyTuple &topology_tuple = *it;
1041  NS_LOG_LOGIC ("Looking at topology tuple: " << topology_tuple);
1042 
1043  RoutingTableEntry destAddrEntry, lastAddrEntry;
1044  bool have_destAddrEntry = Lookup (topology_tuple.destAddr, destAddrEntry);
1045  bool have_lastAddrEntry = Lookup (topology_tuple.lastAddr, lastAddrEntry);
1046  if (!have_destAddrEntry && have_lastAddrEntry && lastAddrEntry.distance == h)
1047  {
1048  NS_LOG_LOGIC ("Adding routing table entry based on the topology tuple.");
1049  // then a new route entry MUST be recorded in
1050  // the routing table (if it does not already exist) where:
1051  // R_dest_addr = T_dest_addr;
1052  // R_next_addr = R_next_addr of the recorded
1053  // route entry where:
1054  // R_dest_addr == T_last_addr
1055  // R_dist = h+1; and
1056  // R_iface_addr = R_iface_addr of the recorded
1057  // route entry where:
1058  // R_dest_addr == T_last_addr.
1059  AddEntry (topology_tuple.destAddr,
1060  lastAddrEntry.nextAddr,
1061  lastAddrEntry.interface,
1062  h + 1);
1063  added = true;
1064  }
1065  else
1066  {
1067  NS_LOG_LOGIC ("NOT adding routing table entry based on the topology tuple: "
1068  "have_destAddrEntry=" << have_destAddrEntry
1069  << " have_lastAddrEntry=" << have_lastAddrEntry
1070  << " lastAddrEntry.distance=" << (int) lastAddrEntry.distance
1071  << " (h=" << h << ")");
1072  }
1073  }
1074 
1075  if (!added)
1076  break;
1077  }
1078 
1079  // 4. For each entry in the multiple interface association base
1080  // where there exists a routing entry such that:
1081  // R_dest_addr == I_main_addr (of the multiple interface association entry)
1082  // AND there is no routing entry such that:
1083  // R_dest_addr == I_iface_addr
1084  const IfaceAssocSet &ifaceAssocSet = m_state.GetIfaceAssocSet ();
1085  for (IfaceAssocSet::const_iterator it = ifaceAssocSet.begin ();
1086  it != ifaceAssocSet.end (); it++)
1087  {
1088  IfaceAssocTuple const &tuple = *it;
1089  RoutingTableEntry entry1, entry2;
1090  bool have_entry1 = Lookup (tuple.mainAddr, entry1);
1091  bool have_entry2 = Lookup (tuple.ifaceAddr, entry2);
1092  if (have_entry1 && !have_entry2)
1093  {
1094  // then a route entry is created in the routing table with:
1095  // R_dest_addr = I_iface_addr (of the multiple interface
1096  // association entry)
1097  // R_next_addr = R_next_addr (of the recorded route entry)
1098  // R_dist = R_dist (of the recorded route entry)
1099  // R_iface_addr = R_iface_addr (of the recorded route entry).
1100  AddEntry (tuple.ifaceAddr,
1101  entry1.nextAddr,
1102  entry1.interface,
1103  entry1.distance);
1104  }
1105  }
1106 
1107  // 5. For each tuple in the association set,
1108  // If there is no entry in the routing table with:
1109  // R_dest_addr == A_network_addr/A_netmask
1110  // and if the announced network is not announced by the node itself,
1111  // then a new routing entry is created.
1112  const AssociationSet &associationSet = m_state.GetAssociationSet ();
1113 
1114  // Clear HNA routing table
1115  for (uint32_t i = 0; i < m_hnaRoutingTable->GetNRoutes (); i++)
1116  {
1117  m_hnaRoutingTable->RemoveRoute (0);
1118  }
1119 
1120  for (AssociationSet::const_iterator it = associationSet.begin ();
1121  it != associationSet.end (); it++)
1122  {
1123  AssociationTuple const &tuple = *it;
1124 
1125  // Test if HNA associations received from other gateways
1126  // are also announced by this node. In such a case, no route
1127  // is created for this association tuple (go to the next one).
1128  bool goToNextAssociationTuple = false;
1129  const Associations &localHnaAssociations = m_state.GetAssociations ();
1130  NS_LOG_DEBUG ("Nb local associations: " << localHnaAssociations.size ());
1131  for (Associations::const_iterator assocIterator = localHnaAssociations.begin ();
1132  assocIterator != localHnaAssociations.end (); assocIterator++)
1133  {
1134  Association const &localHnaAssoc = *assocIterator;
1135  if (localHnaAssoc.networkAddr == tuple.networkAddr && localHnaAssoc.netmask == tuple.netmask)
1136  {
1137  NS_LOG_DEBUG ("HNA association received from another GW is part of local HNA associations: no route added for network "
1138  << tuple.networkAddr << "/" << tuple.netmask);
1139  goToNextAssociationTuple = true;
1140  }
1141  }
1142  if (goToNextAssociationTuple)
1143  {
1144  continue;
1145  }
1146 
1147  RoutingTableEntry gatewayEntry;
1148 
1149  bool gatewayEntryExists = Lookup (tuple.gatewayAddr, gatewayEntry);
1150  bool addRoute = false;
1151 
1152  uint32_t routeIndex = 0;
1153 
1154  for (routeIndex = 0; routeIndex < m_hnaRoutingTable->GetNRoutes (); routeIndex++)
1155  {
1156  Ipv4RoutingTableEntry route = m_hnaRoutingTable->GetRoute (routeIndex);
1157  if (route.GetDestNetwork () == tuple.networkAddr &&
1158  route.GetDestNetworkMask () == tuple.netmask)
1159  {
1160  break;
1161  }
1162  }
1163 
1164  if (routeIndex == m_hnaRoutingTable->GetNRoutes ())
1165  {
1166  addRoute = true;
1167  }
1168  else if(gatewayEntryExists && m_hnaRoutingTable->GetMetric (routeIndex) > gatewayEntry.distance)
1169  {
1170  m_hnaRoutingTable->RemoveRoute (routeIndex);
1171  addRoute = true;
1172  }
1173 
1174  if(addRoute && gatewayEntryExists)
1175  {
1176  m_hnaRoutingTable->AddNetworkRouteTo (tuple.networkAddr,
1177  tuple.netmask,
1178  gatewayEntry.nextAddr,
1179  gatewayEntry.interface,
1180  gatewayEntry.distance);
1181 
1182  }
1183  }
1184 
1185  NS_LOG_DEBUG ("Node " << m_mainAddress << ": RoutingTableComputation end.");
1187 }
1188 
1189 
1200 void
1202  const Ipv4Address &receiverIface,
1203  const Ipv4Address &senderIface)
1204 {
1205  NS_LOG_FUNCTION (msg << receiverIface << senderIface);
1206 
1207  const olsr::MessageHeader::Hello &hello = msg.GetHello ();
1208 
1209  LinkSensing (msg, hello, receiverIface, senderIface);
1210 
1211 #ifdef NS3_LOG_ENABLE
1212  {
1213  const LinkSet &links = m_state.GetLinks ();
1214  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
1215  << "s ** BEGIN dump Link Set for OLSR Node " << m_mainAddress);
1216  for (LinkSet::const_iterator link = links.begin (); link != links.end (); link++)
1217  {
1218  NS_LOG_DEBUG (*link);
1219  }
1220  NS_LOG_DEBUG ("** END dump Link Set for OLSR Node " << m_mainAddress);
1221 
1222  const NeighborSet &neighbors = m_state.GetNeighbors ();
1223  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
1224  << "s ** BEGIN dump Neighbor Set for OLSR Node " << m_mainAddress);
1225  for (NeighborSet::const_iterator neighbor = neighbors.begin (); neighbor != neighbors.end (); neighbor++)
1226  {
1227  NS_LOG_DEBUG (*neighbor);
1228  }
1229  NS_LOG_DEBUG ("** END dump Neighbor Set for OLSR Node " << m_mainAddress);
1230  }
1231 #endif // NS3_LOG_ENABLE
1232 
1233  PopulateNeighborSet (msg, hello);
1234  PopulateTwoHopNeighborSet (msg, hello);
1235 
1236 #ifdef NS3_LOG_ENABLE
1237  {
1238  const TwoHopNeighborSet &twoHopNeighbors = m_state.GetTwoHopNeighbors ();
1239  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
1240  << "s ** BEGIN dump TwoHopNeighbor Set for OLSR Node " << m_mainAddress);
1241  for (TwoHopNeighborSet::const_iterator tuple = twoHopNeighbors.begin ();
1242  tuple != twoHopNeighbors.end (); tuple++)
1243  {
1244  NS_LOG_DEBUG (*tuple);
1245  }
1246  NS_LOG_DEBUG ("** END dump TwoHopNeighbor Set for OLSR Node " << m_mainAddress);
1247  }
1248 #endif // NS3_LOG_ENABLE
1249 
1250  MprComputation ();
1251  PopulateMprSelectorSet (msg, hello);
1252 }
1253 
1263 void
1265  const Ipv4Address &senderIface)
1266 {
1267  const olsr::MessageHeader::Tc &tc = msg.GetTc ();
1268  Time now = Simulator::Now ();
1269 
1270  // 1. If the sender interface of this message is not in the symmetric
1271  // 1-hop neighborhood of this node, the message MUST be discarded.
1272  const LinkTuple *link_tuple = m_state.FindSymLinkTuple (senderIface, now);
1273  if (link_tuple == NULL)
1274  return;
1275 
1276  // 2. If there exist some tuple in the topology set where:
1277  // T_last_addr == originator address AND
1278  // T_seq > ANSN,
1279  // then further processing of this TC message MUST NOT be
1280  // performed.
1281  const TopologyTuple *topologyTuple =
1283  if (topologyTuple != NULL)
1284  return;
1285 
1286  // 3. All tuples in the topology set where:
1287  // T_last_addr == originator address AND
1288  // T_seq < ANSN
1289  // MUST be removed from the topology set.
1291 
1292  // 4. For each of the advertised neighbor main address received in
1293  // the TC message:
1294  for (std::vector<Ipv4Address>::const_iterator i = tc.neighborAddresses.begin ();
1295  i != tc.neighborAddresses.end (); i++)
1296  {
1297  const Ipv4Address &addr = *i;
1298  // 4.1. If there exist some tuple in the topology set where:
1299  // T_dest_addr == advertised neighbor main address, AND
1300  // T_last_addr == originator address,
1301  // then the holding time of that tuple MUST be set to:
1302  // T_time = current time + validity time.
1303  TopologyTuple *topologyTuple =
1305 
1306  if (topologyTuple != NULL)
1307  {
1308  topologyTuple->expirationTime = now + msg.GetVTime ();
1309  }
1310  else
1311  {
1312  // 4.2. Otherwise, a new tuple MUST be recorded in the topology
1313  // set where:
1314  // T_dest_addr = advertised neighbor main address,
1315  // T_last_addr = originator address,
1316  // T_seq = ANSN,
1317  // T_time = current time + validity time.
1318  TopologyTuple topologyTuple;;
1319  topologyTuple.destAddr = addr;
1320  topologyTuple.lastAddr = msg.GetOriginatorAddress ();
1321  topologyTuple.sequenceNumber = tc.ansn;
1322  topologyTuple.expirationTime = now + msg.GetVTime ();
1323  AddTopologyTuple (topologyTuple);
1324 
1325  // Schedules topology tuple deletion
1328  this,
1329  topologyTuple.destAddr,
1330  topologyTuple.lastAddr));
1331  }
1332  }
1333 
1334 #ifdef NS3_LOG_ENABLE
1335  {
1336  const TopologySet &topology = m_state.GetTopologySet ();
1337  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
1338  << "s ** BEGIN dump TopologySet for OLSR Node " << m_mainAddress);
1339  for (TopologySet::const_iterator tuple = topology.begin ();
1340  tuple != topology.end (); tuple++)
1341  {
1342  NS_LOG_DEBUG (*tuple);
1343  }
1344  NS_LOG_DEBUG ("** END dump TopologySet Set for OLSR Node " << m_mainAddress);
1345  }
1346 #endif // NS3_LOG_ENABLE
1347 }
1348 
1358 void
1360  const Ipv4Address &senderIface)
1361 {
1362  const olsr::MessageHeader::Mid &mid = msg.GetMid ();
1363  Time now = Simulator::Now ();
1364 
1365  NS_LOG_DEBUG ("Node " << m_mainAddress << " ProcessMid from " << senderIface);
1366  // 1. If the sender interface of this message is not in the symmetric
1367  // 1-hop neighborhood of this node, the message MUST be discarded.
1368  const LinkTuple *linkTuple = m_state.FindSymLinkTuple (senderIface, now);
1369  if (linkTuple == NULL)
1370  {
1371  NS_LOG_LOGIC ("Node " << m_mainAddress <<
1372  ": the sender interface of this message is not in the "
1373  "symmetric 1-hop neighborhood of this node,"
1374  " the message MUST be discarded.");
1375  return;
1376  }
1377 
1378  // 2. For each interface address listed in the MID message
1379  for (std::vector<Ipv4Address>::const_iterator i = mid.interfaceAddresses.begin ();
1380  i != mid.interfaceAddresses.end (); i++)
1381  {
1382  bool updated = false;
1384  for (IfaceAssocSet::iterator tuple = ifaceAssoc.begin ();
1385  tuple != ifaceAssoc.end (); tuple++)
1386  {
1387  if (tuple->ifaceAddr == *i
1388  && tuple->mainAddr == msg.GetOriginatorAddress ())
1389  {
1390  NS_LOG_LOGIC ("IfaceAssoc updated: " << *tuple);
1391  tuple->time = now + msg.GetVTime ();
1392  updated = true;
1393  }
1394  }
1395  if (!updated)
1396  {
1397  IfaceAssocTuple tuple;
1398  tuple.ifaceAddr = *i;
1399  tuple.mainAddr = msg.GetOriginatorAddress ();
1400  tuple.time = now + msg.GetVTime ();
1401  AddIfaceAssocTuple (tuple);
1402  NS_LOG_LOGIC ("New IfaceAssoc added: " << tuple);
1403  // Schedules iface association tuple deletion
1404  Simulator::Schedule (DELAY (tuple.time),
1406  }
1407  }
1408 
1409  // 3. (not part of the RFC) iterate over all NeighborTuple's and
1410  // TwoHopNeighborTuples, update the neighbor addresses taking into account
1411  // the new MID information.
1412  NeighborSet &neighbors = m_state.GetNeighbors ();
1413  for (NeighborSet::iterator neighbor = neighbors.begin (); neighbor != neighbors.end (); neighbor++)
1414  {
1415  neighbor->neighborMainAddr = GetMainAddress (neighbor->neighborMainAddr);
1416  }
1417 
1418  TwoHopNeighborSet &twoHopNeighbors = m_state.GetTwoHopNeighbors ();
1419  for (TwoHopNeighborSet::iterator twoHopNeighbor = twoHopNeighbors.begin ();
1420  twoHopNeighbor != twoHopNeighbors.end (); twoHopNeighbor++)
1421  {
1422  twoHopNeighbor->neighborMainAddr = GetMainAddress (twoHopNeighbor->neighborMainAddr);
1423  twoHopNeighbor->twoHopNeighborAddr = GetMainAddress (twoHopNeighbor->twoHopNeighborAddr);
1424  }
1425  NS_LOG_DEBUG ("Node " << m_mainAddress << " ProcessMid from " << senderIface << " -> END.");
1426 }
1427 
1437 void
1439  const Ipv4Address &senderIface)
1440 {
1441 
1442  const olsr::MessageHeader::Hna &hna = msg.GetHna ();
1443  Time now = Simulator::Now ();
1444 
1445  // 1. If the sender interface of this message is not in the symmetric
1446  // 1-hop neighborhood of this node, the message MUST be discarded.
1447  const LinkTuple *link_tuple = m_state.FindSymLinkTuple (senderIface, now);
1448  if (link_tuple == NULL)
1449  return;
1450 
1451  // 2. Otherwise, for each (network address, netmask) pair in the
1452  // message:
1453 
1454  for (std::vector<olsr::MessageHeader::Hna::Association>::const_iterator it = hna.associations.begin ();
1455  it != hna.associations.end (); it++)
1456  {
1457  AssociationTuple *tuple = m_state.FindAssociationTuple (msg.GetOriginatorAddress (),it->address,it->mask);
1458 
1459  // 2.1 if an entry in the association set already exists, where:
1460  // A_gateway_addr == originator address
1461  // A_network_addr == network address
1462  // A_netmask == netmask
1463  // then the holding time for that tuple MUST be set to:
1464  // A_time = current time + validity time
1465  if(tuple != NULL)
1466  {
1467  tuple->expirationTime = now + msg.GetVTime ();
1468  }
1469 
1470  // 2.2 otherwise, a new tuple MUST be recorded with:
1471  // A_gateway_addr = originator address
1472  // A_network_addr = network address
1473  // A_netmask = netmask
1474  // A_time = current time + validity time
1475  else
1476  {
1477  AssociationTuple assocTuple = {
1478  msg.GetOriginatorAddress (),
1479  it->address,
1480  it->mask,
1481  now + msg.GetVTime ()
1482  };
1483  AddAssociationTuple (assocTuple);
1484 
1485  //Schedule Association Tuple deletion
1488  assocTuple.gatewayAddr,assocTuple.networkAddr,assocTuple.netmask);
1489  }
1490 
1491  }
1492 }
1493 
1505 void
1507  DuplicateTuple *duplicated,
1508  const Ipv4Address &localIface,
1509  const Ipv4Address &senderAddress)
1510 {
1511  Time now = Simulator::Now ();
1512 
1513  // If the sender interface address is not in the symmetric
1514  // 1-hop neighborhood the message must not be forwarded
1515  const LinkTuple *linkTuple = m_state.FindSymLinkTuple (senderAddress, now);
1516  if (linkTuple == NULL)
1517  return;
1518 
1519  // If the message has already been considered for forwarding,
1520  // it must not be retransmitted again
1521  if (duplicated != NULL && duplicated->retransmitted)
1522  {
1523  NS_LOG_LOGIC (Simulator::Now () << "Node " << m_mainAddress << " does not forward a message received"
1524  " from " << olsrMessage.GetOriginatorAddress () << " because it is duplicated");
1525  return;
1526  }
1527 
1528  // If the sender interface address is an interface address
1529  // of a MPR selector of this node and ttl is greater than 1,
1530  // the message must be retransmitted
1531  bool retransmitted = false;
1532  if (olsrMessage.GetTimeToLive () > 1)
1533  {
1534  const MprSelectorTuple *mprselTuple =
1535  m_state.FindMprSelectorTuple (GetMainAddress (senderAddress));
1536  if (mprselTuple != NULL)
1537  {
1538  olsrMessage.SetTimeToLive (olsrMessage.GetTimeToLive () - 1);
1539  olsrMessage.SetHopCount (olsrMessage.GetHopCount () + 1);
1540  // We have to introduce a random delay to avoid
1541  // synchronization with neighbors.
1542  QueueMessage (olsrMessage, JITTER);
1543  retransmitted = true;
1544  }
1545  }
1546 
1547  // Update duplicate tuple...
1548  if (duplicated != NULL)
1549  {
1550  duplicated->expirationTime = now + OLSR_DUP_HOLD_TIME;
1551  duplicated->retransmitted = retransmitted;
1552  duplicated->ifaceList.push_back (localIface);
1553  }
1554  // ...or create a new one
1555  else
1556  {
1557  DuplicateTuple newDup;
1558  newDup.address = olsrMessage.GetOriginatorAddress ();
1559  newDup.sequenceNumber = olsrMessage.GetMessageSequenceNumber ();
1560  newDup.expirationTime = now + OLSR_DUP_HOLD_TIME;
1561  newDup.retransmitted = retransmitted;
1562  newDup.ifaceList.push_back (localIface);
1563  AddDuplicateTuple (newDup);
1564  // Schedule dup tuple deletion
1565  Simulator::Schedule (OLSR_DUP_HOLD_TIME,
1567  newDup.address, newDup.sequenceNumber);
1568  }
1569 }
1570 
1580 void
1582 {
1583  m_queuedMessages.push_back (message);
1584  if (not m_queuedMessagesTimer.IsRunning ())
1585  {
1588  }
1589 }
1590 
1591 void
1593  const MessageList &containedMessages)
1594 {
1595  NS_LOG_DEBUG ("OLSR node " << m_mainAddress << " sending a OLSR packet");
1596 
1597  // Add a header
1598  olsr::PacketHeader header;
1599  header.SetPacketLength (header.GetSerializedSize () + packet->GetSize ());
1601  packet->AddHeader (header);
1602 
1603  // Trace it
1604  m_txPacketTrace (header, containedMessages);
1605 
1606  // Send it
1607  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator i =
1608  m_socketAddresses.begin (); i != m_socketAddresses.end (); i++)
1609  {
1610  Ipv4Address bcast = i->second.GetLocal ().GetSubnetDirectedBroadcast (i->second.GetMask ());
1611  i->first->SendTo (packet, 0, InetSocketAddress (bcast, OLSR_PORT_NUMBER));
1612  }
1613 }
1614 
1622 void
1624 {
1625  Ptr<Packet> packet = Create<Packet> ();
1626  int numMessages = 0;
1627 
1628  NS_LOG_DEBUG ("Olsr node " << m_mainAddress << ": SendQueuedMessages");
1629 
1630  MessageList msglist;
1631 
1632  for (std::vector<olsr::MessageHeader>::const_iterator message = m_queuedMessages.begin ();
1633  message != m_queuedMessages.end ();
1634  message++)
1635  {
1636  Ptr<Packet> p = Create<Packet> ();
1637  p->AddHeader (*message);
1638  packet->AddAtEnd (p);
1639  msglist.push_back (*message);
1640  if (++numMessages == OLSR_MAX_MSGS)
1641  {
1642  SendPacket (packet, msglist);
1643  msglist.clear ();
1644  // Reset variables for next packet
1645  numMessages = 0;
1646  packet = Create<Packet> ();
1647  }
1648  }
1649 
1650  if (packet->GetSize ())
1651  {
1652  SendPacket (packet, msglist);
1653  }
1654 
1655  m_queuedMessages.clear ();
1656 }
1657 
1661 void
1663 {
1664  NS_LOG_FUNCTION (this);
1665 
1666  olsr::MessageHeader msg;
1667  Time now = Simulator::Now ();
1668 
1671  msg.SetTimeToLive (1);
1672  msg.SetHopCount (0);
1674  olsr::MessageHeader::Hello &hello = msg.GetHello ();
1675 
1676  hello.SetHTime (m_helloInterval);
1677  hello.willingness = m_willingness;
1678 
1679  std::vector<olsr::MessageHeader::Hello::LinkMessage>
1680  &linkMessages = hello.linkMessages;
1681 
1682  const LinkSet &links = m_state.GetLinks ();
1683  for (LinkSet::const_iterator link_tuple = links.begin ();
1684  link_tuple != links.end (); link_tuple++)
1685  {
1686  if (!(GetMainAddress (link_tuple->localIfaceAddr) == m_mainAddress
1687  && link_tuple->time >= now))
1688  {
1689  continue;
1690  }
1691 
1692  uint8_t link_type, nb_type = 0xff;
1693 
1694  // Establishes link type
1695  if (link_tuple->symTime >= now)
1696  {
1697  link_type = OLSR_SYM_LINK;
1698  }
1699  else if (link_tuple->asymTime >= now)
1700  {
1701  link_type = OLSR_ASYM_LINK;
1702  }
1703  else
1704  {
1705  link_type = OLSR_LOST_LINK;
1706  }
1707  // Establishes neighbor type.
1708  if (m_state.FindMprAddress (GetMainAddress (link_tuple->neighborIfaceAddr)))
1709  {
1710  nb_type = OLSR_MPR_NEIGH;
1711  NS_LOG_DEBUG ("I consider neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr)
1712  << " to be MPR_NEIGH.");
1713  }
1714  else
1715  {
1716  bool ok = false;
1717  for (NeighborSet::const_iterator nb_tuple = m_state.GetNeighbors ().begin ();
1718  nb_tuple != m_state.GetNeighbors ().end ();
1719  nb_tuple++)
1720  {
1721  if (nb_tuple->neighborMainAddr == GetMainAddress (link_tuple->neighborIfaceAddr))
1722  {
1723  if (nb_tuple->status == NeighborTuple::STATUS_SYM)
1724  {
1725  NS_LOG_DEBUG ("I consider neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr)
1726  << " to be SYM_NEIGH.");
1727  nb_type = OLSR_SYM_NEIGH;
1728  }
1729  else if (nb_tuple->status == NeighborTuple::STATUS_NOT_SYM)
1730  {
1731  nb_type = OLSR_NOT_NEIGH;
1732  NS_LOG_DEBUG ("I consider neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr)
1733  << " to be NOT_NEIGH.");
1734  }
1735  else
1736  {
1737  NS_FATAL_ERROR ("There is a neighbor tuple with an unknown status!\n");
1738  }
1739  ok = true;
1740  break;
1741  }
1742  }
1743  if (!ok)
1744  {
1745  NS_LOG_WARN ("I don't know the neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr) << "!!!");
1746  continue;
1747  }
1748  }
1749 
1751  linkMessage.linkCode = (link_type & 0x03) | ((nb_type << 2) & 0x0f);
1752  linkMessage.neighborInterfaceAddresses.push_back
1753  (link_tuple->neighborIfaceAddr);
1754 
1755  std::vector<Ipv4Address> interfaces =
1756  m_state.FindNeighborInterfaces (link_tuple->neighborIfaceAddr);
1757 
1758  linkMessage.neighborInterfaceAddresses.insert
1759  (linkMessage.neighborInterfaceAddresses.end (),
1760  interfaces.begin (), interfaces.end ());
1761 
1762  linkMessages.push_back (linkMessage);
1763  }
1764  NS_LOG_DEBUG ("OLSR HELLO message size: " << int (msg.GetSerializedSize ())
1765  << " (with " << int (linkMessages.size ()) << " link messages)");
1766  QueueMessage (msg, JITTER);
1767 }
1768 
1772 void
1774 {
1775  NS_LOG_FUNCTION (this);
1776 
1777  olsr::MessageHeader msg;
1778 
1781  msg.SetTimeToLive (255);
1782  msg.SetHopCount (0);
1784 
1785  olsr::MessageHeader::Tc &tc = msg.GetTc ();
1786  tc.ansn = m_ansn;
1787 
1788  for (MprSelectorSet::const_iterator mprsel_tuple = m_state.GetMprSelectors ().begin ();
1789  mprsel_tuple != m_state.GetMprSelectors ().end (); mprsel_tuple++)
1790  {
1791  tc.neighborAddresses.push_back (mprsel_tuple->mainAddr);
1792  }
1793  QueueMessage (msg, JITTER);
1794 }
1795 
1799 void
1801 {
1802  olsr::MessageHeader msg;
1803  olsr::MessageHeader::Mid &mid = msg.GetMid ();
1804 
1805  // A node which has only a single interface address participating in
1806  // the MANET (i.e., running OLSR), MUST NOT generate any MID
1807  // message.
1808 
1809  // A node with several interfaces, where only one is participating
1810  // in the MANET and running OLSR (e.g., a node is connected to a
1811  // wired network as well as to a MANET) MUST NOT generate any MID
1812  // messages.
1813 
1814  // A node with several interfaces, where more than one is
1815  // participating in the MANET and running OLSR MUST generate MID
1816  // messages as specified.
1817 
1818  // [ Note: assuming here that all interfaces participate in the
1819  // MANET; later we may want to make this configurable. ]
1820 
1821  Ipv4Address loopback ("127.0.0.1");
1822  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
1823  {
1824  Ipv4Address addr = m_ipv4->GetAddress (i, 0).GetLocal ();
1825  if (addr != m_mainAddress && addr != loopback && m_interfaceExclusions.find (i) == m_interfaceExclusions.end ())
1826  mid.interfaceAddresses.push_back (addr);
1827  }
1828  if (mid.interfaceAddresses.size () == 0)
1829  return;
1830 
1833  msg.SetTimeToLive (255);
1834  msg.SetHopCount (0);
1836 
1837  QueueMessage (msg, JITTER);
1838 }
1839 
1843 void
1845 {
1846 
1847  olsr::MessageHeader msg;
1848 
1851  msg.SetTimeToLive (255);
1852  msg.SetHopCount (0);
1854  olsr::MessageHeader::Hna &hna = msg.GetHna ();
1855 
1856  std::vector<olsr::MessageHeader::Hna::Association> &associations = hna.associations;
1857 
1858  // Add all local HNA associations to the HNA message
1859  const Associations &localHnaAssociations = m_state.GetAssociations ();
1860  for (Associations::const_iterator it = localHnaAssociations.begin ();
1861  it != localHnaAssociations.end (); it++)
1862  {
1863  olsr::MessageHeader::Hna::Association assoc = { it->networkAddr, it->netmask};
1864  associations.push_back (assoc);
1865  }
1866  // If there is no HNA associations to send, return without queuing the message
1867  if (associations.size () == 0)
1868  {
1869  return;
1870  }
1871 
1872  // Else, queue the message to be sent later on
1873  QueueMessage (msg, JITTER);
1874 }
1875 
1881 void
1883 {
1884  // Check if the (networkAddr, netmask) tuple already exist
1885  // in the list of local HNA associations
1886  const Associations &localHnaAssociations = m_state.GetAssociations ();
1887  for (Associations::const_iterator assocIterator = localHnaAssociations.begin ();
1888  assocIterator != localHnaAssociations.end (); assocIterator++)
1889  {
1890  Association const &localHnaAssoc = *assocIterator;
1891  if (localHnaAssoc.networkAddr == networkAddr && localHnaAssoc.netmask == netmask)
1892  {
1893  NS_LOG_INFO ("HNA association for network " << networkAddr << "/" << netmask << " already exists.");
1894  return;
1895  }
1896  }
1897  // If the tuple does not already exist, add it to the list of local HNA associations.
1898  NS_LOG_INFO ("Adding HNA association for network " << networkAddr << "/" << netmask << ".");
1899  m_state.InsertAssociation ( (Association) { networkAddr, netmask} );
1900 }
1901 
1907 void
1909 {
1910  NS_LOG_INFO ("Removing HNA association for network " << networkAddr << "/" << netmask << ".");
1911  m_state.EraseAssociation ( (Association) { networkAddr, netmask} );
1912 }
1913 
1924 void
1926 {
1927  // If a routing table has already been associated, remove
1928  // corresponding entries from the list of local HNA associations
1929  if (m_routingTableAssociation != 0)
1930  {
1931  NS_LOG_INFO ("Removing HNA entries coming from the old routing table association.");
1932  for (uint32_t i = 0; i < m_routingTableAssociation->GetNRoutes (); i++)
1933  {
1934  Ipv4RoutingTableEntry route = m_routingTableAssociation->GetRoute (i);
1935  // If the outgoing interface for this route is a non-olsr interface
1936  if (UsesNonOlsrOutgoingInterface (route))
1937  {
1938  // remove the corresponding entry
1940  }
1941  }
1942  }
1943 
1944  // Sets the routingTableAssociation to its new value
1945  m_routingTableAssociation = routingTable;
1946 
1947  // Iterate over entries of the associated routing table and
1948  // add the routes using non-olsr outgoing interfaces to the list
1949  // of local HNA associations
1950  NS_LOG_DEBUG ("Nb local associations before adding some entries from"
1951  " the associated routing table: " << m_state.GetAssociations ().size ());
1952  for (uint32_t i = 0; i < m_routingTableAssociation->GetNRoutes (); i++)
1953  {
1954  Ipv4RoutingTableEntry route = m_routingTableAssociation->GetRoute (i);
1955  Ipv4Address destNetworkAddress = route.GetDestNetwork ();
1956  Ipv4Mask destNetmask = route.GetDestNetworkMask ();
1957 
1958  // If the outgoing interface for this route is a non-olsr interface,
1959  if (UsesNonOlsrOutgoingInterface (route))
1960  {
1961  // Add this entry's network address and netmask to the list of local HNA entries
1962  AddHostNetworkAssociation (destNetworkAddress, destNetmask);
1963  }
1964  }
1965  NS_LOG_DEBUG ("Nb local associations after having added some entries from "
1966  "the associated routing table: " << m_state.GetAssociations ().size ());
1967 }
1968 
1974 bool
1976 {
1977  std::set<uint32_t>::const_iterator ci = m_interfaceExclusions.find (route.GetInterface ());
1978  // The outgoing interface is a non-OLSR interface if a match is found
1979  // before reaching the end of the list of excluded interfaces
1980  return ci != m_interfaceExclusions.end ();
1981 }
1982 
1986 void
1988  const olsr::MessageHeader::Hello &hello,
1989  const Ipv4Address &receiverIface,
1990  const Ipv4Address &senderIface)
1991 {
1992  Time now = Simulator::Now ();
1993  bool updated = false;
1994  bool created = false;
1995  NS_LOG_DEBUG ("@" << now.GetSeconds () << ": Olsr node " << m_mainAddress
1996  << ": LinkSensing(receiverIface=" << receiverIface
1997  << ", senderIface=" << senderIface << ") BEGIN");
1998 
1999  NS_ASSERT (msg.GetVTime () > Seconds (0));
2000  LinkTuple *link_tuple = m_state.FindLinkTuple (senderIface);
2001  if (link_tuple == NULL)
2002  {
2003  LinkTuple newLinkTuple;
2004  // We have to create a new tuple
2005  newLinkTuple.neighborIfaceAddr = senderIface;
2006  newLinkTuple.localIfaceAddr = receiverIface;
2007  newLinkTuple.symTime = now - Seconds (1);
2008  newLinkTuple.time = now + msg.GetVTime ();
2009  link_tuple = &m_state.InsertLinkTuple (newLinkTuple);
2010  created = true;
2011  NS_LOG_LOGIC ("Existing link tuple did not exist => creating new one");
2012  }
2013  else
2014  {
2015  NS_LOG_LOGIC ("Existing link tuple already exists => will update it");
2016  updated = true;
2017  }
2018 
2019  link_tuple->asymTime = now + msg.GetVTime ();
2020  for (std::vector<olsr::MessageHeader::Hello::LinkMessage>::const_iterator linkMessage =
2021  hello.linkMessages.begin ();
2022  linkMessage != hello.linkMessages.end ();
2023  linkMessage++)
2024  {
2025  int lt = linkMessage->linkCode & 0x03; // Link Type
2026  int nt = (linkMessage->linkCode >> 2) & 0x03; // Neighbor Type
2027 
2028 #ifdef NS3_LOG_ENABLE
2029  const char *linkTypeName;
2030  switch (lt)
2031  {
2032  case OLSR_UNSPEC_LINK: linkTypeName = "UNSPEC_LINK"; break;
2033  case OLSR_ASYM_LINK: linkTypeName = "ASYM_LINK"; break;
2034  case OLSR_SYM_LINK: linkTypeName = "SYM_LINK"; break;
2035  case OLSR_LOST_LINK: linkTypeName = "LOST_LINK"; break;
2036  /* no default, since lt must be in 0..3, covered above
2037  default: linkTypeName = "(invalid value!)";
2038  */
2039  }
2040 
2041  const char *neighborTypeName;
2042  switch (nt)
2043  {
2044  case OLSR_NOT_NEIGH: neighborTypeName = "NOT_NEIGH"; break;
2045  case OLSR_SYM_NEIGH: neighborTypeName = "SYM_NEIGH"; break;
2046  case OLSR_MPR_NEIGH: neighborTypeName = "MPR_NEIGH"; break;
2047  default: neighborTypeName = "(invalid value!)";
2048  }
2049 
2050  NS_LOG_DEBUG ("Looking at HELLO link messages with Link Type "
2051  << lt << " (" << linkTypeName
2052  << ") and Neighbor Type " << nt
2053  << " (" << neighborTypeName << ")");
2054 #endif // NS3_LOG_ENABLE
2055 
2056  // We must not process invalid advertised links
2057  if ((lt == OLSR_SYM_LINK && nt == OLSR_NOT_NEIGH) ||
2058  (nt != OLSR_SYM_NEIGH && nt != OLSR_MPR_NEIGH
2059  && nt != OLSR_NOT_NEIGH))
2060  {
2061  NS_LOG_LOGIC ("HELLO link code is invalid => IGNORING");
2062  continue;
2063  }
2064 
2065  for (std::vector<Ipv4Address>::const_iterator neighIfaceAddr =
2066  linkMessage->neighborInterfaceAddresses.begin ();
2067  neighIfaceAddr != linkMessage->neighborInterfaceAddresses.end ();
2068  neighIfaceAddr++)
2069  {
2070  NS_LOG_DEBUG (" -> Neighbor: " << *neighIfaceAddr);
2071  if (*neighIfaceAddr == receiverIface)
2072  {
2073  if (lt == OLSR_LOST_LINK)
2074  {
2075  NS_LOG_LOGIC ("link is LOST => expiring it");
2076  link_tuple->symTime = now - Seconds (1);
2077  updated = true;
2078  }
2079  else if (lt == OLSR_SYM_LINK || lt == OLSR_ASYM_LINK)
2080  {
2081  NS_LOG_DEBUG (*link_tuple << ": link is SYM or ASYM => should become SYM now"
2082  " (symTime being increased to " << now + msg.GetVTime ());
2083  link_tuple->symTime = now + msg.GetVTime ();
2084  link_tuple->time = link_tuple->symTime + OLSR_NEIGHB_HOLD_TIME;
2085  updated = true;
2086  }
2087  else
2088  {
2089  NS_FATAL_ERROR ("bad link type");
2090  }
2091  break;
2092  }
2093  else
2094  {
2095  NS_LOG_DEBUG (" \\-> *neighIfaceAddr (" << *neighIfaceAddr
2096  << " != receiverIface (" << receiverIface << ") => IGNORING!");
2097  }
2098  }
2099  NS_LOG_DEBUG ("Link tuple updated: " << int (updated));
2100  }
2101  link_tuple->time = std::max (link_tuple->time, link_tuple->asymTime);
2102 
2103  if (updated)
2104  {
2105  LinkTupleUpdated (*link_tuple, hello.willingness);
2106  }
2107 
2108  // Schedules link tuple deletion
2109  if (created)
2110  {
2111  LinkTupleAdded (*link_tuple, hello.willingness);
2112  m_events.Track (Simulator::Schedule (DELAY (std::min (link_tuple->time, link_tuple->symTime)),
2114  link_tuple->neighborIfaceAddr));
2115  }
2116  NS_LOG_DEBUG ("@" << now.GetSeconds () << ": Olsr node " << m_mainAddress
2117  << ": LinkSensing END");
2118 }
2119 
2123 void
2125  const olsr::MessageHeader::Hello &hello)
2126 {
2128  if (nb_tuple != NULL)
2129  {
2130  nb_tuple->willingness = hello.willingness;
2131  }
2132 }
2133 
2134 
2138 void
2140  const olsr::MessageHeader::Hello &hello)
2141 {
2142  Time now = Simulator::Now ();
2143 
2144  NS_LOG_DEBUG ("Olsr node " << m_mainAddress << ": PopulateTwoHopNeighborSet BEGIN");
2145 
2146  for (LinkSet::const_iterator link_tuple = m_state.GetLinks ().begin ();
2147  link_tuple != m_state.GetLinks ().end (); link_tuple++)
2148  {
2149  NS_LOG_LOGIC ("Looking at link tuple: " << *link_tuple);
2150  if (GetMainAddress (link_tuple->neighborIfaceAddr) != msg.GetOriginatorAddress ())
2151  {
2152  NS_LOG_LOGIC ("Link tuple ignored: "
2153  "GetMainAddress (link_tuple->neighborIfaceAddr) != msg.GetOriginatorAddress ()");
2154  NS_LOG_LOGIC ("(GetMainAddress(" << link_tuple->neighborIfaceAddr << "): "
2155  << GetMainAddress (link_tuple->neighborIfaceAddr)
2156  << "; msg.GetOriginatorAddress (): " << msg.GetOriginatorAddress ());
2157  continue;
2158  }
2159 
2160  if (link_tuple->symTime < now)
2161  {
2162  NS_LOG_LOGIC ("Link tuple ignored: expired.");
2163  continue;
2164  }
2165 
2166  typedef std::vector<olsr::MessageHeader::Hello::LinkMessage> LinkMessageVec;
2167  for (LinkMessageVec::const_iterator linkMessage = hello.linkMessages.begin ();
2168  linkMessage != hello.linkMessages.end (); linkMessage++)
2169  {
2170  int neighborType = (linkMessage->linkCode >> 2) & 0x3;
2171 #ifdef NS3_LOG_ENABLE
2172  const char *neighborTypeNames[3] = { "NOT_NEIGH", "SYM_NEIGH", "MPR_NEIGH" };
2173  const char *neighborTypeName = ((neighborType < 3) ?
2174  neighborTypeNames[neighborType]
2175  : "(invalid value)");
2176  NS_LOG_DEBUG ("Looking at Link Message from HELLO message: neighborType="
2177  << neighborType << " (" << neighborTypeName << ")");
2178 #endif // NS3_LOG_ENABLE
2179 
2180  for (std::vector<Ipv4Address>::const_iterator nb2hop_addr_iter =
2181  linkMessage->neighborInterfaceAddresses.begin ();
2182  nb2hop_addr_iter != linkMessage->neighborInterfaceAddresses.end ();
2183  nb2hop_addr_iter++)
2184  {
2185  Ipv4Address nb2hop_addr = GetMainAddress (*nb2hop_addr_iter);
2186  NS_LOG_DEBUG ("Looking at 2-hop neighbor address from HELLO message: "
2187  << *nb2hop_addr_iter
2188  << " (main address is " << nb2hop_addr << ")");
2189  if (neighborType == OLSR_SYM_NEIGH || neighborType == OLSR_MPR_NEIGH)
2190  {
2191  // If the main address of the 2-hop neighbor address == main address
2192  // of the receiving node, silently discard the 2-hop
2193  // neighbor address.
2194  if (nb2hop_addr == m_mainAddress)
2195  {
2196  NS_LOG_LOGIC ("Ignoring 2-hop neighbor (it is the node itself)");
2197  continue;
2198  }
2199 
2200  // Otherwise, a 2-hop tuple is created
2201  TwoHopNeighborTuple *nb2hop_tuple =
2203  NS_LOG_LOGIC ("Adding the 2-hop neighbor"
2204  << (nb2hop_tuple ? " (refreshing existing entry)" : ""));
2205  if (nb2hop_tuple == NULL)
2206  {
2207  TwoHopNeighborTuple new_nb2hop_tuple;
2208  new_nb2hop_tuple.neighborMainAddr = msg.GetOriginatorAddress ();
2209  new_nb2hop_tuple.twoHopNeighborAddr = nb2hop_addr;
2210  new_nb2hop_tuple.expirationTime = now + msg.GetVTime ();
2211  AddTwoHopNeighborTuple (new_nb2hop_tuple);
2212  // Schedules nb2hop tuple deletion
2213  m_events.Track (Simulator::Schedule (DELAY (new_nb2hop_tuple.expirationTime),
2215  new_nb2hop_tuple.neighborMainAddr,
2216  new_nb2hop_tuple.twoHopNeighborAddr));
2217  }
2218  else
2219  {
2220  nb2hop_tuple->expirationTime = now + msg.GetVTime ();
2221  }
2222  }
2223  else if (neighborType == OLSR_NOT_NEIGH)
2224  {
2225  // For each 2-hop node listed in the HELLO message
2226  // with Neighbor Type equal to NOT_NEIGH all 2-hop
2227  // tuples where: N_neighbor_main_addr == Originator
2228  // Address AND N_2hop_addr == main address of the
2229  // 2-hop neighbor are deleted.
2230  NS_LOG_LOGIC ("2-hop neighbor is NOT_NEIGH => deleting matching 2-hop neighbor state");
2232  }
2233  else
2234  {
2235  NS_LOG_LOGIC ("*** WARNING *** Ignoring link message (inside HELLO) with bad"
2236  " neighbor type value: " << neighborType);
2237  }
2238  }
2239  }
2240  }
2241 
2242  NS_LOG_DEBUG ("Olsr node " << m_mainAddress << ": PopulateTwoHopNeighborSet END");
2243 }
2244 
2245 
2246 
2250 void
2252  const olsr::MessageHeader::Hello &hello)
2253 {
2254  NS_LOG_FUNCTION (this);
2255 
2256  Time now = Simulator::Now ();
2257 
2258  typedef std::vector<olsr::MessageHeader::Hello::LinkMessage> LinkMessageVec;
2259  for (LinkMessageVec::const_iterator linkMessage = hello.linkMessages.begin ();
2260  linkMessage != hello.linkMessages.end ();
2261  linkMessage++)
2262  {
2263  int nt = linkMessage->linkCode >> 2;
2264  if (nt == OLSR_MPR_NEIGH)
2265  {
2266  NS_LOG_DEBUG ("Processing a link message with neighbor type MPR_NEIGH");
2267 
2268  for (std::vector<Ipv4Address>::const_iterator nb_iface_addr =
2269  linkMessage->neighborInterfaceAddresses.begin ();
2270  nb_iface_addr != linkMessage->neighborInterfaceAddresses.end ();
2271  nb_iface_addr++)
2272  {
2273  if (GetMainAddress (*nb_iface_addr) == m_mainAddress)
2274  {
2275  NS_LOG_DEBUG ("Adding entry to mpr selector set for neighbor " << *nb_iface_addr);
2276 
2277  // We must create a new entry into the mpr selector set
2278  MprSelectorTuple *existing_mprsel_tuple =
2280  if (existing_mprsel_tuple == NULL)
2281  {
2282  MprSelectorTuple mprsel_tuple;
2283 
2284  mprsel_tuple.mainAddr = msg.GetOriginatorAddress ();
2285  mprsel_tuple.expirationTime = now + msg.GetVTime ();
2286  AddMprSelectorTuple (mprsel_tuple);
2287 
2288  // Schedules mpr selector tuple deletion
2290  (DELAY (mprsel_tuple.expirationTime),
2292  mprsel_tuple.mainAddr));
2293  }
2294  else
2295  {
2296  existing_mprsel_tuple->expirationTime = now + msg.GetVTime ();
2297  }
2298  }
2299  }
2300  }
2301  }
2302  NS_LOG_DEBUG ("Computed MPR selector set for node " << m_mainAddress << ": " << m_state.PrintMprSelectorSet ());
2303 }
2304 
2305 
2306 #if 0
2307 void
2315 OLSR::mac_failed (Ptr<Packet> p) {
2316  double now = Simulator::Now ();
2317  struct hdr_ip* ih = HDR_IP (p);
2318  struct hdr_cmn* ch = HDR_CMN (p);
2319 
2320  debug ("%f: Node %d MAC Layer detects a breakage on link to %d\n",
2321  now,
2322  OLSR::node_id (ra_addr ()),
2323  OLSR::node_id (ch->next_hop ()));
2324 
2325  if ((u_int32_t)ih->daddr () == IP_BROADCAST) {
2326  drop (p, DROP_RTR_MAC_CALLBACK);
2327  return;
2328  }
2329 
2330  OLSR_link_tuple* link_tuple = state_.find_link_tuple (ch->next_hop ());
2331  if (link_tuple != NULL) {
2332  link_tuple->lost_time () = now + OLSR_NEIGHB_HOLD_TIME;
2333  link_tuple->time () = now + OLSR_NEIGHB_HOLD_TIME;
2334  nb_loss (link_tuple);
2335  }
2336  drop (p, DROP_RTR_MAC_CALLBACK);
2337 }
2338 #endif
2339 
2340 
2341 
2342 
2350 void
2352 {
2353  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
2354  << "s: OLSR Node " << m_mainAddress
2355  << " LinkTuple " << tuple.neighborIfaceAddr << " -> neighbor loss.");
2359 
2360  MprComputation ();
2362 }
2363 
2369 void
2371 {
2372  /*debug("%f: Node %d adds dup tuple: addr = %d seq_num = %d\n",
2373  Simulator::Now (),
2374  OLSR::node_id(ra_addr()),
2375  OLSR::node_id(tuple->addr()),
2376  tuple->seq_num());*/
2377  m_state.InsertDuplicateTuple (tuple);
2378 }
2379 
2385 void
2387 {
2388  /*debug("%f: Node %d removes dup tuple: addr = %d seq_num = %d\n",
2389  Simulator::Now (),
2390  OLSR::node_id(ra_addr()),
2391  OLSR::node_id(tuple->addr()),
2392  tuple->seq_num());*/
2393  m_state.EraseDuplicateTuple (tuple);
2394 }
2395 
2396 void
2397 RoutingProtocol::LinkTupleAdded (const LinkTuple &tuple, uint8_t willingness)
2398 {
2399  // Creates associated neighbor tuple
2400  NeighborTuple nb_tuple;
2402  nb_tuple.willingness = willingness;
2403 
2404  if (tuple.symTime >= Simulator::Now ())
2405  {
2406  nb_tuple.status = NeighborTuple::STATUS_SYM;
2407  }
2408  else
2409  {
2411  }
2412 
2413  AddNeighborTuple (nb_tuple);
2414 }
2415 
2421 void
2423 {
2424  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
2425  << "s: OLSR Node " << m_mainAddress
2426  << " LinkTuple " << tuple << " REMOVED.");
2427 
2428  m_state.EraseLinkTuple (tuple);
2430 
2431 }
2432 
2439 void
2440 RoutingProtocol::LinkTupleUpdated (const LinkTuple &tuple, uint8_t willingness)
2441 {
2442  // Each time a link tuple changes, the associated neighbor tuple must be recomputed
2443 
2444  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
2445  << "s: OLSR Node " << m_mainAddress
2446  << " LinkTuple " << tuple << " UPDATED.");
2447 
2448  NeighborTuple *nb_tuple =
2450 
2451  if (nb_tuple == NULL)
2452  {
2453  LinkTupleAdded (tuple, willingness);
2455  }
2456 
2457  if (nb_tuple != NULL)
2458  {
2459  int statusBefore = nb_tuple->status;
2460 
2461  bool hasSymmetricLink = false;
2462 
2463  const LinkSet &linkSet = m_state.GetLinks ();
2464  for (LinkSet::const_iterator it = linkSet.begin ();
2465  it != linkSet.end (); it++)
2466  {
2467  const LinkTuple &link_tuple = *it;
2468  if (GetMainAddress (link_tuple.neighborIfaceAddr) == nb_tuple->neighborMainAddr
2469  && link_tuple.symTime >= Simulator::Now ())
2470  {
2471  hasSymmetricLink = true;
2472  break;
2473  }
2474  }
2475 
2476  if (hasSymmetricLink)
2477  {
2478  nb_tuple->status = NeighborTuple::STATUS_SYM;
2479  NS_LOG_DEBUG (*nb_tuple << "->status = STATUS_SYM; changed:"
2480  << int (statusBefore != nb_tuple->status));
2481  }
2482  else
2483  {
2485  NS_LOG_DEBUG (*nb_tuple << "->status = STATUS_NOT_SYM; changed:"
2486  << int (statusBefore != nb_tuple->status));
2487  }
2488  }
2489  else
2490  {
2491  NS_LOG_WARN ("ERROR! Wanted to update a NeighborTuple but none was found!");
2492  }
2493 }
2494 
2500 void
2502 {
2503 // debug("%f: Node %d adds neighbor tuple: nb_addr = %d status = %s\n",
2504 // Simulator::Now (),
2505 // OLSR::node_id(ra_addr()),
2506 // OLSR::node_id(tuple->neighborMainAddr),
2507 // ((tuple->status() == OLSR_STATUS_SYM) ? "sym" : "not_sym"));
2508 
2509  m_state.InsertNeighborTuple (tuple);
2510  IncrementAnsn ();
2511 }
2512 
2518 void
2520 {
2521 // debug("%f: Node %d removes neighbor tuple: nb_addr = %d status = %s\n",
2522 // Simulator::Now (),
2523 // OLSR::node_id(ra_addr()),
2524 // OLSR::node_id(tuple->neighborMainAddr),
2525 // ((tuple->status() == OLSR_STATUS_SYM) ? "sym" : "not_sym"));
2526 
2527  m_state.EraseNeighborTuple (tuple);
2528  IncrementAnsn ();
2529 }
2530 
2536 void
2538 {
2539 // debug("%f: Node %d adds 2-hop neighbor tuple: nb_addr = %d nb2hop_addr = %d\n",
2540 // Simulator::Now (),
2541 // OLSR::node_id(ra_addr()),
2542 // OLSR::node_id(tuple->neighborMainAddr),
2543 // OLSR::node_id(tuple->twoHopNeighborAddr));
2544 
2546 }
2547 
2553 void
2555 {
2556 // debug("%f: Node %d removes 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 
2565 void
2567 {
2568  m_ansn = (m_ansn + 1) % (OLSR_MAX_SEQ_NUM + 1);
2569 }
2570 
2578 void
2580 {
2581 // debug("%f: Node %d adds MPR selector tuple: nb_addr = %d\n",
2582 // Simulator::Now (),
2583 // OLSR::node_id(ra_addr()),
2584 // OLSR::node_id(tuple->main_addr()));
2585 
2587  IncrementAnsn ();
2588 }
2589 
2597 void
2599 {
2600 // debug("%f: Node %d removes MPR selector tuple: nb_addr = %d\n",
2601 // Simulator::Now (),
2602 // OLSR::node_id(ra_addr()),
2603 // OLSR::node_id(tuple->main_addr()));
2604 
2606  IncrementAnsn ();
2607 }
2608 
2614 void
2616 {
2617 // debug("%f: Node %d adds topology tuple: dest_addr = %d last_addr = %d seq = %d\n",
2618 // Simulator::Now (),
2619 // OLSR::node_id(ra_addr()),
2620 // OLSR::node_id(tuple->dest_addr()),
2621 // OLSR::node_id(tuple->last_addr()),
2622 // tuple->seq());
2623 
2624  m_state.InsertTopologyTuple (tuple);
2625 }
2626 
2632 void
2634 {
2635 // debug("%f: Node %d removes topology tuple: dest_addr = %d last_addr = %d seq = %d\n",
2636 // Simulator::Now (),
2637 // OLSR::node_id(ra_addr()),
2638 // OLSR::node_id(tuple->dest_addr()),
2639 // OLSR::node_id(tuple->last_addr()),
2640 // tuple->seq());
2641 
2642  m_state.EraseTopologyTuple (tuple);
2643 }
2644 
2650 void
2652 {
2653 // debug("%f: Node %d adds iface association tuple: main_addr = %d iface_addr = %d\n",
2654 // Simulator::Now (),
2655 // OLSR::node_id(ra_addr()),
2656 // OLSR::node_id(tuple->main_addr()),
2657 // OLSR::node_id(tuple->iface_addr()));
2658 
2660 }
2661 
2667 void
2669 {
2670 // debug("%f: Node %d removes 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 
2676  m_state.EraseIfaceAssocTuple (tuple);
2677 }
2678 
2684 void
2686 {
2688 }
2689 
2695 void
2697 {
2699 }
2700 
2701 
2702 
2704 {
2706  return m_packetSequenceNumber;
2707 }
2708 
2711 {
2713  return m_messageSequenceNumber;
2714 }
2715 
2716 
2721 void
2723 {
2724  SendHello ();
2726 }
2727 
2732 void
2734 {
2735  if (m_state.GetMprSelectors ().size () > 0)
2736  {
2737  SendTc ();
2738  }
2739  else
2740  {
2741  NS_LOG_DEBUG ("Not sending any TC, no one selected me as MPR.");
2742  }
2744 }
2745 
2750 void
2752 {
2753  SendMid ();
2755 }
2756 
2760 void
2762 {
2763  if (m_state.GetAssociations ().size () > 0)
2764  {
2765  SendHna ();
2766  }
2767  else
2768  {
2769  NS_LOG_DEBUG ("Not sending any HNA, no associations to advertise.");
2770  }
2772 }
2773 
2781 void
2783 {
2784  DuplicateTuple *tuple =
2785  m_state.FindDuplicateTuple (address, sequenceNumber);
2786  if (tuple == NULL)
2787  {
2788  return;
2789  }
2790  if (tuple->expirationTime < Simulator::Now ())
2791  {
2792  RemoveDuplicateTuple (*tuple);
2793  }
2794  else
2795  {
2798  address, sequenceNumber));
2799  }
2800 }
2801 
2813 void
2815 {
2816  Time now = Simulator::Now ();
2817 
2818  // the tuple parameter may be a stale copy; get a newer version from m_state
2819  LinkTuple *tuple = m_state.FindLinkTuple (neighborIfaceAddr);
2820  if (tuple == NULL)
2821  {
2822  return;
2823  }
2824  if (tuple->time < now)
2825  {
2826  RemoveLinkTuple (*tuple);
2827  }
2828  else if (tuple->symTime < now)
2829  {
2831  m_linkTupleTimerFirstTime = false;
2832  else
2833  NeighborLoss (*tuple);
2834 
2837  neighborIfaceAddr));
2838  }
2839  else
2840  {
2841  m_events.Track (Simulator::Schedule (DELAY (std::min (tuple->time, tuple->symTime)),
2843  neighborIfaceAddr));
2844  }
2845 }
2846 
2854 void
2856 {
2857  TwoHopNeighborTuple *tuple;
2858  tuple = m_state.FindTwoHopNeighborTuple (neighborMainAddr, twoHopNeighborAddr);
2859  if (tuple == NULL)
2860  {
2861  return;
2862  }
2863  if (tuple->expirationTime < Simulator::Now ())
2864  {
2865  RemoveTwoHopNeighborTuple (*tuple);
2866  }
2867  else
2868  {
2871  this, neighborMainAddr, twoHopNeighborAddr));
2872  }
2873 }
2874 
2882 void
2884 {
2885  MprSelectorTuple *tuple = m_state.FindMprSelectorTuple (mainAddr);
2886  if (tuple == NULL)
2887  {
2888  return;
2889  }
2890  if (tuple->expirationTime < Simulator::Now ())
2891  {
2892  RemoveMprSelectorTuple (*tuple);
2893  }
2894  else
2895  {
2898  this, mainAddr));
2899  }
2900 }
2901 
2909 void
2911 {
2912  TopologyTuple *tuple = m_state.FindTopologyTuple (destAddr, lastAddr);
2913  if (tuple == NULL)
2914  {
2915  return;
2916  }
2917  if (tuple->expirationTime < Simulator::Now ())
2918  {
2919  RemoveTopologyTuple (*tuple);
2920  }
2921  else
2922  {
2925  this, tuple->destAddr, tuple->lastAddr));
2926  }
2927 }
2928 
2933 void
2935 {
2936  IfaceAssocTuple *tuple = m_state.FindIfaceAssocTuple (ifaceAddr);
2937  if (tuple == NULL)
2938  {
2939  return;
2940  }
2941  if (tuple->time < Simulator::Now ())
2942  {
2943  RemoveIfaceAssocTuple (*tuple);
2944  }
2945  else
2946  {
2949  this, ifaceAddr));
2950  }
2951 }
2952 
2956 void
2958 {
2959  AssociationTuple *tuple = m_state.FindAssociationTuple (gatewayAddr, networkAddr, netmask);
2960  if (tuple == NULL)
2961  {
2962  return;
2963  }
2964  if (tuple->expirationTime < Simulator::Now ())
2965  {
2966  RemoveAssociationTuple (*tuple);
2967  }
2968  else
2969  {
2972  this, gatewayAddr, networkAddr, netmask));
2973  }
2974 }
2975 
2979 void
2981 {
2983  m_table.clear ();
2984 }
2985 
2990 void
2992 {
2993  m_table.erase (dest);
2994 }
2995 
3002 bool
3004  RoutingTableEntry &outEntry) const
3005 {
3006  // Get the iterator at "dest" position
3007  std::map<Ipv4Address, RoutingTableEntry>::const_iterator it =
3008  m_table.find (dest);
3009  // If there is no route to "dest", return NULL
3010  if (it == m_table.end ())
3011  return false;
3012  outEntry = it->second;
3013  return true;
3014 }
3015 
3032 bool
3034  RoutingTableEntry &outEntry) const
3035 {
3036  outEntry = entry;
3037  while (outEntry.destAddr != outEntry.nextAddr)
3038  {
3039  if (not Lookup (outEntry.nextAddr, outEntry))
3040  return false;
3041  }
3042  return true;
3043 }
3044 
3047 {
3048  NS_LOG_FUNCTION (this << " " << m_ipv4->GetObject<Node> ()->GetId () << " " << header.GetDestination () << " " << oif);
3049  Ptr<Ipv4Route> rtentry;
3050  RoutingTableEntry entry1, entry2;
3051  bool found = false;
3052 
3053  if (Lookup (header.GetDestination (), entry1) != 0)
3054  {
3055  bool foundSendEntry = FindSendEntry (entry1, entry2);
3056  if (!foundSendEntry)
3057  {
3058  NS_FATAL_ERROR ("FindSendEntry failure");
3059  }
3060  uint32_t interfaceIdx = entry2.interface;
3061  if (oif && m_ipv4->GetInterfaceForDevice (oif) != static_cast<int> (interfaceIdx))
3062  {
3063  // We do not attempt to perform a constrained routing search
3064  // if the caller specifies the oif; we just enforce that
3065  // that the found route matches the requested outbound interface
3066  NS_LOG_DEBUG ("Olsr node " << m_mainAddress
3067  << ": RouteOutput for dest=" << header.GetDestination ()
3068  << " Route interface " << interfaceIdx
3069  << " does not match requested output interface "
3070  << m_ipv4->GetInterfaceForDevice (oif));
3071  sockerr = Socket::ERROR_NOROUTETOHOST;
3072  return rtentry;
3073  }
3074  rtentry = Create<Ipv4Route> ();
3075  rtentry->SetDestination (header.GetDestination ());
3076  // the source address is the interface address that matches
3077  // the destination address (when multiple are present on the
3078  // outgoing interface, one is selected via scoping rules)
3079  NS_ASSERT (m_ipv4);
3080  uint32_t numOifAddresses = m_ipv4->GetNAddresses (interfaceIdx);
3081  NS_ASSERT (numOifAddresses > 0);
3082  Ipv4InterfaceAddress ifAddr;
3083  if (numOifAddresses == 1) {
3084  ifAddr = m_ipv4->GetAddress (interfaceIdx, 0);
3085  } else {
3087  NS_FATAL_ERROR ("XXX Not implemented yet: IP aliasing and OLSR");
3088  }
3089  rtentry->SetSource (ifAddr.GetLocal ());
3090  rtentry->SetGateway (entry2.nextAddr);
3091  rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIdx));
3092  sockerr = Socket::ERROR_NOTERROR;
3093  NS_LOG_DEBUG ("Olsr node " << m_mainAddress
3094  << ": RouteOutput for dest=" << header.GetDestination ()
3095  << " --> nextHop=" << entry2.nextAddr
3096  << " interface=" << entry2.interface);
3097  NS_LOG_DEBUG ("Found route to " << rtentry->GetDestination () << " via nh " << rtentry->GetGateway () << " with source addr " << rtentry->GetSource () << " and output dev " << rtentry->GetOutputDevice ());
3098  found = true;
3099  }
3100  else
3101  {
3102  rtentry = m_hnaRoutingTable->RouteOutput (p, header, oif, sockerr);
3103 
3104  if (rtentry)
3105  {
3106  found = true;
3107  NS_LOG_DEBUG ("Found route to " << rtentry->GetDestination () << " via nh " << rtentry->GetGateway () << " with source addr " << rtentry->GetSource () << " and output dev " << rtentry->GetOutputDevice ());
3108  }
3109  }
3110 
3111  if (!found)
3112  {
3113  NS_LOG_DEBUG ("Olsr node " << m_mainAddress
3114  << ": RouteOutput for dest=" << header.GetDestination ()
3115  << " No route to host");
3116  sockerr = Socket::ERROR_NOROUTETOHOST;
3117  }
3118  return rtentry;
3119 }
3120 
3122  const Ipv4Header &header, Ptr<const NetDevice> idev,
3125 {
3126  NS_LOG_FUNCTION (this << " " << m_ipv4->GetObject<Node> ()->GetId () << " " << header.GetDestination ());
3127 
3128  Ipv4Address dst = header.GetDestination ();
3129  Ipv4Address origin = header.GetSource ();
3130 
3131  // Consume self-originated packets
3132  if (IsMyOwnAddress (origin) == true)
3133  {
3134  return true;
3135  }
3136 
3137  // Local delivery
3138  NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
3139  uint32_t iif = m_ipv4->GetInterfaceForDevice (idev);
3140  if (m_ipv4->IsDestinationAddress (dst, iif))
3141  {
3142  if (!lcb.IsNull ())
3143  {
3144  NS_LOG_LOGIC ("Local delivery to " << dst);
3145  lcb (p, header, iif);
3146  return true;
3147  }
3148  else
3149  {
3150  // The local delivery callback is null. This may be a multicast
3151  // or broadcast packet, so return false so that another
3152  // multicast routing protocol can handle it. It should be possible
3153  // to extend this to explicitly check whether it is a unicast
3154  // packet, and invoke the error callback if so
3155  return false;
3156  }
3157  }
3158 
3159  // Forwarding
3160  Ptr<Ipv4Route> rtentry;
3161  RoutingTableEntry entry1, entry2;
3162  if (Lookup (header.GetDestination (), entry1))
3163  {
3164  bool foundSendEntry = FindSendEntry (entry1, entry2);
3165  if (!foundSendEntry)
3166  NS_FATAL_ERROR ("FindSendEntry failure");
3167  rtentry = Create<Ipv4Route> ();
3168  rtentry->SetDestination (header.GetDestination ());
3169  uint32_t interfaceIdx = entry2.interface;
3170  // the source address is the interface address that matches
3171  // the destination address (when multiple are present on the
3172  // outgoing interface, one is selected via scoping rules)
3173  NS_ASSERT (m_ipv4);
3174  uint32_t numOifAddresses = m_ipv4->GetNAddresses (interfaceIdx);
3175  NS_ASSERT (numOifAddresses > 0);
3176  Ipv4InterfaceAddress ifAddr;
3177  if (numOifAddresses == 1) {
3178  ifAddr = m_ipv4->GetAddress (interfaceIdx, 0);
3179  } else {
3181  NS_FATAL_ERROR ("XXX Not implemented yet: IP aliasing and OLSR");
3182  }
3183  rtentry->SetSource (ifAddr.GetLocal ());
3184  rtentry->SetGateway (entry2.nextAddr);
3185  rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIdx));
3186 
3187  NS_LOG_DEBUG ("Olsr node " << m_mainAddress
3188  << ": RouteInput for dest=" << header.GetDestination ()
3189  << " --> nextHop=" << entry2.nextAddr
3190  << " interface=" << entry2.interface);
3191 
3192  ucb (rtentry, p, header);
3193  return true;
3194  }
3195  else
3196  {
3197  if(m_hnaRoutingTable->RouteInput (p, header, idev, ucb, mcb, lcb, ecb))
3198  {
3199  return true;
3200  }
3201  else
3202  {
3203 
3204 #ifdef NS3_LOG_ENABLE
3205  NS_LOG_DEBUG ("Olsr node " << m_mainAddress
3206  << ": RouteInput for dest=" << header.GetDestination ()
3207  << " --> NOT FOUND; ** Dumping routing table...");
3208 
3209  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin ();
3210  iter != m_table.end (); iter++)
3211  {
3212  NS_LOG_DEBUG ("dest=" << iter->first << " --> next=" << iter->second.nextAddr
3213  << " via interface " << iter->second.interface);
3214  }
3215 
3216  NS_LOG_DEBUG ("** Routing table dump end.");
3217 #endif // NS3_LOG_ENABLE
3218 
3219  return false;
3220  }
3221  }
3222 }
3223 void
3225 {}
3226 void
3228 {}
3229 void
3231 {}
3232 void
3234 {}
3235 
3236 
3247 void
3249  Ipv4Address const &next,
3250  uint32_t interface,
3251  uint32_t distance)
3252 {
3253  NS_LOG_FUNCTION (this << dest << next << interface << distance << m_mainAddress);
3254 
3255  NS_ASSERT (distance > 0);
3256 
3257  // Creates a new rt entry with specified values
3258  RoutingTableEntry &entry = m_table[dest];
3259 
3260  entry.destAddr = dest;
3261  entry.nextAddr = next;
3262  entry.interface = interface;
3263  entry.distance = distance;
3264 }
3265 
3266 void
3268  Ipv4Address const &next,
3269  Ipv4Address const &interfaceAddress,
3270  uint32_t distance)
3271 {
3272  NS_LOG_FUNCTION (this << dest << next << interfaceAddress << distance << m_mainAddress);
3273 
3274  NS_ASSERT (distance > 0);
3275  NS_ASSERT (m_ipv4);
3276 
3277  RoutingTableEntry entry;
3278  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
3279  {
3280  for (uint32_t j = 0; j < m_ipv4->GetNAddresses (i); j++)
3281  {
3282  if (m_ipv4->GetAddress (i,j).GetLocal () == interfaceAddress)
3283  {
3284  AddEntry (dest, next, i, distance);
3285  return;
3286  }
3287  }
3288  }
3289  NS_ASSERT (false); // should not be reached
3290  AddEntry (dest, next, 0, distance);
3291 }
3292 
3293 
3294 std::vector<RoutingTableEntry>
3296 {
3297  std::vector<RoutingTableEntry> retval;
3298  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin ();
3299  iter != m_table.end (); iter++)
3300  {
3301  retval.push_back (iter->second);
3302  }
3303  return retval;
3304 }
3305 
3306 int64_t
3308 {
3309  NS_LOG_FUNCTION (this << stream);
3311  return 1;
3312 }
3313 
3314 bool
3316 {
3317  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
3318  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
3319  {
3320  Ipv4InterfaceAddress iface = j->second;
3321  if (a == iface.GetLocal ())
3322  {
3323  return true;
3324  }
3325  }
3326  return false;
3327 }
3328 
3329 void
3331 {
3332 #ifdef NS3_LOG_ENABLE
3333  Time now = Simulator::Now ();
3334  NS_LOG_DEBUG ("Dumping for node with main address " << m_mainAddress);
3335  NS_LOG_DEBUG (" Neighbor set");
3336  for (NeighborSet::const_iterator iter = m_state.GetNeighbors ().begin ();
3337  iter != m_state.GetNeighbors ().end (); iter++)
3338  {
3339  NS_LOG_DEBUG (" " << *iter);
3340  }
3341  NS_LOG_DEBUG (" Two-hop neighbor set");
3342  for (TwoHopNeighborSet::const_iterator iter = m_state.GetTwoHopNeighbors ().begin ();
3343  iter != m_state.GetTwoHopNeighbors ().end (); iter++)
3344  {
3345  if (now < iter->expirationTime)
3346  {
3347  NS_LOG_DEBUG (" " << *iter);
3348  }
3349  }
3350  NS_LOG_DEBUG (" Routing table");
3351  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin (); iter != m_table.end (); iter++)
3352  {
3353  NS_LOG_DEBUG (" dest=" << iter->first << " --> next=" << iter->second.nextAddr << " via interface " << iter->second.interface);
3354  }
3355  NS_LOG_DEBUG ("");
3356 #endif //NS3_LOG_ENABLE
3357 }
3358 
3361 {
3362  return m_hnaRoutingTable;
3363 }
3364 
3365 } // namespace olsr
3366 } // namespace ns3
3367 
3368 
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:79
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:60
void DoDispose()
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
#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.
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)
Definition: enum.cc:178
TwoHopNeighborTuple * FindTwoHopNeighborTuple(const Ipv4Address &neighbor, const Ipv4Address &twoHopNeighbor)
Definition: olsr-state.cc:190
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:924
#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:45
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register the class in the ns-3 factory.
Definition: object-base.h:38
#define OLSR_DUP_HOLD_TIME
Dup holding time.
void EraseMprSelectorTuples(const Ipv4Address &mainAddr)
Definition: olsr-state.cc:64
Doxygen 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:125
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:222
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.
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:1018
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:61
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:170
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:744
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...
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Definition: object.cc:335
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:223
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:95
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
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
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Schedule an event to expire at the relative time "time" is reached.
Definition: simulator.h:825
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.
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
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:86
LinkTuple * FindLinkTuple(const Ipv4Address &ifaceAddr)
Definition: olsr-state.cc:318
bool IsRunning(void) const
Definition: timer.cc:121
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.
#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
Definition: nstime.h:272
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
Definition: packet.cc:317
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:37
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].
hold objects of type ns3::Time
Definition: nstime.h:1008
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:152
const AssociationSet & GetAssociationSet() const
Definition: olsr-state.h:152
void SetGateway(Ipv4Address gw)
Definition: ipv4-route.cc:63
void SetFunction(FN fn)
Definition: timer.h:254
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:40
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:1242
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:127
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:70
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:69
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:233
#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.
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.
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
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.
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
void EraseAssociationTuple(const AssociationTuple &tuple)
Definition: olsr-state.cc:507
static Time Now(void)
Return the "current simulation time".
Definition: simulator.cc:180
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)
Doxygen introspection did not find any typical Config paths.
Definition: olsr-header.h:69
uint16_t m_packetSequenceNumber
Packets sequence number counter.
Ptr< const AttributeAccessor > MakeEnumAccessor(T1 a1)
Definition: enum.h:118
virtual void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
Definition: socket.cc:329
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.
#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:38
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
uint32_t GetId(void) const
Definition: node.cc:106
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:203
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
A network Node.
Definition: node.h:55
std::set< Ipv4Address > MprSet
MPR Set type.
#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:213
const LinkSet & GetLinks() const
Definition: olsr-state.h:114
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:664
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.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:441
void Dump(void)
Dump the neighbor table, two-hop neighbor table, and routing table to logging output (NS_LOG_DEBUG lo...
uint16_t GetPort(void) const
Ipv4Address neighborMainAddr
Main address of a neighbor.
virtual void DoInitialize(void)
This method is called only once by Object::Initialize.
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:183
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:49
An Interface Association Tuple.
bool retransmitted
Indicates whether the message has been retransmitted or not.
TypeId SetParent(TypeId tid)
Definition: type-id.cc:610
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:253
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.