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