Files
unison/src/network/model/net-device.h
Stefano Avallone defeaea224 network: Add the NetDeviceQueue and NetDeviceQueueInterface classes
This patch adds a NetDeviceQueue class to store information about a single
transmission queue of a network device. This class is meant to store the
state of a transmission queue (i.e., whether the queue is stopped or not)
and some data used by techniques such as Byte Queue Limits. Also, multi-queue
aware queue discs can aggregate a child queue disc to an object of this class.
These features (excluding BQL) are added in subsequent commits.
The NetDevice class maintains a vector of NetDeviceQueue pointers, one for
each transmission queue. A NetDevice constructor is added which creates a
single transmission queue by default for every device. The number of transmission
queues can be modified (by child classes) by calling NetDevice::SetTxQueuesN.
Two public methods, GetTxQueue and GetTxQueuesN, are also added to the NetDevice class
to return the i-th NetDeviceQueue and the number of transmission queues, respectively.
2016-03-08 10:44:08 -08:00

609 lines
20 KiB
C++

/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2005,2006 INRIA
*
* 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
* Modified by Emmanuelle Laprise to remove dependence on LLC headers
* Modified by Stefano Avallone to add NetDeviceQueue and NetDeviceQueueInterface
*/
#ifndef NET_DEVICE_H
#define NET_DEVICE_H
#include <string>
#include <vector>
#include <stdint.h>
#include "ns3/callback.h"
#include "ns3/object.h"
#include "ns3/ptr.h"
#include "address.h"
#include "ns3/ipv4-address.h"
#include "ns3/ipv6-address.h"
namespace ns3 {
class Node;
class Channel;
class Packet;
/**
* \ingroup network
* \defgroup netdevice Network Device
*/
/**
* \ingroup netdevice
* \brief Base class to represent items of packet Queues
*
* An item stored in an ns-3 packet Queue contains a packet and possibly other
* information. An item of the base class only contains a packet. Subclasses
* can be derived from this base class to allow items to contain additional
* information.
*/
class QueueItem : public SimpleRefCount<QueueItem>
{
public:
/**
* \brief Create a queue item containing a packet.
* \param p the packet included in the created item.
*/
QueueItem (Ptr<Packet> p);
virtual ~QueueItem ();
/**
* \return the packet included in this item.
*/
Ptr<Packet> GetPacket (void) const;
/**
* \brief Use this method (instead of GetPacket ()->GetSize ()) to get the packet size
*
* Subclasses may keep header and payload separate to allow manipulating the header,
* so using this method ensures that the correct packet size is returned.
*
* \return the size of the packet included in this item.
*/
virtual uint32_t GetPacketSize (void) const;
/**
* \brief Print the item contents.
* \param os output stream in which the data should be printed.
*/
virtual void Print (std::ostream &os) const;
/**
* TracedCallback signature for Ptr<QueueItem>
*
* \param [in] item The queue item.
*/
typedef void (* TracedCallback) (Ptr<const QueueItem> item);
private:
/**
* \brief Default constructor
*
* Defined and unimplemented to avoid misuse
*/
QueueItem ();
/**
* \brief Copy constructor
*
* Defined and unimplemented to avoid misuse
*/
QueueItem (const QueueItem &);
/**
* \brief Assignment operator
*
* Defined and unimplemented to avoid misuse
* \returns
*/
QueueItem &operator = (const QueueItem &);
Ptr<Packet> m_packet;
};
/**
* \brief Stream insertion operator.
*
* \param os the stream
* \param item the item
* \returns a reference to the stream
*/
std::ostream& operator<< (std::ostream& os, const QueueItem &item);
/**
* \ingroup netdevice
*
* \brief Network device transmission queue
*
* This class stores information about a single transmission queue
* of a network device that is exposed to queue discs. Such information
* includes the state of the transmission queue (whether it has been
* stopped or not) and data used by techniques such as Byte Queue Limits.
*
* This class roughly models the struct netdev_queue of Linux.
* \todo Implement BQL
*/
class NetDeviceQueue : public SimpleRefCount<NetDeviceQueue>
{
public:
NetDeviceQueue ();
virtual ~NetDeviceQueue();
/**
* Called by the device to start this (hardware) transmission queue.
* This is the analogous to the netif_tx_start_queue function of the Linux kernel.
*/
virtual void Start (void);
/**
* Called by the device to stop this (hardware) transmission queue.
* This is the analogous to the netif_tx_stop_queue function of the Linux kernel.
*/
virtual void Stop (void);
/**
* Called by the device to wake the queue disc associated with this
* (hardware) transmission queue. This is done by invoking the wake callback.
* This is the analogous to the netif_tx_wake_queue function of the Linux kernel.
*/
virtual void Wake (void);
/**
* \brief Get the status of the device transmission queue.
* \return true if the (hardware) transmission queue is stopped.
*
* Called by queue discs to enquire about the status of a given transmission queue.
* This is the analogous to the netif_tx_queue_stopped function of the Linux kernel.
*/
bool IsStopped (void) const;
/// Callback invoked by netdevices to wake upper layers
typedef Callback< void > WakeCallback;
/**
* \brief Set the wake callback
* \param cb the callback to set
*
* Called by the traffic control layer to set the wake callback. The wake callback
* is invoked by the device whenever it is needed to "wake" the upper layers (i.e.,
* solicitate the queue disc associated with this transmission queue (in case of
* multi-queue aware queue discs) or to the network device (otherwise) to send
* packets down to the device).
*/
virtual void SetWakeCallback (WakeCallback cb);
/**
* \brief Check whether a wake callback has been set on this device queue.
* \return true if the wake callback has been set.
*/
virtual bool HasWakeCallbackSet (void) const;
private:
bool m_stopped; //!< Status of the transmission queue
WakeCallback m_wakeCallback; //!< Wake callback
};
/**
* \ingroup netdevice
*
* \brief Network device transmission queue interface
*
* This interface is required by the traffic control layer to access the information
* about the status of the transmission queues of a device. Thus, every NetDevice
* (but loopback) needs to create this interface. NetDevices supporting flow control
* can start and stop their device transmission queues and wake the upper layers through
* this interface. By default, a NetDeviceQueueInterface object is created with a single
* device transmission queue. Therefore, multi-queue devices need to call SetTxQueuesN
* to create additional queues (before a root queue disc is installed, i.e., typically
* before an IPv4/IPv6 address is assigned to the device), implement a GetSelectedQueue
* method and pass a callback to such a method through the SetSelectedQueueCallback method.
*/
class NetDeviceQueueInterface : public Object
{
public:
/**
* \brief Get the type ID.
* \return the object TypeId
*/
static TypeId GetTypeId (void);
/**
* \brief Constructor
*
* Creates one NetDeviceQueue by default
*/
NetDeviceQueueInterface ();
virtual ~NetDeviceQueueInterface ();
/**
* \brief Get the i-th transmission queue of the device.
* \return the i-th transmission queue of the device.
*
* The index of the first transmission queue is zero.
*/
Ptr<NetDeviceQueue> GetTxQueue (uint8_t i) const;
/**
* \brief Get the number of device transmission queues.
* \return the number of device transmission queues.
*/
uint8_t GetTxQueuesN (void) const;
/**
* \brief Set the number of device transmission queues.
* \param numTxQueues number of device transmission queues.
*
* Called by a device to set the number of device transmission queues.
* This method can be called by a NetDevice at initialization time only, because
* it is not possible to change the number of device transmission queues after
* the wake callbacks have been set on the device queues.
*/
void SetTxQueuesN (uint8_t numTxQueues);
/// Callback invoked to determine the tx queue selected for a given packet
typedef Callback< uint8_t, Ptr<QueueItem> > SelectQueueCallback;
/**
* \brief Set the select queue callback
* \param cb the callback to set
*
* Called by a device to set the select queue callback, i.e., the method used
* to select a device transmission queue for a given packet
*/
void SetSelectQueueCallback (SelectQueueCallback cb);
/**
* \brief Get the id of the transmission queue selected for the given packet
* \return the id of the transmission queue selected for the given packet
*
* Called by the traffic control when it needs to determine which device
* transmission queue a given packet must be enqueued into. This function
* calls the select queue callback, if set by the device. Return 0 otherwise.
*/
uint8_t GetSelectedQueue (Ptr<QueueItem> item) const;
/**
* \brief Return true if a queue disc is installed on the device.
* \return true if a queue disc is installed on the device.
*/
bool IsQueueDiscInstalled (void) const;
/**
* \brief Set the member variable indicating whether a queue disc is installed or not
* \param installed the value for the member variable indicating whether a queue disc is installed or not
*/
void SetQueueDiscInstalled (bool installed);
protected:
/**
* \brief Dispose of the object
*/
virtual void DoDispose (void);
private:
std::vector< Ptr<NetDeviceQueue> > m_txQueuesVector; //!< Device transmission queues
SelectQueueCallback m_selectQueueCallback; //!< Select queue callback
bool m_queueDiscInstalled; //!< Boolean value indicating whether a queue disc is installed or not
};
/**
* \ingroup netdevice
*
* \brief Network layer to device interface
*
* This interface defines the API which the IP and ARP
* layers need to access to manage an instance of a network device
* layer. It currently does not support MAC-level
* multicast but this should not be too hard to add by adding
* extra methods to register MAC multicast addresses to
* filter out unwanted packets before handing them to the
* higher layers.
*
* In Linux, this interface is analogous to the interface
* just above dev_queue_xmit() (i.e., IP packet is fully
* constructed with destination MAC address already selected).
*
* If you want to write a new MAC layer, you need to subclass
* this base class and implement your own version of the
* pure virtual methods in this class.
*
* This class was designed to hide as many MAC-level details as
* possible from the perspective of layer 3 to allow a single layer 3
* to work with any kind of MAC layer. Specifically, this class
* encapsulates the specific format of MAC addresses used by a
* device such that the layer 3 does not need any modification
* to handle new address formats. This means obviously that the
* NetDevice class must know about the address format of all potential
* layer 3 protocols through its GetMulticast methods: the current
* API has been optimized to make it easy to add new MAC protocols,
* not to add new layer 3 protocols.
*/
class NetDevice : public Object
{
public:
/**
* \brief Get the type ID.
* \return the object TypeId
*/
static TypeId GetTypeId (void);
virtual ~NetDevice();
/**
* \param index ifIndex of the device
*/
virtual void SetIfIndex (const uint32_t index) = 0;
/**
* \return index ifIndex of the device
*/
virtual uint32_t GetIfIndex (void) const = 0;
/**
* \return the channel this NetDevice is connected to. The value
* returned can be zero if the NetDevice is not yet connected
* to any channel or if the underlying NetDevice has no
* concept of a channel. i.e., callers _must_ check for zero
* and be ready to handle it.
*/
virtual Ptr<Channel> GetChannel (void) const = 0;
/**
* Set the address of this interface
* \param address address to set
*/
virtual void SetAddress (Address address) = 0;
/**
* \return the current Address of this interface.
*/
virtual Address GetAddress (void) const = 0;
/**
* \param mtu MTU value, in bytes, to set for the device
* \return whether the MTU value was within legal bounds
*
* Override for default MTU defined on a per-type basis.
*/
virtual bool SetMtu (const uint16_t mtu) = 0;
/**
* \return the link-level MTU in bytes for this interface.
*
* This value is typically used by the IP layer to perform
* IP fragmentation when needed.
*/
virtual uint16_t GetMtu (void) const = 0;
/**
* \return true if link is up; false otherwise
*/
virtual bool IsLinkUp (void) const = 0;
/**
* TracedCallback signature for link changed event.
*/
typedef void (* LinkChangeTracedCallback) (void);
/**
* \param callback the callback to invoke
*
* Add a callback invoked whenever the link
* status changes to UP. This callback is typically used
* by the IP/ARP layer to flush the ARP cache and by IPv6 stack
* to flush NDISC cache whenever the link goes up.
*/
virtual void AddLinkChangeCallback (Callback<void> callback) = 0;
/**
* \return true if this interface supports a broadcast address,
* false otherwise.
*/
virtual bool IsBroadcast (void) const = 0;
/**
* \return the broadcast address supported by
* this netdevice.
*
* Calling this method is invalid if IsBroadcast returns
* not true.
*/
virtual Address GetBroadcast (void) const = 0;
/**
* \return value of m_isMulticast flag
*/
virtual bool IsMulticast (void) const = 0;
/**
* \brief Make and return a MAC multicast address using the provided
* multicast group
*
* \RFC{1112} says that an Ipv4 host group address is mapped to an Ethernet
* multicast address by placing the low-order 23-bits of the IP address into
* the low-order 23 bits of the Ethernet multicast address
* 01-00-5E-00-00-00 (hex). Similar RFCs exist for Ipv6 and Eui64 mappings.
* This method performs the multicast address creation function appropriate
* to the underlying MAC address of the device. This MAC address is
* encapsulated in an abstract Address to avoid dependencies on the exact
* MAC address format.
*
* In the case of net devices that do not support
* multicast, clients are expected to test NetDevice::IsMulticast and avoid
* attempting to map multicast packets. Subclasses of NetDevice that do
* support multicasting are expected to override this method and provide an
* implementation appropriate to the particular device.
*
* \param multicastGroup The IP address for the multicast group destination
* of the packet.
* \return The MAC multicast Address used to send packets to the provided
* multicast group.
*
* \warning Calling this method is invalid if IsMulticast returns not true.
* \see IsMulticast()
*/
virtual Address GetMulticast (Ipv4Address multicastGroup) const = 0;
/**
* \brief Get the MAC multicast address corresponding
* to the IPv6 address provided.
* \param addr IPv6 address
* \return the MAC multicast address
* \warning Calling this method is invalid if IsMulticast returns not true.
*/
virtual Address GetMulticast (Ipv6Address addr) const = 0;
/**
* \brief Return true if the net device is acting as a bridge.
*
* \return value of m_isBridge flag
*/
virtual bool IsBridge (void) const = 0;
/**
* \brief Return true if the net device is on a point-to-point link.
*
* \return value of m_isPointToPoint flag
*/
virtual bool IsPointToPoint (void) const = 0;
/**
* \param packet packet sent from above down to Network Device
* \param dest mac address of the destination (already resolved)
* \param protocolNumber identifies the type of payload contained in
* this packet. Used to call the right L3Protocol when the packet
* is received.
*
* Called from higher layer to send packet into Network Device
* to the specified destination Address
*
* \return whether the Send operation succeeded
*/
virtual bool Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber) = 0;
/**
* \param packet packet sent from above down to Network Device
* \param source source mac address (so called "MAC spoofing")
* \param dest mac address of the destination (already resolved)
* \param protocolNumber identifies the type of payload contained in
* this packet. Used to call the right L3Protocol when the packet
* is received.
*
* Called from higher layer to send packet into Network Device
* with the specified source and destination Addresses.
*
* \return whether the Send operation succeeded
*/
virtual bool SendFrom (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber) = 0;
/**
* \returns the node base class which contains this network
* interface.
*
* When a subclass needs to get access to the underlying node
* base class to print the nodeid for example, it can invoke
* this method.
*/
virtual Ptr<Node> GetNode (void) const = 0;
/**
* \param node the node associated to this netdevice.
*
* This method is called from ns3::Node::AddDevice.
*/
virtual void SetNode (Ptr<Node> node) = 0;
/**
* \returns true if ARP is needed, false otherwise.
*
* Called by higher-layers to check if this NetDevice requires
* ARP to be used.
*/
virtual bool NeedsArp (void) const = 0;
/**
* Packet types are used as they are in Linux. GCC name resolution on
* typedef enum {} PacketType is broken for the foreseeable future, so
* if you need to use ns-3 PacketType in a driver that also uses the
* Linux packet types you're hosed unless we define a shadow type,
* which we do here.
*/
enum PacketType
{
PACKET_HOST = 1, /**< Packet addressed oo us */
NS3_PACKET_HOST = PACKET_HOST,
PACKET_BROADCAST, /**< Packet addressed to all */
NS3_PACKET_BROADCAST = PACKET_BROADCAST,
PACKET_MULTICAST, /**< Packet addressed to multicast group */
NS3_PACKET_MULTICAST = PACKET_MULTICAST,
PACKET_OTHERHOST, /**< Packet addressed to someone else */
NS3_PACKET_OTHERHOST = PACKET_OTHERHOST,
};
/**
* \param device a pointer to the net device which is calling this callback
* \param packet the packet received
* \param protocol the 16 bit protocol number associated with this packet.
* This protocol number is expected to be the same protocol number
* given to the Send method by the user on the sender side.
* \param sender the address of the sender
* \returns true if the callback could handle the packet successfully, false
* otherwise.
*/
typedef Callback< bool, Ptr<NetDevice>, Ptr<const Packet>, uint16_t, const Address & > ReceiveCallback;
/**
* \param cb callback to invoke whenever a packet has been received and must
* be forwarded to the higher layers.
*
* Set the callback to be used to notify higher layers when a packet has been
* received.
*/
virtual void SetReceiveCallback (ReceiveCallback cb) = 0;
/**
* \param device a pointer to the net device which is calling this callback
* \param packet the packet received
* \param protocol the 16 bit protocol number associated with this packet.
* This protocol number is expected to be the same protocol number
* given to the Send method by the user on the sender side.
* \param sender the address of the sender
* \param receiver the address of the receiver
* \param packetType type of packet received (broadcast/multicast/unicast/otherhost)
* \returns true if the callback could handle the packet successfully, false
* otherwise.
*/
typedef Callback< bool, Ptr<NetDevice>, Ptr<const Packet>, uint16_t,
const Address &, const Address &, enum PacketType > PromiscReceiveCallback;
/**
* \param cb callback to invoke whenever a packet has been received in promiscuous mode and must
* be forwarded to the higher layers.
*
* Enables netdevice promiscuous mode and sets the callback that
* will handle promiscuous mode packets. Note, promiscuous mode
* packets means _all_ packets, including those packets that can be
* sensed by the netdevice but which are intended to be received by
* other hosts.
*/
virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb) = 0;
/**
* \return true if this interface supports a bridging mode, false otherwise.
*/
virtual bool SupportsSendFrom (void) const = 0;
};
} // namespace ns3
#endif /* NET_DEVICE_H */