|
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ |
|
2 /* |
|
3 * Copyright (c) 2004 Francisco J. Ros |
|
4 * Copyright (c) 2007 INESC Porto |
|
5 * |
|
6 * This program is free software; you can redistribute it and/or modify |
|
7 * it under the terms of the GNU General Public License version 2 as |
|
8 * published by the Free Software Foundation; |
|
9 * |
|
10 * This program is distributed in the hope that it will be useful, |
|
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
13 * GNU General Public License for more details. |
|
14 * |
|
15 * You should have received a copy of the GNU General Public License |
|
16 * along with this program; if not, write to the Free Software |
|
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
18 * |
|
19 * Authors: Francisco J. Ros <fjrm@dif.um.es> |
|
20 * Gustavo J. A. M. Carneiro <gjc@inescporto.pt> |
|
21 */ |
|
22 |
|
23 |
|
24 /// |
|
25 /// \file OLSR.cc |
|
26 /// \brief Implementation of OLSR agent and related classes. |
|
27 /// |
|
28 /// This is the main file of this software because %OLSR's behaviour is |
|
29 /// implemented here. |
|
30 /// |
|
31 |
|
32 #define NS_LOG_APPEND_CONTEXT \ |
|
33 if (GetObject<Node> ()) { std::clog << "[node " << GetObject<Node> ()->GetId () << "] "; } |
|
34 |
|
35 |
|
36 #include "olsr-routing-protocol.h" |
|
37 #include "ns3/socket-factory.h" |
|
38 #include "ns3/udp-socket-factory.h" |
|
39 #include "ns3/simulator.h" |
|
40 #include "ns3/log.h" |
|
41 #include "ns3/random-variable.h" |
|
42 #include "ns3/inet-socket-address.h" |
|
43 #include "ns3/boolean.h" |
|
44 #include "ns3/uinteger.h" |
|
45 #include "ns3/enum.h" |
|
46 #include "ns3/trace-source-accessor.h" |
|
47 #include "ns3/ipv4-header.h" |
|
48 |
|
49 /********** Useful macros **********/ |
|
50 |
|
51 /// |
|
52 /// \brief Gets the delay between a given time and the current time. |
|
53 /// |
|
54 /// If given time is previous to the current one, then this macro returns |
|
55 /// a number close to 0. This is used for scheduling events at a certain moment. |
|
56 /// |
|
57 #define DELAY(time) (((time) < (Simulator::Now ())) ? Seconds (0.000001) : \ |
|
58 (time - Simulator::Now () + Seconds (0.000001))) |
|
59 |
|
60 |
|
61 |
|
62 /// |
|
63 /// \brief Period at which a node must cite every link and every neighbor. |
|
64 /// |
|
65 /// We only use this value in order to define OLSR_NEIGHB_HOLD_TIME. |
|
66 /// |
|
67 #define OLSR_REFRESH_INTERVAL Seconds (2) |
|
68 |
|
69 |
|
70 /********** Holding times **********/ |
|
71 |
|
72 /// Neighbor holding time. |
|
73 #define OLSR_NEIGHB_HOLD_TIME (Scalar (3) * OLSR_REFRESH_INTERVAL) |
|
74 /// Top holding time. |
|
75 #define OLSR_TOP_HOLD_TIME (Scalar (3) * m_tcInterval) |
|
76 /// Dup holding time. |
|
77 #define OLSR_DUP_HOLD_TIME Seconds (30) |
|
78 /// MID holding time. |
|
79 #define OLSR_MID_HOLD_TIME (Scalar (3) * m_midInterval) |
|
80 |
|
81 |
|
82 /********** Link types **********/ |
|
83 |
|
84 /// Unspecified link type. |
|
85 #define OLSR_UNSPEC_LINK 0 |
|
86 /// Asymmetric link type. |
|
87 #define OLSR_ASYM_LINK 1 |
|
88 /// Symmetric link type. |
|
89 #define OLSR_SYM_LINK 2 |
|
90 /// Lost link type. |
|
91 #define OLSR_LOST_LINK 3 |
|
92 |
|
93 /********** Neighbor types **********/ |
|
94 |
|
95 /// Not neighbor type. |
|
96 #define OLSR_NOT_NEIGH 0 |
|
97 /// Symmetric neighbor type. |
|
98 #define OLSR_SYM_NEIGH 1 |
|
99 /// Asymmetric neighbor type. |
|
100 #define OLSR_MPR_NEIGH 2 |
|
101 |
|
102 |
|
103 /********** Willingness **********/ |
|
104 |
|
105 /// Willingness for forwarding packets from other nodes: never. |
|
106 #define OLSR_WILL_NEVER 0 |
|
107 /// Willingness for forwarding packets from other nodes: low. |
|
108 #define OLSR_WILL_LOW 1 |
|
109 /// Willingness for forwarding packets from other nodes: medium. |
|
110 #define OLSR_WILL_DEFAULT 3 |
|
111 /// Willingness for forwarding packets from other nodes: high. |
|
112 #define OLSR_WILL_HIGH 6 |
|
113 /// Willingness for forwarding packets from other nodes: always. |
|
114 #define OLSR_WILL_ALWAYS 7 |
|
115 |
|
116 |
|
117 /********** Miscellaneous constants **********/ |
|
118 |
|
119 /// Maximum allowed jitter. |
|
120 #define OLSR_MAXJITTER (m_helloInterval.GetSeconds () / 4) |
|
121 /// Maximum allowed sequence number. |
|
122 #define OLSR_MAX_SEQ_NUM 65535 |
|
123 /// Random number between [0-OLSR_MAXJITTER] used to jitter OLSR packet transmission. |
|
124 #define JITTER (Seconds (UniformVariable().GetValue (0, OLSR_MAXJITTER))) |
|
125 |
|
126 |
|
127 #define OLSR_PORT_NUMBER 698 |
|
128 /// Maximum number of messages per packet. |
|
129 #define OLSR_MAX_MSGS 64 |
|
130 |
|
131 /// Maximum number of hellos per message (4 possible link types * 3 possible nb types). |
|
132 #define OLSR_MAX_HELLOS 12 |
|
133 |
|
134 /// Maximum number of addresses advertised on a message. |
|
135 #define OLSR_MAX_ADDRS 64 |
|
136 |
|
137 |
|
138 namespace ns3 { |
|
139 namespace olsr { |
|
140 |
|
141 NS_LOG_COMPONENT_DEFINE ("OlsrAgent"); |
|
142 |
|
143 |
|
144 /********** OLSR class **********/ |
|
145 |
|
146 NS_OBJECT_ENSURE_REGISTERED (RoutingProtocol); |
|
147 |
|
148 TypeId |
|
149 RoutingProtocol::GetTypeId (void) |
|
150 { |
|
151 static TypeId tid = TypeId ("ns3::olsr::RoutingProtocol") |
|
152 .SetParent<Ipv4RoutingProtocol> () |
|
153 .AddConstructor<RoutingProtocol> () |
|
154 .AddAttribute ("HelloInterval", "HELLO messages emission interval.", |
|
155 TimeValue (Seconds (2)), |
|
156 MakeTimeAccessor (&RoutingProtocol::m_helloInterval), |
|
157 MakeTimeChecker ()) |
|
158 .AddAttribute ("TcInterval", "TC messages emission interval.", |
|
159 TimeValue (Seconds (5)), |
|
160 MakeTimeAccessor (&RoutingProtocol::m_tcInterval), |
|
161 MakeTimeChecker ()) |
|
162 .AddAttribute ("MidInterval", "MID messages emission interval. Normally it is equal to TcInterval.", |
|
163 TimeValue (Seconds (5)), |
|
164 MakeTimeAccessor (&RoutingProtocol::m_midInterval), |
|
165 MakeTimeChecker ()) |
|
166 .AddAttribute ("Willingness", "Willingness of a node to carry and forward traffic for other nodes.", |
|
167 EnumValue (OLSR_WILL_DEFAULT), |
|
168 MakeEnumAccessor (&RoutingProtocol::m_willingness), |
|
169 MakeEnumChecker (OLSR_WILL_NEVER, "never", |
|
170 OLSR_WILL_LOW, "low", |
|
171 OLSR_WILL_DEFAULT, "default", |
|
172 OLSR_WILL_HIGH, "high", |
|
173 OLSR_WILL_ALWAYS, "always")) |
|
174 .AddTraceSource ("Rx", "Receive OLSR packet.", |
|
175 MakeTraceSourceAccessor (&RoutingProtocol::m_rxPacketTrace)) |
|
176 .AddTraceSource ("Tx", "Send OLSR packet.", |
|
177 MakeTraceSourceAccessor (&RoutingProtocol::m_txPacketTrace)) |
|
178 .AddTraceSource ("RoutingTableChanged", "The OLSR routing table has changed.", |
|
179 MakeTraceSourceAccessor (&RoutingProtocol::m_routingTableChanged)) |
|
180 ; |
|
181 return tid; |
|
182 } |
|
183 |
|
184 |
|
185 RoutingProtocol::RoutingProtocol () |
|
186 : |
|
187 m_helloTimer (Timer::CANCEL_ON_DESTROY), |
|
188 m_tcTimer (Timer::CANCEL_ON_DESTROY), |
|
189 m_midTimer (Timer::CANCEL_ON_DESTROY) |
|
190 {} |
|
191 |
|
192 RoutingProtocol::~RoutingProtocol () |
|
193 {} |
|
194 |
|
195 void |
|
196 RoutingProtocol::SetNode (Ptr<Node> node) |
|
197 { |
|
198 NS_LOG_DEBUG ("Created olsr::RoutingProtocol"); |
|
199 m_helloTimer.SetFunction (&RoutingProtocol::HelloTimerExpire, this); |
|
200 m_tcTimer.SetFunction (&RoutingProtocol::TcTimerExpire, this); |
|
201 m_midTimer.SetFunction (&RoutingProtocol::MidTimerExpire, this); |
|
202 m_queuedMessagesTimer.SetFunction (&RoutingProtocol::SendQueuedMessages, this); |
|
203 |
|
204 m_packetSequenceNumber = OLSR_MAX_SEQ_NUM; |
|
205 m_messageSequenceNumber = OLSR_MAX_SEQ_NUM; |
|
206 m_ansn = OLSR_MAX_SEQ_NUM; |
|
207 |
|
208 m_linkTupleTimerFirstTime = true; |
|
209 |
|
210 m_ipv4 = node->GetObject<Ipv4> (); |
|
211 NS_ASSERT (m_ipv4); |
|
212 } |
|
213 |
|
214 void RoutingProtocol::DoDispose () |
|
215 { |
|
216 m_ipv4 = 0; |
|
217 |
|
218 for (std::map< Ptr<Socket>, Ipv4Address >::iterator iter = m_socketAddresses.begin (); |
|
219 iter != m_socketAddresses.end (); iter++) |
|
220 { |
|
221 iter->first->Close (); |
|
222 } |
|
223 m_socketAddresses.clear (); |
|
224 |
|
225 Ipv4RoutingProtocol::DoDispose (); |
|
226 } |
|
227 |
|
228 void RoutingProtocol::Start () |
|
229 { |
|
230 if (m_mainAddress == Ipv4Address ()) |
|
231 { |
|
232 Ipv4Address loopback ("127.0.0.1"); |
|
233 for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++) |
|
234 { |
|
235 Ipv4Address addr = m_ipv4->GetAddress (i); |
|
236 if (addr != loopback) |
|
237 { |
|
238 m_mainAddress = addr; |
|
239 break; |
|
240 } |
|
241 } |
|
242 |
|
243 NS_ASSERT (m_mainAddress != Ipv4Address ()); |
|
244 } |
|
245 |
|
246 NS_LOG_DEBUG ("Starting OLSR on node " << m_mainAddress); |
|
247 |
|
248 Ipv4Address loopback ("127.0.0.1"); |
|
249 for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++) |
|
250 { |
|
251 Ipv4Address addr = m_ipv4->GetAddress (i); |
|
252 if (addr == loopback) |
|
253 continue; |
|
254 |
|
255 if (addr != m_mainAddress) |
|
256 { |
|
257 // Create never expiring interface association tuple entries for our |
|
258 // own network interfaces, so that GetMainAddress () works to |
|
259 // translate the node's own interface addresses into the main address. |
|
260 IfaceAssocTuple tuple; |
|
261 tuple.ifaceAddr = addr; |
|
262 tuple.mainAddr = m_mainAddress; |
|
263 AddIfaceAssocTuple (tuple); |
|
264 NS_ASSERT (GetMainAddress (addr) == m_mainAddress); |
|
265 } |
|
266 |
|
267 // Create a socket to listen only on this interface |
|
268 Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (), |
|
269 UdpSocketFactory::GetTypeId()); |
|
270 socket->SetRecvCallback (MakeCallback (&RoutingProtocol::RecvOlsr, this)); |
|
271 if (socket->Bind (InetSocketAddress (addr, OLSR_PORT_NUMBER))) |
|
272 { |
|
273 NS_FATAL_ERROR ("Failed to bind() OLSR receive socket"); |
|
274 } |
|
275 socket->Connect (InetSocketAddress (Ipv4Address (0xffffffff), OLSR_PORT_NUMBER)); |
|
276 m_socketAddresses[socket] = addr; |
|
277 } |
|
278 |
|
279 HelloTimerExpire (); |
|
280 TcTimerExpire (); |
|
281 MidTimerExpire (); |
|
282 |
|
283 NS_LOG_DEBUG ("OLSR on node " << m_mainAddress << " started"); |
|
284 } |
|
285 |
|
286 void RoutingProtocol::SetMainInterface (uint32_t interface) |
|
287 { |
|
288 m_mainAddress = m_ipv4->GetAddress (interface); |
|
289 } |
|
290 |
|
291 |
|
292 // |
|
293 // \brief Processes an incoming %OLSR packet following RFC 3626 specification. |
|
294 void |
|
295 RoutingProtocol::RecvOlsr (Ptr<Socket> socket) |
|
296 { |
|
297 Ptr<Packet> receivedPacket; |
|
298 Address sourceAddress; |
|
299 receivedPacket = socket->RecvFrom (sourceAddress); |
|
300 |
|
301 InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom (sourceAddress); |
|
302 Ipv4Address senderIfaceAddr = inetSourceAddr.GetIpv4 (); |
|
303 Ipv4Address receiverIfaceAddr = m_socketAddresses[socket]; |
|
304 NS_ASSERT (receiverIfaceAddr != Ipv4Address ()); |
|
305 NS_LOG_DEBUG ("OLSR node " << m_mainAddress << " received a OLSR packet from " |
|
306 << senderIfaceAddr << " to " << receiverIfaceAddr); |
|
307 |
|
308 // All routing messages are sent from and to port RT_PORT, |
|
309 // so we check it. |
|
310 NS_ASSERT (inetSourceAddr.GetPort () == OLSR_PORT_NUMBER); |
|
311 |
|
312 Ptr<Packet> packet = receivedPacket; |
|
313 |
|
314 olsr::PacketHeader olsrPacketHeader; |
|
315 packet->RemoveHeader (olsrPacketHeader); |
|
316 NS_ASSERT (olsrPacketHeader.GetPacketLength () >= olsrPacketHeader.GetSerializedSize ()); |
|
317 uint32_t sizeLeft = olsrPacketHeader.GetPacketLength () - olsrPacketHeader.GetSerializedSize (); |
|
318 |
|
319 MessageList messages; |
|
320 |
|
321 while (sizeLeft) |
|
322 { |
|
323 MessageHeader messageHeader; |
|
324 if (packet->RemoveHeader (messageHeader) == 0) |
|
325 NS_ASSERT (false); |
|
326 |
|
327 sizeLeft -= messageHeader.GetSerializedSize (); |
|
328 |
|
329 NS_LOG_DEBUG ("Olsr Msg received with type " |
|
330 << std::dec << int (messageHeader.GetMessageType ()) |
|
331 << " TTL=" << int (messageHeader.GetTimeToLive ()) |
|
332 << " origAddr=" << messageHeader.GetOriginatorAddress ()); |
|
333 messages.push_back (messageHeader); |
|
334 } |
|
335 |
|
336 m_rxPacketTrace (olsrPacketHeader, messages); |
|
337 |
|
338 for (MessageList::const_iterator messageIter = messages.begin (); |
|
339 messageIter != messages.end (); messageIter++) |
|
340 { |
|
341 const MessageHeader &messageHeader = *messageIter; |
|
342 // If ttl is less than or equal to zero, or |
|
343 // the receiver is the same as the originator, |
|
344 // the message must be silently dropped |
|
345 if (messageHeader.GetTimeToLive () == 0 |
|
346 || messageHeader.GetOriginatorAddress () == m_mainAddress) |
|
347 { |
|
348 packet->RemoveAtStart (messageHeader.GetSerializedSize () |
|
349 - messageHeader.GetSerializedSize ()); |
|
350 continue; |
|
351 } |
|
352 |
|
353 // If the message has been processed it must not be processed again |
|
354 bool do_forwarding = true; |
|
355 DuplicateTuple *duplicated = m_state.FindDuplicateTuple |
|
356 (messageHeader.GetOriginatorAddress (), |
|
357 messageHeader.GetMessageSequenceNumber ()); |
|
358 |
|
359 // Get main address of the peer, which may be different from the packet source address |
|
360 // const IfaceAssocTuple *ifaceAssoc = m_state.FindIfaceAssocTuple (inetSourceAddr.GetIpv4 ()); |
|
361 // Ipv4Address peerMainAddress; |
|
362 // if (ifaceAssoc != NULL) |
|
363 // { |
|
364 // peerMainAddress = ifaceAssoc->mainAddr; |
|
365 // } |
|
366 // else |
|
367 // { |
|
368 // peerMainAddress = inetSourceAddr.GetIpv4 () ; |
|
369 // } |
|
370 |
|
371 if (duplicated == NULL) |
|
372 { |
|
373 switch (messageHeader.GetMessageType ()) |
|
374 { |
|
375 case olsr::MessageHeader::HELLO_MESSAGE: |
|
376 NS_LOG_DEBUG (Simulator::Now ().GetSeconds () |
|
377 << "s OLSR node " << m_mainAddress |
|
378 << " received HELLO message of size " << messageHeader.GetSerializedSize ()); |
|
379 ProcessHello (messageHeader, receiverIfaceAddr, senderIfaceAddr); |
|
380 break; |
|
381 |
|
382 case olsr::MessageHeader::TC_MESSAGE: |
|
383 NS_LOG_DEBUG (Simulator::Now ().GetSeconds () |
|
384 << "s OLSR node " << m_mainAddress |
|
385 << " received TC message of size " << messageHeader.GetSerializedSize ()); |
|
386 ProcessTc (messageHeader, senderIfaceAddr); |
|
387 break; |
|
388 |
|
389 case olsr::MessageHeader::MID_MESSAGE: |
|
390 NS_LOG_DEBUG (Simulator::Now ().GetSeconds () |
|
391 << "s OLSR node " << m_mainAddress |
|
392 << " received MID message of size " << messageHeader.GetSerializedSize ()); |
|
393 ProcessMid (messageHeader, senderIfaceAddr); |
|
394 break; |
|
395 |
|
396 default: |
|
397 NS_LOG_DEBUG ("OLSR message type " << |
|
398 int (messageHeader.GetMessageType ()) << |
|
399 " not implemented"); |
|
400 } |
|
401 } |
|
402 else |
|
403 { |
|
404 NS_LOG_DEBUG ("OLSR message is duplicated, not reading it."); |
|
405 |
|
406 // If the message has been considered for forwarding, it should |
|
407 // not be retransmitted again |
|
408 for (std::vector<Ipv4Address>::const_iterator it = duplicated->ifaceList.begin (); |
|
409 it != duplicated->ifaceList.end(); it++) |
|
410 { |
|
411 if (*it == receiverIfaceAddr) |
|
412 { |
|
413 do_forwarding = false; |
|
414 break; |
|
415 } |
|
416 } |
|
417 } |
|
418 |
|
419 if (do_forwarding) |
|
420 { |
|
421 // HELLO messages are never forwarded. |
|
422 // TC and MID messages are forwarded using the default algorithm. |
|
423 // Remaining messages are also forwarded using the default algorithm. |
|
424 if (messageHeader.GetMessageType () != olsr::MessageHeader::HELLO_MESSAGE) |
|
425 { |
|
426 ForwardDefault (messageHeader, duplicated, |
|
427 receiverIfaceAddr, inetSourceAddr.GetIpv4 ()); |
|
428 } |
|
429 } |
|
430 |
|
431 } |
|
432 |
|
433 // After processing all OLSR messages, we must recompute the routing table |
|
434 RoutingTableComputation (); |
|
435 } |
|
436 |
|
437 /// |
|
438 /// \brief This auxiliary function (defined in RFC 3626) is used for calculating the MPR Set. |
|
439 /// |
|
440 /// \param tuple the neighbor tuple which has the main address of the node we are going to calculate its degree to. |
|
441 /// \return the degree of the node. |
|
442 /// |
|
443 int |
|
444 RoutingProtocol::Degree (NeighborTuple const &tuple) |
|
445 { |
|
446 int degree = 0; |
|
447 for (TwoHopNeighborSet::const_iterator it = m_state.GetTwoHopNeighbors ().begin (); |
|
448 it != m_state.GetTwoHopNeighbors ().end (); it++) |
|
449 { |
|
450 TwoHopNeighborTuple const &nb2hop_tuple = *it; |
|
451 if (nb2hop_tuple.neighborMainAddr == tuple.neighborMainAddr) |
|
452 { |
|
453 const NeighborTuple *nb_tuple = |
|
454 m_state.FindNeighborTuple (nb2hop_tuple.neighborMainAddr); |
|
455 if (nb_tuple == NULL) |
|
456 degree++; |
|
457 } |
|
458 } |
|
459 return degree; |
|
460 } |
|
461 |
|
462 /// |
|
463 /// \brief Computates MPR set of a node following RFC 3626 hints. |
|
464 /// |
|
465 void |
|
466 RoutingProtocol::MprComputation() |
|
467 { |
|
468 NS_LOG_FUNCTION (this); |
|
469 |
|
470 // MPR computation should be done for each interface. See section 8.3.1 |
|
471 // (RFC 3626) for details. |
|
472 MprSet mprSet; |
|
473 |
|
474 |
|
475 // N is the subset of neighbors of the node, which are |
|
476 // neighbor "of the interface I" |
|
477 NeighborSet N; |
|
478 for (NeighborSet::const_iterator neighbor = m_state.GetNeighbors ().begin(); |
|
479 neighbor != m_state.GetNeighbors ().end (); neighbor++) |
|
480 { |
|
481 if (neighbor->status == NeighborTuple::STATUS_SYM) // I think that we need this check |
|
482 { |
|
483 N.push_back (*neighbor); |
|
484 } |
|
485 } |
|
486 |
|
487 // N2 is the set of 2-hop neighbors reachable from "the interface |
|
488 // I", excluding: |
|
489 // (i) the nodes only reachable by members of N with willingness WILL_NEVER |
|
490 // (ii) the node performing the computation |
|
491 // (iii) all the symmetric neighbors: the nodes for which there exists a symmetric |
|
492 // link to this node on some interface. |
|
493 TwoHopNeighborSet N2; |
|
494 for (TwoHopNeighborSet::const_iterator twoHopNeigh = m_state.GetTwoHopNeighbors ().begin (); |
|
495 twoHopNeigh != m_state.GetTwoHopNeighbors ().end (); twoHopNeigh++) |
|
496 { |
|
497 // excluding: |
|
498 // (ii) the node performing the computation |
|
499 if (twoHopNeigh->twoHopNeighborAddr == m_mainAddress) |
|
500 { |
|
501 continue; |
|
502 } |
|
503 |
|
504 // excluding: |
|
505 // (i) the nodes only reachable by members of N with willingness WILL_NEVER |
|
506 bool ok = false; |
|
507 for (NeighborSet::const_iterator neigh = N.begin (); |
|
508 neigh != N.end (); neigh++) |
|
509 { |
|
510 if (neigh->neighborMainAddr == twoHopNeigh->neighborMainAddr) |
|
511 { |
|
512 if (neigh->willingness == OLSR_WILL_NEVER) |
|
513 { |
|
514 ok = false; |
|
515 break; |
|
516 } |
|
517 else |
|
518 { |
|
519 ok = true; |
|
520 break; |
|
521 } |
|
522 } |
|
523 } |
|
524 if (!ok) |
|
525 { |
|
526 continue; |
|
527 } |
|
528 |
|
529 // excluding: |
|
530 // (iii) all the symmetric neighbors: the nodes for which there exists a symmetric |
|
531 // link to this node on some interface. |
|
532 for (NeighborSet::const_iterator neigh = N.begin (); |
|
533 neigh != N.end (); neigh++) |
|
534 { |
|
535 if (neigh->neighborMainAddr == twoHopNeigh->twoHopNeighborAddr) |
|
536 { |
|
537 ok = false; |
|
538 break; |
|
539 } |
|
540 } |
|
541 |
|
542 if (ok) |
|
543 { |
|
544 N2.push_back (*twoHopNeigh); |
|
545 } |
|
546 } |
|
547 |
|
548 NS_LOG_DEBUG ("Size of N2: " << N2.size ()); |
|
549 |
|
550 // 1. Start with an MPR set made of all members of N with |
|
551 // N_willingness equal to WILL_ALWAYS |
|
552 for (NeighborSet::const_iterator neighbor = N.begin (); neighbor != N.end (); neighbor++) |
|
553 { |
|
554 if (neighbor->willingness == OLSR_WILL_ALWAYS) |
|
555 { |
|
556 mprSet.insert (neighbor->neighborMainAddr); |
|
557 // (not in RFC but I think is needed: remove the 2-hop |
|
558 // neighbors reachable by the MPR from N2) |
|
559 for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin (); |
|
560 twoHopNeigh != N2.end (); ) |
|
561 { |
|
562 if (twoHopNeigh->neighborMainAddr == neighbor->neighborMainAddr) |
|
563 { |
|
564 twoHopNeigh = N2.erase (twoHopNeigh); |
|
565 } |
|
566 else |
|
567 { |
|
568 twoHopNeigh++; |
|
569 } |
|
570 } |
|
571 } |
|
572 } |
|
573 |
|
574 // 2. Calculate D(y), where y is a member of N, for all nodes in N. |
|
575 // (we do this later) |
|
576 |
|
577 // 3. Add to the MPR set those nodes in N, which are the *only* |
|
578 // nodes to provide reachability to a node in N2. |
|
579 std::set<Ipv4Address> coveredTwoHopNeighbors; |
|
580 for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin (); twoHopNeigh != N2.end (); twoHopNeigh++) |
|
581 { |
|
582 NeighborSet::const_iterator onlyNeighbor = N.end (); |
|
583 |
|
584 for (NeighborSet::const_iterator neighbor = N.begin (); |
|
585 neighbor != N.end (); neighbor++) |
|
586 { |
|
587 if (neighbor->neighborMainAddr == twoHopNeigh->neighborMainAddr) |
|
588 { |
|
589 if (onlyNeighbor == N.end ()) |
|
590 { |
|
591 onlyNeighbor = neighbor; |
|
592 } |
|
593 else |
|
594 { |
|
595 onlyNeighbor = N.end (); |
|
596 break; |
|
597 } |
|
598 } |
|
599 } |
|
600 if (onlyNeighbor != N.end ()) |
|
601 { |
|
602 mprSet.insert (onlyNeighbor->neighborMainAddr); |
|
603 coveredTwoHopNeighbors.insert (twoHopNeigh->twoHopNeighborAddr); |
|
604 } |
|
605 } |
|
606 // Remove the nodes from N2 which are now covered by a node in the MPR set. |
|
607 for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin (); |
|
608 twoHopNeigh != N2.end (); ) |
|
609 { |
|
610 if (coveredTwoHopNeighbors.find (twoHopNeigh->twoHopNeighborAddr) != coveredTwoHopNeighbors.end ()) |
|
611 { |
|
612 twoHopNeigh = N2.erase (twoHopNeigh); |
|
613 } |
|
614 else |
|
615 { |
|
616 twoHopNeigh++; |
|
617 } |
|
618 } |
|
619 |
|
620 // 4. While there exist nodes in N2 which are not covered by at |
|
621 // least one node in the MPR set: |
|
622 while (N2.begin () != N2.end ()) |
|
623 { |
|
624 // 4.1. For each node in N, calculate the reachability, i.e., the |
|
625 // number of nodes in N2 which are not yet covered by at |
|
626 // least one node in the MPR set, and which are reachable |
|
627 // through this 1-hop neighbor |
|
628 std::map<int, std::vector<const NeighborTuple *> > reachability; |
|
629 std::set<int> rs; |
|
630 for (NeighborSet::iterator it = N.begin(); it != N.end(); it++) |
|
631 { |
|
632 NeighborTuple const &nb_tuple = *it; |
|
633 int r = 0; |
|
634 for (TwoHopNeighborSet::iterator it2 = N2.begin (); it2 != N2.end (); it2++) |
|
635 { |
|
636 TwoHopNeighborTuple const &nb2hop_tuple = *it2; |
|
637 if (nb_tuple.neighborMainAddr == nb2hop_tuple.neighborMainAddr) |
|
638 r++; |
|
639 } |
|
640 rs.insert (r); |
|
641 reachability[r].push_back (&nb_tuple); |
|
642 } |
|
643 |
|
644 // 4.2. Select as a MPR the node with highest N_willingness among |
|
645 // the nodes in N with non-zero reachability. In case of |
|
646 // multiple choice select the node which provides |
|
647 // reachability to the maximum number of nodes in N2. In |
|
648 // case of multiple nodes providing the same amount of |
|
649 // reachability, select the node as MPR whose D(y) is |
|
650 // greater. Remove the nodes from N2 which are now covered |
|
651 // by a node in the MPR set. |
|
652 NeighborTuple const *max = NULL; |
|
653 int max_r = 0; |
|
654 for (std::set<int>::iterator it = rs.begin (); it != rs.end (); it++) |
|
655 { |
|
656 int r = *it; |
|
657 if (r == 0) |
|
658 { |
|
659 continue; |
|
660 } |
|
661 for (std::vector<const NeighborTuple *>::iterator it2 = reachability[r].begin (); |
|
662 it2 != reachability[r].end (); it2++) |
|
663 { |
|
664 const NeighborTuple *nb_tuple = *it2; |
|
665 if (max == NULL || nb_tuple->willingness > max->willingness) |
|
666 { |
|
667 max = nb_tuple; |
|
668 max_r = r; |
|
669 } |
|
670 else if (nb_tuple->willingness == max->willingness) |
|
671 { |
|
672 if (r > max_r) |
|
673 { |
|
674 max = nb_tuple; |
|
675 max_r = r; |
|
676 } |
|
677 else if (r == max_r) |
|
678 { |
|
679 if (Degree (*nb_tuple) > Degree (*max)) |
|
680 { |
|
681 max = nb_tuple; |
|
682 max_r = r; |
|
683 } |
|
684 } |
|
685 } |
|
686 } |
|
687 } |
|
688 |
|
689 if (max != NULL) |
|
690 { |
|
691 mprSet.insert (max->neighborMainAddr); |
|
692 for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin (); |
|
693 twoHopNeigh != N2.end (); ) |
|
694 { |
|
695 if (twoHopNeigh->neighborMainAddr == max->neighborMainAddr) |
|
696 { |
|
697 twoHopNeigh = N2.erase (twoHopNeigh); |
|
698 } |
|
699 else |
|
700 { |
|
701 twoHopNeigh++; |
|
702 } |
|
703 } |
|
704 } |
|
705 } |
|
706 |
|
707 #ifdef NS3_LOG_ENABLE |
|
708 { |
|
709 std::ostringstream os; |
|
710 os << "["; |
|
711 for (MprSet::const_iterator iter = mprSet.begin (); |
|
712 iter != mprSet.end (); iter++) |
|
713 { |
|
714 MprSet::const_iterator next = iter; |
|
715 next++; |
|
716 os << *iter; |
|
717 if (next != mprSet.end ()) |
|
718 os << ", "; |
|
719 } |
|
720 os << "]"; |
|
721 NS_LOG_DEBUG ("Computed MPR set for node " << m_mainAddress << ": " << os.str ()); |
|
722 } |
|
723 #endif |
|
724 |
|
725 m_state.SetMprSet (mprSet); |
|
726 } |
|
727 |
|
728 /// |
|
729 /// \brief Gets the main address associated with a given interface address. |
|
730 /// |
|
731 /// \param iface_addr the interface address. |
|
732 /// \return the corresponding main address. |
|
733 /// |
|
734 Ipv4Address |
|
735 RoutingProtocol::GetMainAddress (Ipv4Address iface_addr) const |
|
736 { |
|
737 const IfaceAssocTuple *tuple = |
|
738 m_state.FindIfaceAssocTuple (iface_addr); |
|
739 |
|
740 if (tuple != NULL) |
|
741 return tuple->mainAddr; |
|
742 else |
|
743 return iface_addr; |
|
744 } |
|
745 |
|
746 /// |
|
747 /// \brief Creates the routing table of the node following RFC 3626 hints. |
|
748 /// |
|
749 void |
|
750 RoutingProtocol::RoutingTableComputation () |
|
751 { |
|
752 NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " s: Node " << m_mainAddress |
|
753 << ": RoutingTableComputation begin..."); |
|
754 |
|
755 // 1. All the entries from the routing table are removed. |
|
756 Clear (); |
|
757 |
|
758 // 2. The new routing entries are added starting with the |
|
759 // symmetric neighbors (h=1) as the destination nodes. |
|
760 const NeighborSet &neighborSet = m_state.GetNeighbors (); |
|
761 for (NeighborSet::const_iterator it = neighborSet.begin (); |
|
762 it != neighborSet.end(); it++) |
|
763 { |
|
764 NeighborTuple const &nb_tuple = *it; |
|
765 NS_LOG_DEBUG ("Looking at neighbor tuple: " << nb_tuple); |
|
766 if (nb_tuple.status == NeighborTuple::STATUS_SYM) |
|
767 { |
|
768 bool nb_main_addr = false; |
|
769 const LinkTuple *lt = NULL; |
|
770 const LinkSet &linkSet = m_state.GetLinks (); |
|
771 for (LinkSet::const_iterator it2 = linkSet.begin(); |
|
772 it2 != linkSet.end(); it2++) |
|
773 { |
|
774 LinkTuple const &link_tuple = *it2; |
|
775 NS_LOG_DEBUG ("Looking at link tuple: " << link_tuple |
|
776 << (link_tuple.time >= Simulator::Now ()? "" : " (expired)")); |
|
777 if ((GetMainAddress (link_tuple.neighborIfaceAddr) == nb_tuple.neighborMainAddr) |
|
778 && link_tuple.time >= Simulator::Now ()) |
|
779 { |
|
780 NS_LOG_LOGIC ("Link tuple matches neighbor " << nb_tuple.neighborMainAddr |
|
781 << " => adding routing table entry to neighbor"); |
|
782 lt = &link_tuple; |
|
783 AddEntry (link_tuple.neighborIfaceAddr, |
|
784 link_tuple.neighborIfaceAddr, |
|
785 link_tuple.localIfaceAddr, |
|
786 1); |
|
787 if (link_tuple.neighborIfaceAddr == nb_tuple.neighborMainAddr) |
|
788 { |
|
789 nb_main_addr = true; |
|
790 } |
|
791 } |
|
792 else |
|
793 { |
|
794 NS_LOG_LOGIC ("Link tuple: linkMainAddress= " << GetMainAddress (link_tuple.neighborIfaceAddr) |
|
795 << "; neighborMainAddr = " << nb_tuple.neighborMainAddr |
|
796 << "; expired=" << int (link_tuple.time < Simulator::Now ()) |
|
797 << " => IGNORE"); |
|
798 } |
|
799 } |
|
800 |
|
801 // If, in the above, no R_dest_addr is equal to the main |
|
802 // address of the neighbor, then another new routing entry |
|
803 // with MUST be added, with: |
|
804 // R_dest_addr = main address of the neighbor; |
|
805 // R_next_addr = L_neighbor_iface_addr of one of the |
|
806 // associated link tuple with L_time >= current time; |
|
807 // R_dist = 1; |
|
808 // R_iface_addr = L_local_iface_addr of the |
|
809 // associated link tuple. |
|
810 if (!nb_main_addr && lt != NULL) |
|
811 { |
|
812 NS_LOG_LOGIC ("no R_dest_addr is equal to the main address of the neighbor " |
|
813 "=> adding additional routing entry"); |
|
814 AddEntry(nb_tuple.neighborMainAddr, |
|
815 lt->neighborIfaceAddr, |
|
816 lt->localIfaceAddr, |
|
817 1); |
|
818 } |
|
819 } |
|
820 } |
|
821 |
|
822 // 3. for each node in N2, i.e., a 2-hop neighbor which is not a |
|
823 // neighbor node or the node itself, and such that there exist at |
|
824 // least one entry in the 2-hop neighbor set where |
|
825 // N_neighbor_main_addr correspond to a neighbor node with |
|
826 // willingness different of WILL_NEVER, |
|
827 const TwoHopNeighborSet &twoHopNeighbors = m_state.GetTwoHopNeighbors (); |
|
828 for (TwoHopNeighborSet::const_iterator it = twoHopNeighbors.begin (); |
|
829 it != twoHopNeighbors.end (); it++) |
|
830 { |
|
831 TwoHopNeighborTuple const &nb2hop_tuple = *it; |
|
832 |
|
833 NS_LOG_LOGIC ("Looking at two-hop neighbor tuple: " << nb2hop_tuple); |
|
834 |
|
835 // a 2-hop neighbor which is not a neighbor node or the node itself |
|
836 if (m_state.FindNeighborTuple (nb2hop_tuple.twoHopNeighborAddr)) |
|
837 { |
|
838 NS_LOG_LOGIC ("Two-hop neighbor tuple is also neighbor; skipped."); |
|
839 continue; |
|
840 } |
|
841 |
|
842 if (nb2hop_tuple.twoHopNeighborAddr == m_mainAddress) |
|
843 { |
|
844 NS_LOG_LOGIC ("Two-hop neighbor is self; skipped."); |
|
845 continue; |
|
846 } |
|
847 |
|
848 // ...and such that there exist at least one entry in the 2-hop |
|
849 // neighbor set where N_neighbor_main_addr correspond to a |
|
850 // neighbor node with willingness different of WILL_NEVER... |
|
851 bool nb2hopOk = false; |
|
852 for (NeighborSet::const_iterator neighbor = neighborSet.begin (); |
|
853 neighbor != neighborSet.end(); neighbor++) |
|
854 { |
|
855 if (neighbor->neighborMainAddr == nb2hop_tuple.neighborMainAddr |
|
856 && neighbor->willingness != OLSR_WILL_NEVER) |
|
857 { |
|
858 nb2hopOk = true; |
|
859 break; |
|
860 } |
|
861 } |
|
862 if (!nb2hopOk) |
|
863 { |
|
864 NS_LOG_LOGIC ("Two-hop neighbor tuple skipped: 2-hop neighbor " |
|
865 << nb2hop_tuple.twoHopNeighborAddr |
|
866 << " is attached to neighbor " << nb2hop_tuple.neighborMainAddr |
|
867 << ", which was not found in the Neighbor Set."); |
|
868 continue; |
|
869 } |
|
870 |
|
871 // one selects one 2-hop tuple and creates one entry in the routing table with: |
|
872 // R_dest_addr = the main address of the 2-hop neighbor; |
|
873 // R_next_addr = the R_next_addr of the entry in the |
|
874 // routing table with: |
|
875 // R_dest_addr == N_neighbor_main_addr |
|
876 // of the 2-hop tuple; |
|
877 // R_dist = 2; |
|
878 // R_iface_addr = the R_iface_addr of the entry in the |
|
879 // routing table with: |
|
880 // R_dest_addr == N_neighbor_main_addr |
|
881 // of the 2-hop tuple; |
|
882 RoutingTableEntry entry; |
|
883 bool foundEntry = Lookup (nb2hop_tuple.neighborMainAddr, entry); |
|
884 if (foundEntry) |
|
885 { |
|
886 NS_LOG_LOGIC ("Adding routing entry for two-hop neighbor."); |
|
887 AddEntry (nb2hop_tuple.twoHopNeighborAddr, |
|
888 entry.nextAddr, |
|
889 entry.interface, |
|
890 2); |
|
891 } |
|
892 else |
|
893 { |
|
894 NS_LOG_LOGIC ("NOT adding routing entry for two-hop neighbor (" |
|
895 << nb2hop_tuple.twoHopNeighborAddr |
|
896 << " not found in the routing table)"); |
|
897 } |
|
898 } |
|
899 |
|
900 for (uint32_t h = 2; ; h++) |
|
901 { |
|
902 bool added = false; |
|
903 |
|
904 // 3.1. For each topology entry in the topology table, if its |
|
905 // T_dest_addr does not correspond to R_dest_addr of any |
|
906 // route entry in the routing table AND its T_last_addr |
|
907 // corresponds to R_dest_addr of a route entry whose R_dist |
|
908 // is equal to h, then a new route entry MUST be recorded in |
|
909 // the routing table (if it does not already exist) |
|
910 const TopologySet &topology = m_state.GetTopologySet (); |
|
911 for (TopologySet::const_iterator it = topology.begin (); |
|
912 it != topology.end (); it++) |
|
913 { |
|
914 const TopologyTuple &topology_tuple = *it; |
|
915 NS_LOG_LOGIC ("Looking at topology tuple: " << topology_tuple); |
|
916 |
|
917 RoutingTableEntry destAddrEntry, lastAddrEntry; |
|
918 bool have_destAddrEntry = Lookup (topology_tuple.destAddr, destAddrEntry); |
|
919 bool have_lastAddrEntry = Lookup (topology_tuple.lastAddr, lastAddrEntry); |
|
920 if (!have_destAddrEntry && have_lastAddrEntry && lastAddrEntry.distance == h) |
|
921 { |
|
922 NS_LOG_LOGIC ("Adding routing table entry based on the topology tuple."); |
|
923 // then a new route entry MUST be recorded in |
|
924 // the routing table (if it does not already exist) where: |
|
925 // R_dest_addr = T_dest_addr; |
|
926 // R_next_addr = R_next_addr of the recorded |
|
927 // route entry where: |
|
928 // R_dest_addr == T_last_addr |
|
929 // R_dist = h+1; and |
|
930 // R_iface_addr = R_iface_addr of the recorded |
|
931 // route entry where: |
|
932 // R_dest_addr == T_last_addr. |
|
933 AddEntry (topology_tuple.destAddr, |
|
934 lastAddrEntry.nextAddr, |
|
935 lastAddrEntry.interface, |
|
936 h + 1); |
|
937 added = true; |
|
938 } |
|
939 else |
|
940 { |
|
941 NS_LOG_LOGIC ("NOT adding routing table entry based on the topology tuple: " |
|
942 "have_destAddrEntry=" << have_destAddrEntry |
|
943 << " have_lastAddrEntry=" << have_lastAddrEntry |
|
944 << " lastAddrEntry.distance=" << (int) lastAddrEntry.distance |
|
945 << " (h=" << h << ")"); |
|
946 } |
|
947 } |
|
948 |
|
949 if (!added) |
|
950 break; |
|
951 } |
|
952 |
|
953 // 4. For each entry in the multiple interface association base |
|
954 // where there exists a routing entry such that: |
|
955 // R_dest_addr == I_main_addr (of the multiple interface association entry) |
|
956 // AND there is no routing entry such that: |
|
957 // R_dest_addr == I_iface_addr |
|
958 const IfaceAssocSet &ifaceAssocSet = m_state.GetIfaceAssocSet (); |
|
959 for (IfaceAssocSet::const_iterator it = ifaceAssocSet.begin (); |
|
960 it != ifaceAssocSet.end (); it++) |
|
961 { |
|
962 IfaceAssocTuple const &tuple = *it; |
|
963 RoutingTableEntry entry1, entry2; |
|
964 bool have_entry1 = Lookup (tuple.mainAddr, entry1); |
|
965 bool have_entry2 = Lookup (tuple.ifaceAddr, entry2); |
|
966 if (have_entry1 && !have_entry2) |
|
967 { |
|
968 // then a route entry is created in the routing table with: |
|
969 // R_dest_addr = I_iface_addr (of the multiple interface |
|
970 // association entry) |
|
971 // R_next_addr = R_next_addr (of the recorded route entry) |
|
972 // R_dist = R_dist (of the recorded route entry) |
|
973 // R_iface_addr = R_iface_addr (of the recorded route entry). |
|
974 AddEntry (tuple.ifaceAddr, |
|
975 entry1.nextAddr, |
|
976 entry1.interface, |
|
977 entry1.distance); |
|
978 } |
|
979 } |
|
980 |
|
981 NS_LOG_DEBUG ("Node " << m_mainAddress << ": RoutingTableComputation end."); |
|
982 m_routingTableChanged (GetSize ()); |
|
983 } |
|
984 |
|
985 |
|
986 /// |
|
987 /// \brief Processes a HELLO message following RFC 3626 specification. |
|
988 /// |
|
989 /// Link sensing and population of the Neighbor Set, 2-hop Neighbor Set and MPR |
|
990 /// Selector Set are performed. |
|
991 /// |
|
992 /// \param msg the %OLSR message which contains the HELLO message. |
|
993 /// \param receiver_iface the address of the interface where the message was received from. |
|
994 /// \param sender_iface the address of the interface where the message was sent from. |
|
995 /// |
|
996 void |
|
997 RoutingProtocol::ProcessHello (const olsr::MessageHeader &msg, |
|
998 const Ipv4Address &receiverIface, |
|
999 const Ipv4Address &senderIface) |
|
1000 { |
|
1001 const olsr::MessageHeader::Hello &hello = msg.GetHello (); |
|
1002 |
|
1003 LinkSensing (msg, hello, receiverIface, senderIface); |
|
1004 |
|
1005 #ifdef NS3_LOG_ENABLE |
|
1006 { |
|
1007 const LinkSet &links = m_state.GetLinks (); |
|
1008 NS_LOG_DEBUG (Simulator::Now ().GetSeconds () |
|
1009 << "s ** BEGIN dump Link Set for OLSR Node " << m_mainAddress); |
|
1010 for (LinkSet::const_iterator link = links.begin (); link != links.end (); link++) |
|
1011 { |
|
1012 NS_LOG_DEBUG(*link); |
|
1013 } |
|
1014 NS_LOG_DEBUG ("** END dump Link Set for OLSR Node " << m_mainAddress); |
|
1015 |
|
1016 const NeighborSet &neighbors = m_state.GetNeighbors (); |
|
1017 NS_LOG_DEBUG (Simulator::Now ().GetSeconds () |
|
1018 << "s ** BEGIN dump Neighbor Set for OLSR Node " << m_mainAddress); |
|
1019 for (NeighborSet::const_iterator neighbor = neighbors.begin (); neighbor != neighbors.end (); neighbor++) |
|
1020 { |
|
1021 NS_LOG_DEBUG(*neighbor); |
|
1022 } |
|
1023 NS_LOG_DEBUG ("** END dump Neighbor Set for OLSR Node " << m_mainAddress); |
|
1024 } |
|
1025 #endif |
|
1026 |
|
1027 PopulateNeighborSet (msg, hello); |
|
1028 PopulateTwoHopNeighborSet (msg, hello); |
|
1029 |
|
1030 #ifdef NS3_LOG_ENABLE |
|
1031 { |
|
1032 const TwoHopNeighborSet &twoHopNeighbors = m_state.GetTwoHopNeighbors (); |
|
1033 NS_LOG_DEBUG (Simulator::Now ().GetSeconds () |
|
1034 << "s ** BEGIN dump TwoHopNeighbor Set for OLSR Node " << m_mainAddress); |
|
1035 for (TwoHopNeighborSet::const_iterator tuple = twoHopNeighbors.begin (); |
|
1036 tuple != twoHopNeighbors.end (); tuple++) |
|
1037 { |
|
1038 NS_LOG_DEBUG(*tuple); |
|
1039 } |
|
1040 NS_LOG_DEBUG ("** END dump TwoHopNeighbor Set for OLSR Node " << m_mainAddress); |
|
1041 } |
|
1042 #endif |
|
1043 |
|
1044 MprComputation (); |
|
1045 PopulateMprSelectorSet (msg, hello); |
|
1046 } |
|
1047 |
|
1048 /// |
|
1049 /// \brief Processes a TC message following RFC 3626 specification. |
|
1050 /// |
|
1051 /// The Topology Set is updated (if needed) with the information of |
|
1052 /// the received TC message. |
|
1053 /// |
|
1054 /// \param msg the %OLSR message which contains the TC message. |
|
1055 /// \param sender_iface the address of the interface where the message was sent from. |
|
1056 /// |
|
1057 void |
|
1058 RoutingProtocol::ProcessTc (const olsr::MessageHeader &msg, |
|
1059 const Ipv4Address &senderIface) |
|
1060 { |
|
1061 const olsr::MessageHeader::Tc &tc = msg.GetTc (); |
|
1062 Time now = Simulator::Now (); |
|
1063 |
|
1064 // 1. If the sender interface of this message is not in the symmetric |
|
1065 // 1-hop neighborhood of this node, the message MUST be discarded. |
|
1066 const LinkTuple *link_tuple = m_state.FindSymLinkTuple (senderIface, now); |
|
1067 if (link_tuple == NULL) |
|
1068 return; |
|
1069 |
|
1070 // 2. If there exist some tuple in the topology set where: |
|
1071 // T_last_addr == originator address AND |
|
1072 // T_seq > ANSN, |
|
1073 // then further processing of this TC message MUST NOT be |
|
1074 // performed. |
|
1075 const TopologyTuple *topologyTuple = |
|
1076 m_state.FindNewerTopologyTuple (msg.GetOriginatorAddress (), tc.ansn); |
|
1077 if (topologyTuple != NULL) |
|
1078 return; |
|
1079 |
|
1080 // 3. All tuples in the topology set where: |
|
1081 // T_last_addr == originator address AND |
|
1082 // T_seq < ANSN |
|
1083 // MUST be removed from the topology set. |
|
1084 m_state.EraseOlderTopologyTuples (msg.GetOriginatorAddress (), tc.ansn); |
|
1085 |
|
1086 // 4. For each of the advertised neighbor main address received in |
|
1087 // the TC message: |
|
1088 for (std::vector<Ipv4Address>::const_iterator i = tc.neighborAddresses.begin (); |
|
1089 i != tc.neighborAddresses.end (); i++) |
|
1090 { |
|
1091 const Ipv4Address &addr = *i; |
|
1092 // 4.1. If there exist some tuple in the topology set where: |
|
1093 // T_dest_addr == advertised neighbor main address, AND |
|
1094 // T_last_addr == originator address, |
|
1095 // then the holding time of that tuple MUST be set to: |
|
1096 // T_time = current time + validity time. |
|
1097 TopologyTuple *topologyTuple = |
|
1098 m_state.FindTopologyTuple (addr, msg.GetOriginatorAddress ()); |
|
1099 |
|
1100 if (topologyTuple != NULL) |
|
1101 { |
|
1102 topologyTuple->expirationTime = now + msg.GetVTime (); |
|
1103 } |
|
1104 else |
|
1105 { |
|
1106 // 4.2. Otherwise, a new tuple MUST be recorded in the topology |
|
1107 // set where: |
|
1108 // T_dest_addr = advertised neighbor main address, |
|
1109 // T_last_addr = originator address, |
|
1110 // T_seq = ANSN, |
|
1111 // T_time = current time + validity time. |
|
1112 TopologyTuple topologyTuple;; |
|
1113 topologyTuple.destAddr = addr; |
|
1114 topologyTuple.lastAddr = msg.GetOriginatorAddress (); |
|
1115 topologyTuple.sequenceNumber = tc.ansn; |
|
1116 topologyTuple.expirationTime = now + msg.GetVTime (); |
|
1117 AddTopologyTuple (topologyTuple); |
|
1118 |
|
1119 // Schedules topology tuple deletion |
|
1120 m_events.Track (Simulator::Schedule (DELAY (topologyTuple.expirationTime), |
|
1121 &RoutingProtocol::TopologyTupleTimerExpire, |
|
1122 this, |
|
1123 topologyTuple.destAddr, |
|
1124 topologyTuple.lastAddr)); |
|
1125 } |
|
1126 } |
|
1127 |
|
1128 #ifdef NS3_LOG_ENABLE |
|
1129 { |
|
1130 const TopologySet &topology = m_state.GetTopologySet (); |
|
1131 NS_LOG_DEBUG (Simulator::Now ().GetSeconds () |
|
1132 << "s ** BEGIN dump TopologySet for OLSR Node " << m_mainAddress); |
|
1133 for (TopologySet::const_iterator tuple = topology.begin (); |
|
1134 tuple != topology.end (); tuple++) |
|
1135 { |
|
1136 NS_LOG_DEBUG (*tuple); |
|
1137 } |
|
1138 NS_LOG_DEBUG ("** END dump TopologySet Set for OLSR Node " << m_mainAddress); |
|
1139 } |
|
1140 #endif |
|
1141 } |
|
1142 |
|
1143 /// |
|
1144 /// \brief Processes a MID message following RFC 3626 specification. |
|
1145 /// |
|
1146 /// The Interface Association Set is updated (if needed) with the information |
|
1147 /// of the received MID message. |
|
1148 /// |
|
1149 /// \param msg the %OLSR message which contains the MID message. |
|
1150 /// \param sender_iface the address of the interface where the message was sent from. |
|
1151 /// |
|
1152 void |
|
1153 RoutingProtocol::ProcessMid (const olsr::MessageHeader &msg, |
|
1154 const Ipv4Address &senderIface) |
|
1155 { |
|
1156 const olsr::MessageHeader::Mid &mid = msg.GetMid (); |
|
1157 Time now = Simulator::Now (); |
|
1158 |
|
1159 NS_LOG_DEBUG ("Node " << m_mainAddress << " ProcessMid from " << senderIface); |
|
1160 // 1. If the sender interface of this message is not in the symmetric |
|
1161 // 1-hop neighborhood of this node, the message MUST be discarded. |
|
1162 const LinkTuple *linkTuple = m_state.FindSymLinkTuple (senderIface, now); |
|
1163 if (linkTuple == NULL) |
|
1164 { |
|
1165 NS_LOG_LOGIC ("Node " << m_mainAddress << |
|
1166 ": the sender interface of this message is not in the " |
|
1167 "symmetric 1-hop neighborhood of this node," |
|
1168 " the message MUST be discarded."); |
|
1169 return; |
|
1170 } |
|
1171 |
|
1172 // 2. For each interface address listed in the MID message |
|
1173 for (std::vector<Ipv4Address>::const_iterator i = mid.interfaceAddresses.begin (); |
|
1174 i != mid.interfaceAddresses.end (); i++) |
|
1175 { |
|
1176 bool updated = false; |
|
1177 IfaceAssocSet &ifaceAssoc = m_state.GetIfaceAssocSetMutable (); |
|
1178 for (IfaceAssocSet::iterator tuple = ifaceAssoc.begin(); |
|
1179 tuple != ifaceAssoc.end(); tuple++) |
|
1180 { |
|
1181 if (tuple->ifaceAddr == *i |
|
1182 && tuple->mainAddr == msg.GetOriginatorAddress ()) |
|
1183 { |
|
1184 NS_LOG_LOGIC ("IfaceAssoc updated: " << *tuple); |
|
1185 tuple->time = now + msg.GetVTime (); |
|
1186 updated = true; |
|
1187 } |
|
1188 } |
|
1189 if (!updated) |
|
1190 { |
|
1191 IfaceAssocTuple tuple; |
|
1192 tuple.ifaceAddr = *i; |
|
1193 tuple.mainAddr = msg.GetOriginatorAddress (); |
|
1194 tuple.time = now + msg.GetVTime (); |
|
1195 AddIfaceAssocTuple (tuple); |
|
1196 NS_LOG_LOGIC ("New IfaceAssoc added: " << tuple); |
|
1197 // Schedules iface association tuple deletion |
|
1198 Simulator::Schedule (DELAY (tuple.time), |
|
1199 &RoutingProtocol::IfaceAssocTupleTimerExpire, this, tuple.ifaceAddr); |
|
1200 } |
|
1201 } |
|
1202 |
|
1203 // 3. (not part of the RFC) iterate over all NeighborTuple's and |
|
1204 // TwoHopNeighborTuples, update the neighbor addresses taking into account |
|
1205 // the new MID information. |
|
1206 NeighborSet &neighbors = m_state.GetNeighbors (); |
|
1207 for (NeighborSet::iterator neighbor = neighbors.begin (); neighbor != neighbors.end(); neighbor++) |
|
1208 { |
|
1209 neighbor->neighborMainAddr = GetMainAddress (neighbor->neighborMainAddr); |
|
1210 } |
|
1211 |
|
1212 TwoHopNeighborSet &twoHopNeighbors = m_state.GetTwoHopNeighbors (); |
|
1213 for (TwoHopNeighborSet::iterator twoHopNeighbor = twoHopNeighbors.begin (); |
|
1214 twoHopNeighbor != twoHopNeighbors.end(); twoHopNeighbor++) |
|
1215 { |
|
1216 twoHopNeighbor->neighborMainAddr = GetMainAddress (twoHopNeighbor->neighborMainAddr); |
|
1217 twoHopNeighbor->twoHopNeighborAddr = GetMainAddress (twoHopNeighbor->twoHopNeighborAddr); |
|
1218 } |
|
1219 NS_LOG_DEBUG ("Node " << m_mainAddress << " ProcessMid from " << senderIface << " -> END."); |
|
1220 } |
|
1221 |
|
1222 |
|
1223 /// |
|
1224 /// \brief OLSR's default forwarding algorithm. |
|
1225 /// |
|
1226 /// See RFC 3626 for details. |
|
1227 /// |
|
1228 /// \param p the %OLSR packet which has been received. |
|
1229 /// \param msg the %OLSR message which must be forwarded. |
|
1230 /// \param dup_tuple NULL if the message has never been considered for forwarding, |
|
1231 /// or a duplicate tuple in other case. |
|
1232 /// \param local_iface the address of the interface where the message was received from. |
|
1233 /// |
|
1234 void |
|
1235 RoutingProtocol::ForwardDefault (olsr::MessageHeader olsrMessage, |
|
1236 DuplicateTuple *duplicated, |
|
1237 const Ipv4Address &localIface, |
|
1238 const Ipv4Address &senderAddress) |
|
1239 { |
|
1240 Time now = Simulator::Now (); |
|
1241 |
|
1242 // If the sender interface address is not in the symmetric |
|
1243 // 1-hop neighborhood the message must not be forwarded |
|
1244 const LinkTuple *linkTuple = m_state.FindSymLinkTuple (senderAddress, now); |
|
1245 if (linkTuple == NULL) |
|
1246 return; |
|
1247 |
|
1248 // If the message has already been considered for forwarding, |
|
1249 // it must not be retransmitted again |
|
1250 if (duplicated != NULL && duplicated->retransmitted) |
|
1251 { |
|
1252 NS_LOG_LOGIC (Simulator::Now () << "Node " << m_mainAddress << " does not forward a message received" |
|
1253 " from " << olsrMessage.GetOriginatorAddress () << " because it is duplicated"); |
|
1254 return; |
|
1255 } |
|
1256 |
|
1257 // If the sender interface address is an interface address |
|
1258 // of a MPR selector of this node and ttl is greater than 1, |
|
1259 // the message must be retransmitted |
|
1260 bool retransmitted = false; |
|
1261 if (olsrMessage.GetTimeToLive () > 1) |
|
1262 { |
|
1263 const MprSelectorTuple *mprselTuple = |
|
1264 m_state.FindMprSelectorTuple (GetMainAddress (senderAddress)); |
|
1265 if (mprselTuple != NULL) |
|
1266 { |
|
1267 olsrMessage.SetTimeToLive (olsrMessage.GetTimeToLive () - 1); |
|
1268 olsrMessage.SetHopCount (olsrMessage.GetHopCount () + 1); |
|
1269 // We have to introduce a random delay to avoid |
|
1270 // synchronization with neighbors. |
|
1271 QueueMessage (olsrMessage, JITTER); |
|
1272 retransmitted = true; |
|
1273 } |
|
1274 } |
|
1275 |
|
1276 // Update duplicate tuple... |
|
1277 if (duplicated != NULL) |
|
1278 { |
|
1279 duplicated->expirationTime = now + OLSR_DUP_HOLD_TIME; |
|
1280 duplicated->retransmitted = retransmitted; |
|
1281 duplicated->ifaceList.push_back (localIface); |
|
1282 } |
|
1283 // ...or create a new one |
|
1284 else |
|
1285 { |
|
1286 DuplicateTuple newDup; |
|
1287 newDup.address = olsrMessage.GetOriginatorAddress (); |
|
1288 newDup.sequenceNumber = olsrMessage.GetMessageSequenceNumber (); |
|
1289 newDup.expirationTime = now + OLSR_DUP_HOLD_TIME; |
|
1290 newDup.retransmitted = retransmitted; |
|
1291 newDup.ifaceList.push_back (localIface); |
|
1292 AddDuplicateTuple (newDup); |
|
1293 // Schedule dup tuple deletion |
|
1294 Simulator::Schedule (OLSR_DUP_HOLD_TIME, |
|
1295 &RoutingProtocol::DupTupleTimerExpire, this, |
|
1296 newDup.address, newDup.sequenceNumber); |
|
1297 } |
|
1298 } |
|
1299 |
|
1300 /// |
|
1301 /// \brief Enques an %OLSR message which will be sent with a delay of (0, delay]. |
|
1302 /// |
|
1303 /// This buffering system is used in order to piggyback several %OLSR messages in |
|
1304 /// a same %OLSR packet. |
|
1305 /// |
|
1306 /// \param msg the %OLSR message which must be sent. |
|
1307 /// \param delay maximum delay the %OLSR message is going to be buffered. |
|
1308 /// |
|
1309 void |
|
1310 RoutingProtocol::QueueMessage (const olsr::MessageHeader &message, Time delay) |
|
1311 { |
|
1312 m_queuedMessages.push_back (message); |
|
1313 if (not m_queuedMessagesTimer.IsRunning ()) |
|
1314 { |
|
1315 m_queuedMessagesTimer.SetDelay (delay); |
|
1316 m_queuedMessagesTimer.Schedule (); |
|
1317 } |
|
1318 } |
|
1319 |
|
1320 void |
|
1321 RoutingProtocol::SendPacket (Ptr<Packet> packet, |
|
1322 const MessageList &containedMessages) |
|
1323 { |
|
1324 NS_LOG_DEBUG ("OLSR node " << m_mainAddress << " sending a OLSR packet"); |
|
1325 |
|
1326 // Add a header |
|
1327 olsr::PacketHeader header; |
|
1328 header.SetPacketLength (header.GetSerializedSize () + packet->GetSize ()); |
|
1329 header.SetPacketSequenceNumber (GetPacketSequenceNumber ()); |
|
1330 packet->AddHeader (header); |
|
1331 |
|
1332 // Trace it |
|
1333 m_txPacketTrace (header, containedMessages); |
|
1334 |
|
1335 // Send it |
|
1336 m_socketAddresses.begin ()->first->Send (packet); |
|
1337 } |
|
1338 |
|
1339 /// |
|
1340 /// \brief Creates as many %OLSR packets as needed in order to send all buffered |
|
1341 /// %OLSR messages. |
|
1342 /// |
|
1343 /// Maximum number of messages which can be contained in an %OLSR packet is |
|
1344 /// dictated by OLSR_MAX_MSGS constant. |
|
1345 /// |
|
1346 void |
|
1347 RoutingProtocol::SendQueuedMessages () |
|
1348 { |
|
1349 Ptr<Packet> packet = Create<Packet> (); |
|
1350 int numMessages = 0; |
|
1351 |
|
1352 NS_LOG_DEBUG ("Olsr node " << m_mainAddress << ": SendQueuedMessages"); |
|
1353 |
|
1354 MessageList msglist; |
|
1355 |
|
1356 for (std::vector<olsr::MessageHeader>::const_iterator message = m_queuedMessages.begin (); |
|
1357 message != m_queuedMessages.end (); |
|
1358 message++) |
|
1359 { |
|
1360 Ptr<Packet> p = Create<Packet> (); |
|
1361 p->AddHeader (*message); |
|
1362 packet->AddAtEnd (p); |
|
1363 msglist.push_back (*message); |
|
1364 if (++numMessages == OLSR_MAX_MSGS) |
|
1365 { |
|
1366 SendPacket (packet, msglist); |
|
1367 msglist.clear (); |
|
1368 // Reset variables for next packet |
|
1369 numMessages = 0; |
|
1370 packet = Create<Packet> (); |
|
1371 } |
|
1372 } |
|
1373 |
|
1374 if (packet->GetSize ()) |
|
1375 { |
|
1376 SendPacket (packet, msglist); |
|
1377 } |
|
1378 |
|
1379 m_queuedMessages.clear (); |
|
1380 } |
|
1381 |
|
1382 /// |
|
1383 /// \brief Creates a new %OLSR HELLO message which is buffered for being sent later on. |
|
1384 /// |
|
1385 void |
|
1386 RoutingProtocol::SendHello () |
|
1387 { |
|
1388 NS_LOG_FUNCTION (this); |
|
1389 |
|
1390 olsr::MessageHeader msg; |
|
1391 Time now = Simulator::Now (); |
|
1392 |
|
1393 msg.SetVTime (OLSR_NEIGHB_HOLD_TIME); |
|
1394 msg.SetOriginatorAddress (m_mainAddress); |
|
1395 msg.SetTimeToLive (1); |
|
1396 msg.SetHopCount (0); |
|
1397 msg.SetMessageSequenceNumber (GetMessageSequenceNumber ()); |
|
1398 olsr::MessageHeader::Hello &hello = msg.GetHello (); |
|
1399 |
|
1400 hello.SetHTime (Scalar (3) * m_helloInterval); |
|
1401 hello.willingness = m_willingness; |
|
1402 |
|
1403 std::vector<olsr::MessageHeader::Hello::LinkMessage> |
|
1404 &linkMessages = hello.linkMessages; |
|
1405 |
|
1406 const LinkSet &links = m_state.GetLinks (); |
|
1407 for (LinkSet::const_iterator link_tuple = links.begin (); |
|
1408 link_tuple != links.end (); link_tuple++) |
|
1409 { |
|
1410 if (!(GetMainAddress (link_tuple->localIfaceAddr) == m_mainAddress |
|
1411 && link_tuple->time >= now)) |
|
1412 { |
|
1413 continue; |
|
1414 } |
|
1415 |
|
1416 uint8_t link_type, nb_type = 0xff; |
|
1417 |
|
1418 // Establishes link type |
|
1419 if (link_tuple->symTime >= now) |
|
1420 { |
|
1421 link_type = OLSR_SYM_LINK; |
|
1422 } |
|
1423 else if (link_tuple->asymTime >= now) |
|
1424 { |
|
1425 link_type = OLSR_ASYM_LINK; |
|
1426 } |
|
1427 else |
|
1428 { |
|
1429 link_type = OLSR_LOST_LINK; |
|
1430 } |
|
1431 // Establishes neighbor type. |
|
1432 if (m_state.FindMprAddress (GetMainAddress (link_tuple->neighborIfaceAddr))) |
|
1433 { |
|
1434 nb_type = OLSR_MPR_NEIGH; |
|
1435 NS_LOG_DEBUG ("I consider neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr) |
|
1436 << " to be MPR_NEIGH."); |
|
1437 } |
|
1438 else |
|
1439 { |
|
1440 bool ok = false; |
|
1441 for (NeighborSet::const_iterator nb_tuple = m_state.GetNeighbors ().begin (); |
|
1442 nb_tuple != m_state.GetNeighbors ().end (); |
|
1443 nb_tuple++) |
|
1444 { |
|
1445 if (nb_tuple->neighborMainAddr == GetMainAddress (link_tuple->neighborIfaceAddr)) |
|
1446 { |
|
1447 if (nb_tuple->status == NeighborTuple::STATUS_SYM) |
|
1448 { |
|
1449 NS_LOG_DEBUG ("I consider neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr) |
|
1450 << " to be SYM_NEIGH."); |
|
1451 nb_type = OLSR_SYM_NEIGH; |
|
1452 } |
|
1453 else if (nb_tuple->status == NeighborTuple::STATUS_NOT_SYM) |
|
1454 { |
|
1455 nb_type = OLSR_NOT_NEIGH; |
|
1456 NS_LOG_DEBUG ("I consider neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr) |
|
1457 << " to be NOT_NEIGH."); |
|
1458 } |
|
1459 else |
|
1460 { |
|
1461 NS_FATAL_ERROR ("There is a neighbor tuple with an unknown status!\n"); |
|
1462 } |
|
1463 ok = true; |
|
1464 break; |
|
1465 } |
|
1466 } |
|
1467 if (!ok) |
|
1468 { |
|
1469 NS_LOG_WARN ("I don't know the neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr) << "!!!"); |
|
1470 continue; |
|
1471 } |
|
1472 } |
|
1473 |
|
1474 olsr::MessageHeader::Hello::LinkMessage linkMessage; |
|
1475 linkMessage.linkCode = (link_type & 0x03) | ((nb_type << 2) & 0x0f); |
|
1476 linkMessage.neighborInterfaceAddresses.push_back |
|
1477 (link_tuple->neighborIfaceAddr); |
|
1478 |
|
1479 std::vector<Ipv4Address> interfaces = |
|
1480 m_state.FindNeighborInterfaces (link_tuple->neighborIfaceAddr); |
|
1481 |
|
1482 linkMessage.neighborInterfaceAddresses.insert |
|
1483 (linkMessage.neighborInterfaceAddresses.end (), |
|
1484 interfaces.begin (), interfaces.end ()); |
|
1485 |
|
1486 linkMessages.push_back (linkMessage); |
|
1487 } |
|
1488 NS_LOG_DEBUG ("OLSR HELLO message size: " << int (msg.GetSerializedSize ()) |
|
1489 << " (with " << int (linkMessages.size ()) << " link messages)"); |
|
1490 QueueMessage (msg, JITTER); |
|
1491 } |
|
1492 |
|
1493 /// |
|
1494 /// \brief Creates a new %OLSR TC message which is buffered for being sent later on. |
|
1495 /// |
|
1496 void |
|
1497 RoutingProtocol::SendTc () |
|
1498 { |
|
1499 NS_LOG_FUNCTION (this); |
|
1500 |
|
1501 olsr::MessageHeader msg; |
|
1502 |
|
1503 msg.SetVTime (OLSR_TOP_HOLD_TIME); |
|
1504 msg.SetOriginatorAddress (m_mainAddress); |
|
1505 msg.SetTimeToLive (255); |
|
1506 msg.SetHopCount (0); |
|
1507 msg.SetMessageSequenceNumber (GetMessageSequenceNumber ()); |
|
1508 |
|
1509 olsr::MessageHeader::Tc &tc = msg.GetTc (); |
|
1510 tc.ansn = m_ansn; |
|
1511 for (MprSelectorSet::const_iterator mprsel_tuple = m_state.GetMprSelectors ().begin(); |
|
1512 mprsel_tuple != m_state.GetMprSelectors ().end(); mprsel_tuple++) |
|
1513 { |
|
1514 tc.neighborAddresses.push_back (mprsel_tuple->mainAddr); |
|
1515 } |
|
1516 QueueMessage (msg, JITTER); |
|
1517 } |
|
1518 |
|
1519 /// |
|
1520 /// \brief Creates a new %OLSR MID message which is buffered for being sent later on. |
|
1521 /// |
|
1522 void |
|
1523 RoutingProtocol::SendMid () |
|
1524 { |
|
1525 olsr::MessageHeader msg; |
|
1526 olsr::MessageHeader::Mid &mid = msg.GetMid (); |
|
1527 |
|
1528 // A node which has only a single interface address participating in |
|
1529 // the MANET (i.e., running OLSR), MUST NOT generate any MID |
|
1530 // message. |
|
1531 |
|
1532 // A node with several interfaces, where only one is participating |
|
1533 // in the MANET and running OLSR (e.g., a node is connected to a |
|
1534 // wired network as well as to a MANET) MUST NOT generate any MID |
|
1535 // messages. |
|
1536 |
|
1537 // A node with several interfaces, where more than one is |
|
1538 // participating in the MANET and running OLSR MUST generate MID |
|
1539 // messages as specified. |
|
1540 |
|
1541 // [ Note: assuming here that all interfaces participate in the |
|
1542 // MANET; later we may want to make this configurable. ] |
|
1543 |
|
1544 Ipv4Address loopback ("127.0.0.1"); |
|
1545 for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++) |
|
1546 { |
|
1547 Ipv4Address addr = m_ipv4->GetAddress (i); |
|
1548 if (addr != m_mainAddress && addr != loopback) |
|
1549 mid.interfaceAddresses.push_back (addr); |
|
1550 } |
|
1551 if (mid.interfaceAddresses.size () == 0) |
|
1552 return; |
|
1553 |
|
1554 msg.SetVTime (OLSR_MID_HOLD_TIME); |
|
1555 msg.SetOriginatorAddress (m_mainAddress); |
|
1556 msg.SetTimeToLive (255); |
|
1557 msg.SetHopCount (0); |
|
1558 msg.SetMessageSequenceNumber (GetMessageSequenceNumber ()); |
|
1559 |
|
1560 QueueMessage (msg, JITTER); |
|
1561 } |
|
1562 |
|
1563 /// |
|
1564 /// \brief Updates Link Set according to a new received HELLO message (following RFC 3626 |
|
1565 /// specification). Neighbor Set is also updated if needed. |
|
1566 void |
|
1567 RoutingProtocol::LinkSensing (const olsr::MessageHeader &msg, |
|
1568 const olsr::MessageHeader::Hello &hello, |
|
1569 const Ipv4Address &receiverIface, |
|
1570 const Ipv4Address &senderIface) |
|
1571 { |
|
1572 Time now = Simulator::Now (); |
|
1573 bool updated = false; |
|
1574 bool created = false; |
|
1575 NS_LOG_DEBUG ("@" << now.GetSeconds () << ": Olsr node " << m_mainAddress |
|
1576 << ": LinkSensing(receiverIface=" << receiverIface |
|
1577 << ", senderIface=" << senderIface << ") BEGIN"); |
|
1578 |
|
1579 NS_ASSERT (msg.GetVTime () > Seconds (0)); |
|
1580 LinkTuple *link_tuple = m_state.FindLinkTuple (senderIface); |
|
1581 if (link_tuple == NULL) |
|
1582 { |
|
1583 LinkTuple newLinkTuple; |
|
1584 // We have to create a new tuple |
|
1585 newLinkTuple.neighborIfaceAddr = senderIface; |
|
1586 newLinkTuple.localIfaceAddr = receiverIface; |
|
1587 newLinkTuple.symTime = now - Seconds (1); |
|
1588 newLinkTuple.time = now + msg.GetVTime (); |
|
1589 link_tuple = &m_state.InsertLinkTuple (newLinkTuple); |
|
1590 created = true; |
|
1591 NS_LOG_LOGIC ("Existing link tuple did not exist => creating new one"); |
|
1592 } |
|
1593 else |
|
1594 { |
|
1595 NS_LOG_LOGIC ("Existing link tuple already exists => will update it"); |
|
1596 updated = true; |
|
1597 } |
|
1598 |
|
1599 link_tuple->asymTime = now + msg.GetVTime (); |
|
1600 for (std::vector<olsr::MessageHeader::Hello::LinkMessage>::const_iterator linkMessage = |
|
1601 hello.linkMessages.begin (); |
|
1602 linkMessage != hello.linkMessages.end (); |
|
1603 linkMessage++) |
|
1604 { |
|
1605 int lt = linkMessage->linkCode & 0x03; // Link Type |
|
1606 int nt = (linkMessage->linkCode >> 2) & 0x03; // Neighbor Type |
|
1607 |
|
1608 #ifdef NS3_LOG_ENABLE |
|
1609 const char *linkTypeName; |
|
1610 switch (lt) |
|
1611 { |
|
1612 case OLSR_UNSPEC_LINK: linkTypeName = "UNSPEC_LINK"; break; |
|
1613 case OLSR_ASYM_LINK: linkTypeName = "ASYM_LINK"; break; |
|
1614 case OLSR_SYM_LINK: linkTypeName = "SYM_LINK"; break; |
|
1615 case OLSR_LOST_LINK: linkTypeName = "LOST_LINK"; break; |
|
1616 default: linkTypeName = "(invalid value!)"; |
|
1617 } |
|
1618 |
|
1619 const char *neighborTypeName; |
|
1620 switch (nt) |
|
1621 { |
|
1622 case OLSR_NOT_NEIGH: neighborTypeName = "NOT_NEIGH"; break; |
|
1623 case OLSR_SYM_NEIGH: neighborTypeName = "SYM_NEIGH"; break; |
|
1624 case OLSR_MPR_NEIGH: neighborTypeName = "MPR_NEIGH"; break; |
|
1625 default: neighborTypeName = "(invalid value!)"; |
|
1626 } |
|
1627 |
|
1628 NS_LOG_DEBUG ("Looking at HELLO link messages with Link Type " |
|
1629 << lt << " (" << linkTypeName |
|
1630 << ") and Neighbor Type " << nt |
|
1631 << " (" << neighborTypeName << ")"); |
|
1632 #endif |
|
1633 |
|
1634 // We must not process invalid advertised links |
|
1635 if ((lt == OLSR_SYM_LINK && nt == OLSR_NOT_NEIGH) || |
|
1636 (nt != OLSR_SYM_NEIGH && nt != OLSR_MPR_NEIGH |
|
1637 && nt != OLSR_NOT_NEIGH)) |
|
1638 { |
|
1639 NS_LOG_LOGIC ("HELLO link code is invalid => IGNORING"); |
|
1640 continue; |
|
1641 } |
|
1642 |
|
1643 for (std::vector<Ipv4Address>::const_iterator neighIfaceAddr = |
|
1644 linkMessage->neighborInterfaceAddresses.begin (); |
|
1645 neighIfaceAddr != linkMessage->neighborInterfaceAddresses.end (); |
|
1646 neighIfaceAddr++) |
|
1647 { |
|
1648 NS_LOG_DEBUG (" -> Neighbor: " << *neighIfaceAddr); |
|
1649 if (*neighIfaceAddr == receiverIface) |
|
1650 { |
|
1651 if (lt == OLSR_LOST_LINK) |
|
1652 { |
|
1653 NS_LOG_LOGIC ("link is LOST => expiring it"); |
|
1654 link_tuple->symTime = now - Seconds (1); |
|
1655 updated = true; |
|
1656 } |
|
1657 else if (lt == OLSR_SYM_LINK || lt == OLSR_ASYM_LINK) |
|
1658 { |
|
1659 NS_LOG_DEBUG (*link_tuple << ": link is SYM or ASYM => should become SYM now" |
|
1660 " (symTime being increased to " << now + msg.GetVTime ()); |
|
1661 link_tuple->symTime = now + msg.GetVTime (); |
|
1662 link_tuple->time = link_tuple->symTime + OLSR_NEIGHB_HOLD_TIME; |
|
1663 updated = true; |
|
1664 } |
|
1665 else |
|
1666 { |
|
1667 NS_FATAL_ERROR ("bad link type"); |
|
1668 } |
|
1669 break; |
|
1670 } |
|
1671 else |
|
1672 { |
|
1673 NS_LOG_DEBUG (" \\-> *neighIfaceAddr (" << *neighIfaceAddr |
|
1674 << " != receiverIface (" << receiverIface << ") => IGNORING!"); |
|
1675 } |
|
1676 } |
|
1677 NS_LOG_DEBUG ("Link tuple updated: " << int (updated)); |
|
1678 } |
|
1679 link_tuple->time = std::max(link_tuple->time, link_tuple->asymTime); |
|
1680 |
|
1681 if (updated) |
|
1682 { |
|
1683 LinkTupleUpdated (*link_tuple, hello.willingness); |
|
1684 } |
|
1685 |
|
1686 // Schedules link tuple deletion |
|
1687 if (created && link_tuple != NULL) |
|
1688 { |
|
1689 LinkTupleAdded (*link_tuple, hello.willingness); |
|
1690 m_events.Track (Simulator::Schedule (DELAY (std::min (link_tuple->time, link_tuple->symTime)), |
|
1691 &RoutingProtocol::LinkTupleTimerExpire, this, |
|
1692 link_tuple->neighborIfaceAddr)); |
|
1693 } |
|
1694 NS_LOG_DEBUG ("@" << now.GetSeconds () << ": Olsr node " << m_mainAddress |
|
1695 << ": LinkSensing END"); |
|
1696 } |
|
1697 |
|
1698 /// |
|
1699 /// \brief Updates the Neighbor Set according to the information contained in a new received |
|
1700 /// HELLO message (following RFC 3626). |
|
1701 void |
|
1702 RoutingProtocol::PopulateNeighborSet (const olsr::MessageHeader &msg, |
|
1703 const olsr::MessageHeader::Hello &hello) |
|
1704 { |
|
1705 NeighborTuple *nb_tuple = m_state.FindNeighborTuple (msg.GetOriginatorAddress ()); |
|
1706 if (nb_tuple != NULL) |
|
1707 { |
|
1708 nb_tuple->willingness = hello.willingness; |
|
1709 } |
|
1710 } |
|
1711 |
|
1712 |
|
1713 /// |
|
1714 /// \brief Updates the 2-hop Neighbor Set according to the information contained in a new |
|
1715 /// received HELLO message (following RFC 3626). |
|
1716 void |
|
1717 RoutingProtocol::PopulateTwoHopNeighborSet (const olsr::MessageHeader &msg, |
|
1718 const olsr::MessageHeader::Hello &hello) |
|
1719 { |
|
1720 Time now = Simulator::Now (); |
|
1721 |
|
1722 NS_LOG_DEBUG ("Olsr node " << m_mainAddress << ": PopulateTwoHopNeighborSet BEGIN"); |
|
1723 |
|
1724 for (LinkSet::const_iterator link_tuple = m_state.GetLinks ().begin (); |
|
1725 link_tuple != m_state.GetLinks ().end (); link_tuple++) |
|
1726 { |
|
1727 NS_LOG_LOGIC ("Looking at link tuple: " << *link_tuple); |
|
1728 if (GetMainAddress (link_tuple->neighborIfaceAddr) != msg.GetOriginatorAddress ()) |
|
1729 { |
|
1730 NS_LOG_LOGIC ("Link tuple ignored: " |
|
1731 "GetMainAddress (link_tuple->neighborIfaceAddr) != msg.GetOriginatorAddress ()"); |
|
1732 NS_LOG_LOGIC ("(GetMainAddress(" << link_tuple->neighborIfaceAddr << "): " |
|
1733 << GetMainAddress (link_tuple->neighborIfaceAddr) |
|
1734 << "; msg.GetOriginatorAddress (): " << msg.GetOriginatorAddress ()); |
|
1735 continue; |
|
1736 } |
|
1737 |
|
1738 if (link_tuple->symTime < now) |
|
1739 { |
|
1740 NS_LOG_LOGIC ("Link tuple ignored: expired."); |
|
1741 continue; |
|
1742 } |
|
1743 |
|
1744 typedef std::vector<olsr::MessageHeader::Hello::LinkMessage> LinkMessageVec; |
|
1745 for (LinkMessageVec::const_iterator linkMessage = hello.linkMessages.begin (); |
|
1746 linkMessage != hello.linkMessages.end (); linkMessage++) |
|
1747 { |
|
1748 int neighborType = (linkMessage->linkCode >> 2) & 0x3; |
|
1749 #ifdef NS3_LOG_ENABLE |
|
1750 const char *neighborTypeNames[3] = { "NOT_NEIGH", "SYM_NEIGH", "MPR_NEIGH" }; |
|
1751 const char *neighborTypeName = ((neighborType < 3)? |
|
1752 neighborTypeNames[neighborType] |
|
1753 : "(invalid value)"); |
|
1754 NS_LOG_DEBUG ("Looking at Link Message from HELLO message: neighborType=" |
|
1755 << neighborType << " (" << neighborTypeName << ")"); |
|
1756 #endif |
|
1757 |
|
1758 for (std::vector<Ipv4Address>::const_iterator nb2hop_addr_iter = |
|
1759 linkMessage->neighborInterfaceAddresses.begin (); |
|
1760 nb2hop_addr_iter != linkMessage->neighborInterfaceAddresses.end (); |
|
1761 nb2hop_addr_iter++) |
|
1762 { |
|
1763 Ipv4Address nb2hop_addr = GetMainAddress (*nb2hop_addr_iter); |
|
1764 NS_LOG_DEBUG ("Looking at 2-hop neighbor address from HELLO message: " |
|
1765 << *nb2hop_addr_iter |
|
1766 << " (main address is " << nb2hop_addr << ")"); |
|
1767 if (neighborType == OLSR_SYM_NEIGH || neighborType == OLSR_MPR_NEIGH) |
|
1768 { |
|
1769 // If the main address of the 2-hop neighbor address == main address |
|
1770 // of the receiving node, silently discard the 2-hop |
|
1771 // neighbor address. |
|
1772 if (nb2hop_addr == m_routingAgentAddr) |
|
1773 { |
|
1774 NS_LOG_LOGIC ("Ignoring 2-hop neighbor (it is the node itself)"); |
|
1775 continue; |
|
1776 } |
|
1777 |
|
1778 // Otherwise, a 2-hop tuple is created |
|
1779 TwoHopNeighborTuple *nb2hop_tuple = |
|
1780 m_state.FindTwoHopNeighborTuple (msg.GetOriginatorAddress (), nb2hop_addr); |
|
1781 NS_LOG_LOGIC ("Adding the 2-hop neighbor" |
|
1782 << (nb2hop_tuple? " (refreshing existing entry)" : "")); |
|
1783 if (nb2hop_tuple == NULL) |
|
1784 { |
|
1785 TwoHopNeighborTuple new_nb2hop_tuple; |
|
1786 new_nb2hop_tuple.neighborMainAddr = msg.GetOriginatorAddress (); |
|
1787 new_nb2hop_tuple.twoHopNeighborAddr = nb2hop_addr; |
|
1788 new_nb2hop_tuple.expirationTime = now + msg.GetVTime (); |
|
1789 AddTwoHopNeighborTuple (new_nb2hop_tuple); |
|
1790 // Schedules nb2hop tuple deletion |
|
1791 m_events.Track (Simulator::Schedule (DELAY (new_nb2hop_tuple.expirationTime), |
|
1792 &RoutingProtocol::Nb2hopTupleTimerExpire, this, |
|
1793 new_nb2hop_tuple.neighborMainAddr, |
|
1794 new_nb2hop_tuple.twoHopNeighborAddr)); |
|
1795 } |
|
1796 else |
|
1797 { |
|
1798 nb2hop_tuple->expirationTime = now + msg.GetVTime (); |
|
1799 } |
|
1800 } |
|
1801 else if (neighborType == OLSR_NOT_NEIGH) |
|
1802 { |
|
1803 // For each 2-hop node listed in the HELLO message |
|
1804 // with Neighbor Type equal to NOT_NEIGH all 2-hop |
|
1805 // tuples where: N_neighbor_main_addr == Originator |
|
1806 // Address AND N_2hop_addr == main address of the |
|
1807 // 2-hop neighbor are deleted. |
|
1808 NS_LOG_LOGIC ("2-hop neighbor is NOT_NEIGH => deleting matching 2-hop neighbor state"); |
|
1809 m_state.EraseTwoHopNeighborTuples (msg.GetOriginatorAddress (), nb2hop_addr); |
|
1810 } |
|
1811 else |
|
1812 { |
|
1813 NS_LOG_LOGIC ("*** WARNING *** Ignoring link message (inside HELLO) with bad" |
|
1814 " neighbor type value: " << neighborType); |
|
1815 } |
|
1816 } |
|
1817 } |
|
1818 } |
|
1819 |
|
1820 NS_LOG_DEBUG ("Olsr node " << m_mainAddress << ": PopulateTwoHopNeighborSet END"); |
|
1821 } |
|
1822 |
|
1823 |
|
1824 |
|
1825 /// |
|
1826 /// \brief Updates the MPR Selector Set according to the information contained in a new |
|
1827 /// received HELLO message (following RFC 3626). |
|
1828 void |
|
1829 RoutingProtocol::PopulateMprSelectorSet (const olsr::MessageHeader &msg, |
|
1830 const olsr::MessageHeader::Hello &hello) |
|
1831 { |
|
1832 NS_LOG_FUNCTION (this); |
|
1833 |
|
1834 Time now = Simulator::Now (); |
|
1835 |
|
1836 typedef std::vector<olsr::MessageHeader::Hello::LinkMessage> LinkMessageVec; |
|
1837 for (LinkMessageVec::const_iterator linkMessage = hello.linkMessages.begin (); |
|
1838 linkMessage != hello.linkMessages.end (); |
|
1839 linkMessage++) |
|
1840 { |
|
1841 int nt = linkMessage->linkCode >> 2; |
|
1842 if (nt == OLSR_MPR_NEIGH) |
|
1843 { |
|
1844 NS_LOG_DEBUG ("Processing a link message with neighbor type MPR_NEIGH"); |
|
1845 |
|
1846 for (std::vector<Ipv4Address>::const_iterator nb_iface_addr = |
|
1847 linkMessage->neighborInterfaceAddresses.begin (); |
|
1848 nb_iface_addr != linkMessage->neighborInterfaceAddresses.end (); |
|
1849 nb_iface_addr++) |
|
1850 { |
|
1851 if (GetMainAddress (*nb_iface_addr) == m_mainAddress) |
|
1852 { |
|
1853 NS_LOG_DEBUG ("Adding entry to mpr selector set for neighbor " << *nb_iface_addr); |
|
1854 |
|
1855 // We must create a new entry into the mpr selector set |
|
1856 MprSelectorTuple *existing_mprsel_tuple = |
|
1857 m_state.FindMprSelectorTuple (msg.GetOriginatorAddress ()); |
|
1858 if (existing_mprsel_tuple == NULL) |
|
1859 { |
|
1860 MprSelectorTuple mprsel_tuple; |
|
1861 |
|
1862 mprsel_tuple.mainAddr = msg.GetOriginatorAddress (); |
|
1863 mprsel_tuple.expirationTime = now + msg.GetVTime (); |
|
1864 AddMprSelectorTuple (mprsel_tuple); |
|
1865 |
|
1866 // Schedules mpr selector tuple deletion |
|
1867 m_events.Track (Simulator::Schedule |
|
1868 (DELAY (mprsel_tuple.expirationTime), |
|
1869 &RoutingProtocol::MprSelTupleTimerExpire, this, |
|
1870 mprsel_tuple.mainAddr)); |
|
1871 } |
|
1872 else |
|
1873 { |
|
1874 existing_mprsel_tuple->expirationTime = now + msg.GetVTime (); |
|
1875 } |
|
1876 } |
|
1877 } |
|
1878 } |
|
1879 } |
|
1880 NS_LOG_DEBUG ("Computed MPR selector set for node " << m_mainAddress << ": " << m_state.PrintMprSelectorSet ()); |
|
1881 } |
|
1882 |
|
1883 |
|
1884 #if 0 |
|
1885 /// |
|
1886 /// \brief Drops a given packet because it couldn't be delivered to the corresponding |
|
1887 /// destination by the MAC layer. This may cause a neighbor loss, and appropiate |
|
1888 /// actions are then taken. |
|
1889 /// |
|
1890 /// \param p the packet which couldn't be delivered by the MAC layer. |
|
1891 /// |
|
1892 void |
|
1893 OLSR::mac_failed(Ptr<Packet> p) { |
|
1894 double now = Simulator::Now (); |
|
1895 struct hdr_ip* ih = HDR_IP(p); |
|
1896 struct hdr_cmn* ch = HDR_CMN(p); |
|
1897 |
|
1898 debug("%f: Node %d MAC Layer detects a breakage on link to %d\n", |
|
1899 now, |
|
1900 OLSR::node_id(ra_addr()), |
|
1901 OLSR::node_id(ch->next_hop())); |
|
1902 |
|
1903 if ((u_int32_t)ih->daddr() == IP_BROADCAST) { |
|
1904 drop(p, DROP_RTR_MAC_CALLBACK); |
|
1905 return; |
|
1906 } |
|
1907 |
|
1908 OLSR_link_tuple* link_tuple = state_.find_link_tuple(ch->next_hop()); |
|
1909 if (link_tuple != NULL) { |
|
1910 link_tuple->lost_time() = now + OLSR_NEIGHB_HOLD_TIME; |
|
1911 link_tuple->time() = now + OLSR_NEIGHB_HOLD_TIME; |
|
1912 nb_loss(link_tuple); |
|
1913 } |
|
1914 drop(p, DROP_RTR_MAC_CALLBACK); |
|
1915 } |
|
1916 #endif |
|
1917 |
|
1918 |
|
1919 |
|
1920 |
|
1921 /// |
|
1922 /// \brief Performs all actions needed when a neighbor loss occurs. |
|
1923 /// |
|
1924 /// Neighbor Set, 2-hop Neighbor Set, MPR Set and MPR Selector Set are updated. |
|
1925 /// |
|
1926 /// \param tuple link tuple with the information of the link to the neighbor which has been lost. |
|
1927 /// |
|
1928 void |
|
1929 RoutingProtocol::NeighborLoss (const LinkTuple &tuple) |
|
1930 { |
|
1931 NS_LOG_DEBUG (Simulator::Now ().GetSeconds () |
|
1932 << "s: OLSR Node " << m_mainAddress |
|
1933 << " LinkTuple " << tuple.neighborIfaceAddr << " -> neighbor loss."); |
|
1934 LinkTupleUpdated (tuple, OLSR_WILL_DEFAULT); |
|
1935 m_state.EraseTwoHopNeighborTuples (GetMainAddress (tuple.neighborIfaceAddr)); |
|
1936 m_state.EraseMprSelectorTuples (GetMainAddress (tuple.neighborIfaceAddr)); |
|
1937 |
|
1938 MprComputation (); |
|
1939 RoutingTableComputation (); |
|
1940 } |
|
1941 |
|
1942 /// |
|
1943 /// \brief Adds a duplicate tuple to the Duplicate Set. |
|
1944 /// |
|
1945 /// \param tuple the duplicate tuple to be added. |
|
1946 /// |
|
1947 void |
|
1948 RoutingProtocol::AddDuplicateTuple (const DuplicateTuple &tuple) |
|
1949 { |
|
1950 /*debug("%f: Node %d adds dup tuple: addr = %d seq_num = %d\n", |
|
1951 Simulator::Now (), |
|
1952 OLSR::node_id(ra_addr()), |
|
1953 OLSR::node_id(tuple->addr()), |
|
1954 tuple->seq_num());*/ |
|
1955 m_state.InsertDuplicateTuple (tuple); |
|
1956 } |
|
1957 |
|
1958 /// |
|
1959 /// \brief Removes a duplicate tuple from the Duplicate Set. |
|
1960 /// |
|
1961 /// \param tuple the duplicate tuple to be removed. |
|
1962 /// |
|
1963 void |
|
1964 RoutingProtocol::RemoveDuplicateTuple (const DuplicateTuple &tuple) |
|
1965 { |
|
1966 /*debug("%f: Node %d removes dup tuple: addr = %d seq_num = %d\n", |
|
1967 Simulator::Now (), |
|
1968 OLSR::node_id(ra_addr()), |
|
1969 OLSR::node_id(tuple->addr()), |
|
1970 tuple->seq_num());*/ |
|
1971 m_state.EraseDuplicateTuple (tuple); |
|
1972 } |
|
1973 |
|
1974 void |
|
1975 RoutingProtocol::LinkTupleAdded (const LinkTuple &tuple, uint8_t willingness) |
|
1976 { |
|
1977 // Creates associated neighbor tuple |
|
1978 NeighborTuple nb_tuple; |
|
1979 nb_tuple.neighborMainAddr = GetMainAddress (tuple.neighborIfaceAddr); |
|
1980 nb_tuple.willingness = willingness; |
|
1981 |
|
1982 if (tuple.symTime >= Simulator::Now ()) |
|
1983 { |
|
1984 nb_tuple.status = NeighborTuple::STATUS_SYM; |
|
1985 } |
|
1986 else |
|
1987 { |
|
1988 nb_tuple.status = NeighborTuple::STATUS_NOT_SYM; |
|
1989 } |
|
1990 |
|
1991 AddNeighborTuple (nb_tuple); |
|
1992 } |
|
1993 |
|
1994 /// |
|
1995 /// \brief Removes a link tuple from the Link Set. |
|
1996 /// |
|
1997 /// \param tuple the link tuple to be removed. |
|
1998 /// |
|
1999 void |
|
2000 RoutingProtocol::RemoveLinkTuple (const LinkTuple &tuple) |
|
2001 { |
|
2002 NS_LOG_DEBUG (Simulator::Now ().GetSeconds () |
|
2003 << "s: OLSR Node " << m_mainAddress |
|
2004 << " LinkTuple " << tuple << " REMOVED."); |
|
2005 |
|
2006 m_state.EraseLinkTuple (tuple); |
|
2007 m_state.EraseNeighborTuple (GetMainAddress (tuple.neighborIfaceAddr)); |
|
2008 |
|
2009 } |
|
2010 |
|
2011 /// |
|
2012 /// \brief This function is invoked when a link tuple is updated. Its aim is to |
|
2013 /// also update the corresponding neighbor tuple if it is needed. |
|
2014 /// |
|
2015 /// \param tuple the link tuple which has been updated. |
|
2016 /// |
|
2017 void |
|
2018 RoutingProtocol::LinkTupleUpdated (const LinkTuple &tuple, uint8_t willingness) |
|
2019 { |
|
2020 // Each time a link tuple changes, the associated neighbor tuple must be recomputed |
|
2021 |
|
2022 NS_LOG_DEBUG (Simulator::Now ().GetSeconds () |
|
2023 << "s: OLSR Node " << m_mainAddress |
|
2024 << " LinkTuple " << tuple << " UPDATED."); |
|
2025 |
|
2026 NeighborTuple *nb_tuple = |
|
2027 m_state.FindNeighborTuple (GetMainAddress (tuple.neighborIfaceAddr)); |
|
2028 |
|
2029 if (nb_tuple == NULL) |
|
2030 { |
|
2031 LinkTupleAdded (tuple, willingness); |
|
2032 nb_tuple = m_state.FindNeighborTuple (GetMainAddress (tuple.neighborIfaceAddr)); |
|
2033 } |
|
2034 |
|
2035 if (nb_tuple != NULL) |
|
2036 { |
|
2037 #ifdef NS3_LOG_ENABLE |
|
2038 int statusBefore = nb_tuple->status; |
|
2039 #endif |
|
2040 if (tuple.symTime >= Simulator::Now ()) |
|
2041 { |
|
2042 nb_tuple->status = NeighborTuple::STATUS_SYM; |
|
2043 NS_LOG_DEBUG (*nb_tuple << "->status = STATUS_SYM; changed:" |
|
2044 << int (statusBefore != nb_tuple->status)); |
|
2045 } |
|
2046 else |
|
2047 { |
|
2048 nb_tuple->status = NeighborTuple::STATUS_NOT_SYM; |
|
2049 NS_LOG_DEBUG (*nb_tuple << "->status = STATUS_NOT_SYM; changed:" |
|
2050 << int (statusBefore != nb_tuple->status)); |
|
2051 } |
|
2052 } |
|
2053 else |
|
2054 { |
|
2055 NS_LOG_WARN ("ERROR! Wanted to update a NeighborTuple but none was found!"); |
|
2056 } |
|
2057 } |
|
2058 |
|
2059 /// |
|
2060 /// \brief Adds a neighbor tuple to the Neighbor Set. |
|
2061 /// |
|
2062 /// \param tuple the neighbor tuple to be added. |
|
2063 /// |
|
2064 void |
|
2065 RoutingProtocol::AddNeighborTuple (const NeighborTuple &tuple) |
|
2066 { |
|
2067 // debug("%f: Node %d adds neighbor tuple: nb_addr = %d status = %s\n", |
|
2068 // Simulator::Now (), |
|
2069 // OLSR::node_id(ra_addr()), |
|
2070 // OLSR::node_id(tuple->neighborMainAddr), |
|
2071 // ((tuple->status() == OLSR_STATUS_SYM) ? "sym" : "not_sym")); |
|
2072 |
|
2073 m_state.InsertNeighborTuple (tuple); |
|
2074 IncrementAnsn (); |
|
2075 } |
|
2076 |
|
2077 /// |
|
2078 /// \brief Removes a neighbor tuple from the Neighbor Set. |
|
2079 /// |
|
2080 /// \param tuple the neighbor tuple to be removed. |
|
2081 /// |
|
2082 void |
|
2083 RoutingProtocol::RemoveNeighborTuple (const NeighborTuple &tuple) |
|
2084 { |
|
2085 // debug("%f: Node %d removes neighbor tuple: nb_addr = %d status = %s\n", |
|
2086 // Simulator::Now (), |
|
2087 // OLSR::node_id(ra_addr()), |
|
2088 // OLSR::node_id(tuple->neighborMainAddr), |
|
2089 // ((tuple->status() == OLSR_STATUS_SYM) ? "sym" : "not_sym")); |
|
2090 |
|
2091 m_state.EraseNeighborTuple (tuple); |
|
2092 IncrementAnsn (); |
|
2093 } |
|
2094 |
|
2095 /// |
|
2096 /// \brief Adds a 2-hop neighbor tuple to the 2-hop Neighbor Set. |
|
2097 /// |
|
2098 /// \param tuple the 2-hop neighbor tuple to be added. |
|
2099 /// |
|
2100 void |
|
2101 RoutingProtocol::AddTwoHopNeighborTuple (const TwoHopNeighborTuple &tuple) |
|
2102 { |
|
2103 // debug("%f: Node %d adds 2-hop neighbor tuple: nb_addr = %d nb2hop_addr = %d\n", |
|
2104 // Simulator::Now (), |
|
2105 // OLSR::node_id(ra_addr()), |
|
2106 // OLSR::node_id(tuple->neighborMainAddr), |
|
2107 // OLSR::node_id(tuple->twoHopNeighborAddr)); |
|
2108 |
|
2109 m_state.InsertTwoHopNeighborTuple (tuple); |
|
2110 } |
|
2111 |
|
2112 /// |
|
2113 /// \brief Removes a 2-hop neighbor tuple from the 2-hop Neighbor Set. |
|
2114 /// |
|
2115 /// \param tuple the 2-hop neighbor tuple to be removed. |
|
2116 /// |
|
2117 void |
|
2118 RoutingProtocol::RemoveTwoHopNeighborTuple (const TwoHopNeighborTuple &tuple) |
|
2119 { |
|
2120 // debug("%f: Node %d removes 2-hop neighbor tuple: nb_addr = %d nb2hop_addr = %d\n", |
|
2121 // Simulator::Now (), |
|
2122 // OLSR::node_id(ra_addr()), |
|
2123 // OLSR::node_id(tuple->neighborMainAddr), |
|
2124 // OLSR::node_id(tuple->twoHopNeighborAddr)); |
|
2125 |
|
2126 m_state.EraseTwoHopNeighborTuple (tuple); |
|
2127 } |
|
2128 |
|
2129 void |
|
2130 RoutingProtocol::IncrementAnsn () |
|
2131 { |
|
2132 m_ansn = (m_ansn + 1) % (OLSR_MAX_SEQ_NUM + 1); |
|
2133 } |
|
2134 |
|
2135 /// |
|
2136 /// \brief Adds an MPR selector tuple to the MPR Selector Set. |
|
2137 /// |
|
2138 /// Advertised Neighbor Sequence Number (ANSN) is also updated. |
|
2139 /// |
|
2140 /// \param tuple the MPR selector tuple to be added. |
|
2141 /// |
|
2142 void |
|
2143 RoutingProtocol::AddMprSelectorTuple (const MprSelectorTuple &tuple) |
|
2144 { |
|
2145 // debug("%f: Node %d adds MPR selector tuple: nb_addr = %d\n", |
|
2146 // Simulator::Now (), |
|
2147 // OLSR::node_id(ra_addr()), |
|
2148 // OLSR::node_id(tuple->main_addr())); |
|
2149 |
|
2150 m_state.InsertMprSelectorTuple (tuple); |
|
2151 IncrementAnsn (); |
|
2152 } |
|
2153 |
|
2154 /// |
|
2155 /// \brief Removes an MPR selector tuple from the MPR Selector Set. |
|
2156 /// |
|
2157 /// Advertised Neighbor Sequence Number (ANSN) is also updated. |
|
2158 /// |
|
2159 /// \param tuple the MPR selector tuple to be removed. |
|
2160 /// |
|
2161 void |
|
2162 RoutingProtocol::RemoveMprSelectorTuple (const MprSelectorTuple &tuple) |
|
2163 { |
|
2164 // debug("%f: Node %d removes MPR selector tuple: nb_addr = %d\n", |
|
2165 // Simulator::Now (), |
|
2166 // OLSR::node_id(ra_addr()), |
|
2167 // OLSR::node_id(tuple->main_addr())); |
|
2168 |
|
2169 m_state.EraseMprSelectorTuple (tuple); |
|
2170 IncrementAnsn (); |
|
2171 } |
|
2172 |
|
2173 /// |
|
2174 /// \brief Adds a topology tuple to the Topology Set. |
|
2175 /// |
|
2176 /// \param tuple the topology tuple to be added. |
|
2177 /// |
|
2178 void |
|
2179 RoutingProtocol::AddTopologyTuple (const TopologyTuple &tuple) |
|
2180 { |
|
2181 // debug("%f: Node %d adds topology tuple: dest_addr = %d last_addr = %d seq = %d\n", |
|
2182 // Simulator::Now (), |
|
2183 // OLSR::node_id(ra_addr()), |
|
2184 // OLSR::node_id(tuple->dest_addr()), |
|
2185 // OLSR::node_id(tuple->last_addr()), |
|
2186 // tuple->seq()); |
|
2187 |
|
2188 m_state.InsertTopologyTuple(tuple); |
|
2189 } |
|
2190 |
|
2191 /// |
|
2192 /// \brief Removes a topology tuple from the Topology Set. |
|
2193 /// |
|
2194 /// \param tuple the topology tuple to be removed. |
|
2195 /// |
|
2196 void |
|
2197 RoutingProtocol::RemoveTopologyTuple (const TopologyTuple &tuple) |
|
2198 { |
|
2199 // debug("%f: Node %d removes topology tuple: dest_addr = %d last_addr = %d seq = %d\n", |
|
2200 // Simulator::Now (), |
|
2201 // OLSR::node_id(ra_addr()), |
|
2202 // OLSR::node_id(tuple->dest_addr()), |
|
2203 // OLSR::node_id(tuple->last_addr()), |
|
2204 // tuple->seq()); |
|
2205 |
|
2206 m_state.EraseTopologyTuple (tuple); |
|
2207 } |
|
2208 |
|
2209 /// |
|
2210 /// \brief Adds an interface association tuple to the Interface Association Set. |
|
2211 /// |
|
2212 /// \param tuple the interface association tuple to be added. |
|
2213 /// |
|
2214 void |
|
2215 RoutingProtocol::AddIfaceAssocTuple (const IfaceAssocTuple &tuple) |
|
2216 { |
|
2217 // debug("%f: Node %d adds iface association tuple: main_addr = %d iface_addr = %d\n", |
|
2218 // Simulator::Now (), |
|
2219 // OLSR::node_id(ra_addr()), |
|
2220 // OLSR::node_id(tuple->main_addr()), |
|
2221 // OLSR::node_id(tuple->iface_addr())); |
|
2222 |
|
2223 m_state.InsertIfaceAssocTuple (tuple); |
|
2224 } |
|
2225 |
|
2226 /// |
|
2227 /// \brief Removes an interface association tuple from the Interface Association Set. |
|
2228 /// |
|
2229 /// \param tuple the interface association tuple to be removed. |
|
2230 /// |
|
2231 void |
|
2232 RoutingProtocol::RemoveIfaceAssocTuple (const IfaceAssocTuple &tuple) |
|
2233 { |
|
2234 // debug("%f: Node %d removes iface association tuple: main_addr = %d iface_addr = %d\n", |
|
2235 // Simulator::Now (), |
|
2236 // OLSR::node_id(ra_addr()), |
|
2237 // OLSR::node_id(tuple->main_addr()), |
|
2238 // OLSR::node_id(tuple->iface_addr())); |
|
2239 |
|
2240 m_state.EraseIfaceAssocTuple (tuple); |
|
2241 } |
|
2242 |
|
2243 |
|
2244 uint16_t RoutingProtocol::GetPacketSequenceNumber () |
|
2245 { |
|
2246 m_packetSequenceNumber = (m_packetSequenceNumber + 1) % (OLSR_MAX_SEQ_NUM + 1); |
|
2247 return m_packetSequenceNumber; |
|
2248 } |
|
2249 |
|
2250 /// Increments message sequence number and returns the new value. |
|
2251 uint16_t RoutingProtocol::GetMessageSequenceNumber () |
|
2252 { |
|
2253 m_messageSequenceNumber = (m_messageSequenceNumber + 1) % (OLSR_MAX_SEQ_NUM + 1); |
|
2254 return m_messageSequenceNumber; |
|
2255 } |
|
2256 |
|
2257 |
|
2258 /// |
|
2259 /// \brief Sends a HELLO message and reschedules the HELLO timer. |
|
2260 /// \param e The event which has expired. |
|
2261 /// |
|
2262 void |
|
2263 RoutingProtocol::HelloTimerExpire () |
|
2264 { |
|
2265 SendHello (); |
|
2266 m_helloTimer.Schedule (m_helloInterval); |
|
2267 } |
|
2268 |
|
2269 /// |
|
2270 /// \brief Sends a TC message (if there exists any MPR selector) and reschedules the TC timer. |
|
2271 /// \param e The event which has expired. |
|
2272 /// |
|
2273 void |
|
2274 RoutingProtocol::TcTimerExpire () |
|
2275 { |
|
2276 if (m_state.GetMprSelectors ().size () > 0) |
|
2277 { |
|
2278 SendTc (); |
|
2279 } |
|
2280 else |
|
2281 { |
|
2282 NS_LOG_DEBUG ("Not sending any TC, no one selected me as MPR."); |
|
2283 } |
|
2284 m_tcTimer.Schedule (m_tcInterval); |
|
2285 } |
|
2286 |
|
2287 /// |
|
2288 /// \brief Sends a MID message (if the node has more than one interface) and resets the MID timer. |
|
2289 /// \warning Currently it does nothing because there is no support for multiple interfaces. |
|
2290 /// \param e The event which has expired. |
|
2291 /// |
|
2292 void |
|
2293 RoutingProtocol::MidTimerExpire () |
|
2294 { |
|
2295 SendMid (); |
|
2296 m_midTimer.Schedule (m_midInterval); |
|
2297 } |
|
2298 |
|
2299 /// |
|
2300 /// \brief Removes tuple if expired. Else timer is rescheduled to expire at tuple.expirationTime. |
|
2301 /// |
|
2302 /// The task of actually removing the tuple is left to the OLSR agent. |
|
2303 /// |
|
2304 /// \param tuple The tuple which has expired. |
|
2305 /// |
|
2306 void |
|
2307 RoutingProtocol::DupTupleTimerExpire (Ipv4Address address, uint16_t sequenceNumber) |
|
2308 { |
|
2309 DuplicateTuple *tuple = |
|
2310 m_state.FindDuplicateTuple (address, sequenceNumber); |
|
2311 if (tuple == NULL) |
|
2312 { |
|
2313 return; |
|
2314 } |
|
2315 if (tuple->expirationTime < Simulator::Now ()) |
|
2316 { |
|
2317 RemoveDuplicateTuple (*tuple); |
|
2318 } |
|
2319 else |
|
2320 { |
|
2321 m_events.Track (Simulator::Schedule (DELAY (tuple->expirationTime), |
|
2322 &RoutingProtocol::DupTupleTimerExpire, this, |
|
2323 address, sequenceNumber)); |
|
2324 } |
|
2325 } |
|
2326 |
|
2327 /// |
|
2328 /// \brief Removes tuple_ if expired. Else if symmetric time |
|
2329 /// has expired then it is assumed a neighbor loss and agent_->nb_loss() |
|
2330 /// is called. In this case the timer is rescheduled to expire at |
|
2331 /// tuple_->time(). Otherwise the timer is rescheduled to expire at |
|
2332 /// the minimum between tuple_->time() and tuple_->sym_time(). |
|
2333 /// |
|
2334 /// The task of actually removing the tuple is left to the OLSR agent. |
|
2335 /// |
|
2336 /// \param e The event which has expired. |
|
2337 /// |
|
2338 void |
|
2339 RoutingProtocol::LinkTupleTimerExpire (Ipv4Address neighborIfaceAddr) |
|
2340 { |
|
2341 Time now = Simulator::Now (); |
|
2342 |
|
2343 // the tuple parameter may be a stale copy; get a newer version from m_state |
|
2344 LinkTuple *tuple = m_state.FindLinkTuple (neighborIfaceAddr); |
|
2345 if (tuple == NULL) |
|
2346 { |
|
2347 return; |
|
2348 } |
|
2349 if (tuple->time < now) |
|
2350 { |
|
2351 RemoveLinkTuple (*tuple); |
|
2352 } |
|
2353 else if (tuple->symTime < now) |
|
2354 { |
|
2355 if (m_linkTupleTimerFirstTime) |
|
2356 m_linkTupleTimerFirstTime = false; |
|
2357 else |
|
2358 NeighborLoss (*tuple); |
|
2359 |
|
2360 m_events.Track (Simulator::Schedule (DELAY (tuple->time), |
|
2361 &RoutingProtocol::LinkTupleTimerExpire, this, |
|
2362 neighborIfaceAddr)); |
|
2363 } |
|
2364 else |
|
2365 { |
|
2366 m_events.Track (Simulator::Schedule (DELAY (std::min (tuple->time, tuple->symTime)), |
|
2367 &RoutingProtocol::LinkTupleTimerExpire, this, |
|
2368 neighborIfaceAddr)); |
|
2369 } |
|
2370 } |
|
2371 |
|
2372 /// |
|
2373 /// \brief Removes tuple_ if expired. Else the timer is rescheduled to expire at tuple_->time(). |
|
2374 /// |
|
2375 /// The task of actually removing the tuple is left to the OLSR agent. |
|
2376 /// |
|
2377 /// \param e The event which has expired. |
|
2378 /// |
|
2379 void |
|
2380 RoutingProtocol::Nb2hopTupleTimerExpire (Ipv4Address neighborMainAddr, Ipv4Address twoHopNeighborAddr) |
|
2381 { |
|
2382 TwoHopNeighborTuple *tuple; |
|
2383 tuple = m_state.FindTwoHopNeighborTuple (neighborMainAddr, twoHopNeighborAddr); |
|
2384 if (tuple == NULL) |
|
2385 { |
|
2386 return; |
|
2387 } |
|
2388 if (tuple->expirationTime < Simulator::Now ()) |
|
2389 { |
|
2390 RemoveTwoHopNeighborTuple (*tuple); |
|
2391 } |
|
2392 else |
|
2393 { |
|
2394 m_events.Track (Simulator::Schedule (DELAY (tuple->expirationTime), |
|
2395 &RoutingProtocol::Nb2hopTupleTimerExpire, |
|
2396 this, neighborMainAddr, twoHopNeighborAddr)); |
|
2397 } |
|
2398 } |
|
2399 |
|
2400 /// |
|
2401 /// \brief Removes tuple_ if expired. Else the timer is rescheduled to expire at tuple_->time(). |
|
2402 /// |
|
2403 /// The task of actually removing the tuple is left to the OLSR agent. |
|
2404 /// |
|
2405 /// \param e The event which has expired. |
|
2406 /// |
|
2407 void |
|
2408 RoutingProtocol::MprSelTupleTimerExpire (Ipv4Address mainAddr) |
|
2409 { |
|
2410 MprSelectorTuple *tuple = m_state.FindMprSelectorTuple (mainAddr); |
|
2411 if (tuple == NULL) |
|
2412 { |
|
2413 return; |
|
2414 } |
|
2415 if (tuple->expirationTime < Simulator::Now ()) |
|
2416 { |
|
2417 RemoveMprSelectorTuple (*tuple); |
|
2418 } |
|
2419 else |
|
2420 { |
|
2421 m_events.Track (Simulator::Schedule (DELAY (tuple->expirationTime), |
|
2422 &RoutingProtocol::MprSelTupleTimerExpire, |
|
2423 this, mainAddr)); |
|
2424 } |
|
2425 } |
|
2426 |
|
2427 /// |
|
2428 /// \brief Removes tuple_ if expired. Else the timer is rescheduled to expire at tuple_->time(). |
|
2429 /// |
|
2430 /// The task of actually removing the tuple is left to the OLSR agent. |
|
2431 /// |
|
2432 /// \param e The event which has expired. |
|
2433 /// |
|
2434 void |
|
2435 RoutingProtocol::TopologyTupleTimerExpire (Ipv4Address destAddr, Ipv4Address lastAddr) |
|
2436 { |
|
2437 TopologyTuple *tuple = m_state.FindTopologyTuple (destAddr, lastAddr); |
|
2438 if (tuple == NULL) |
|
2439 { |
|
2440 return; |
|
2441 } |
|
2442 if (tuple->expirationTime < Simulator::Now ()) |
|
2443 { |
|
2444 RemoveTopologyTuple (*tuple); |
|
2445 } |
|
2446 else |
|
2447 { |
|
2448 m_events.Track (Simulator::Schedule (DELAY (tuple->expirationTime), |
|
2449 &RoutingProtocol::TopologyTupleTimerExpire, |
|
2450 this, tuple->destAddr, tuple->lastAddr)); |
|
2451 } |
|
2452 } |
|
2453 |
|
2454 /// |
|
2455 /// \brief Removes tuple_ if expired. Else timer is rescheduled to expire at tuple_->time(). |
|
2456 /// \warning Actually this is never invoked because there is no support for multiple interfaces. |
|
2457 /// \param e The event which has expired. |
|
2458 /// |
|
2459 void |
|
2460 RoutingProtocol::IfaceAssocTupleTimerExpire (Ipv4Address ifaceAddr) |
|
2461 { |
|
2462 IfaceAssocTuple *tuple = m_state.FindIfaceAssocTuple (ifaceAddr); |
|
2463 if (tuple == NULL) |
|
2464 { |
|
2465 return; |
|
2466 } |
|
2467 if (tuple->time < Simulator::Now ()) |
|
2468 { |
|
2469 RemoveIfaceAssocTuple (*tuple); |
|
2470 } |
|
2471 else |
|
2472 { |
|
2473 m_events.Track (Simulator::Schedule (DELAY (tuple->time), |
|
2474 &RoutingProtocol::IfaceAssocTupleTimerExpire, |
|
2475 this, ifaceAddr)); |
|
2476 } |
|
2477 } |
|
2478 |
|
2479 /// |
|
2480 /// \brief Clears the routing table and frees the memory assigned to each one of its entries. |
|
2481 /// |
|
2482 void |
|
2483 RoutingProtocol::Clear () |
|
2484 { |
|
2485 NS_LOG_FUNCTION_NOARGS (); |
|
2486 m_table.clear (); |
|
2487 } |
|
2488 |
|
2489 /// |
|
2490 /// \brief Deletes the entry whose destination address is given. |
|
2491 /// \param dest address of the destination node. |
|
2492 /// |
|
2493 void |
|
2494 RoutingProtocol::RemoveEntry (Ipv4Address const &dest) |
|
2495 { |
|
2496 m_table.erase (dest); |
|
2497 } |
|
2498 |
|
2499 /// |
|
2500 /// \brief Looks up an entry for the specified destination address. |
|
2501 /// \param dest destination address. |
|
2502 /// \param outEntry output parameter to hold the routing entry result, if fuond |
|
2503 /// \return true if found, false if not found |
|
2504 /// |
|
2505 bool |
|
2506 RoutingProtocol::Lookup (Ipv4Address const &dest, |
|
2507 RoutingTableEntry &outEntry) const |
|
2508 { |
|
2509 // Get the iterator at "dest" position |
|
2510 std::map<Ipv4Address, RoutingTableEntry>::const_iterator it = |
|
2511 m_table.find (dest); |
|
2512 // If there is no route to "dest", return NULL |
|
2513 if (it == m_table.end ()) |
|
2514 return false; |
|
2515 outEntry = it->second; |
|
2516 return true; |
|
2517 } |
|
2518 |
|
2519 /// |
|
2520 /// \brief Finds the appropiate entry which must be used in order to forward |
|
2521 /// a data packet to a next hop (given a destination). |
|
2522 /// |
|
2523 /// Imagine a routing table like this: [A,B] [B,C] [C,C]; being each pair of the |
|
2524 /// form [dest addr,next-hop addr]. In this case, if this function is invoked with |
|
2525 /// [A,B] then pair [C,C] is returned because C is the next hop that must be used |
|
2526 /// to forward a data packet destined to A. That is, C is a neighbor of this node, |
|
2527 /// but B isn't. This function finds the appropiate neighbor for forwarding a packet. |
|
2528 /// |
|
2529 /// \param entry the routing table entry which indicates the destination node |
|
2530 /// we are interested in. |
|
2531 /// \return the appropiate routing table entry which indicates the next |
|
2532 /// hop which must be used for forwarding a data packet, or NULL |
|
2533 /// if there is no such entry. |
|
2534 /// |
|
2535 bool |
|
2536 RoutingProtocol::FindSendEntry (RoutingTableEntry const &entry, |
|
2537 RoutingTableEntry &outEntry) const |
|
2538 { |
|
2539 outEntry = entry; |
|
2540 while (outEntry.destAddr != outEntry.nextAddr) |
|
2541 { |
|
2542 if (not Lookup(outEntry.nextAddr, outEntry)) |
|
2543 return false; |
|
2544 } |
|
2545 return true; |
|
2546 } |
|
2547 |
|
2548 |
|
2549 bool |
|
2550 RoutingProtocol::RequestRoute (uint32_t ifIndex, |
|
2551 const Ipv4Header &ipHeader, |
|
2552 Ptr<Packet> packet, |
|
2553 RouteReplyCallback routeReply) |
|
2554 { |
|
2555 RoutingTableEntry entry1, entry2; |
|
2556 if (Lookup (ipHeader.GetDestination (), entry1)) |
|
2557 { |
|
2558 bool foundSendEntry = FindSendEntry (entry1, entry2); |
|
2559 if (!foundSendEntry) |
|
2560 NS_FATAL_ERROR ("FindSendEntry failure"); |
|
2561 |
|
2562 Ipv4Route route = Ipv4Route::CreateHostRouteTo |
|
2563 (ipHeader.GetDestination (), entry2.nextAddr, entry2.interface); |
|
2564 |
|
2565 NS_LOG_DEBUG ("Olsr node " << m_mainAddress |
|
2566 << ": RouteRequest for dest=" << ipHeader.GetDestination () |
|
2567 << " --> nestHop=" << entry2.nextAddr |
|
2568 << " interface=" << entry2.interface); |
|
2569 |
|
2570 routeReply (true, route, packet, ipHeader); |
|
2571 return true; |
|
2572 } |
|
2573 else |
|
2574 { |
|
2575 #ifdef NS3_LOG_ENABLE |
|
2576 NS_LOG_DEBUG ("Olsr node " << m_mainAddress |
|
2577 << ": RouteRequest for dest=" << ipHeader.GetDestination () |
|
2578 << " --> NOT FOUND; ** Dumping routing table..."); |
|
2579 for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin (); |
|
2580 iter != m_table.end (); iter++) |
|
2581 { |
|
2582 NS_LOG_DEBUG ("dest=" << iter->first << " --> next=" << iter->second.nextAddr |
|
2583 << " via interface " << iter->second.interface); |
|
2584 } |
|
2585 |
|
2586 NS_LOG_DEBUG ("** Routing table dump end."); |
|
2587 #endif |
|
2588 return false; |
|
2589 } |
|
2590 } |
|
2591 |
|
2592 bool |
|
2593 RoutingProtocol::RequestIfIndex (Ipv4Address destination, |
|
2594 uint32_t& ifIndex) |
|
2595 { |
|
2596 RoutingTableEntry entry1, entry2; |
|
2597 if (Lookup (destination, entry1)) |
|
2598 { |
|
2599 bool foundSendEntry = FindSendEntry (entry1, entry2); |
|
2600 if (!foundSendEntry) |
|
2601 NS_FATAL_ERROR ("FindSendEntry failure"); |
|
2602 ifIndex = entry2.interface; |
|
2603 return true; |
|
2604 } |
|
2605 else |
|
2606 { |
|
2607 return false; |
|
2608 } |
|
2609 } |
|
2610 |
|
2611 |
|
2612 /// |
|
2613 /// \brief Adds a new entry into the routing table. |
|
2614 /// |
|
2615 /// If an entry for the given destination existed, it is deleted and freed. |
|
2616 /// |
|
2617 /// \param dest address of the destination node. |
|
2618 /// \param next address of the next hop node. |
|
2619 /// \param iface address of the local interface. |
|
2620 /// \param dist distance to the destination node. |
|
2621 /// |
|
2622 void |
|
2623 RoutingProtocol::AddEntry (Ipv4Address const &dest, |
|
2624 Ipv4Address const &next, |
|
2625 uint32_t interface, |
|
2626 uint32_t distance) |
|
2627 { |
|
2628 NS_LOG_FUNCTION (this << dest << next << interface << distance << m_mainAddress); |
|
2629 |
|
2630 NS_ASSERT (distance > 0); |
|
2631 |
|
2632 // Creates a new rt entry with specified values |
|
2633 RoutingTableEntry &entry = m_table[dest]; |
|
2634 |
|
2635 entry.destAddr = dest; |
|
2636 entry.nextAddr = next; |
|
2637 entry.interface = interface; |
|
2638 entry.distance = distance; |
|
2639 } |
|
2640 |
|
2641 void |
|
2642 RoutingProtocol::AddEntry (Ipv4Address const &dest, |
|
2643 Ipv4Address const &next, |
|
2644 Ipv4Address const &interfaceAddress, |
|
2645 uint32_t distance) |
|
2646 { |
|
2647 NS_LOG_FUNCTION (this << dest << next << interfaceAddress << distance << m_mainAddress); |
|
2648 |
|
2649 NS_ASSERT (distance > 0); |
|
2650 NS_ASSERT (m_ipv4); |
|
2651 |
|
2652 RoutingTableEntry entry; |
|
2653 for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++) |
|
2654 { |
|
2655 if (m_ipv4->GetAddress (i) == interfaceAddress) |
|
2656 { |
|
2657 AddEntry (dest, next, i, distance); |
|
2658 return; |
|
2659 } |
|
2660 } |
|
2661 NS_ASSERT (false); // should not be reached |
|
2662 AddEntry (dest, next, 0, distance); |
|
2663 } |
|
2664 |
|
2665 |
|
2666 std::vector<RoutingTableEntry> |
|
2667 RoutingProtocol::GetEntries () const |
|
2668 { |
|
2669 std::vector<RoutingTableEntry> retval; |
|
2670 for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin (); |
|
2671 iter != m_table.end (); iter++) |
|
2672 { |
|
2673 retval.push_back (iter->second); |
|
2674 } |
|
2675 return retval; |
|
2676 } |
|
2677 |
|
2678 |
|
2679 }} // namespace olsr, ns3 |
|
2680 |
|
2681 |