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,76 +1,19 @@
1
- require 'forwardable'
2
- require 'pio/open_flow'
1
+ require 'pio/open_flow/echo'
3
2
 
4
3
  # Base module.
5
4
  module Pio
6
- remove_const :Echo
7
-
8
- module Echo
9
- # Base class of Echo Request and Reply.
10
- class Message
11
- def self.message_name
12
- name.split('::')[1..-1].map { |each| each.gsub(/\d+$/, '') }.join(' ')
13
- end
14
-
15
- def self.read(raw_data)
16
- allocate.tap do |message|
17
- message.instance_variable_set(:@format,
18
- const_get(:Format).read(raw_data))
19
- end
20
- rescue BinData::ValidityError
21
- raise Pio::ParseError, "Invalid #{message_name} 1.3 message."
22
- end
23
-
24
- def initialize(user_attrs = {})
25
- unknown_attrs = user_attrs.keys - [:transaction_id, :xid, :body]
26
- unless unknown_attrs.empty?
27
- fail "Unknown keyword: #{unknown_attrs.first}"
28
- end
29
- header_options = OpenFlowHeader::Options.parse(user_attrs)
30
- @format =
31
- self.class.const_get(:Format).new(open_flow_header: header_options,
32
- body: user_attrs[:body])
33
- end
34
-
35
- def method_missing(method, *args, &block)
36
- @format.__send__ method, *args, &block
37
- end
38
- end
39
-
40
- # Base class of Echo Request and Reply Format
41
- class Format < BinData::Record
42
- extend Forwardable
43
-
44
- def_delegators :open_flow_header, :ofp_version
45
- def_delegators :open_flow_header, :message_type
46
- def_delegators :open_flow_header, :message_length
47
- def_delegators :open_flow_header, :transaction_id
48
- def_delegator :open_flow_header, :transaction_id, :xid
49
-
50
- def to_binary
51
- to_binary_s
5
+ module OpenFlow13
6
+ module Echo
7
+ # OpenFlow 1.3 Echo Request message.
8
+ class Request < OpenFlow::Echo
9
+ version 4
10
+ message_type 2
52
11
  end
53
- end
54
-
55
- # OpenFlow 1.3 Echo Request message.
56
- class Request < Message
57
- # OpenFlow 1.3 Echo Request message format.
58
- class Format < Echo::Format
59
- endian :big
60
- open_flow_header :open_flow_header,
61
- ofp_version_value: 4, message_type_value: 2
62
- string :body, read_length: -> { message_length - 8 }
63
- end
64
- end
65
12
 
66
- # OpenFlow 1.3 Echo Reply message.
67
- class Reply < Message
68
- # OpenFlow 1.3 Echo Request message format.
69
- class Format < Echo::Format
70
- endian :big
71
- open_flow_header :open_flow_header,
72
- ofp_version_value: 4, message_type_value: 3
73
- string :body, read_length: -> { message_length - 8 }
13
+ # OpenFlow 1.3 Echo Reply message.
14
+ class Reply < OpenFlow::Echo
15
+ version 4
16
+ message_type 3
74
17
  end
75
18
  end
76
19
  end
@@ -1,90 +1,61 @@
1
- require 'forwardable'
2
1
  require 'pio/open_flow'
3
2
 
4
3
  # Base module.
5
4
  module Pio
6
- # OpenFlow 1.3 Features Request and Reply message.
7
- class Features
8
- remove_const :Reply
9
-
10
- # OpenFlow 1.3 Features Reply message.
11
- class Reply
12
- # OpenFlow 1.3 Features Reply message body.
13
- class Body < BinData::Record
14
- extend OpenFlow::Flags
15
-
16
- flags_32bit(:capabilities,
17
- [:flow_stats,
18
- :table_stats,
19
- :port_stats,
20
- :group_stats,
21
- :NOT_USED,
22
- :ip_reasm,
23
- :queue_stats,
24
- :NOT_USED,
25
- :port_blocked])
26
-
27
- endian :big
28
-
29
- uint64 :datapath_id
30
- uint32 :n_buffers
31
- uint8 :n_tables
32
- uint8 :auxiliary_id
33
- uint16 :padding
34
- hide :padding
35
- capabilities :capabilities
36
- uint32 :reserved
37
-
38
- def length
39
- 24
5
+ # OpenFlow 1.3 messages
6
+ module OpenFlow13
7
+ # OpenFlow 1.3 Features Request and Reply message.
8
+ class Features
9
+ # OpenFlow 1.3 Features Reply message.
10
+ class Reply < OpenFlow::Message
11
+ # OpenFlow 1.3 Features Reply message body.
12
+ class Body < BinData::Record
13
+ extend OpenFlow::Flags
14
+
15
+ flags_32bit(:capabilities,
16
+ [:flow_stats,
17
+ :table_stats,
18
+ :port_stats,
19
+ :group_stats,
20
+ :NOT_USED,
21
+ :ip_reasm,
22
+ :queue_stats,
23
+ :NOT_USED,
24
+ :port_blocked])
25
+
26
+ endian :big
27
+
28
+ datapath_id :datapath_id
29
+ uint32 :n_buffers
30
+ uint8 :n_tables
31
+ uint8 :auxiliary_id
32
+ uint16 :padding
33
+ hide :padding
34
+ capabilities :capabilities
35
+ uint32 :reserved
36
+
37
+ def length
38
+ 24
39
+ end
40
40
  end
41
- end
42
-
43
- # OpenFlow 1.3 Features Reply message format.
44
- class Format < BinData::Record
45
- extend Forwardable
46
41
 
47
- endian :big
48
- open_flow_header(:open_flow_header,
49
- ofp_version_value: 4, message_type_value: 6)
50
- body :body
42
+ # OpenFlow 1.3 Features Reply message format.
43
+ class Format < BinData::Record
44
+ extend OpenFlow::Format
51
45
 
52
- def_delegators :open_flow_header, :ofp_version
53
- def_delegators :open_flow_header, :message_type
54
- def_delegators :open_flow_header, :message_length
55
- def_delegators :open_flow_header, :transaction_id
56
- def_delegator :open_flow_header, :transaction_id, :xid
57
- def_delegators :body, :datapath_id
58
- def_delegators :body, :n_buffers
59
- def_delegators :body, :n_tables
60
- def_delegators :body, :auxiliary_id
61
- def_delegators :body, :capabilities
62
- def_delegators :body, :reserved
46
+ header version: 4, message_type: 6
47
+ body :body
63
48
 
64
- def dpid
65
- datapath_id
49
+ def dpid
50
+ datapath_id
51
+ end
66
52
  end
67
- end
68
-
69
- def self.read(raw_data)
70
- allocate.tap do |message|
71
- message.instance_variable_set(:@format, Format.read(raw_data))
72
- end
73
- rescue BinData::ValidityError
74
- raise Pio::ParseError, 'Invalid Features Reply 1.3 message.'
75
- end
76
-
77
- def initialize(user_attrs = {})
78
- header_options = OpenFlowHeader::Options.parse(user_attrs)
79
- body_options = user_attrs.dup
80
- body_options[:datapath_id] =
81
- body_options[:dpid] || body_options[:datapath_id]
82
- @format = Format.new(open_flow_header: header_options,
83
- body: body_options)
84
- end
85
53
 
86
- def method_missing(method, *args, &block)
87
- @format.__send__ method, *args, &block
54
+ body_option :dpid
55
+ body_option :datapath_id
56
+ body_option :n_buffers
57
+ body_option :n_tables
58
+ body_option :capabilities
88
59
  end
89
60
  end
90
61
  end
@@ -1,53 +1,24 @@
1
- require 'forwardable'
2
1
  require 'pio/open_flow'
3
2
 
4
3
  # Base module.
5
4
  module Pio
6
- # OpenFlow 1.3 Features Request and Reply message.
7
- class Features
8
- remove_const :Request
9
-
10
- # OpenFlow 1.3 Features Request message.
11
- class Request
12
- # OpenFlow 1.3 Features Request message format.
13
- class Format < BinData::Record
14
- extend Forwardable
15
-
16
- endian :big
17
- open_flow_header(:open_flow_header,
18
- ofp_version_value: 4, message_type_value: 5)
19
- string :body, value: ''
20
-
21
- def_delegators :open_flow_header, :ofp_version
22
- def_delegators :open_flow_header, :message_type
23
- def_delegators :open_flow_header, :message_length
24
- def_delegators :open_flow_header, :transaction_id
25
- def_delegator :open_flow_header, :transaction_id, :xid
26
-
27
- def to_binary
28
- to_binary_s
29
- end
30
- end
31
-
32
- def self.read(raw_data)
33
- allocate.tap do |message|
34
- message.instance_variable_set(:@format, Format.read(raw_data))
35
- end
36
- rescue BinData::ValidityError
37
- raise Pio::ParseError, 'Invalid Features Request 1.3 message.'
38
- end
39
-
40
- def initialize(user_attrs = {})
41
- unknown_attrs = user_attrs.keys - [:transaction_id, :xid]
42
- unless unknown_attrs.empty?
43
- fail "Unknown keyword: #{unknown_attrs.first}"
5
+ # OpenFlow 1.3 messages
6
+ module OpenFlow13
7
+ # OpenFlow 1.3 Features Request and Reply message.
8
+ class Features
9
+ # OpenFlow 1.3 Features Request message.
10
+ class Request < OpenFlow::Message
11
+ # OpenFlow 1.3 Features Request message format.
12
+ class Format < BinData::Record
13
+ extend OpenFlow::Format
14
+
15
+ header version: 4, message_type: 5
16
+ string :body, value: ''
17
+
18
+ def user_data
19
+ body
20
+ end
44
21
  end
45
- header_options = OpenFlowHeader::Options.parse(user_attrs)
46
- @format = Format.new(open_flow_header: header_options)
47
- end
48
-
49
- def method_missing(method, *args, &block)
50
- @format.__send__ method, *args, &block
51
22
  end
52
23
  end
53
24
  end
@@ -1,182 +1,159 @@
1
- require 'forwardable'
2
1
  require 'pio/open_flow'
3
2
  require 'pio/open_flow13/buffer_id'
4
3
  require 'pio/open_flow13/match'
5
4
 
6
5
  # Base module.
7
6
  module Pio
8
- remove_const :FlowMod if const_defined?(:FlowMod)
9
-
10
- # OpenFlow 1.3 FlowMod message parser and generator
11
- class FlowMod
12
- # enum ofp_flow_mod_command
13
- class Command < BinData::Primitive
14
- COMMANDS = {
15
- add: 0,
16
- modify: 1,
17
- modify_strict: 2,
18
- delete: 3,
19
- delete_strict: 4
20
- }
21
-
22
- uint8 :command
23
-
24
- def get
25
- COMMANDS.invert.fetch(command)
26
- end
7
+ module OpenFlow13
8
+ # OpenFlow 1.3 FlowMod message parser and generator
9
+ class FlowMod < OpenFlow::Message
10
+ # enum ofp_flow_mod_command
11
+ class Command < BinData::Primitive
12
+ COMMANDS = {
13
+ add: 0,
14
+ modify: 1,
15
+ modify_strict: 2,
16
+ delete: 3,
17
+ delete_strict: 4
18
+ }
19
+
20
+ uint8 :command
21
+
22
+ def get
23
+ COMMANDS.invert.fetch(command)
24
+ end
27
25
 
28
- def set(value)
29
- self.command = COMMANDS.fetch(value)
26
+ def set(value)
27
+ self.command = COMMANDS.fetch(value)
28
+ end
30
29
  end
31
- end
32
30
 
33
- # For delete commands, require matching entries to include this as
34
- # an output port.
35
- class OutPort < BinData::Primitive
36
- ANY = 0xffffffff
31
+ # For delete commands, require matching entries to include this as
32
+ # an output port.
33
+ class OutPort < BinData::Primitive
34
+ ANY = 0xffffffff
37
35
 
38
- endian :big
39
- uint32 :out_port, initial_value: ANY
36
+ endian :big
37
+ uint32 :out_port, initial_value: ANY
40
38
 
41
- def get
42
- (out_port == ANY) ? :any : out_port
43
- end
39
+ def get
40
+ (out_port == ANY) ? :any : out_port
41
+ end
44
42
 
45
- def set(value)
46
- self.out_port = (value == :any ? ANY : value)
43
+ def set(value)
44
+ self.out_port = (value == :any ? ANY : value)
45
+ end
47
46
  end
48
- end
49
47
 
50
- # For delete commands, require matching entries to include this as
51
- # an output group.
52
- class OutGroup < BinData::Primitive
53
- ANY = 0xffffffff
48
+ # For delete commands, require matching entries to include this as
49
+ # an output group.
50
+ class OutGroup < BinData::Primitive
51
+ ANY = 0xffffffff
54
52
 
55
- endian :big
56
- uint32 :out_group, initial_value: ANY
53
+ endian :big
54
+ uint32 :out_group, initial_value: ANY
57
55
 
58
- def get
59
- (out_group == ANY) ? :any : out_group
60
- end
56
+ def get
57
+ (out_group == ANY) ? :any : out_group
58
+ end
61
59
 
62
- def set(value)
63
- self.out_group = (value == :any ? ANY : value)
60
+ def set(value)
61
+ self.out_group = (value == :any ? ANY : value)
62
+ end
64
63
  end
65
- end
66
64
 
67
- # OpenFlow 1.3 instructions
68
- class Instructions < BinData::Primitive
69
- endian :big
65
+ # OpenFlow 1.3 instructions
66
+ class Instructions < BinData::Primitive
67
+ endian :big
70
68
 
71
- count_bytes_remaining :instructions_length
72
- string :instructions, read_length: :instructions_length
69
+ count_bytes_remaining :instructions_length
70
+ string :instructions, read_length: :instructions_length
73
71
 
74
- def set(object)
75
- self.instructions = [object].flatten.map(&:to_binary_s).join
76
- end
72
+ def set(object)
73
+ self.instructions = [object].flatten.map(&:to_binary_s).join
74
+ end
77
75
 
78
- # rubocop:disable MethodLength
79
- def get
80
- list = []
81
- tmp = instructions
82
- while tmp.length > 0
83
- instruction_type = BinData::Uint16be.read(tmp)
84
- instruction = case instruction_type
85
- when 1
86
- GotoTable.read(tmp)
87
- when 2
88
- WriteMetadata.read(tmp)
89
- when 4
90
- Apply.read(tmp)
91
- when 6
92
- Meter.read(tmp)
93
- else
94
- fail "Unsupported instruction #{instruction_type}"
95
- end
96
- tmp = tmp[instruction.instruction_length..-1]
97
- list << instruction
76
+ # rubocop:disable MethodLength
77
+ def get
78
+ list = []
79
+ tmp = instructions
80
+ while tmp.length > 0
81
+ instruction_type = BinData::Uint16be.read(tmp)
82
+ instruction = case instruction_type
83
+ when 1
84
+ GotoTable.read(tmp)
85
+ when 2
86
+ WriteMetadata.read(tmp)
87
+ when 4
88
+ Apply.read(tmp)
89
+ when 6
90
+ Meter.read(tmp)
91
+ else
92
+ fail "Unsupported instruction #{instruction_type}"
93
+ end
94
+ tmp = tmp[instruction.instruction_length..-1]
95
+ list << instruction
96
+ end
97
+ list
98
98
  end
99
- list
100
- end
101
- # rubocop:enable MethodLength
99
+ # rubocop:enable MethodLength
102
100
 
103
- def length
104
- instructions.length
101
+ def length
102
+ instructions.length
103
+ end
105
104
  end
106
- end
107
105
 
108
- # OpenFlow 1.3 FlowMod message body
109
- class Body < BinData::Record
110
- extend OpenFlow::Flags
111
- flags_16bit :flags,
112
- [:send_flow_rem,
113
- :check_overwrap,
114
- :reset_counts,
115
- :no_packet_counts,
116
- :no_byte_counts]
117
-
118
- endian :big
119
-
120
- uint64 :cookie
121
- uint64 :cookie_mask
122
- uint8 :table_id
123
- command :command
124
- uint16 :idle_timeout
125
- uint16 :hard_timeout
126
- uint16 :priority, initial_value: 0xffff
127
- buffer_id :buffer_id
128
- out_port :out_port
129
- out_group :out_group
130
- flags :flags
131
- string :padding, length: 2
132
- hide :padding
133
- oxm :match
134
- instructions :instructions
135
-
136
- def length
137
- 40 + match.length + instructions.length
106
+ # OpenFlow 1.3 FlowMod message body
107
+ class Body < BinData::Record
108
+ extend OpenFlow::Flags
109
+ flags_16bit :flags,
110
+ [:send_flow_rem,
111
+ :check_overwrap,
112
+ :reset_counts,
113
+ :no_packet_counts,
114
+ :no_byte_counts]
115
+
116
+ endian :big
117
+
118
+ uint64 :cookie
119
+ uint64 :cookie_mask
120
+ uint8 :table_id
121
+ command :command
122
+ uint16 :idle_timeout
123
+ uint16 :hard_timeout
124
+ uint16 :priority, initial_value: 0xffff
125
+ buffer_id :buffer_id
126
+ out_port :out_port
127
+ out_group :out_group
128
+ flags :flags
129
+ string :padding, length: 2
130
+ hide :padding
131
+ oxm :match
132
+ instructions :instructions
133
+
134
+ def length
135
+ 40 + match.length + instructions.length
136
+ end
138
137
  end
139
- end
140
-
141
- # OpenFlow 1.3 FlowMod message format
142
- class Format < BinData::Record
143
- extend Forwardable
144
-
145
- endian :big
146
-
147
- open_flow_header :open_flow_header,
148
- ofp_version_value: 4,
149
- message_type_value: OpenFlow::FLOW_MOD
150
- body :body
151
138
 
152
- def_delegators :open_flow_header, :ofp_version
153
- def_delegators :open_flow_header, :message_type
154
- def_delegators :open_flow_header, :message_length
155
- def_delegators :open_flow_header, :transaction_id
156
- def_delegator :open_flow_header, :transaction_id, :xid
139
+ # OpenFlow 1.3 FlowMod message format
140
+ class Format < BinData::Record
141
+ extend OpenFlow::Format
157
142
 
158
- alias_method :to_binary, :to_binary_s
159
-
160
- def method_missing(method, *args, &block)
161
- body.__send__ method, *args, &block
162
- end
163
- end
164
-
165
- def self.read(raw_data)
166
- allocate.tap do |message|
167
- message.instance_variable_set(:@format, Format.read(raw_data))
143
+ header version: 4, message_type: 14
144
+ body :body
168
145
  end
169
- end
170
-
171
- def initialize(user_attrs = {})
172
- header_attrs = OpenFlowHeader::Options.parse(user_attrs)
173
- body_attrs = { match: user_attrs[:match],
174
- instructions: user_attrs[:instructions] }
175
- @format = Format.new(open_flow_header: header_attrs, body: body_attrs)
176
- end
177
146
 
178
- def method_missing(method, *args, &block)
179
- @format.__send__ method, *args, &block
147
+ body_option :actions
148
+ body_option :buffer_id
149
+ body_option :command
150
+ body_option :flags
151
+ body_option :hard_timeout
152
+ body_option :idle_timeout
153
+ body_option :instructions
154
+ body_option :match
155
+ body_option :priority
156
+ body_option :table_id
180
157
  end
181
158
  end
182
159
  end