quality: Add test cases for group_mod message

This commit is contained in:
Eishun Kondoh 2019-04-28 14:48:28 +09:00
parent ca07b47575
commit 37754a6ca4
8 changed files with 142 additions and 21 deletions

View file

@ -1,4 +1,63 @@
defmodule Openflow.Action do defmodule Openflow.Action do
@moduledoc """
Openflow parser handler
"""
@type type ::
Openflow.Action.Output.t()
| Openflow.Action.CopyTtlOut.t()
| Openflow.Action.CopyTtlIn.t()
| Openflow.Action.SetMplsTtl.t()
| Openflow.Action.DecMplsTtl.t()
| Openflow.Action.PushVlan.t()
| Openflow.Action.PopVlan.t()
| Openflow.Action.PushMpls.t()
| Openflow.Action.PopMpls.t()
| Openflow.Action.SetQueue.t()
| Openflow.Action.Group.t()
| Openflow.Action.SetNwTtl.t()
| Openflow.Action.DecNwTtl.t()
| Openflow.Action.SetField.t()
| Openflow.Action.PushPbb.t()
| Openflow.Action.PopPbb.t()
| Openflow.Action.NxResubmit.t()
| Openflow.Action.NxSetTunnel.t()
| Openflow.Action.NxRegMove.t()
| Openflow.Action.NxRegLoad.t()
| Openflow.Action.NxNote.t()
| Openflow.Action.NxSetTunnel64.t()
| Openflow.Action.NxMultipath.t()
| Openflow.Action.NxBundle.t()
| Openflow.Action.NxBundleLoad.t()
| Openflow.Action.NxResubmitTable.t()
| Openflow.Action.NxOutputReg.t()
| Openflow.Action.NxLearn.t()
| Openflow.Action.NxExit.t()
| Openflow.Action.NxDecTtl.t()
| Openflow.Action.NxFinTimeout.t()
| Openflow.Action.NxController.t()
| Openflow.Action.NxDecTtlCntIds.t()
| Openflow.Action.NxWriteMetadata.t()
| Openflow.Action.NxPushMpls.t()
| Openflow.Action.NxPopMpls.t()
| Openflow.Action.NxStackPush.t()
| Openflow.Action.NxStackPop.t()
| Openflow.Action.NxSample.t()
| Openflow.Action.NxOutputReg2.t()
| Openflow.Action.NxRegLoad2.t()
| Openflow.Action.NxConjunction.t()
| Openflow.Action.NxConntrack.t()
| Openflow.Action.NxNat.t()
| Openflow.Action.NxController2.t()
| Openflow.Action.NxSample2.t()
| Openflow.Action.NxOutputTrunc.t()
| Openflow.Action.NxGroup.t()
| Openflow.Action.NxSample3.t()
| Openflow.Action.NxClone.t()
| Openflow.Action.NxCtClear.t()
| Openflow.Action.NxResubmitTableCt.t()
| Openflow.Action.NxLearn2.t()
def read(action_bin) do def read(action_bin) do
do_read([], action_bin) do_read([], action_bin)
end end

View file

@ -3,6 +3,8 @@ defmodule Openflow.Action.Experimenter do
alias __MODULE__ alias __MODULE__
@type t :: %Experimenter{exp_id: 0..0xFFFFFFFF, data: binary()}
@experimter_size 8 @experimter_size 8
def ofpat, do: 0xFFFF def ofpat, do: 0xFFFF

View file

@ -8,23 +8,35 @@ defmodule Openflow.Bucket do
alias __MODULE__ alias __MODULE__
@type t :: %Bucket{
weight: 0..0xFFFF,
watch_port: Openflow.Port.no(),
watch_group: Openflow.GroupMod.id(),
actions: [Openflow.Actions.type()]
}
@header_size 16 @header_size 16
@spec new(
weight: 0..0xFFFF,
watch_port: Openflow.Port.no(),
watch_group: Openflow.GroupMod.id(),
actions: [Openflow.Actions.type()]
) :: t()
def new(options) do def new(options) do
weight = Keyword.get(options, :weight, 0) %Bucket{
watch_port = Keyword.get(options, :watch_port, :any) weight: options[:weight] || 0,
watch_group = Keyword.get(options, :watch_group, :any) watch_port: options[:watch_port] || :any,
actions = Keyword.get(options, :actions, []) watch_group: options[:watch_group] || :any,
%Bucket{weight: weight, watch_port: watch_port, watch_group: watch_group, actions: actions} actions: options[:actions] || []
}
end end
def read(buckets_bin) do @spec read(<<_::_*128>>) :: [t()]
do_read([], buckets_bin) def read(buckets_bin), do: do_read([], buckets_bin)
end
def to_binary(buckets) do @spec read([t()]) :: <<_::_*128>>
to_binary("", buckets) def to_binary(buckets), do: to_binary("", buckets)
end
# private functions # private functions

View file

@ -25,10 +25,9 @@ defmodule Openflow.FlowMod do
@type command :: :add | :modify | :modify_strict | :delete | :delete_strict @type command :: :add | :modify | :modify_strict | :delete | :delete_strict
@type out_port :: @type out_port :: Openflow.Port.number()
0..0xFFFFFFFF | :max | :table | :normal | :flood | :all | :controller | :local | :any
@type out_group :: 0..0xFFFFFFFF | :max | :all | :any @type out_group :: Openflow.GroupMod.id()
@type flags :: [ @type flags :: [
:send_flow_rem | :check_overlap | :reset_counts | :no_packet_counts | :no_byte_counts :send_flow_rem | :check_overlap | :reset_counts | :no_packet_counts | :no_byte_counts

View file

@ -26,12 +26,14 @@ defmodule Openflow.GetConfig.Reply do
@spec ofp_type() :: t() @spec ofp_type() :: t()
def ofp_type, do: 8 def ofp_type, do: 8
@spec read(<<_::32>>) :: t()
def read(<<flags_int::16, miss_send_len0::16>>) do def read(<<flags_int::16, miss_send_len0::16>>) do
flags = Openflow.Enums.int_to_flags(flags_int, :config_flags) flags = Openflow.Enums.int_to_flags(flags_int, :config_flags)
miss_send_len = Openflow.Utils.get_enum(miss_send_len0, :controller_max_len) miss_send_len = Openflow.Utils.get_enum(miss_send_len0, :controller_max_len)
%Reply{flags: flags, miss_send_len: miss_send_len} %Reply{flags: flags, miss_send_len: miss_send_len}
end end
@spec to_binary(t()) :: <<_::32>>
def to_binary(%Reply{flags: flags, miss_send_len: miss_send_len0}) do def to_binary(%Reply{flags: flags, miss_send_len: miss_send_len0}) do
flags_int = Openflow.Enums.flags_to_int(flags, :config_flags) flags_int = Openflow.Enums.flags_to_int(flags, :config_flags)
miss_send_len = Openflow.Utils.get_enum(miss_send_len0, :controller_max_len) miss_send_len = Openflow.Utils.get_enum(miss_send_len0, :controller_max_len)

View file

@ -12,17 +12,42 @@ defmodule Openflow.GroupMod do
alias __MODULE__ alias __MODULE__
@type command :: :add | :delete | :modify
@type type :: :add | :select | :indirect | :fast_failover
@type id :: :max | :all | :any | 0..0xFFFFFFFF
@type t :: %GroupMod{
version: 4,
datapath_id: String.t() | nil,
aux_id: 0..0xF | nil,
xid: 0..0xFFFFFFFF,
command: command(),
type: type(),
group_id: id(),
buckets: [Openflow.Bucket.t()]
}
@spec ofp_type() :: 15
def ofp_type, do: 15 def ofp_type, do: 15
@spec new(
xid: 0..0xFFFFFFFF,
command: command(),
type: type(),
group_id: id(),
buckets: [Openflow.Bucket.t()]
) :: t()
def new(options \\ []) do def new(options \\ []) do
xid = Keyword.get(options, :xid, 0) %GroupMod{
command = Keyword.get(options, :command, :add) xid: options[:xid] || 0,
type = Keyword.get(options, :type, :all) command: options[:command] || :add,
group_id = Keyword.get(options, :group_id, 0) type: options[:type] || :all,
buckets = Keyword.get(options, :buckets, []) group_id: options[:group_id] || 0,
%GroupMod{xid: xid, command: command, type: type, group_id: group_id, buckets: buckets} buckets: options[:buckets] || []
}
end end
@spec read(<<_::64, _::_*128>>) :: t()
def read(<<command_int::16, type_int::8, _::8, group_id_int::32, buckets_bin::bytes>>) do def read(<<command_int::16, type_int::8, _::8, group_id_int::32, buckets_bin::bytes>>) do
command = Openflow.Utils.get_enum(command_int, :group_mod_command) command = Openflow.Utils.get_enum(command_int, :group_mod_command)
type = Openflow.Utils.get_enum(type_int, :group_type) type = Openflow.Utils.get_enum(type_int, :group_type)
@ -31,6 +56,7 @@ defmodule Openflow.GroupMod do
%GroupMod{command: command, type: type, group_id: group_id, buckets: buckets} %GroupMod{command: command, type: type, group_id: group_id, buckets: buckets}
end end
@spec to_binary(t()) :: <<_::64, _::_*128>>
def to_binary(%GroupMod{command: command, type: type, group_id: group_id, buckets: buckets}) do def to_binary(%GroupMod{command: command, type: type, group_id: group_id, buckets: buckets}) do
command_int = Openflow.Utils.get_enum(command, :group_mod_command) command_int = Openflow.Utils.get_enum(command, :group_mod_command)
type_int = Openflow.Utils.get_enum(type, :group_type) type_int = Openflow.Utils.get_enum(type, :group_type)

View file

@ -17,6 +17,17 @@ defmodule Openflow.Port do
alias __MODULE__ alias __MODULE__
@type no ::
0..0xFFFFFFFF
| :max
| :table
| :normal
| :flood
| :all
| :controller
| :local
| :any
def read( def read(
<<port_no_int::32, _::size(4)-unit(8), hw_addr_bin::6-bytes, _::size(2)-unit(8), <<port_no_int::32, _::size(4)-unit(8), hw_addr_bin::6-bytes, _::size(2)-unit(8),
name_bin::size(@ofp_max_port_name_len)-bytes, config_int::32, state_int::32, name_bin::size(@ofp_max_port_name_len)-bytes, config_int::32, state_int::32,

View file

@ -5,7 +5,17 @@ defmodule OfpGroupModTest do
describe "Openflow.read/1" do describe "Openflow.read/1" do
test "with OFP_GROUP_MOD packet" do test "with OFP_GROUP_MOD packet" do
binary = File.read!("test/packet_data/4-21-ofp_group_mod.packet") binary = File.read!("test/packet_data/4-21-ofp_group_mod.packet")
{:ok, group_mod, ""} = Openflow.read(binary) {:ok, _group_mod, ""} = Openflow.read(binary)
group_mod =
binary
|> Openflow.read()
|> elem(1)
|> Map.to_list()
|> Openflow.GroupMod.new()
|> Openflow.to_binary()
|> Openflow.read()
|> elem(1)
assert group_mod.version == 4 assert group_mod.version == 4
assert group_mod.xid == 0 assert group_mod.xid == 0