pio 0.23.1 → 0.24.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +16 -0
  3. data/README.md +2 -0
  4. data/Rakefile +1 -1
  5. data/features/open_flow10/barrier_reply.feature +58 -0
  6. data/features/open_flow10/barrier_request.feature +58 -0
  7. data/features/open_flow10/echo_reply.feature +50 -40
  8. data/features/open_flow10/echo_request.feature +54 -51
  9. data/features/open_flow10/features_reply.feature +62 -63
  10. data/features/open_flow10/features_request.feature +2 -19
  11. data/features/open_flow10/flow_mod.feature +1 -0
  12. data/features/open_flow10/hello.feature +38 -44
  13. data/features/open_flow10/packet_in.feature +1 -2
  14. data/features/open_flow10/packet_in.raw +0 -0
  15. data/features/open_flow10/packet_out.feature +14 -14
  16. data/features/open_flow10/port_status.feature +17 -17
  17. data/features/open_flow13/apply_actions.feature +15 -17
  18. data/features/open_flow13/echo_reply.feature +58 -58
  19. data/features/open_flow13/echo_request.feature +58 -58
  20. data/features/open_flow13/features_reply.feature +2 -6
  21. data/features/open_flow13/features_request.feature +3 -23
  22. data/features/open_flow13/flow_mod.feature +86 -93
  23. data/features/open_flow13/goto_table.feature +4 -4
  24. data/features/open_flow13/hello.feature +8 -15
  25. data/features/open_flow13/match.feature +14 -3
  26. data/features/open_flow13/meter.feature +3 -3
  27. data/features/open_flow13/oxm_experimenter_stratos_basic_dot11.raw +0 -0
  28. data/features/open_flow13/oxm_invalid_field.raw +0 -0
  29. data/features/open_flow13/packet_in.feature +15 -20
  30. data/features/open_flow13/packet_out.feature +39 -42
  31. data/features/open_flow13/send_out_port.feature +1 -5
  32. data/features/open_flow13/write_metadata.feature +3 -3
  33. data/features/open_flow_read.feature +43 -0
  34. data/features/open_flow_version.feature +10 -0
  35. data/features/step_definitions/open_flow_steps.rb +10 -2
  36. data/features/step_definitions/packet_data_steps.rb +4 -0
  37. data/features/support/hooks.rb +7 -0
  38. data/lib/pio.rb +1 -1
  39. data/lib/pio/monkey_patch/integer/ranges.rb +4 -0
  40. data/lib/pio/open_flow.rb +54 -16
  41. data/lib/pio/open_flow/datapath_id.rb +26 -0
  42. data/lib/pio/open_flow/echo.rb +44 -0
  43. data/lib/pio/open_flow/format.rb +45 -0
  44. data/lib/pio/open_flow/message.rb +88 -0
  45. data/lib/pio/open_flow/open_flow_header.rb +0 -14
  46. data/lib/pio/open_flow10.rb +3 -8
  47. data/lib/pio/open_flow10/actions.rb +1 -1
  48. data/lib/pio/open_flow10/barrier_reply.rb +21 -0
  49. data/lib/pio/open_flow10/barrier_request.rb +22 -0
  50. data/lib/pio/open_flow10/echo.rb +15 -11
  51. data/lib/pio/open_flow10/features.rb +99 -71
  52. data/lib/pio/open_flow10/flow_mod.rb +73 -66
  53. data/lib/pio/open_flow10/hello.rb +19 -4
  54. data/lib/pio/open_flow10/match.rb +133 -131
  55. data/lib/pio/open_flow10/packet_in.rb +55 -49
  56. data/lib/pio/open_flow10/packet_out.rb +31 -24
  57. data/lib/pio/open_flow10/port_status.rb +54 -27
  58. data/lib/pio/open_flow10/send_out_port.rb +66 -64
  59. data/lib/pio/open_flow13.rb +0 -15
  60. data/lib/pio/open_flow13/echo.rb +11 -68
  61. data/lib/pio/open_flow13/features_reply.rb +48 -77
  62. data/lib/pio/open_flow13/features_request.rb +16 -45
  63. data/lib/pio/open_flow13/flow_mod.rb +125 -148
  64. data/lib/pio/open_flow13/goto_table.rb +1 -0
  65. data/lib/pio/open_flow13/hello.rb +54 -84
  66. data/lib/pio/open_flow13/match.rb +69 -11
  67. data/lib/pio/open_flow13/meter.rb +1 -0
  68. data/lib/pio/open_flow13/packet_in.rb +38 -50
  69. data/lib/pio/open_flow13/packet_out.rb +50 -75
  70. data/lib/pio/open_flow13/send_out_port.rb +34 -34
  71. data/lib/pio/open_flow13/write_metadata.rb +1 -0
  72. data/lib/pio/parser.rb +3 -0
  73. data/lib/pio/version.rb +1 -1
  74. data/pio.gemspec +6 -6
  75. data/spec/pio/open_flow10/echo_reply_spec.rb +7 -0
  76. data/spec/pio/open_flow10/echo_request_spec.rb +7 -0
  77. data/spec/pio/open_flow10/features_reply_spec.rb +8 -0
  78. data/spec/pio/open_flow10/features_request_spec.rb +13 -0
  79. data/spec/pio/open_flow10/flow_mod_spec.rb +17 -16
  80. data/spec/pio/open_flow10/hello_spec.rb +7 -0
  81. data/spec/pio/open_flow10/match_spec.rb +8 -6
  82. data/spec/pio/open_flow10/packet_in_spec.rb +14 -0
  83. data/spec/pio/open_flow10/packet_out_spec.rb +21 -14
  84. data/spec/pio/open_flow10/send_out_port_spec.rb +4 -4
  85. data/spec/pio/open_flow10/wildcards_spec.rb +2 -2
  86. data/spec/pio/open_flow13/echo_reply_spec.rb +7 -0
  87. data/spec/pio/open_flow13/echo_request_spec.rb +7 -0
  88. data/spec/pio/open_flow13/features_reply_spec.rb +8 -0
  89. data/spec/pio/open_flow13/features_request_spec.rb +13 -0
  90. data/spec/pio/open_flow13/hello_spec.rb +14 -59
  91. data/spec/pio/open_flow13/packet_in_spec.rb +14 -0
  92. data/spec/pio/open_flow13/packet_out_spec.rb +7 -0
  93. data/spec/pio/open_flow_spec.rb +34 -0
  94. data/spec/spec_helper.rb +1 -0
  95. data/spec/support/shared_examples_for_openflow_messages.rb +75 -0
  96. metadata +215 -170
  97. data/bin/byebug +0 -16
  98. data/bin/terminal-notifier +0 -16
  99. data/lib/pio/open_flow10/message.rb +0 -78
  100. data/spec/pio/open_flow/type_spec.rb +0 -5
@@ -1,4 +1,3 @@
1
- require 'bindata'
2
1
  require 'pio/ethernet_header'
3
2
  require 'pio/ipv4_header'
4
3
  require 'pio/open_flow'
@@ -7,67 +6,74 @@ require 'pio/parser'
7
6
 
8
7
  # Base module.
9
8
  module Pio
10
- # OpenFlow 1.0 Packet-In message
11
- class PacketIn
12
- # Why is this packet being sent to the controller?
13
- # (enum ofp_packet_in_reason)
14
- class Reason < BinData::Primitive
15
- REASONS = { no_match: 0, action: 1 }
9
+ module OpenFlow10
10
+ # OpenFlow 1.0 Packet-In message
11
+ class PacketIn < OpenFlow::Message
12
+ # Why is this packet being sent to the controller?
13
+ # (enum ofp_packet_in_reason)
14
+ class Reason < BinData::Primitive
15
+ REASONS = { no_match: 0, action: 1 }
16
16
 
17
- uint8 :reason
17
+ uint8 :reason
18
18
 
19
- def get
20
- REASONS.invert.fetch(reason)
21
- end
19
+ def get
20
+ REASONS.invert.fetch(reason)
21
+ end
22
22
 
23
- def set(value)
24
- self.reason = REASONS.fetch(value)
23
+ def set(value)
24
+ self.reason = REASONS.fetch(value)
25
+ end
25
26
  end
26
- end
27
27
 
28
- # Message body of Packet-In.
29
- class Body < BinData::Record
30
- endian :big
28
+ # Message body of Packet-In.
29
+ class Body < BinData::Record
30
+ endian :big
31
31
 
32
- uint32 :buffer_id
33
- uint16 :total_len, value: -> { raw_data.length }
34
- uint16 :in_port
35
- reason :reason
36
- uint8 :padding
37
- hide :padding
38
- string :raw_data, read_length: :total_len
32
+ uint32 :buffer_id
33
+ uint16 :total_len, value: -> { raw_data.length }
34
+ uint16 :in_port
35
+ reason :reason
36
+ uint8 :padding
37
+ hide :padding
38
+ string :raw_data, read_length: :total_len
39
39
 
40
- def empty?
41
- false
42
- end
40
+ def data
41
+ @data ||= Pio::Parser.read(raw_data)
42
+ end
43
43
 
44
- def length
45
- 10 + raw_data.length
46
- end
47
- end
48
- end
44
+ def empty?
45
+ false
46
+ end
49
47
 
50
- OpenFlow::Message.factory(PacketIn, OpenFlow::PACKET_IN) do
51
- def_delegators :body, :buffer_id
52
- def_delegators :body, :total_len
53
- def_delegators :body, :in_port
54
- def_delegators :body, :reason
55
- def_delegators :body, :raw_data
48
+ def length
49
+ 10 + raw_data.length
50
+ end
56
51
 
57
- attr_accessor :datapath_id
58
- alias_method :dpid, :datapath_id
59
- alias_method :dpid=, :datapath_id=
52
+ def lldp?
53
+ data.is_a? Lldp
54
+ end
60
55
 
61
- def data
62
- @data ||= Pio::Parser.read(raw_data)
63
- end
56
+ def method_missing(method, *args)
57
+ data.__send__(method, *args).snapshot
58
+ end
59
+ end
64
60
 
65
- def lldp?
66
- data.is_a? Lldp
67
- end
61
+ # OpenFlow 1.0 Flow Mod message format.
62
+ class Format < BinData::Record
63
+ extend OpenFlow::Format
64
+
65
+ header version: 1, message_type: 10
66
+ body :body
67
+ end
68
+
69
+ attr_accessor :datapath_id
70
+ alias_method :dpid, :datapath_id
71
+ alias_method :dpid=, :datapath_id=
68
72
 
69
- def method_missing(method, *args)
70
- data.__send__(method, *args).snapshot
73
+ body_option :buffer_id
74
+ body_option :in_port
75
+ body_option :reason
76
+ body_option :raw_data
71
77
  end
72
78
  end
73
79
  end
@@ -1,35 +1,42 @@
1
- require 'bindata'
2
1
  require 'pio/open_flow'
2
+ require 'pio/open_flow10/actions'
3
3
 
4
4
  # Base module.
5
5
  module Pio
6
- # OpenFlow 1.0 Packet-Out message
7
- class PacketOut
8
- # Message body of Packet-Out
9
- class Body < BinData::Record
10
- endian :big
6
+ module OpenFlow10
7
+ # OpenFlow 1.0 Packet-Out message
8
+ class PacketOut < OpenFlow::Message
9
+ # OpenFlow 1.0 Flow Mod message format.
10
+ class Format < BinData::Record
11
+ # Message body of Packet-Out
12
+ class Body < BinData::Record
13
+ endian :big
11
14
 
12
- uint32 :buffer_id
13
- uint16 :in_port
14
- uint16 :actions_len, initial_value: -> { actions.binary.length }
15
- actions :actions, length: -> { actions_len }
16
- rest :raw_data
15
+ uint32 :buffer_id
16
+ uint16 :in_port
17
+ uint16 :actions_len, initial_value: -> { actions.binary.length }
18
+ actions :actions, length: -> { actions_len }
19
+ rest :raw_data
17
20
 
18
- def empty?
19
- false
20
- end
21
+ def empty?
22
+ false
23
+ end
24
+
25
+ def length
26
+ 8 + actions_len + raw_data.length
27
+ end
28
+ end
29
+
30
+ extend OpenFlow::Format
21
31
 
22
- def length
23
- 8 + actions_len + raw_data.length
32
+ header version: 1, message_type: 13
33
+ body :body
24
34
  end
25
- end
26
- end
27
35
 
28
- OpenFlow::Message.factory(PacketOut, OpenFlow::PACKET_OUT) do
29
- def_delegators :body, :buffer_id
30
- def_delegators :body, :in_port
31
- def_delegators :body, :actions_len
32
- def_delegators :body, :actions
33
- def_delegators :body, :raw_data
36
+ body_option :buffer_id
37
+ body_option :in_port
38
+ body_option :actions
39
+ body_option :raw_data
40
+ end
34
41
  end
35
42
  end
@@ -2,43 +2,70 @@ require 'pio/open_flow'
2
2
 
3
3
  # Base module.
4
4
  module Pio
5
- # OpenFlow 1.0 Port Status message
6
- class PortStatus
7
- # What changed about the physical port
8
- class Reason < BinData::Primitive
9
- REASONS = { add: 0, delete: 1, modify: 2 }
5
+ # OpenFlow 1.0 messages
6
+ module OpenFlow10
7
+ # OpenFlow 1.0 Port Status message
8
+ class PortStatus < OpenFlow::Message
9
+ # What changed about the physical port
10
+ class Reason < BinData::Primitive
11
+ REASONS = { add: 0, delete: 1, modify: 2 }
10
12
 
11
- uint8 :reason
13
+ uint8 :reason
12
14
 
13
- def get
14
- REASONS.invert.fetch(reason)
15
+ def get
16
+ REASONS.invert.fetch(reason)
17
+ end
18
+
19
+ def set(value)
20
+ self.reason = REASONS.fetch(value)
21
+ end
15
22
  end
16
23
 
17
- def set(value)
18
- self.reason = REASONS.fetch(value)
24
+ # Message body of Port Status
25
+ class Body < BinData::Record
26
+ endian :big
27
+
28
+ reason :reason
29
+ uint56 :padding
30
+ hide :padding
31
+ phy_port :desc
19
32
  end
20
- end
21
33
 
22
- # Message body of Port Status
23
- class Body < BinData::Record
24
- endian :big
34
+ # OpenFlow 1.0 Flow Mod message format.
35
+ class Format < BinData::Record
36
+ extend OpenFlow::Format
25
37
 
26
- reason :reason
27
- uint56 :padding
28
- hide :padding
29
- phy_port :desc
30
- end
31
- end
38
+ header version: 1, message_type: 12
39
+ body :body
32
40
 
33
- OpenFlow::Message.factory(PortStatus, OpenFlow::PORT_STATUS) do
34
- def_delegators :body, :reason
41
+ def reason
42
+ body.reason.to_sym
43
+ end
44
+ end
45
+
46
+ attr_writer :datapath_id
35
47
 
36
- attr_writer :datapath_id
48
+ def desc
49
+ @desc ||= @format.body.desc.snapshot
50
+ @desc.instance_variable_set :@datapath_id, @datapath_id
51
+ @desc
52
+ end
37
53
 
38
- def desc
39
- @desc ||= @format.body.desc.snapshot
40
- @desc.instance_variable_set :@datapath_id, @datapath_id
41
- @desc
54
+ # rubocop:disable MethodLength
55
+ def initialize(user_options = {})
56
+ header_options = parse_header_options(user_options)
57
+ body_options = if user_options.respond_to?(:fetch)
58
+ user_options.delete :transaction_id
59
+ user_options.delete :xid
60
+ dpid = user_options[:dpid]
61
+ user_options[:datapath_id] = dpid if dpid
62
+ user_options
63
+ else
64
+ ''
65
+ end
66
+ @format = Format.new(header: header_options, body: body_options)
67
+ end
68
+ # rubocop:enable MethodLength
42
69
  end
43
70
  end
44
71
  end
@@ -4,77 +4,79 @@ require 'pio/monkey_patch/integer'
4
4
  require 'pio/open_flow/port_number'
5
5
 
6
6
  module Pio
7
- # An action to output a packet to a port.
8
- class SendOutPort
9
- # OpenFlow 1.0 OFPAT_OUTPUT action format.
10
- class Format < BinData::Record
11
- endian :big
7
+ module OpenFlow10
8
+ # An action to output a packet to a port.
9
+ class SendOutPort
10
+ # OpenFlow 1.0 OFPAT_OUTPUT action format.
11
+ class Format < BinData::Record
12
+ endian :big
12
13
 
13
- uint16 :type, value: 0
14
- uint16 :message_length, value: 8
15
- port_number :port_number
16
- uint16 :max_len, initial_value: 2**16 - 1
17
- end
14
+ uint16 :type, value: 0
15
+ uint16 :message_length, value: 8
16
+ port_number :port_number
17
+ uint16 :max_len, initial_value: 2**16 - 1
18
+ end
18
19
 
19
- def self.read(raw_data)
20
- send_out_port = allocate
21
- send_out_port.instance_variable_set :@format, Format.read(raw_data)
22
- send_out_port
23
- end
20
+ def self.read(raw_data)
21
+ send_out_port = allocate
22
+ send_out_port.instance_variable_set :@format, Format.read(raw_data)
23
+ send_out_port
24
+ end
24
25
 
25
- extend Forwardable
26
+ extend Forwardable
26
27
 
27
- def_delegators :@format, :message_length
28
- def_delegators :@format, :port_number
29
- def_delegators :@format, :max_len
30
- def_delegator :@format, :to_binary_s, :to_binary
28
+ def_delegators :@format, :message_length
29
+ def_delegators :@format, :port_number
30
+ def_delegators :@format, :max_len
31
+ def_delegator :@format, :to_binary_s, :to_binary
31
32
 
32
- # Creates an action to output a packet to a port.
33
- #
34
- # @example
35
- # SendOutPort.new(1)
36
- # SendOutPort.new(port_number: 1)
37
- # SendOutPort.new(port_number: :controller, max_len: 256)
38
- #
39
- # @param [Integer|Hash] user_options
40
- # the port number or the options hash to create this action
41
- # class instance with.
42
- #
43
- # @option user_options [Number] :port_number
44
- # port number an index into switch's physical port list. There
45
- # are also fake output ports. For example a port number set to
46
- # +:flood+ would output packets to all physical ports except
47
- # input port and ports disabled by STP.
48
- # @option user_options [Number] :max_len
49
- # the maximum number of bytes from a packet to send to
50
- # controller when port is set to +:controller+. A zero length
51
- # means no bytes of the packet should be sent. It defaults to
52
- # 64K.
53
- #
54
- # @raise [ArgumentError] if +:port_number+ is not an unsigned
55
- # 16-bit integer.
56
- # @raise [ArgumentError] if +:max_len+ is not an unsigned 16-bit integer.
57
- #
58
- # rubocop:disable MethodLength
59
- def initialize(user_options)
60
- options = if user_options.respond_to?(:to_i)
61
- { port_number: user_options.to_i }
62
- elsif PortNumber::NUMBERS.key?(user_options)
63
- { port_number: user_options }
64
- else
65
- user_options
66
- end
67
- max_len = options[:max_len]
68
- if max_len && !max_len.unsigned_16bit?
69
- fail ArgumentError, 'The max_len should be an unsigned 16bit integer.'
33
+ # Creates an action to output a packet to a port.
34
+ #
35
+ # @example
36
+ # SendOutPort.new(1)
37
+ # SendOutPort.new(port_number: 1)
38
+ # SendOutPort.new(port_number: :controller, max_len: 256)
39
+ #
40
+ # @param [Integer|Hash] user_options
41
+ # the port number or the options hash to create this action
42
+ # class instance with.
43
+ #
44
+ # @option user_options [Number] :port_number
45
+ # port number an index into switch's physical port list. There
46
+ # are also fake output ports. For example a port number set to
47
+ # +:flood+ would output packets to all physical ports except
48
+ # input port and ports disabled by STP.
49
+ # @option user_options [Number] :max_len
50
+ # the maximum number of bytes from a packet to send to
51
+ # controller when port is set to +:controller+. A zero length
52
+ # means no bytes of the packet should be sent. It defaults to
53
+ # 64K.
54
+ #
55
+ # @raise [ArgumentError] if +:port_number+ is not an unsigned
56
+ # 16-bit integer.
57
+ # @raise [ArgumentError] if +:max_len+ is not an unsigned 16-bit integer.
58
+ #
59
+ # rubocop:disable MethodLength
60
+ def initialize(user_options)
61
+ options = if user_options.respond_to?(:to_i)
62
+ { port_number: user_options.to_i }
63
+ elsif PortNumber::NUMBERS.key?(user_options)
64
+ { port_number: user_options }
65
+ else
66
+ user_options
67
+ end
68
+ max_len = options[:max_len]
69
+ if max_len && !max_len.unsigned_16bit?
70
+ fail ArgumentError, 'The max_len should be an unsigned 16bit integer.'
71
+ end
72
+ @format = Format.new(options)
70
73
  end
71
- @format = Format.new(options)
72
- end
73
- # rubocop:enable MethodLength
74
+ # rubocop:enable MethodLength
74
75
 
75
- def ==(other)
76
- return false unless other
77
- to_binary == other.to_binary
76
+ def ==(other)
77
+ return false unless other
78
+ to_binary == other.to_binary
79
+ end
78
80
  end
79
81
  end
80
82
  end
@@ -1,11 +1,3 @@
1
- module Pio
2
- # OpenFlow specific types.
3
- module OpenFlow
4
- remove_const :VERSION
5
- VERSION = 4
6
- end
7
- end
8
-
9
1
  require 'pio/open_flow13/apply'
10
2
  require 'pio/open_flow13/echo'
11
3
  require 'pio/open_flow13/features_reply'
@@ -13,15 +5,8 @@ require 'pio/open_flow13/features_request'
13
5
  require 'pio/open_flow13/flow_mod'
14
6
  require 'pio/open_flow13/goto_table'
15
7
  require 'pio/open_flow13/hello'
16
- require 'pio/open_flow13/match'
17
8
  require 'pio/open_flow13/meter'
18
9
  require 'pio/open_flow13/packet_in'
19
10
  require 'pio/open_flow13/packet_out'
20
11
  require 'pio/open_flow13/send_out_port'
21
12
  require 'pio/open_flow13/write_metadata'
22
-
23
- # Base module.
24
- module Pio
25
- remove_const :Match
26
- Match = OpenFlow13::Match
27
- end