A Discrete-Event Network Simulator
API
openflow-interface.h
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License version 2 as
4  * published by the Free Software Foundation;
5  *
6  * This program is distributed in the hope that it will be useful,
7  * but WITHOUT ANY WARRANTY; without even the implied warranty of
8  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9  * GNU General Public License for more details.
10  *
11  * You should have received a copy of the GNU General Public License
12  * along with this program; if not, write to the Free Software
13  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14  *
15  * Author: Blake Hurd <naimorai@gmail.com>
16  */
17 #ifndef OPENFLOW_INTERFACE_H
18 #define OPENFLOW_INTERFACE_H
19 
20 #include <assert.h>
21 #include <errno.h>
22 
23 // Include OFSI code
24 #include "ns3/address.h"
25 #include "ns3/log.h"
26 #include "ns3/mac48-address.h"
27 #include "ns3/net-device.h"
28 #include "ns3/nstime.h"
29 #include "ns3/packet.h"
30 #include "ns3/simulator.h"
31 
32 #include <limits>
33 #include <map>
34 #include <set>
35 
36 // Include main header and Vendor Extension files
37 #include "openflow/ericsson-ext.h"
38 #include "openflow/nicira-ext.h"
39 #include "openflow/openflow.h"
40 
41 extern "C"
42 {
43 // Inexplicably, the OpenFlow implementation uses these two reserved words as member names.
44 #define private _private
45 #define delete _delete
46 #define list List
47 
48 // Include OFSI Library files
49 #include "openflow/private/csum.h"
50 #include "openflow/private/poll-loop.h"
51 #include "openflow/private/rconn.h"
52 #include "openflow/private/stp.h"
53 #include "openflow/private/vconn.h"
54 #include "openflow/private/xtoxll.h"
55 
56 // Include OFSI Switch files
57 #include "openflow/private/chain.h"
58 #include "openflow/private/datapath.h" // The functions below are defined in datapath.c
59 #include "openflow/private/table.h"
60  uint32_t save_buffer(ofpbuf*);
61  ofpbuf* retrieve_buffer(uint32_t id);
62  void discard_buffer(uint32_t id);
63 #include "openflow/private/dp_act.h" // The functions below are defined in dp_act.c
64  void set_vlan_vid(ofpbuf* buffer, sw_flow_key* key, const ofp_action_header* ah);
65  void set_vlan_pcp(ofpbuf* buffer, sw_flow_key* key, const ofp_action_header* ah);
66  void strip_vlan(ofpbuf* buffer, sw_flow_key* key, const ofp_action_header* ah);
67  void set_dl_addr(ofpbuf* buffer, sw_flow_key* key, const ofp_action_header* ah);
68  void set_nw_addr(ofpbuf* buffer, sw_flow_key* key, const ofp_action_header* ah);
69  void set_tp_port(ofpbuf* buffer, sw_flow_key* key, const ofp_action_header* ah);
70  void set_mpls_label(ofpbuf* buffer, sw_flow_key* key, const ofp_action_header* ah);
71  void set_mpls_exp(ofpbuf* buffer, sw_flow_key* key, const ofp_action_header* ah);
72 #include "openflow/private/pt_act.h"
73 
74 #undef list
75 #undef private
76 #undef delete
77 }
78 
79 // Capabilities supported by this implementation.
80 #ifndef OFP_SUPPORTED_CAPABILITIES
81 #define OFP_SUPPORTED_CAPABILITIES \
82  (OFPC_FLOW_STATS | OFPC_TABLE_STATS | OFPC_PORT_STATS | OFPC_MULTI_PHY_TX | OFPC_VPORT_TABLE)
83 #endif
84 
85 // Actions supported by this implementation.
86 #ifndef OFP_SUPPORTED_ACTIONS
87 #define OFP_SUPPORTED_ACTIONS \
88  ((1 << OFPAT_OUTPUT) | (1 << OFPAT_SET_VLAN_VID) | (1 << OFPAT_SET_VLAN_PCP) | \
89  (1 << OFPAT_STRIP_VLAN) | (1 << OFPAT_SET_DL_SRC) | (1 << OFPAT_SET_DL_DST) | \
90  (1 << OFPAT_SET_NW_SRC) | (1 << OFPAT_SET_NW_DST) | (1 << OFPAT_SET_TP_SRC) | \
91  (1 << OFPAT_SET_TP_DST) | (1 << OFPAT_SET_MPLS_LABEL) | (1 << OFPAT_SET_MPLS_EXP))
92 #endif
93 
94 #ifndef OFP_SUPPORTED_VPORT_TABLE_ACTIONS
95 #define OFP_SUPPORTED_VPORT_TABLE_ACTIONS \
96  ((1 << OFPPAT_OUTPUT) | (1 << OFPPAT_POP_MPLS) | (1 << OFPPAT_PUSH_MPLS) | \
97  (1 << OFPPAT_SET_MPLS_LABEL) | (1 << OFPPAT_SET_MPLS_EXP))
98 #endif
99 
100 namespace ns3
101 {
102 
103 class OpenFlowSwitchNetDevice;
104 
105 namespace ofi
106 {
107 
117 struct Port
118 {
120  : config(0),
121  state(0),
122  netdev(nullptr),
123  rx_packets(0),
124  tx_packets(0),
125  rx_bytes(0),
126  tx_bytes(0),
127  tx_dropped(0),
129  {
130  }
131 
132  uint32_t config;
133  uint32_t state;
135  unsigned long long int rx_packets;
136  unsigned long long int tx_packets;
137  unsigned long long int rx_bytes;
138  unsigned long long int tx_bytes;
139  unsigned long long int tx_dropped;
140  unsigned long long int mpls_ttl0_dropped;
141 };
142 
147 class Stats
148 {
149  public:
155  Stats(ofp_stats_types _type, size_t body_len);
156 
165  int DoInit(const void* body, int body_len, void** state);
166 
176  int DoDump(Ptr<OpenFlowSwitchNetDevice> swtch, void* state, ofpbuf* buffer);
177 
185  void DoCleanup(void* state);
186 
191  {
192  int table_idx;
193  sw_table_position position;
194  ofp_flow_stats_request rq;
195  time_t now;
196 
197  ofpbuf* buffer;
198  };
199 
205  {
206  uint32_t num_ports;
207  uint32_t* ports;
208  };
209 
210  ofp_stats_types type;
211  private:
218  int DescStatsDump(void* state, ofpbuf* buffer);
219 
228  int FlowStatsInit(const void* body, int body_len, void** state);
229  int AggregateStatsInit(const void* body, int body_len, void** state);
230  int PortStatsInit(const void* body, int body_len, void** state);
234  int (*FlowDumpCallback)(sw_flow* flow, void* state);
236  int (*AggregateDumpCallback)(sw_flow* flow, void* state);
237 
246  int FlowStatsDump(Ptr<OpenFlowSwitchNetDevice> dp, FlowStatsState* state, ofpbuf* buffer);
248  ofp_aggregate_stats_request* state,
249  ofpbuf* buffer);
250  int TableStatsDump(Ptr<OpenFlowSwitchNetDevice> dp, void* state, ofpbuf* buffer);
251  int PortStatsDump(Ptr<OpenFlowSwitchNetDevice> dp, PortStatsState* state, ofpbuf* buffer);
252  int PortTableStatsDump(Ptr<OpenFlowSwitchNetDevice> dp, void* state, ofpbuf* buffer);
254 };
255 
260 struct Action
261 {
266  static bool IsValidType(ofp_action_type type);
267 
277  static uint16_t Validate(ofp_action_type type,
278  size_t len,
279  const sw_flow_key* key,
280  const ofp_action_header* ah);
281 
290  static void Execute(ofp_action_type type,
291  ofpbuf* buffer,
292  sw_flow_key* key,
293  const ofp_action_header* ah);
294 };
295 
301 {
306  static bool IsValidType(ofp_vport_action_type type);
307 
316  static uint16_t Validate(ofp_vport_action_type type, size_t len, const ofp_action_header* ah);
317 
326  static void Execute(ofp_vport_action_type type,
327  ofpbuf* buffer,
328  const sw_flow_key* key,
329  const ofp_action_header* ah);
330 };
331 
337 {
342  static bool IsValidType(er_action_type type);
343 
351  static uint16_t Validate(er_action_type type, size_t len);
352 
361  static void Execute(er_action_type type,
362  ofpbuf* buffer,
363  const sw_flow_key* key,
364  const er_action_header* ah);
365 };
366 
372 {
373  bool done;
374  ofp_stats_request* rq;
375  Stats* s;
376  void* state;
378 };
379 
385 {
387  ofpbuf* buffer;
388  uint16_t protocolNumber;
391 };
392 
399 class Controller : public Object
400 {
401  public:
406  static TypeId GetTypeId();
408  ~Controller() override;
409 
416 
424  {
425  }
426 
445  void StartDump(StatsDumpCallback* cb);
446 
447  protected:
456  virtual void SendToSwitch(Ptr<OpenFlowSwitchNetDevice> swtch, void* msg, size_t length);
457 
474  ofp_flow_mod* BuildFlow(sw_flow_key key,
475  uint32_t buffer_id,
476  uint16_t command,
477  void* acts,
478  size_t actions_len,
479  int idle_timeout,
480  int hard_timeout);
481 
489  uint8_t GetPacketType(ofpbuf* buffer);
490 
492  typedef std::set<Ptr<OpenFlowSwitchNetDevice>> Switches_t;
494 };
495 
503 {
504  public:
509  static TypeId GetTypeId();
510 
511  void ReceiveFromSwitch(Ptr<OpenFlowSwitchNetDevice> swtch, ofpbuf* buffer) override;
512 };
513 
523 {
524  public:
529  static TypeId GetTypeId();
530 
532  {
533  m_learnState.clear();
534  }
535 
536  void ReceiveFromSwitch(Ptr<OpenFlowSwitchNetDevice> swtch, ofpbuf* buffer) override;
537 
538  protected:
541  {
542  uint32_t port;
543  };
544 
547  typedef std::map<Mac48Address, LearnedState> LearnState_t;
549 };
550 
564  uint64_t packet_uid,
565  ofpbuf* buffer,
566  sw_flow_key* key,
567  const ofp_action_header* actions,
568  size_t actions_len,
569  int ignore_no_fwd);
570 
580 uint16_t ValidateActions(const sw_flow_key* key,
581  const ofp_action_header* actions,
582  size_t actions_len);
583 
595  uint64_t packet_uid,
596  ofpbuf* buffer,
597  sw_flow_key* key,
598  const ofp_action_header* actions,
599  size_t actions_len);
600 
609 uint16_t ValidateVPortActions(const ofp_action_header* actions, size_t actions_len);
610 
618 void ExecuteVendor(ofpbuf* buffer, const sw_flow_key* key, const ofp_action_header* ah);
619 
629 uint16_t ValidateVendor(const sw_flow_key* key, const ofp_action_header* ah, uint16_t len);
630 
631 /*
632  * From datapath.c
633  * Buffers are identified to userspace by a 31-bit opaque ID. We divide the ID
634  * into a buffer number (low bits) and a cookie (high bits). The buffer number
635  * is an index into an array of buffers. The cookie distinguishes between
636  * different packets that have occupied a single buffer. Thus, the more
637  * buffers we have, the lower-quality the cookie...
638  */
639 #define PKT_BUFFER_BITS 8
640 #define N_PKT_BUFFERS (1 << PKT_BUFFER_BITS)
641 #define PKT_BUFFER_MASK (N_PKT_BUFFERS - 1)
642 #define PKT_COOKIE_BITS (32 - PKT_BUFFER_BITS)
643 
644 } // namespace ofi
645 
646 } // namespace ns3
647 
648 #endif /* OPENFLOW_INTERFACE_H */
NS_ASSERT() and NS_ASSERT_MSG() macro definitions.
a polymophic address class
Definition: address.h:101
A base class which provides memory management and object aggregation.
Definition: object.h:89
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
a unique identifier for an interface.
Definition: type-id.h:59
An interface for a Controller of OpenFlowSwitchNetDevices.
virtual void SendToSwitch(Ptr< OpenFlowSwitchNetDevice > swtch, void *msg, size_t length)
However the controller is implemented, this method is to be used to pass a message on to a switch.
uint8_t GetPacketType(ofpbuf *buffer)
Get the packet type on the buffer, which can then be used to determine how to handle the buffer.
Switches_t m_switches
The collection of switches registered to this controller.
~Controller() override
Destructor.
virtual void ReceiveFromSwitch(Ptr< OpenFlowSwitchNetDevice > swtch, ofpbuf *buffer)
A switch calls this method to pass a message on to the Controller.
static TypeId GetTypeId()
Register this type.
ofp_flow_mod * BuildFlow(sw_flow_key key, uint32_t buffer_id, uint16_t command, void *acts, size_t actions_len, int idle_timeout, int hard_timeout)
Construct flow data from a matching key to build a flow entry for adding, modifying,...
std::set< Ptr< OpenFlowSwitchNetDevice > > Switches_t
OpenFlowSwitchNetDevice container type.
void StartDump(StatsDumpCallback *cb)
Starts a callback-based, reliable, possibly multi-message reply to a request made by the controller.
virtual void AddSwitch(Ptr< OpenFlowSwitchNetDevice > swtch)
Adds a switch to the controller.
Demonstration of a Drop controller.
void ReceiveFromSwitch(Ptr< OpenFlowSwitchNetDevice > swtch, ofpbuf *buffer) override
A switch calls this method to pass a message on to the Controller.
static TypeId GetTypeId()
Register this type.
Demonstration of a Learning controller.
static TypeId GetTypeId()
Register this type.
std::map< Mac48Address, LearnedState > LearnState_t
Learned state type.
void ReceiveFromSwitch(Ptr< OpenFlowSwitchNetDevice > swtch, ofpbuf *buffer) override
A switch calls this method to pass a message on to the Controller.
Time m_expirationTime
Time it takes for learned MAC state entry/created flow to expire.
LearnState_t m_learnState
Learned state data.
OpenFlow statistics.
int PortStatsInit(const void *body, int body_len, void **state)
Initialize the stats.
int PortTableStatsDump(Ptr< OpenFlowSwitchNetDevice > dp, void *state, ofpbuf *buffer)
Dump the stats.
int FlowStatsDump(Ptr< OpenFlowSwitchNetDevice > dp, FlowStatsState *state, ofpbuf *buffer)
Dump the stats.
int(* AggregateDumpCallback)(sw_flow *flow, void *state)
Aggregate dump callback functor.
Stats(ofp_stats_types _type, size_t body_len)
Constructor.
void DoCleanup(void *state)
Cleans any state created by the init or dump functions.
int AggregateStatsInit(const void *body, int body_len, void **state)
Initialize the stats.
int DoDump(Ptr< OpenFlowSwitchNetDevice > swtch, void *state, ofpbuf *buffer)
Appends statistics for OpenFlowSwitchNetDevice to 'buffer'.
int DoInit(const void *body, int body_len, void **state)
Prepares to dump some kind of statistics on the connected OpenFlowSwitchNetDevice.
int AggregateStatsDump(Ptr< OpenFlowSwitchNetDevice > dp, ofp_aggregate_stats_request *state, ofpbuf *buffer)
Dump the stats.
int TableStatsDump(Ptr< OpenFlowSwitchNetDevice > dp, void *state, ofpbuf *buffer)
Dump the stats.
int PortStatsDump(Ptr< OpenFlowSwitchNetDevice > dp, PortStatsState *state, ofpbuf *buffer)
Dump the stats.
ofp_stats_types type
Status type.
int FlowStatsInit(const void *body, int body_len, void **state)
Initialize the stats.
int DescStatsDump(void *state, ofpbuf *buffer)
Dumps the stats description.
int(* FlowDumpCallback)(sw_flow *flow, void *state)
Flow dump callback functor.
void ExecuteVPortActions(Ptr< OpenFlowSwitchNetDevice > swtch, uint64_t packet_uid, ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *actions, size_t actions_len)
Executes a list of virtual port table entry actions.
void ExecuteActions(Ptr< OpenFlowSwitchNetDevice > swtch, uint64_t packet_uid, ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *actions, size_t actions_len, int ignore_no_fwd)
Executes a list of flow table actions.
uint16_t ValidateVendor(const sw_flow_key *key, const ofp_action_header *ah, uint16_t len)
Validates a vendor-defined action.
void ExecuteVendor(ofpbuf *buffer, const sw_flow_key *key, const ofp_action_header *ah)
Executes a vendor-defined action.
uint16_t ValidateActions(const sw_flow_key *key, const ofp_action_header *actions, size_t actions_len)
Validates a list of flow table actions.
uint16_t ValidateVPortActions(const ofp_action_header *actions, size_t actions_len)
Validates a list of virtual port table entry actions.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void discard_buffer(uint32_t id)
ofpbuf * retrieve_buffer(uint32_t id)
void strip_vlan(ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah)
void set_mpls_label(ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah)
void set_dl_addr(ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah)
uint32_t save_buffer(ofpbuf *)
void set_nw_addr(ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah)
void set_vlan_pcp(ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah)
void set_tp_port(ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah)
void set_mpls_exp(ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah)
void set_vlan_vid(ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah)
Class for handling flow table actions.
static bool IsValidType(ofp_action_type type)
static void Execute(ofp_action_type type, ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah)
Executes the action.
static uint16_t Validate(ofp_action_type type, size_t len, const sw_flow_key *key, const ofp_action_header *ah)
Validates the action on whether its data is valid or not.
Class for handling Ericsson Vendor-defined actions.
static bool IsValidType(er_action_type type)
static void Execute(er_action_type type, ofpbuf *buffer, const sw_flow_key *key, const er_action_header *ah)
Executes the action.
static uint16_t Validate(er_action_type type, size_t len)
Validates the action on whether its data is valid or not.
Port and its metadata.
Ptr< NetDevice > netdev
NetDevice pointer.
unsigned long long int mpls_ttl0_dropped
Counter of packets dropped due to MPLS TTL.
unsigned long long int tx_packets
Counter of Tx packets.
unsigned long long int tx_bytes
Counter of Tx bytes.
unsigned long long int rx_packets
Counter of Rx packets.
unsigned long long int rx_bytes
Counter of Rx bytes.
uint32_t config
Some subset of OFPPC_* flags.
unsigned long long int tx_dropped
Counter of Tx dropped packets.
uint32_t state
Some subset of OFPPS_* flags.
State of the FlowStats request/reply.
ofp_flow_stats_request rq
Stats requests.
sw_table_position position
Table position.
State of the PortStats request/reply.
uint32_t * ports
Array of ports in network byte order.
uint32_t num_ports
Number of ports in host byte order.
Callback for a stats dump request.
ofp_stats_request * rq
Current stats request.
Stats * s
Handler of the stats request.
void * state
Stats request state data.
Ptr< OpenFlowSwitchNetDevice > swtch
The switch that we're requesting data from.
bool done
Whether we are done requesting stats.
Packet Metadata, allows us to track the packet's metadata as it passes through the switch.
Address src
Source Address of the Packet when the Packet is received.
uint16_t protocolNumber
Protocol type of the Packet when the Packet is received.
Address dst
Destination Address of the Packet when the Packet is received.
ofpbuf * buffer
The OpenFlow buffer as created from the Packet, with its data and headers.
Ptr< Packet > packet
The Packet itself.
Class for handling virtual port table actions.
static uint16_t Validate(ofp_vport_action_type type, size_t len, const ofp_action_header *ah)
Validates the action on whether its data is valid or not.
static void Execute(ofp_vport_action_type type, ofpbuf *buffer, const sw_flow_key *key, const ofp_action_header *ah)
Executes the action.
static bool IsValidType(ofp_vport_action_type type)