--- a/src/internet/model/ipv6-l3-protocol.cc Sun Aug 11 20:53:01 2013 -0700
+++ b/src/internet/model/ipv6-l3-protocol.cc Mon Aug 12 06:51:18 2013 +0200
@@ -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 @@
: m_nInterfaces (0)
{
NS_LOG_FUNCTION_NOARGS ();
+ m_pmtuCache = CreateObject<Ipv6PmtuCache> ();
}
Ipv6L3Protocol::~Ipv6L3Protocol ()
@@ -131,6 +135,7 @@
m_node = 0;
m_routingProtocol = 0;
+ m_pmtuCache = 0;
Object::DoDispose ();
}
@@ -449,10 +454,24 @@
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 @@
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 @@
// 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 @@
// 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 ()))