A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
openflow-interface.h
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),
132  mpls_ttl0_dropped (0)
133  {
134  }
135 
136  uint32_t config;
137  uint32_t state;
138  Ptr<NetDevice> netdev;
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  {
184  int table_idx;
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:
349  static TypeId GetTypeId (void)
350  {
351  static TypeId tid = TypeId ("ns3::ofi::Controller")
352  .SetParent<Object> ()
353  .AddConstructor<Controller> ()
354  ;
355  return tid;
356  }
357 
358  virtual ~Controller ()
359  {
360  m_switches.clear ();
361  }
362 
368  virtual void AddSwitch (Ptr<OpenFlowSwitchNetDevice> swtch);
369 
376  virtual void ReceiveFromSwitch (Ptr<OpenFlowSwitchNetDevice> swtch, ofpbuf* buffer)
377  {
378  }
379 
397  void StartDump (StatsDumpCallback* cb);
398 
399 protected:
410  virtual void SendToSwitch (Ptr<OpenFlowSwitchNetDevice> swtch, void * msg, size_t length);
411 
427  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);
428 
438  uint8_t GetPacketType (ofpbuf* buffer);
439 
440  typedef std::set<Ptr<OpenFlowSwitchNetDevice> > Switches_t;
441  Switches_t m_switches;
442 };
443 
450 {
451 public:
452  void ReceiveFromSwitch (Ptr<OpenFlowSwitchNetDevice> swtch, ofpbuf* buffer);
453 };
454 
463 {
464 public:
465  static TypeId GetTypeId (void);
466 
467  virtual ~LearningController ()
468  {
469  m_learnState.clear ();
470  }
471 
472  void ReceiveFromSwitch (Ptr<OpenFlowSwitchNetDevice> swtch, ofpbuf* buffer);
473 
474 protected:
476  {
477  uint32_t port;
478  };
480  typedef std::map<Mac48Address, LearnedState> LearnState_t;
481  LearnState_t m_learnState;
482 };
483 
495 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);
496 
505 uint16_t ValidateActions (const sw_flow_key *key, const ofp_action_header *actions, size_t actions_len);
506 
517 void ExecuteVPortActions (Ptr<OpenFlowSwitchNetDevice> swtch, uint64_t packet_uid, ofpbuf* buffer, sw_flow_key *key, const ofp_action_header *actions, size_t actions_len);
518 
526 uint16_t ValidateVPortActions (const ofp_action_header *actions, size_t actions_len);
527 
535 void ExecuteVendor (ofpbuf *buffer, const sw_flow_key *key, const ofp_action_header *ah);
536 
545 uint16_t ValidateVendor (const sw_flow_key *key, const ofp_action_header *ah, uint16_t len);
546 
547 /*
548  * From datapath.c
549  * Buffers are identified to userspace by a 31-bit opaque ID. We divide the ID
550  * into a buffer number (low bits) and a cookie (high bits). The buffer number
551  * is an index into an array of buffers. The cookie distinguishes between
552  * different packets that have occupied a single buffer. Thus, the more
553  * buffers we have, the lower-quality the cookie...
554  */
555 #define PKT_BUFFER_BITS 8
556 #define N_PKT_BUFFERS (1 << PKT_BUFFER_BITS)
557 #define PKT_BUFFER_MASK (N_PKT_BUFFERS - 1)
558 #define PKT_COOKIE_BITS (32 - PKT_BUFFER_BITS)
559 
560 }
561 
562 }
563 
564 #endif /* OPENFLOW_INTERFACE_H */
void StartDump(StatsDumpCallback *cb)
Starts a callback-based, reliable, possibly multi-message reply to a request made by the controller...
static bool IsValidType(ofp_action_type type)
keep track of time unit.
Definition: nstime.h:149
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:59
Ptr< Packet > packet
The Packet itself.
Ptr< OpenFlowSwitchNetDevice > swtch
The switch that we're requesting data from.
int DoInit(const void *body, int body_len, void **state)
Prepares to dump some kind of statistics on the connected OpenFlowSwitchNetDevice.
uint32_t config
Some subset of OFPPC_* flags.
void ReceiveFromSwitch(Ptr< OpenFlowSwitchNetDevice > swtch, ofpbuf *buffer)
void ReceiveFromSwitch(Ptr< OpenFlowSwitchNetDevice > swtch, ofpbuf *buffer)
virtual void ReceiveFromSwitch(Ptr< OpenFlowSwitchNetDevice > swtch, ofpbuf *buffer)
a polymophic address class
Definition: address.h:86
bool done
Whether we are done requesting stats.
Stats * s
Handler of the stats request.
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(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.
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.
int DoDump(Ptr< OpenFlowSwitchNetDevice > swtch, void *state, ofpbuf *buffer)
Appends statistics for OpenFlowSwitchNetDevice to 'buffer'.
An interface for a Controller of OpenFlowSwitchNetDevices.
uint32_t num_ports
Number of ports in host byte order.
uint16_t protocolNumber
Protocol type of the Packet when the Packet is received.
virtual void SendToSwitch(Ptr< OpenFlowSwitchNetDevice > swtch, void *msg, size_t length)
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.
Class for handling Ericsson Vendor-defined actions.
uint32_t * ports
Array of ports in network byte order.
virtual void AddSwitch(Ptr< OpenFlowSwitchNetDevice > swtch)
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)
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.
ofpbuf * buffer
The OpenFlow buffer as created from the Packet, with its data and headers.
Time m_expirationTime
Time it takes for learned MAC state entry/created flow to expire.
uint8_t GetPacketType(ofpbuf *buffer)
Address src
Source Address of the Packet when the Packet is received.
State of the FlowStats request/reply.
a base class which provides memory management and object aggregation
Definition: object.h:63
static bool IsValidType(ofp_vport_action_type type)
a unique identifier for an interface.
Definition: type-id.h:44
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.
TypeId SetParent(TypeId tid)
Definition: type-id.cc:471
void DoCleanup(void *state)
Cleans any state created by the init or dump functions.
Port and its metadata.
State of the PortStats request/reply.
Class for handling flow table actions.