From 1f5d3cbab2c23d4cbe9c9cf46e10e89a24f8d3cf Mon Sep 17 00:00:00 2001 From: Eishun Kondoh Date: Mon, 6 May 2019 03:10:57 +0900 Subject: [PATCH] quality: Add test case for nx_set_packet_in_format message --- lib/openflow/nx_packet_in2.ex | 211 ------------------ lib/openflow/nx_packet_in_format.ex | 11 +- mix.exs | 2 +- .../ofp_set_packet_in_format_test.exs | 23 ++ 4 files changed, 33 insertions(+), 214 deletions(-) create mode 100644 test/lib/openflow/ofp_set_packet_in_format_test.exs diff --git a/lib/openflow/nx_packet_in2.ex b/lib/openflow/nx_packet_in2.ex index 02e2572..a2d9af6 100644 --- a/lib/openflow/nx_packet_in2.ex +++ b/lib/openflow/nx_packet_in2.ex @@ -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(<>, 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(<>, 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(<>, 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(<>, 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(<>, 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 - <> = 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(<>, 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(<>, 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 = <> - 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 = <> - 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 = <> - 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 = <> - 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 = <> - 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 = <> - 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 = <> - 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 diff --git a/lib/openflow/nx_packet_in_format.ex b/lib/openflow/nx_packet_in_format.ex index e42b570..968e487 100644 --- a/lib/openflow/nx_packet_in_format.ex +++ b/lib/openflow/nx_packet_in_format.ex @@ -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 diff --git a/mix.exs b/mix.exs index 4def777..d9fc8d3 100644 --- a/mix.exs +++ b/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" diff --git a/test/lib/openflow/ofp_set_packet_in_format_test.exs b/test/lib/openflow/ofp_set_packet_in_format_test.exs new file mode 100644 index 0000000..356f5c9 --- /dev/null +++ b/test/lib/openflow/ofp_set_packet_in_format_test.exs @@ -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