A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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:
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;
442 };
443 
450 {
451 public:
452  void ReceiveFromSwitch (Ptr<OpenFlowSwitchNetDevice> swtch, ofpbuf* buffer);
453 };
454 
463 {
464 public:
465  static TypeId GetTypeId (void);
466 
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;
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 */