apply MTU/FrameSize treatment to point-to-point

This commit is contained in:
Unknown
2008-09-05 15:18:20 -07:00
parent a618b8efaa
commit f4ea04de0b
6 changed files with 209 additions and 52 deletions

View File

@@ -14,7 +14,7 @@ def register_types(module):
## csma-net-device.h: ns3::CsmaNetDevice [class]
module.add_class('CsmaNetDevice', parent=root_module['ns3::NetDevice'])
## csma-net-device.h: ns3::CsmaNetDevice::EncapsulationMode [enumeration]
module.add_enum('EncapsulationMode', ['ETHERNET_V1', 'IP_ARP', 'RAW', 'LLC'], outer_class=root_module['ns3::CsmaNetDevice'])
module.add_enum('EncapsulationMode', ['ILLEGAL', 'DIX', 'LLC'], outer_class=root_module['ns3::CsmaNetDevice'])
## Register a nested module for the namespace internal
@@ -256,21 +256,12 @@ def register_Ns3CsmaNetDevice_methods(root_module, cls):
cls.add_method('SetAddress',
'void',
[param('ns3::Mac48Address', 'addr')])
## csma-net-device.h: void ns3::CsmaNetDevice::SetMaxPayloadLength(uint16_t maxPayloadLength) [member function]
cls.add_method('SetMaxPayloadLength',
## csma-net-device.h: void ns3::CsmaNetDevice::SetFrameSize(uint16_t frameSize) [member function]
cls.add_method('SetFrameSize',
'void',
[param('uint16_t', 'maxPayloadLength')])
## csma-net-device.h: uint16_t ns3::CsmaNetDevice::GetMaxPayloadLength() const [member function]
cls.add_method('GetMaxPayloadLength',
'uint16_t',
[],
is_const=True)
## csma-net-device.h: void ns3::CsmaNetDevice::SetMacMtu(uint16_t mtu) [member function]
cls.add_method('SetMacMtu',
'void',
[param('uint16_t', 'mtu')])
## csma-net-device.h: uint16_t ns3::CsmaNetDevice::GetMacMtu() const [member function]
cls.add_method('GetMacMtu',
[param('uint16_t', 'frameSize')])
## csma-net-device.h: uint16_t ns3::CsmaNetDevice::GetFrameSize() const [member function]
cls.add_method('GetFrameSize',
'uint16_t',
[],
is_const=True)

View File

@@ -313,6 +313,10 @@ def register_Ns3NetDeviceContainer_methods(root_module, cls):
cls.add_constructor([param('ns3::NetDeviceContainer const &', 'arg0')])
## net-device-container.h: ns3::NetDeviceContainer::NetDeviceContainer() [constructor]
cls.add_constructor([])
## net-device-container.h: ns3::NetDeviceContainer::NetDeviceContainer(ns3::Ptr<ns3::NetDevice> dev) [constructor]
cls.add_constructor([param('ns3::Ptr< ns3::NetDevice >', 'dev')])
## net-device-container.h: ns3::NetDeviceContainer::NetDeviceContainer(ns3::NetDeviceContainer const & a, ns3::NetDeviceContainer const & b) [constructor]
cls.add_constructor([param('ns3::NetDeviceContainer const &', 'a'), param('ns3::NetDeviceContainer const &', 'b')])
## net-device-container.h: __gnu_cxx::__normal_iterator<const ns3::Ptr<ns3::NetDevice>*,std::vector<ns3::Ptr<ns3::NetDevice>, std::allocator<ns3::Ptr<ns3::NetDevice> > > > ns3::NetDeviceContainer::Begin() const [member function]
cls.add_method('Begin',
'__gnu_cxx::__normal_iterator< const ns3::Ptr< ns3::NetDevice >, std::vector< ns3::Ptr< ns3::NetDevice > > >',

View File

@@ -50,7 +50,7 @@ CsmaNetDevice::GetTypeId (void)
Mac48AddressValue (Mac48Address ("ff:ff:ff:ff:ff:ff")),
MakeMac48AddressAccessor (&CsmaNetDevice::m_address),
MakeMac48AddressChecker ())
.AddAttribute ("FrameLength",
.AddAttribute ("FrameSize",
"The maximum size of a packet sent over this device.",
UintegerValue (DEFAULT_FRAME_SIZE),
MakeUintegerAccessor (&CsmaNetDevice::SetFrameSize,

View File

@@ -685,26 +685,6 @@ private:
static const uint16_t DEFAULT_FRAME_SIZE = 1518;
static const uint16_t ETHERNET_OVERHEAD = 18;
static const uint16_t DEFAULT_MTU = (DEFAULT_FRAME_SIZE - ETHERNET_OVERHEAD);
/**
* There are two MTU types that are used in this driver. The MAC-level
* MTU corresponds to the amount of data (payload) an upper layer can
* send across the link. The PHY-level MTU corresponds to the Type/Length
* field in the 802.3 header and corresponds to the maximum amount of data
* the underlying packet can accept. These are not the same thing. For
* example, if you choose "Llc" as your encapsulation mode, the MAC-level
* MTU will be reduced by the eight bytes with respect to the PHY-level
* MTU which are consumed by the LLC/SNAP header.
*
* This method checks the current enacpuslation mode (and any other
* relevent information) and determines if the provided frame size
* and mtu are consistent.
*
* \param frameSize The proposed new frame size
* \param mtu The proposed new MTU
*/
bool CheckMtuConsistency (uint16_t frameSize, uint16_t mtu);
/**
* The frame size/packet size. This corresponds to the maximum

View File

@@ -23,6 +23,7 @@
#include "ns3/llc-snap-header.h"
#include "ns3/error-model.h"
#include "ns3/trace-source-accessor.h"
#include "ns3/uinteger.h"
#include "ns3/pointer.h"
#include "point-to-point-net-device.h"
#include "point-to-point-channel.h"
@@ -45,6 +46,12 @@ PointToPointNetDevice::GetTypeId (void)
Mac48AddressValue (Mac48Address ("ff:ff:ff:ff:ff:ff")),
MakeMac48AddressAccessor (&PointToPointNetDevice::m_address),
MakeMac48AddressChecker ())
.AddAttribute ("FrameSize",
"The maximum size of a packet sent over this device.",
UintegerValue (DEFAULT_FRAME_SIZE),
MakeUintegerAccessor (&PointToPointNetDevice::SetFrameSize,
&PointToPointNetDevice::GetFrameSize),
MakeUintegerChecker<uint16_t> ())
.AddAttribute ("DataRate",
"The default data rate for point to point links",
DataRateValue (DataRate ("32768b/s")),
@@ -83,10 +90,19 @@ PointToPointNetDevice::PointToPointNetDevice ()
m_txMachineState (READY),
m_channel (0),
m_name (""),
m_linkUp (false),
m_mtu (0xffff)
m_linkUp (false)
{
NS_LOG_FUNCTION (this);
//
// A quick sanity check to ensure consistent constants.
//
PppHeader ppp;
NS_ASSERT_MSG (PPP_OVERHEAD == ppp.GetSerializedSize (),
"PointToPointNetDevice::PointToPointNetDevice(): PPP_OVERHEAD inconsistent");
m_frameSize = DEFAULT_FRAME_SIZE;
m_mtu = MtuFromFrameSize (m_frameSize);
}
PointToPointNetDevice::~PointToPointNetDevice ()
@@ -313,19 +329,6 @@ PointToPointNetDevice::GetAddress (void) const
return m_address;
}
bool
PointToPointNetDevice::SetMtu (const uint16_t mtu)
{
m_mtu = mtu;
return true;
}
uint16_t
PointToPointNetDevice::GetMtu (void) const
{
return m_mtu;
}
bool
PointToPointNetDevice::IsLinkUp (void) const
{
@@ -501,4 +504,65 @@ PointToPointNetDevice::GetRemote (void) const
return Address ();
}
uint16_t
PointToPointNetDevice::MtuFromFrameSize (uint16_t frameSize)
{
NS_LOG_FUNCTION (frameSize);
PppHeader ppp;
NS_ASSERT_MSG ((uint32_t)frameSize >= ppp.GetSerializedSize (),
"PointToPointNetDevice::MtuFromFrameSize(): Given frame size too small to support PPP");
return frameSize - ppp.GetSerializedSize ();
}
uint16_t
PointToPointNetDevice::FrameSizeFromMtu (uint16_t mtu)
{
NS_LOG_FUNCTION (mtu);
PppHeader ppp;
return mtu + ppp.GetSerializedSize ();
}
void
PointToPointNetDevice::SetFrameSize (uint16_t frameSize)
{
NS_LOG_FUNCTION (frameSize);
m_frameSize = frameSize;
m_mtu = MtuFromFrameSize (frameSize);
NS_LOG_LOGIC ("m_frameSize = " << m_frameSize);
NS_LOG_LOGIC ("m_mtu = " << m_mtu);
}
uint16_t
PointToPointNetDevice::GetFrameSize (void) const
{
return m_frameSize;
}
bool
PointToPointNetDevice::SetMtu (uint16_t mtu)
{
NS_LOG_FUNCTION (mtu);
m_frameSize = FrameSizeFromMtu (mtu);
m_mtu = mtu;
NS_LOG_LOGIC ("m_frameSize = " << m_frameSize);
NS_LOG_LOGIC ("m_mtu = " << m_mtu);
return true;
}
uint16_t
PointToPointNetDevice::GetMtu (void) const
{
NS_LOG_FUNCTION_NOARGS ();
return m_mtu;
}
} // namespace ns3

View File

@@ -139,6 +139,93 @@ public:
*/
void SetAddress (Mac48Address addr);
/**
* Set The max frame size of packets sent over this device.
*
* Okay, that was easy to say, but the details are a bit thorny. We have a MAC-level MTU that is the payload that higher
* level protocols see. We have a PHY-level MTU which is the maximum number of bytes we can send over the link
* (cf. 1500 bytes for Ethernet). We also have a frame size which is some total number of bytes in a packet which could
* or could not include any framing and overhead. There can be a lot of inconsistency in definitions of these terms. For
* example, RFC 1042 asserts that the terms maximum transmission unit and maximum packet size are equivalent. RFC 791,
* however, defines MTU as the maximum sized IP datagram that can be sent. Packet size and frame size are sometimes
* used interchangeably.
*
* So, some careful definitions are in order to avoid confusion:
*
* In real serial channel (HDLC, for example), the wire idles (sends all ones) until the channel begins sending a packet.
* A frame on the wire starts with a flag character (01111110). This is followed by what is usually called the packet:
* address, control, payload, and a Frame Check Sequence (FCS). This is followed by another flag character. If the flag
* characters are used, then bit stuffing must be used to prevent flag characters from appearing in the packet and confusing
* the link. Som to be strictly and pedantically correct the frame size is then necessarily larger than the packet size on
* a real link. But, this isn't a real link, it's a simulation of a device similar to a point-to-point device, and we have
* no good reason to add framing bits and therefore to do bit-stuffing. So, in the case of the point-to-point device, the
* frame size is equal to the packet size. Since these two values are defined to be equal, there is no danger in assuming
* they are identical. We define packet size to be equal to frame size and this excludes the flag characters. We define a
* single (MAC-level) MTU that coresponds to the payload size of the packet, which is the IP-centric view of the term as
* seen in RFC 791.
*
* To make this concrete, consider PPP framing on a synchronous link. In this framing scheme, a real serial frame on the
* wire starts with a flag character, address and control characters, then a 16-bit PPP protocol ID (0x21 = IP). Then we
* would see the actual payload we are supposed to send, presumably an IP datagram. At then we see the FCS and finally
* another flag character to end the frame. We ignore the flag bits on this device since it they are not needed. We
* aren't really using HDLC to send frames across the link, so we don't need the address and control bits either. In fact,
* to encapsulate using unframed PPP all we need to do is prepend the two-byte protocol ID.
*
* Typically the limiting factor in frame size is due to hardware limitations in the underlying HDLC controller receive
* FIFO buffer size. This number can vary widely. For example, the Motorola MC92460 has a 64 KByte maximum frame size;
* the Intel IXP4XX series has a 16 KByte size. Older USARTs have a maximum frame size around 2KBytes, and typical PPP
* links on the Internet have their MTU set to 1500 bytes since this is what will typically be used on Ethernet segments
* and will avoid path MTU issues. We choose to make the default MTU 1500 bytes which then fixes the maximum frame size
* as described below.
*
* So, there are really two related variables at work here. There is the maximum frame size that can be sent over the
* link and there is the MTU.
*
* So, what do we do since these values must always be consistent in the driver? We want to actually allow a user to change
* these variables, but we want the results (even at intermediate stages of her ultimate change) to be consistent. We
* certainly don't want to require that users must understand the details of PPP encapsulation in order to set these
* variables.
*
* Consider the following situation: A user wants to set the maximum frame size to 16 KBytes. This user shouldn't have to
* concern herself that the PPP encapsulation will consume six bytes. She should not have to figure out that the MTU needs
* to be set to 16K - 2 bytes to make things consistent.
*
* Similarly, a user who is interested in setting the MTU to 1500 bytes should not be forced to understand that the frame
* size will need to be set to 1502 bytes.
*
* We could play games trying to figure out what the user wants to do, but that is typically a bad plan and programmers
* have a long and distinguished history of guessing wrong. We'll avoid all of that and just define a flexible behavior
* that can be worked to get what you want. Here it is:
*
* - If the user is changing the MTU, she is interested in getting that part of the system set, so the frame size
* will be changed to make it consistent;
*
* - If the user is changing the frame size, he is interested in getting that part of the system set, so the MTU
* will be changed to make it consistent;
*
* - You cannot define the MTU and frame size separately -- they are always tied together by the overhead of the PPP
* encapsulation. This is not a restriction. Consider what this means. Perhaps you want to set the frame size to some
* large number and the MTU to some small number. The largest packet you can send is going to be limited by the MTU, so it
* is not possible to send a frame larger than the MTU plus overhead. Having the ability to set a larger frame size is not
* useful.
*
* So, if a user calls SetFrameSize, we assume that the maximum frame size is the interesting thing for that user and
* we just adjust the MTU to a new "correct value" based on the current encapsulation mode. If a user calls SetMtu, we
* assume that the MTU is the interesting property for that user, and we adjust the frame size to a new "correct value"
* for the current encapsulation mode. If a user calls SetEncapsulationMode, then we take the MTU as the free variable
* and set its value to match the current frame size.
*
* \param frameSize The max frame size of packets sent over this device.
*/
void SetFrameSize (uint16_t frameSize);
/**
* Get The max frame size of packets sent over this device.
*
* \returns The max frame size of packets sent over this device.
*/
uint16_t GetFrameSize (void) const;
//
// Pure virtual methods inherited from NetDevice we must implement.
//
@@ -195,11 +282,24 @@ private:
Ptr<Queue> GetQueue(void) const;
private:
/**
* Calculate the value for the MTU that would result from
* setting the frame size to the given value.
*/
uint16_t MtuFromFrameSize (uint16_t frameSize);
/**
* Calculate the value for the frame size that would be required
* to be able to set the MTU to the given value.
*/
uint16_t FrameSizeFromMtu (uint16_t mtu);
/**
* \returns the address of the remote device connected to this device
* through the point to point channel.
*/
Address GetRemote (void) const;
/**
* Adds the necessary headers and trailers to a packet of data in order to
* respect the protocol implemented by the agent.
@@ -314,7 +414,25 @@ private:
std::string m_name;
bool m_linkUp;
Callback<void> m_linkChangeCallback;
uint16_t m_mtu;
static const uint16_t DEFAULT_MTU = 1500;
static const uint16_t PPP_OVERHEAD = 2;
static const uint16_t DEFAULT_FRAME_SIZE = DEFAULT_MTU + PPP_OVERHEAD;
/**
* The frame size/packet size. This corresponds to the maximum
* number of bytes that can be transmitted as a packet without framing.
* This corresponds to the 1518 byte packet size often seen on Ethernet.
*/
uint32_t m_frameSize;
/**
* The Maxmimum Transmission Unit. This corresponds to the maximum
* number of bytes that can be transmitted as seen from higher layers.
* This corresponds to the 1500 byte MTU size often seen on IP over
* Ethernet.
*/
uint32_t m_mtu;
};
} // namespace ns3