A Discrete-Event Network Simulator
API
ofswitch13-controller.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-controller.h"
21 
22 #include <ns3/tcp-socket-factory.h>
23 #include <ns3/uinteger.h>
24 
25 #include <wordexp.h>
26 
27 namespace ns3
28 {
29 
30 NS_LOG_COMPONENT_DEFINE("OFSwitch13Controller");
31 NS_OBJECT_ENSURE_REGISTERED(OFSwitch13Controller);
32 
33 /********** Public methods ***********/
35  : m_serverSocket(nullptr)
36 {
37  NS_LOG_FUNCTION(this);
38 
39  m_xid = rand() & 0xffffffff;
40 }
41 
43 {
44  NS_LOG_FUNCTION(this);
45 }
46 
47 TypeId
49 {
50  static TypeId tid =
51  TypeId("ns3::OFSwitch13Controller")
52  .SetParent<Object>()
53  .SetGroupName("OFSwitch13")
54  .AddAttribute("Port",
55  "Port number to listen for incoming packets.",
56  UintegerValue(6653),
58  MakeUintegerChecker<uint16_t>());
59  return tid;
60 }
61 
62 void
64 {
65  NS_LOG_FUNCTION(this);
66 
67  m_serverSocket = nullptr;
68  m_addrSwMap.clear();
69  m_barrierMap.clear();
70  m_commandsMap.clear();
71  m_dpIdSwMap.clear();
72  m_echoMap.clear();
73 
75 }
76 
77 int
78 OFSwitch13Controller::DpctlExecute(uint64_t dpId, const std::string textCmd)
79 {
80  NS_LOG_FUNCTION(this << dpId << textCmd);
81 
83  if (!swtch)
84  {
85  // Save this command for further execution after handshake procedure.
86  NS_LOG_DEBUG("Schedulling command for an unregistered switch.");
87  auto it = m_commandsMap.find(dpId);
88  if (it == m_commandsMap.end())
89  {
90  // Create a new pending commands object for this datapath id.
91  Ptr<PendingCommands> pendCmds = Create<PendingCommands>();
92  std::pair<uint64_t, Ptr<PendingCommands>> entry(dpId, pendCmds);
93  auto ret = m_commandsMap.insert(entry);
94  if (ret.second == false)
95  {
96  NS_LOG_ERROR("Error when creating pending commands object.");
97  }
98  it = ret.first;
99  }
100 
101  // Save the dpctl command in the pending queue and return.
102  it->second->m_queue.push(textCmd);
103  return 0;
104  }
105 
106  // Parse the textCmd.
107  wordexp_t cmd;
108  wordexp(textCmd.c_str(), &cmd, 0);
109  char** argv = cmd.we_wordv;
110  size_t argc = cmd.we_wordc;
111 
112  // Execute the command.
113  int ret = dpctl_exec_ns3_command((void*)PeekPointer(swtch), argc, argv);
114  wordfree(&cmd);
115  return ret;
116 }
117 
118 void
120  struct ofl_msg_header* msg)
121 {
123 
124  Ptr<const RemoteSwitch> swtch((RemoteSwitch*)vconn, true);
125  swtch->m_ctrlApp->SendToSwitch(swtch, msg, 0);
126 }
127 
128 /********* Protected methods *********/
129 void
131 {
132  NS_LOG_FUNCTION(this << m_port);
133 
134  // Create the server listening socket
135  TypeId tcpFactory = TypeId::LookupByName("ns3::TcpSocketFactory");
137  m_serverSocket->SetAttribute("SegmentSize", UintegerValue(8900));
140 
141  // Setting socket callbacks
148 }
149 
150 void
152 {
153  NS_LOG_FUNCTION(this << m_port);
154 
155  for (const auto& it : m_dpIdSwMap)
156  {
157  Ptr<RemoteSwitch> swtch = it.second;
158  swtch->m_handler = nullptr;
159  }
160 
161  if (m_serverSocket)
162  {
165  }
166 
167  m_addrSwMap.clear();
168  m_barrierMap.clear();
169  m_commandsMap.clear();
170  m_dpIdSwMap.clear();
171  m_echoMap.clear();
172 }
173 
174 uint32_t
176 {
177  return ++m_xid;
178 }
179 
180 void
182 {
183  NS_LOG_FUNCTION(this << swtch);
184 }
185 
188 {
189  NS_LOG_FUNCTION(this << dpId);
190 
191  auto it = m_dpIdSwMap.find(dpId);
192  if (it != m_dpIdSwMap.end())
193  {
194  return it->second;
195  }
196  return nullptr;
197 }
198 
199 int
201  struct ofl_msg_header* msg,
202  uint32_t xid)
203 {
204  NS_LOG_FUNCTION(this << swtch);
205 
206  char* msgStr = ofl_msg_to_string(msg, nullptr);
207  NS_LOG_DEBUG("TX to switch " << swtch->GetIpv4() << " [dp "
208  << swtch->GetDpId() << "]: " << msgStr);
209  free(msgStr);
210 
211  // Set the transaction ID only for unknown values
212  if (!xid)
213  {
214  xid = GetNextXid();
215  }
216 
217  // Create the packet from the OpenFlow message and send it to the switch.
218  return swtch->m_handler->SendMessage(PacketFromMsg(msg, xid));
219 }
220 
221 void
223  size_t payloadSize)
224 {
225  NS_LOG_FUNCTION(this << swtch);
226 
227  // Create the echo request message
228  struct ofl_msg_echo msg;
229  msg.header.type = OFPT_ECHO_REQUEST;
230  msg.data_length = payloadSize;
231  msg.data = nullptr;
232 
233  // Fill payload with random bytes
234  if (payloadSize)
235  {
236  msg.data = (uint8_t*)xmalloc(payloadSize);
237  random_bytes(msg.data, payloadSize);
238  }
239 
240  // Create and save the echo metadata for this request
241  uint32_t xid = GetNextXid();
242  std::pair<uint32_t, EchoInfo> entry(xid, EchoInfo(swtch));
243  auto ret = m_echoMap.insert(entry);
244  if (ret.second == false)
245  {
246  NS_LOG_ERROR("Error requesting echo to switch " << swtch);
247  }
248 
249  // Send the message to the switch
250  SendToSwitch(swtch, (struct ofl_msg_header*)&msg, xid);
251 
252  // Free the payload
253  if (payloadSize)
254  {
255  free(msg.data);
256  }
257 }
258 
259 void
261 {
262  NS_LOG_FUNCTION(this << swtch);
263 
264  // Create the barrier request message
265  struct ofl_msg_header msg;
266  msg.type = OFPT_BARRIER_REQUEST;
267 
268  // Create and save the barrier metadata for this request
269  uint32_t xid = GetNextXid();
270  std::pair<uint32_t, BarrierInfo> entry(xid, BarrierInfo(swtch));
271  auto ret = m_barrierMap.insert(entry);
272  if (ret.second == false)
273  {
274  NS_LOG_ERROR("Error requesting barrier to switch " << swtch);
275  }
276 
277  // Send the message to the switch
278  SendToSwitch(swtch, &msg, xid);
279 }
280 
281 // --- BEGIN: Handlers functions -------
282 ofl_err
285  uint32_t xid)
286 {
287  NS_LOG_FUNCTION(this << swtch << xid);
288 
289  // Create the echo reply message
290  struct ofl_msg_echo reply;
291  reply.header.type = OFPT_ECHO_REPLY;
292  reply.data_length = msg->data_length;
293  reply.data = msg->data;
294  SendToSwitch(swtch, (struct ofl_msg_header*)&reply, xid);
295  ofl_msg_free((struct ofl_msg_header*)msg, nullptr);
296  return 0;
297 }
298 
299 ofl_err
300 OFSwitch13Controller::HandleEchoReply(struct ofl_msg_echo* msg,
302  uint32_t xid)
303 {
304  NS_LOG_FUNCTION(this << swtch << xid);
305 
306  auto it = m_echoMap.find(xid);
307  if (it == m_echoMap.end())
308  {
309  NS_LOG_WARN("Echo response for unknonw echo request.");
310  }
311  else
312  {
313  it->second.m_waiting = false;
314  it->second.m_recv = Simulator::Now();
315  NS_LOG_INFO("Echo reply from " << it->second.m_swtch->GetIpv4()
316  << " with RTT "
317  << it->second.GetRtt().As(Time::MS));
318  m_echoMap.erase(it);
319  }
320 
321  ofl_msg_free((struct ofl_msg_header*)msg, nullptr);
322  return 0;
323 }
324 
325 ofl_err
326 OFSwitch13Controller::HandleBarrierReply(struct ofl_msg_header* msg,
328  uint32_t xid)
329 {
330  NS_LOG_FUNCTION(this << swtch << xid);
331 
332  auto it = m_barrierMap.find(xid);
333  if (it == m_barrierMap.end())
334  {
335  NS_LOG_WARN("Barrier response for unknonw barrier request.");
336  }
337  else
338  {
339  NS_LOG_INFO("Barrier reply from " << it->second.m_swtch->GetIpv4());
340  m_barrierMap.erase(it);
341  }
342 
343  ofl_msg_free(msg, nullptr);
344  return 0;
345 }
346 
347 ofl_err
348 OFSwitch13Controller::HandleHello(struct ofl_msg_header* msg,
350  uint32_t xid)
351 {
352  NS_LOG_FUNCTION(this << swtch << xid);
353 
354  // We got the hello message from the switch. Let's proceed with the
355  // handshake and request the switch features.
356  ofl_msg_free(msg, nullptr);
357 
358  struct ofl_msg_header features;
359  features.type = OFPT_FEATURES_REQUEST;
360  SendToSwitch(swtch, &features);
361  SendBarrierRequest(swtch);
362 
363  return 0;
364 }
365 
366 ofl_err
367 OFSwitch13Controller::HandleFeaturesReply(struct ofl_msg_features_reply* msg,
368  Ptr<RemoteSwitch> swtch,
369  uint32_t xid)
370 {
371  NS_LOG_FUNCTION(this << swtch << xid);
372 
373  // We got the features reply message from the switch. Let's save switch
374  // features into metadata structure.
375  swtch->m_dpId = msg->datapath_id;
376  swtch->m_nBuffers = msg->n_buffers;
377  swtch->m_nTables = msg->n_tables;
378  swtch->m_auxiliaryId = msg->auxiliary_id;
379  swtch->m_capabilities = msg->capabilities;
380  ofl_msg_free((struct ofl_msg_header*)msg, nullptr);
381 
382  std::pair<uint64_t, Ptr<RemoteSwitch>> entry(swtch->m_dpId, swtch);
383  auto ret = m_dpIdSwMap.insert(entry);
384  if (ret.second == false)
385  {
386  NS_LOG_ERROR("This switch is already registered with this controller.");
387  }
388 
389  // Execute any pending command for this OpenFlow datapath ID.
390  auto it = m_commandsMap.find(swtch->m_dpId);
391  if (it != m_commandsMap.end())
392  {
393  Ptr<PendingCommands> pendCommands = it->second;
394  while (!pendCommands->m_queue.empty())
395  {
396  DpctlExecute(swtch->m_dpId, pendCommands->m_queue.front());
397  pendCommands->m_queue.pop();
398  }
399  m_commandsMap.erase(swtch->m_dpId);
400  }
401 
402  // Notify listeners that the handshake procedure is concluded.
403  HandshakeSuccessful(swtch);
404  return 0;
405 }
406 
407 ofl_err
408 OFSwitch13Controller::HandlePacketIn(struct ofl_msg_packet_in* msg,
410  uint32_t xid)
411 {
412  NS_LOG_FUNCTION(this << swtch << xid);
413 
414  ofl_msg_free((struct ofl_msg_header*)msg, nullptr);
415  return 0;
416 }
417 
418 ofl_err
419 OFSwitch13Controller::HandleError(struct ofl_msg_error* msg,
421  uint32_t xid)
422 {
423  NS_LOG_FUNCTION(this << swtch << xid);
424 
425  char* msgStr = ofl_msg_to_string((struct ofl_msg_header*)msg, nullptr);
426  NS_LOG_ERROR("OpenFlow error: " << msgStr);
427  free(msgStr);
428 
429  ofl_msg_free((struct ofl_msg_header*)msg, nullptr);
430  return 0;
431 }
432 
433 ofl_err
434 OFSwitch13Controller::HandleGetConfigReply(struct ofl_msg_get_config_reply* msg,
436  uint32_t xid)
437 {
438  NS_LOG_FUNCTION(this << swtch << xid);
439 
440  ofl_msg_free((struct ofl_msg_header*)msg, nullptr);
441  return 0;
442 }
443 
444 ofl_err
445 OFSwitch13Controller::HandleFlowRemoved(struct ofl_msg_flow_removed* msg,
447  uint32_t xid)
448 {
449  NS_LOG_FUNCTION(this << swtch << xid);
450 
451  ofl_msg_free_flow_removed(msg, true, nullptr);
452  return 0;
453 }
454 
455 ofl_err
456 OFSwitch13Controller::HandlePortStatus(struct ofl_msg_port_status* msg,
458  uint32_t xid)
459 {
460  NS_LOG_FUNCTION(this << swtch << xid);
461 
462  ofl_msg_free((struct ofl_msg_header*)msg, nullptr);
463  return 0;
464 }
465 
466 ofl_err
467 OFSwitch13Controller::HandleAsyncReply(struct ofl_msg_async_config* msg,
469  uint32_t xid)
470 {
471  NS_LOG_FUNCTION(this << swtch << xid);
472 
473  ofl_msg_free((struct ofl_msg_header*)msg, nullptr);
474  return 0;
475 }
476 
477 ofl_err
479  struct ofl_msg_multipart_reply_header* msg,
481  uint32_t xid)
482 {
483  NS_LOG_FUNCTION(this << swtch << xid);
484 
485  ofl_msg_free((struct ofl_msg_header*)msg, nullptr);
486  return 0;
487 }
488 
489 ofl_err
490 OFSwitch13Controller::HandleRoleReply(struct ofl_msg_role_request* msg,
492  uint32_t xid)
493 {
494  NS_LOG_FUNCTION(this << swtch << xid);
495 
496  ofl_msg_free((struct ofl_msg_header*)msg, nullptr);
497  return 0;
498 }
499 
500 ofl_err
502  struct ofl_msg_queue_get_config_reply* msg,
504  uint32_t xid)
505 {
506  NS_LOG_FUNCTION(this << swtch << xid);
507 
508  ofl_msg_free((struct ofl_msg_header*)msg, nullptr);
509  return 0;
510 }
511 
512 // --- END: Handlers functions -------
513 
514 /********** Private methods **********/
515 ofl_err
516 OFSwitch13Controller::HandleSwitchMsg(struct ofl_msg_header* msg,
517  Ptr<RemoteSwitch> swtch,
518  uint32_t xid)
519 {
520  NS_LOG_FUNCTION(this << swtch << xid);
521 
522  // Dispatches control messages to appropriate handler functions.
523  switch (msg->type)
524  {
525  case OFPT_HELLO:
526  return HandleHello(msg, swtch, xid);
527 
528  case OFPT_BARRIER_REPLY:
529  return HandleBarrierReply(msg, swtch, xid);
530 
531  case OFPT_PACKET_IN:
532  return HandlePacketIn((struct ofl_msg_packet_in*)msg, swtch, xid);
533 
534  case OFPT_ECHO_REQUEST:
535  return HandleEchoRequest((struct ofl_msg_echo*)msg, swtch, xid);
536 
537  case OFPT_ECHO_REPLY:
538  return HandleEchoReply((struct ofl_msg_echo*)msg, swtch, xid);
539 
540  case OFPT_ERROR:
541  return HandleError((struct ofl_msg_error*)msg, swtch, xid);
542 
543  case OFPT_FEATURES_REPLY:
544  return HandleFeaturesReply((struct ofl_msg_features_reply*)msg,
545  swtch,
546  xid);
547 
548  case OFPT_GET_CONFIG_REPLY:
549  return HandleGetConfigReply((struct ofl_msg_get_config_reply*)msg,
550  swtch,
551  xid);
552 
553  case OFPT_FLOW_REMOVED:
554  return HandleFlowRemoved((struct ofl_msg_flow_removed*)msg, swtch, xid);
555 
556  case OFPT_PORT_STATUS:
557  return HandlePortStatus((struct ofl_msg_port_status*)msg, swtch, xid);
558 
559  case OFPT_GET_ASYNC_REPLY:
560  return HandleAsyncReply((struct ofl_msg_async_config*)msg, swtch, xid);
561 
562  case OFPT_MULTIPART_REPLY:
563  return HandleMultipartReply((struct ofl_msg_multipart_reply_header*)msg,
564  swtch,
565  xid);
566 
567  case OFPT_ROLE_REPLY:
568  return HandleRoleReply((struct ofl_msg_role_request*)msg, swtch, xid);
569 
570  case OFPT_QUEUE_GET_CONFIG_REPLY:
572  (struct ofl_msg_queue_get_config_reply*)msg,
573  swtch,
574  xid);
575 
576  case OFPT_EXPERIMENTER:
577  default:
578  return ofl_error(OFPET_BAD_REQUEST, OFPGMFC_BAD_TYPE);
579  }
580 }
581 
582 void
584 {
585  NS_LOG_FUNCTION(this << packet);
586 
587  uint32_t xid;
588  struct ofl_msg_header* msg;
589  ofl_err error;
590 
591  // Get the openflow buffer, unpack the message and send to message handler
592  struct ofpbuf* buffer = BufferFromPacket(packet, packet->GetSize());
593  error = ofl_msg_unpack((uint8_t*)buffer->data,
594  buffer->size,
595  &msg,
596  &xid,
597  nullptr);
598 
599  if (!error)
600  {
601  Ptr<RemoteSwitch> swtch = GetRemoteSwitch(from);
602  char* msgStr = ofl_msg_to_string(msg, nullptr);
603  NS_LOG_DEBUG("RX from switch " << swtch->GetIpv4() << " [dp "
604  << swtch->GetDpId() << "]: " << msgStr);
605  free(msgStr);
606 
607  error = HandleSwitchMsg(msg, swtch, xid);
608  if (error)
609  {
610  // NOTE: It is assumed that if a handler returns with error, it did
611  // not use any part of the control message, thus it can be freed up.
612  // If no error is returned however, the message must be freed inside
613  // the handler (because the handler might keep parts of the message)
614  ofl_msg_free(msg, nullptr);
615  }
616  }
617  if (error)
618  {
619  NS_LOG_ERROR("Error processing OpenFlow message from switch.");
620  }
621  ofpbuf_delete(buffer);
622 }
623 
626 {
627  NS_LOG_FUNCTION(this << address);
628 
629  auto it = m_addrSwMap.find(address);
630  if (it != m_addrSwMap.end())
631  {
632  return it->second;
633  }
634  NS_ABORT_MSG("Couldn't find the remote switch for this address.");
635 }
636 
637 bool
639 {
640  NS_LOG_FUNCTION(this << socket << from);
641 
643  "Invalid address type (only IPv4 supported by now).");
645  uint16_t port = InetSocketAddress::ConvertFrom(from).GetPort();
646  NS_LOG_INFO("Switch request connection from " << ipAddr << ":" << port);
647 
648  return true;
649 }
650 
651 void
653 {
654  NS_LOG_FUNCTION(this << socket << from);
655 
657  uint16_t port = InetSocketAddress::ConvertFrom(from).GetPort();
658  NS_LOG_INFO("Switch connection accepted from " << ipAddr << ":" << port);
659 
660  // This is a new switch connection to this controller.
661  // Let's create the remote switch metadata and save it.
662  Ptr<RemoteSwitch> swtch = Create<RemoteSwitch>();
663  swtch->m_address = from;
664  swtch->m_ctrlApp = Ptr<OFSwitch13Controller>(this);
665 
666  // As we have more than one socket that is used for communication between
667  // this OpenFlow controller and switches, we need to handle the process of
668  // sending/receiving OpenFlow messages to/from sockets in an independent
669  // way. So, each socket has its own socket handler to this end.
670  swtch->m_handler = CreateObject<OFSwitch13SocketHandler>(socket);
671  swtch->m_handler->SetReceiveCallback(
673 
674  std::pair<Address, Ptr<RemoteSwitch>> entry(swtch->m_address, swtch);
675  auto ret = m_addrSwMap.insert(entry);
676  if (ret.second == false)
677  {
678  NS_LOG_ERROR("This switch is already registered with this controller.");
679  }
680 
681  // Let's send the hello message to the switch and wait for the hello message
682  // from the switch to proceed with the handshake procedure.
683  struct ofl_msg_header hello;
684  hello.type = OFPT_HELLO;
685  SendToSwitch(swtch, &hello);
686 }
687 
688 void
690 {
691  NS_LOG_FUNCTION(this << socket);
692 
693  NS_LOG_DEBUG("Connection successfully closed.");
694  socket->ShutdownSend();
695  socket->ShutdownRecv();
696 }
697 
698 void
700 {
701  NS_LOG_FUNCTION(this << socket);
702 
703  NS_LOG_ERROR("Socket peer error " << socket);
704  socket->ShutdownSend();
705  socket->ShutdownRecv();
706 }
707 
709  : m_handler(nullptr),
710  m_ctrlApp(nullptr),
711  m_dpId(0),
712  m_role(OFPCR_ROLE_EQUAL)
713 {
714  m_address = Address();
715 }
716 
719 {
720  return InetSocketAddress::ConvertFrom(m_address).GetIpv4();
721 }
722 
723 uint16_t
725 {
726  return InetSocketAddress::ConvertFrom(m_address).GetPort();
727 }
728 
729 uint64_t
731 {
732  return m_dpId;
733 }
734 
736  : m_waiting(true),
737  m_send(Simulator::Now()),
738  m_swtch(swtch)
739 {
740 }
741 
742 Time
744 {
745  if (m_waiting)
746  {
747  return Time(-1);
748  }
749  else
750  {
751  return m_recv - m_send;
752  }
753 }
754 
756  : m_waiting(true),
757  m_swtch(swtch)
758 {
759 }
760 
762 {
763 }
764 
765 } // namespace ns3
a polymophic address class
Definition: address.h:100
void DoDispose() override
Destructor implementation.
Definition: application.cc:85
Ptr< Node > GetNode() const
Definition: application.cc:107
an Inet address class
static bool IsMatchingType(const Address &address)
Ipv4Address GetIpv4() const
static InetSocketAddress ConvertFrom(const Address &address)
Returns an InetSocketAddress which corresponds to the input Address.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:43
static Ipv4Address GetAny()
std::queue< std::string > m_queue
Queue of pending dpctl commands.
Inner class to save information of a remote active OpenFlow switch connected to this controller.
uint32_t m_capabilities
Bitmap of support ofp_capabilities.
RemoteSwitch()
Default (empty) constructor.
Ipv4Address GetIpv4() const
Get the IP from socket connection address.
Ptr< OFSwitch13Controller > m_ctrlApp
Controller application.
uint8_t m_auxiliaryId
Identify auxiliary connections.
Address m_address
Switch connection address.
Ptr< OFSwitch13SocketHandler > m_handler
Socket handler.
uint16_t GetPort() const
Get the port from socket connection address.
uint32_t m_nBuffers
Switch features informed to the controller during handshake procedure.
uint64_t GetDpId() const
Get the datapath ID.
uint8_t m_nTables
Number of tables supported by datapath.
void StopApplication() override
Application specific shutdown code.
OFSwitch13Controller()
Default constructor.
ofl_err HandleEchoRequest(struct ofl_msg_echo *msg, Ptr< const RemoteSwitch > swtch, uint32_t xid)
Called when an OpenFlow message is received from a switch.
ofl_err HandleEchoReply(struct ofl_msg_echo *msg, Ptr< const RemoteSwitch > swtch, uint32_t xid)
Called when an OpenFlow message is received from a switch.
virtual ofl_err HandlePortStatus(struct ofl_msg_port_status *msg, Ptr< const RemoteSwitch > swtch, uint32_t xid)
Called when an OpenFlow message is received from a switch.
virtual void HandshakeSuccessful(Ptr< const RemoteSwitch > swtch)
Function invoked after a successfully handshake procedure between this controller and a remote switch...
virtual ofl_err HandlePacketIn(struct ofl_msg_packet_in *msg, Ptr< const RemoteSwitch > swtch, uint32_t xid)
Called when an OpenFlow message is received from a switch.
void SocketPeerError(Ptr< Socket > socket)
TCP connection error.
AddrSwMap_t m_addrSwMap
Registered switches by address.
void SocketAccept(Ptr< Socket > socket, const Address &from)
TCP handshake succeeded.
virtual ofl_err HandleGetConfigReply(struct ofl_msg_get_config_reply *msg, Ptr< const RemoteSwitch > swtch, uint32_t xid)
Called when an OpenFlow message is received from a switch.
virtual ofl_err HandleMultipartReply(struct ofl_msg_multipart_reply_header *msg, Ptr< const RemoteSwitch > swtch, uint32_t xid)
Called when an OpenFlow message is received from a switch.
void StartApplication() override
Application specific startup code.
static void DpctlSendAndPrint(struct vconn *vconn, struct ofl_msg_header *msg)
Overriding BOFUSS dpctl_send_and_print and dpctl_transact_and_print weak functions from utilities/dpc...
void SocketPeerClose(Ptr< Socket > socket)
TCP connection closed.
uint32_t m_xid
Global transaction idx.
~OFSwitch13Controller() override
Dummy destructor, see DoDispose.
void ReceiveFromSwitch(Ptr< Packet > packet, Address from)
Receive an OpenFlow packet from switch.
void SendEchoRequest(Ptr< const RemoteSwitch > swtch, size_t payloadSize=0)
Send an echo request message to switch, and wait for a non-blocking reply.
virtual ofl_err HandleFlowRemoved(struct ofl_msg_flow_removed *msg, Ptr< const RemoteSwitch > swtch, uint32_t xid)
Called when an OpenFlow message is received from a switch.
ofl_err HandleHello(struct ofl_msg_header *msg, Ptr< const RemoteSwitch > swtch, uint32_t xid)
Called when an OpenFlow message is received from a switch.
Ptr< Socket > m_serverSocket
Listening server socket.
ofl_err HandleBarrierReply(struct ofl_msg_header *msg, Ptr< const RemoteSwitch > swtch, uint32_t xid)
Called when an OpenFlow message is received from a switch.
bool SocketRequest(Ptr< Socket > socket, const Address &from)
TCP request from switch.
uint16_t m_port
Local controller tcp port.
virtual ofl_err HandleQueueGetConfigReply(struct ofl_msg_queue_get_config_reply *msg, Ptr< const RemoteSwitch > swtch, uint32_t xid)
Called when an OpenFlow message is received from a switch.
ofl_err HandleSwitchMsg(struct ofl_msg_header *msg, Ptr< RemoteSwitch > swtch, uint32_t xid)
Called when an OpenFlow message is received from a switch.
ofl_err HandleFeaturesReply(struct ofl_msg_features_reply *msg, Ptr< RemoteSwitch > swtch, uint32_t xid)
Called when an OpenFlow message is received from a switch.
static TypeId GetTypeId()
Register this type.
int SendToSwitch(Ptr< const RemoteSwitch > swtch, struct ofl_msg_header *msg, uint32_t xid=0)
Send a OFLib message to a registered switch.
void SendBarrierRequest(Ptr< const RemoteSwitch > swtch)
Send a barrier request message to switch, and wait for a non-blocking reply.
EchoMsgMap_t m_echoMap
Metadata for echo requests.
virtual ofl_err HandleError(struct ofl_msg_error *msg, Ptr< const RemoteSwitch > swtch, uint32_t xid)
Called when an OpenFlow message is received from a switch.
Ptr< const RemoteSwitch > GetRemoteSwitch(uint64_t dpId) const
Get the remote switch for this OpenFlow datapath ID.
BarrierMsgMap_t m_barrierMap
Metadata for barrier requests.
DpIdCmdMap_t m_commandsMap
Commands scheduled for execution.
virtual ofl_err HandleAsyncReply(struct ofl_msg_async_config *msg, Ptr< const RemoteSwitch > swtch, uint32_t xid)
Called when an OpenFlow message is received from a switch.
virtual ofl_err HandleRoleReply(struct ofl_msg_role_request *msg, Ptr< const RemoteSwitch > swtch, uint32_t xid)
Called when an OpenFlow message is received from a switch.
int DpctlExecute(uint64_t dpId, const std::string textCmd)
Execute a dpctl command to interact with the remote switch.
void DoDispose() override
Destructor implementation.
DpIdSwMap_t m_dpIdSwMap
Registered switches by datapath id.
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:200
A base class which provides memory management and object aggregation.
Definition: object.h:89
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:863
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
Control the scheduling of simulation events.
Definition: simulator.h:68
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:199
void SetCloseCallbacks(Callback< void, Ptr< Socket >> normalClose, Callback< void, Ptr< Socket >> errorClose)
Detect socket recv() events such as graceful shutdown or error.
Definition: socket.cc:94
void SetAcceptCallback(Callback< bool, Ptr< Socket >, const Address & > connectionRequest, Callback< void, Ptr< Socket >, const Address & > newConnectionCreated)
Accept connection requests from remote hosts.
Definition: socket.cc:103
void SetRecvCallback(Callback< void, Ptr< Socket >> receivedData)
Notify application when new data is available to be read.
Definition: socket.cc:126
virtual int ShutdownRecv()=0
virtual int ShutdownSend()=0
static Ptr< Socket > CreateSocket(Ptr< Node > node, TypeId tid)
This method wraps the creation of sockets that is performed on a given node by a SocketFactory specif...
Definition: socket.cc:72
virtual int Close()=0
Close a socket.
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
virtual int Listen()=0
Listen for incoming connections.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
@ MS
millisecond
Definition: nstime.h:117
a unique identifier for an interface.
Definition: type-id.h:60
static TypeId LookupByName(std::string name)
Get a TypeId by name.
Definition: type-id.cc:839
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
Hold an unsigned integer type.
Definition: uinteger.h:45
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
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
Callback< R, Args... > MakeNullCallback()
Definition: callback.h:750
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:49
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:254
#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_NOARGS()
Output the name of the function.
#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_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Ptr< Packet > PacketFromMsg(struct ofl_msg_header *msg, uint32_t xid)
Create a new ns3::Packet from internal OFLib message.
struct ofpbuf * BufferFromPacket(Ptr< const Packet > packet, size_t bodyRoom, size_t headRoom)
Create an internal BOFUSS buffer from ns3::Packet.
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:296
address
Definition: first.py:40
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
Definition: nstime.h:848
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:707
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:488
cmd
Definition: second.py:33
Structure to save barrier metadata used by the controller interface.
BarrierInfo(Ptr< const RemoteSwitch > swtch)
Complete constructor, with remote switch.
Structure to save echo request metadata used by the controller interface.
Time GetRtt() const
Compute the echo RTT time.
EchoInfo(Ptr< const RemoteSwitch > swtch)
Complete constructor, with remote switch.