A Discrete-Event Network Simulator
API
openflow-interface.h
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License version 2 as
5  * published by the Free Software Foundation;
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15  *
16  * Author: Blake Hurd <naimorai@gmail.com>
17  */
18 #ifndef OPENFLOW_INTERFACE_H
19 #define OPENFLOW_INTERFACE_H
20 
21 #include <assert.h>
22 #include <errno.h>
23 
24 // Include OFSI code
25 #include "ns3/simulator.h"
26 #include "ns3/log.h"
27 #include "ns3/net-device.h"
28 #include "ns3/packet.h"
29 #include "ns3/address.h"
30 #include "ns3/nstime.h"
31 #include "ns3/mac48-address.h"
32 
33 #include <set>
34 #include <map>
35 #include <limits>
36 
37 // Include main header and Vendor Extension files
38 #include "openflow/openflow.h"
39 #include "openflow/nicira-ext.h"
40 #include "openflow/ericsson-ext.h"
41 
42 extern "C"
43 {
44 // Inexplicably, the OpenFlow implementation uses these two reserved words as member names.
45 #define private _private
46 #define delete _delete
47 #define list List
48 
49 // Include OFSI Library files
50 #include "openflow/private/csum.h"
51 #include "openflow/private/poll-loop.h"
52 #include "openflow/private/rconn.h"
53 #include "openflow/private/stp.h"
54 #include "openflow/private/vconn.h"
55 #include "openflow/private/xtoxll.h"
56 
57 // Include OFSI Switch files
58 #include "openflow/private/chain.h"
59 #include "openflow/private/table.h"
60 #include "openflow/private/datapath.h" // The functions below are defined in datapath.c
61 uint32_t save_buffer (ofpbuf *);
62 ofpbuf * retrieve_buffer (uint32_t id);
63 void discard_buffer (uint32_t id);
64 #include "openflow/private/dp_act.h" // The functions below are defined in dp_act.c
65 void set_vlan_vid (ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah);
66 void set_vlan_pcp (ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah);
67 void strip_vlan (ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah);
68 void set_dl_addr (ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah);
69 void set_nw_addr (ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah);
70 void set_tp_port (ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah);
71 void set_mpls_label (ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah);
72 void set_mpls_exp (ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah);
73 #include "openflow/private/pt_act.h" // The function below is defined in pt_act.c
74 void update_checksums (ofpbuf *buffer, const sw_flow_key *key, uint32_t old_word, uint32_t new_word);
75 
76 #undef list
77 #undef private
78 #undef delete
79 }
80 
81 // Capabilities supported by this implementation.
82 #define OFP_SUPPORTED_CAPABILITIES ( OFPC_FLOW_STATS \
83  | OFPC_TABLE_STATS \
84  | OFPC_PORT_STATS \
85  | OFPC_MULTI_PHY_TX \
86  | OFPC_VPORT_TABLE)
87 
88 // Actions supported by this implementation.
89 #define OFP_SUPPORTED_ACTIONS ( (1 << OFPAT_OUTPUT) \
90  | (1 << OFPAT_SET_VLAN_VID) \
91  | (1 << OFPAT_SET_VLAN_PCP) \
92  | (1 << OFPAT_STRIP_VLAN) \
93  | (1 << OFPAT_SET_DL_SRC) \
94  | (1 << OFPAT_SET_DL_DST) \
95  | (1 << OFPAT_SET_NW_SRC) \
96  | (1 << OFPAT_SET_NW_DST) \
97  | (1 << OFPAT_SET_TP_SRC) \
98  | (1 << OFPAT_SET_TP_DST) \
99  | (1 << OFPAT_SET_MPLS_LABEL) \
100  | (1 << OFPAT_SET_MPLS_EXP) )
101 
102 #define OFP_SUPPORTED_VPORT_TABLE_ACTIONS ( (1 << OFPPAT_OUTPUT) \
103  | (1 << OFPPAT_POP_MPLS) \
104  | (1 << OFPPAT_PUSH_MPLS) \
105  | (1 << OFPPAT_SET_MPLS_LABEL) \
106  | (1 << OFPPAT_SET_MPLS_EXP) ) \
107 
108 namespace ns3 {
109 
110 class OpenFlowSwitchNetDevice;
111 
112 namespace ofi {
113 
122 struct Port
123 {
124  Port () : config (0),
125  state (0),
126  netdev (0),
127  rx_packets (0),
128  tx_packets (0),
129  rx_bytes (0),
130  tx_bytes (0),
131  tx_dropped (0),
133  {
134  }
135 
136  uint32_t config;
137  uint32_t state;
139  unsigned long long int rx_packets, tx_packets;
140  unsigned long long int rx_bytes, tx_bytes;
141  unsigned long long int tx_dropped;
142  unsigned long long int mpls_ttl0_dropped;
143 };
144 
145 class Stats
146 {
147 public:
148  Stats (ofp_stats_types _type, size_t body_len);
149 
158  int DoInit (const void *body, int body_len, void **state);
159 
168  int DoDump (Ptr<OpenFlowSwitchNetDevice> swtch, void *state, ofpbuf *buffer);
169 
177  void DoCleanup (void *state);
178 
183  {
185  sw_table_position position;
186  ofp_flow_stats_request rq;
187  time_t now;
188 
189  ofpbuf *buffer;
190  };
191 
196  {
197  uint32_t num_ports;
198  uint32_t *ports;
199  };
200 
201  ofp_stats_types type;
202 private:
203  int DescStatsDump (void *state, ofpbuf *buffer);
204 
205  int FlowStatsInit (const void *body, int body_len, void **state);
206  int (*FlowDumpCallback)(sw_flow *flow, void *state);
207  int FlowStatsDump (Ptr<OpenFlowSwitchNetDevice> dp, FlowStatsState *s, ofpbuf *buffer);
208 
209  int AggregateStatsInit (const void *body, int body_len, void **state);
210  int (*AggregateDumpCallback)(sw_flow *flow, void *state);
211  int AggregateStatsDump (Ptr<OpenFlowSwitchNetDevice> dp, ofp_aggregate_stats_request *s, ofpbuf *buffer);
212 
213  int TableStatsDump (Ptr<OpenFlowSwitchNetDevice> dp, void *state, ofpbuf *buffer);
214 
215  int PortStatsInit (const void *body, int body_len, void **state);
216  int PortStatsDump (Ptr<OpenFlowSwitchNetDevice> dp, PortStatsState *s, ofpbuf *buffer);
217 
218  int PortTableStatsDump (Ptr<OpenFlowSwitchNetDevice> dp, void *state, ofpbuf *buffer);
219 };
220 
224 struct Action
225 {
230  static bool IsValidType (ofp_action_type type);
231 
241  static uint16_t Validate (ofp_action_type type, size_t len, const sw_flow_key *key, const ofp_action_header *ah);
242 
251  static void Execute (ofp_action_type type, ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah);
252 };
253 
258 {
263  static bool IsValidType (ofp_vport_action_type type);
264 
273  static uint16_t Validate (ofp_vport_action_type type, size_t len, const ofp_action_header *ah);
274 
283  static void Execute (ofp_vport_action_type type, ofpbuf *buffer, const sw_flow_key *key, const ofp_action_header *ah);
284 };
285 
290 {
295  static bool IsValidType (er_action_type type);
296 
304  static uint16_t Validate (er_action_type type, size_t len);
305 
314  static void Execute (er_action_type type, ofpbuf *buffer, const sw_flow_key *key, const er_action_header *ah);
315 };
316 
321 {
322  bool done;
323  ofp_stats_request *rq;
324  Stats *s;
325  void *state;
327 };
328 
333 {
335  ofpbuf* buffer;
336  uint16_t protocolNumber;
339 };
340 
346 class Controller : public Object
347 {
348 public:
353  static TypeId GetTypeId (void);
355  virtual ~Controller ();
356 
362  virtual void AddSwitch (Ptr<OpenFlowSwitchNetDevice> swtch);
363 
370  virtual void ReceiveFromSwitch (Ptr<OpenFlowSwitchNetDevice> swtch, ofpbuf* buffer)
371  {
372  }
373 
391  void StartDump (StatsDumpCallback* cb);
392 
393 protected:
402  virtual void SendToSwitch (Ptr<OpenFlowSwitchNetDevice> swtch, void * msg, size_t length);
403 
417  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);
418 
426  uint8_t GetPacketType (ofpbuf* buffer);
427 
428  typedef std::set<Ptr<OpenFlowSwitchNetDevice> > Switches_t;
429  Switches_t m_switches;
430 };
431 
438 {
439 public:
444  static TypeId GetTypeId (void);
445 
446  void ReceiveFromSwitch (Ptr<OpenFlowSwitchNetDevice> swtch, ofpbuf* buffer);
447 };
448 
457 {
458 public:
463  static TypeId GetTypeId (void);
464 
466  {
467  m_learnState.clear ();
468  }
469 
470  void ReceiveFromSwitch (Ptr<OpenFlowSwitchNetDevice> swtch, ofpbuf* buffer);
471 
472 protected:
474  {
475  uint32_t port;
476  };
478  typedef std::map<Mac48Address, LearnedState> LearnState_t;
479  LearnState_t m_learnState;
480 };
481 
493 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);
494 
503 uint16_t ValidateActions (const sw_flow_key *key, const ofp_action_header *actions, size_t actions_len);
504 
515 void ExecuteVPortActions (Ptr<OpenFlowSwitchNetDevice> swtch, uint64_t packet_uid, ofpbuf* buffer, sw_flow_key *key, const ofp_action_header *actions, size_t actions_len);
516 
524 uint16_t ValidateVPortActions (const ofp_action_header *actions, size_t actions_len);
525 
533 void ExecuteVendor (ofpbuf *buffer, const sw_flow_key *key, const ofp_action_header *ah);
534 
543 uint16_t ValidateVendor (const sw_flow_key *key, const ofp_action_header *ah, uint16_t len);
544 
545 /*
546  * From datapath.c
547  * Buffers are identified to userspace by a 31-bit opaque ID. We divide the ID
548  * into a buffer number (low bits) and a cookie (high bits). The buffer number
549  * is an index into an array of buffers. The cookie distinguishes between
550  * different packets that have occupied a single buffer. Thus, the more
551  * buffers we have, the lower-quality the cookie...
552  */
553 #define PKT_BUFFER_BITS 8
554 #define N_PKT_BUFFERS (1 << PKT_BUFFER_BITS)
555 #define PKT_BUFFER_MASK (N_PKT_BUFFERS - 1)
556 #define PKT_COOKIE_BITS (32 - PKT_BUFFER_BITS)
557 
558 }
559 
560 }
561 
562 #endif /* OPENFLOW_INTERFACE_H */
void StartDump(StatsDumpCallback *cb)
Starts a callback-based, reliable, possibly multi-message reply to a request made by the controller...
void strip_vlan(ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah)
void discard_buffer(uint32_t id)
static bool IsValidType(ofp_action_type type)
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
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.
Ptr< Packet > packet
The Packet itself.
static TypeId GetTypeId(void)
Register this type.
Ptr< OpenFlowSwitchNetDevice > swtch
The switch that we're requesting data from.
int(* AggregateDumpCallback)(sw_flow *flow, void *state)
static TypeId GetTypeId(void)
Register this type.
int DoInit(const void *body, int body_len, void **state)
Prepares to dump some kind of statistics on the connected OpenFlowSwitchNetDevice.
int(* FlowDumpCallback)(sw_flow *flow, void *state)
uint32_t config
Some subset of OFPPC_* flags.
int AggregateStatsInit(const void *body, int body_len, void **state)
void ReceiveFromSwitch(Ptr< OpenFlowSwitchNetDevice > swtch, ofpbuf *buffer)
A switch calls this method to pass a message on to the Controller.
int AggregateStatsDump(Ptr< OpenFlowSwitchNetDevice > dp, ofp_aggregate_stats_request *s, ofpbuf *buffer)
ofpbuf * retrieve_buffer(uint32_t id)
void ReceiveFromSwitch(Ptr< OpenFlowSwitchNetDevice > swtch, ofpbuf *buffer)
A switch calls this method to pass a message on to the Controller.
Demonstration of a Drop controller.
Stats(ofp_stats_types _type, size_t body_len)
unsigned long long int rx_packets
int PortTableStatsDump(Ptr< OpenFlowSwitchNetDevice > dp, void *state, ofpbuf *buffer)
void set_dl_addr(ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah)
virtual void ReceiveFromSwitch(Ptr< OpenFlowSwitchNetDevice > swtch, ofpbuf *buffer)
A switch calls this method to pass a message on to the Controller.
a polymophic address class
Definition: address.h:90
bool done
Whether we are done requesting stats.
int TableStatsDump(Ptr< OpenFlowSwitchNetDevice > dp, void *state, ofpbuf *buffer)
Stats * s
Handler of the stats request.
ofp_stats_types type
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.
Definition of assertion macros NS_ASSERT() and NS_ASSERT_MSG().
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.
static void Execute(er_action_type type, ofpbuf *buffer, const sw_flow_key *key, const er_action_header *ah)
Executes the action.
LearnState_t m_learnState
Learned state data.
static bool IsValidType(er_action_type type)
void * state
Stats request state data.
static void Execute(ofp_vport_action_type type, ofpbuf *buffer, const sw_flow_key *key, const ofp_action_header *ah)
Executes the action.
static TypeId GetTypeId(void)
Register this type.
std::map< Mac48Address, LearnedState > LearnState_t
Switches_t m_switches
The collection of switches registered to this controller.
Packet Metadata, allows us to track the packet's metadata as it passes through the switch...
Callback for a stats dump request.
static uint16_t Validate(er_action_type type, size_t len)
Validates the action on whether its data is valid or not.
uint32_t save_buffer(ofpbuf *)
unsigned long long int tx_bytes
int DoDump(Ptr< OpenFlowSwitchNetDevice > swtch, void *state, ofpbuf *buffer)
Appends statistics for OpenFlowSwitchNetDevice to 'buffer'.
Ptr< NetDevice > netdev
An interface for a Controller of OpenFlowSwitchNetDevices.
uint32_t num_ports
Number of ports in host byte order.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void set_tp_port(ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah)
int PortStatsDump(Ptr< OpenFlowSwitchNetDevice > dp, PortStatsState *s, ofpbuf *buffer)
unsigned long long int tx_dropped
uint16_t protocolNumber
Protocol type of the Packet when the Packet is received.
void update_checksums(ofpbuf *buffer, const sw_flow_key *key, uint32_t old_word, uint32_t new_word)
Demonstration of a Learning controller.
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...
Address dst
Destination Address of the Packet when the Packet is received.
ofp_stats_request * rq
Current stats request.
Class for handling virtual port table actions.
void set_mpls_exp(ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah)
int FlowStatsInit(const void *body, int body_len, void **state)
uint16_t ValidateActions(const sw_flow_key *key, const ofp_action_header *actions, size_t actions_len)
Validates a list of flow table actions.
Class for handling Ericsson Vendor-defined actions.
unsigned long long int rx_bytes
uint32_t * ports
Array of ports in network byte order.
virtual void AddSwitch(Ptr< OpenFlowSwitchNetDevice > swtch)
Adds a switch to the controller.
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, or deleting a flow.
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.
unsigned long long int mpls_ttl0_dropped
void set_vlan_pcp(ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah)
ofpbuf * buffer
The OpenFlow buffer as created from the Packet, with its data and headers.
void set_nw_addr(ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah)
Time m_expirationTime
Time it takes for learned MAC state entry/created flow to expire.
uint8_t GetPacketType(ofpbuf *buffer)
Get the packet type on the buffer, which can then be used to determine how to handle the buffer...
Address src
Source Address of the Packet when the Packet is received.
int DescStatsDump(void *state, ofpbuf *buffer)
State of the FlowStats request/reply.
int PortStatsInit(const void *body, int body_len, void **state)
std::set< Ptr< OpenFlowSwitchNetDevice > > Switches_t
A base class which provides memory management and object aggregation.
Definition: object.h:87
void set_mpls_label(ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah)
static bool IsValidType(ofp_vport_action_type type)
uint16_t ValidateVPortActions(const ofp_action_header *actions, size_t actions_len)
Validates a list of virtual port table entry actions.
void ExecuteVendor(ofpbuf *buffer, const sw_flow_key *key, const ofp_action_header *ah)
Executes a vendor-defined action.
int FlowStatsDump(Ptr< OpenFlowSwitchNetDevice > dp, FlowStatsState *s, ofpbuf *buffer)
a unique identifier for an interface.
Definition: type-id.h:58
uint32_t state
Some subset of OFPPS_* flags.
static void Execute(ofp_action_type type, ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah)
Executes the action.
void DoCleanup(void *state)
Cleans any state created by the init or dump functions.
unsigned long long int tx_packets
uint16_t ValidateVendor(const sw_flow_key *key, const ofp_action_header *ah, uint16_t len)
Validates a vendor-defined action.
void set_vlan_vid(ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah)
Port and its metadata.
State of the PortStats request/reply.
virtual ~Controller()
Destructor.
Class for handling flow table actions.