A Discrete-Event Network Simulator
API
qos-controller.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 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 "qos-controller.h"
21 
22 #include <ns3/internet-module.h>
23 #include <ns3/network-module.h>
24 
25 NS_LOG_COMPONENT_DEFINE("QosController");
27 
29 {
30  NS_LOG_FUNCTION(this);
31 }
32 
34 {
35  NS_LOG_FUNCTION(this);
36 }
37 
38 void
40 {
41  NS_LOG_FUNCTION(this);
42 
43  m_arpTable.clear();
44  OFSwitch13Controller::DoDispose();
45 }
46 
47 TypeId
49 {
50  static TypeId tid = TypeId("ns3::QosController")
52  .SetGroupName("OFSwitch13")
53  .AddConstructor<QosController>()
54  .AddAttribute("EnableMeter",
55  "Enable per-flow mettering.",
56  BooleanValue(false),
59  .AddAttribute("MeterRate",
60  "Per-flow meter rate.",
61  DataRateValue(DataRate("256Kbps")),
62  MakeDataRateAccessor(&QosController::m_meterRate),
63  MakeDataRateChecker())
64  .AddAttribute("LinkAggregation",
65  "Enable link aggregation.",
66  BooleanValue(true),
69  .AddAttribute("ServerIpAddr",
70  "Server IPv4 address.",
71  AddressValue(Address(Ipv4Address("10.1.1.1"))),
72  MakeAddressAccessor(&QosController::m_serverIpAddress),
73  MakeAddressChecker())
74  .AddAttribute("ServerTcpPort",
75  "Server TCP port.",
76  UintegerValue(9),
78  MakeUintegerChecker<uint64_t>())
79  .AddAttribute("ServerMacAddr",
80  "Server MAC address.",
81  AddressValue(Address(Mac48Address("00:00:00:00:00:01"))),
82  MakeAddressAccessor(&QosController::m_serverMacAddress),
83  MakeAddressChecker());
84  return tid;
85 }
86 
87 ofl_err
88 QosController::HandlePacketIn(struct ofl_msg_packet_in* msg,
90  uint32_t xid)
91 {
92  NS_LOG_FUNCTION(this << swtch << xid);
93 
94  char* msgStr = ofl_structs_match_to_string((struct ofl_match_header*)msg->match, nullptr);
95  NS_LOG_DEBUG("Packet in match: " << msgStr);
96  free(msgStr);
97 
98  if (msg->reason == OFPR_ACTION)
99  {
100  // Get Ethernet frame type
101  uint16_t ethType;
102  struct ofl_match_tlv* tlv;
103  tlv = oxm_match_lookup(OXM_OF_ETH_TYPE, (struct ofl_match*)msg->match);
104  memcpy(&ethType, tlv->value, OXM_LENGTH(OXM_OF_ETH_TYPE));
105 
106  if (ethType == ArpL3Protocol::PROT_NUMBER)
107  {
108  // ARP packet
109  return HandleArpPacketIn(msg, swtch, xid);
110  }
111  else if (ethType == Ipv4L3Protocol::PROT_NUMBER)
112  {
113  // Must be a TCP packet for connection request
114  return HandleConnectionRequest(msg, swtch, xid);
115  }
116  }
117 
118  // All handlers must free the message when everything is ok
119  ofl_msg_free((struct ofl_msg_header*)msg, nullptr);
120  return 0;
121 }
122 
123 void
125 {
126  NS_LOG_FUNCTION(this << swtch);
127 
128  // This function is called after a successfully handshake between controller
129  // and each switch. Let's check the switch for proper configuration.
130  if (swtch->GetDpId() == 1)
131  {
132  ConfigureBorderSwitch(swtch);
133  }
134  else if (swtch->GetDpId() == 2)
135  {
137  }
138 }
139 
140 void
142 {
143  NS_LOG_FUNCTION(this << swtch);
144 
145  // Get the switch datapath ID
146  uint64_t swDpId = swtch->GetDpId();
147 
148  // For packet-in messages, send only the first 128 bytes to the controller
149  DpctlExecute(swDpId, "set-config miss=128");
150 
151  // Redirect ARP requests to the controller
152  DpctlExecute(swDpId,
153  "flow-mod cmd=add,table=0,prio=20 "
154  "eth_type=0x0806,arp_op=1 apply:output=ctrl");
155 
156  // Using group #3 for rewriting headers and forwarding packets to clients
157  if (m_linkAggregation)
158  {
159  // Configure Group #3 for aggregating links 1 and 2
160  DpctlExecute(swDpId,
161  "group-mod cmd=add,type=sel,group=3 "
162  "weight=1,port=any,group=any set_field=ip_src:10.1.1.1"
163  ",set_field=eth_src:00:00:00:00:00:01,output=1 "
164  "weight=1,port=any,group=any set_field=ip_src:10.1.1.1"
165  ",set_field=eth_src:00:00:00:00:00:01,output=2");
166  }
167  else
168  {
169  // Configure Group #3 for sending packets only over link 1
170  DpctlExecute(swDpId,
171  "group-mod cmd=add,type=ind,group=3 "
172  "weight=0,port=any,group=any set_field=ip_src:10.1.1.1"
173  ",set_field=eth_src:00:00:00:00:00:01,output=1");
174  }
175 
176  // Groups #1 and #2 send traffic to internal servers (ports 3 and 4)
177  DpctlExecute(swDpId,
178  "group-mod cmd=add,type=ind,group=1 "
179  "weight=0,port=any,group=any set_field=ip_dst:10.1.1.2,"
180  "set_field=eth_dst:00:00:00:00:00:08,output=3");
181  DpctlExecute(swDpId,
182  "group-mod cmd=add,type=ind,group=2 "
183  "weight=0,port=any,group=any set_field=ip_dst:10.1.1.3,"
184  "set_field=eth_dst:00:00:00:00:00:0a,output=4");
185 
186  // Incoming TCP connections (ports 1 and 2) are sent to the controller
187  DpctlExecute(swDpId,
188  "flow-mod cmd=add,table=0,prio=500 "
189  "in_port=1,eth_type=0x0800,ip_proto=6,ip_dst=10.1.1.1,"
190  "eth_dst=00:00:00:00:00:01 apply:output=ctrl");
191  DpctlExecute(swDpId,
192  "flow-mod cmd=add,table=0,prio=500 "
193  "in_port=2,eth_type=0x0800,ip_proto=6,ip_dst=10.1.1.1,"
194  "eth_dst=00:00:00:00:00:01 apply:output=ctrl");
195 
196  // TCP packets from servers are sent to the external network through group 3
197  DpctlExecute(swDpId,
198  "flow-mod cmd=add,table=0,prio=700 "
199  "in_port=3,eth_type=0x0800,ip_proto=6 apply:group=3");
200  DpctlExecute(swDpId,
201  "flow-mod cmd=add,table=0,prio=700 "
202  "in_port=4,eth_type=0x0800,ip_proto=6 apply:group=3");
203 }
204 
205 void
207 {
208  NS_LOG_FUNCTION(this << swtch);
209 
210  // Get the switch datapath ID
211  uint64_t swDpId = swtch->GetDpId();
212 
213  if (m_linkAggregation)
214  {
215  // Configure Group #1 for aggregating links 1 and 2
216  DpctlExecute(swDpId,
217  "group-mod cmd=add,type=sel,group=1 "
218  "weight=1,port=any,group=any output=1 "
219  "weight=1,port=any,group=any output=2");
220  }
221  else
222  {
223  // Configure Group #1 for sending packets only over link 1
224  DpctlExecute(swDpId,
225  "group-mod cmd=add,type=ind,group=1 "
226  "weight=0,port=any,group=any output=1");
227  }
228 
229  // Packets from input ports 1 and 2 are redirecte to port 3
230  DpctlExecute(swDpId,
231  "flow-mod cmd=add,table=0,prio=500 "
232  "in_port=1 write:output=3");
233  DpctlExecute(swDpId,
234  "flow-mod cmd=add,table=0,prio=500 "
235  "in_port=2 write:output=3");
236 
237  // Packets from input port 3 are redirected to group 1
238  DpctlExecute(swDpId,
239  "flow-mod cmd=add,table=0,prio=500 "
240  "in_port=3 write:group=1");
241 }
242 
243 ofl_err
244 QosController::HandleArpPacketIn(struct ofl_msg_packet_in* msg,
246  uint32_t xid)
247 {
248  NS_LOG_FUNCTION(this << swtch << xid);
249 
250  struct ofl_match_tlv* tlv;
251  Ipv4Address serverIp = Ipv4Address::ConvertFrom(m_serverIpAddress);
252  Mac48Address serverMac = Mac48Address::ConvertFrom(m_serverMacAddress);
253 
254  // Get ARP operation
255  uint16_t arpOp;
256  tlv = oxm_match_lookup(OXM_OF_ARP_OP, (struct ofl_match*)msg->match);
257  memcpy(&arpOp, tlv->value, OXM_LENGTH(OXM_OF_ARP_OP));
258 
259  // Get input port
260  uint32_t inPort;
261  tlv = oxm_match_lookup(OXM_OF_IN_PORT, (struct ofl_match*)msg->match);
262  memcpy(&inPort, tlv->value, OXM_LENGTH(OXM_OF_IN_PORT));
263 
264  // Get source and target IP address
265  Ipv4Address srcIp;
266  Ipv4Address dstIp;
267  srcIp = ExtractIpv4Address(OXM_OF_ARP_SPA, (struct ofl_match*)msg->match);
268  dstIp = ExtractIpv4Address(OXM_OF_ARP_TPA, (struct ofl_match*)msg->match);
269 
270  // Get Source MAC address
271  Mac48Address srcMac;
272  Mac48Address dstMac;
273  tlv = oxm_match_lookup(OXM_OF_ARP_SHA, (struct ofl_match*)msg->match);
274  srcMac.CopyFrom(tlv->value);
275  tlv = oxm_match_lookup(OXM_OF_ARP_THA, (struct ofl_match*)msg->match);
276  dstMac.CopyFrom(tlv->value);
277 
278  // Check for ARP request
279  if (arpOp == ArpHeader::ARP_TYPE_REQUEST)
280  {
281  uint8_t replyData[64];
282 
283  // Check for destination IP
284  if (dstIp == serverIp)
285  {
286  // Reply with virtual service IP/MAC addresses
287  Ptr<Packet> pkt = CreateArpReply(serverMac, dstIp, srcMac, srcIp);
288  NS_ASSERT_MSG(pkt->GetSize() == 64, "Invalid packet size.");
289  pkt->CopyData(replyData, 64);
290  }
291  else
292  {
293  // Check for existing information
294  Mac48Address replyMac = GetArpEntry(dstIp);
295  Ptr<Packet> pkt = CreateArpReply(replyMac, dstIp, srcMac, srcIp);
296  NS_ASSERT_MSG(pkt->GetSize() == 64, "Invalid packet size.");
297  pkt->CopyData(replyData, 64);
298  }
299 
300  // Send the ARP replay back to the input port
301  struct ofl_action_output* action =
302  (struct ofl_action_output*)xmalloc(sizeof(struct ofl_action_output));
303  action->header.type = OFPAT_OUTPUT;
304  action->port = OFPP_IN_PORT;
305  action->max_len = 0;
306 
307  // Send the ARP reply within an OpenFlow PacketOut message
308  struct ofl_msg_packet_out reply;
309  reply.header.type = OFPT_PACKET_OUT;
310  reply.buffer_id = OFP_NO_BUFFER;
311  reply.in_port = inPort;
312  reply.data_length = 64;
313  reply.data = &replyData[0];
314  reply.actions_num = 1;
315  reply.actions = (struct ofl_action_header**)&action;
316 
317  SendToSwitch(swtch, (struct ofl_msg_header*)&reply, xid);
318  free(action);
319  }
320 
321  // All handlers must free the message when everything is ok
322  ofl_msg_free((struct ofl_msg_header*)msg, nullptr);
323  return 0;
324 }
325 
326 ofl_err
327 QosController::HandleConnectionRequest(struct ofl_msg_packet_in* msg,
329  uint32_t xid)
330 {
331  NS_LOG_FUNCTION(this << swtch << xid);
332 
333  static uint32_t connectionCounter = 0;
334  connectionCounter++;
335 
336  struct ofl_match_tlv* tlv;
337  Ipv4Address serverIp = Ipv4Address::ConvertFrom(m_serverIpAddress);
338  Mac48Address serverMac = Mac48Address::ConvertFrom(m_serverMacAddress);
339 
340  // Get input port
341  uint32_t inPort;
342  tlv = oxm_match_lookup(OXM_OF_IN_PORT, (struct ofl_match*)msg->match);
343  memcpy(&inPort, tlv->value, OXM_LENGTH(OXM_OF_IN_PORT));
344 
345  // Get Source MAC address
346  Mac48Address srcMac;
347  tlv = oxm_match_lookup(OXM_OF_ETH_SRC, (struct ofl_match*)msg->match);
348  srcMac.CopyFrom(tlv->value);
349 
350  // Get source and destination IP address
351  Ipv4Address srcIp;
352  Ipv4Address dstIp;
353  srcIp = ExtractIpv4Address(OXM_OF_IPV4_SRC, (struct ofl_match*)msg->match);
354  dstIp = ExtractIpv4Address(OXM_OF_IPV4_DST, (struct ofl_match*)msg->match);
355 
356  // Get source and destination TCP ports
357  uint16_t srcPort;
358  uint16_t dstPort;
359  tlv = oxm_match_lookup(OXM_OF_TCP_SRC, (struct ofl_match*)msg->match);
360  memcpy(&srcPort, tlv->value, OXM_LENGTH(OXM_OF_TCP_SRC));
361  tlv = oxm_match_lookup(OXM_OF_TCP_DST, (struct ofl_match*)msg->match);
362  memcpy(&dstPort, tlv->value, OXM_LENGTH(OXM_OF_TCP_DST));
363 
364  // Create an ARP request for further address resolution
365  SaveArpEntry(srcIp, srcMac);
366  uint8_t replyData[64];
367  Ptr<Packet> pkt = CreateArpRequest(serverMac, serverIp, srcIp);
368  NS_ASSERT_MSG(pkt->GetSize() == 64, "Invalid packet size.");
369  pkt->CopyData(replyData, 64);
370 
371  struct ofl_action_output* arpAction =
372  (struct ofl_action_output*)xmalloc(sizeof(struct ofl_action_output));
373  arpAction->header.type = OFPAT_OUTPUT;
374  arpAction->port = OFPP_IN_PORT;
375  arpAction->max_len = 0;
376 
377  // Send the ARP request within an OpenFlow PacketOut message
378  struct ofl_msg_packet_out arpRequest;
379  arpRequest.header.type = OFPT_PACKET_OUT;
380  arpRequest.buffer_id = OFP_NO_BUFFER;
381  arpRequest.in_port = inPort;
382  arpRequest.data_length = 64;
383  arpRequest.data = &replyData[0];
384  arpRequest.actions_num = 1;
385  arpRequest.actions = (struct ofl_action_header**)&arpAction;
386 
387  SendToSwitch(swtch, (struct ofl_msg_header*)&arpRequest, 0);
388  free(arpAction);
389 
390  // Check for valid service connection request
391  NS_ASSERT_MSG((dstIp == serverIp) && (dstPort == m_serverTcpPort),
392  "Invalid IP address / TCP port.");
393 
394  // Select an internal server to handle this connection
395  uint16_t serverNumber = 1 + (connectionCounter % 2);
396  NS_LOG_INFO("Connection " << connectionCounter << " redirected to server " << serverNumber);
397 
398  // Get the switch datapath ID
399  uint64_t swDpId = swtch->GetDpId();
400 
401  // If enable, install the metter entry for this connection
402  if (m_meterEnable)
403  {
404  std::ostringstream meterCmd;
405  meterCmd << "meter-mod cmd=add,flags=1,meter=" << connectionCounter
406  << " drop:rate=" << m_meterRate.GetBitRate() / 1000;
407  DpctlExecute(swDpId, meterCmd.str());
408  }
409 
410  // Install the flow entry for this TCP connection
411  std::ostringstream flowCmd;
412  flowCmd << "flow-mod cmd=add,table=0,prio=1000 eth_type=0x0800,ip_proto=6"
413  << ",ip_src=" << srcIp << "ip_dst=" << m_serverIpAddress
414  << ",tcp_dst=" << m_serverTcpPort << ",tcp_src=" << srcPort;
415  if (m_meterEnable)
416  {
417  flowCmd << " meter:" << connectionCounter;
418  }
419  flowCmd << " write:group=" << serverNumber;
420  DpctlExecute(swDpId, flowCmd.str());
421 
422  // Create group action with server number
423  struct ofl_action_group* action =
424  (struct ofl_action_group*)xmalloc(sizeof(struct ofl_action_group));
425  action->header.type = OFPAT_GROUP;
426  action->group_id = serverNumber;
427 
428  // Send the packet out to the switch.
429  struct ofl_msg_packet_out reply;
430  reply.header.type = OFPT_PACKET_OUT;
431  reply.buffer_id = msg->buffer_id;
432  reply.in_port = inPort;
433  reply.actions_num = 1;
434  reply.actions = (struct ofl_action_header**)&action;
435  reply.data_length = 0;
436  reply.data = nullptr;
437  if (msg->buffer_id == NO_BUFFER)
438  {
439  // No packet buffer. Send data back to switch
440  reply.data_length = msg->data_length;
441  reply.data = msg->data;
442  }
443 
444  SendToSwitch(swtch, (struct ofl_msg_header*)&reply, xid);
445  free(action);
446 
447  // All handlers must free the message when everything is ok
448  ofl_msg_free((struct ofl_msg_header*)msg, nullptr);
449  return 0;
450 }
451 
453 QosController::ExtractIpv4Address(uint32_t oxm_of, struct ofl_match* match)
454 {
455  switch (oxm_of)
456  {
457  case static_cast<uint32_t>(OXM_OF_ARP_SPA):
458  case static_cast<uint32_t>(OXM_OF_ARP_TPA):
459  case static_cast<uint32_t>(OXM_OF_IPV4_DST):
460  case static_cast<uint32_t>(OXM_OF_IPV4_SRC): {
461  uint32_t ip;
462  int size = OXM_LENGTH(oxm_of);
463  struct ofl_match_tlv* tlv = oxm_match_lookup(oxm_of, match);
464  memcpy(&ip, tlv->value, size);
465  return Ipv4Address(ntohl(ip));
466  }
467  default:
468  NS_ABORT_MSG("Invalid IP field.");
469  }
470 }
471 
474 {
475  NS_LOG_FUNCTION(this << srcMac << srcIp << dstIp);
476 
477  Ptr<Packet> packet = Create<Packet>();
478 
479  // ARP header
480  ArpHeader arp;
481  arp.SetRequest(srcMac, srcIp, Mac48Address::GetBroadcast(), dstIp);
482  packet->AddHeader(arp);
483 
484  // Ethernet header
485  EthernetHeader eth(false);
486  eth.SetSource(srcMac);
487  eth.SetDestination(Mac48Address::GetBroadcast());
488  if (packet->GetSize() < 46)
489  {
490  uint8_t buffer[46];
491  memset(buffer, 0, 46);
492  Ptr<Packet> padd = Create<Packet>(buffer, 46 - packet->GetSize());
493  packet->AddAtEnd(padd);
494  }
495  eth.SetLengthType(ArpL3Protocol::PROT_NUMBER);
496  packet->AddHeader(eth);
497 
498  // Ethernet trailer
499  EthernetTrailer trailer;
500  if (Node::ChecksumEnabled())
501  {
502  trailer.EnableFcs(true);
503  }
504  trailer.CalcFcs(packet);
505  packet->AddTrailer(trailer);
506 
507  return packet;
508 }
509 
512  Ipv4Address srcIp,
513  Mac48Address dstMac,
514  Ipv4Address dstIp)
515 {
516  NS_LOG_FUNCTION(this << srcMac << srcIp << dstMac << dstIp);
517 
518  Ptr<Packet> packet = Create<Packet>();
519 
520  // ARP header
521  ArpHeader arp;
522  arp.SetReply(srcMac, srcIp, dstMac, dstIp);
523  packet->AddHeader(arp);
524 
525  // Ethernet header
526  EthernetHeader eth(false);
527  eth.SetSource(srcMac);
528  eth.SetDestination(dstMac);
529  if (packet->GetSize() < 46)
530  {
531  uint8_t buffer[46];
532  memset(buffer, 0, 46);
533  Ptr<Packet> padd = Create<Packet>(buffer, 46 - packet->GetSize());
534  packet->AddAtEnd(padd);
535  }
536  eth.SetLengthType(ArpL3Protocol::PROT_NUMBER);
537  packet->AddHeader(eth);
538 
539  // Ethernet trailer
540  EthernetTrailer trailer;
541  if (Node::ChecksumEnabled())
542  {
543  trailer.EnableFcs(true);
544  }
545  trailer.CalcFcs(packet);
546  packet->AddTrailer(trailer);
547 
548  return packet;
549 }
550 
551 void
553 {
554  std::pair<Ipv4Address, Mac48Address> entry(ipAddr, macAddr);
555  std::pair<IpMacMap_t::iterator, bool> ret;
556  ret = m_arpTable.insert(entry);
557  if (ret.second == true)
558  {
559  NS_LOG_INFO("New ARP entry: " << ipAddr << " - " << macAddr);
560  return;
561  }
562 }
563 
566 {
567  IpMacMap_t::iterator ret;
568  ret = m_arpTable.find(ip);
569  if (ret != m_arpTable.end())
570  {
571  NS_LOG_INFO("Found ARP entry: " << ip << " - " << ret->second);
572  return ret->second;
573  }
574  NS_ABORT_MSG("No ARP information for this IP.");
575 }
An border OpenFlow 1.3 controller.
Address m_serverIpAddress
Virtual server IP address.
ofl_err HandleConnectionRequest(struct ofl_msg_packet_in *msg, Ptr< const RemoteSwitch > swtch, uint32_t xid)
Handle TCP connection request.
Ipv4Address ExtractIpv4Address(uint32_t oxm_of, struct ofl_match *match)
Extract an IPv4 address from packet match.
Ptr< Packet > CreateArpRequest(Mac48Address srcMac, Ipv4Address srcIp, Ipv4Address dstIp)
Create an ARP request packet, encapsulated inside of an Ethernet frame.
void HandshakeSuccessful(Ptr< const RemoteSwitch > swtch) override
Function invoked after a successfully handshake procedure between this controller and a remote switch...
Ptr< Packet > CreateArpReply(Mac48Address srcMac, Ipv4Address srcIp, Mac48Address dstMac, Ipv4Address dstIp)
Create an ARP reply packet, encapsulated inside of an Ethernet frame.
uint16_t m_serverTcpPort
Virtual server TCP port.
void DoDispose() override
Destructor implementation.
QosController()
Default constructor.
ofl_err HandlePacketIn(struct ofl_msg_packet_in *msg, Ptr< const RemoteSwitch > swtch, uint32_t xid) override
Handle a packet in message sent by the switch to this controller.
static TypeId GetTypeId()
Register this type.
void ConfigureBorderSwitch(Ptr< const RemoteSwitch > swtch)
Configure the border switch.
Address m_serverMacAddress
Border switch MAC address.
void ConfigureAggregationSwitch(Ptr< const RemoteSwitch > swtch)
Configure the aggregation switch.
IpMacMap_t m_arpTable
ARP resolution table.
bool m_meterEnable
Enable per-flow mettering.
~QosController() override
Dummy destructor.
DataRate m_meterRate
Per-flow meter rate.
ofl_err HandleArpPacketIn(struct ofl_msg_packet_in *msg, Ptr< const RemoteSwitch > swtch, uint32_t xid)
Handle ARP request messages.
void SaveArpEntry(Ipv4Address ipAddr, Mac48Address macAddr)
Save the pair IP / MAC address in ARP table.
bool m_linkAggregation
Enable link aggregation.
Mac48Address GetArpEntry(Ipv4Address ip)
Perform an ARP resolution.
a polymophic address class
Definition: address.h:100
AttributeValue implementation for Address.
The packet header for an ARP packet.
Definition: arp-header.h:36
void SetReply(Address sourceHardwareAddress, Ipv4Address sourceProtocolAddress, Address destinationHardwareAddress, Ipv4Address destinationProtocolAddress)
Set the ARP reply parameters.
Definition: arp-header.cc:49
void SetRequest(Address sourceHardwareAddress, Ipv4Address sourceProtocolAddress, Address destinationHardwareAddress, Ipv4Address destinationProtocolAddress)
Set the ARP request parameters.
Definition: arp-header.cc:34
AttributeValue implementation for Boolean.
Definition: boolean.h:37
uint64_t GetBitRate() const
Get the underlying bitrate.
Definition: data-rate.cc:305
AttributeValue implementation for DataRate.
Packet header for Ethernet.
void SetDestination(Mac48Address destination)
void SetLengthType(uint16_t size)
void SetSource(Mac48Address source)
Packet trailer for Ethernet.
void EnableFcs(bool enable)
Enable or disable FCS checking and calculations.
void CalcFcs(Ptr< const Packet > p)
Updates the Fcs Field to the correct FCS.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:43
an EUI-48 address
Definition: mac48-address.h:46
void CopyFrom(const uint8_t buffer[6])
OpenFlow 1.3 controller base class that can handle a collection of OpenFlow switches and provides the...
int SendToSwitch(Ptr< const RemoteSwitch > swtch, struct ofl_msg_header *msg, uint32_t xid=0)
Send a OFLib message to a registered switch.
int DpctlExecute(uint64_t dpId, const std::string textCmd)
Execute a dpctl command to interact with the remote switch.
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
Definition: packet.cc:354
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:268
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:863
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Copy the packet contents to a byte buffer.
Definition: packet.cc:400
void AddTrailer(const Trailer &trailer)
Add trailer to this packet.
Definition: packet.cc:324
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
a unique identifier for an interface.
Definition: type-id.h:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
Hold an unsigned integer type.
Definition: uinteger.h: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
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: boolean.h:86
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: uinteger.h:46
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:49
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#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_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
void(* DataRate)(DataRate oldValue, DataRate newValue)
TracedValue callback signature for DataRate.
Definition: data-rate.h:328
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46