pio 0.9.0 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +36 -0
- data/examples/packet_out_new.rb +18 -0
- data/examples/packet_out_read.rb +6 -0
- data/features/packet_out_read.feature +5 -0
- data/lib/pio.rb +1 -0
- data/lib/pio/echo.rb +5 -6
- data/lib/pio/echo/message.rb +39 -13
- data/lib/pio/echo/reply.rb +1 -6
- data/lib/pio/echo/request.rb +3 -5
- data/lib/pio/enqueue.rb +62 -0
- data/lib/pio/features.rb +5 -15
- data/lib/pio/features/reply.rb +28 -48
- data/lib/pio/features/request.rb +11 -8
- data/lib/pio/hello.rb +24 -2
- data/lib/pio/monkey_patch/integer.rb +6 -0
- data/lib/pio/monkey_patch/integer/ranges.rb +22 -0
- data/lib/pio/open_flow.rb +1 -0
- data/lib/pio/open_flow/flags.rb +40 -26
- data/lib/pio/open_flow/message.rb +28 -0
- data/lib/pio/open_flow/parser.rb +22 -0
- data/lib/pio/open_flow/phy_port.rb +34 -50
- data/lib/pio/open_flow/port_number.rb +39 -0
- data/lib/pio/open_flow/type.rb +1 -0
- data/lib/pio/packet_in.rb +42 -9
- data/lib/pio/packet_out.rb +102 -0
- data/lib/pio/send_out_port.rb +74 -0
- data/lib/pio/set_eth_addr.rb +52 -0
- data/lib/pio/set_ip_addr.rb +49 -0
- data/lib/pio/set_ip_tos.rb +42 -0
- data/lib/pio/set_transport_port.rb +58 -0
- data/lib/pio/set_vlan.rb +37 -0
- data/lib/pio/set_vlan_priority.rb +18 -0
- data/lib/pio/set_vlan_vid.rb +30 -0
- data/lib/pio/strip_vlan_header.rb +19 -0
- data/lib/pio/type/ip_address.rb +11 -2
- data/lib/pio/type/ipv4_header.rb +1 -0
- data/lib/pio/type/mac_address.rb +2 -0
- data/lib/pio/version.rb +1 -1
- data/pio.gemspec +4 -4
- data/spec/pio/echo/reply_spec.rb +1 -4
- data/spec/pio/echo/request_spec.rb +5 -8
- data/spec/pio/enqueue_spec.rb +67 -0
- data/spec/pio/features/request_spec.rb +4 -4
- data/spec/pio/features_spec.rb +1 -2
- data/spec/pio/hello_spec.rb +1 -4
- data/spec/pio/packet_out_spec.rb +290 -0
- data/spec/pio/send_out_port_spec.rb +121 -0
- data/spec/pio/set_eth_dst_addr_spec.rb +28 -0
- data/spec/pio/set_eth_src_addr_spec.rb +28 -0
- data/spec/pio/set_ip_dst_addr_spec.rb +25 -0
- data/spec/pio/set_ip_src_addr_spec.rb +25 -0
- data/spec/pio/set_ip_tos_spec.rb +30 -0
- data/spec/pio/set_transport_dst_port_spec.rb +42 -0
- data/spec/pio/set_transport_src_port_spec.rb +42 -0
- data/spec/pio/set_vlan_priority_spec.rb +42 -0
- data/spec/pio/set_vlan_vid_spec.rb +42 -0
- data/spec/pio/strip_vlan_header_spec.rb +20 -0
- metadata +55 -13
- data/lib/pio/echo/format.rb +0 -22
- data/lib/pio/hello/format.rb +0 -18
- data/lib/pio/packet_in/format.rb +0 -55
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'pio/send_out_port'
|
2
|
+
|
3
|
+
describe Pio::SendOutPort do
|
4
|
+
describe '.new' do
|
5
|
+
When(:send_out_port) do
|
6
|
+
Pio::SendOutPort.new(options)
|
7
|
+
end
|
8
|
+
|
9
|
+
context 'with an integer' do
|
10
|
+
When(:options) { 1 }
|
11
|
+
|
12
|
+
Then { send_out_port.port_number == 1 }
|
13
|
+
Then { send_out_port.max_len == 2**16 - 1 }
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'with 0' do
|
17
|
+
When(:options) { 0 }
|
18
|
+
|
19
|
+
Then do
|
20
|
+
send_out_port ==
|
21
|
+
Failure(ArgumentError, 'The port_number should be > 0')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'with 0xff01 (OFPP_MAX + 1)' do
|
26
|
+
When(:options) { 0xff01 }
|
27
|
+
|
28
|
+
Then do
|
29
|
+
send_out_port ==
|
30
|
+
Failure(ArgumentError, 'The port_number should be < 0xff00')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'with :in_port' do
|
35
|
+
When(:options) { :in_port }
|
36
|
+
|
37
|
+
Then { send_out_port.port_number == :in_port }
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'with :table' do
|
41
|
+
When(:options) { :table }
|
42
|
+
|
43
|
+
Then { send_out_port.port_number == :table }
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'with :normal' do
|
47
|
+
When(:options) { :normal }
|
48
|
+
|
49
|
+
Then { send_out_port.port_number == :normal }
|
50
|
+
end
|
51
|
+
|
52
|
+
context 'with :flood' do
|
53
|
+
When(:options) { :flood }
|
54
|
+
|
55
|
+
Then { send_out_port.port_number == :flood }
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'with :all' do
|
59
|
+
When(:options) { :all }
|
60
|
+
|
61
|
+
Then { send_out_port.port_number == :all }
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'with :controller' do
|
65
|
+
When(:options) { :controller }
|
66
|
+
|
67
|
+
Then { send_out_port.port_number == :controller }
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'with :controller' do
|
71
|
+
When(:options) { :local }
|
72
|
+
|
73
|
+
Then { send_out_port.port_number == :local }
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'with :controller' do
|
77
|
+
When(:options) { :none }
|
78
|
+
|
79
|
+
Then { send_out_port.port_number == :none }
|
80
|
+
end
|
81
|
+
|
82
|
+
context 'with port_number: NUMBER option' do
|
83
|
+
When(:options) { { port_number: 1 } }
|
84
|
+
|
85
|
+
Then { send_out_port.port_number == 1 }
|
86
|
+
end
|
87
|
+
|
88
|
+
context 'with port_number: SYMBOL option' do
|
89
|
+
When(:options) { { port_number: :flood } }
|
90
|
+
|
91
|
+
Then { send_out_port.port_number == :flood }
|
92
|
+
end
|
93
|
+
|
94
|
+
context 'with port_number: and max_len: option' do
|
95
|
+
When(:options) { { port_number: 1, max_len: 256 } }
|
96
|
+
|
97
|
+
Then { send_out_port.port_number == 1 }
|
98
|
+
Then { send_out_port.max_len == 256 }
|
99
|
+
end
|
100
|
+
|
101
|
+
context 'with invalid max_len: (-1) option' do
|
102
|
+
When(:options) { { port_number: 1, max_len: -1 } }
|
103
|
+
|
104
|
+
Then do
|
105
|
+
send_out_port ==
|
106
|
+
Failure(ArgumentError,
|
107
|
+
'The max_len should be an unsigned 16bit integer.')
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
context 'with invalid max_len: (2**16) option' do
|
112
|
+
When(:options) { { port_number: 1, max_len: 2**16 } }
|
113
|
+
|
114
|
+
Then do
|
115
|
+
send_out_port ==
|
116
|
+
Failure(ArgumentError,
|
117
|
+
'The max_len should be an unsigned 16bit integer.')
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'pio/set_eth_addr'
|
2
|
+
|
3
|
+
describe Pio::SetEthDstAddr do
|
4
|
+
describe '.new' do
|
5
|
+
Given(:set_eth_dst_addr) do
|
6
|
+
Pio::SetEthDstAddr.new(mac_address)
|
7
|
+
end
|
8
|
+
|
9
|
+
context "with '11:22:33:44:55:66'" do
|
10
|
+
When(:mac_address) { '11:22:33:44:55:66' }
|
11
|
+
Then { set_eth_dst_addr.mac_address == '11:22:33:44:55:66' }
|
12
|
+
|
13
|
+
describe '#to_binary' do
|
14
|
+
Then { set_eth_dst_addr.to_binary.length == 16 }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'with 0x112233445566' do
|
19
|
+
When(:mac_address) { 0x112233445566 }
|
20
|
+
Then { set_eth_dst_addr.mac_address == '11:22:33:44:55:66' }
|
21
|
+
end
|
22
|
+
|
23
|
+
context "with Pio::Mac.new('11:22:33:44:55:66')" do
|
24
|
+
When(:mac_address) { Pio::Mac.new('11:22:33:44:55:66') }
|
25
|
+
Then { set_eth_dst_addr.mac_address == '11:22:33:44:55:66' }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'pio/set_eth_addr'
|
2
|
+
|
3
|
+
describe Pio::SetEthSrcAddr do
|
4
|
+
describe '.new' do
|
5
|
+
Given(:set_eth_src_addr) do
|
6
|
+
Pio::SetEthSrcAddr.new(mac_address)
|
7
|
+
end
|
8
|
+
|
9
|
+
context "with '11:22:33:44:55:66'" do
|
10
|
+
When(:mac_address) { '11:22:33:44:55:66' }
|
11
|
+
Then { set_eth_src_addr.mac_address == '11:22:33:44:55:66' }
|
12
|
+
|
13
|
+
describe '#to_binary' do
|
14
|
+
Then { set_eth_src_addr.to_binary.length == 16 }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'with 0x112233445566' do
|
19
|
+
When(:mac_address) { 0x112233445566 }
|
20
|
+
Then { set_eth_src_addr.mac_address == '11:22:33:44:55:66' }
|
21
|
+
end
|
22
|
+
|
23
|
+
context "with Pio::Mac.new('11:22:33:44:55:66')" do
|
24
|
+
When(:mac_address) { Pio::Mac.new('11:22:33:44:55:66') }
|
25
|
+
Then { set_eth_src_addr.mac_address == '11:22:33:44:55:66' }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'pio/set_ip_addr'
|
2
|
+
|
3
|
+
describe Pio::SetIpDstAddr do
|
4
|
+
describe '.new' do
|
5
|
+
context "with '1.2.3.4'" do
|
6
|
+
When(:set_ip_dst_addr) { Pio::SetIpDstAddr.new('1.2.3.4') }
|
7
|
+
|
8
|
+
describe '#ip_address' do
|
9
|
+
Then { set_ip_dst_addr.ip_address == '1.2.3.4' }
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '#type' do
|
13
|
+
Then { set_ip_dst_addr.type == 7 }
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#message_length' do
|
17
|
+
Then { set_ip_dst_addr.message_length == 8 }
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#to_binary' do
|
21
|
+
Then { set_ip_dst_addr.to_binary.length == 8 }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'pio/set_ip_addr'
|
2
|
+
|
3
|
+
describe Pio::SetIpSrcAddr do
|
4
|
+
describe '.new' do
|
5
|
+
context "with '1.2.3.4'" do
|
6
|
+
When(:set_ip_src_addr) { Pio::SetIpSrcAddr.new('1.2.3.4') }
|
7
|
+
|
8
|
+
describe '#ip_address' do
|
9
|
+
Then { set_ip_src_addr.ip_address == '1.2.3.4' }
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '#type' do
|
13
|
+
Then { set_ip_src_addr.type == 6 }
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#message_length' do
|
17
|
+
Then { set_ip_src_addr.message_length == 8 }
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#to_binary' do
|
21
|
+
Then { set_ip_src_addr.to_binary.length == 8 }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'pio/set_ip_tos'
|
2
|
+
|
3
|
+
describe Pio::SetIpTos do
|
4
|
+
describe '.new' do
|
5
|
+
context 'with 32' do
|
6
|
+
When(:set_ip_tos) { Pio::SetIpTos.new(32) }
|
7
|
+
|
8
|
+
describe '#type_of_service' do
|
9
|
+
Then { set_ip_tos.type_of_service == 32 }
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '#type' do
|
13
|
+
Then { set_ip_tos.type == 8 }
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#message_length' do
|
17
|
+
Then { set_ip_tos.message_length == 8 }
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#to_binary' do
|
21
|
+
Then { set_ip_tos.to_binary.length == 8 }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'with 1' do
|
26
|
+
When(:set_ip_tos) { Pio::SetIpTos.new(1) }
|
27
|
+
Then { set_ip_tos == Failure(ArgumentError) }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'pio/set_transport_port'
|
2
|
+
|
3
|
+
describe Pio::SetTransportDstPort do
|
4
|
+
describe '.new' do
|
5
|
+
When(:set_transport_dst_port) { Pio::SetTransportDstPort.new(port_number) }
|
6
|
+
|
7
|
+
context 'with 100' do
|
8
|
+
When(:port_number) { 100 }
|
9
|
+
|
10
|
+
describe '#port_number' do
|
11
|
+
Then { set_transport_dst_port.port_number == 100 }
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#type' do
|
15
|
+
Then { set_transport_dst_port.type == 10 }
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#message_length' do
|
19
|
+
Then { set_transport_dst_port.message_length == 8 }
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '#to_binary' do
|
23
|
+
Then { set_transport_dst_port.to_binary.length == 8 }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'with -1' do
|
28
|
+
When(:port_number) { -1 }
|
29
|
+
Then { set_transport_dst_port == Failure(ArgumentError) }
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'with 2**16' do
|
33
|
+
When(:port_number) { 2**16 }
|
34
|
+
Then { set_transport_dst_port == Failure(ArgumentError) }
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'with :INVALID_PORT_NUMBER' do
|
38
|
+
When(:port_number) { :INVALID_PORT_NUMBER }
|
39
|
+
Then { set_transport_dst_port == Failure(TypeError) }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'pio/set_transport_port'
|
2
|
+
|
3
|
+
describe Pio::SetTransportSrcPort do
|
4
|
+
describe '.new' do
|
5
|
+
When(:set_transport_src_port) { Pio::SetTransportSrcPort.new(port_number) }
|
6
|
+
|
7
|
+
context 'with 100' do
|
8
|
+
When(:port_number) { 100 }
|
9
|
+
|
10
|
+
describe '#port_number' do
|
11
|
+
Then { set_transport_src_port.port_number == 100 }
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#type' do
|
15
|
+
Then { set_transport_src_port.type == 9 }
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#message_length' do
|
19
|
+
Then { set_transport_src_port.message_length == 8 }
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '#to_binary' do
|
23
|
+
Then { set_transport_src_port.to_binary.length == 8 }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'with -1' do
|
28
|
+
When(:port_number) { -1 }
|
29
|
+
Then { set_transport_src_port == Failure(ArgumentError) }
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'with 2**16' do
|
33
|
+
When(:port_number) { 2**16 }
|
34
|
+
Then { set_transport_src_port == Failure(ArgumentError) }
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'with :INVALID_PORT_NUMBER' do
|
38
|
+
When(:port_number) { :INVALID_PORT_NUMBER }
|
39
|
+
Then { set_transport_src_port == Failure(TypeError) }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'pio/set_vlan_priority'
|
2
|
+
|
3
|
+
describe Pio::SetVlanPriority do
|
4
|
+
describe '.new' do
|
5
|
+
When(:set_vlan_priority) { Pio::SetVlanPriority.new(priority) }
|
6
|
+
|
7
|
+
context 'with 3' do
|
8
|
+
When(:priority) { 3 }
|
9
|
+
|
10
|
+
describe '#vlan_priority' do
|
11
|
+
Then { set_vlan_priority.vlan_priority == 3 }
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#type' do
|
15
|
+
Then { set_vlan_priority.type == 2 }
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#message_length' do
|
19
|
+
Then { set_vlan_priority.message_length == 8 }
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '#to_binary' do
|
23
|
+
Then { set_vlan_priority.to_binary.length == 8 }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'with -1' do
|
28
|
+
When(:priority) { -1 }
|
29
|
+
Then { set_vlan_priority == Failure(ArgumentError) }
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'with 8' do
|
33
|
+
When(:priority) { 8 }
|
34
|
+
Then { set_vlan_priority == Failure(ArgumentError) }
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'with :INVALID_PRIORITY' do
|
38
|
+
When(:priority) { :INVALID_PRIORITY }
|
39
|
+
Then { set_vlan_priority == Failure(TypeError) }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'pio/set_vlan_vid'
|
2
|
+
|
3
|
+
describe Pio::SetVlanVid do
|
4
|
+
describe '.new' do
|
5
|
+
When(:set_vlan_vid) { Pio::SetVlanVid.new(vlan_id) }
|
6
|
+
|
7
|
+
context 'with 10' do
|
8
|
+
When(:vlan_id) { 10 }
|
9
|
+
|
10
|
+
describe '#vlan_id' do
|
11
|
+
Then { set_vlan_vid.vlan_id == 10 }
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#type' do
|
15
|
+
Then { set_vlan_vid.type == 1 }
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#message_length' do
|
19
|
+
Then { set_vlan_vid.message_length == 8 }
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '#to_binary' do
|
23
|
+
Then { set_vlan_vid.to_binary.length == 8 }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'with 0' do
|
28
|
+
When(:vlan_id) { 0 }
|
29
|
+
Then { set_vlan_vid == Failure(ArgumentError) }
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'with 4906' do
|
33
|
+
When(:vlan_id) { 4096 }
|
34
|
+
Then { set_vlan_vid == Failure(ArgumentError) }
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'with :INVALID_VLAN_ID' do
|
38
|
+
When(:vlan_id) { :INVALID_VLAN_ID }
|
39
|
+
Then { set_vlan_vid == Failure(TypeError) }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'pio/strip_vlan_header'
|
2
|
+
|
3
|
+
describe Pio::StripVlanHeader do
|
4
|
+
Given(:strip_vlan_header) { Pio::StripVlanHeader.new }
|
5
|
+
|
6
|
+
describe '#type' do
|
7
|
+
When(:type) { strip_vlan_header.type }
|
8
|
+
Then { type == 3 }
|
9
|
+
end
|
10
|
+
|
11
|
+
describe '#message_length' do
|
12
|
+
When(:message_length) { strip_vlan_header.message_length }
|
13
|
+
Then { message_length == 8 }
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#to_binary' do
|
17
|
+
When(:binary) { strip_vlan_header.to_binary }
|
18
|
+
Then { binary.length == 8 }
|
19
|
+
end
|
20
|
+
end
|