pio 0.23.1 → 0.24.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 +16 -0
- data/README.md +2 -0
- data/Rakefile +1 -1
- data/features/open_flow10/barrier_reply.feature +58 -0
- data/features/open_flow10/barrier_request.feature +58 -0
- data/features/open_flow10/echo_reply.feature +50 -40
- data/features/open_flow10/echo_request.feature +54 -51
- data/features/open_flow10/features_reply.feature +62 -63
- data/features/open_flow10/features_request.feature +2 -19
- data/features/open_flow10/flow_mod.feature +1 -0
- data/features/open_flow10/hello.feature +38 -44
- data/features/open_flow10/packet_in.feature +1 -2
- data/features/open_flow10/packet_in.raw +0 -0
- data/features/open_flow10/packet_out.feature +14 -14
- data/features/open_flow10/port_status.feature +17 -17
- data/features/open_flow13/apply_actions.feature +15 -17
- data/features/open_flow13/echo_reply.feature +58 -58
- data/features/open_flow13/echo_request.feature +58 -58
- data/features/open_flow13/features_reply.feature +2 -6
- data/features/open_flow13/features_request.feature +3 -23
- data/features/open_flow13/flow_mod.feature +86 -93
- data/features/open_flow13/goto_table.feature +4 -4
- data/features/open_flow13/hello.feature +8 -15
- data/features/open_flow13/match.feature +14 -3
- data/features/open_flow13/meter.feature +3 -3
- data/features/open_flow13/oxm_experimenter_stratos_basic_dot11.raw +0 -0
- data/features/open_flow13/oxm_invalid_field.raw +0 -0
- data/features/open_flow13/packet_in.feature +15 -20
- data/features/open_flow13/packet_out.feature +39 -42
- data/features/open_flow13/send_out_port.feature +1 -5
- data/features/open_flow13/write_metadata.feature +3 -3
- data/features/open_flow_read.feature +43 -0
- data/features/open_flow_version.feature +10 -0
- data/features/step_definitions/open_flow_steps.rb +10 -2
- data/features/step_definitions/packet_data_steps.rb +4 -0
- data/features/support/hooks.rb +7 -0
- data/lib/pio.rb +1 -1
- data/lib/pio/monkey_patch/integer/ranges.rb +4 -0
- data/lib/pio/open_flow.rb +54 -16
- data/lib/pio/open_flow/datapath_id.rb +26 -0
- data/lib/pio/open_flow/echo.rb +44 -0
- data/lib/pio/open_flow/format.rb +45 -0
- data/lib/pio/open_flow/message.rb +88 -0
- data/lib/pio/open_flow/open_flow_header.rb +0 -14
- data/lib/pio/open_flow10.rb +3 -8
- data/lib/pio/open_flow10/actions.rb +1 -1
- data/lib/pio/open_flow10/barrier_reply.rb +21 -0
- data/lib/pio/open_flow10/barrier_request.rb +22 -0
- data/lib/pio/open_flow10/echo.rb +15 -11
- data/lib/pio/open_flow10/features.rb +99 -71
- data/lib/pio/open_flow10/flow_mod.rb +73 -66
- data/lib/pio/open_flow10/hello.rb +19 -4
- data/lib/pio/open_flow10/match.rb +133 -131
- data/lib/pio/open_flow10/packet_in.rb +55 -49
- data/lib/pio/open_flow10/packet_out.rb +31 -24
- data/lib/pio/open_flow10/port_status.rb +54 -27
- data/lib/pio/open_flow10/send_out_port.rb +66 -64
- data/lib/pio/open_flow13.rb +0 -15
- data/lib/pio/open_flow13/echo.rb +11 -68
- data/lib/pio/open_flow13/features_reply.rb +48 -77
- data/lib/pio/open_flow13/features_request.rb +16 -45
- data/lib/pio/open_flow13/flow_mod.rb +125 -148
- data/lib/pio/open_flow13/goto_table.rb +1 -0
- data/lib/pio/open_flow13/hello.rb +54 -84
- data/lib/pio/open_flow13/match.rb +69 -11
- data/lib/pio/open_flow13/meter.rb +1 -0
- data/lib/pio/open_flow13/packet_in.rb +38 -50
- data/lib/pio/open_flow13/packet_out.rb +50 -75
- data/lib/pio/open_flow13/send_out_port.rb +34 -34
- data/lib/pio/open_flow13/write_metadata.rb +1 -0
- data/lib/pio/parser.rb +3 -0
- data/lib/pio/version.rb +1 -1
- data/pio.gemspec +6 -6
- data/spec/pio/open_flow10/echo_reply_spec.rb +7 -0
- data/spec/pio/open_flow10/echo_request_spec.rb +7 -0
- data/spec/pio/open_flow10/features_reply_spec.rb +8 -0
- data/spec/pio/open_flow10/features_request_spec.rb +13 -0
- data/spec/pio/open_flow10/flow_mod_spec.rb +17 -16
- data/spec/pio/open_flow10/hello_spec.rb +7 -0
- data/spec/pio/open_flow10/match_spec.rb +8 -6
- data/spec/pio/open_flow10/packet_in_spec.rb +14 -0
- data/spec/pio/open_flow10/packet_out_spec.rb +21 -14
- data/spec/pio/open_flow10/send_out_port_spec.rb +4 -4
- data/spec/pio/open_flow10/wildcards_spec.rb +2 -2
- data/spec/pio/open_flow13/echo_reply_spec.rb +7 -0
- data/spec/pio/open_flow13/echo_request_spec.rb +7 -0
- data/spec/pio/open_flow13/features_reply_spec.rb +8 -0
- data/spec/pio/open_flow13/features_request_spec.rb +13 -0
- data/spec/pio/open_flow13/hello_spec.rb +14 -59
- data/spec/pio/open_flow13/packet_in_spec.rb +14 -0
- data/spec/pio/open_flow13/packet_out_spec.rb +7 -0
- data/spec/pio/open_flow_spec.rb +34 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/support/shared_examples_for_openflow_messages.rb +75 -0
- metadata +215 -170
- data/bin/byebug +0 -16
- data/bin/terminal-notifier +0 -16
- data/lib/pio/open_flow10/message.rb +0 -78
- 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
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
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
|
-
|
17
|
+
uint8 :reason
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
def get
|
20
|
+
REASONS.invert.fetch(reason)
|
21
|
+
end
|
22
22
|
|
23
|
-
|
24
|
-
|
23
|
+
def set(value)
|
24
|
+
self.reason = REASONS.fetch(value)
|
25
|
+
end
|
25
26
|
end
|
26
|
-
end
|
27
27
|
|
28
|
-
|
29
|
-
|
30
|
-
|
28
|
+
# Message body of Packet-In.
|
29
|
+
class Body < BinData::Record
|
30
|
+
endian :big
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
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
|
-
|
41
|
-
|
42
|
-
|
40
|
+
def data
|
41
|
+
@data ||= Pio::Parser.read(raw_data)
|
42
|
+
end
|
43
43
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
end
|
48
|
-
end
|
44
|
+
def empty?
|
45
|
+
false
|
46
|
+
end
|
49
47
|
|
50
|
-
|
51
|
-
|
52
|
-
|
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
|
-
|
58
|
-
|
59
|
-
|
52
|
+
def lldp?
|
53
|
+
data.is_a? Lldp
|
54
|
+
end
|
60
55
|
|
61
|
-
|
62
|
-
|
63
|
-
|
56
|
+
def method_missing(method, *args)
|
57
|
+
data.__send__(method, *args).snapshot
|
58
|
+
end
|
59
|
+
end
|
64
60
|
|
65
|
-
|
66
|
-
|
67
|
-
|
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
|
-
|
70
|
-
|
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
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
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
|
-
|
19
|
-
|
20
|
-
|
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
|
-
|
23
|
-
|
32
|
+
header version: 1, message_type: 13
|
33
|
+
body :body
|
24
34
|
end
|
25
|
-
end
|
26
|
-
end
|
27
35
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
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
|
6
|
-
|
7
|
-
#
|
8
|
-
class
|
9
|
-
|
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
|
-
|
13
|
+
uint8 :reason
|
12
14
|
|
13
|
-
|
14
|
-
|
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
|
-
|
18
|
-
|
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
|
-
|
23
|
-
|
24
|
-
|
34
|
+
# OpenFlow 1.0 Flow Mod message format.
|
35
|
+
class Format < BinData::Record
|
36
|
+
extend OpenFlow::Format
|
25
37
|
|
26
|
-
|
27
|
-
|
28
|
-
hide :padding
|
29
|
-
phy_port :desc
|
30
|
-
end
|
31
|
-
end
|
38
|
+
header version: 1, message_type: 12
|
39
|
+
body :body
|
32
40
|
|
33
|
-
|
34
|
-
|
41
|
+
def reason
|
42
|
+
body.reason.to_sym
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
attr_writer :datapath_id
|
35
47
|
|
36
|
-
|
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
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
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
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
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
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
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
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
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
|
-
|
26
|
+
extend Forwardable
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
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
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
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
|
-
|
72
|
-
end
|
73
|
-
# rubocop:enable MethodLength
|
74
|
+
# rubocop:enable MethodLength
|
74
75
|
|
75
|
-
|
76
|
-
|
77
|
-
|
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
|
data/lib/pio/open_flow13.rb
CHANGED
@@ -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
|