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