Skip to content

Commit

Permalink
Refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
yasuhito committed Jul 12, 2016
1 parent e3f0a6d commit 5b60203
Show file tree
Hide file tree
Showing 19 changed files with 89 additions and 357 deletions.
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'.freeze
FLAY_THRESHOLD = 1386
FLAY_THRESHOLD = 1418

task default: :travis
task test: [:spec, :cucumber]
Expand Down
2 changes: 1 addition & 1 deletion features/open_flow13/packet_out.feature
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,5 @@ Feature: PacketOut
| operation | 1 |
| sender_hardware_address | ac:5d:10:31:37:79 |
| sender_protocol_address | 192.168.2.254 |
| target_hardware_address | ff:ff:ff:ff:ff:ff |
| target_hardware_address | 00:00:00:00:00:00 |
| target_protocol_address | 192.168.2.5 |
2 changes: 1 addition & 1 deletion features/open_flow13/set_arp_operation.feature
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Feature: SetArpOperation
Scenario: new(Pio::Arp::Reply::OPERATION)
When I create an OpenFlow action with:
"""
Pio::SetArpOperation.new(Pio::Arp::Reply::OPERATION)
Pio::SetArpOperation.new(Pio::Arp::Reply.operation)
"""
Then the action has the following fields and values:
| field | value |
Expand Down
14 changes: 9 additions & 5 deletions lib/pio/arp.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
require 'pio/arp/format'
require 'pio/arp/request'
require 'pio/arp/reply'
require 'pio/message_type_selector'
require 'pio/arp/request'
require 'pio/parse_error'

# Packet parser and generator library.
module Pio
# ARP parser and generator.
class Arp
extend MessageTypeSelector
message_type Request::OPERATION => Request, Reply::OPERATION => Reply
def self.read(raw_data)
format = Format.read(raw_data)
{ Request.operation => Request,
Reply.operation => Reply }.fetch(format.operation).create(format)
rescue
raise Pio::ParseError, $ERROR_INFO.message
end
end
ARP = Arp
end
4 changes: 0 additions & 4 deletions lib/pio/arp/format.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,6 @@ class Format < BinData::Record
mac_address :target_hardware_address
ip_address :target_protocol_address

def message_type
operation
end

# rubocop:disable MethodLength
def to_exact_match(in_port)
match_options = {
Expand Down
14 changes: 8 additions & 6 deletions lib/pio/arp/message.rb
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
require 'pio/arp/format'
require 'pio/ruby_dumper'
require 'pio/message'

module Pio
class Arp
# Base class of ARP Request and Reply
class Message
include RubyDumper
private_class_method :new
class Message < Pio::Message
def self.create(format)
allocate.tap do |message|
message.instance_variable_set :@format, format
end
end

def initialize(user_options)
options = self.class.const_get(:Options).new(user_options.dup.freeze)
@format = Arp::Format.new(options.to_hash)
@format = Arp::Format.new(parse_options(user_options))
end

def method_missing(method, *args)
Expand Down
40 changes: 7 additions & 33 deletions lib/pio/arp/reply.rb
Original file line number Diff line number Diff line change
@@ -1,46 +1,20 @@
require 'pio/arp/message'
require 'pio/instance_inspector'
require 'pio/mac'
require 'pio/options'

module Pio
class Arp
# ARP Reply packet generator
class Reply < Message
include InstanceInspector

OPERATION = 2
public_class_method :new

# User options for creating an Arp Reply.
class Options < Pio::Options
mandatory_option :source_mac
mandatory_option :destination_mac
mandatory_option :sender_protocol_address
mandatory_option :target_protocol_address

def initialize(options)
validate options
@source_mac = Mac.new(options[:source_mac]).freeze
@destination_mac = Mac.new(options[:destination_mac]).freeze
@sender_protocol_address =
IPv4Address.new(options[:sender_protocol_address]).freeze
@target_protocol_address =
IPv4Address.new(options[:target_protocol_address]).freeze
end

def to_hash
{
operation: OPERATION,
source_mac: @source_mac,
destination_mac: @destination_mac,
sender_hardware_address: @source_mac,
target_hardware_address: @destination_mac,
sender_protocol_address: @sender_protocol_address,
target_protocol_address: @target_protocol_address
}.freeze
end
end
options operation: 2,
source_mac: :source_mac,
destination_mac: :destination_mac,
sender_hardware_address: :source_mac,
target_hardware_address: :destination_mac,
sender_protocol_address: :sender_protocol_address,
target_protocol_address: :target_protocol_address
end
end
end
41 changes: 7 additions & 34 deletions lib/pio/arp/request.rb
Original file line number Diff line number Diff line change
@@ -1,47 +1,20 @@
require 'pio/arp/message'
require 'pio/instance_inspector'
require 'pio/mac'
require 'pio/options'

module Pio
class Arp
# ARP Request packet generator
class Request < Message
include InstanceInspector

OPERATION = 1
public_class_method :new

# User options for creating an Arp Request.
class Options < Pio::Options
mandatory_option :source_mac
mandatory_option :sender_protocol_address
mandatory_option :target_protocol_address

BROADCAST_MAC = Mac.new(0xffffffffffff).freeze
ALL_ZERO_MAC = Mac.new(0).freeze

def initialize(options)
validate options
@source_mac = Mac.new(options[:source_mac]).freeze
@sender_protocol_address =
IPv4Address.new(options[:sender_protocol_address]).freeze
@target_protocol_address =
IPv4Address.new(options[:target_protocol_address]).freeze
end

def to_hash
{
operation: OPERATION,
source_mac: @source_mac,
destination_mac: BROADCAST_MAC,
sender_hardware_address: @source_mac,
target_hardware_address: ALL_ZERO_MAC,
sender_protocol_address: @sender_protocol_address,
target_protocol_address: @target_protocol_address
}.freeze
end
end
options operation: 1,
source_mac: :source_mac,
destination_mac: 'ff:ff:ff:ff:ff:ff'.freeze,
sender_hardware_address: :source_mac,
target_hardware_address: '00:00:00:00:00:00'.freeze,
sender_protocol_address: :sender_protocol_address,
target_protocol_address: :target_protocol_address
end
end
end
40 changes: 40 additions & 0 deletions lib/pio/message.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
require 'active_support/core_ext/class/attribute'
require 'pio/ruby_dumper'

module Pio
# Base message class
class Message
include RubyDumper

class_attribute :options

def self.options(options)
options.each_pair do |key, value|
next if value.is_a?(Symbol)
class_eval { class_attribute key }
class_eval { __send__("#{key}=", value) }
end
self.options = options
end

private

# rubocop:disable MethodLength
def parse_options(user_options)
options = {}
self.class.options.each_pair do |key, value|
if value.is_a?(Symbol)
begin
options[key] = user_options.fetch(value)
rescue
raise "#{key} option is a mandatory"
end
else
options[key] = user_options[key] || value
end
end
options
end
# rubocop:enable MethodLength
end
end
4 changes: 3 additions & 1 deletion lib/pio/open_flow10/packet_in.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require 'active_support/core_ext/object/try'
require 'pio/open_flow/message'
require 'pio/open_flow10/packet_in/reason'
require 'pio/parser'
Expand Down Expand Up @@ -46,7 +47,8 @@ def inspect
# rubocop:enable LineLength

def method_missing(method, *args)
data.__send__(method, *args).snapshot
bindata_value = data.__send__(method, *args)
bindata_value.try(:snapshot) || bindata_value
end

attr_accessor :datapath_id
Expand Down
4 changes: 3 additions & 1 deletion lib/pio/open_flow13/packet_in.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require 'active_support/core_ext/object/try'
require 'pio/open_flow'
require 'pio/open_flow13/match'
require 'pio/parser'
Expand Down Expand Up @@ -49,7 +50,8 @@ def in_port
end

def method_missing(method, *args)
data.__send__(method, *args).snapshot
bindata_value = data.__send__(method, *args)
bindata_value.try(:snapshot) || bindata_value
end
end
end
Expand Down
4 changes: 3 additions & 1 deletion lib/pio/open_flow13/packet_out.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require 'active_support/core_ext/object/try'
require 'pio/open_flow'
require 'pio/open_flow/buffer_id'
require 'pio/open_flow13/actions'
Expand Down Expand Up @@ -38,7 +39,8 @@ def data
end

def method_missing(method, *args)
data.__send__(method, *args).snapshot
bindata_value = data.__send__(method, *args)
bindata_value.try(:snapshot) || bindata_value
end
end
end
Expand Down
5 changes: 5 additions & 0 deletions lib/pio/options.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ def self.option(name)
const_get(:OPTIONS) << name
end

def initialize(options)
validate options
@options = options
end

private

def validate(user_options)
Expand Down
2 changes: 1 addition & 1 deletion lib/pio/ruby_dumper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def to_ruby
bit_names = []
bit = false
end
list = __send__(each).to_bytes
list = (@format || self).__send__(each).to_bytes
next if list.empty?
bytes << " #{list}, # #{each}\n"
pack_template << 'C' * (list.count(',') + 1)
Expand Down

0 comments on commit 5b60203

Please sign in to comment.