diff --git a/.travis.yml b/.travis.yml index ecbde71..097035a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ language: elixir elixir: - "1.8.1" otp_release: - - "22.0.5" + - "21.3.6" before_install: - sudo apt-get install -y wget curl gdebi debhelper unbound diff --git a/examples/nx_learning_switch/lib/nx_learning_switch.ex b/examples/nx_learning_switch/lib/nx_learning_switch.ex index 9c3d9b9..2565ec2 100644 --- a/examples/nx_learning_switch/lib/nx_learning_switch.ex +++ b/examples/nx_learning_switch/lib/nx_learning_switch.ex @@ -56,7 +56,29 @@ defmodule NxLearningSwitch do send_flow_mod_add( datapath_id, table_id: 0, - instructions: l2_learning_instr() + instructions: ApplyActions.new([ + NxLearn.new( + table_id: 1, + priority: 2, + hard_timeout: 10, + flow_specs: [ + NxFlowSpecMatch.new( + src: :eth_src, + dst: :eth_dst + ), + NxFlowSpecMatch.new( + src: :vlan_vid, + dst: :vlan_vid, + offset: 0, + n_bits: 12 + ), + NxFlowSpecOutput.new( + src: :nx_in_port + ) + ] + ), + NxResubmitTable.new(1) + ]) ) end @@ -68,28 +90,4 @@ defmodule NxLearningSwitch do instructions: ApplyActions.new(Output.new(:flood)) ) end - - defp l2_learning_instr do - ApplyActions.new([ - l2_learning_action(), - NxResubmitTable.new(1) - ]) - end - - defp l2_learning_action do - NxLearn.new( - table_id: 1, - priority: 2, - hard_timeout: 10, - flow_specs: l2_learning_flow_specs() - ) - end - - defp l2_learning_flow_specs do - [ - NxFlowSpecMatch.new(src: :eth_src, dst: :eth_dst), - NxFlowSpecMatch.new(src: :vlan_vid, n_bits: 12), - NxFlowSpecOutput.new(src: :nx_in_port) - ] - end end diff --git a/lib/openflow/actions/experimenter.ex b/lib/openflow/actions/experimenter.ex index 4f7cf47..16b3302 100644 --- a/lib/openflow/actions/experimenter.ex +++ b/lib/openflow/actions/experimenter.ex @@ -20,54 +20,34 @@ defmodule Openflow.Action.Experimenter do @spec pack_exp_header(binary()) :: binary() def pack_exp_header(exp_body) do - pad_length = pad_length_of(exp_body) + pad_length = + exp_body + |> Kernel.byte_size() + |> Kernel.+(4) + |> Openflow.Utils.padding(8) - << - 0xFFFF::16, - length_of(exp_body, pad_length)::16, - exp_body::bytes, - 0::size(pad_length)-unit(8) - >> + length = + exp_body + |> byte_size() + |> Kernel.+(4) + |> Kernel.+(pad_length) + + <<0xFFFF::16, length::16, exp_body::bytes, 0::size(pad_length)-unit(8)>> end - def read(<< - 0xFFFF::16, - _length::16, - exp_id::32, - exp_type::16, - data::bytes - >>) do - exp_id - |> Openflow.Utils.get_enum(:action_vendor) - |> read(exp_id, exp_type, data) - end - - ## private functions - - defp read(vendor_id, exp_id, exp_type, <>) when is_atom(vendor_id) do - case Openflow.Utils.get_enum(exp_type, vendor_id) do - codec when is_atom(codec) -> - codec.read(<>) - - exp_type when is_integer(exp_type) -> + def read(<<0xFFFF::16, _length::16, exp_id::32, exp_type::16, data::bytes>>) do + case Openflow.Utils.get_enum(exp_id, :action_vendor) do + vendor_id when is_integer(vendor_id) -> %Experimenter{exp_id: exp_id, data: <>} + + vendor when is_atom(vendor) -> + case Openflow.Utils.get_enum(exp_type, vendor) do + codec when is_atom(codec) -> + codec.read(<>) + + exp_type when is_integer(exp_type) -> + %Experimenter{exp_id: exp_id, data: <>} + end end end - - defp read(vendor_id, exp_id, exp_type, <>) when is_integer(vendor_id), - do: %Experimenter{exp_id: exp_id, data: <>} - - defp pad_length_of(<>) do - exp_body - |> Kernel.byte_size() - |> Kernel.+(4) - |> Openflow.Utils.padding(8) - end - - defp length_of(<>, pad_length) do - exp_body - |> byte_size() - |> Kernel.+(4) - |> Kernel.+(pad_length) - end end diff --git a/lib/openflow/actions/nx_check_pkt_larger.ex b/lib/openflow/actions/nx_check_pkt_larger.ex deleted file mode 100644 index ac0ecb6..0000000 --- a/lib/openflow/actions/nx_check_pkt_larger.ex +++ /dev/null @@ -1,46 +0,0 @@ -defmodule Openflow.Action.NxCheckPktLarger do - defstruct( - pkt_len: 0, - offset: 0, - dst_field: nil - ) - - @experimenter 0x00002320 - @nxast 49 - - alias __MODULE__ - alias Openflow.Action.Experimenter - - @type t :: %NxCheckPktLarger{dst_field: atom(), pkt_len: 0..0xFFFF, offset: 0..0xFFFF} - - @spec new(dst_field: atom(), pkt_len: 0..0xFFFF, offset: 0..0xFFFF) :: t() - def new(options \\ []) do - dst_field = options[:dst_field] || raise "dst_field must be specified" - pkt_len = options[:pkt_len] || raise "pkt_len must be specified" - ofs = Keyword.get(options, :offset, 0) - %NxCheckPktLarger{dst_field: dst_field, pkt_len: pkt_len, offset: ofs} - end - - @spec to_binary(t()) :: binary() - def to_binary(%NxCheckPktLarger{} = pkt_larger) do - dst_field_bin = Openflow.Match.codec_header(pkt_larger.dst_field) - pkt_len = pkt_larger.pkt_len - ofs = pkt_larger.offset - - Experimenter.pack_exp_header(<< - @experimenter::32, - @nxast::16, - pkt_len::16, - ofs::16, - dst_field_bin::4-bytes, - 0::size(10)-unit(8) - >>) - end - - @spec read(binary()) :: t() - def read(<<@experimenter::32, @nxast::16, body::bytes>>) do - <> = body - dst_field = Openflow.Match.codec_header(dst_field_bin) - %NxCheckPktLarger{dst_field: dst_field, pkt_len: pkt_len, offset: ofs} - end -end diff --git a/lib/openflow/actions/nx_flow_spec_match.ex b/lib/openflow/actions/nx_flow_spec_match.ex index 546aeb8..d9b76b3 100644 --- a/lib/openflow/actions/nx_flow_spec_match.ex +++ b/lib/openflow/actions/nx_flow_spec_match.ex @@ -29,8 +29,8 @@ defmodule Openflow.Action.NxFlowSpecMatch do dst_offset: non_neg_integer() ) :: t() def new(options \\ []) do + dst = options[:dst] || raise ":dst must be specified" src = options[:src] || raise ":src must be specified" - dst = options[:dst] || src n_bits = options[:n_bits] || Openflow.Match.n_bits_of(dst) %NxFlowSpecMatch{ diff --git a/lib/openflow/enums.ex b/lib/openflow/enums.ex index 7913581..6975a3d 100644 --- a/lib/openflow/enums.ex +++ b/lib/openflow/enums.ex @@ -1535,16 +1535,10 @@ defmodule Openflow.Enums do throw(:bad_enum) end - def to_int(:nxoxm_nsh_match, :experimenter_oxm_vendors) do - experimenter_oxm_vendors_to_int(:nxoxm_nsh_match) + def to_int(:nicira_ext_match, :experimenter_oxm_vendors) do + experimenter_oxm_vendors_to_int(:nicira_ext_match) catch - _class, _reason -> :nxoxm_nsh_match - end - - def to_int(:nxoxm_match, :experimenter_oxm_vendors) do - experimenter_oxm_vendors_to_int(:nxoxm_match) - catch - _class, _reason -> :nxoxm_match + _class, _reason -> :nicira_ext_match end def to_int(:hp_ext_match, :experimenter_oxm_vendors) do @@ -2731,12 +2725,6 @@ defmodule Openflow.Enums do _class, _reason -> :pbb_uca end - def to_int(:packet_type, :openflow_basic) do - openflow_basic_to_int(:packet_type) - catch - _class, _reason -> :packet_type - end - def to_int(_int, :openflow_basic) do throw(:bad_enum) end @@ -2993,67 +2981,67 @@ defmodule Openflow.Enums do throw(:bad_enum) end - def to_int(:nsh_flags, :nxoxm_nsh_match) do - nxoxm_nsh_match_to_int(:nsh_flags) + def to_int(:nsh_flags, :nicira_ext_match) do + nicira_ext_match_to_int(:nsh_flags) catch _class, _reason -> :nsh_flags end - def to_int(:nsh_mdtype, :nxoxm_nsh_match) do - nxoxm_nsh_match_to_int(:nsh_mdtype) + def to_int(:nsh_mdtype, :nicira_ext_match) do + nicira_ext_match_to_int(:nsh_mdtype) catch _class, _reason -> :nsh_mdtype end - def to_int(:nsh_np, :nxoxm_nsh_match) do - nxoxm_nsh_match_to_int(:nsh_np) + def to_int(:nsh_np, :nicira_ext_match) do + nicira_ext_match_to_int(:nsh_np) catch _class, _reason -> :nsh_np end - def to_int(:nsh_spi, :nxoxm_nsh_match) do - nxoxm_nsh_match_to_int(:nsh_spi) + def to_int(:nsh_spi, :nicira_ext_match) do + nicira_ext_match_to_int(:nsh_spi) catch _class, _reason -> :nsh_spi end - def to_int(:nsh_si, :nxoxm_nsh_match) do - nxoxm_nsh_match_to_int(:nsh_si) + def to_int(:nsh_si, :nicira_ext_match) do + nicira_ext_match_to_int(:nsh_si) catch _class, _reason -> :nsh_si end - def to_int(:nsh_c1, :nxoxm_nsh_match) do - nxoxm_nsh_match_to_int(:nsh_c1) + def to_int(:nsh_c1, :nicira_ext_match) do + nicira_ext_match_to_int(:nsh_c1) catch _class, _reason -> :nsh_c1 end - def to_int(:nsh_c2, :nxoxm_nsh_match) do - nxoxm_nsh_match_to_int(:nsh_c2) + def to_int(:nsh_c2, :nicira_ext_match) do + nicira_ext_match_to_int(:nsh_c2) catch _class, _reason -> :nsh_c2 end - def to_int(:nsh_c3, :nxoxm_nsh_match) do - nxoxm_nsh_match_to_int(:nsh_c3) + def to_int(:nsh_c3, :nicira_ext_match) do + nicira_ext_match_to_int(:nsh_c3) catch _class, _reason -> :nsh_c3 end - def to_int(:nsh_c4, :nxoxm_nsh_match) do - nxoxm_nsh_match_to_int(:nsh_c4) + def to_int(:nsh_c4, :nicira_ext_match) do + nicira_ext_match_to_int(:nsh_c4) catch _class, _reason -> :nsh_c4 end - def to_int(:nsh_ttl, :nxoxm_nsh_match) do - nxoxm_nsh_match_to_int(:nsh_ttl) + def to_int(:nsh_ttl, :nicira_ext_match) do + nicira_ext_match_to_int(:nsh_ttl) catch _class, _reason -> :nsh_ttl end - def to_int(_int, :nxoxm_nsh_match) do + def to_int(_int, :nicira_ext_match) do throw(:bad_enum) end @@ -3079,40 +3067,6 @@ defmodule Openflow.Enums do throw(:bad_enum) end - def to_int(:nxoxm_dp_hash, :nxoxm_match) do - nxoxm_match_to_int(:nxoxm_dp_hash) - catch - _class, _reason -> :nxoxm_dp_hash - end - - def to_int(:tun_erspan_idx, :nxoxm_match) do - nxoxm_match_to_int(:tun_erspan_idx) - catch - _class, _reason -> :tun_erspan_idx - end - - def to_int(:tun_erspan_ver, :nxoxm_match) do - nxoxm_match_to_int(:tun_erspan_ver) - catch - _class, _reason -> :tun_erspan_ver - end - - def to_int(:tun_erspan_dir, :nxoxm_match) do - nxoxm_match_to_int(:tun_erspan_dir) - catch - _class, _reason -> :tun_erspan_dir - end - - def to_int(:tun_erspan_hwid, :nxoxm_match) do - nxoxm_match_to_int(:tun_erspan_hwid) - catch - _class, _reason -> :tun_erspan_hwid - end - - def to_int(_int, :nxoxm_match) do - throw(:bad_enum) - end - def to_int(:no_buffer, :buffer_id) do buffer_id_to_int(:no_buffer) catch @@ -4463,12 +4417,6 @@ defmodule Openflow.Enums do _class, _reason -> Openflow.Action.NxDecap end - def to_int(Openflow.Action.NxCheckPktLarger, :nicira_ext_action) do - nicira_ext_action_to_int(Openflow.Action.NxCheckPktLarger) - catch - _class, _reason -> Openflow.Action.NxCheckPktLarger - end - def to_int(Openflow.Action.NxDebugRecirc, :nicira_ext_action) do nicira_ext_action_to_int(Openflow.Action.NxDebugRecirc) catch @@ -6789,12 +6737,6 @@ defmodule Openflow.Enums do throw(:bad_enum) end - def to_atom(0x5AD650, :experimenter_oxm_vendors) do - experimenter_oxm_vendors_to_atom(0x5AD650) - catch - _class, _reason -> 5_953_104 - end - def to_atom(0x2320, :experimenter_oxm_vendors) do experimenter_oxm_vendors_to_atom(0x2320) catch @@ -7985,12 +7927,6 @@ defmodule Openflow.Enums do _class, _reason -> 41 end - def to_atom(0x2C, :openflow_basic) do - openflow_basic_to_atom(0x2C) - catch - _class, _reason -> 44 - end - def to_atom(_, :openflow_basic) do throw(:bad_enum) end @@ -8247,67 +8183,67 @@ defmodule Openflow.Enums do throw(:bad_enum) end - def to_atom(0x1, :nxoxm_nsh_match) do - nxoxm_nsh_match_to_atom(0x1) + def to_atom(0x1, :nicira_ext_match) do + nicira_ext_match_to_atom(0x1) catch _class, _reason -> 1 end - def to_atom(0x2, :nxoxm_nsh_match) do - nxoxm_nsh_match_to_atom(0x2) + def to_atom(0x2, :nicira_ext_match) do + nicira_ext_match_to_atom(0x2) catch _class, _reason -> 2 end - def to_atom(0x3, :nxoxm_nsh_match) do - nxoxm_nsh_match_to_atom(0x3) + def to_atom(0x3, :nicira_ext_match) do + nicira_ext_match_to_atom(0x3) catch _class, _reason -> 3 end - def to_atom(0x4, :nxoxm_nsh_match) do - nxoxm_nsh_match_to_atom(0x4) + def to_atom(0x4, :nicira_ext_match) do + nicira_ext_match_to_atom(0x4) catch _class, _reason -> 4 end - def to_atom(0x5, :nxoxm_nsh_match) do - nxoxm_nsh_match_to_atom(0x5) + def to_atom(0x5, :nicira_ext_match) do + nicira_ext_match_to_atom(0x5) catch _class, _reason -> 5 end - def to_atom(0x6, :nxoxm_nsh_match) do - nxoxm_nsh_match_to_atom(0x6) + def to_atom(0x6, :nicira_ext_match) do + nicira_ext_match_to_atom(0x6) catch _class, _reason -> 6 end - def to_atom(0x7, :nxoxm_nsh_match) do - nxoxm_nsh_match_to_atom(0x7) + def to_atom(0x7, :nicira_ext_match) do + nicira_ext_match_to_atom(0x7) catch _class, _reason -> 7 end - def to_atom(0x8, :nxoxm_nsh_match) do - nxoxm_nsh_match_to_atom(0x8) + def to_atom(0x8, :nicira_ext_match) do + nicira_ext_match_to_atom(0x8) catch _class, _reason -> 8 end - def to_atom(0x9, :nxoxm_nsh_match) do - nxoxm_nsh_match_to_atom(0x9) + def to_atom(0x9, :nicira_ext_match) do + nicira_ext_match_to_atom(0x9) catch _class, _reason -> 9 end - def to_atom(0xA, :nxoxm_nsh_match) do - nxoxm_nsh_match_to_atom(0xA) + def to_atom(0xA, :nicira_ext_match) do + nicira_ext_match_to_atom(0xA) catch _class, _reason -> 10 end - def to_atom(_, :nxoxm_nsh_match) do + def to_atom(_, :nicira_ext_match) do throw(:bad_enum) end @@ -8333,40 +8269,6 @@ defmodule Openflow.Enums do throw(:bad_enum) end - def to_atom(0x0, :nxoxm_match) do - nxoxm_match_to_atom(0x0) - catch - _class, _reason -> 0 - end - - def to_atom(0xB, :nxoxm_match) do - nxoxm_match_to_atom(0xB) - catch - _class, _reason -> 11 - end - - def to_atom(0xC, :nxoxm_match) do - nxoxm_match_to_atom(0xC) - catch - _class, _reason -> 12 - end - - def to_atom(0xD, :nxoxm_match) do - nxoxm_match_to_atom(0xD) - catch - _class, _reason -> 13 - end - - def to_atom(0xE, :nxoxm_match) do - nxoxm_match_to_atom(0xE) - catch - _class, _reason -> 14 - end - - def to_atom(_, :nxoxm_match) do - throw(:bad_enum) - end - def to_atom(0xFFFFFFFF, :buffer_id) do buffer_id_to_atom(0xFFFFFFFF) catch @@ -9717,12 +9619,6 @@ defmodule Openflow.Enums do _class, _reason -> 47 end - def to_atom(0x31, :nicira_ext_action) do - nicira_ext_action_to_atom(0x31) - catch - _class, _reason -> 49 - end - def to_atom(0xFF, :nicira_ext_action) do nicira_ext_action_to_atom(0xFF) catch @@ -11039,13 +10935,11 @@ defmodule Openflow.Enums do def controller_max_len_to_atom(0xFFE5), do: :max def controller_max_len_to_atom(0xFFFF), do: :no_buffer def controller_max_len_to_atom(_), do: throw(:bad_enum) - def experimenter_oxm_vendors_to_int(:nxoxm_nsh_match), do: 0x5AD650 - def experimenter_oxm_vendors_to_int(:nxoxm_match), do: 0x2320 + def experimenter_oxm_vendors_to_int(:nicira_ext_match), do: 0x2320 def experimenter_oxm_vendors_to_int(:hp_ext_match), do: 0x2428 def experimenter_oxm_vendors_to_int(:onf_ext_match), do: 0x4F4E4600 def experimenter_oxm_vendors_to_int(_), do: throw(:bad_enum) - def experimenter_oxm_vendors_to_atom(0x5AD650), do: :nxoxm_nsh_match - def experimenter_oxm_vendors_to_atom(0x2320), do: :nxoxm_match + def experimenter_oxm_vendors_to_atom(0x2320), do: :nicira_ext_match def experimenter_oxm_vendors_to_atom(0x2428), do: :hp_ext_match def experimenter_oxm_vendors_to_atom(0x4F4E4600), do: :onf_ext_match def experimenter_oxm_vendors_to_atom(_), do: throw(:bad_enum) @@ -11400,7 +11294,6 @@ defmodule Openflow.Enums do def openflow_basic_to_int(:tunnel_id), do: 0x26 def openflow_basic_to_int(:ipv6_exthdr), do: 0x27 def openflow_basic_to_int(:pbb_uca), do: 0x29 - def openflow_basic_to_int(:packet_type), do: 0x2C def openflow_basic_to_int(_), do: throw(:bad_enum) def openflow_basic_to_atom(0x0), do: :in_port def openflow_basic_to_atom(0x1), do: :in_phy_port @@ -11443,7 +11336,6 @@ defmodule Openflow.Enums do def openflow_basic_to_atom(0x26), do: :tunnel_id def openflow_basic_to_atom(0x27), do: :ipv6_exthdr def openflow_basic_to_atom(0x29), do: :pbb_uca - def openflow_basic_to_atom(0x2C), do: :packet_type def openflow_basic_to_atom(_), do: throw(:bad_enum) def vlan_id_to_int(:vid_present), do: 0x1000 def vlan_id_to_int(:vid_none), do: 0x0 @@ -11533,28 +11425,28 @@ defmodule Openflow.Enums do def packet_register_to_atom(0x6), do: :xreg6 def packet_register_to_atom(0x7), do: :xreg7 def packet_register_to_atom(_), do: throw(:bad_enum) - def nxoxm_nsh_match_to_int(:nsh_flags), do: 0x1 - def nxoxm_nsh_match_to_int(:nsh_mdtype), do: 0x2 - def nxoxm_nsh_match_to_int(:nsh_np), do: 0x3 - def nxoxm_nsh_match_to_int(:nsh_spi), do: 0x4 - def nxoxm_nsh_match_to_int(:nsh_si), do: 0x5 - def nxoxm_nsh_match_to_int(:nsh_c1), do: 0x6 - def nxoxm_nsh_match_to_int(:nsh_c2), do: 0x7 - def nxoxm_nsh_match_to_int(:nsh_c3), do: 0x8 - def nxoxm_nsh_match_to_int(:nsh_c4), do: 0x9 - def nxoxm_nsh_match_to_int(:nsh_ttl), do: 0xA - def nxoxm_nsh_match_to_int(_), do: throw(:bad_enum) - def nxoxm_nsh_match_to_atom(0x1), do: :nsh_flags - def nxoxm_nsh_match_to_atom(0x2), do: :nsh_mdtype - def nxoxm_nsh_match_to_atom(0x3), do: :nsh_np - def nxoxm_nsh_match_to_atom(0x4), do: :nsh_spi - def nxoxm_nsh_match_to_atom(0x5), do: :nsh_si - def nxoxm_nsh_match_to_atom(0x6), do: :nsh_c1 - def nxoxm_nsh_match_to_atom(0x7), do: :nsh_c2 - def nxoxm_nsh_match_to_atom(0x8), do: :nsh_c3 - def nxoxm_nsh_match_to_atom(0x9), do: :nsh_c4 - def nxoxm_nsh_match_to_atom(0xA), do: :nsh_ttl - def nxoxm_nsh_match_to_atom(_), do: throw(:bad_enum) + def nicira_ext_match_to_int(:nsh_flags), do: 0x1 + def nicira_ext_match_to_int(:nsh_mdtype), do: 0x2 + def nicira_ext_match_to_int(:nsh_np), do: 0x3 + def nicira_ext_match_to_int(:nsh_spi), do: 0x4 + def nicira_ext_match_to_int(:nsh_si), do: 0x5 + def nicira_ext_match_to_int(:nsh_c1), do: 0x6 + def nicira_ext_match_to_int(:nsh_c2), do: 0x7 + def nicira_ext_match_to_int(:nsh_c3), do: 0x8 + def nicira_ext_match_to_int(:nsh_c4), do: 0x9 + def nicira_ext_match_to_int(:nsh_ttl), do: 0xA + def nicira_ext_match_to_int(_), do: throw(:bad_enum) + def nicira_ext_match_to_atom(0x1), do: :nsh_flags + def nicira_ext_match_to_atom(0x2), do: :nsh_mdtype + def nicira_ext_match_to_atom(0x3), do: :nsh_np + def nicira_ext_match_to_atom(0x4), do: :nsh_spi + def nicira_ext_match_to_atom(0x5), do: :nsh_si + def nicira_ext_match_to_atom(0x6), do: :nsh_c1 + def nicira_ext_match_to_atom(0x7), do: :nsh_c2 + def nicira_ext_match_to_atom(0x8), do: :nsh_c3 + def nicira_ext_match_to_atom(0x9), do: :nsh_c4 + def nicira_ext_match_to_atom(0xA), do: :nsh_ttl + def nicira_ext_match_to_atom(_), do: throw(:bad_enum) def onf_ext_match_to_int(:onf_tcp_flags), do: 0x2A def onf_ext_match_to_int(:onf_actset_output), do: 0x2B def onf_ext_match_to_int(:onf_pbb_uca), do: 0xA00 @@ -11563,18 +11455,6 @@ defmodule Openflow.Enums do def onf_ext_match_to_atom(0x2B), do: :onf_actset_output def onf_ext_match_to_atom(0xA00), do: :onf_pbb_uca def onf_ext_match_to_atom(_), do: throw(:bad_enum) - def nxoxm_match_to_int(:nxoxm_dp_hash), do: 0x0 - def nxoxm_match_to_int(:tun_erspan_idx), do: 0xB - def nxoxm_match_to_int(:tun_erspan_ver), do: 0xC - def nxoxm_match_to_int(:tun_erspan_dir), do: 0xD - def nxoxm_match_to_int(:tun_erspan_hwid), do: 0xE - def nxoxm_match_to_int(_), do: throw(:bad_enum) - def nxoxm_match_to_atom(0x0), do: :nxoxm_dp_hash - def nxoxm_match_to_atom(0xB), do: :tun_erspan_idx - def nxoxm_match_to_atom(0xC), do: :tun_erspan_ver - def nxoxm_match_to_atom(0xD), do: :tun_erspan_dir - def nxoxm_match_to_atom(0xE), do: :tun_erspan_hwid - def nxoxm_match_to_atom(_), do: throw(:bad_enum) def buffer_id_to_int(:no_buffer), do: 0xFFFFFFFF def buffer_id_to_int(_), do: throw(:bad_enum) def buffer_id_to_atom(0xFFFFFFFF), do: :no_buffer @@ -12008,7 +11888,6 @@ defmodule Openflow.Enums do def nicira_ext_action_to_int(Openflow.Action.NxLearn2), do: 0x2D def nicira_ext_action_to_int(Openflow.Action.NxEncap), do: 0x2E def nicira_ext_action_to_int(Openflow.Action.NxDecap), do: 0x2F - def nicira_ext_action_to_int(Openflow.Action.NxCheckPktLarger), do: 0x31 def nicira_ext_action_to_int(Openflow.Action.NxDebugRecirc), do: 0xFF def nicira_ext_action_to_int(_), do: throw(:bad_enum) def nicira_ext_action_to_atom(0x1), do: Openflow.Action.NxResubmit @@ -12048,7 +11927,6 @@ defmodule Openflow.Enums do def nicira_ext_action_to_atom(0x2D), do: Openflow.Action.NxLearn2 def nicira_ext_action_to_atom(0x2E), do: Openflow.Action.NxEncap def nicira_ext_action_to_atom(0x2F), do: Openflow.Action.NxDecap - def nicira_ext_action_to_atom(0x31), do: Openflow.Action.NxCheckPktLarger def nicira_ext_action_to_atom(0xFF), do: Openflow.Action.NxDebugRecirc def nicira_ext_action_to_atom(_), do: throw(:bad_enum) def nx_mp_algorithm_to_int(:modulo_n), do: 0x0 @@ -12486,18 +12364,14 @@ defmodule Openflow.Enums do Openflow.Utils.int_to_flags([], int, enum_of(:packet_register)) end - def int_to_flags(int, :nxoxm_nsh_match) do - Openflow.Utils.int_to_flags([], int, enum_of(:nxoxm_nsh_match)) + def int_to_flags(int, :nicira_ext_match) do + Openflow.Utils.int_to_flags([], int, enum_of(:nicira_ext_match)) end def int_to_flags(int, :onf_ext_match) do Openflow.Utils.int_to_flags([], int, enum_of(:onf_ext_match)) end - def int_to_flags(int, :nxoxm_match) do - Openflow.Utils.int_to_flags([], int, enum_of(:nxoxm_match)) - end - def int_to_flags(int, :buffer_id) do Openflow.Utils.int_to_flags([], int, enum_of(:buffer_id)) end @@ -12874,18 +12748,14 @@ defmodule Openflow.Enums do Openflow.Utils.flags_to_int(0, flags, enum_of(:packet_register)) end - def flags_to_int(flags, :nxoxm_nsh_match) do - Openflow.Utils.flags_to_int(0, flags, enum_of(:nxoxm_nsh_match)) + def flags_to_int(flags, :nicira_ext_match) do + Openflow.Utils.flags_to_int(0, flags, enum_of(:nicira_ext_match)) end def flags_to_int(flags, :onf_ext_match) do Openflow.Utils.flags_to_int(0, flags, enum_of(:onf_ext_match)) end - def flags_to_int(flags, :nxoxm_match) do - Openflow.Utils.flags_to_int(0, flags, enum_of(:nxoxm_match)) - end - def flags_to_int(flags, :buffer_id) do Openflow.Utils.flags_to_int(0, flags, enum_of(:buffer_id)) end @@ -13393,12 +13263,7 @@ defmodule Openflow.Enums do defp enum_of(:controller_max_len), do: [max: 65509, no_buffer: 65535] defp enum_of(:experimenter_oxm_vendors), - do: [ - nxoxm_nsh_match: 5_953_104, - nxoxm_match: 8992, - hp_ext_match: 9256, - onf_ext_match: 1_330_529_792 - ] + do: [nicira_ext_match: 8992, hp_ext_match: 9256, onf_ext_match: 1_330_529_792] defp enum_of(:match_type), do: [standard: 0, oxm: 1] @@ -13605,8 +13470,7 @@ defmodule Openflow.Enums do pbb_isid: 37, tunnel_id: 38, ipv6_exthdr: 39, - pbb_uca: 41, - packet_type: 44 + pbb_uca: 41 ] defp enum_of(:vlan_id), do: [vid_present: 4096, vid_none: 0] @@ -13635,7 +13499,7 @@ defmodule Openflow.Enums do defp enum_of(:packet_register), do: [xreg0: 0, xreg1: 1, xreg2: 2, xreg3: 3, xreg4: 4, xreg5: 5, xreg6: 6, xreg7: 7] - defp enum_of(:nxoxm_nsh_match), + defp enum_of(:nicira_ext_match), do: [ nsh_flags: 1, nsh_mdtype: 2, @@ -13650,16 +13514,6 @@ defmodule Openflow.Enums do ] defp enum_of(:onf_ext_match), do: [onf_tcp_flags: 42, onf_actset_output: 43, onf_pbb_uca: 2560] - - defp enum_of(:nxoxm_match), - do: [ - nxoxm_dp_hash: 0, - tun_erspan_idx: 11, - tun_erspan_ver: 12, - tun_erspan_dir: 13, - tun_erspan_hwid: 14 - ] - defp enum_of(:buffer_id), do: [no_buffer: 4_294_967_295] defp enum_of(:port_config), do: [port_down: 1, no_receive: 4, no_forward: 32, no_packet_in: 64] defp enum_of(:port_state), do: [link_down: 1, blocked: 2, live: 4] @@ -13888,7 +13742,6 @@ defmodule Openflow.Enums do {Openflow.Action.NxLearn2, 45}, {Openflow.Action.NxEncap, 46}, {Openflow.Action.NxDecap, 47}, - {Openflow.Action.NxCheckPktLarger, 49}, {Openflow.Action.NxDebugRecirc, 255} ] diff --git a/lib/openflow/match.ex b/lib/openflow/match.ex index b655c86..2f60a63 100644 --- a/lib/openflow/match.ex +++ b/lib/openflow/match.ex @@ -63,8 +63,8 @@ defmodule Openflow.Match do {oxm_class_int, vendor_int} -> oxm_class = Openflow.Enums.oxm_class_to_atom(oxm_class_int) oxm_field_int = Openflow.Enums.to_int(oxm_field, oxm_class) - oxm_length = div(n_bits_of(oxm_field) + 4, 8) - <> + oxm_length = div(n_bits_of(oxm_field) + 6, 8) + <> oxm_class_int -> oxm_class = Openflow.Enums.oxm_class_to_atom(oxm_class_int) @@ -141,15 +141,15 @@ defmodule Openflow.Match do acc, << 0xFFFF::16, - field_int::7, + _::7, has_mask::1, length::8, body_bin::size(length)-bytes, rest::bytes >> ) do - value_len = length - 4 - <> = body_bin + value_len = length - 6 + <> = body_bin oxm_field = match_field({0xFFFF, exp_int}, field_int) field = decode_field(has_mask, oxm_field, value_bin) decode_fields([field | acc], rest) @@ -370,8 +370,7 @@ defmodule Openflow.Match do :pbb_isid, :tunnel_id, :ipv6_exthdr, - :pbb_uca, - :packet_type + :pbb_uca ], do: 0x8000 @@ -545,7 +544,7 @@ defmodule Openflow.Match do ], do: 0x0001 - # Nicira NSH Ext + # Nicira Ext defp match_class(f) when f in [ :nsh_flags, @@ -559,17 +558,6 @@ defmodule Openflow.Match do :nsh_c4, :nsh_ttl ], - do: {0xFFFF, 0x005AD650} - - # Nicira Ext - defp match_class(f) - when f in [ - :nxoxm_dp_hash, - :tun_erspan_idx, - :tun_erspan_ver, - :tun_erspan_dir, - :tun_erspan_hwid - ], do: {0xFFFF, 0x00002320} # ONF Ext @@ -704,10 +692,7 @@ defmodule Openflow.Match do :nsh_si, :nsh_ttl, :pbb_uca, - :onf_pbb_uca, - :tun_erspan_ver, - :tun_erspan_dir, - :tun_erspan_hwid + :onf_pbb_uca ], do: :u8 @@ -766,7 +751,6 @@ defmodule Openflow.Match do :nx_ipv6_flabel, :pkt_mark, :dp_hash, - :nxoxm_dp_hash, :recirc_id, :conj_id, :ct_mark, @@ -774,9 +758,7 @@ defmodule Openflow.Match do :nsh_c1, :nsh_c2, :nsh_c3, - :nsh_c4, - :packet_type, - :tun_erspan_idx + :nsh_c4 ], do: :u32 @@ -880,7 +862,7 @@ defmodule Openflow.Match do do: :arbitrary defp oxm_header__({class, exp}, field, has_mask, length), - do: <> + do: <> defp oxm_header__(class, field, has_mask, length), do: <> diff --git a/lib/tres/actions.ex b/lib/tres/actions.ex deleted file mode 100644 index 8ed6b45..0000000 --- a/lib/tres/actions.ex +++ /dev/null @@ -1,82 +0,0 @@ -defmodule Tres.Actions do - @moduledoc """ - Action aliases - """ - - defmacro __using__(_) do - quote do - alias Openflow.Action.Output - alias Openflow.Action.CopyTtlOut - alias Openflow.Action.CopyTtlIn - alias Openflow.Action.SetMplsTtl - alias Openflow.Action.DecMplsTtl - alias Openflow.Action.PushVlan - alias Openflow.Action.PopVlan - alias Openflow.Action.PushMpls - alias Openflow.Action.PopMpls - alias Openflow.Action.SetQueue - alias Openflow.Action.Group - alias Openflow.Action.SetNwTtl - alias Openflow.Action.DecNwTtl - alias Openflow.Action.SetField - alias Openflow.Action.PushPbb - alias Openflow.Action.PopPbb - alias Openflow.Action.Encap - alias Openflow.Action.Decap - alias Openflow.Action.SetSequence - alias Openflow.Action.ValidateSequence - - alias Openflow.Action.NxResubmit - alias Openflow.Action.NxSetTunnel - alias Openflow.Action.NxSetQueue - alias Openflow.Action.NxPopQueue - alias Openflow.Action.NxRegMove - alias Openflow.Action.NxRegLoad - alias Openflow.Action.NxNote - alias Openflow.Action.NxSetTunnel64 - alias Openflow.Action.NxMultipath - alias Openflow.Action.NxBundle - alias Openflow.Action.NxBundleLoad - alias Openflow.Action.NxResubmitTable - alias Openflow.Action.NxOutputReg - alias Openflow.Action.NxLearn - alias Openflow.Action.NxExit - alias Openflow.Action.NxDecTtl - alias Openflow.Action.NxFinTimeout - alias Openflow.Action.NxController - alias Openflow.Action.NxDecTtlCntIds - alias Openflow.Action.NxWriteMetadata - alias Openflow.Action.NxPushMpls - alias Openflow.Action.NxPopMpls - alias Openflow.Action.NxSetMplsTtl - alias Openflow.Action.NxDecMplsTtl - alias Openflow.Action.NxStackPush - alias Openflow.Action.NxStackPop - alias Openflow.Action.NxSample - alias Openflow.Action.NxSetMplsLabel - alias Openflow.Action.NxSetMplsTc - alias Openflow.Action.NxOutputReg2 - alias Openflow.Action.NxRegLoad2 - alias Openflow.Action.NxConjunction - alias Openflow.Action.NxConntrack - alias Openflow.Action.NxNat - alias Openflow.Action.NxController2 - alias Openflow.Action.NxSample2 - alias Openflow.Action.NxOutputTrunc - alias Openflow.Action.NxGroup - alias Openflow.Action.NxSample3 - alias Openflow.Action.NxClone - alias Openflow.Action.NxCtClear - alias Openflow.Action.NxResubmitTableCt - alias Openflow.Action.NxLearn2 - alias Openflow.Action.NxEncap - alias Openflow.Action.NxDecap - alias Openflow.Action.NxDebugRecirc - alias Openflow.Action.NxCheckPktLarger - - alias Openflow.Action.NxFlowSpecMatch - alias Openflow.Action.NxFlowSpecLoad - alias Openflow.Action.NxFlowSpecOutput - end - end -end diff --git a/lib/tres/controller.ex b/lib/tres/controller.ex index 34be717..323355e 100644 --- a/lib/tres/controller.ex +++ b/lib/tres/controller.ex @@ -10,9 +10,7 @@ defmodule Tres.Controller do get_current_xid: 1 ] - use Tres.Actions use Tres.Messages - use Tres.Instructions use Tres.MessageHelper def handler_spec(dpid) do diff --git a/lib/tres/instructions.ex b/lib/tres/instructions.ex deleted file mode 100644 index 36a3908..0000000 --- a/lib/tres/instructions.ex +++ /dev/null @@ -1,16 +0,0 @@ -defmodule Tres.Instructions do - @moduledoc """ - Instruction Aliases - """ - - defmacro __using__(_) do - quote do - alias Openflow.Instruction.GotoTable - alias Openflow.Instruction.WriteMetadata - alias Openflow.Instruction.WriteActions - alias Openflow.Instruction.ApplyActions - alias Openflow.Instruction.ClearActions - alias Openflow.Instruction.Meter - end - end -end diff --git a/lib/tres/messages.ex b/lib/tres/messages.ex index 4a6fea8..04810a2 100644 --- a/lib/tres/messages.ex +++ b/lib/tres/messages.ex @@ -43,6 +43,85 @@ defmodule Tres.Messages do alias Openflow.Multipart.TableFeatures alias Openflow.Multipart.PortDesc + alias Openflow.Instruction.GotoTable + alias Openflow.Instruction.WriteMetadata + alias Openflow.Instruction.WriteActions + alias Openflow.Instruction.ApplyActions + alias Openflow.Instruction.ClearActions + alias Openflow.Instruction.Meter + + alias Openflow.Action.Output + alias Openflow.Action.CopyTtlOut + alias Openflow.Action.CopyTtlIn + alias Openflow.Action.SetMplsTtl + alias Openflow.Action.DecMplsTtl + alias Openflow.Action.PushVlan + alias Openflow.Action.PopVlan + alias Openflow.Action.PushMpls + alias Openflow.Action.PopMpls + alias Openflow.Action.SetQueue + alias Openflow.Action.Group + alias Openflow.Action.SetNwTtl + alias Openflow.Action.DecNwTtl + alias Openflow.Action.SetField + alias Openflow.Action.PushPbb + alias Openflow.Action.PopPbb + alias Openflow.Action.Encap + alias Openflow.Action.Decap + alias Openflow.Action.SetSequence + alias Openflow.Action.ValidateSequence + + alias Openflow.Action.NxResubmit + alias Openflow.Action.NxSetTunnel + alias Openflow.Action.NxSetQueue + alias Openflow.Action.NxPopQueue + alias Openflow.Action.NxRegMove + alias Openflow.Action.NxRegLoad + alias Openflow.Action.NxNote + alias Openflow.Action.NxSetTunnel64 + alias Openflow.Action.NxMultipath + alias Openflow.Action.NxBundle + alias Openflow.Action.NxBundleLoad + alias Openflow.Action.NxResubmitTable + alias Openflow.Action.NxOutputReg + alias Openflow.Action.NxLearn + alias Openflow.Action.NxExit + alias Openflow.Action.NxDecTtl + alias Openflow.Action.NxFinTimeout + alias Openflow.Action.NxController + alias Openflow.Action.NxDecTtlCntIds + alias Openflow.Action.NxWriteMetadata + alias Openflow.Action.NxPushMpls + alias Openflow.Action.NxPopMpls + alias Openflow.Action.NxSetMplsTtl + alias Openflow.Action.NxDecMplsTtl + alias Openflow.Action.NxStackPush + alias Openflow.Action.NxStackPop + alias Openflow.Action.NxSample + alias Openflow.Action.NxSetMplsLabel + alias Openflow.Action.NxSetMplsTc + alias Openflow.Action.NxOutputReg2 + alias Openflow.Action.NxRegLoad2 + alias Openflow.Action.NxConjunction + alias Openflow.Action.NxConntrack + alias Openflow.Action.NxNat + alias Openflow.Action.NxController2 + alias Openflow.Action.NxSample2 + alias Openflow.Action.NxOutputTrunc + alias Openflow.Action.NxGroup + alias Openflow.Action.NxSample3 + alias Openflow.Action.NxClone + alias Openflow.Action.NxCtClear + alias Openflow.Action.NxResubmitTableCt + alias Openflow.Action.NxLearn2 + alias Openflow.Action.NxEncap + alias Openflow.Action.NxDecap + alias Openflow.Action.NxDebugRecirc + + alias Openflow.Action.NxFlowSpecMatch + alias Openflow.Action.NxFlowSpecLoad + alias Openflow.Action.NxFlowSpecOutput + alias Tres.SwitchRegistry end end diff --git a/mix.exs b/mix.exs index 0bfb166..0ac30ca 100644 --- a/mix.exs +++ b/mix.exs @@ -8,7 +8,7 @@ defmodule Tres.Mixfile do def project do [ app: :tres, - version: "0.1.3", + version: "0.1.2", description: @description, elixir: "~> 1.8", package: package(), diff --git a/priv/openflow_enum_gen.exs b/priv/openflow_enum_gen.exs index beb1c3b..ae370b7 100644 --- a/priv/openflow_enum_gen.exs +++ b/priv/openflow_enum_gen.exs @@ -304,8 +304,7 @@ enums = [ no_buffer: 0xFFFF ], experimenter_oxm_vendors: [ - nxoxm_nsh_match: 0x005AD650, - nxoxm_match: 0x00002320, + nicira_ext_match: 0x00002320, hp_ext_match: 0x00002428, onf_ext_match: 0x4F4E4600 ], @@ -509,8 +508,7 @@ enums = [ pbb_isid: 37, tunnel_id: 38, ipv6_exthdr: 39, - pbb_uca: 41, - packet_type: 44 + pbb_uca: 41 ], vlan_id: [ # Bit that indicate that a VLAN id is set. @@ -572,7 +570,7 @@ enums = [ xreg6: 6, xreg7: 7 ], - nxoxm_nsh_match: [ + nicira_ext_match: [ nsh_flags: 1, nsh_mdtype: 2, nsh_np: 3, @@ -589,13 +587,6 @@ enums = [ onf_actset_output: 43, onf_pbb_uca: 2560 ], - nxoxm_match: [ - nxoxm_dp_hash: 0, - tun_erspan_idx: 11, - tun_erspan_ver: 12, - tun_erspan_dir: 13, - tun_erspan_hwid: 14 - ], buffer_id: [ no_buffer: 0xFFFFFFFF ], @@ -870,7 +861,6 @@ enums = [ {Openflow.Action.NxLearn2, 45}, {Openflow.Action.NxEncap, 46}, {Openflow.Action.NxDecap, 47}, - {Openflow.Action.NxCheckPktLarger, 49}, {Openflow.Action.NxDebugRecirc, 0xFF} ], nx_mp_algorithm: [ diff --git a/test/lib/openflow/ofp_action_test.exs b/test/lib/openflow/ofp_action_test.exs index 1edc5d8..f2c6296 100644 --- a/test/lib/openflow/ofp_action_test.exs +++ b/test/lib/openflow/ofp_action_test.exs @@ -741,7 +741,7 @@ defmodule OfpActionTest do fin_idle_timeout: 2, fin_hard_timeout: 4, flow_specs: [ - Openflow.Action.NxFlowSpecMatch.new(src: :nx_vlan_tci, n_bits: 12), + Openflow.Action.NxFlowSpecMatch.new(src: :nx_vlan_tci, dst: :nx_vlan_tci, n_bits: 12), Openflow.Action.NxFlowSpecMatch.new(src: :nx_eth_src, dst: :nx_eth_dst), Openflow.Action.NxFlowSpecOutput.new(src: :nx_in_port) ] @@ -773,7 +773,7 @@ defmodule OfpActionTest do result_dst: :reg0, result_dst_offset: 8, flow_specs: [ - Openflow.Action.NxFlowSpecMatch.new(src: :nx_vlan_tci, n_bits: 12), + Openflow.Action.NxFlowSpecMatch.new(src: :nx_vlan_tci, dst: :nx_vlan_tci, n_bits: 12), Openflow.Action.NxFlowSpecMatch.new(src: :nx_eth_src, dst: :nx_eth_dst), Openflow.Action.NxFlowSpecOutput.new(src: :nx_in_port) ] @@ -846,21 +846,22 @@ defmodule OfpActionTest do end test "with no option" do - assert_raise RuntimeError, ":src must be specified", fn -> + assert_raise RuntimeError, ":dst must be specified", fn -> Openflow.Action.NxFlowSpecMatch.new() end end + test "with no dst option" do + assert_raise RuntimeError, ":dst must be specified", fn -> + Openflow.Action.NxFlowSpecMatch.new(src: :in_port) + end + end + test "with no src option" do assert_raise RuntimeError, ":src must be specified", fn -> Openflow.Action.NxFlowSpecMatch.new(dst: :reg0) end end - - test "with no dst option" do - learn = Openflow.Action.NxFlowSpecMatch.new(src: :in_port) - assert learn.dst == :in_port - end end describe "Openflow.Action.NxFlowSpecLoad" do @@ -1016,37 +1017,6 @@ defmodule OfpActionTest do end end - describe "Openflow.Action.NxCheckPktLarger" do - test "with options: if the packet larger than 100 bytes, set mark to reg1" do - test_file = "test/packet_data/nx_check_pkt_larger.raw" - packet = File.read!(test_file) - actions = Openflow.Action.read(packet) - - check_pkt_larger = - Openflow.Action.NxCheckPktLarger.new( - dst_field: :reg1, - offset: 0, - pkt_len: 100 - ) - - actions_bin = Openflow.Action.to_binary(check_pkt_larger) - assert actions_bin == packet - assert actions == [check_pkt_larger] - end - - test "with no dst_field option" do - assert_raise RuntimeError, "dst_field must be specified", fn -> - Openflow.Action.NxCheckPktLarger.new(pkt_len: 100) - end - end - - test "with no pkt_len option" do - assert_raise RuntimeError, "pkt_len must be specified", fn -> - Openflow.Action.NxCheckPktLarger.new(dst_field: :reg1) - end - end - end - describe "Openflow.Action.NxRegMove" do test "with options: move in_port value to vlan_tci field" do test_file = "test/packet_data/nx_reg_move.raw" diff --git a/test/lib/openflow/ofp_flow_mod_test.exs b/test/lib/openflow/ofp_flow_mod_test.exs index 2d593e6..aca8f69 100644 --- a/test/lib/openflow/ofp_flow_mod_test.exs +++ b/test/lib/openflow/ofp_flow_mod_test.exs @@ -12,6 +12,62 @@ defmodule OfpFlowModTest do @flow_mod8 "test/packet_data/libofproto-OFP13-flow_mod_match_conj.packet" describe "Openflow.read/1" do + test "with OFP_FLOW_MOD packet(1)" do + binary = File.read!(@flow_mod1) + + fm = + binary + |> Openflow.read() + |> elem(1) + |> Map.to_list() + |> Openflow.FlowMod.new() + |> Openflow.to_binary() + |> Openflow.read() + |> elem(1) + + assert fm.cookie == 0 + assert fm.cookie_mask == 0 + assert fm.table_id == 1 + assert fm.command == :add + assert fm.idle_timeout == 0 + assert fm.hard_timeout == 0 + assert fm.priority == 123 + assert fm.buffer_id == 0xFFFF + assert fm.out_port == :any + assert fm.out_group == :any + assert fm.flags == [] + assert fm.match == Openflow.Match.new(eth_dst: <<0xF20BA47DF8EA::48>>) + + assert fm.instructions == [ + Openflow.Instruction.WriteActions.new([ + Openflow.Action.SetField.new(vlan_vid: 258), + Openflow.Action.CopyTtlOut.new(), + Openflow.Action.CopyTtlIn.new(), + Openflow.Action.CopyTtlIn.new(), + Openflow.Action.PopPbb.new(), + Openflow.Action.PushPbb.new(4660), + Openflow.Action.PopMpls.new(39030), + Openflow.Action.PushMpls.new(34887), + Openflow.Action.PopVlan.new(), + Openflow.Action.PushVlan.new(33024), + Openflow.Action.DecMplsTtl.new(), + Openflow.Action.SetMplsTtl.new(10), + Openflow.Action.DecNwTtl.new(), + Openflow.Action.SetNwTtl.new(10), + Openflow.Action.Experimenter.new(101, <<0, 1, 2, 3, 4, 5, 6, 7>>), + Openflow.Action.SetQueue.new(3), + Openflow.Action.Group.new(99), + Openflow.Action.Output.new(6) + ]), + Openflow.Instruction.ApplyActions.new([ + Openflow.Action.SetField.new(eth_src: <<0x010203040506::48>>), + Openflow.Action.SetField.new(onf_pbb_uca: 1) + ]) + ] + + assert Openflow.to_binary(fm) == binary + end + test "with OFP_FLOW_MOD packet(2)" do binary = File.read!(@flow_mod2) {:ok, fm, ""} = Openflow.read(binary) @@ -58,6 +114,72 @@ defmodule OfpFlowModTest do assert Openflow.to_binary(fm) == binary end + test "with OFP_FLOW_MOD packet(4)" do + binary = File.read!(@flow_mod4) + {:ok, fm, ""} = Openflow.read(binary) + + assert fm.cookie == 0 + assert fm.cookie_mask == 0 + assert fm.table_id == 1 + assert fm.command == :add + assert fm.idle_timeout == 0 + assert fm.hard_timeout == 0 + assert fm.priority == 123 + assert fm.buffer_id == 0xFFFF + assert fm.out_port == :any + assert fm.out_group == :any + assert fm.flags == [] + + assert fm.match == + Openflow.Match.new( + in_port: 84_281_096, + in_phy_port: 16_909_060, + metadata: 283_686_952_306_183, + eth_type: 2054, + eth_dst: <<0xFFFFFFFFFFFF::48>>, + eth_src: <<0xF20BA47DF8EA::48>>, + vlan_vid: 999, + ip_dscp: 9, + ip_ecn: 3, + ip_proto: 99, + ipv4_src: {1, 2, 3, 4}, + ipv4_dst: {1, 2, 3, 4}, + tcp_src: 8080, + tcp_dst: 18_080, + udp_src: 28_080, + udp_dst: 55_936, + sctp_src: 48_080, + sctp_dst: 59_328, + icmpv4_type: 100, + icmpv4_code: 101, + arp_op: 1, + arp_spa: {10, 0, 0, 1}, + arp_tpa: {10, 0, 0, 3}, + arp_sha: <<0xF20BA47DF8EA::48>>, + arp_tha: <<0x000000000000::48>>, + ipv6_src: {65152, 0, 0, 0, 61451, 42239, 65096, 10405}, + ipv6_dst: {65152, 0, 0, 0, 61451, 42239, 65029, 47068}, + ipv6_flabel: 541_473, + icmpv6_type: 200, + icmpv6_code: 201, + ipv6_nd_target: {65152, 0, 0, 0, 2656, 28415, 65151, 29927}, + ipv6_nd_sll: <<0x00000000029A::48>>, + ipv6_nd_tll: <<0x00000000022B::48>>, + mpls_label: 624_485, + mpls_tc: 5, + mpls_bos: 1, + pbb_isid: 11_259_375, + tunnel_id: 651_061_555_542_690_057, + ipv6_exthdr: [:auth, :frag, :router, :hop, :unrep, :unseq], + onf_pbb_uca: 1, + tun_src: {1, 2, 3, 4}, + tun_dst: {1, 2, 3, 4} + ) + + assert fm.instructions == [] + assert Openflow.to_binary(fm) == binary + end + test "with OFP_FLOW_MOD packet(5)" do binary = File.read!(@flow_mod5) {:ok, fm, ""} = Openflow.read(binary) diff --git a/test/lib/openflow/ofp_flow_stats_test.exs b/test/lib/openflow/ofp_flow_stats_test.exs index 845e702..96fe3dc 100644 --- a/test/lib/openflow/ofp_flow_stats_test.exs +++ b/test/lib/openflow/ofp_flow_stats_test.exs @@ -20,4 +20,122 @@ defmodule OfpFlowStatsTest do assert flow_stats.match == [] end end + + describe "Openflow.Multipart.Flow.Reply" do + test "with test packet_data" do + flow_stats = + "test/packet_data/4-12-ofp_flow_stats_reply.packet" + |> File.read!() + |> Openflow.read() + |> Kernel.elem(1) + + %Openflow.Multipart.Flow.Reply{ + aux_id: nil, + datapath_id: nil, + flags: [], + flows: [ + %Openflow.Multipart.FlowStats{ + byte_count: 0, + cookie: 0, + duration_nsec: 115_277_000, + duration_sec: 358, + flags: [], + hard_timeout: 0, + idle_timeout: 0, + instructions: [], + match: [], + packet_count: 0, + priority: 65535, + table_id: 0 + }, + %Openflow.Multipart.FlowStats{ + byte_count: 0, + cookie: 0, + duration_nsec: 115_055_000, + duration_sec: 358, + flags: [], + hard_timeout: 0, + idle_timeout: 0, + instructions: [ + %Openflow.Instruction.ApplyActions{ + actions: [%Openflow.Action.Output{max_len: 0, port_number: :normal}] + } + ], + match: [eth_type: 2054], + packet_count: 0, + priority: 65534, + table_id: 0 + }, + %Openflow.Multipart.FlowStats{ + byte_count: 238, + cookie: 0, + duration_nsec: 511_582_000, + duration_sec: 316_220, + flags: [], + hard_timeout: 0, + idle_timeout: 0, + instructions: [%Openflow.Instruction.GotoTable{table_id: 1}], + match: [in_port: 6, eth_src: <<0xF20BA47DF8EA::48>>], + packet_count: 3, + priority: 123, + table_id: 0 + }, + %Openflow.Multipart.FlowStats{ + byte_count: 98, + cookie: 0, + duration_nsec: 980_901_000, + duration_sec: 313_499, + flags: [], + hard_timeout: 0, + idle_timeout: 0, + instructions: [ + %Openflow.Instruction.WriteActions{ + actions: [ + %Openflow.Action.SetField{field: [vlan_vid: 258]}, + %Openflow.Action.CopyTtlOut{}, + %Openflow.Action.CopyTtlIn{}, + %Openflow.Action.CopyTtlIn{}, + %Openflow.Action.PopPbb{}, + %Openflow.Action.PushPbb{ethertype: 4660}, + %Openflow.Action.PopMpls{ethertype: 39030}, + %Openflow.Action.PushMpls{ethertype: 34887}, + %Openflow.Action.PopVlan{}, + %Openflow.Action.PushVlan{ethertype: 33024}, + %Openflow.Action.DecMplsTtl{}, + %Openflow.Action.SetMplsTtl{ttl: 10}, + %Openflow.Action.DecNwTtl{}, + %Openflow.Action.SetNwTtl{ttl: 10}, + %Openflow.Action.SetQueue{id: 3}, + %Openflow.Action.Group{id: 99}, + %Openflow.Action.Output{max_len: :no_buffer, port_number: 6}, + %Openflow.Action.Experimenter{data: "exp_data", exp_id: 98_765_432}, + %Openflow.Action.Experimenter{data: "exp_data", exp_id: 8992} + ] + }, + %Openflow.Instruction.ApplyActions{ + actions: [ + %Openflow.Action.SetField{field: [eth_src: <<0x010203040506::48>>]}, + %Openflow.Action.SetField{field: [onf_pbb_uca: 1]} + ] + }, + %Openflow.Instruction.WriteActions{ + actions: [ + %Openflow.Action.Output{ + max_len: :no_buffer, + port_number: :controller + } + ] + } + ], + match: [], + packet_count: 1, + priority: 0, + table_id: 0 + } + ], + version: 4, + xid: 0 + } = flow_stats + end + end end diff --git a/test/lib/openflow/ofp_packet_in_test.exs b/test/lib/openflow/ofp_packet_in_test.exs index 37381e1..5199fc2 100644 --- a/test/lib/openflow/ofp_packet_in_test.exs +++ b/test/lib/openflow/ofp_packet_in_test.exs @@ -27,5 +27,63 @@ defmodule OfpPacketInTest do arp_tha: <<0x000000000000::48>> ] end + + test "with OFP_PACKET_IN packet(with complex matches)" do + {:ok, pktin, ""} = + "test/packet_data/4-59-ofp_packet_in.packet" + |> File.read!() + |> Openflow.read() + + assert pktin.version == 4 + assert pktin.xid == 0 + assert pktin.total_len == 0 + assert pktin.table_id == 200 + assert pktin.reason == :no_match + assert pktin.in_port == 84_281_096 + + assert pktin.match == [ + in_phy_port: 16_909_060, + metadata: 283_686_952_306_183, + eth_type: 2054, + eth_dst: <<0xFFFFFFFFFFFF::48>>, + eth_src: <<0xF20BA47DF8EA::48>>, + vlan_vid: 999, + ip_dscp: 9, + ip_ecn: 3, + ip_proto: 99, + ipv4_src: {1, 2, 3, 4}, + ipv4_dst: {1, 2, 3, 4}, + tcp_src: 8080, + tcp_dst: 18080, + udp_src: 28080, + udp_dst: 55936, + sctp_src: 48080, + sctp_dst: 59328, + icmpv4_type: 100, + icmpv4_code: 101, + arp_op: 1, + arp_spa: {10, 0, 0, 1}, + arp_tpa: {10, 0, 0, 3}, + arp_sha: <<0xF20BA47DF8EA::48>>, + arp_tha: <<0x000000000000::48>>, + ipv6_src: {65152, 0, 0, 0, 61451, 42239, 65096, 10405}, + ipv6_dst: {65152, 0, 0, 0, 61451, 42239, 65029, 47068}, + ipv6_flabel: 541_473, + icmpv6_type: 200, + icmpv6_code: 201, + ipv6_nd_target: {65152, 0, 0, 0, 2656, 28415, 65151, 29927}, + ipv6_nd_sll: <<0x00000000029A::48>>, + ipv6_nd_tll: <<0x00000000022B::48>>, + mpls_label: 624_485, + mpls_tc: 5, + mpls_bos: 1, + pbb_isid: 11_259_375, + tunnel_id: 651_061_555_542_690_057, + ipv6_exthdr: [:auth, :frag, :router, :hop, :unrep, :unseq], + onf_pbb_uca: 1, + tun_src: {1, 2, 3, 4}, + tun_dst: {1, 2, 3, 4} + ] + end end end diff --git a/test/packet_data/nx_check_pkt_larger.raw b/test/packet_data/nx_check_pkt_larger.raw deleted file mode 100644 index adeeeee..0000000 Binary files a/test/packet_data/nx_check_pkt_larger.raw and /dev/null differ