Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add offset and n_bits options to NiciraRegMove #287

Merged
merged 2 commits into from
Nov 19, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Rakefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require 'bundler/gem_tasks'

RELISH_PROJECT = 'trema/pio'
FLAY_THRESHOLD = 1343
FLAY_THRESHOLD = 1204

task default: :travis
task test: [:spec, :cucumber]
Expand Down
65 changes: 37 additions & 28 deletions features/open_flow13/nicira_reg_move.feature
Original file line number Diff line number Diff line change
@@ -1,42 +1,51 @@
@open_flow13
Feature: Pio::NiciraRegMove

Scenario: new(from: :arp_sender_hardware_address, to: :arp_target_hardware_address)
Copies source[source_offset:sourcce_offset+n_bits] to
destination[destination_offset:dst_ofs+n_bits], where a[b:c] denotes
the bits within 'a' numbered 'b' through 'c' (not including bit 'c').

Scenario: new(source: :arp_sender_hardware_address, destination: :arp_target_hardware_address)
When I try to create an OpenFlow action with:
"""
Pio::NiciraRegMove.new(from: :arp_sender_hardware_address, to: :arp_target_hardware_address)
Pio::NiciraRegMove.new(source: :arp_sender_hardware_address,
destination: :arp_target_hardware_address)
"""
Then it should finish successfully
And the action has the following fields and values:
| field | value |
| action_type.to_hex | 0xffff |
| action_length | 24 |
| experimenter_id.to_hex | 0x2320 |
| experimenter_type | 6 |
| from | :arp_sender_hardware_address |
| source_oxm_field | 24 |
| source_oxm_length | 6 |
| to | :arp_target_hardware_address |
| destination_oxm_field | 25 |
| destination_oxm_length | 6 |
| field | value |
| n_bits | 48 |
| source | :arp_sender_hardware_address |
| source_offset | 0 |
| destination | :arp_target_hardware_address |
| destination_offset | 0 |

Scenario: new(from: :reg0, to: :reg7)
Scenario: new(source: :reg0, destination: :reg7)
When I try to create an OpenFlow action with:
"""
Pio::NiciraRegMove.new(source: :reg0, destination: :reg7)
"""
Then it should finish successfully
And the action has the following fields and values:
| field | value |
| n_bits | 32 |
| source | :reg0 |
| source_offset | 0 |
| destination | :reg7 |
| destination_offset | 0 |

Scenario: new(source: :reg0, source_offset: 16, destination: :reg7, destination_offset: 16, n_bits: 16)
When I try to create an OpenFlow action with:
"""
Pio::NiciraRegMove.new(from: :reg0, to: :reg7)
Pio::NiciraRegMove.new(source: :reg0, source_offset: 16,
destination: :reg7, destination_offset: 16,
n_bits: 16)
"""
Then it should finish successfully
And the action has the following fields and values:
| field | value |
| action_type.to_hex | 0xffff |
| action_length | 24 |
| experimenter_id.to_hex | 0x2320 |
| experimenter_type | 6 |
| from | :reg0 |
| source_oxm_class | 1 |
| source_oxm_field | 0 |
| source_oxm_length | 4 |
| to | :reg7 |
| destination_oxm_class | 1 |
| destination_oxm_field | 7 |
| destination_oxm_length | 4 |
| field | value |
| n_bits | 16 |
| source | :reg0 |
| source_offset | 16 |
| destination | :reg7 |
| destination_offset | 16 |
15 changes: 5 additions & 10 deletions features/open_flow13/nicira_send_out_port.feature
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,8 @@ Feature: Pio::NiciraSendOutPort
"""
Then it should finish successfully
And the action has the following fields and values:
| field | value |
| action_type.to_hex | 0xffff |
| action_length | 24 |
| experimenter_id.to_hex | 0x2320 |
| experimenter_type | 15 |
| offset | 0 |
| source | :reg0 |
| max_length | 0 |


| field | value |
| offset | 0 |
| n_bits | 32 |
| source | :reg0 |
| max_length | 0 |
2 changes: 1 addition & 1 deletion lib/pio/open_flow13/nicira_reg_load.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def value
private

def oxm_class
destination_oxm_class.superclass.const_get(:OXM_CLASS)
destination_oxm_class.const_get(:OXM_CLASS)
end

def oxm_field
Expand Down
112 changes: 77 additions & 35 deletions lib/pio/open_flow13/nicira_reg_move.rb
Original file line number Diff line number Diff line change
@@ -1,42 +1,84 @@
require 'active_support/core_ext/string/inflections'
require 'pio/open_flow/action'
require 'pio/open_flow/nicira_action'
require 'pio/open_flow13/match'

module Pio
module OpenFlow13
# NXAST_REG_MOVE action
class NiciraRegMove < OpenFlow::Action
action_header action_type: 0xffff, action_length: 24
uint32 :experimenter_id, value: 0x2320
uint16 :experimenter_type, value: 6
uint16 :n_bits, initial_value: -> { source_oxm_length * 8 }
uint16 :source_offset, value: 0
uint16 :destination_offset, value: 0
uint16 :source_oxm_class
bit7 :source_oxm_field
bit1 :source_oxm_hasmask, value: 0
uint8 :source_oxm_length
uint16 :destination_oxm_class
bit7 :destination_oxm_field
bit1 :destination_oxm_hasmask, value: 0
uint8 :destination_oxm_length

attr_reader :from
attr_reader :to

# rubocop:disable AbcSize
def initialize(options)
@from = options.fetch(:from)
@to = options.fetch(:to)
from_klass = Match.const_get(@from.to_s.classify)
to_klass = Match.const_get(@to.to_s.classify)
super(source_oxm_class: from_klass.superclass.const_get(:OXM_CLASS),
source_oxm_field: from_klass.const_get(:OXM_FIELD),
source_oxm_length: from_klass.new.length,
destination_oxm_class: to_klass.superclass.const_get(:OXM_CLASS),
destination_oxm_field: to_klass.const_get(:OXM_FIELD),
destination_oxm_length: to_klass.new.length)
end
# rubocop:enable AbcSize
class NiciraRegMove < OpenFlow::NiciraAction
nicira_action_header action_type: 0xffff,
action_length: 24,
subtype: 6
uint16 :n_bits, initial_value: -> { _source[:oxm_length] * 8 }
uint16 :source_offset, initial_value: 0
uint16 :destination_offset, initial_value: 0
struct :_source do
uint16 :oxm_class
bit7 :oxm_field
bit1 :oxm_hasmask, value: 0
uint8 :oxm_length
end
struct :_destination do
uint16 :oxm_class
bit7 :oxm_field
bit1 :oxm_hasmask, value: 0
uint8 :oxm_length
end

# rubocop:disable MethodLength
def initialize(arguments)
@source = arguments.fetch(:source)
@destination = arguments.fetch(:destination)
registers = { _source: { oxm_class: source_oxm_class,
oxm_field: source_oxm_field,
oxm_length: source_oxm_length },
_destination: { oxm_class: destination_oxm_class,
oxm_field: destination_oxm_field,
oxm_length: destination_oxm_length } }
options = [:n_bits,
:source_offset,
:destination_offset].each_with_object({}) do |each, opts|
opts[each] = arguments[each] if arguments[each]
end
super registers.merge(options)
end
# rubocop:enable MethodLength

attr_reader :source
attr_reader :destination

private

def source_oxm_class
source_class.const_get(:OXM_CLASS)
end

def source_oxm_field
source_class.const_get(:OXM_FIELD)
end

def source_oxm_length
source_class.new.length
end

def source_class
Match.const_get(@source.to_s.split('_').map(&:capitalize).join)
end

def destination_oxm_class
destination_class.const_get(:OXM_CLASS)
end

def destination_oxm_field
destination_class.const_get(:OXM_FIELD)
end

def destination_oxm_length
destination_class.new.length
end

def destination_class
Match.const_get(@destination.to_s.split('_').map(&:capitalize).join)
end
end
end
end
58 changes: 39 additions & 19 deletions lib/pio/open_flow13/nicira_send_out_port.rb
Original file line number Diff line number Diff line change
@@ -1,37 +1,57 @@
require 'pio/open_flow/action'
require 'pio/open_flow/nicira_action'
require 'pio/open_flow13/match'

module Pio
module OpenFlow13
# NXAST_OUTPUT_REG action
class NiciraSendOutPort < OpenFlow::Action
action_header action_type: 0xffff, action_length: 24
uint32 :experimenter_id, value: 0x2320
uint16 :experimenter_type, value: 15
bit10 :offset_internal, value: 0
bit6 :n_bits_internal
uint32 :source_internal
class NiciraSendOutPort < OpenFlow::NiciraAction
nicira_action_header action_type: 0xffff,
action_length: 24,
subtype: 15
bit10 :_offset, value: 0
bit6 :_n_bits
struct :_source do
uint16 :oxm_class
bit9 :oxm_field
bit7 :oxm_length
end
uint16 :max_length, value: 0
string :zero, length: 6

attr_reader :source

# rubocop:disable AbcSize
# rubocop:disable LineLength
def initialize(source)
@source = source
oxm_klass = Match.const_get(source.to_s.split('_').map(&:capitalize).join)
super(n_bits_internal: oxm_klass.new.length * 8 - 1,
source_internal: ((oxm_klass.superclass.const_get(:OXM_CLASS) << 16) | (oxm_klass.const_get(:OXM_FIELD) << 9) | oxm_klass.new.length))
super(_n_bits: oxm_length * 8 - 1,
_source: { oxm_class: oxm_class,
oxm_field: oxm_field,
oxm_length: oxm_length })
end
# rubocop:enable AbcSize
# rubocop:enable LineLength

attr_reader :source

def offset
offset_internal
_offset
end

def n_bits
n_bits_internal + 1
_n_bits + 1
end

private

def oxm_class
source_oxm_class.const_get(:OXM_CLASS)
end

def oxm_field
source_oxm_class.const_get(:OXM_FIELD)
end

def oxm_length
source_oxm_class.new.length
end

def source_oxm_class
Match.const_get(@source.to_s.split('_').map(&:capitalize).join)
end
end
end
Expand Down
40 changes: 40 additions & 0 deletions spec/pio/open_flow13/nicira_reg_move_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
require 'pio/open_flow13/nicira_reg_move'

describe Pio::OpenFlow13::NiciraRegMove do
describe '.new' do
When(:nicira_reg_move) do
Pio::OpenFlow13::NiciraRegMove.new(options)
end

context 'with source: :arp_sender_hardware_address,'\
' destination: :arp_target_hardware_address' do
Given(:options) do
{ source: :arp_sender_hardware_address,
destination: :arp_target_hardware_address }
end

Invariant do
nicira_reg_move.n_bits ==
nicira_reg_move._source[:oxm_length] * 8
end

Then { nicira_reg_move.action_type == 0xffff }
Then { nicira_reg_move.action_length == 24 }
Then { nicira_reg_move.vendor == 0x2320 }
Then { nicira_reg_move.subtype == 6 }
Then { nicira_reg_move.n_bits == 48 }
Then { nicira_reg_move.source_offset == 0 }
Then { nicira_reg_move.destination_offset == 0 }
Then { nicira_reg_move.source == :arp_sender_hardware_address }
Then { nicira_reg_move._source[:oxm_class] == 0x8000 }
Then { nicira_reg_move._source[:oxm_field] == 24 }
Then { nicira_reg_move._source[:oxm_hasmask] == 0 }
Then { nicira_reg_move._source[:oxm_length] == 6 }
Then { nicira_reg_move.destination == :arp_target_hardware_address }
Then { nicira_reg_move._destination[:oxm_class] == 0x8000 }
Then { nicira_reg_move._destination[:oxm_field] == 25 }
Then { nicira_reg_move._destination[:oxm_hasmask] == 0 }
Then { nicira_reg_move._destination[:oxm_length] == 6 }
end
end
end
29 changes: 29 additions & 0 deletions spec/pio/open_flow13/nicira_send_out_port_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
require 'pio/open_flow13/nicira_send_out_port'

describe Pio::OpenFlow13::NiciraSendOutPort do
describe '.new' do
When(:nicira_send_out_port) do
Pio::OpenFlow13::NiciraSendOutPort.new(source)
end

context 'with :reg0' do
Given(:source) { :reg0 }

Invariant do
nicira_send_out_port.n_bits ==
nicira_send_out_port._source[:oxm_length] * 8
end

Then { nicira_send_out_port.action_type == 0xffff }
Then { nicira_send_out_port.action_length == 24 }
Then { nicira_send_out_port.vendor == 0x2320 }
Then { nicira_send_out_port.subtype == 15 }
Then { nicira_send_out_port.offset == 0 }
Then { nicira_send_out_port.n_bits == 32 }
Then { nicira_send_out_port.source == :reg0 }
Then { nicira_send_out_port._source[:oxm_class] == 1 }
Then { nicira_send_out_port._source[:oxm_field] == 0 }
Then { nicira_send_out_port._source[:oxm_length] == 4 }
end
end
end