quality: Add test case for nx_set_packet_in_format message
This commit is contained in:
parent
ad1a441239
commit
1f5d3cbab2
4 changed files with 33 additions and 214 deletions
|
|
@ -26,28 +26,6 @@ defmodule Openflow.NxPacketIn2 do
|
|||
|
||||
alias __MODULE__
|
||||
|
||||
@encode_keys ~w(
|
||||
packet
|
||||
full_len
|
||||
buffer_id
|
||||
table_id
|
||||
cookie
|
||||
reason
|
||||
metadata
|
||||
userdata
|
||||
)a
|
||||
|
||||
@continuation_keys ~w(
|
||||
continuation_bridge
|
||||
continuation_stack
|
||||
continuation_conntracked
|
||||
continuation_table_id
|
||||
continuation_cookie
|
||||
continuation_actions
|
||||
continuation_mirrors
|
||||
continuation_action_set
|
||||
)a
|
||||
|
||||
@experimenter 0x00002320
|
||||
@nx_type 30
|
||||
|
||||
|
|
@ -74,12 +52,6 @@ defmodule Openflow.NxPacketIn2 do
|
|||
|
||||
def ofp_type, do: 4
|
||||
|
||||
def to_binary(%NxPacketIn2{} = pin) do
|
||||
props_bin = encode_props("", pin, @encode_keys)
|
||||
continuations_bin = encode_continuations("", pin, @continuation_keys)
|
||||
<<@experimenter::32, @nx_type::32, props_bin::bytes, continuations_bin::bytes>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nx_type::32, props_bin::bytes>>) do
|
||||
%NxPacketIn2{}
|
||||
|> decode_props(props_bin)
|
||||
|
|
@ -87,189 +59,6 @@ defmodule Openflow.NxPacketIn2 do
|
|||
|
||||
## private functions
|
||||
|
||||
defp encode_props(acc, _pin, []), do: acc
|
||||
|
||||
defp encode_props(acc, %NxPacketIn2{packet: packet} = pin, [:packet | rest])
|
||||
when not is_nil(packet) and is_binary(packet) do
|
||||
length = @prop_header_length + byte_size(packet)
|
||||
pad_length = Openflow.Utils.pad_length(length, 8)
|
||||
binary = <<@packet::16, length::16, packet::bytes, 0::size(pad_length)-unit(8)>>
|
||||
encode_props(<<acc::bytes, binary::bytes>>, pin, rest)
|
||||
end
|
||||
|
||||
defp encode_props(acc, %NxPacketIn2{full_len: full_len} = pin, [:full_len | rest])
|
||||
when not is_nil(full_len) and is_integer(full_len) do
|
||||
length = @prop_header_length + 4
|
||||
binary = <<@full_len::16, length::16, full_len::32>>
|
||||
encode_props(<<acc::bytes, binary::bytes>>, pin, rest)
|
||||
end
|
||||
|
||||
defp encode_props(acc, %NxPacketIn2{buffer_id: buffer_id} = pin, [:buffer_id | rest])
|
||||
when not is_nil(buffer_id) and is_integer(buffer_id) do
|
||||
length = @prop_header_length + 4
|
||||
binary = <<@buffer_id::16, length::16, buffer_id::32>>
|
||||
encode_props(<<acc::bytes, binary::bytes>>, pin, rest)
|
||||
end
|
||||
|
||||
defp encode_props(acc, %NxPacketIn2{table_id: table_id} = pin, [:table_id | rest])
|
||||
when not is_nil(table_id) and is_integer(table_id) do
|
||||
length = @prop_header_length + 4
|
||||
binary = <<@table_id::16, length::16, table_id::8, 0::24>>
|
||||
encode_props(<<acc::bytes, binary::bytes>>, pin, rest)
|
||||
end
|
||||
|
||||
defp encode_props(acc, %NxPacketIn2{cookie: cookie} = pin, [:cookie | rest])
|
||||
when not is_nil(cookie) and is_integer(cookie) do
|
||||
length = @prop_header_length + 4
|
||||
binary = <<@cookie::16, length::16, 0::32, cookie::64>>
|
||||
encode_props(<<acc::bytes, binary::bytes>>, pin, rest)
|
||||
end
|
||||
|
||||
defp encode_props(acc, %NxPacketIn2{metadata: metadata} = pin, [:metadata | rest])
|
||||
when not is_nil(metadata) and is_list(metadata) do
|
||||
pad_match_bin =
|
||||
metadata
|
||||
|> Openflow.Match.new()
|
||||
|> Openflow.Match.to_binary()
|
||||
|
||||
<<1::16, match_len_with_header::16, padded_match_bin::bytes>> = pad_match_bin
|
||||
match_len = match_len_with_header - 4
|
||||
<<match_bin::size(match_len)-bytes, _pad::bytes>> = padded_match_bin
|
||||
length = @prop_header_length + match_len
|
||||
pad_length = Openflow.Utils.pad_length(length, 8)
|
||||
binary = <<@metadata::16, length::16, match_bin::bytes, 0::size(pad_length)-unit(8)>>
|
||||
encode_props(<<acc::bytes, binary::bytes>>, pin, rest)
|
||||
end
|
||||
|
||||
defp encode_props(acc, %NxPacketIn2{userdata: userdata} = pin, [:userdata | rest])
|
||||
when not is_nil(userdata) and is_binary(userdata) do
|
||||
length = @prop_header_length + byte_size(userdata)
|
||||
pad_length = Openflow.Utils.pad_length(length, 8)
|
||||
binary = <<@userdata::16, length::16, userdata::bytes, 0::size(pad_length)-unit(8)>>
|
||||
encode_props(<<acc::bytes, binary::bytes>>, pin, rest)
|
||||
end
|
||||
|
||||
defp encode_props(acc, pin, [_ | rest]) do
|
||||
encode_props(acc, pin, rest)
|
||||
end
|
||||
|
||||
defp encode_continuations(acc, _pin, []) do
|
||||
if byte_size(acc) > 0 do
|
||||
length = @prop_header_length + byte_size(acc)
|
||||
pad_length = Openflow.Utils.pad_length(length, 8)
|
||||
<<@continuation::16, acc::bytes, 0::size(pad_length)-unit(8)>>
|
||||
else
|
||||
<<>>
|
||||
end
|
||||
end
|
||||
|
||||
defp encode_continuations(
|
||||
acc,
|
||||
%NxPacketIn2{continuation_bridge: br} = pin,
|
||||
[:continuation_bridge | rest]
|
||||
)
|
||||
when not is_nil(br) do
|
||||
length = @prop_header_length + byte_size(br)
|
||||
pad_length = Openflow.Utils.pad_length(length, 8)
|
||||
bridge_bin = <<br::bytes, 0::size(pad_length)-unit(8), acc::bytes>>
|
||||
binary = <<@nxcpt_bridge::16, length::16, bridge_bin::bytes, acc::bytes>>
|
||||
encode_continuations(binary, pin, rest)
|
||||
end
|
||||
|
||||
defp encode_continuations(
|
||||
acc,
|
||||
%NxPacketIn2{continuation_stack: stack} = pin,
|
||||
[:continuation_stack | rest]
|
||||
)
|
||||
when not is_nil(stack) do
|
||||
length = @prop_header_length + byte_size(stack)
|
||||
pad_length = Openflow.Utils.pad_length(length, 8)
|
||||
stack_bin = <<stack::bytes, 0::size(pad_length)-unit(8), acc::bytes>>
|
||||
binary = <<@nxcpt_stack::16, length::16, stack_bin::bytes, acc::bytes>>
|
||||
encode_continuations(binary, pin, rest)
|
||||
end
|
||||
|
||||
defp encode_continuations(
|
||||
acc,
|
||||
%NxPacketIn2{continuation_mirrors: mirrors} = pin,
|
||||
[:continuation_mirrors | rest]
|
||||
)
|
||||
when not is_nil(mirrors) do
|
||||
length = @prop_header_length + byte_size(mirrors)
|
||||
pad_length = Openflow.Utils.pad_length(length, 8)
|
||||
mirrors_bin = <<mirrors::bytes, 0::size(pad_length)-unit(8), acc::bytes>>
|
||||
binary = <<@nxcpt_mirrors::16, length::16, mirrors_bin::bytes, acc::bytes>>
|
||||
encode_continuations(binary, pin, rest)
|
||||
end
|
||||
|
||||
defp encode_continuations(
|
||||
acc,
|
||||
%NxPacketIn2{continuation_conntracked: true} = pin,
|
||||
[:continuation_conntracked | rest]
|
||||
) do
|
||||
length = @prop_header_length + 1
|
||||
pad_length = Openflow.Utils.pad_length(length, 8)
|
||||
conntracked_bin = <<1::size(1)-unit(8), 0::size(pad_length)-unit(8), acc::bytes>>
|
||||
binary = <<@nxcpt_conntracked::16, length::16, conntracked_bin::bytes, acc::bytes>>
|
||||
encode_continuations(binary, pin, rest)
|
||||
end
|
||||
|
||||
defp encode_continuations(
|
||||
acc,
|
||||
%NxPacketIn2{continuation_table_id: table_id} = pin,
|
||||
[:continuation_table_id | rest]
|
||||
)
|
||||
when not is_nil(table_id) do
|
||||
length = @prop_header_length + 1
|
||||
pad_length = Openflow.Utils.pad_length(length, 8)
|
||||
table_id_bin = <<table_id::8, 0::size(pad_length)-unit(8), acc::bytes>>
|
||||
binary = <<@nxcpt_table_id::16, length::16, table_id_bin::bytes, acc::bytes>>
|
||||
encode_continuations(binary, pin, rest)
|
||||
end
|
||||
|
||||
defp encode_continuations(
|
||||
acc,
|
||||
%NxPacketIn2{continuation_cookie: cookie} = pin,
|
||||
[:continuation_cookie | rest]
|
||||
)
|
||||
when not is_nil(cookie) do
|
||||
length = @prop_header_length + 8
|
||||
pad_length = Openflow.Utils.pad_length(length, 8)
|
||||
cookie_bin = <<cookie::64, 0::size(pad_length)-unit(8), acc::bytes>>
|
||||
binary = <<@nxcpt_cookie::16, length::16, cookie_bin::bytes, acc::bytes>>
|
||||
encode_continuations(binary, pin, rest)
|
||||
end
|
||||
|
||||
defp encode_continuations(
|
||||
acc,
|
||||
%NxPacketIn2{continuation_actions: actions} = pin,
|
||||
[:continuation_actions | rest]
|
||||
) do
|
||||
actions_bin = Openflow.Action.to_binary(actions)
|
||||
length = @prop_header_length + byte_size(actions_bin)
|
||||
pad_length = Openflow.Utils.pad_length(length, 8)
|
||||
actions_bin = <<actions_bin::bytes, 0::size(pad_length)-unit(8), acc::bytes>>
|
||||
binary = <<@nxcpt_actions::16, length::16, actions_bin::bytes, acc::bytes>>
|
||||
encode_continuations(binary, pin, rest)
|
||||
end
|
||||
|
||||
defp encode_continuations(
|
||||
acc,
|
||||
%NxPacketIn2{continuation_action_set: action_set} = pin,
|
||||
[:continuation_action_set | rest]
|
||||
)
|
||||
when not is_nil(action_set) do
|
||||
length = @prop_header_length + byte_size(action_set)
|
||||
pad_length = Openflow.Utils.pad_length(length, 8)
|
||||
action_set_bin = <<action_set::bytes, 0::size(pad_length)-unit(8), acc::bytes>>
|
||||
binary = <<@nxcpt_action_set::16, length::16, action_set_bin::bytes, acc::bytes>>
|
||||
encode_continuations(binary, pin, rest)
|
||||
end
|
||||
|
||||
defp encode_continuations(acc, pin, [_ | rest]) do
|
||||
encode_continuations(acc, pin, rest)
|
||||
end
|
||||
|
||||
defp decode_props(pktin, ""), do: pktin
|
||||
|
||||
defp decode_props(pktin, <<@packet::16, length::16, tail::bytes>>) do
|
||||
|
|
|
|||
|
|
@ -14,8 +14,15 @@ defmodule Openflow.NxSetPacketInFormat do
|
|||
|
||||
def ofp_type, do: 4
|
||||
|
||||
def new(format \\ :standard) do
|
||||
%NxSetPacketInFormat{format: format}
|
||||
def new(format) when is_atom(format) do
|
||||
new(format: format)
|
||||
end
|
||||
|
||||
def new(options) when is_list(options) do
|
||||
%NxSetPacketInFormat{
|
||||
format: options[:format] || :standard,
|
||||
xid: options[:xid] || 0
|
||||
}
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nx_type::32, format_int::32>>) do
|
||||
|
|
|
|||
2
mix.exs
2
mix.exs
|
|
@ -11,7 +11,7 @@ defmodule Tres.Mixfile do
|
|||
deps: deps(),
|
||||
aliases: [
|
||||
test: [
|
||||
"test --no-start"
|
||||
"test"
|
||||
],
|
||||
generate_enum: [
|
||||
"run priv/openflow_enum_gen.exs"
|
||||
|
|
|
|||
23
test/lib/openflow/ofp_set_packet_in_format_test.exs
Normal file
23
test/lib/openflow/ofp_set_packet_in_format_test.exs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
defmodule OfpSetPacketInFormatTest do
|
||||
use ExUnit.Case
|
||||
doctest Openflow
|
||||
|
||||
describe "Openflow.to_binary/1" do
|
||||
test "with Openflow.SetPacket_In_Format.new/1" do
|
||||
packet_in_format =
|
||||
"test/packet_data/nx_set_packet_in_format.raw"
|
||||
|> File.read!()
|
||||
|> Openflow.read()
|
||||
|> Kernel.elem(1)
|
||||
|
||||
packet_in_format
|
||||
|> Openflow.to_binary()
|
||||
|> Openflow.read()
|
||||
|> Kernel.elem(1)
|
||||
|> Map.to_list()
|
||||
|> Openflow.NxSetPacketInFormat.new()
|
||||
|> Kernel.==(packet_in_format)
|
||||
|> assert()
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue