Class: OFSwitch

Inherits:
OpenflowNode show all
Defined in:
lib/openflowdev/of_switch.rb

Overview

Class that represents an instance of ‘OpenFlow Switch’ (OpenFlow capable device).

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(controller: nil, name: nil, dpid: nil) ⇒ OFSwitch

Parameters

  • controller

    Controller : Controller object through which the OpenFlow switch is to be controlled.

  • name

    String : Node name of the OpenFlow node.

  • dpid

    String : The OpenFlow datapath identifier for the OpenFlow device I. e.g. admin



48
49
50
51
# File 'lib/openflowdev/of_switch.rb', line 48

def initialize(controller: nil, name: nil, dpid: nil)
  super(controller: controller, name: name)
  @dpid = dpid
end

Instance Attribute Details

#nameObject (readonly)

String: name of the controller node.



41
42
43
# File 'lib/openflowdev/of_switch.rb', line 41

def name
  @name
end

Instance Method Details

#add_modify_flow(flow) ⇒ Object

Add a new flow or modify an existing one.

Parameters

  • flow

    FlowEntry : the flow definition

Return Value

  • NetconfResponse : Status ( NetconfResponseStatus ) and error details (if Status indicates an error).



191
192
193
194
195
196
197
198
199
200
201
# File 'lib/openflowdev/of_switch.rb', line 191

def add_modify_flow(flow)
  put_uri = "#{@controller.get_node_config_uri(self)}/table/#{flow.table_id}/"\
    "flow/#{flow.id}"
  response = @controller.rest_agent.put_request(put_uri, flow.to_hash,
    headers: {'Content-Type' => 'application/yang.data+json'})
  if response.code.to_i == 200
    NetconfResponse.new(NetconfResponseStatus::OK)
  else
    handle_error_response(response)
  end
end

#delete_flow(table_id: nil, flow_id: nil) ⇒ Object

Remove a flow.

Parameters

  • table_id

    String : the identifier for the OpenFlow table from which to remove the flow

  • flow_id

    String : the identifier for the flow to remove.

Return Value

  • NetconfResponse : Status ( NetconfResponseStatus ) and details on error (if Status indicates an error).

Raises:

  • (ArgumentError)


230
231
232
233
234
235
236
237
238
239
240
241
# File 'lib/openflowdev/of_switch.rb', line 230

def delete_flow(table_id: nil, flow_id: nil)
  raise ArgumentError, "Table ID (table_id) required" unless table_id
  raise ArgumentError, "Flow ID (flow_id) required" unless flow_id
  delete_uri = "#{@controller.get_node_config_uri(self)}/table/#{table_id}/"\
    "flow/#{flow_id}"
  response = @controller.rest_agent.delete_request(delete_uri)
  if response.code.to_i == 200
    NetconfResponse.new(NetconfResponseStatus::OK)
  else
    handle_error_response(response)
  end
end

#get_configured_flow(table_id: nil, flow_id: nil) ⇒ Object

Return details of a specific flow.

Parameters

  • table_id

    String : the identifier for the OpenFlow table from which to retrieve the flow

  • flow_id

    String : the identifier for the flow to retrieve.

Return Value

  • NetconfResponse : Status ( NetconfResponseStatus ) and details about the requested flow.

Raises:

  • (ArgumentError)


211
212
213
214
215
216
217
218
219
220
# File 'lib/openflowdev/of_switch.rb', line 211

def get_configured_flow(table_id: nil, flow_id: nil)
  raise ArgumentError, "Table ID (table_id) required" unless table_id
  raise ArgumentError, "Flow ID (flow_id) required" unless flow_id
  get_uri = "#{@controller.get_node_config_uri(self)}/table/#{table_id}/"\
    "flow/#{flow_id}"
  response = @controller.rest_agent.get_request(get_uri)
  check_response_for_success(response) do |body|
    NetconfResponse.new(NetconfResponseStatus::OK, body)
  end
end

#get_configured_flows(table_id: nil) ⇒ Object

Return a list of flows in the controller’s configuration data store for the OpenFlow switch. These are the flows that the controller is supposed to program into the OpenFlow switch.

Parameters

  • table_id

    String : the identifier for the OpenFlow table from which to retrieve the flows

Return Value

  • NetconfResponse : Status ( NetconfResponseStatus ) and list of flows.

Raises:

  • (ArgumentError)


262
263
264
265
# File 'lib/openflowdev/of_switch.rb', line 262

def get_configured_flows(table_id: nil)
  raise ArgumentError, "Table ID (table_id) required" unless table_id
  get_flows(table_id: table_id, is_operational: false)
end

#get_configured_flows_ovs_syntax(table_id: nil, sort: false) ⇒ Object

Return a list of flows in the controller’s configured data store for the OpenFlow switch.

These are the flows that the controller is to program into the OpenFlow switch. These flows will be returned in Open Vswitch (OVS) format.

Parameters

  • table_id

    String : the identifier for the OpenFlow table from which to retrieve the flows

Return Value

  • NetconfResponse : Status ( NetconfResponseStatus ) and list of flows in Open VSwitch format.

Raises:

  • (ArgumentError)


300
301
302
303
304
305
306
307
308
309
310
311
312
313
# File 'lib/openflowdev/of_switch.rb', line 300

def get_configured_flows_ovs_syntax(table_id: nil, sort: false)
  raise ArgumentError, "Table ID (table_id) required" unless table_id
  response = get_configured_flows(table_id: table_id)
  if response.status == NetconfResponseStatus::OK
    flows = []
    response.body.sort! { |x,y| x['priority'] <=> y['priority']} if sort
    response.body.each do |flow|
      flows << odl_to_ovs_flow_syntax(flow)
    end
    NetconfResponse.new(NetconfResponseStatus::OK, flows)
  else
    response
  end
end

#get_features_infoObject

Return a list of OpenFlow features supported by the OpenFlow switch.

Return Value

  • NetconfResponse : Status ( NetconfResponseStatus ) and supported features.



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/openflowdev/of_switch.rb', line 93

def get_features_info
  get_uri = @controller.get_node_operational_uri(self)
  response = @controller.rest_agent.get_request(get_uri)
  check_response_for_success(response) do |body|
    if body.has_key?('node') && body['node'].is_a?(Array) &&
        body['node'][0].has_key?('flow-node-inventory:switch-features')
      properties = body['node'][0]['flow-node-inventory:switch-features']
      feature_info = {'max_tables' => properties['max_tables'],
        'max_buffers' => properties['max_buffers']}
      capabilities = []
      properties['capabilities'].each do |capability|
        capabilities << capability.gsub('flow-node-inventory:flow-feature-capability-', '')
      end
      feature_info['capabilities'] = capabilities
      NetconfResponse.new(NetconfResponseStatus::OK, feature_info)
    else
      NetconfResponse.new(NetconfResponseStatus::DATA_NOT_FOUND)
    end
  end
end

#get_operational_flows(table_id: nil) ⇒ Object

Return a list of flows in the controller’s operational data store for the OpenFlow switch. These are the flows that are in the switch.

Parameters

  • table_id

    String : the identifier for the OpenFlow table from which to retrieve the flows

Return Value

  • NetconfResponse : Status ( NetconfResponseStatus ) and list of flows.

Raises:

  • (ArgumentError)


250
251
252
253
# File 'lib/openflowdev/of_switch.rb', line 250

def get_operational_flows(table_id: nil)
  raise ArgumentError, "Table ID (table_id) required" unless table_id
  get_flows(table_id: table_id)
end

#get_operational_flows_ovs_syntax(table_id: nil, sort: false) ⇒ Object

Return a list of flows in the controller’s operational data store for the OpenFlow switch. These are the flows that are in the switch. These flows will be returned in Open Vswitch (OVS) format.

Parameters

  • table_id

    String : the identifier for the OpenFlow table from which to retrieve the flows

Return Value

  • NetconfResponse : Status ( NetconfResponseStatus ) and list of flows in Open VSwitch format.

Raises:

  • (ArgumentError)


275
276
277
278
279
280
281
282
283
284
285
286
287
288
# File 'lib/openflowdev/of_switch.rb', line 275

def get_operational_flows_ovs_syntax(table_id: nil, sort: false)
  raise ArgumentError, "Table ID (table_id) required" unless table_id
  response = get_operational_flows(table_id: table_id)
  if response.status == NetconfResponseStatus::OK
    flows = []
    response.body.sort! { |x,y| x['priority'] <=> y['priority']} if sort
    response.body.each do |flow|
      flows << odl_to_ovs_flow_syntax(flow)
    end
    NetconfResponse.new(NetconfResponseStatus::OK, flows)
  else
    response
  end
end

#get_port_detail_info(port) ⇒ Object

Return detailed information about a specific port.

Parameters

  • port

    Integer : number for the port from the #get_ports_brief_info

Return Value

  • NetconfResponse : Status ( NetconfResponseStatus ) and detailed information about the requested port.



170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/openflowdev/of_switch.rb', line 170

def get_port_detail_info(port)
  get_uri = "#{@controller.get_node_operational_uri(self)}/node-connector/"\
    "#{self.name}:#{port}"
  response = @controller.rest_agent.get_request(get_uri)
  check_response_for_success(response) do |body|
    if body.has_key?('node-connector') &&
        body['node-connector'].is_a?(Array) && body['node-connector'][0]
      NetconfResponse.new(NetconfResponseStatus::OK, body['node-connector'][0])
    else
      NetconfResponse.new(NetconfResponseStatus::DATA_NOT_FOUND)
    end
  end
end

#get_ports_brief_infoObject

Return a brief set of information about each port on the OpenFlow switch.

Return Value

  • NetconfResponse : Status ( NetconfResponseStatus ) and list of ports with brief info for each.



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/openflowdev/of_switch.rb', line 141

def get_ports_brief_info
  get_uri = @controller.get_node_operational_uri(self)
  response = @controller.rest_agent.get_request(get_uri)
  check_response_for_success(response) do |body|
    if body.has_key?('node') && body['node'].is_a?(Array) &&
        body['node'][0].has_key?('node-connector')
      ports_info = []
      body['node'][0]['node-connector'].each do |port|
        port_info = {'id' => port['id'],
          'number' => port['flow-node-inventory:port-number'],
          'name' => port['flow-node-inventory:name'],
          'mac-address' => port['flow-node-inventory:hardware-address'],
          'current-feature' => port['flow-node-inventory:current-feature'].upcase}
        ports_info << port_info
      end
      NetconfResponse.new(NetconfResponseStatus::OK, ports_info)
    else
      NetconfResponse.new(NetconfResponseStatus::DATA_NOT_FOUND)
    end
  end
end

#get_ports_listObject

Return a list of ports for the OpenFlow switch.

Return Value

  • NetconfResponse : Status ( NetconfResponseStatus ) and list of ports.



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/openflowdev/of_switch.rb', line 119

def get_ports_list
  get_uri = @controller.get_node_operational_uri(self)
  response = @controller.rest_agent.get_request(get_uri)
  check_response_for_success(response) do |body|
    if body.has_key?('node') && body['node'].is_a?(Array) &&
        body['node'][0].has_key?('node-connector')
      ports = []
      body['node'][0]['node-connector'].each do |port|
        ports << port['flow-node-inventory:port-number']
      end
      NetconfResponse.new(NetconfResponseStatus::OK, ports)
    else
      NetconfResponse.new(NetconfResponseStatus::DATA_NOT_FOUND)
    end
  end
end

#get_switch_infoObject

Return info about the OpenFlow switch.

Return Value

  • NetconfResponse : Status ( NetconfResponseStatus ) and info about the OpenFlow switch.



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/openflowdev/of_switch.rb', line 59

def get_switch_info
  get_uri = @controller.get_node_operational_uri(self)
  response = @controller.rest_agent.get_request(get_uri)
  check_response_for_success(response) do |body|
    general_info = {}
    if body.has_key?('node') && body['node'].is_a?(Array)
      properties = body['node'][0]
      if properties.has_key?('flow-node-inventory:manufacturer')
        general_info['manufacturer'] = properties['flow-node-inventory:manufacturer']
      end
      if properties.has_key?('flow-node-inventory:serial-number')
        general_info['serial-number'] = properties['flow-node-inventory:serial-number']
      end
      if properties.has_key?('flow-node-inventory:software')
        general_info['software'] = properties['flow-node-inventory:software']
      end
      if properties.has_key?('flow-node-inventory:hardware')
        general_info['hardware'] = properties['flow-node-inventory:hardware']
      end
      if properties.has_key?('flow-node-inventory:description')
        general_info['description'] = properties['flow-node-inventory:description']
      end
      NetconfResponse.new(NetconfResponseStatus::OK, general_info)
    else
      NetconfResponse.new(NetconfResponseStatus::DATA_NOT_FOUND)
    end
  end
end