pio 0.25.0 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +4 -0
- data/Rakefile +1 -1
- data/bin/terminal-notifier +16 -0
- data/features/open_flow10/bad_request.feature +35 -0
- data/features/open_flow10/bad_request.raw +0 -0
- data/features/open_flow10/barrier_reply.feature +4 -4
- data/features/open_flow10/barrier_request.feature +4 -4
- data/features/open_flow10/echo_reply.feature +13 -13
- data/features/open_flow10/echo_request.feature +6 -6
- data/features/open_flow10/enqueue.feature +17 -0
- data/features/open_flow10/features_reply.feature +2 -2
- data/features/open_flow10/features_request.feature +28 -28
- data/features/open_flow10/flow_mod.feature +5 -5
- data/features/open_flow10/flow_stats_reply.feature +12 -12
- data/features/open_flow10/flow_stats_request.feature +3 -3
- data/features/open_flow10/hello.feature +8 -15
- data/features/open_flow10/hello_failed.feature +69 -0
- data/features/open_flow10/hello_failed.raw +0 -0
- data/features/open_flow10/nxast_learn.raw +0 -0
- data/features/open_flow10/packet_in.feature +2 -2
- data/features/open_flow10/packet_out.feature +13 -13
- data/features/open_flow10/port_status.feature +1 -1
- data/features/open_flow10/send_out_port.feature +106 -0
- data/features/open_flow10/set_ether_destination_address.feature +16 -0
- data/features/open_flow10/set_ether_source_address.feature +16 -0
- data/features/open_flow10/set_ip_destination_address.feature +16 -0
- data/features/open_flow10/set_ip_source_address.feature +16 -0
- data/features/open_flow10/set_ip_tos.feature +16 -0
- data/features/open_flow10/set_transport_destination_port.feature +16 -0
- data/features/open_flow10/set_transport_source_port.feature +16 -0
- data/features/open_flow10/set_vlan_priority.feature +16 -0
- data/features/open_flow10/set_vlan_vid.feature +16 -0
- data/features/open_flow10/strip_vlan_header.feature +15 -0
- data/features/open_flow10/vendor_action.feature +14 -0
- data/features/open_flow13/bad_request.feature +35 -0
- data/features/open_flow13/bad_request.raw +0 -0
- data/features/open_flow13/echo_reply.feature +7 -7
- data/features/open_flow13/echo_request.feature +7 -7
- data/features/open_flow13/features_reply.feature +2 -2
- data/features/open_flow13/features_request.feature +28 -28
- data/features/open_flow13/flow_mod.feature +24 -24
- data/features/open_flow13/hello.feature +5 -5
- data/features/open_flow13/hello_failed.feature +69 -0
- data/features/open_flow13/hello_failed.raw +0 -0
- data/features/open_flow13/packet_in.feature +3 -3
- data/features/open_flow13/packet_out.feature +3 -3
- data/features/open_flow13/send_out_port.feature +101 -10
- data/features/open_flow13/table_stats_reply.raw +0 -0
- data/features/open_flow13/table_stats_request.raw +0 -0
- data/features/open_flow_read.feature +6 -0
- data/features/step_definitions/Gemfile +9 -0
- data/features/step_definitions/Gemfile.lock +76 -0
- data/features/step_definitions/Guardfile +4 -0
- data/features/step_definitions/LICENSE +675 -0
- data/features/step_definitions/README.md +7 -0
- data/features/step_definitions/Rakefile +10 -0
- data/features/step_definitions/dump_flows_steps.rb +13 -0
- data/features/step_definitions/packet_data_steps.rb +4 -0
- data/features/step_definitions/rest_api_steps.rb +40 -0
- data/features/step_definitions/show_stats_steps.rb +83 -0
- data/features/step_definitions/trema_steps.rb +33 -0
- data/features/step_definitions/virtual_link_steps.rb +8 -0
- data/lib/pio/open_flow.rb +5 -5
- data/lib/pio/open_flow/echo.rb +1 -1
- data/lib/pio/open_flow/error.rb +19 -0
- data/lib/pio/open_flow/format.rb +2 -1
- data/lib/pio/open_flow/hello_failed_code.rb +21 -0
- data/lib/pio/open_flow/open_flow_header.rb +11 -2
- data/lib/pio/open_flow/port.rb +69 -0
- data/lib/pio/open_flow10.rb +5 -0
- data/lib/pio/open_flow10/actions.rb +8 -6
- data/lib/pio/open_flow10/enqueue.rb +13 -13
- data/lib/pio/open_flow10/error.rb +28 -0
- data/lib/pio/open_flow10/error/bad_request.rb +66 -0
- data/lib/pio/open_flow10/error/error_type10.rb +26 -0
- data/lib/pio/open_flow10/error/hello_failed.rb +41 -0
- data/lib/pio/open_flow10/features.rb +6 -10
- data/lib/pio/open_flow10/flow_mod.rb +1 -1
- data/lib/pio/open_flow10/flow_stats_request.rb +1 -1
- data/lib/pio/open_flow10/hello.rb +2 -2
- data/lib/pio/open_flow10/match.rb +2 -2
- data/lib/pio/{open_flow/phy_port.rb → open_flow10/phy_port16.rb} +4 -4
- data/lib/pio/open_flow10/port16.rb +21 -0
- data/lib/pio/open_flow10/port_status.rb +1 -1
- data/lib/pio/open_flow10/send_out_port.rb +16 -40
- data/lib/pio/open_flow10/set_ether_address.rb +9 -8
- data/lib/pio/open_flow10/set_ip_address.rb +4 -4
- data/lib/pio/open_flow10/set_ip_tos.rb +4 -4
- data/lib/pio/open_flow10/set_transport_port.rb +12 -12
- data/lib/pio/open_flow10/set_vlan.rb +4 -4
- data/lib/pio/open_flow10/set_vlan_vid.rb +0 -12
- data/lib/pio/open_flow10/strip_vlan_header.rb +7 -7
- data/lib/pio/open_flow10/vendor_action.rb +33 -0
- data/lib/pio/open_flow13.rb +3 -0
- data/lib/pio/open_flow13/actions.rb +3 -3
- data/lib/pio/open_flow13/error.rb +28 -0
- data/lib/pio/open_flow13/error/bad_request.rb +66 -0
- data/lib/pio/open_flow13/error/error_type13.rb +37 -0
- data/lib/pio/open_flow13/error/hello_failed.rb +42 -0
- data/lib/pio/open_flow13/features_reply.rb +33 -33
- data/lib/pio/open_flow13/features_request.rb +3 -3
- data/lib/pio/open_flow13/flow_mod.rb +2 -2
- data/lib/pio/open_flow13/goto_table.rb +2 -0
- data/lib/pio/open_flow13/packet_out.rb +1 -1
- data/lib/pio/open_flow13/port32.rb +21 -0
- data/lib/pio/open_flow13/send_out_port.rb +3 -2
- data/lib/pio/version.rb +1 -1
- data/pio.gemspec +5 -5
- data/spec/pio/open_flow10/enqueue_spec.rb +22 -22
- data/spec/pio/open_flow10/error/hello_failed_spec.rb +26 -0
- data/spec/pio/open_flow10/flow_mod_spec.rb +6 -6
- data/spec/pio/open_flow10/flow_stats_request_spec.rb +1 -1
- data/spec/pio/open_flow10/hello_spec.rb +3 -3
- data/spec/pio/open_flow10/packet_out_spec.rb +33 -33
- data/spec/pio/{open_flow/phy_port_spec.rb → open_flow10/phy_port16_spec.rb} +7 -7
- data/spec/pio/open_flow10/send_out_port_spec.rb +28 -28
- data/spec/pio/open_flow10/set_ether_destination_address_spec.rb +2 -2
- data/spec/pio/open_flow10/set_ether_source_address_spec.rb +2 -2
- data/spec/pio/open_flow10/set_ip_destination_address_spec.rb +4 -4
- data/spec/pio/open_flow10/set_ip_source_address_spec.rb +4 -4
- data/spec/pio/open_flow10/set_ip_tos_spec.rb +4 -4
- data/spec/pio/open_flow10/set_transport_destination_port_spec.rb +11 -11
- data/spec/pio/open_flow10/set_transport_source_port_spec.rb +11 -11
- data/spec/pio/open_flow10/set_vlan_priority_spec.rb +4 -4
- data/spec/pio/open_flow10/set_vlan_vid_spec.rb +4 -4
- data/spec/pio/open_flow10/strip_vlan_header_spec.rb +6 -6
- data/spec/pio/open_flow13/error/bad_request_spec.rb +6 -0
- data/spec/pio/open_flow13/error/hello_failed_spec.rb +26 -0
- data/spec/pio/open_flow13/hello_spec.rb +3 -3
- data/spec/support/shared_examples_for_openflow_messages.rb +40 -27
- metadata +106 -16
- data/lib/pio/open_flow/port_number.rb +0 -39
@@ -0,0 +1,13 @@
|
|
1
|
+
# rubocop:disable LineLength
|
2
|
+
|
3
|
+
Then(/^the switch "(.*?)" has (\d+) flow entr(?:y|ies)$/) do |switch, num_entries|
|
4
|
+
command = "trema dump_flows #{switch} -S."
|
5
|
+
step "I run `#{command}`"
|
6
|
+
expect(output_from(command).split("\n").size - 1).to eq(num_entries.to_i)
|
7
|
+
end
|
8
|
+
|
9
|
+
Then(/^the switch "(.*?)" has no flow entry$/) do |switch|
|
10
|
+
step %(the switch "#{switch}" has 0 flow entry)
|
11
|
+
end
|
12
|
+
|
13
|
+
# rubocop:enable LineLength
|
@@ -59,6 +59,10 @@ Then(/^the message has the following fields and values:$/) do |table|
|
|
59
59
|
step 'the packet has the following fields and values:', table
|
60
60
|
end
|
61
61
|
|
62
|
+
Then(/^the action has the following fields and values:$/) do |table|
|
63
|
+
step 'the packet has the following fields and values:', table
|
64
|
+
end
|
65
|
+
|
62
66
|
# rubocop:disable LineLength
|
63
67
|
Then(/^the message \#(\d+) have the following fields and values:$/) do |index, table|
|
64
68
|
table.hashes.each do |each|
|
@@ -0,0 +1,40 @@
|
|
1
|
+
begin
|
2
|
+
require 'rack/test'
|
3
|
+
|
4
|
+
World(Rack::Test::Methods)
|
5
|
+
|
6
|
+
Given(/^I send and accept JSON$/) do
|
7
|
+
header 'Accept', 'application/json'
|
8
|
+
header 'Cotent-Type', 'application/json'
|
9
|
+
end
|
10
|
+
|
11
|
+
Given(/^I send a GET request for "([^\"]*)"$/) do |path|
|
12
|
+
in_current_dir { get path }
|
13
|
+
end
|
14
|
+
|
15
|
+
# rubocop:disable LineLength
|
16
|
+
Given(/^I send a POST request for "([^\"]*)" with body "([^\"]*)"$/) do |path, body|
|
17
|
+
in_current_dir { post path, Object.instance_eval(body) }
|
18
|
+
end
|
19
|
+
# rubocop:enable LineLength
|
20
|
+
|
21
|
+
# rubocop:disable LineLength
|
22
|
+
Given(/^I send a DELETE request for "([^\"]*)" with body "([^\"]*)"$/) do |path, body|
|
23
|
+
in_current_dir { delete path, Object.instance_eval(body) }
|
24
|
+
end
|
25
|
+
# rubocop:enable LineLength
|
26
|
+
|
27
|
+
Then(/^the response should be "([^\"]*)"$/) do |status|
|
28
|
+
expect(last_response.status).to eq(status.to_i)
|
29
|
+
end
|
30
|
+
|
31
|
+
Then(/^the JSON response should be "([^\"]*)"$/) do |json|
|
32
|
+
expect(JSON.parse(last_response.body)).to eq(JSON.parse(json))
|
33
|
+
end
|
34
|
+
|
35
|
+
Then(/^the JSON response should be:$/) do |json|
|
36
|
+
expect(JSON.parse(last_response.body)).to eq(JSON.parse(json))
|
37
|
+
end
|
38
|
+
rescue LoadError
|
39
|
+
$stderr.puts 'Rack is disabled'
|
40
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# rubocop:disable LineLength
|
2
|
+
|
3
|
+
Then(/^the number of packets sent from "(.*?)" should be:$/) do |host_name, table|
|
4
|
+
command = "trema show_stats #{host_name}"
|
5
|
+
step "I run `#{command}`"
|
6
|
+
|
7
|
+
result = {}
|
8
|
+
cd('.') do
|
9
|
+
output_from(command).split("\n").each do |each|
|
10
|
+
case each
|
11
|
+
when /Packets sent/
|
12
|
+
next
|
13
|
+
when /Packets recevied/
|
14
|
+
break
|
15
|
+
when /-> (\S+) = (\d+) packet/
|
16
|
+
result[Regexp.last_match(1)] = Regexp.last_match(2).to_i
|
17
|
+
else
|
18
|
+
fail "Failed to parse line '#{each}'"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
table.hashes.each do |each|
|
23
|
+
ip_address = each.fetch('destination')
|
24
|
+
expect(result.fetch(ip_address)).to eq(each.fetch('#packets').to_i)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
Then(/^the number of packets received by "(.*?)" should be:$/) do |host_name, table|
|
29
|
+
command = "trema show_stats #{host_name}"
|
30
|
+
step "I run `#{command}`"
|
31
|
+
|
32
|
+
result = Hash.new(0)
|
33
|
+
cd('.') do
|
34
|
+
received = false
|
35
|
+
output_from(command).split("\n").each do |each|
|
36
|
+
case each
|
37
|
+
when /Packets sent/
|
38
|
+
next
|
39
|
+
when /Packets received/
|
40
|
+
received = true
|
41
|
+
next
|
42
|
+
when /(\S+) -> (\S+) = (\d+) packet/
|
43
|
+
next unless received
|
44
|
+
result[Regexp.last_match(1)] = Regexp.last_match(3).to_i
|
45
|
+
else
|
46
|
+
fail "Failed to parse line '#{each}'"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
table.hashes.each do |each|
|
51
|
+
ip_address = each.fetch('source')
|
52
|
+
expect(result[ip_address]).to eq(each.fetch('#packets').to_i)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
Then(/^the total number of received packets should be:$/) do |table|
|
57
|
+
table.hashes[0].each_pair do |host_name, npackets|
|
58
|
+
command = "trema show_stats #{host_name}"
|
59
|
+
step "I run `#{command}`"
|
60
|
+
|
61
|
+
result = 0
|
62
|
+
cd('.') do
|
63
|
+
received = false
|
64
|
+
output_from(command).split("\n").each do |each|
|
65
|
+
case each
|
66
|
+
when /Packets sent/
|
67
|
+
next
|
68
|
+
when /Packets received/
|
69
|
+
received = true
|
70
|
+
next
|
71
|
+
when /(\S+) -> (\S+) = (\d+) packet/
|
72
|
+
next unless received
|
73
|
+
result += Regexp.last_match(3).to_i
|
74
|
+
else
|
75
|
+
fail "Failed to parse line '#{each}'"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
expect(result).to eq(npackets.to_i)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# rubocop:enable LineLength
|
@@ -0,0 +1,33 @@
|
|
1
|
+
Given(/^I use OpenFlow 1\.0$/) do
|
2
|
+
@open_flow_version = :open_flow10
|
3
|
+
end
|
4
|
+
|
5
|
+
Given(/^I use OpenFlow 1\.3$/) do
|
6
|
+
@open_flow_version = :open_flow13
|
7
|
+
end
|
8
|
+
|
9
|
+
# rubocop:disable LineLength
|
10
|
+
When(/^I trema run "([^"]*)"( interactively)? with the configuration "([^"]*)"$/) do |controller_file, interactive, configuration_file|
|
11
|
+
open_flow_option = @open_flow_version == :open_flow13 ? ' --openflow13' : ''
|
12
|
+
run_arguments = "#{File.join '..', '..', controller_file}#{open_flow_option} -c #{configuration_file}"
|
13
|
+
if interactive
|
14
|
+
step %(I run `trema run #{run_arguments}` interactively)
|
15
|
+
else
|
16
|
+
step %(I successfully run `trema run #{run_arguments} -d`)
|
17
|
+
end
|
18
|
+
step %(I successfully run `sleep 3`)
|
19
|
+
end
|
20
|
+
# rubocop:enable LineLength
|
21
|
+
|
22
|
+
When(/^I trema killall "([^"]*)"$/) do |controller_name|
|
23
|
+
step %(I successfully run `trema killall #{controller_name}`)
|
24
|
+
end
|
25
|
+
|
26
|
+
# rubocop:disable LineLength
|
27
|
+
Then(/^the log file "([^"]*)" should contain following messages:$/) do |log_file, messages|
|
28
|
+
step %(a file named "#{log_file}" should exist)
|
29
|
+
messages.rows.flatten.each do |each|
|
30
|
+
step %(the file "#{log_file}" should contain "#{each}")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
# rubocop:enable LineLength
|
data/lib/pio/open_flow.rb
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
require 'pio/open_flow/datapath_id'
|
2
|
+
require 'pio/open_flow/error'
|
2
3
|
require 'pio/open_flow/flags'
|
3
4
|
require 'pio/open_flow/format'
|
4
5
|
require 'pio/open_flow/message'
|
5
6
|
require 'pio/open_flow/open_flow_header'
|
6
|
-
require 'pio/open_flow/phy_port'
|
7
|
-
require 'pio/open_flow/port_number'
|
8
7
|
require 'pio/open_flow10'
|
9
8
|
require 'pio/open_flow13'
|
10
9
|
|
@@ -19,7 +18,7 @@ module Pio
|
|
19
18
|
def self.switch_version(version)
|
20
19
|
[:Barrier, :Echo, :Features, :FlowMod, :Hello, :Match,
|
21
20
|
:PacketIn, :PacketOut, :SendOutPort, :PortStatus,
|
22
|
-
:FlowStats].each do |each|
|
21
|
+
:FlowStats, :Error].each do |each|
|
23
22
|
set_message_class_name each, version
|
24
23
|
@version = version.to_s
|
25
24
|
end
|
@@ -29,12 +28,15 @@ module Pio
|
|
29
28
|
def self.read(binary)
|
30
29
|
parser = {
|
31
30
|
0 => Pio::Hello,
|
31
|
+
1 => Pio::OpenFlow::Error,
|
32
32
|
2 => Pio::Echo::Request,
|
33
33
|
3 => Pio::Echo::Reply,
|
34
34
|
5 => Pio::Features::Request,
|
35
35
|
6 => Pio::Features::Reply,
|
36
36
|
10 => Pio::PacketIn,
|
37
37
|
12 => Pio::PortStatus,
|
38
|
+
13 => Pio::PacketOut,
|
39
|
+
14 => Pio::FlowMod,
|
38
40
|
16 => Pio::FlowStats::Request,
|
39
41
|
17 => Pio::FlowStats::Reply,
|
40
42
|
18 => Pio::Barrier::Request,
|
@@ -42,8 +44,6 @@ module Pio
|
|
42
44
|
}
|
43
45
|
header = OpenFlowHeaderParser.read(binary)
|
44
46
|
parser.fetch(header.message_type).read(binary)
|
45
|
-
rescue
|
46
|
-
raise "Unknown message type #{header.message_type}"
|
47
47
|
end
|
48
48
|
# rubocop:enable MethodLength
|
49
49
|
|
data/lib/pio/open_flow/echo.rb
CHANGED
@@ -0,0 +1,19 @@
|
|
1
|
+
module Pio
|
2
|
+
module OpenFlow
|
3
|
+
# Error message parser
|
4
|
+
class Error
|
5
|
+
def self.read(binary)
|
6
|
+
version = OpenFlowHeaderParser.read(binary).ofp_version
|
7
|
+
error_parser = case version
|
8
|
+
when 1
|
9
|
+
Pio::OpenFlow10::Error
|
10
|
+
when 4
|
11
|
+
Pio::OpenFlow13::Error
|
12
|
+
else
|
13
|
+
fail "Unsupported OpenFlow version: #{version}"
|
14
|
+
end
|
15
|
+
error_parser.read binary
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/pio/open_flow/format.rb
CHANGED
@@ -32,10 +32,11 @@ module Pio
|
|
32
32
|
def_delegators :header, :snapshot
|
33
33
|
def_delegators :snapshot, :ofp_version
|
34
34
|
def_delegators :snapshot, :message_type
|
35
|
-
def_delegators :snapshot, :
|
35
|
+
def_delegators :snapshot, :_length
|
36
36
|
def_delegators :snapshot, :transaction_id
|
37
37
|
def_delegator :snapshot, :transaction_id, :xid
|
38
38
|
|
39
|
+
alias_method :length, :_length
|
39
40
|
alias_method :to_binary, :to_binary_s
|
40
41
|
end
|
41
42
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'bindata'
|
2
|
+
|
3
|
+
module Pio
|
4
|
+
module OpenFlow
|
5
|
+
# enum ofp_hello_failed_code
|
6
|
+
class HelloFailedCode < BinData::Primitive
|
7
|
+
ERROR_CODES = { incompatible: 0, permissions_error: 1 }
|
8
|
+
|
9
|
+
endian :big
|
10
|
+
uint16 :error_code
|
11
|
+
|
12
|
+
def get
|
13
|
+
ERROR_CODES.invert.fetch(error_code)
|
14
|
+
end
|
15
|
+
|
16
|
+
def set(value)
|
17
|
+
self.error_code = ERROR_CODES.fetch(value)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -8,8 +8,13 @@ module Pio
|
|
8
8
|
|
9
9
|
uint8 :ofp_version
|
10
10
|
uint8 :message_type
|
11
|
-
uint16 :
|
11
|
+
uint16 :_length
|
12
12
|
transaction_id :transaction_id
|
13
|
+
rest :body
|
14
|
+
|
15
|
+
def length
|
16
|
+
_length
|
17
|
+
end
|
13
18
|
end
|
14
19
|
|
15
20
|
# OpenFlow message header.
|
@@ -20,7 +25,11 @@ module Pio
|
|
20
25
|
virtual assert: -> { ofp_version == ofp_version_value }
|
21
26
|
uint8 :message_type, value: :message_type_value
|
22
27
|
virtual assert: -> { message_type == message_type_value }
|
23
|
-
uint16 :
|
28
|
+
uint16 :_length, initial_value: -> { 8 + body.length }
|
24
29
|
transaction_id :transaction_id, initial_value: 0
|
30
|
+
|
31
|
+
def length
|
32
|
+
_length
|
33
|
+
end
|
25
34
|
end
|
26
35
|
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module Pio
|
2
|
+
module OpenFlow
|
3
|
+
# Port numbering.
|
4
|
+
class Port < BinData::Primitive
|
5
|
+
endian :big
|
6
|
+
|
7
|
+
def self.port_size_in_bytes(nbytes)
|
8
|
+
class_eval "uint#{nbytes} :port"
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.max_port_number(port_number)
|
12
|
+
const_set :MAX, port_number
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.reserved_ports(port_name_and_number)
|
16
|
+
@reserved = port_name_and_number
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.reserved_port_number(port_name)
|
20
|
+
@reserved.fetch port_name
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.reserved_port_name?(port_name)
|
24
|
+
@reserved.key? port_name
|
25
|
+
end
|
26
|
+
|
27
|
+
def max
|
28
|
+
self.class.const_get :MAX
|
29
|
+
end
|
30
|
+
|
31
|
+
def reserved_port_number(port_name)
|
32
|
+
self.class.reserved_port_number port_name
|
33
|
+
end
|
34
|
+
|
35
|
+
def reserved_port_name?(port_name)
|
36
|
+
self.class.reserved_port_name? port_name
|
37
|
+
end
|
38
|
+
|
39
|
+
def reserved_port_number?(port_number)
|
40
|
+
self.class.instance_variable_get(:@reserved).invert.key?(port_number)
|
41
|
+
end
|
42
|
+
|
43
|
+
def reserved_port_name(port_number)
|
44
|
+
self.class.instance_variable_get(:@reserved).invert.fetch(port_number)
|
45
|
+
end
|
46
|
+
|
47
|
+
def get
|
48
|
+
if reserved_port_number?(port)
|
49
|
+
reserved_port_name(port)
|
50
|
+
else
|
51
|
+
port
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def set(port)
|
56
|
+
if reserved_port_name?(port)
|
57
|
+
self.port = reserved_port_number(port)
|
58
|
+
else
|
59
|
+
port_num = port.to_i
|
60
|
+
fail ArgumentError, 'The port should be > 0' if port_num < 1
|
61
|
+
if port_num >= max
|
62
|
+
fail ArgumentError, "The port should be < #{max.to_hex}"
|
63
|
+
end
|
64
|
+
self.port = port_num
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/lib/pio/open_flow10.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
require 'pio/open_flow10/barrier_reply'
|
2
2
|
require 'pio/open_flow10/barrier_request'
|
3
3
|
require 'pio/open_flow10/echo'
|
4
|
+
require 'pio/open_flow10/error'
|
5
|
+
require 'pio/open_flow10/error/bad_request'
|
6
|
+
require 'pio/open_flow10/error/hello_failed'
|
4
7
|
require 'pio/open_flow10/exact_match'
|
5
8
|
require 'pio/open_flow10/features'
|
6
9
|
require 'pio/open_flow10/flow_mod'
|
@@ -9,5 +12,7 @@ require 'pio/open_flow10/flow_stats_request'
|
|
9
12
|
require 'pio/open_flow10/hello'
|
10
13
|
require 'pio/open_flow10/packet_in'
|
11
14
|
require 'pio/open_flow10/packet_out'
|
15
|
+
require 'pio/open_flow10/phy_port16'
|
16
|
+
require 'pio/open_flow10/port16'
|
12
17
|
require 'pio/open_flow10/port_status'
|
13
18
|
require 'pio/open_flow10/send_out_port'
|
@@ -8,6 +8,7 @@ require 'pio/open_flow10/set_transport_port'
|
|
8
8
|
require 'pio/open_flow10/set_vlan_priority'
|
9
9
|
require 'pio/open_flow10/set_vlan_vid'
|
10
10
|
require 'pio/open_flow10/strip_vlan_header'
|
11
|
+
require 'pio/open_flow10/vendor_action'
|
11
12
|
|
12
13
|
module Pio
|
13
14
|
module OpenFlow
|
@@ -18,14 +19,15 @@ module Pio
|
|
18
19
|
1 => Pio::SetVlanVid,
|
19
20
|
2 => Pio::SetVlanPriority,
|
20
21
|
3 => Pio::StripVlanHeader,
|
21
|
-
4 => Pio::
|
22
|
-
5 => Pio::
|
22
|
+
4 => Pio::SetEtherSourceAddress,
|
23
|
+
5 => Pio::SetEtherDestinationAddress,
|
23
24
|
6 => Pio::SetIpSourceAddress,
|
24
25
|
7 => Pio::SetIpDestinationAddress,
|
25
26
|
8 => Pio::SetIpTos,
|
26
27
|
9 => Pio::SetTransportSourcePort,
|
27
28
|
10 => Pio::SetTransportDestinationPort,
|
28
|
-
11 => Pio::Enqueue
|
29
|
+
11 => Pio::Enqueue,
|
30
|
+
0xffff => Pio::VendorAction
|
29
31
|
}
|
30
32
|
|
31
33
|
mandatory_parameter :length
|
@@ -34,8 +36,8 @@ module Pio
|
|
34
36
|
|
35
37
|
string :binary, read_length: :length
|
36
38
|
|
37
|
-
def set(
|
38
|
-
self.binary =
|
39
|
+
def set(actions)
|
40
|
+
self.binary = Array(actions).map(&:to_binary).join
|
39
41
|
end
|
40
42
|
|
41
43
|
# rubocop:disable MethodLength
|
@@ -47,7 +49,7 @@ module Pio
|
|
47
49
|
type = BinData::Uint16be.read(tmp)
|
48
50
|
begin
|
49
51
|
action = ACTION_CLASS.fetch(type).read(tmp)
|
50
|
-
tmp = tmp[action.
|
52
|
+
tmp = tmp[action.length..-1]
|
51
53
|
actions << action
|
52
54
|
rescue KeyError
|
53
55
|
raise "action type #{type} is not supported."
|