A Discrete-Event Network Simulator
API
ofswitch13-queue.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 University of Campinas (Unicamp)
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Luciano Jerez Chaves <ljerezchaves@gmail.com>
18  */
19 
20 #include "ofswitch13-queue.h"
21 
22 #include "queue-tag.h"
23 
24 #include "ns3/log.h"
25 #include "ns3/object-vector.h"
26 #include "ns3/string.h"
27 
28 #undef NS_LOG_APPEND_CONTEXT
29 #define NS_LOG_APPEND_CONTEXT \
30  std::clog << "[dp " << m_dpId << " port " << m_portNo << "] ";
31 
32 namespace ns3
33 {
34 
35 NS_LOG_COMPONENT_DEFINE("OFSwitch13Queue");
36 NS_OBJECT_ENSURE_REGISTERED(OFSwitch13Queue);
37 
38 TypeId
40 {
41  static TypeId tid =
42  TypeId("ns3::OFSwitch13Queue")
44  .SetGroupName("OFSwitch13")
45  .AddAttribute("QueueList",
46  "The list of internal queues.",
49  MakeObjectVectorChecker<Queue<Packet>>());
50  return tid;
51 }
52 
54  : Queue<Packet>(),
55  m_dpId(0),
56  m_portNo(0),
57  m_swPort(nullptr),
58  NS_LOG_TEMPLATE_DEFINE("OFSwitch13Queue")
59 {
60  NS_LOG_FUNCTION(this);
61 }
62 
64 {
65  NS_LOG_FUNCTION(this);
66 }
67 
68 bool
70 {
71  NS_LOG_FUNCTION(this << packet);
72 
73  QueueTag queueTag;
74  packet->PeekPacketTag(queueTag);
75  int queueId = static_cast<int>(queueTag.GetQueueId());
76  NS_ASSERT_MSG(queueId < GetNQueues(), "Queue ID is out of range.");
77  NS_LOG_DEBUG("Packet to be enqueued in queue " << queueId);
78 
79  struct sw_queue* swQueue;
80  swQueue = dp_ports_lookup_queue(m_swPort, queueId);
81  NS_ASSERT_MSG(swQueue, "Invalid queue id.");
82 
83  bool retval = GetQueue(queueId)->Enqueue(packet);
84  if (retval)
85  {
86  swQueue->stats->tx_packets++;
87  swQueue->stats->tx_bytes += packet->GetSize();
88 
89  // Enqueue the packet in this queue too.
90  // This is necessary to ensure consistent statistics. Otherwise, when
91  // the NetDevice calls the IsEmpty () method, it will return true.
92  DoEnqueue(GetContainer().end(), packet);
93  }
94  else
95  {
96  NS_LOG_DEBUG("Packet enqueue dropped by internal queue " << queueId);
97  swQueue->stats->tx_errors++;
98 
99  // Drop the packet in this queue too.
100  // This is necessary to ensure consistent statistics.
101  DropBeforeEnqueue(packet);
102  }
103  return retval;
104 }
105 
106 int
108 {
109  return m_queues.size();
110 }
111 
113 OFSwitch13Queue::GetQueue(int queueId) const
114 {
115  return m_queues.at(queueId);
116 }
117 
118 void
120 {
121  NS_LOG_FUNCTION(this << port);
122 
123  m_swPort = port;
124  m_dpId = port->dp->id;
125  m_portNo = port->conf->port_no;
126 }
127 
128 void
130 {
131  NS_LOG_FUNCTION(this);
132 
133  // While m_swPort is valid, free internal stats and props
134  // structures for each available queue
135  if (m_swPort)
136  {
137  struct sw_queue* swQueue;
138  for (int queueId = 0; queueId < GetNQueues(); queueId++)
139  {
140  swQueue = &(m_swPort->queues[queueId]);
141  free(swQueue->stats);
142  free(swQueue->props);
143  }
144  m_swPort = nullptr;
145  }
146  m_queues.clear();
147 
148  // Chain up.
150 }
151 
152 void
154 {
155  NS_LOG_FUNCTION(this);
156 
157  // Chain up.
159 }
160 
161 uint32_t
163 {
164  NS_LOG_FUNCTION(this << queue);
165 
166  NS_ASSERT_MSG(queue, "Invalid queue pointer.");
167  NS_ASSERT_MSG(m_swPort, "Invalid OpenFlow port metadata.");
168 
169  uint32_t queueId = (m_swPort->num_queues)++;
170  struct sw_queue* swQueue = &(m_swPort->queues[queueId]);
171  NS_ASSERT_MSG(!swQueue->port, "Queue id already in use.");
172 
173  // Filling BOFUSS internal structures for this queue
174  swQueue->port = m_swPort;
175  swQueue->created = time_msec();
176 
177  size_t oflQueueStatsSize = sizeof(struct ofl_queue_stats);
178  swQueue->stats = (struct ofl_queue_stats*)xmalloc(oflQueueStatsSize);
179  memset(swQueue->stats, 0x00, oflQueueStatsSize);
180  swQueue->stats->port_no = m_swPort->conf->port_no;
181  swQueue->stats->queue_id = queueId;
182 
183  size_t oflPacketQueueSize = sizeof(struct ofl_packet_queue);
184  swQueue->props = (struct ofl_packet_queue*)xmalloc(oflPacketQueueSize);
185  swQueue->props->queue_id = queueId;
186  swQueue->props->properties_num = 0;
187 
188  // Inserting the ns3::Queue object into queue list.
189  m_queues.emplace_back(queue);
190  NS_LOG_DEBUG("New queue with ID " << queueId);
191 
192  return queueId;
193 }
194 
195 void
197 {
198  NS_LOG_FUNCTION(this << packet);
199 
200  // Dequeue the packet from this queue too. As we don't know the
201  // exactly packet location on this queue, we have to look for it.
202  for (auto it = GetContainer().begin(); it != GetContainer().end(); it++)
203  {
204  if ((*it) == packet)
205  {
206  DoDequeue(it);
207  return;
208  }
209  }
210  NS_LOG_WARN("Packet was not found on this queue.");
211 }
212 
213 void
215 {
216  NS_LOG_FUNCTION(this << packet);
217 
218  // Remove the packet from this queue too. As we don't know the
219  // exactly packet location on this queue, we have to look for it.
220  for (auto it = GetContainer().begin(); it != GetContainer().end(); it++)
221  {
222  if ((*it) == packet)
223  {
224  DoRemove(it);
225  return;
226  }
227  }
228  NS_LOG_WARN("Packet was not found on this queue.");
229 }
230 
231 } // namespace ns3
static TypeId GetTypeId()
Register this type.
void NotifyRemove(Ptr< Packet > packet)
Notify the parent class of a packet removed from any internal queue.
uint32_t AddQueue(Ptr< Queue< Packet >> queue)
Add a new internal queue to this OpenFlow queue interface.
void NotifyDequeue(Ptr< Packet > packet)
Notify the parent class of a packet dequeued from any internal queue.
Ptr< Queue< Packet > > GetQueue(int queueId) const
Get a pointer to internal queue with specific id.
bool Enqueue(Ptr< Packet > packet) override
QueueList_t m_queues
List of internal queues.
void DoDispose() override
Destructor implementation.
int GetNQueues() const
Get the number of internal queues.
OFSwitch13Queue()
Default constructor.
struct sw_port * m_swPort
BOFUSS port structure.
void SetPortStruct(struct sw_port *port)
Set the pointer to the internal BOFUSS port structure.
void DoInitialize() override
uint64_t m_dpId
OpenFlow datapath ID.
~OFSwitch13Queue() override
Dummy destructor, see DoDispose.
uint32_t m_portNo
OpenFlow port number.
virtual void DoInitialize()
Initialize() implementation.
Definition: object.cc:360
network packets
Definition: packet.h:241
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:863
bool PeekPacketTag(Tag &tag) const
Search a matching tag and call Tag::Deserialize if it is found.
Definition: packet.cc:1002
Template class for packet Queues.
Definition: queue.h:267
void DoDispose() override
Destructor implementation.
Definition: queue.h:618
Tag used to hold the queue id before enqueueing a packet into OFSwitch13Queue.
Definition: queue-tag.h:36
uint32_t GetQueueId() const
Definition: queue-tag.cc:63
a unique identifier for an interface.
Definition: type-id.h:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
uint16_t port
Definition: dsdv-manet.cc:45
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
ObjectPtrContainerValue ObjectVectorValue
ObjectVectorValue is an alias for ObjectPtrContainerValue.
Definition: object-vector.h:40
Ptr< const AttributeAccessor > MakeObjectVectorAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
Definition: object-vector.h:76
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_TEMPLATE_DEFINE(name)
Initialize a reference to a Log component.
Definition: log.h:236
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:261
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Every class exported by the ns3 library is enclosed in the ns3 namespace.
long long int time_msec(void)
Overriding BOFUSS time_msec weak function from timeval.c.