pio 0.24.2 → 0.25.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/README.md +2 -0
  4. data/bin/byebug +16 -0
  5. data/features/arp.feature +2 -2
  6. data/features/dhcp.feature +4 -4
  7. data/features/icmp.feature +2 -2
  8. data/features/lldp.feature +1 -1
  9. data/features/open_flow10/barrier_reply.feature +4 -4
  10. data/features/open_flow10/barrier_request.feature +4 -4
  11. data/features/open_flow10/echo_reply.feature +6 -6
  12. data/features/open_flow10/echo_request.feature +6 -6
  13. data/features/open_flow10/exact_match.feature +2 -2
  14. data/features/open_flow10/features_reply.feature +2 -2
  15. data/features/open_flow10/features_request.feature +4 -4
  16. data/features/open_flow10/flow_mod.feature +6 -6
  17. data/features/open_flow10/flow_stats_reply.feature +105 -0
  18. data/features/open_flow10/flow_stats_request.feature +90 -0
  19. data/features/open_flow10/hello.feature +4 -4
  20. data/features/open_flow10/packet_in.feature +2 -2
  21. data/features/open_flow10/packet_out.feature +1 -1
  22. data/features/open_flow10/port_status.feature +1 -1
  23. data/features/open_flow13/apply_actions.feature +3 -3
  24. data/features/open_flow13/echo_reply.feature +7 -7
  25. data/features/open_flow13/echo_request.feature +7 -7
  26. data/features/open_flow13/features_reply.feature +2 -2
  27. data/features/open_flow13/features_request.feature +4 -4
  28. data/features/open_flow13/flow_mod.feature +5 -5
  29. data/features/open_flow13/goto_table.feature +2 -2
  30. data/features/open_flow13/hello.feature +5 -5
  31. data/features/open_flow13/match.feature +81 -81
  32. data/features/open_flow13/meter.feature +2 -2
  33. data/features/open_flow13/packet_in.feature +3 -3
  34. data/features/open_flow13/packet_out.feature +3 -3
  35. data/features/open_flow13/send_out_port.feature +2 -2
  36. data/features/open_flow13/write_metadata.feature +2 -2
  37. data/features/open_flow_read.feature +12 -10
  38. data/features/step_definitions/packet_data_steps.rb +3 -3
  39. data/lib/pio/open_flow.rb +4 -1
  40. data/lib/pio/open_flow/message.rb +3 -0
  41. data/lib/pio/open_flow10.rb +2 -0
  42. data/lib/pio/open_flow10/flow_mod.rb +1 -16
  43. data/lib/pio/open_flow10/flow_stats_reply.rb +59 -0
  44. data/lib/pio/open_flow10/flow_stats_request.rb +64 -0
  45. data/lib/pio/open_flow10/match.rb +17 -0
  46. data/lib/pio/open_flow10/stats_type.rb +27 -0
  47. data/lib/pio/version.rb +1 -1
  48. data/pio.gemspec +2 -2
  49. data/spec/pio/open_flow10/flow_stats_reply_spec.rb +39 -0
  50. data/spec/pio/open_flow10/flow_stats_request_spec.rb +38 -0
  51. metadata +185 -173
@@ -6,7 +6,7 @@ Feature: Pio::Meter
6
6
  Pio::Meter.new(1)
7
7
  """
8
8
  Then it should finish successfully
9
- And the message have the following fields and values:
9
+ And the message has the following fields and values:
10
10
  | field | value |
11
11
  | class | Pio::Meter |
12
12
  | instruction_type | 6 |
@@ -17,7 +17,7 @@ Feature: Pio::Meter
17
17
  Scenario: read
18
18
  When I try to parse a file named "open_flow13/instruction_meter.raw" with "Pio::Meter" class
19
19
  Then it should finish successfully
20
- And the message have the following fields and values:
20
+ And the message has the following fields and values:
21
21
  | field | value |
22
22
  | class | Pio::Meter |
23
23
  | instruction_type | 6 |
@@ -6,7 +6,7 @@ Feature: Pio::PacketIn
6
6
  Pio::PacketIn.new
7
7
  """
8
8
  Then it should finish successfully
9
- And the message have the following fields and values:
9
+ And the message has the following fields and values:
10
10
  | field | value |
11
11
  | ofp_version | 4 |
12
12
  | message_type | 10 |
@@ -36,7 +36,7 @@ Feature: Pio::PacketIn
36
36
  Pio::PacketIn.new(raw_data: data_dump)
37
37
  """
38
38
  Then it should finish successfully
39
- And the message have the following fields and values:
39
+ And the message has the following fields and values:
40
40
  | field | value |
41
41
  | ofp_version | 4 |
42
42
  | message_length | 94 |
@@ -55,7 +55,7 @@ Feature: Pio::PacketIn
55
55
  Scenario: read
56
56
  When I try to parse a file named "open_flow13/packet_in.raw" with "PacketIn" class
57
57
  Then it should finish successfully
58
- And the message have the following fields and values:
58
+ And the message has the following fields and values:
59
59
  | field | value |
60
60
  | ofp_version | 4 |
61
61
  | message_type | 10 |
@@ -6,7 +6,7 @@ Feature: Pio::PacketOut
6
6
  Pio::PacketOut.new
7
7
  """
8
8
  Then it should finish successfully
9
- And the message have the following fields and values:
9
+ And the message has the following fields and values:
10
10
  | field | value |
11
11
  | ofp_version | 4 |
12
12
  | message_type | 13 |
@@ -34,7 +34,7 @@ Feature: Pio::PacketOut
34
34
  Pio::PacketOut.new(raw_data: data_dump, actions: Pio::SendOutPort.new(1))
35
35
  """
36
36
  Then it should finish successfully
37
- And the message have the following fields and values:
37
+ And the message has the following fields and values:
38
38
  | field | value |
39
39
  | ofp_version | 4 |
40
40
  | message_type | 13 |
@@ -63,7 +63,7 @@ Feature: Pio::PacketOut
63
63
  Scenario: read
64
64
  When I try to parse a file named "open_flow13/packet_out.raw" with "PacketOut" class
65
65
  Then it should finish successfully
66
- And the message have the following fields and values:
66
+ And the message has the following fields and values:
67
67
  | field | value |
68
68
  | ofp_version | 4 |
69
69
  | message_type | 13 |
@@ -6,7 +6,7 @@ Feature: Pio::SendOutPort
6
6
  Pio::SendOutPort.new(1)
7
7
  """
8
8
  Then it should finish successfully
9
- And the message have the following fields and values:
9
+ And the message has the following fields and values:
10
10
  | field | value |
11
11
  | action_type | 0 |
12
12
  | action_length | 16 |
@@ -16,7 +16,7 @@ Feature: Pio::SendOutPort
16
16
  Scenario: read
17
17
  When I try to parse a file named "open_flow13/send_out_port.raw" with "Pio::SendOutPort" class
18
18
  Then it should finish successfully
19
- And the message have the following fields and values:
19
+ And the message has the following fields and values:
20
20
  | field | value |
21
21
  | action_type | 0 |
22
22
  | action_length | 16 |
@@ -6,7 +6,7 @@ Feature: Pio::WriteMetadata
6
6
  Pio::WriteMetadata.new(metadata: 1)
7
7
  """
8
8
  Then it should finish successfully
9
- And the message have the following fields and values:
9
+ And the message has the following fields and values:
10
10
  | field | value |
11
11
  | class | Pio::WriteMetadata |
12
12
  | instruction_type | 2 |
@@ -18,7 +18,7 @@ Feature: Pio::WriteMetadata
18
18
  Scenario: read
19
19
  When I try to parse a file named "open_flow13/instruction_write_metadata.raw" with "Pio::WriteMetadata" class
20
20
  Then it should finish successfully
21
- And the message have the following fields and values:
21
+ And the message has the following fields and values:
22
22
  | field | value |
23
23
  | class | Pio::WriteMetadata |
24
24
  | instruction_type | 2 |
@@ -2,13 +2,15 @@ Feature: Pio::OpenFlow.read
2
2
  Scenario: OpenFlow10
3
3
  Given I switch the Pio::OpenFlow version to "OpenFlow10"
4
4
  Then the following each raw file should be parsed into its corresponding object using OpenFlow.read
5
- | raw file | result object |
6
- | open_flow10/hello.raw | Pio::OpenFlow10::Hello |
7
- | open_flow10/echo_request.raw | Pio::OpenFlow10::Echo::Request |
8
- | open_flow10/echo_reply.raw | Pio::OpenFlow10::Echo::Reply |
9
- | open_flow10/features_request.raw | Pio::OpenFlow10::Features::Request |
10
- | open_flow10/features_reply.raw | Pio::OpenFlow10::Features::Reply |
11
- | open_flow10/packet_in.raw | Pio::OpenFlow10::PacketIn |
12
- | open_flow10/port_status.raw | Pio::OpenFlow10::PortStatus |
13
- | open_flow10/barrier_request.raw | Pio::OpenFlow10::Barrier::Request |
14
- | open_flow10/barrier_reply.raw | Pio::OpenFlow10::Barrier::Reply |
5
+ | raw file | result object |
6
+ | open_flow10/hello.raw | Pio::OpenFlow10::Hello |
7
+ | open_flow10/echo_request.raw | Pio::OpenFlow10::Echo::Request |
8
+ | open_flow10/echo_reply.raw | Pio::OpenFlow10::Echo::Reply |
9
+ | open_flow10/features_request.raw | Pio::OpenFlow10::Features::Request |
10
+ | open_flow10/features_reply.raw | Pio::OpenFlow10::Features::Reply |
11
+ | open_flow10/packet_in.raw | Pio::OpenFlow10::PacketIn |
12
+ | open_flow10/port_status.raw | Pio::OpenFlow10::PortStatus |
13
+ | open_flow10/barrier_request.raw | Pio::OpenFlow10::Barrier::Request |
14
+ | open_flow10/barrier_reply.raw | Pio::OpenFlow10::Barrier::Reply |
15
+ | open_flow10/flow_stats_request.raw | Pio::OpenFlow10::FlowStats::Request |
16
+ | open_flow10/flow_stats_reply.raw | Pio::OpenFlow10::FlowStats::Reply |
@@ -44,7 +44,7 @@ Then(/^the message should be a "([^"]*)"$/) do |expected_klass|
44
44
  expect(@result.class.to_s).to eq(expected_klass)
45
45
  end
46
46
 
47
- Then(/^the packet have the following fields and values:$/) do |table|
47
+ Then(/^the packet has the following fields and values:$/) do |table|
48
48
  table.hashes.each do |each|
49
49
  output = @result.instance_eval("self.#{each['field']}")
50
50
  if /^:/ =~ output.inspect
@@ -55,8 +55,8 @@ Then(/^the packet have the following fields and values:$/) do |table|
55
55
  end
56
56
  end
57
57
 
58
- Then(/^the message have the following fields and values:$/) do |table|
59
- step 'the packet have the following fields and values:', table
58
+ Then(/^the message has the following fields and values:$/) do |table|
59
+ step 'the packet has the following fields and values:', table
60
60
  end
61
61
 
62
62
  # rubocop:disable LineLength
@@ -18,7 +18,8 @@ module Pio
18
18
 
19
19
  def self.switch_version(version)
20
20
  [:Barrier, :Echo, :Features, :FlowMod, :Hello, :Match,
21
- :PacketIn, :PacketOut, :SendOutPort, :PortStatus].each do |each|
21
+ :PacketIn, :PacketOut, :SendOutPort, :PortStatus,
22
+ :FlowStats].each do |each|
22
23
  set_message_class_name each, version
23
24
  @version = version.to_s
24
25
  end
@@ -34,6 +35,8 @@ module Pio
34
35
  6 => Pio::Features::Reply,
35
36
  10 => Pio::PacketIn,
36
37
  12 => Pio::PortStatus,
38
+ 16 => Pio::FlowStats::Request,
39
+ 17 => Pio::FlowStats::Reply,
37
40
  18 => Pio::Barrier::Request,
38
41
  19 => Pio::Barrier::Reply
39
42
  }
@@ -1,3 +1,6 @@
1
+ require 'bindata'
2
+ require 'pio/parse_error'
3
+
1
4
  module Pio
2
5
  module OpenFlow
3
6
  # OpenFlow messages.
@@ -4,6 +4,8 @@ require 'pio/open_flow10/echo'
4
4
  require 'pio/open_flow10/exact_match'
5
5
  require 'pio/open_flow10/features'
6
6
  require 'pio/open_flow10/flow_mod'
7
+ require 'pio/open_flow10/flow_stats_reply'
8
+ require 'pio/open_flow10/flow_stats_request'
7
9
  require 'pio/open_flow10/hello'
8
10
  require 'pio/open_flow10/packet_in'
9
11
  require 'pio/open_flow10/packet_out'
@@ -31,21 +31,6 @@ module Pio
31
31
 
32
32
  # Message body of FlowMod.
33
33
  class Body < BinData::Record
34
- # Pio::MatchFormat wrapper.
35
- class Match < BinData::Primitive
36
- endian :big
37
-
38
- string :match, read_length: 40
39
-
40
- def set(object)
41
- self.match = object.to_binary_s
42
- end
43
-
44
- def get
45
- Pio::OpenFlow10::Match.read match
46
- end
47
- end
48
-
49
34
  extend OpenFlow::Flags
50
35
 
51
36
  flags_16bit :flags,
@@ -55,7 +40,7 @@ module Pio
55
40
 
56
41
  endian :big
57
42
 
58
- match :match
43
+ match_open_flow10 :match
59
44
  uint64 :cookie
60
45
  command :command
61
46
  uint16 :idle_timeout
@@ -0,0 +1,59 @@
1
+ require 'pio/open_flow10/actions'
2
+ require 'pio/open_flow10/stats_type'
3
+
4
+ # Base module.
5
+ module Pio
6
+ # OpenFlow 1.0 messages
7
+ module OpenFlow10
8
+ # OpenFlow 1.0 FlowStats messages
9
+ module FlowStats
10
+ # OpenFlow 1.0 Flow Stats Reply message
11
+ class Reply < OpenFlow::Message
12
+ # Body of reply to Flow Stats Request.
13
+ class FlowStatsEntry < BinData::Record
14
+ endian :big
15
+
16
+ uint16 :entry_length
17
+ uint8 :table_id
18
+ string :padding1, length: 1
19
+ hide :padding1
20
+ match_open_flow10 :match
21
+ uint32 :duration_sec
22
+ uint32 :duration_nsec
23
+ uint16 :priority
24
+ uint16 :idle_timeout
25
+ uint16 :hard_timeout
26
+ string :padding2, length: 6
27
+ hide :padding2
28
+ uint64 :cookie
29
+ uint64 :packet_count
30
+ uint64 :byte_count
31
+ actions :actions, length: -> { entry_length - 88 }
32
+ end
33
+
34
+ # Message body of Flow Stats Reply.
35
+ class Body < BinData::Record
36
+ endian :big
37
+
38
+ stats_type :stats_type, value: -> { :flow }
39
+ uint16 :flags
40
+ array(:stats,
41
+ type: :flow_stats_entry,
42
+ read_until: :eof)
43
+
44
+ def length
45
+ 4 + stats.to_binary_s.length
46
+ end
47
+ end
48
+
49
+ # OpenFlow 1.0 Flow Stats Reply message format.
50
+ class Format < BinData::Record
51
+ extend OpenFlow::Format
52
+
53
+ header version: 1, message_type: 17
54
+ body :body
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,64 @@
1
+ require 'pio/open_flow10/match'
2
+ require 'pio/open_flow10/stats_type'
3
+ require 'pio/open_flow/format'
4
+ require 'pio/open_flow/message'
5
+
6
+ # Base module.
7
+ module Pio
8
+ # OpenFlow 1.0 messages
9
+ module OpenFlow10
10
+ # OpenFlow 1.0 FlowStats messages
11
+ module FlowStats
12
+ # OpenFlow 1.0 Flow Stats Request message
13
+ class Request < OpenFlow::Message
14
+ # Body for Stats Request of type :flow
15
+ class FlowStatsRequestBody < BinData::Record
16
+ endian :big
17
+
18
+ match_open_flow10 :match
19
+ uint8 :table_id, initial_value: 0xff
20
+ string :padding, length: 1
21
+ hide :padding
22
+ port_number :out_port, initial_value: -> { :none }
23
+ end
24
+
25
+ # Message body of Flow Stats Request.
26
+ class Body < BinData::Record
27
+ endian :big
28
+
29
+ stats_type :stats_type, value: -> { :flow }
30
+ uint16 :flags
31
+ choice :stats_request_body, selection: -> { stats_type.to_s } do
32
+ flow_stats_request_body 'flow'
33
+ string :default
34
+ end
35
+
36
+ def length
37
+ 48
38
+ end
39
+
40
+ def method_missing(method, *args, &block)
41
+ stats_request_body.__send__(method, *args, &block)
42
+ end
43
+ end
44
+
45
+ # OpenFlow 1.0 Flow Stats Request message format.
46
+ class Format < BinData::Record
47
+ extend OpenFlow::Format
48
+
49
+ header version: 1, message_type: 16
50
+ body :body
51
+ end
52
+
53
+ body_option :match
54
+
55
+ def initialize(user_options = {})
56
+ validate_user_options user_options
57
+ header_options = parse_header_options(user_options)
58
+ @format = Format.new(header: header_options,
59
+ body: { stats_request_body: user_options })
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -161,5 +161,22 @@ module Pio
161
161
  @format.__send__ method, *args, &block
162
162
  end
163
163
  end
164
+
165
+ # Pio::MatchFormat wrapper.
166
+ class MatchOpenFlow10 < BinData::Primitive
167
+ endian :big
168
+
169
+ string :match,
170
+ read_length: 40,
171
+ initial_value: Pio::OpenFlow10::Match.new.to_binary_s
172
+
173
+ def set(object)
174
+ self.match = object.to_binary_s
175
+ end
176
+
177
+ def get
178
+ Pio::OpenFlow10::Match.read match
179
+ end
180
+ end
164
181
  end
165
182
  end
@@ -0,0 +1,27 @@
1
+ module Pio
2
+ module OpenFlow10
3
+ # enum ofp_stats_types
4
+ class StatsType < BinData::Primitive
5
+ STATS_TYPES = {
6
+ description: 0,
7
+ flow: 1,
8
+ aggregate: 2,
9
+ table: 3,
10
+ port: 4,
11
+ queue: 5,
12
+ vendor: 0xffff
13
+ }
14
+
15
+ endian :big
16
+ uint16 :command
17
+
18
+ def get
19
+ STATS_TYPES.invert.fetch(command)
20
+ end
21
+
22
+ def set(value)
23
+ self.command = STATS_TYPES.fetch(value)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -1,5 +1,5 @@
1
1
  # Base module.
2
2
  module Pio
3
3
  # gem version.
4
- VERSION = '0.24.2'.freeze
4
+ VERSION = '0.25.0'.freeze
5
5
  end
@@ -38,7 +38,7 @@ Gem::Specification.new do |gem|
38
38
  gem.add_development_dependency 'guard', '~> 2.13.0'
39
39
  gem.add_development_dependency 'guard-bundler', '~> 2.1.0'
40
40
  gem.add_development_dependency 'guard-cucumber', '~> 1.6.0'
41
- gem.add_development_dependency 'guard-rspec', '~> 4.6.3'
41
+ gem.add_development_dependency 'guard-rspec', '~> 4.6.4'
42
42
  gem.add_development_dependency 'guard-rubocop', '~> 1.2.0'
43
43
  gem.add_development_dependency 'rb-fchange', '~> 0.0.6'
44
44
  gem.add_development_dependency 'rb-fsevent', '~> 0.9.5'
@@ -59,5 +59,5 @@ Gem::Specification.new do |gem|
59
59
  gem.add_development_dependency 'reek', '~> 3.1'
60
60
  gem.add_development_dependency 'rspec', '~> 3.3.0'
61
61
  gem.add_development_dependency 'rspec-given', '~> 3.7.1'
62
- gem.add_development_dependency 'rubocop', '~> 0.32.1'
62
+ gem.add_development_dependency 'rubocop', '~> 0.33.0'
63
63
  end
@@ -0,0 +1,39 @@
1
+ require 'pio/open_flow10/flow_stats_reply'
2
+
3
+ describe Pio::OpenFlow10::FlowStats::Reply do
4
+ describe '.read' do
5
+ context 'with a Flow Stats Reply binary' do
6
+ Given(:binary) do
7
+ [0x01, 0x11, 0x00, 0xe4, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01,
8
+ 0x00, 0x00, 0x00, 0x68, 0x03, 0x00, 0x00, 0x3f, 0xff, 0xff,
9
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
13
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x64, 0x00, 0x05, 0x00, 0x0a,
14
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x23, 0x45, 0x67,
15
+ 0x89, 0xab, 0xcd, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
16
+ 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe8,
17
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
18
+ 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x70, 0x04, 0x00,
19
+ 0x00, 0x3f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
20
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
21
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
22
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
23
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x64,
24
+ 0x00, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
25
+ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x00, 0x00,
26
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00,
27
+ 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01,
28
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00,
29
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00, 0x00].pack('C*')
30
+ end
31
+
32
+ When(:flow_stats_reply) do
33
+ Pio::OpenFlow10::FlowStats::Reply.read(binary)
34
+ end
35
+
36
+ Then { flow_stats_reply.class == Pio::OpenFlow10::FlowStats::Reply }
37
+ end
38
+ end
39
+ end