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