Bug 1721 - Path MTU isn't handled properly
This commit is contained in:
@@ -69,6 +69,8 @@ us a note on ns-developers mailing list.</p>
|
||||
an Autoconfigured address.</li>
|
||||
<li>Mac64Address support has been extended. It can now be used with
|
||||
IPv6 to make an Autoconfigured address.</li>
|
||||
<li>IPv6 can now detect and use Path-MTU. See
|
||||
examples/ipv6/fragmentation-ipv6-two-MTU.cc for an example.</li>
|
||||
</ul>
|
||||
|
||||
<h2>Changes to existing API:</h2>
|
||||
|
||||
@@ -39,6 +39,8 @@ New user-visible features
|
||||
- PHY support for UE measurements (RSRP and RSRQ)
|
||||
- RRC support for UE measurements (configuration, execution, reporting)
|
||||
- Automatic Handover trigger based on RRC UE measurement reports
|
||||
- IPv6 can now detect and use Path-MTU. See
|
||||
examples/ipv6/fragmentation-ipv6-two-MTU.cc for an example.
|
||||
|
||||
Bugs fixed
|
||||
----------
|
||||
@@ -63,6 +65,7 @@ Bugs fixed
|
||||
- Bug 1712 - The IP (v4 and v6) forwarding needs a test
|
||||
- Bug 1718 - Ipv4StaticRouting log component is misspelled
|
||||
- Bug 1720 - IPv6 Fragmentation cause crashes
|
||||
- Bug 1721 - Path MTU isn't handled properly
|
||||
- Bug 1727 - Ping6 should use a proper source address
|
||||
- Bug 1731 - lte-phy-error-model passes unexpectedly
|
||||
- Bug 1742 - IPv6 HbH and Dst Extension Header size is not correctly calculated
|
||||
|
||||
169
examples/ipv6/fragmentation-ipv6-two-MTU.cc
Normal file
169
examples/ipv6/fragmentation-ipv6-two-MTU.cc
Normal file
@@ -0,0 +1,169 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008-2009 Strasbourg University
|
||||
* Copyright (c) 2013 Universita' di Firenze
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: David Gross <gdavid.devel@gmail.com>
|
||||
* Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
|
||||
* Modified by Tommaso Pecorella <tommaso.pecorella@unifi.it>
|
||||
*/
|
||||
|
||||
// Network topology
|
||||
// //
|
||||
// // Src n0 r n1 Dst
|
||||
// // | _ |
|
||||
// // MTU ====|_|==== MTU
|
||||
// // 5000 router 1500
|
||||
// //
|
||||
// // - Tracing of queues and packet receptions to file "fragmentation-ipv6-two-mtu.tr"
|
||||
|
||||
#include <fstream>
|
||||
#include "ns3/core-module.h"
|
||||
#include "ns3/internet-module.h"
|
||||
#include "ns3/csma-module.h"
|
||||
#include "ns3/applications-module.h"
|
||||
#include "ns3/ipv6-static-routing-helper.h"
|
||||
|
||||
#include "ns3/ipv6-routing-table-entry.h"
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("FragmentationIpv6TwoMtuExample");
|
||||
|
||||
/**
|
||||
* \class StackHelper
|
||||
* \brief Helper to set or get some IPv6 information about nodes.
|
||||
*/
|
||||
class StackHelper
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* \brief Add an address to a IPv6 node.
|
||||
* \param n node
|
||||
* \param interface interface index
|
||||
* \param address IPv6 address to add
|
||||
*/
|
||||
inline void AddAddress (Ptr<Node>& n, uint32_t interface, Ipv6Address address)
|
||||
{
|
||||
Ptr<Ipv6> ipv6 = n->GetObject<Ipv6> ();
|
||||
ipv6->AddAddress (interface, address);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Print the routing table.
|
||||
* \param n the node
|
||||
*/
|
||||
inline void PrintRoutingTable (Ptr<Node>& n)
|
||||
{
|
||||
Ptr<Ipv6StaticRouting> routing = 0;
|
||||
Ipv6StaticRoutingHelper routingHelper;
|
||||
Ptr<Ipv6> ipv6 = n->GetObject<Ipv6> ();
|
||||
uint32_t nbRoutes = 0;
|
||||
Ipv6RoutingTableEntry route;
|
||||
|
||||
routing = routingHelper.GetStaticRouting (ipv6);
|
||||
|
||||
std::cout << "Routing table of " << n << " : " << std::endl;
|
||||
std::cout << "Destination\t\t\t\t" << "Gateway\t\t\t\t\t" << "Interface\t" << "Prefix to use" << std::endl;
|
||||
|
||||
nbRoutes = routing->GetNRoutes ();
|
||||
for (uint32_t i = 0; i < nbRoutes; i++)
|
||||
{
|
||||
route = routing->GetRoute (i);
|
||||
std::cout << route.GetDest () << "\t"
|
||||
<< route.GetGateway () << "\t"
|
||||
<< route.GetInterface () << "\t"
|
||||
<< route.GetPrefixToUse () << "\t"
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
#if 0
|
||||
LogComponentEnable ("Ipv6L3Protocol", LOG_LEVEL_ALL);
|
||||
LogComponentEnable ("Icmpv6L4Protocol", LOG_LEVEL_ALL);
|
||||
LogComponentEnable ("Ipv6StaticRouting", LOG_LEVEL_ALL);
|
||||
LogComponentEnable ("Ipv6Interface", LOG_LEVEL_ALL);
|
||||
LogComponentEnable ("Ping6Application", LOG_LEVEL_ALL);
|
||||
#endif
|
||||
|
||||
CommandLine cmd;
|
||||
cmd.Parse (argc, argv);
|
||||
|
||||
StackHelper stackHelper;
|
||||
|
||||
NS_LOG_INFO ("Create nodes.");
|
||||
Ptr<Node> n0 = CreateObject<Node> ();
|
||||
Ptr<Node> r = CreateObject<Node> ();
|
||||
Ptr<Node> n1 = CreateObject<Node> ();
|
||||
|
||||
NodeContainer net1 (n0, r);
|
||||
NodeContainer net2 (r, n1);
|
||||
NodeContainer all (n0, r, n1);
|
||||
|
||||
NS_LOG_INFO ("Create IPv6 Internet Stack");
|
||||
InternetStackHelper internetv6;
|
||||
internetv6.Install (all);
|
||||
|
||||
NS_LOG_INFO ("Create channels.");
|
||||
CsmaHelper csma;
|
||||
csma.SetChannelAttribute ("DataRate", DataRateValue (5000000));
|
||||
csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
|
||||
NetDeviceContainer d2 = csma.Install (net2);
|
||||
csma.SetDeviceAttribute ("Mtu", UintegerValue (5000));
|
||||
NetDeviceContainer d1 = csma.Install (net1);
|
||||
|
||||
NS_LOG_INFO ("Create networks and assign IPv6 Addresses.");
|
||||
Ipv6AddressHelper ipv6;
|
||||
ipv6.SetBase (Ipv6Address ("2001:1::"), Ipv6Prefix (64));
|
||||
Ipv6InterfaceContainer i1 = ipv6.Assign (d1);
|
||||
i1.SetForwarding (1, true);
|
||||
i1.SetDefaultRouteInAllNodes (1);
|
||||
ipv6.SetBase (Ipv6Address ("2001:2::"), Ipv6Prefix (64));
|
||||
Ipv6InterfaceContainer i2 = ipv6.Assign (d2);
|
||||
i2.SetForwarding (0, true);
|
||||
i2.SetDefaultRouteInAllNodes (0);
|
||||
|
||||
stackHelper.PrintRoutingTable (n0);
|
||||
|
||||
/* Create a Ping6 application to send ICMPv6 echo request from n0 to n1 via r */
|
||||
uint32_t packetSize = 4096;
|
||||
uint32_t maxPacketCount = 5;
|
||||
Time interPacketInterval = Seconds (1.0);
|
||||
Ping6Helper ping6;
|
||||
|
||||
ping6.SetLocal (i1.GetAddress (0, 1));
|
||||
ping6.SetRemote (i2.GetAddress (1, 1));
|
||||
|
||||
ping6.SetAttribute ("MaxPackets", UintegerValue (maxPacketCount));
|
||||
ping6.SetAttribute ("Interval", TimeValue (interPacketInterval));
|
||||
ping6.SetAttribute ("PacketSize", UintegerValue (packetSize));
|
||||
ApplicationContainer apps = ping6.Install (net1.Get (0));
|
||||
apps.Start (Seconds (2.0));
|
||||
apps.Stop (Seconds (20.0));
|
||||
|
||||
AsciiTraceHelper ascii;
|
||||
csma.EnableAsciiAll (ascii.CreateFileStream ("fragmentation-ipv6-two-mtu.tr"));
|
||||
csma.EnablePcapAll (std::string ("fragmentation-ipv6-two-mtu"), true);
|
||||
|
||||
NS_LOG_INFO ("Run Simulation.");
|
||||
Simulator::Run ();
|
||||
Simulator::Destroy ();
|
||||
NS_LOG_INFO ("Done.");
|
||||
}
|
||||
|
||||
@@ -19,6 +19,9 @@ def build(bld):
|
||||
obj = bld.create_ns3_program('fragmentation-ipv6', ['csma', 'internet'])
|
||||
obj.source = 'fragmentation-ipv6.cc'
|
||||
|
||||
obj = bld.create_ns3_program('fragmentation-ipv6-two-MTU', ['csma', 'internet'])
|
||||
obj.source = 'fragmentation-ipv6-two-MTU.cc'
|
||||
|
||||
obj = bld.create_ns3_program('loose-routing-ipv6', ['csma', 'internet'])
|
||||
obj.source = 'loose-routing-ipv6.cc'
|
||||
|
||||
|
||||
@@ -835,6 +835,10 @@ void Icmpv6L4Protocol::HandlePacketTooBig (Ptr<Packet> p, Ipv6Address const &src
|
||||
origPkt->RemoveHeader (ipHeader);
|
||||
uint8_t payload[8];
|
||||
origPkt->CopyData (payload, 8);
|
||||
|
||||
Ptr<Ipv6L3Protocol> ipv6 = m_node->GetObject<Ipv6L3Protocol> ();
|
||||
ipv6->SetPmtu(ipHeader.GetDestinationAddress(), tooBig.GetMtu ());
|
||||
|
||||
Forward (src, tooBig, tooBig.GetMtu (), ipHeader, payload);
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,9 @@
|
||||
#include "icmpv6-l4-protocol.h"
|
||||
#include "ndisc-cache.h"
|
||||
|
||||
// Minimum IPv6 MTU, as defined by RFC 2460
|
||||
#define IPV6_MIN_MTU 1280
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (Ipv6L3Protocol);
|
||||
@@ -88,6 +91,7 @@ Ipv6L3Protocol::Ipv6L3Protocol ()
|
||||
: m_nInterfaces (0)
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
m_pmtuCache = CreateObject<Ipv6PmtuCache> ();
|
||||
}
|
||||
|
||||
Ipv6L3Protocol::~Ipv6L3Protocol ()
|
||||
@@ -131,6 +135,7 @@ void Ipv6L3Protocol::DoDispose ()
|
||||
|
||||
m_node = 0;
|
||||
m_routingProtocol = 0;
|
||||
m_pmtuCache = 0;
|
||||
Object::DoDispose ();
|
||||
}
|
||||
|
||||
@@ -449,10 +454,24 @@ uint16_t Ipv6L3Protocol::GetMetric (uint32_t i) const
|
||||
uint16_t Ipv6L3Protocol::GetMtu (uint32_t i) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << i);
|
||||
|
||||
// RFC 1981, if PMTU is disabled, return the minimum MTU
|
||||
if (!m_mtuDiscover)
|
||||
{
|
||||
return IPV6_MIN_MTU;
|
||||
}
|
||||
|
||||
Ptr<Ipv6Interface> interface = GetInterface (i);
|
||||
return interface->GetDevice ()->GetMtu ();
|
||||
}
|
||||
|
||||
void Ipv6L3Protocol::SetPmtu (Ipv6Address dst, uint32_t pmtu)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << dst << int(pmtu));
|
||||
m_pmtuCache->SetPmtu (dst, pmtu);
|
||||
}
|
||||
|
||||
|
||||
bool Ipv6L3Protocol::IsUp (uint32_t i) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << i);
|
||||
@@ -556,6 +575,18 @@ bool Ipv6L3Protocol::GetIpForward () const
|
||||
return m_ipForward;
|
||||
}
|
||||
|
||||
void Ipv6L3Protocol::SetMtuDiscover (bool mtuDiscover)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << int(mtuDiscover));
|
||||
m_mtuDiscover = mtuDiscover;
|
||||
}
|
||||
|
||||
bool Ipv6L3Protocol::GetMtuDiscover () const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
return m_mtuDiscover;
|
||||
}
|
||||
|
||||
void Ipv6L3Protocol::SetSendIcmpv6Redirect (bool sendIcmpv6Redirect)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << sendIcmpv6Redirect);
|
||||
@@ -848,7 +879,14 @@ void Ipv6L3Protocol::SendRealOut (Ptr<Ipv6Route> route, Ptr<Packet> packet, Ipv6
|
||||
// Check packet size
|
||||
std::list<Ptr<Packet> > fragments;
|
||||
|
||||
if (packet->GetSize () > (size_t)(dev->GetMtu () + 40)) /* 40 => size of IPv6 header */
|
||||
// Check if we have a Path MTU stored. If so, use it. Else, use the link MTU.
|
||||
size_t targetMtu = (size_t)(m_pmtuCache->GetPmtu (ipHeader.GetDestinationAddress()));
|
||||
if (targetMtu == 0)
|
||||
{
|
||||
targetMtu = dev->GetMtu ();
|
||||
}
|
||||
|
||||
if (packet->GetSize () > targetMtu + 40) /* 40 => size of IPv6 header */
|
||||
{
|
||||
// Router => drop
|
||||
|
||||
@@ -882,7 +920,7 @@ void Ipv6L3Protocol::SendRealOut (Ptr<Ipv6Route> route, Ptr<Packet> packet, Ipv6
|
||||
// To get specific method GetFragments from Ipv6ExtensionFragmentation
|
||||
Ipv6ExtensionFragment *ipv6Fragment = dynamic_cast<Ipv6ExtensionFragment *> (PeekPointer (ipv6ExtensionDemux->GetExtension (Ipv6Header::IPV6_EXT_FRAGMENTATION)));
|
||||
NS_ASSERT (ipv6Fragment != 0);
|
||||
ipv6Fragment->GetFragments (packet, outInterface->GetDevice ()->GetMtu (), fragments);
|
||||
ipv6Fragment->GetFragments (packet, targetMtu, fragments);
|
||||
}
|
||||
|
||||
if (!route->GetGateway ().IsEqual (Ipv6Address::GetAny ()))
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "ns3/ipv6.h"
|
||||
#include "ns3/ipv6-address.h"
|
||||
#include "ns3/ipv6-header.h"
|
||||
#include "ns3/ipv6-pmtu-cache.h"
|
||||
|
||||
namespace ns3
|
||||
{
|
||||
@@ -277,6 +278,13 @@ public:
|
||||
*/
|
||||
uint16_t GetMtu (uint32_t i) const;
|
||||
|
||||
/**
|
||||
* \brief Set the Path MTU for the specified IPv6 destination address.
|
||||
* \param dst Ipv6 destination address
|
||||
* \param pmtu the Path MTU
|
||||
*/
|
||||
virtual void SetPmtu (Ipv6Address dst, uint32_t pmtu);
|
||||
|
||||
/**
|
||||
* \brief Is specified interface up ?
|
||||
* \param i interface index
|
||||
@@ -484,6 +492,18 @@ private:
|
||||
*/
|
||||
virtual bool GetIpForward () const;
|
||||
|
||||
/**
|
||||
* \brief Set IPv6 MTU discover state.
|
||||
* \param mtuDiscover IPv6 MTU discover enabled or not
|
||||
*/
|
||||
virtual void SetMtuDiscover (bool mtuDiscover);
|
||||
|
||||
/**
|
||||
* \brief Get IPv6 MTU discover state.
|
||||
* \return MTU discover state (enabled or not)
|
||||
*/
|
||||
virtual bool GetMtuDiscover (void) const;
|
||||
|
||||
/**
|
||||
* \brief Set the ICMPv6 Redirect sending state.
|
||||
* \param sendIcmpv6Redirect ICMPv6 Redirect sending enabled or not
|
||||
@@ -506,6 +526,16 @@ private:
|
||||
*/
|
||||
bool m_ipForward;
|
||||
|
||||
/**
|
||||
* \brief MTU Discover (i.e. Path MTU) state.
|
||||
*/
|
||||
bool m_mtuDiscover;
|
||||
|
||||
/**
|
||||
* \brief Path MTU Cache.
|
||||
*/
|
||||
Ptr<Ipv6PmtuCache> m_pmtuCache;
|
||||
|
||||
/**
|
||||
* \brief List of transport protocol.
|
||||
*/
|
||||
|
||||
115
src/internet/model/ipv6-pmtu-cache.cc
Normal file
115
src/internet/model/ipv6-pmtu-cache.cc
Normal file
@@ -0,0 +1,115 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013 Universita' di Firenze
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Tommaso Pecorella <tommaso.pecorella@unifi.it>
|
||||
*/
|
||||
|
||||
#include "ipv6-pmtu-cache.h"
|
||||
#include "ns3/log.h"
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("Ipv6PmtuCache");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (Ipv6PmtuCache);
|
||||
|
||||
TypeId Ipv6PmtuCache::GetTypeId ()
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::Ipv6PmtuCache")
|
||||
.SetParent<Object> ()
|
||||
.AddAttribute ("CacheExpiryTime",
|
||||
"Validity time for a Path MTU entry. Default is 10 minutes, minimum is 5 minutes.",
|
||||
TimeValue (Seconds (60 * 10)),
|
||||
MakeTimeAccessor (&Ipv6PmtuCache::m_validityTime),
|
||||
MakeTimeChecker (Time (Seconds (60 * 5))))
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
Ipv6PmtuCache::Ipv6PmtuCache ()
|
||||
{
|
||||
}
|
||||
|
||||
Ipv6PmtuCache::~Ipv6PmtuCache ()
|
||||
{
|
||||
}
|
||||
|
||||
void Ipv6PmtuCache::DoDispose ()
|
||||
{
|
||||
for (pathMtuTimerIter iter = m_pathMtuTimer.begin (); iter != m_pathMtuTimer.end (); iter++)
|
||||
{
|
||||
iter->second.Cancel ();
|
||||
}
|
||||
m_pathMtuTimer.clear ();
|
||||
m_pathMtu.clear ();
|
||||
}
|
||||
|
||||
uint32_t Ipv6PmtuCache::GetPmtu (Ipv6Address dst)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << dst);
|
||||
|
||||
if (m_pathMtu.find (dst) != m_pathMtu.end ())
|
||||
{
|
||||
return m_pathMtu[dst];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Ipv6PmtuCache::SetPmtu (Ipv6Address dst, uint32_t pmtu)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << dst << pmtu);
|
||||
|
||||
m_pathMtu[dst] = pmtu;
|
||||
if (m_pathMtuTimer.find (dst) != m_pathMtuTimer.end ())
|
||||
{
|
||||
m_pathMtuTimer[dst].Cancel ();
|
||||
}
|
||||
EventId pMtuTimer;
|
||||
pMtuTimer = Simulator::Schedule (m_validityTime, &Ipv6PmtuCache::ClearPmtu, this, dst);
|
||||
m_pathMtuTimer[dst] = pMtuTimer;
|
||||
}
|
||||
|
||||
Time Ipv6PmtuCache::GetPmtuValidityTime () const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
return m_validityTime;
|
||||
}
|
||||
|
||||
bool Ipv6PmtuCache::SetPmtuValidityTime (Time validity)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << validity);
|
||||
|
||||
if (validity > Seconds (60 * 5))
|
||||
{
|
||||
m_validityTime = validity;
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_LOG_LOGIC ("rejecting a PMTU validity timer lesser than 5 minutes");
|
||||
return false;
|
||||
}
|
||||
|
||||
void Ipv6PmtuCache::ClearPmtu (Ipv6Address dst)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << dst);
|
||||
|
||||
m_pathMtu.erase (dst);
|
||||
m_pathMtuTimer.erase (dst);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
122
src/internet/model/ipv6-pmtu-cache.h
Normal file
122
src/internet/model/ipv6-pmtu-cache.h
Normal file
@@ -0,0 +1,122 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013 Universita' di Firenze
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Tommaso Pecorella <tommaso.pecorella@unifi.it>
|
||||
*/
|
||||
|
||||
#ifndef IPV6_PMTU_CACHE_H
|
||||
#define IPV6_PMTU_CACHE_H
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "ns3/core-module.h"
|
||||
#include "ns3/ipv6-address.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/**
|
||||
* \ingroup ipv6
|
||||
* \brief This class implements the Path MTU cache, as defined by RFC 1981.
|
||||
*
|
||||
* The Path MTU is stored according to the destination address, and it is
|
||||
* cleared upon expiration (default validity time is 10 minutes).
|
||||
*
|
||||
* The "infinite lifetime" PMTU entry type is not implemented, since it is
|
||||
* useful only in an very limited number of cases. See the RFC for further
|
||||
* details.
|
||||
*/
|
||||
|
||||
class Ipv6PmtuCache : public Object
|
||||
{
|
||||
public:
|
||||
class Entry;
|
||||
|
||||
/**
|
||||
* \brief Get the type ID
|
||||
* \return type ID
|
||||
*/
|
||||
static TypeId GetTypeId ();
|
||||
|
||||
/**
|
||||
* \brief Constructor.
|
||||
*/
|
||||
Ipv6PmtuCache ();
|
||||
|
||||
/**
|
||||
* \brief Destructor.
|
||||
*/
|
||||
~Ipv6PmtuCache ();
|
||||
|
||||
/**
|
||||
* \brief Dispose object.
|
||||
*/
|
||||
virtual void DoDispose ();
|
||||
|
||||
/**
|
||||
* \brief Gets the known Path MTU for the specific destination
|
||||
* \param dst the destination
|
||||
* \return the Path MTU (zero if unknown)
|
||||
*/
|
||||
uint32_t GetPmtu (Ipv6Address dst);
|
||||
|
||||
/**
|
||||
* \brief Sets the Path MTU for the specific destination
|
||||
* \param dst the destination
|
||||
* \param pmtu the Path MTU
|
||||
*/
|
||||
void SetPmtu (Ipv6Address dst, uint32_t pmtu);
|
||||
|
||||
/**
|
||||
* \brief Gets the Path MTU validity time
|
||||
* \return the Path MTU validity time
|
||||
*/
|
||||
Time GetPmtuValidityTime () const;
|
||||
|
||||
/**
|
||||
* \brief Sets the Path MTU validity time (minimum is 5 minutes)
|
||||
* \param validity the Path MTU validity time
|
||||
* \return true if the change was successful
|
||||
*/
|
||||
bool SetPmtuValidityTime (Time validity);
|
||||
|
||||
private:
|
||||
/**
|
||||
* \brief Clears the Path MTU for the specific destination
|
||||
* \param dst the destination
|
||||
*/
|
||||
void ClearPmtu (Ipv6Address dst);
|
||||
|
||||
/**
|
||||
* \brief Path MTU table
|
||||
*/
|
||||
std::map<Ipv6Address, uint32_t> m_pathMtu;
|
||||
|
||||
typedef std::map<Ipv6Address, EventId> ::iterator pathMtuTimerIter;
|
||||
/**
|
||||
* \brief Path MTU Expiration table
|
||||
*/
|
||||
std::map<Ipv6Address, EventId> m_pathMtuTimer;
|
||||
|
||||
/**
|
||||
* \brief Path MTU entry validity time
|
||||
*/
|
||||
Time m_validityTime;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* IPV6_PMTU_CACHE_H */
|
||||
@@ -40,13 +40,11 @@ TypeId Ipv6::GetTypeId (void)
|
||||
MakeBooleanAccessor (&Ipv6::SetIpForward,
|
||||
&Ipv6::GetIpForward),
|
||||
MakeBooleanChecker ())
|
||||
#if 0
|
||||
.AddAttribute ("MtuDiscover", "If enabled, every outgoing IPv6 packet will have the DF flag set.",
|
||||
BooleanValue (false),
|
||||
MakeBooleanAccessor (&UdpSocket::SetMtuDiscover,
|
||||
&UdpSocket::GetMtuDiscover),
|
||||
.AddAttribute ("MtuDiscover", "If disabled, every interface will have its MTU set to 1280 bytes.",
|
||||
BooleanValue (true),
|
||||
MakeBooleanAccessor (&Ipv6::SetMtuDiscover,
|
||||
&Ipv6::GetMtuDiscover),
|
||||
MakeBooleanChecker ())
|
||||
#endif
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
@@ -252,6 +252,13 @@ public:
|
||||
*/
|
||||
virtual uint16_t GetMtu (uint32_t interface) const = 0;
|
||||
|
||||
/**
|
||||
* \brief Set the Path MTU for the specified IPv6 destination address.
|
||||
* \param dst Ipv6 destination address
|
||||
* \param pmtu the Path MTU
|
||||
*/
|
||||
virtual void SetPmtu (Ipv6Address dst, uint32_t pmtu) = 0;
|
||||
|
||||
/**
|
||||
* \brief If the specified interface index is in "up" state.
|
||||
* \param interface Interface number of IPv6 interface
|
||||
@@ -320,6 +327,18 @@ private:
|
||||
* \return forwarding state (enabled or not)
|
||||
*/
|
||||
virtual bool GetIpForward (void) const = 0;
|
||||
|
||||
/**
|
||||
* \brief Set IPv6 MTU discover state.
|
||||
* \param mtuDiscover IPv6 MTU discover enabled or not
|
||||
*/
|
||||
virtual void SetMtuDiscover (bool mtuDiscover) = 0;
|
||||
|
||||
/**
|
||||
* \brief Get IPv6 MTU discover state.
|
||||
* \return MTU discover state (enabled or not)
|
||||
*/
|
||||
virtual bool GetMtuDiscover (void) const = 0;
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -191,6 +191,7 @@ def build(bld):
|
||||
'model/ipv6-address-generator.cc',
|
||||
'model/ipv4-packet-probe.cc',
|
||||
'model/ipv6-packet-probe.cc',
|
||||
'model/ipv6-pmtu-cache.cc',
|
||||
]
|
||||
|
||||
internet_test = bld.create_ns3_module_test_library('internet')
|
||||
@@ -304,6 +305,7 @@ def build(bld):
|
||||
'model/rtt-estimator.h',
|
||||
'model/ipv4-packet-probe.h',
|
||||
'model/ipv6-packet-probe.h',
|
||||
'model/ipv6-pmtu-cache.h',
|
||||
]
|
||||
|
||||
if bld.env['NSC_ENABLED']:
|
||||
|
||||
Reference in New Issue
Block a user