--- a/src/devices/csma/csma-net-device.h Sun Aug 03 21:55:49 2008 -0700
+++ b/src/devices/csma/csma-net-device.h Mon Aug 04 17:32:32 2008 -0700
@@ -65,11 +65,12 @@
{
public:
static TypeId GetTypeId (void);
+
/**
* Enumeration of the types of packets supported in the class.
*
*/
- enum CsmaEncapsulationMode {
+ enum EncapsulationMode {
ETHERNET_V1, /**< Version one ethernet packet, length field */
IP_ARP, /**< Ethernet packet encapsulates IP/ARP packet */
RAW, /**< Packet that contains no headers */
@@ -197,17 +198,108 @@
*/
void SetAddress (Mac48Address addr);
-//
-// The following methods are inherited from NetDevice base class.
-//
+ /**
+ * Set The max PHY-level payload length of packets sent over this device.
+ *
+ * Okay, that was easy to say, but the details are a bit thorny. We have a MAC-level 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). The value that determines the relationship between these two values is the link
+ * encapsulation mode. The link encapsulation defines the number of bytes of overhead that are required for the particular
+ * MAC protocol used. For example, if the LLC/SNAP encapsulation is used, eight bytes of LLC/SNAP header are consumed and
+ * therefore the MAC-level MTU must be set and reported as eight bytes less than the PHY-level MTU (which we call the
+ * payload length to try and avoid confusion).
+ *
+ * So, what do we do since there must be three values which must always be consistent in the driver? Which values to we
+ * allow to be changed and how do we ensure the other two are consistent? We want to actually enable a user to change
+ * these two payload lengths in flexible ways, but we want the results (even at intermediate stages) to be consistent.
+ * We certainly don't want to require that users must understand the various requirements of an enapsulation mode in order
+ * to set these variables.
+ *
+ * Consider the following situation: A user wants to set the physical layer MTU to 1400 bytes instead of 1500. This
+ * user shouldn't have to concern herself that the current encapuslation mode is LLC and this will consume eight bytes.
+ * She should not have to also set the MAC MTU to 1392 bytes, and she should certainly not have to do this before setting
+ * the PHY MTU.
+ *
+ * A user who is interested in setting the MAC-level MTU to 1400 bytes should not be forced to understand that in certain
+ * cases the PHY-level MTU must be set to eight bytes more than what he wants in certain cases and zero bytes in others.
+ *
+ * Now, consider a user who is only interested in changing the encapsulation mode from LLC/SNAP to ETHERNET_V1. This
+ * is going to change the relationship between the MAC MTU and the PHY MTU. We've may have to come up with a new value
+ * for at least one of the MTUs? Which one?
+ *
+ * We could play games trying to figure out what the user wants to do, but that is typically a bad plan. So we're going
+ * to just define a flexible behavior. Here it is:
+ *
+ * - If the user is changing the encapsulation mode, the PHY MTU will remain fixed and the MAC MTU will change, if required,
+ * to make the three values consistent;
+ *
+ * - If the user is changing the MAC MTU, she is interested in getting that part of the system set, so the PHY MTU
+ * will be changed to make the three values consistent;
+ *
+ * - If the user is changing the PHY MTU, he is interested in getting that part of the system set, so the MAC MTU
+ * will be changed to make the three values consistent.
+ *
+ * So, if a user calls SetMaxPayloadLength, we assume that the PHY-level MTU is the interesting thing for that user and
+ * we just adjust the MAC-level MTU to "the correct value" based on the current encapsulation mode. If a user calls
+ * SetMacMtu, we assume that the MAC-level MTU is the interesting property for that user, and we adjust the PHY-level MTU
+ * to "the correct value" for the current encapsulation mode. If a user calls SetEncapsulationMode, then we take the
+ * MAC-level MTU as the free variable and set its value to match the current PHY-level MTU.
+ *
+ * \param mayPayloadLength The max PHY-level payload length of packets sent over this device.
+ */
+ void SetMaxPayloadLength (uint16_t maxPayloadLength);
+
+ /**
+ * Get The max PHY-level payload length of packets sent over this device.
+ *
+ * \returns The max PHY-level payload length of packets sent over this device.
+ */
+ uint16_t GetMaxPayloadLength (void) const;
+
+ /**
+ * Set The MAC-level MTU (client payload) of packets sent over this device.
+ *
+ * \param mtu The MAC-level MTU (client payload) of packets sent over this device.
+ *
+ * \see SetMaxPayloadLength
+ */
+ void SetMacMtu (uint16_t mtu);
+
+ /**
+ * Get The MAC-level MTU (client payload) of packets sent over this device.
+ *
+ * \returns The MAC-level MTU (client payload) of packets sent over this device.
+ */
+ uint16_t GetMacMtu (void) const;
+
+
+ /**
+ * Set the encapsulation mode of this device.
+ *
+ * \param mode The encapsulation mode of this device.
+ *
+ * \see SetMaxPayloadLength
+ */
+ void SetEncapsulationMode (CsmaNetDevice::EncapsulationMode mode);
+
+ /**
+ * Get the encapsulation mode of this device.
+ *
+ * \returns The encapsulation mode of this device.
+ */
+ CsmaNetDevice::EncapsulationMode GetEncapsulationMode (void);
+
+ //
+ // The following methods are inherited from NetDevice base class.
+ //
virtual void SetName (const std::string name);
virtual std::string GetName (void) const;
virtual void SetIfIndex (const uint32_t index);
virtual uint32_t GetIfIndex (void) const;
virtual Ptr<Channel> GetChannel (void) const;
- virtual Address GetAddress (void) const;
virtual bool SetMtu (const uint16_t mtu);
virtual uint16_t GetMtu (void) const;
+ virtual Address GetAddress (void) const;
virtual bool IsLinkUp (void) const;
virtual void SetLinkChangeCallback (Callback<void> callback);
virtual bool IsBroadcast (void) const;
@@ -333,9 +425,6 @@
private:
- static const uint16_t DEFAULT_FRAME_LENGTH = 1500;
- static const uint16_t DEFAULT_MTU = 1492;
-
/**
* Operator = is declared but not implemented. This disables the assigment
* operator for CsmaNetDevice objects.
@@ -355,6 +444,18 @@
void Init (bool sendEnable, bool receiveEnable);
/**
+ * Calculate the value for the MAC-level MTU that would result from
+ * setting the PHY-level MTU to the given value.
+ */
+ uint16_t MacMtuFromPayload (uint16_t payloadLength);
+
+ /**
+ * Calculate the value for the PHY-level MTU that would be required
+ * to be able to set the MAC-level MTU to the given value.
+ */
+ uint16_t PayloadFromMacMtu (uint16_t mtu);
+
+ /**
* Start Sending a Packet Down the Wire.
*
* The TransmitStart method is the method that is used internally in
@@ -460,7 +561,7 @@
* function and that should be processed by the ProcessHeader
* function.
*/
- CsmaEncapsulationMode m_encapMode;
+ EncapsulationMode m_encapMode;
/**
* The data rate that the Net Device uses to simulate packet transmission
@@ -568,6 +669,28 @@
*/
Callback<void> m_linkChangeCallback;
+ static const uint16_t DEFAULT_PAYLOAD_LENGTH = 1500;
+ static const uint16_t DEFAULT_MTU = 1492;
+
+ /**
+ * 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 payloadLength
+ * (PHY-level MTU) and mtu (MAC-level MTU) are consistent.
+ *
+ * \param payloadLength The proposed PHY-level MTU
+ * \param mtu The proposed MAC-level MTU
+ */
+ bool CheckMtuConsistency (uint16_t payloadLength, uint16_t mtu);
+
/**
* The MAC-level maximum transmission unit allowed to be sent or received by
* this network device. This corresponds to the maximum payload the device