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