INET Framework for OMNeT++/OMNEST
inet::IPv6Tunneling Class Reference

Management of IP tunnels. More...

#include <IPv6Tunneling.h>

Inheritance diagram for inet::IPv6Tunneling:
inet::ILifecycle

Classes

struct  equalTunnel
 
struct  Tunnel
 

Public Types

enum  TunnelType {
  INVALID = 0, SPLIT, NON_SPLIT, NORMAL,
  T2RH, HA_OPT, MOBILITY
}
 

Public Member Functions

 IPv6Tunneling ()
 
virtual void initialize (int stage) override
 Initialize tunnel manager. More...
 
virtual int numInitStages () const override
 
virtual void handleMessage (cMessage *msg) override
 Receive messages from IPv6 module and encapsulate/decapsulate them. More...
 
virtual bool handleOperationStage (LifecycleOperation *operation, int stage, IDoneCallback *doneCallback) override
 Perform one stage of a lifecycle operation. More...
 
int createTunnel (TunnelType tunnelType, const IPv6Address &src, const IPv6Address &dest, const IPv6Address &destTrigger=IPv6Address::UNSPECIFIED_ADDRESS)
 Creates a tunnel with given entry and exit point, which will be used for datagrams destined for destTrigger. More...
 
bool destroyTunnel (const IPv6Address &src, const IPv6Address &dest, const IPv6Address &destTrigger)
 Creates a pseudo-tunnel for use with either Type 2 Routing Header or Home Address Option with given entry and exit point, which will be used for datagrams destined for destTrigger. More...
 
void destroyTunnels (const IPv6Address &entry)
 Remove all tunnels with provided entry point. More...
 
void destroyTunnel (const IPv6Address &entry, const IPv6Address &exit)
 Remove the tunnel with the provided entry and exit point. More...
 
void destroyTunnelForExitAndTrigger (const IPv6Address &exit, const IPv6Address &trigger)
 Remove the tunnel with the provided exit point and trigger. More...
 
void destroyTunnelForEntryAndTrigger (const IPv6Address &entry, const IPv6Address &trigger)
 Remove the tunnel with the provided entry point and trigger. More...
 
void destroyTunnelFromTrigger (const IPv6Address &trigger)
 Remove the tunnel with the provided destination trigger. More...
 
int getVIfIndexForDest (const IPv6Address &destAddress)
 Returns the virtual interface identifier for the tunnel which has the provided destination as destination trigger. More...
 
virtual int getVIfIndexForDest (const IPv6Address &destAddress, TunnelType tunnelType)
 This method is equivalent for getVIfIndexForDest() except that it only searches for either "normal" or mobility tunnels. More...
 
bool isTunnelExit (const IPv6Address &exit)
 This method is equivalent for getVIfIndexForDest() except that it only searches for pseudo tunnels (T2RH, etc.). More...
 
- Public Member Functions inherited from inet::ILifecycle
virtual ~ILifecycle ()
 

Protected Types

typedef std::map< int, struct TunnelTunnels
 
typedef Tunnels::const_iterator TI
 

Protected Member Functions

int findTunnel (const IPv6Address &src, const IPv6Address &dest, const IPv6Address &destTrigger) const
 Returns the type of the tunnels: non-split, split, T2RH, ... More...
 
void encapsulateDatagram (IPv6Datagram *dgram)
 Encapsulate a datagram with tunnel headers. More...
 
void decapsulateDatagram (IPv6Datagram *dgram)
 Strip tunnel headers from datagram. More...
 

Protected Attributes

IInterfaceTableift = nullptr
 
IPv6RoutingTablert = nullptr
 
Tunnels tunnels
 
int vIfIndexTop = 0
 
int noOfNonSplitTunnels = 0
 

Private Member Functions

int lookupTunnels (const IPv6Address &dest)
 Search through all tunnels and locate one entry which is anything but a non-split tunnel and has a destination trigger for the provided address. More...
 
int doPrefixMatch (const IPv6Address &dest)
 Search through all tunnels and locate one entry which is a non-split tunnel (later on this could be exteded to searching for a tunnel that has a prefix matching the provided address). More...
 
void resetVIfIndex ()
 Reset the vIfIndex to its starting value if no tunnels exist anymore. More...
 

Friends

std::ostream & operator<< (std::ostream &os, const IPv6Tunneling::Tunnel &tun)
 

Detailed Description

Management of IP tunnels.

Member Typedef Documentation

typedef Tunnels::const_iterator inet::IPv6Tunneling::TI
protected
typedef std::map<int, struct Tunnel> inet::IPv6Tunneling::Tunnels
protected

Member Enumeration Documentation

Enumerator
INVALID 
SPLIT 
NON_SPLIT 
NORMAL 
T2RH 
HA_OPT 
MOBILITY 
48  {
49  INVALID = 0,
50  SPLIT,
51  NON_SPLIT,
52  NORMAL, // either split or non-split
53  T2RH,
54  HA_OPT,
55  MOBILITY // either T2RH or HA_OPT
56  };
Definition: IPv6Tunneling.h:50
Definition: IPv6Tunneling.h:54
Definition: IPv6Tunneling.h:51
Definition: IPv6Tunneling.h:53
Definition: IPv6Tunneling.h:52
Definition: IPv6Tunneling.h:55
Definition: IPv6Tunneling.h:49

Constructor & Destructor Documentation

inet::IPv6Tunneling::IPv6Tunneling ( )
59 {
60 }

Member Function Documentation

int inet::IPv6Tunneling::createTunnel ( TunnelType  tunnelType,
const IPv6Address src,
const IPv6Address dest,
const IPv6Address destTrigger = IPv6Address::UNSPECIFIED_ADDRESS 
)

Creates a tunnel with given entry and exit point, which will be used for datagrams destined for destTrigger.

Type of tunnel (normal tunnel, mobility related pseudo-tunnel) is determined by first parameter. Returns virtual interface index.

Referenced by inet::IPv6RoutingTable::configureTunnelFromXML(), inet::xMIPv6::processBAMessage(), and inet::xMIPv6::processBUMessage().

112 {
113  ASSERT(entry != IPv6Address::UNSPECIFIED_ADDRESS);
114  ASSERT(exit != IPv6Address::UNSPECIFIED_ADDRESS);
115 
116  // Test for entry and exit point node pointing to same node i.e. localDeliver
117  // addresses to prevent loopback encapsulation 4.1.2
118  if ((tunnelType == NORMAL || tunnelType == SPLIT || tunnelType == NON_SPLIT) // check does not work for T2RH or HoA_Opt. Why?
119  && rt->isLocalAddress(entry) && rt->isLocalAddress(exit))
120  {
121  EV_INFO << "Cannot create tunnel with local endpoints (prevents loopback tunneling)" << endl;
122  return 0;
123  }
124 
125  int search = findTunnel(entry, exit, destTrigger);
126  if (search != 0) {
127  EV_INFO << "Tunnel with entry = " << entry << ", exit = " << exit << " and trigger = "
128  << destTrigger << " already exists!" << endl;
129  return search;
130  }
131 
133  throw cRuntimeError("Error: Not more than %d tunnels supported!", INT_MAX - ift->getBiggestInterfaceId());
134 
135  if ((destTrigger == IPv6Address::UNSPECIFIED_ADDRESS) && (noOfNonSplitTunnels == 1))
136  throw cRuntimeError("Error: Not more than 1 non-split tunnel supported!");
137 
138  // 6.1-6.2
139  ASSERT(entry.isUnicast());
140  tunnels[vIfIndexTop] = Tunnel(entry, exit, destTrigger);
141 
142  if (tunnelType == NORMAL || tunnelType == SPLIT || tunnelType == NON_SPLIT) {
143  if (destTrigger == IPv6Address::UNSPECIFIED_ADDRESS) {
144  // this is a "full" tunnel over which everything gets routed
145  tunnels[vIfIndexTop].tunnelType = NON_SPLIT;
147  }
148 
149  // default values: 5.
150  // 6.4
151  tunnels[vIfIndexTop].trafficClass = 0;
152 
153  // 6.5
154  tunnels[vIfIndexTop].flowLabel = 0;
155 
156  // 6.3
157  // The tunnel hop limit default value for hosts is the IPv6 Neighbor
158  // Discovery advertised hop limit [ND-Spec].
159  if (rt->isRouter())
161  else
162  tunnels[vIfIndexTop].hopLimit = 255;
163 
164  // 6.7
165  // TODO perform path MTU on link (interface resolved via exit address)
166  tunnels[vIfIndexTop].tunnelMTU = IPv6_MIN_MTU - 40;
167 
168  EV_INFO << "Tunneling: Created tunnel with entry=" << entry << ", exit=" << exit
169  << " and trigger=" << destTrigger << endl;
170  }
171  else if (tunnelType == T2RH || tunnelType == HA_OPT) {
172  tunnels[vIfIndexTop].tunnelType = tunnelType;
173 
174  if (tunnelType == T2RH)
175  EV_INFO << "Tunneling: Created RH2 path with entry=" << entry << ", exit=" << exit
176  << " and trigger=" << destTrigger << endl;
177  else
178  EV_INFO << "Tunneling: Created HA option path with entry=" << entry << ", exit=" << exit
179  << " and trigger=" << destTrigger << endl;
180  }
181  else {
182  throw cRuntimeError("tunnel type %d not supported for createTunnel()", tunnelType);
183  }
184 
185  if (hasGUI())
186  bubble("Created Tunnel");
187 
188  return vIfIndexTop--; // decrement vIfIndex for use with next createTunnel() call
189 }
virtual int getBiggestInterfaceId() const =0
Returns the biggest interface Id.
Definition: IPv6Tunneling.h:50
Definition: IPv6Tunneling.h:54
IInterfaceTable * ift
Definition: IPv6Tunneling.h:59
#define IPv6__INET_DEFAULT_ROUTER_HOPLIMIT
Definition: IPv6InterfaceData.h:44
Definition: IPv6Tunneling.h:51
Definition: IPv6Tunneling.h:53
Definition: IPv6Tunneling.h:52
#define IPv6_MIN_MTU
Definition: IPv6InterfaceData.h:38
int findTunnel(const IPv6Address &src, const IPv6Address &dest, const IPv6Address &destTrigger) const
Returns the type of the tunnels: non-split, split, T2RH, ...
Definition: IPv6Tunneling.cc:191
IPv6RoutingTable * rt
Definition: IPv6Tunneling.h:60
static const IPv6Address UNSPECIFIED_ADDRESS
The unspecified address.
Definition: IPv6Address.h:66
virtual bool isRouter() const
IP forwarding on/off.
Definition: IPv6RoutingTable.h:155
int noOfNonSplitTunnels
Definition: IPv6Tunneling.h:130
virtual bool isLocalAddress(const IPv6Address &dest) const
Checks if the address is one of the host&#39;s addresses, i.e.
Definition: IPv6RoutingTable.cc:423
Tunnels tunnels
Definition: IPv6Tunneling.h:124
int vIfIndexTop
Definition: IPv6Tunneling.h:127
void inet::IPv6Tunneling::decapsulateDatagram ( IPv6Datagram dgram)
protected

Strip tunnel headers from datagram.

Referenced by handleMessage().

479 {
480  // decapsulation is performed in IPv6 module
481  // just update controlInfo
482  IPv6ControlInfo *controlInfo = check_and_cast<IPv6ControlInfo *>(dgram->removeControlInfo());
483 
484 #ifdef WITH_xMIPv6
485  // we only decapsulate packets for which we have a tunnel
486  // where the exit point is equal to the packets source
487  // 11.9.07 - CB
488  if (rt->isHomeAgent() && !isTunnelExit(controlInfo->getSrcAddr())) {
489  /*RFC 3775, 10.4.5
490  Otherwise, when a home agent decapsulates a tunneled packet from
491  the mobile node, the home agent MUST verify that the Source
492  Address in the tunnel IP header is the mobile node's primary
493  care-of address. Otherwise, any node in the Internet could send
494  traffic through the home agent and escape ingress filtering
495  limitations. This simple check forces the attacker to know the
496  current location of the real mobile node and be able to defeat
497  ingress filtering. This check is not necessary if the reverse-
498  tunneled packet is protected by ESP in tunnel mode.*/
499  EV_INFO << "Dropping packet: source address of tunnel IP header different from tunnel exit points!" << endl;
500  delete controlInfo;
501  delete dgram;
502  return;
503  }
504 #endif // ifdef WITH_xMIPv6
505 
506  // FIX: we leave the interface Id to it's previous value to make sure
507  // that later processing knowns from which interface the datagram came from
508  // (important if several interfaces are available)
509  //controlInfo->setInterfaceId(-1);
510  dgram->setControlInfo(controlInfo);
511 
512  send(dgram, "linkLayerOut");
513 
514 #ifdef WITH_xMIPv6
515  // Alain Tigyo, 21.03.2008
516  // The following code is used for triggering RO to a CN
517  InterfaceEntry *ie = ift->getInterfaceById(controlInfo->getInterfaceId());
518  if (rt->isMobileNode() && (controlInfo->getSrcAddr() == ie->ipv6Data()->getHomeAgentAddress())
519  && (dgram->getTransportProtocol() != IP_PROT_IPv6EXT_MOB))
520  {
521  EV_INFO << "Checking Route Optimization for: " << dgram->getSrcAddress() << endl;
522  xMIPv6 *mipv6 = findModuleFromPar<xMIPv6>(par("xmipv6Module"), this);
523  if (mipv6)
524  mipv6->triggerRouteOptimization(dgram->getSrcAddress(), ie->ipv6Data()->getMNHomeAddress(), ie);
525  }
526 #endif // ifdef WITH_xMIPv6
527 }
virtual InterfaceEntry * getInterfaceById(int id) const =0
Returns an interface by its Id.
IInterfaceTable * ift
Definition: IPv6Tunneling.h:59
bool isMobileNode() const
Determine whether a node is a Mobile Node or Correspondent Node: MN if TRUE or else a CN...
Definition: IPv6RoutingTable.h:181
IPv6RoutingTable * rt
Definition: IPv6Tunneling.h:60
bool isTunnelExit(const IPv6Address &exit)
This method is equivalent for getVIfIndexForDest() except that it only searches for pseudo tunnels (T...
Definition: IPv6Tunneling.cc:562
Definition: IPProtocolId_m.h:100
bool isHomeAgent() const
Determine whether normal Router or Home Agent.
Definition: IPv6RoutingTable.h:170
bool inet::IPv6Tunneling::destroyTunnel ( const IPv6Address src,
const IPv6Address dest,
const IPv6Address destTrigger 
)

Creates a pseudo-tunnel for use with either Type 2 Routing Header or Home Address Option with given entry and exit point, which will be used for datagrams destined for destTrigger.

Returns virtual interface index. Remove tunnel and the associated entries from destination cache

Referenced by inet::xMIPv6::cancelEntries(), destroyTunnel(), destroyTunnelForEntryAndTrigger(), destroyTunnelForExitAndTrigger(), destroyTunnelFromTrigger(), destroyTunnels(), inet::xMIPv6::handleBULExpiry(), and inet::xMIPv6::returningHome().

205 {
206  EV_INFO << "Destroy tunnel entry =" << src << ", exit = " << dest
207  << ", destTrigger = " << destTrigger << "\n";
208 
209  // search for tunnel with given entry and exit point as well as trigger
210  int vIfIndex = findTunnel(src, dest, destTrigger);
211 
212  if (vIfIndex == 0) {
213  EV_WARN << "Tunnel not found\n";
214  return false;
215  }
216 
217  // if we delete a non-split tunnel, then we can
218  // also decrement the appropriate counter
219  if (tunnels[vIfIndex].tunnelType == NON_SPLIT)
221 
222  // TODO store vIfIndex for later reuse when creating a new tunnel
223  tunnels.erase(vIfIndex);
224 
225  // reset the index if we do not have a single tunnel anymore
226  resetVIfIndex();
227 
228  if (hasGUI())
229  bubble("Destroyed Tunnel");
230 
231  return true;
232 }
Definition: IPv6Tunneling.h:51
int findTunnel(const IPv6Address &src, const IPv6Address &dest, const IPv6Address &destTrigger) const
Returns the type of the tunnels: non-split, split, T2RH, ...
Definition: IPv6Tunneling.cc:191
int noOfNonSplitTunnels
Definition: IPv6Tunneling.h:130
Tunnels tunnels
Definition: IPv6Tunneling.h:124
void resetVIfIndex()
Reset the vIfIndex to its starting value if no tunnels exist anymore.
Definition: IPv6Tunneling.h:266
void inet::IPv6Tunneling::destroyTunnel ( const IPv6Address entry,
const IPv6Address exit 
)

Remove the tunnel with the provided entry and exit point.

235 {
236  for (auto it = tunnels.begin(); it != tunnels.end(); ) {
237  if (it->second.entry == entry && it->second.exit == exit) {
238  destroyTunnel(it->second.entry, it->second.exit, it->second.destTrigger);
239  break;
240  }
241  else
242  ++it;
243  }
244 
245  // reset the index if we do not have a single tunnel anymore
246  resetVIfIndex();
247 }
Tunnels tunnels
Definition: IPv6Tunneling.h:124
void resetVIfIndex()
Reset the vIfIndex to its starting value if no tunnels exist anymore.
Definition: IPv6Tunneling.h:266
bool destroyTunnel(const IPv6Address &src, const IPv6Address &dest, const IPv6Address &destTrigger)
Creates a pseudo-tunnel for use with either Type 2 Routing Header or Home Address Option with given e...
Definition: IPv6Tunneling.cc:203
void inet::IPv6Tunneling::destroyTunnelForEntryAndTrigger ( const IPv6Address entry,
const IPv6Address trigger 
)

Remove the tunnel with the provided entry point and trigger.

Referenced by inet::xMIPv6::cancelEntries(), and inet::xMIPv6::processBUMessage().

265 {
266  for (auto it = tunnels.begin(); it != tunnels.end(); ) {
267  if (it->second.entry == entry && it->second.destTrigger == trigger) {
268  destroyTunnel(it->second.entry, it->second.exit, it->second.destTrigger);
269  break;
270  }
271  else
272  ++it;
273  }
274 
275  // reset the index if we do not have a single tunnel anymore
276  resetVIfIndex();
277 }
Tunnels tunnels
Definition: IPv6Tunneling.h:124
void resetVIfIndex()
Reset the vIfIndex to its starting value if no tunnels exist anymore.
Definition: IPv6Tunneling.h:266
bool destroyTunnel(const IPv6Address &src, const IPv6Address &dest, const IPv6Address &destTrigger)
Creates a pseudo-tunnel for use with either Type 2 Routing Header or Home Address Option with given e...
Definition: IPv6Tunneling.cc:203
void inet::IPv6Tunneling::destroyTunnelForExitAndTrigger ( const IPv6Address exit,
const IPv6Address trigger 
)

Remove the tunnel with the provided exit point and trigger.

Referenced by inet::xMIPv6::initiateMIPv6Protocol(), inet::xMIPv6::processBAMessage(), and inet::xMIPv6::returningHome().

250 {
251  for (auto it = tunnels.begin(); it != tunnels.end(); ) {
252  if (it->second.exit == exit && it->second.destTrigger == trigger) {
253  destroyTunnel(it->second.entry, it->second.exit, it->second.destTrigger);
254  break;
255  }
256  else
257  ++it;
258  }
259 
260  // reset the index if we do not have a single tunnel anymore
261  resetVIfIndex();
262 }
Tunnels tunnels
Definition: IPv6Tunneling.h:124
void resetVIfIndex()
Reset the vIfIndex to its starting value if no tunnels exist anymore.
Definition: IPv6Tunneling.h:266
bool destroyTunnel(const IPv6Address &src, const IPv6Address &dest, const IPv6Address &destTrigger)
Creates a pseudo-tunnel for use with either Type 2 Routing Header or Home Address Option with given e...
Definition: IPv6Tunneling.cc:203
void inet::IPv6Tunneling::destroyTunnelFromTrigger ( const IPv6Address trigger)

Remove the tunnel with the provided destination trigger.

Referenced by inet::xMIPv6::handleBCExpiry(), and inet::xMIPv6::processBUMessage().

297 {
298  for (auto & elem : tunnels) {
299  if (elem.second.destTrigger == trigger) {
300  destroyTunnel(elem.second.entry, elem.second.exit, elem.second.destTrigger);
301 
302  // reset the index if we do not have a single tunnel anymore
303  resetVIfIndex();
304 
305  return; // there can not be more than one tunnel for a trigger
306  }
307  }
308 }
Tunnels tunnels
Definition: IPv6Tunneling.h:124
void resetVIfIndex()
Reset the vIfIndex to its starting value if no tunnels exist anymore.
Definition: IPv6Tunneling.h:266
bool destroyTunnel(const IPv6Address &src, const IPv6Address &dest, const IPv6Address &destTrigger)
Creates a pseudo-tunnel for use with either Type 2 Routing Header or Home Address Option with given e...
Definition: IPv6Tunneling.cc:203
void inet::IPv6Tunneling::destroyTunnels ( const IPv6Address entry)

Remove all tunnels with provided entry point.

280 {
281  for (auto it = tunnels.begin(); it != tunnels.end(); ) {
282  if (it->second.entry == entry) {
283  auto oldIt = it;
284  ++it;
285 
286  destroyTunnel(oldIt->second.entry, oldIt->second.exit, oldIt->second.destTrigger);
287  }
288  else
289  ++it;
290  }
291 
292  // reset the index if we do not have a single tunnel anymore
293  resetVIfIndex();
294 }
Tunnels tunnels
Definition: IPv6Tunneling.h:124
void resetVIfIndex()
Reset the vIfIndex to its starting value if no tunnels exist anymore.
Definition: IPv6Tunneling.h:266
bool destroyTunnel(const IPv6Address &src, const IPv6Address &dest, const IPv6Address &destTrigger)
Creates a pseudo-tunnel for use with either Type 2 Routing Header or Home Address Option with given e...
Definition: IPv6Tunneling.cc:203
int inet::IPv6Tunneling::doPrefixMatch ( const IPv6Address dest)
private

Search through all tunnels and locate one entry which is a non-split tunnel (later on this could be exteded to searching for a tunnel that has a prefix matching the provided address).

Referenced by encapsulateDatagram(), and getVIfIndexForDest().

547 {
548  int outInterfaceId = -1;
549 
550  // we'll just stop at the first match, because it is assumed that not
551  // more than a single non-split tunnel is possible
552  for (auto & elem : tunnels) {
553  if (elem.second.tunnelType == NON_SPLIT) {
554  outInterfaceId = elem.first;
555  break;
556  }
557  }
558 
559  return outInterfaceId;
560 }
Definition: IPv6Tunneling.h:51
Tunnels tunnels
Definition: IPv6Tunneling.h:124
void inet::IPv6Tunneling::encapsulateDatagram ( IPv6Datagram dgram)
protected

Encapsulate a datagram with tunnel headers.

Attaches a Type 2 Routing Header in the control info if the datagram is routed over an appropriate RH2 pseudo tunnel.

Referenced by handleMessage().

361 {
362  int vIfIndex = -1;
363 
364  if (dgram->getTransportProtocol() == IP_PROT_IPv6EXT_MOB) {
365  // only look at non-split tunnel
366  // (HoTI is only sent over HA tunnel)
367  vIfIndex = doPrefixMatch(dgram->getDestAddress());
368  }
369 
370  if ((dgram->getTransportProtocol() != IP_PROT_IPv6EXT_MOB) || (vIfIndex == -1)) {
371  // look up all tunnels for dgram's destination
372  vIfIndex = getVIfIndexForDest(dgram->getDestAddress());
373  //EV << "looked up again!" << endl;
374  }
375 
376  if (vIfIndex == -1)
377  throw cRuntimeError("encapsulateDatagram(): tunnel not existent");
378 
379  // TODO copy information from old ctrlInfo into new one (Traffic Class, Flow label, etc.)
380  delete dgram->removeControlInfo();
381 
382 #ifdef WITH_xMIPv6
383  if ((tunnels[vIfIndex].tunnelType == T2RH) || (tunnels[vIfIndex].tunnelType == HA_OPT)) {
384  // pseudo-tunnel for Type 2 Routing Header
385  // or Home Address Option
386 
387  IPv6Address src = dgram->getSrcAddress();
388  IPv6Address dest = dgram->getDestAddress();
389  IPv6Address rh2; //dest
390 
391  if (src.isUnspecified()) {
392  // if we do not have a valid source address, we'll have to ask
393  // the routing table for the correct interface.
394  int interfaceId;
395  (void)(rt->lookupDestCache(dest, interfaceId));
396  }
397 
398  if (tunnels[vIfIndex].tunnelType == T2RH) { // update 15.01.08 - CB
399  // this is the CN -> MN path
400  src = tunnels[vIfIndex].entry; // CN address
401  dest = tunnels[vIfIndex].exit; // CoA
402  rh2 = tunnels[vIfIndex].destTrigger; // HoA
403  }
404  else {
405  // path MN -> CN
406  src = tunnels[vIfIndex].entry; // CoA
407  dest = tunnels[vIfIndex].destTrigger; // CN address
408  rh2 = tunnels[vIfIndex].exit; // HoA
409  }
410 
411  // and now construct the new control info for the packet
412  IPv6ControlInfo *controlInfo = new IPv6ControlInfo();
413  controlInfo->setProtocol(dgram->getTransportProtocol());
414 
415  // get rid of the encapsulation of the IPv6 module
416  cMessage *packet = dgram->decapsulate();
417  delete dgram;
418 
419  if (tunnels[vIfIndex].tunnelType == T2RH) {
420  // construct Type 2 Routing Header (RFC 3775 - 6.4.1)
421  /*For a type 2 routing header, the Hdr Ext Len MUST be 2. The Segments
422  Left value describes the number of route segments remaining; i.e.,
423  number of explicitly listed intermediate nodes still to be visited
424  before reaching the final destination. Segments Left MUST be 1.*/
425  IPv6RoutingHeader *t2RH = new IPv6RoutingHeader();
426  t2RH->setRoutingType(2);
427  t2RH->setSegmentsLeft(1);
428  t2RH->setAddressArraySize(1);
429  // old src becomes address of T2RH
430  t2RH->setAddress(0, rh2);
431 
432  // append T2RH to routing headers
433  controlInfo->addExtensionHeader(t2RH);
434 
435  EV_INFO << "Added Type 2 Routing Header." << endl;
436  }
437  else { // HA_OPT
438  /*The Home Address option is carried by the Destination Option
439  extension header (Next Header value = 60). It is used in a packet
440  sent by a mobile node while away from home, to inform the recipient
441  of the mobile node's home address.*/
442  HomeAddressOption *haOpt = new HomeAddressOption();
443  haOpt->setHomeAddress(rh2);
444 
445  // append HA option to routing headers
446  controlInfo->addExtensionHeader(haOpt);
447 
448  EV_INFO << "Added Home Address Option header." << endl;
449  }
450 
451  // new src is tunnel entry (either CoA or CN)
452  controlInfo->setSrcAddr(src);
453  // copy old dest addr
454  controlInfo->setDestAddr(dest);
455 
456  packet->setControlInfo(controlInfo);
457  send(packet, "upperLayerOut");
458  }
459  else {
460 #endif // WITH_xMIPv6
461  // normal tunnel - just modify controlInfo and send
462  // datagram back to IPv6 module for encapsulation
463 
464  IPv6ControlInfo *controlInfo = new IPv6ControlInfo();
465  controlInfo->setProtocol(IP_PROT_IPv6);
466  controlInfo->setSrcAddr(tunnels[vIfIndex].entry);
467  controlInfo->setDestAddr(tunnels[vIfIndex].exit);
468  controlInfo->setInterfaceId(-1);
469 
470  dgram->setControlInfo(controlInfo);
471  send(dgram, "upperLayerOut");
472 #ifdef WITH_xMIPv6
473 }
474 
475 #endif // ifdef WITH_xMIPv6
476 }
const IPv6Address & lookupDestCache(const IPv6Address &dest, int &outInterfaceId)
Looks up the given destination address in the Destination Cache, then returns the next-hop address an...
Definition: IPv6RoutingTable.cc:455
Definition: IPv6Tunneling.h:54
Definition: IPv6Tunneling.h:53
int getVIfIndexForDest(const IPv6Address &destAddress)
Returns the virtual interface identifier for the tunnel which has the provided destination as destina...
Definition: IPv6Tunneling.cc:310
IPv6RoutingTable * rt
Definition: IPv6Tunneling.h:60
Definition: IPProtocolId_m.h:100
Tunnels tunnels
Definition: IPv6Tunneling.h:124
Definition: IPProtocolId_m.h:85
int doPrefixMatch(const IPv6Address &dest)
Search through all tunnels and locate one entry which is a non-split tunnel (later on this could be e...
Definition: IPv6Tunneling.cc:546
int inet::IPv6Tunneling::findTunnel ( const IPv6Address src,
const IPv6Address dest,
const IPv6Address destTrigger 
) const
protected

Returns the type of the tunnels: non-split, split, T2RH, ...

Returns the vIfIndex of tunnel if found, 0 otherwise.

Referenced by createTunnel(), and destroyTunnel().

193 {
194  TI it = find_if(tunnels.begin(), tunnels.end(),
195  bind1st(equalTunnel(), std::make_pair((int)0, Tunnel(src, dest, destTrigger))));
196 
197  if (it != tunnels.end())
198  return it->first;
199 
200  return 0;
201 }
Tunnels::const_iterator TI
Definition: IPv6Tunneling.h:111
Tunnels tunnels
Definition: IPv6Tunneling.h:124
int inet::IPv6Tunneling::getVIfIndexForDest ( const IPv6Address destAddress)

Returns the virtual interface identifier for the tunnel which has the provided destination as destination trigger.

This is done by first looking at the split tunnels; if no split tunnels are found, a prefix matching on the non-split tunnels is then performed. In case both searches do not return a search hit, a value of -1 is returned.

Referenced by encapsulateDatagram(), inet::IPv6::routePacket(), and inet::xMIPv6::triggerRouteOptimization().

311 {
312  //Enter_Method("Looking up Tunnels (%s)", destAddress.str().c_str());
313  EV_INFO << "Looking up tunnels...";
314 
315  // first we look for tunnels with destAddress as trigger
316  int vIfIndex = lookupTunnels(destAddress);
317 
318  if (vIfIndex == -1) {
319  // then the only chance left for finding a suitable tunnel
320  // is to find a non-split tunnel
321  vIfIndex = doPrefixMatch(destAddress);
322  }
323 
324  EV_DETAIL << "found vIf=" << vIfIndex << endl;
325 
326  return vIfIndex;
327 }
int lookupTunnels(const IPv6Address &dest)
Search through all tunnels and locate one entry which is anything but a non-split tunnel and has a de...
Definition: IPv6Tunneling.cc:529
int doPrefixMatch(const IPv6Address &dest)
Search through all tunnels and locate one entry which is a non-split tunnel (later on this could be e...
Definition: IPv6Tunneling.cc:546
int inet::IPv6Tunneling::getVIfIndexForDest ( const IPv6Address destAddress,
TunnelType  tunnelType 
)
virtual

This method is equivalent for getVIfIndexForDest() except that it only searches for either "normal" or mobility tunnels.

330 {
331  int outInterfaceId = -1;
332 
333  for (auto & elem : tunnels) {
334  if (tunnelType == NORMAL || tunnelType == NON_SPLIT || tunnelType == SPLIT) {
335  // we search here for tunnels which have a destination trigger and
336  // check whether the trigger is equal to the destination
337  // only "normal" tunnels, both split and non-split, are possible entry points
338  if ((elem.second.tunnelType == NON_SPLIT) ||
339  (elem.second.tunnelType == SPLIT && elem.second.destTrigger == destAddress))
340  {
341  outInterfaceId = elem.first;
342  break;
343  }
344  }
345  else if (tunnelType == MOBILITY || tunnelType == HA_OPT || tunnelType == T2RH) {
346  if (elem.second.tunnelType != NON_SPLIT &&
347  elem.second.tunnelType != SPLIT &&
348  elem.second.destTrigger == destAddress
349  )
350  {
351  outInterfaceId = elem.first;
352  break;
353  }
354  }
355  }
356 
357  return outInterfaceId;
358 }
Definition: IPv6Tunneling.h:50
Definition: IPv6Tunneling.h:54
Definition: IPv6Tunneling.h:51
Definition: IPv6Tunneling.h:53
Definition: IPv6Tunneling.h:52
Definition: IPv6Tunneling.h:55
Tunnels tunnels
Definition: IPv6Tunneling.h:124
void inet::IPv6Tunneling::handleMessage ( cMessage *  msg)
overridevirtual

Receive messages from IPv6 module and encapsulate/decapsulate them.

85 {
86  IPv6Datagram *dgram = check_and_cast<IPv6Datagram *>(msg);
87 
88  if (msg->getArrivalGate()->isName("upperLayerIn")) {
89  // decapsulate
90  decapsulateDatagram(dgram);
91  }
92  else if (msg->getArrivalGate()->isName("linkLayerIn")) {
93  // encapsulate
94  encapsulateDatagram(dgram);
95  }
96  else
97  throw cRuntimeError("IPv6Tunneling: Unknown gate: %s!", msg->getArrivalGate()->getFullName());
98 }
void encapsulateDatagram(IPv6Datagram *dgram)
Encapsulate a datagram with tunnel headers.
Definition: IPv6Tunneling.cc:360
void decapsulateDatagram(IPv6Datagram *dgram)
Strip tunnel headers from datagram.
Definition: IPv6Tunneling.cc:478
bool inet::IPv6Tunneling::handleOperationStage ( LifecycleOperation operation,
int  stage,
IDoneCallback doneCallback 
)
overridevirtual

Perform one stage of a lifecycle operation.

Processing may be done entirely within this method, or may be a longer process that involves nonzero simulation time or several events, and is triggered by this method call.

Return value: true = "done"; false = "not yet done, will invoke doneCallback when done"

Implements inet::ILifecycle.

101 {
102  throw cRuntimeError("Lifecycle operation support not implemented");
103 }
void inet::IPv6Tunneling::initialize ( int  stage)
overridevirtual

Initialize tunnel manager.

63 {
64  cSimpleModule::initialize(stage);
65 
66  if (stage == INITSTAGE_LOCAL) {
67  ift = getModuleFromPar<IInterfaceTable>(par("interfaceTableModule"), this);
68  rt = getModuleFromPar<IPv6RoutingTable>(par("routingTableModule"), this);
69 
70  vIfIndexTop = INT_MAX; // virtual interface number set to maximum int value
71  noOfNonSplitTunnels = 0; // current number of non-split tunnels on this host
72 
73  WATCH_MAP(tunnels);
74  }
75  else if (stage == INITSTAGE_NETWORK_LAYER) {
76  bool isOperational;
77  NodeStatus *nodeStatus = dynamic_cast<NodeStatus *>(findContainingNode(this)->getSubmodule("status"));
78  isOperational = (!nodeStatus) || nodeStatus->getState() == NodeStatus::UP;
79  if (!isOperational)
80  throw cRuntimeError("This module doesn't support starting in node DOWN state");
81  }
82 }
IInterfaceTable * ift
Definition: IPv6Tunneling.h:59
cModule * findContainingNode(const cModule *from)
Find the node containing the given module.
Definition: ModuleAccess.cc:56
Initialization of network-layer protocols, stage 1.
Definition: InitStages.h:72
Local initializations.
Definition: InitStages.h:35
IPv6RoutingTable * rt
Definition: IPv6Tunneling.h:60
int noOfNonSplitTunnels
Definition: IPv6Tunneling.h:130
Tunnels tunnels
Definition: IPv6Tunneling.h:124
int vIfIndexTop
Definition: IPv6Tunneling.h:127
Definition: NodeStatus.h:40
bool inet::IPv6Tunneling::isTunnelExit ( const IPv6Address exit)

This method is equivalent for getVIfIndexForDest() except that it only searches for pseudo tunnels (T2RH, etc.).

Check if there exists a tunnel with exit equal to the provided address.

Referenced by decapsulateDatagram().

563 {
564  for (auto & elem : tunnels) {
565  // mobility "tunnels" are not relevant for decapsulation
566  // 17.10.07 - same for Home Address Option
567  if (elem.second.tunnelType != T2RH && elem.second.tunnelType != HA_OPT
568  && elem.second.exit == exit)
569  {
570  return true;
571  }
572  }
573 
574  return false;
575 }
Definition: IPv6Tunneling.h:54
Definition: IPv6Tunneling.h:53
Tunnels tunnels
Definition: IPv6Tunneling.h:124
int inet::IPv6Tunneling::lookupTunnels ( const IPv6Address dest)
private

Search through all tunnels and locate one entry which is anything but a non-split tunnel and has a destination trigger for the provided address.

Referenced by getVIfIndexForDest().

530 {
531  int outInterfaceId = -1;
532 
533  // we search here for tunnels which have a destination trigger and
534  // check whether the trigger is equal to the destination
535  // only split tunnels or mobility paths are possible entry points
536  for (auto & elem : tunnels) {
537  if ((elem.second.tunnelType != NON_SPLIT) && (elem.second.destTrigger == dest)) {
538  outInterfaceId = elem.first;
539  break;
540  }
541  }
542 
543  return outInterfaceId;
544 }
Definition: IPv6Tunneling.h:51
Tunnels tunnels
Definition: IPv6Tunneling.h:124
virtual int inet::IPv6Tunneling::numInitStages ( ) const
inlineoverridevirtual
140 { return NUM_INIT_STAGES; }
The number of initialization stages.
Definition: InitStages.h:116
void inet::IPv6Tunneling::resetVIfIndex ( )
inlineprivate

Reset the vIfIndex to its starting value if no tunnels exist anymore.

Referenced by destroyTunnel(), destroyTunnelForEntryAndTrigger(), destroyTunnelForExitAndTrigger(), destroyTunnelFromTrigger(), and destroyTunnels().

266 { if (tunnels.size() == 0) vIfIndexTop = INT_MAX; };
Tunnels tunnels
Definition: IPv6Tunneling.h:124
int vIfIndexTop
Definition: IPv6Tunneling.h:127

Friends And Related Function Documentation

std::ostream& operator<< ( std::ostream &  os,
const IPv6Tunneling::Tunnel tun 
)
friend
590 {
591  os << "tunnel entry = " << tun.entry << ", exit = " << tun.exit << ", tunnelMTU = "
592  << tun.tunnelMTU << ", dest = " << tun.destTrigger << ", type: ";
593 
594  switch (tun.tunnelType) {
596  os << "split tunnel";
597  break;
598 
600  os << "non-split tunnel";
601  break;
602 
603  case IPv6Tunneling::T2RH:
604  os << "T2RH path";
605  break;
606 
608  os << "Home Address Option path";
609  break;
610 
611  default:
612  throw cRuntimeError("Not a valid type for an existing tunnel!");
613  break;
614  }
615 
616  os << endl;
617 
618  return os;
619 }
Definition: IPv6Tunneling.h:50
Definition: IPv6Tunneling.h:54
Definition: IPv6Tunneling.h:51
Definition: IPv6Tunneling.h:53

Member Data Documentation

IInterfaceTable* inet::IPv6Tunneling::ift = nullptr
protected
int inet::IPv6Tunneling::noOfNonSplitTunnels = 0
protected
IPv6RoutingTable* inet::IPv6Tunneling::rt = nullptr
protected
int inet::IPv6Tunneling::vIfIndexTop = 0
protected

Referenced by createTunnel(), and initialize().


The documentation for this class was generated from the following files: