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