From 8c2484e68312e42a7135e6ea0047a84b792c3584 Mon Sep 17 00:00:00 2001 From: Eishun Kondoh Date: Sat, 15 Jun 2019 11:03:35 +0900 Subject: [PATCH 01/12] README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c391143..ec22282 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Tres is a framework and set of helper libraries to develop OpenFlow controllers ```elixir def deps do [ - {:tres, "~> 0.1.0"} + {:tres, "~> 0.1.1"} ] end ``` From e65bf77a3cfc1b16be7806c3e076039b5859f947 Mon Sep 17 00:00:00 2001 From: Eishun Kondoh Date: Sat, 15 Jun 2019 12:06:22 +0900 Subject: [PATCH 02/12] Better badges --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ec22282..73629da 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![codecov](https://img.shields.io/codecov/c/github/shun159/tres/develop.svg?style=flat-square)](https://codecov.io/gh/shun159/tres) [![Supported OTP version](https://img.shields.io/badge/erlang-22.x-blue.svg?style=flat-square)](http://erlang.org/) [![LICENSE](https://img.shields.io/badge/license-SUSHI--WARE%F0%9F%8D%A3-blue.svg?style=flat-square)](https://github.com/MakeNowJust/sushi-ware) -[![hex version](https://img.shields.io/badge/hex-0.1.0-yellow.svg?style=flat-square)](https://hex.pm/packages/tres/0.1.0) +[![Hex Version](https://img.shields.io/hexpm/v/tres.svg?style=flat-square)](https://hex.pm/packages/tres) ## Overview From 9ddd82fcab5d9d513edcd470fc32f8b20598b19c Mon Sep 17 00:00:00 2001 From: Eishun Kondoh Date: Tue, 9 Jul 2019 11:58:23 +0900 Subject: [PATCH 03/12] openflow/match: Refactored --- config/config.exs | 2 +- .../lib/learning_switch/ofctl.ex | 6 +- .../lib/nx_learning_switch.ex | 8 +- .../simple_router/lib/simple_router/config.ex | 11 +- .../lib/simple_router/ipv4_address.ex | 120 ++ .../lib/simple_router/mac_address.ex | 87 ++ .../lib/simple_router/openflow/flow_tables.ex | 7 +- lib/openflow/actions/nx_bundle_load.ex | 2 +- lib/openflow/actions/nx_flow_spec_load.ex | 6 +- lib/openflow/actions/nx_flow_spec_match.ex | 6 +- lib/openflow/actions/nx_flow_spec_output.ex | 2 +- lib/openflow/actions/nx_multipath.ex | 2 +- lib/openflow/actions/nx_output_reg.ex | 2 +- lib/openflow/actions/nx_output_reg2.ex | 2 +- lib/openflow/actions/nx_reg_load.ex | 6 +- lib/openflow/actions/nx_reg_move.ex | 2 +- lib/openflow/actions/nx_stack_pop.ex | 2 +- lib/openflow/actions/nx_stack_push.ex | 2 +- lib/openflow/enums.ex | 697 ++--------- lib/openflow/match.ex | 1019 ++++++++++++++--- lib/openflow/match/field.ex | 673 ----------- priv/openflow_enum_gen.exs | 59 +- test/lib/openflow/ofp_flow_mod_test.exs | 30 +- test/lib/openflow/ofp_flow_removed_test.exs | 4 +- test/lib/openflow/ofp_flow_stats_test.exs | 4 +- test/lib/openflow/ofp_packet_in_test.exs | 20 +- .../lib/openflow/ofp_tables_features_test.exs | 4 +- 27 files changed, 1201 insertions(+), 1584 deletions(-) create mode 100644 examples/simple_router/lib/simple_router/ipv4_address.ex create mode 100644 examples/simple_router/lib/simple_router/mac_address.ex delete mode 100644 lib/openflow/match/field.ex diff --git a/config/config.exs b/config/config.exs index c04ed23..d9cfaf3 100644 --- a/config/config.exs +++ b/config/config.exs @@ -11,7 +11,7 @@ config :tres, callback_args: [] config :logger, - level: :debug, + level: :info, format: "$date $time [$level] $message\n", metadata: [], handle_otp_reports: true diff --git a/examples/learning_switch/lib/learning_switch/ofctl.ex b/examples/learning_switch/lib/learning_switch/ofctl.ex index 8c42401..cc9cb8f 100644 --- a/examples/learning_switch/lib/learning_switch/ofctl.ex +++ b/examples/learning_switch/lib/learning_switch/ofctl.ex @@ -11,9 +11,9 @@ defmodule LearningSwitch.Ofctl do @aging_time 180 - @mcast {"010000000000", "110000000000"} - @bcast "ffffffffffff" - @ipv6_mcast {"333300000000", "ffff00000000"} + @mcast {<<0x010000000000::48>>, <<0x110000000000::48>>} + @bcast <<0xffffffffffff::48>> + @ipv6_mcast {<<0x333300000000::48>>, <<0xffff00000000::48>>} defmodule State do defstruct [ diff --git a/examples/nx_learning_switch/lib/nx_learning_switch.ex b/examples/nx_learning_switch/lib/nx_learning_switch.ex index 08214a1..2565ec2 100644 --- a/examples/nx_learning_switch/lib/nx_learning_switch.ex +++ b/examples/nx_learning_switch/lib/nx_learning_switch.ex @@ -63,12 +63,12 @@ defmodule NxLearningSwitch do hard_timeout: 10, flow_specs: [ NxFlowSpecMatch.new( - src: :nx_eth_src, - dst: :nx_eth_dst + src: :eth_src, + dst: :eth_dst ), NxFlowSpecMatch.new( - src: :nx_vlan_tci, - dst: :nx_vlan_tci, + src: :vlan_vid, + dst: :vlan_vid, offset: 0, n_bits: 12 ), diff --git a/examples/simple_router/lib/simple_router/config.ex b/examples/simple_router/lib/simple_router/config.ex index cba4f9c..bc195d6 100644 --- a/examples/simple_router/lib/simple_router/config.ex +++ b/examples/simple_router/lib/simple_router/config.ex @@ -1,7 +1,7 @@ defmodule SimpleRouter.Config do @moduledoc false - alias Tres.IPv4Address + alias SimpleRouter.IPv4Address @spec interfaces() :: %{String.t() => map()} def interfaces do @@ -24,7 +24,7 @@ defmodule SimpleRouter.Config do entry = %{ - mac_address: String.replace(mac, ~r/:/, ""), + mac_address: mac_to_bin(mac), ip_address: ipaddr, subnet_mask: mask, network_address: IPv4Address.to_network({ipaddr, mask}), @@ -50,6 +50,13 @@ defmodule SimpleRouter.Config do end end + defp mac_to_bin(mac) do + mac + |> String.replace(~r/:/, "") + |> String.to_integer(16) + |> :binary.encode_unsigned(:big) + end + defp get_env(key, default), do: Application.get_env(:simple_router, key, default) end diff --git a/examples/simple_router/lib/simple_router/ipv4_address.ex b/examples/simple_router/lib/simple_router/ipv4_address.ex new file mode 100644 index 0000000..345e15b --- /dev/null +++ b/examples/simple_router/lib/simple_router/ipv4_address.ex @@ -0,0 +1,120 @@ +defmodule SimpleRouter.IPv4Address do + @moduledoc """ + IP Address Utils + """ + + use Bitwise + + @typep in_addr :: {byte, byte, byte, byte} + @typep in_addr_str :: String.t() + + @doc """ + iex> {{192, 168, 0, 1}, {255, 255, 255, 255}} = IPv4Address.parse(<<192, 168, 0, 1>>) + iex> {{192, 168, 0, 1}, {255, 255, 255, 255}} = IPv4Address.parse("192.168.0.1") + iex> {{192, 168, 0, 1}, {255, 255, 255, 0}} = IPv4Address.parse("192.168.0.1/24") + """ + @spec parse(in_addr_str | binary()) :: {in_addr, in_addr} + def parse(<>), do: {{a1, a2, a3, a4}, {255, 255, 255, 255}} + + def parse(addr) do + case String.split(addr, ~r/\//) do + [^addr] -> + {:ok, ipaddr} = addr |> to_charlist |> :inet.parse_address() + {ipaddr, {255, 255, 255, 255}} + + [netaddr, cidr_str] -> + cidr = String.to_integer(cidr_str) + mask = 0xFFFFFFFF >>> (32 - cidr) <<< (32 - cidr) + <> = <> + {:ok, ipaddr} = netaddr |> to_charlist |> :inet.parse_address() + {ipaddr, {m1, m2, m3, m4}} + end + end + + @doc """ + iex> addr = IPv4Address.parse("192.168.10.1/24") + iex> {192, 168, 10, 0} = IPv4Address.to_network(addr) + """ + @spec to_network({in_addr(), in_addr()}) :: in_addr() + def to_network({{a1, a2, a3, a4}, {m1, m2, m3, m4}}) do + addr_int = :binary.decode_unsigned(<>, :big) + mask_int = :binary.decode_unsigned(<>, :big) + <> = <> + {n1, n2, n3, n4} + end + + @doc """ + iex> "192.168.0.1" = IPv4Address.to_str({192, 168, 0, 1}) + """ + @spec to_str(in_addr | in_addr_str) :: in_addr_str + def to_str(addr) when is_binary(addr) do + addr + end + + def to_str(addr) when is_tuple(addr) do + "#{:inet.ntoa(addr)}" + end + + @doc """ + iex> 0xc0a80001 = IPv4Address.to_int({192, 168, 0, 1}) + """ + @spec to_int(in_addr) :: 0..0xFFFFFFFF + def to_int({a, b, c, d}) do + <> |> :binary.decode_unsigned(:big) + end + + @doc """ + iex> true = IPv4Address.is_private?({192, 168, 0, 1}) + """ + @spec is_private?(in_addr) :: boolean + def is_private?(addr) do + ipaddr_int = to_int(addr) + priv_class_a?(ipaddr_int) or priv_class_b?(ipaddr_int) or priv_class_c?(ipaddr_int) + end + + @doc """ + iex> false = IPv4Address.is_loopback?({192, 168, 0, 1}) + iex> true = IPv4Address.is_loopback?({127, 0, 0, 1}) + """ + @spec is_loopback?(in_addr) :: boolean + def is_loopback?({127, _, _, _}), do: true + def is_loopback?({_, _, _, _}), do: false + + @doc """ + iex> false = IPv4Address.is_multicast?({192, 168, 0, 1}) + iex> true = IPv4Address.is_multicast?({224, 0, 0, 1}) + """ + @spec is_multicast?(in_addr) :: boolean + def is_multicast?(in_addr) do + in_addr + |> to_int + |> mcast_class_d? + end + + @doc """ + iex> false = IPv4Address.is_broadcast?({192, 168, 0, 1}) + iex> true = IPv4Address.is_broadcast?({255, 255, 255, 255}) + """ + @spec is_broadcast?(in_addr) :: boolean + def is_broadcast?({255, _, _, _}), do: true + def is_broadcast?({_, _, _, _}), do: false + + # private functions + + @class_a_subnet 0xFF000000 + @class_b_subnet 0xFFF00000 + @class_c_subnet 0xFFFF0000 + @class_d_subnet 0xE0000000 + + @class_a_start_addr 167_772_160 + @class_b_start_addr 2_886_729_728 + @class_c_start_addr 3_232_235_520 + + defp priv_class_a?(ipaddr_int), do: (ipaddr_int &&& @class_a_subnet) == @class_a_start_addr + + defp priv_class_b?(ipaddr_int), do: (ipaddr_int &&& @class_b_subnet) == @class_b_start_addr + + defp priv_class_c?(ipaddr_int), do: (ipaddr_int &&& @class_c_subnet) == @class_c_start_addr + + defp mcast_class_d?(ipaddr_int), do: (ipaddr_int &&& @class_d_subnet) == @class_d_subnet +end diff --git a/examples/simple_router/lib/simple_router/mac_address.ex b/examples/simple_router/lib/simple_router/mac_address.ex new file mode 100644 index 0000000..2d90188 --- /dev/null +++ b/examples/simple_router/lib/simple_router/mac_address.ex @@ -0,0 +1,87 @@ +defmodule SimpleRouter.MacAddress do + @moduledoc """ + MAC Address Utils + """ + + use Bitwise + + @mac_addr_pattern ~r/^(?:[0-9a-fA-F][0-9a-fA-F]){6}$/ + + @spec bin_to_str(<<_::48>>) :: String.t() + def bin_to_str(<<_::6-bytes>> = mac) do + mac + |> :erlang.binary_to_list() + |> Enum.reduce("", &to_hex/2) + |> String.downcase() + end + + @spec to_a(String.t()) :: [non_neg_integer()] + def to_a(mac) do + mac + |> check_format() + |> to_a([]) + rescue + _e in ArgumentError -> + {:error, :invalid_format} + end + + @spec to_i(String.t()) :: non_neg_integer() + def to_i(mac) do + mac + |> check_format() + |> String.to_integer(16) + rescue + _e in ArgumentError -> + {:error, :invalid_format} + end + + @spec is_broadcast?(String.t()) :: boolean() + def is_broadcast?(mac) do + mac + |> check_format() + |> to_a() + |> Enum.at(0) + |> Kernel.==(0xFF) + rescue + _e in ArgumentError -> + {:error, :invalid_format} + end + + @spec is_multicast?(String.t()) :: boolean() + def is_multicast?(mac) do + mac + |> check_format() + |> to_a() + |> Enum.at(0) + |> Bitwise.&&&(1) + |> Kernel.==(1) + rescue + _e in ArgumentError -> + {:error, :invalid_format} + end + + # private functions + + defp to_a(<<>>, acc), do: Enum.reverse(acc) + + defp to_a(<>, acc) do + to_a(rest, [String.to_integer(octet, 16) | acc]) + end + + @spec to_hex(0..0xFF, String.t()) :: String.t() + defp to_hex(int, acc), do: "#{acc}#{to_hex(int)}" + + @spec to_hex(0..0xFF) :: String.t() + defp to_hex(int) do + int + |> Integer.to_string(16) + |> String.pad_leading(2, "0") + end + + @spec check_format(String.t()) :: String.t() | none() + defp check_format(mac) when is_binary(mac) do + if String.match?(mac, @mac_addr_pattern), + do: mac, + else: raise(ArgumentError, message: "MAC address should be 12 letters hex string format") + end +end diff --git a/examples/simple_router/lib/simple_router/openflow/flow_tables.ex b/examples/simple_router/lib/simple_router/openflow/flow_tables.ex index db4c88b..2ede7a1 100644 --- a/examples/simple_router/lib/simple_router/openflow/flow_tables.ex +++ b/examples/simple_router/lib/simple_router/openflow/flow_tables.ex @@ -5,8 +5,7 @@ defmodule SimpleRouter.Openflow.FlowTables do use Tres.Controller - alias Tres.IPv4Address - alias Tres.MacAddress + alias SimpleRouter.IPv4Address @classifier_table_id 0 @arp_handler_table_id 1 @@ -219,7 +218,7 @@ defmodule SimpleRouter.Openflow.FlowTables do defp arp_packet(iface) do ether_header = << 0xffffffffffff::48, # destination ethernet address - (MacAddress.to_i(iface.mac_address))::48, # source ethernet address + iface.mac_address::48-bits, # source ethernet address 0x0806::16 # ethernet type >> @@ -230,7 +229,7 @@ defmodule SimpleRouter.Openflow.FlowTables do 6::8, # hardware address length 4::8, # protocol address length 1::16, # ARPOP_REQUEST - (MacAddress.to_i(iface.mac_address))::48, # Source Hardware Address + iface.mac_address::48-bits, # Source Hardware Address (IPv4Address.to_int(iface.ip_address))::32, # Source Protocol Address 0x000000000000::48 # Target Hardware Address >> diff --git a/lib/openflow/actions/nx_bundle_load.ex b/lib/openflow/actions/nx_bundle_load.ex index 743689c..9816310 100644 --- a/lib/openflow/actions/nx_bundle_load.ex +++ b/lib/openflow/actions/nx_bundle_load.ex @@ -53,7 +53,7 @@ defmodule Openflow.Action.NxBundleLoad do ) :: t() def new(options \\ []) do dst_field = options[:dst_field] || raise "dst_field must be specified" - default_n_bits = Openflow.Match.Field.n_bits_of(dst_field) + default_n_bits = Openflow.Match.n_bits_of(dst_field) slaves = options[:slaves] || [] %NxBundleLoad{ diff --git a/lib/openflow/actions/nx_flow_spec_load.ex b/lib/openflow/actions/nx_flow_spec_load.ex index bd7a849..44df464 100644 --- a/lib/openflow/actions/nx_flow_spec_load.ex +++ b/lib/openflow/actions/nx_flow_spec_load.ex @@ -31,7 +31,7 @@ defmodule Openflow.Action.NxFlowSpecLoad do def new(options) do dst = options[:dst] || raise(":dst must be specified") src = options[:src] || raise(":src must be specified") - n_bits = options[:n_bits] || Openflow.Match.Field.n_bits_of(dst) + n_bits = options[:n_bits] || Openflow.Match.n_bits_of(dst) %NxFlowSpecLoad{ src: src, @@ -90,7 +90,7 @@ defmodule Openflow.Action.NxFlowSpecLoad do binary dst = Openflow.Match.codec_header(dst_bin) - src = Openflow.Match.Field.codec(src_bin, dst) + src = Openflow.Match.decode_value(src_bin, dst) flow_spec = %NxFlowSpecLoad{src: src, dst: dst, n_bits: n_bits, dst_offset: dst_ofs} {flow_spec, rest} end @@ -103,7 +103,7 @@ defmodule Openflow.Action.NxFlowSpecLoad do end defp codec_src(%NxFlowSpecLoad{src: src, dst: dst_field}) do - src_bin = Openflow.Match.Field.codec(src, dst_field) + src_bin = Openflow.Match.encode_value(src, dst_field) {@learn_src_immediate, src_bin} end end diff --git a/lib/openflow/actions/nx_flow_spec_match.ex b/lib/openflow/actions/nx_flow_spec_match.ex index 22312a9..d9b76b3 100644 --- a/lib/openflow/actions/nx_flow_spec_match.ex +++ b/lib/openflow/actions/nx_flow_spec_match.ex @@ -31,7 +31,7 @@ defmodule Openflow.Action.NxFlowSpecMatch do def new(options \\ []) do dst = options[:dst] || raise ":dst must be specified" src = options[:src] || raise ":src must be specified" - n_bits = options[:n_bits] || Openflow.Match.Field.n_bits_of(dst) + n_bits = options[:n_bits] || Openflow.Match.n_bits_of(dst) %NxFlowSpecMatch{ src: src, @@ -92,7 +92,7 @@ defmodule Openflow.Action.NxFlowSpecMatch do binary dst = Openflow.Match.codec_header(dst_bin) - src = Openflow.Match.Field.codec(src_bin, dst) + src = Openflow.Match.decode_value(src_bin, dst) flow_spec = %NxFlowSpecMatch{src: src, dst: dst, n_bits: n_bits, dst_offset: dst_ofs} {flow_spec, rest} end @@ -105,7 +105,7 @@ defmodule Openflow.Action.NxFlowSpecMatch do end defp codec_src(%NxFlowSpecMatch{src: src, dst: dst_field}) do - src_bin = Openflow.Match.Field.codec(src, dst_field) + src_bin = Openflow.Match.encode_value(src, dst_field) {@learn_src_immediate, src_bin} end end diff --git a/lib/openflow/actions/nx_flow_spec_output.ex b/lib/openflow/actions/nx_flow_spec_output.ex index 87980f7..9fa54ed 100644 --- a/lib/openflow/actions/nx_flow_spec_output.ex +++ b/lib/openflow/actions/nx_flow_spec_output.ex @@ -19,7 +19,7 @@ defmodule Openflow.Action.NxFlowSpecOutput do @spec new(src: atom(), n_bits: non_neg_integer(), src_offset: non_neg_integer()) :: t() def new(options \\ []) do src = options[:src] || raise ":src must be specified" - n_bits = options[:n_bits] || Openflow.Match.Field.n_bits_of(src) + n_bits = options[:n_bits] || Openflow.Match.n_bits_of(src) %NxFlowSpecOutput{n_bits: n_bits, src: src, src_offset: options[:src_offset] || 0} end diff --git a/lib/openflow/actions/nx_multipath.ex b/lib/openflow/actions/nx_multipath.ex index 1e7c693..e4655b1 100644 --- a/lib/openflow/actions/nx_multipath.ex +++ b/lib/openflow/actions/nx_multipath.ex @@ -21,7 +21,7 @@ defmodule Openflow.Action.NxMultipath do @spec new(Keyword.t()) :: %NxMultipath{} def new(options) do dst_field = options[:dst_field] || raise "dst_field must be specified" - default_n_bits = Openflow.Match.Field.n_bits_of(dst_field) + default_n_bits = Openflow.Match.n_bits_of(dst_field) %NxMultipath{ hash_field: options[:hash_field] || :eth_src, diff --git a/lib/openflow/actions/nx_output_reg.ex b/lib/openflow/actions/nx_output_reg.ex index a5efe89..1078754 100644 --- a/lib/openflow/actions/nx_output_reg.ex +++ b/lib/openflow/actions/nx_output_reg.ex @@ -30,7 +30,7 @@ defmodule Openflow.Action.NxOutputReg do ) :: t() def new(options) do src_field = options[:src_field] || raise "src_field must be specified" - default_n_bits = Openflow.Match.Field.n_bits_of(src_field) + default_n_bits = Openflow.Match.n_bits_of(src_field) %NxOutputReg{ n_bits: options[:n_bits] || default_n_bits, diff --git a/lib/openflow/actions/nx_output_reg2.ex b/lib/openflow/actions/nx_output_reg2.ex index bfaf212..dfcfdfd 100644 --- a/lib/openflow/actions/nx_output_reg2.ex +++ b/lib/openflow/actions/nx_output_reg2.ex @@ -30,7 +30,7 @@ defmodule Openflow.Action.NxOutputReg2 do ) :: t() def new(options) do src_field = options[:src_field] || raise "src_field must be specified" - default_n_bits = Openflow.Match.Field.n_bits_of(src_field) + default_n_bits = Openflow.Match.n_bits_of(src_field) %NxOutputReg2{ n_bits: options[:n_bits] || default_n_bits, diff --git a/lib/openflow/actions/nx_reg_load.ex b/lib/openflow/actions/nx_reg_load.ex index 8a9ccd7..9de253a 100644 --- a/lib/openflow/actions/nx_reg_load.ex +++ b/lib/openflow/actions/nx_reg_load.ex @@ -45,7 +45,7 @@ defmodule Openflow.Action.NxRegLoad do def new(options \\ []) do dst_field = options[:dst_field] || raise "dst_field must be specified" value = options[:value] || raise "value must be specified" - default_n_bits = Openflow.Match.Field.n_bits_of(dst_field) + default_n_bits = Openflow.Match.n_bits_of(dst_field) %NxRegLoad{ n_bits: options[:n_bits] || default_n_bits, @@ -61,7 +61,7 @@ defmodule Openflow.Action.NxRegLoad do value_int = load.value - |> Openflow.Match.Field.codec(load.dst_field) + |> Openflow.Match.encode_value(load.dst_field) |> :binary.decode_unsigned(:big) Experimenter.pack_exp_header(<< @@ -76,7 +76,7 @@ defmodule Openflow.Action.NxRegLoad do def read(<<@experimenter::32, @nxast::16, body::bytes>>) do <> = body dst_field = Openflow.Match.codec_header(dst_field_bin) - value = Openflow.Match.Field.codec(value_bin, dst_field) + value = Openflow.Match.decode_value(value_bin, dst_field) %NxRegLoad{n_bits: n_bits + 1, offset: ofs, dst_field: dst_field, value: value} end end diff --git a/lib/openflow/actions/nx_reg_move.ex b/lib/openflow/actions/nx_reg_move.ex index defcb65..ed9e023 100644 --- a/lib/openflow/actions/nx_reg_move.ex +++ b/lib/openflow/actions/nx_reg_move.ex @@ -147,7 +147,7 @@ defmodule Openflow.Action.NxRegMove do def new(options \\ []) do src_field = options[:src_field] || raise "src_field must be specified" dst_field = options[:dst_field] || raise "dst_field must be specified" - default_n_bits = Openflow.Match.Field.n_bits_of(dst_field) + default_n_bits = Openflow.Match.n_bits_of(dst_field) %NxRegMove{ n_bits: options[:n_bits] || default_n_bits, diff --git a/lib/openflow/actions/nx_stack_pop.ex b/lib/openflow/actions/nx_stack_pop.ex index cc3be8c..5be2b64 100644 --- a/lib/openflow/actions/nx_stack_pop.ex +++ b/lib/openflow/actions/nx_stack_pop.ex @@ -13,7 +13,7 @@ defmodule Openflow.Action.NxStackPop do def new(options) do field = options[:field] || raise "field must be specified" - default_n_bits = Openflow.Match.Field.n_bits_of(field) + default_n_bits = Openflow.Match.n_bits_of(field) %NxStackPop{ n_bits: options[:n_bits] || default_n_bits, diff --git a/lib/openflow/actions/nx_stack_push.ex b/lib/openflow/actions/nx_stack_push.ex index b4eee19..0c1a697 100644 --- a/lib/openflow/actions/nx_stack_push.ex +++ b/lib/openflow/actions/nx_stack_push.ex @@ -13,7 +13,7 @@ defmodule Openflow.Action.NxStackPush do def new(options) do field = options[:field] || raise "field must be specified" - default_n_bits = Openflow.Match.Field.n_bits_of(field) + default_n_bits = Openflow.Match.n_bits_of(field) %NxStackPush{ n_bits: options[:n_bits] || default_n_bits, diff --git a/lib/openflow/enums.ex b/lib/openflow/enums.ex index 3fd02f4..6975a3d 100644 --- a/lib/openflow/enums.ex +++ b/lib/openflow/enums.ex @@ -2725,176 +2725,20 @@ 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(:gre_flags, :openflow_basic) do - openflow_basic_to_int(:gre_flags) - catch - _class, _reason -> :gre_flags - end - - def to_int(:gre_ver, :openflow_basic) do - openflow_basic_to_int(:gre_ver) - catch - _class, _reason -> :gre_ver - end - - def to_int(:gre_protocol, :openflow_basic) do - openflow_basic_to_int(:gre_protocol) - catch - _class, _reason -> :gre_protocol - end - - def to_int(:gre_key, :openflow_basic) do - openflow_basic_to_int(:gre_key) - catch - _class, _reason -> :gre_key - end - - def to_int(:gre_seqnum, :openflow_basic) do - openflow_basic_to_int(:gre_seqnum) - catch - _class, _reason -> :gre_seqnum - end - - def to_int(:lisp_flags, :openflow_basic) do - openflow_basic_to_int(:lisp_flags) - catch - _class, _reason -> :lisp_flags - end - - def to_int(:lisp_nonce, :openflow_basic) do - openflow_basic_to_int(:lisp_nonce) - catch - _class, _reason -> :lisp_nonce - end - - def to_int(:lisp_id, :openflow_basic) do - openflow_basic_to_int(:lisp_id) - catch - _class, _reason -> :lisp_id - end - - def to_int(:vxlan_flags, :openflow_basic) do - openflow_basic_to_int(:vxlan_flags) - catch - _class, _reason -> :vxlan_flags - end - - def to_int(:vxlan_vni, :openflow_basic) do - openflow_basic_to_int(:vxlan_vni) - catch - _class, _reason -> :vxlan_vni - end - - def to_int(:mpls_data_first_nibble, :openflow_basic) do - openflow_basic_to_int(:mpls_data_first_nibble) - catch - _class, _reason -> :mpls_data_first_nibble - end - - def to_int(:mpls_ach_version, :openflow_basic) do - openflow_basic_to_int(:mpls_ach_version) - catch - _class, _reason -> :mpls_ach_version - end - - def to_int(:mpls_ach_channel, :openflow_basic) do - openflow_basic_to_int(:mpls_ach_channel) - catch - _class, _reason -> :mpls_ach_channel - end - - def to_int(:mpls_pw_metadata, :openflow_basic) do - openflow_basic_to_int(:mpls_pw_metadata) - catch - _class, _reason -> :mpls_pw_metadata - end - - def to_int(:mpls_cw_flags, :openflow_basic) do - openflow_basic_to_int(:mpls_cw_flags) - catch - _class, _reason -> :mpls_cw_flags - end - - def to_int(:mpls_cw_fragment, :openflow_basic) do - openflow_basic_to_int(:mpls_cw_fragment) - catch - _class, _reason -> :mpls_cw_fragment - end - - def to_int(:mpls_cw_len, :openflow_basic) do - openflow_basic_to_int(:mpls_cw_len) - catch - _class, _reason -> :mpls_cw_len - end - - def to_int(:mpls_cw_seq_num, :openflow_basic) do - openflow_basic_to_int(:mpls_cw_seq_num) - catch - _class, _reason -> :mpls_cw_seq_num - end - - def to_int(:gtpu_flags, :openflow_basic) do - openflow_basic_to_int(:gtpu_flags) - catch - _class, _reason -> :gtpu_flags - end - - def to_int(:gtpu_ver, :openflow_basic) do - openflow_basic_to_int(:gtpu_ver) - catch - _class, _reason -> :gtpu_ver - end - - def to_int(:gtpu_msg_type, :openflow_basic) do - openflow_basic_to_int(:gtpu_msg_type) - catch - _class, _reason -> :gtpu_msg_type - end - - def to_int(:gtpu_teid, :openflow_basic) do - openflow_basic_to_int(:gtpu_teid) - catch - _class, _reason -> :gtpu_teid - end - - def to_int(:gtpu_extn_hdr, :openflow_basic) do - openflow_basic_to_int(:gtpu_extn_hdr) - catch - _class, _reason -> :gtpu_extn_hdr - end - - def to_int(:gtpu_extn_udp_port, :openflow_basic) do - openflow_basic_to_int(:gtpu_extn_udp_port) - catch - _class, _reason -> :gtpu_extn_udp_port - end - - def to_int(:gtpu_extn_sci, :openflow_basic) do - openflow_basic_to_int(:gtpu_extn_sci) - catch - _class, _reason -> :gtpu_extn_sci - end - def to_int(_int, :openflow_basic) do throw(:bad_enum) end - def to_int(:present, :vlan_id) do - vlan_id_to_int(:present) + def to_int(:vid_present, :vlan_id) do + vlan_id_to_int(:vid_present) catch - _class, _reason -> :present + _class, _reason -> :vid_present end - def to_int(:none, :vlan_id) do - vlan_id_to_int(:none) + def to_int(:vid_none, :vlan_id) do + vlan_id_to_int(:vid_none) catch - _class, _reason -> :none + _class, _reason -> :vid_none end def to_int(_int, :vlan_id) do @@ -3017,6 +2861,22 @@ defmodule Openflow.Enums do throw(:bad_enum) end + def to_int(:policy_applied, :tun_gbp_flags) do + tun_gbp_flags_to_int(:policy_applied) + catch + _class, _reason -> :policy_applied + end + + def to_int(:dont_learn, :tun_gbp_flags) do + tun_gbp_flags_to_int(:dont_learn) + catch + _class, _reason -> :dont_learn + end + + def to_int(_int, :tun_gbp_flags) do + throw(:bad_enum) + end + def to_int(:new, :ct_state_flags) do ct_state_flags_to_int(:new) catch @@ -3175,90 +3035,16 @@ defmodule Openflow.Enums do _class, _reason -> :nsh_c4 end + 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, :nicira_ext_match) do throw(:bad_enum) end - def to_int(:hp_udp_src_port_range, :hp_ext_match) do - hp_ext_match_to_int(:hp_udp_src_port_range) - catch - _class, _reason -> :hp_udp_src_port_range - end - - def to_int(:hp_udp_dst_port_range, :hp_ext_match) do - hp_ext_match_to_int(:hp_udp_dst_port_range) - catch - _class, _reason -> :hp_udp_dst_port_range - end - - def to_int(:hp_tcp_src_port_range, :hp_ext_match) do - hp_ext_match_to_int(:hp_tcp_src_port_range) - catch - _class, _reason -> :hp_tcp_src_port_range - end - - def to_int(:hp_tcp_dst_port_range, :hp_ext_match) do - hp_ext_match_to_int(:hp_tcp_dst_port_range) - catch - _class, _reason -> :hp_tcp_dst_port_range - end - - def to_int(:hp_tcp_flags, :hp_ext_match) do - hp_ext_match_to_int(:hp_tcp_flags) - catch - _class, _reason -> :hp_tcp_flags - end - - def to_int(:hp_custom_1, :hp_ext_match) do - hp_ext_match_to_int(:hp_custom_1) - catch - _class, _reason -> :hp_custom_1 - end - - def to_int(:hp_custom_2, :hp_ext_match) do - hp_ext_match_to_int(:hp_custom_2) - catch - _class, _reason -> :hp_custom_2 - end - - def to_int(:hp_custom_3, :hp_ext_match) do - hp_ext_match_to_int(:hp_custom_3) - catch - _class, _reason -> :hp_custom_3 - end - - def to_int(:hp_custom_4, :hp_ext_match) do - hp_ext_match_to_int(:hp_custom_4) - catch - _class, _reason -> :hp_custom_4 - end - - def to_int(_int, :hp_ext_match) do - throw(:bad_enum) - end - - def to_int(:l2_start, :hp_custom_match_type) do - hp_custom_match_type_to_int(:l2_start) - catch - _class, _reason -> :l2_start - end - - def to_int(:l3_start, :hp_custom_match_type) do - hp_custom_match_type_to_int(:l3_start) - catch - _class, _reason -> :l3_start - end - - def to_int(:l4_start, :hp_custom_match_type) do - hp_custom_match_type_to_int(:l4_start) - catch - _class, _reason -> :l4_start - end - - def to_int(_int, :hp_custom_match_type) do - throw(:bad_enum) - end - def to_int(:onf_tcp_flags, :onf_ext_match) do onf_ext_match_to_int(:onf_tcp_flags) catch @@ -8141,162 +7927,6 @@ defmodule Openflow.Enums do _class, _reason -> 41 end - def to_atom(0x2A, :openflow_basic) do - openflow_basic_to_atom(0x2A) - catch - _class, _reason -> 42 - end - - def to_atom(0x2B, :openflow_basic) do - openflow_basic_to_atom(0x2B) - catch - _class, _reason -> 43 - end - - def to_atom(0x2C, :openflow_basic) do - openflow_basic_to_atom(0x2C) - catch - _class, _reason -> 44 - end - - def to_atom(0x2D, :openflow_basic) do - openflow_basic_to_atom(0x2D) - catch - _class, _reason -> 45 - end - - def to_atom(0x2E, :openflow_basic) do - openflow_basic_to_atom(0x2E) - catch - _class, _reason -> 46 - end - - def to_atom(0x2F, :openflow_basic) do - openflow_basic_to_atom(0x2F) - catch - _class, _reason -> 47 - end - - def to_atom(0x30, :openflow_basic) do - openflow_basic_to_atom(0x30) - catch - _class, _reason -> 48 - end - - def to_atom(0x31, :openflow_basic) do - openflow_basic_to_atom(0x31) - catch - _class, _reason -> 49 - end - - def to_atom(0x32, :openflow_basic) do - openflow_basic_to_atom(0x32) - catch - _class, _reason -> 50 - end - - def to_atom(0x33, :openflow_basic) do - openflow_basic_to_atom(0x33) - catch - _class, _reason -> 51 - end - - def to_atom(0x34, :openflow_basic) do - openflow_basic_to_atom(0x34) - catch - _class, _reason -> 52 - end - - def to_atom(0x35, :openflow_basic) do - openflow_basic_to_atom(0x35) - catch - _class, _reason -> 53 - end - - def to_atom(0x36, :openflow_basic) do - openflow_basic_to_atom(0x36) - catch - _class, _reason -> 54 - end - - def to_atom(0x37, :openflow_basic) do - openflow_basic_to_atom(0x37) - catch - _class, _reason -> 55 - end - - def to_atom(0x38, :openflow_basic) do - openflow_basic_to_atom(0x38) - catch - _class, _reason -> 56 - end - - def to_atom(0x39, :openflow_basic) do - openflow_basic_to_atom(0x39) - catch - _class, _reason -> 57 - end - - def to_atom(0x3A, :openflow_basic) do - openflow_basic_to_atom(0x3A) - catch - _class, _reason -> 58 - end - - def to_atom(0x3B, :openflow_basic) do - openflow_basic_to_atom(0x3B) - catch - _class, _reason -> 59 - end - - def to_atom(0x3C, :openflow_basic) do - openflow_basic_to_atom(0x3C) - catch - _class, _reason -> 60 - end - - def to_atom(0x3D, :openflow_basic) do - openflow_basic_to_atom(0x3D) - catch - _class, _reason -> 61 - end - - def to_atom(0x3E, :openflow_basic) do - openflow_basic_to_atom(0x3E) - catch - _class, _reason -> 62 - end - - def to_atom(0x3F, :openflow_basic) do - openflow_basic_to_atom(0x3F) - catch - _class, _reason -> 63 - end - - def to_atom(0x40, :openflow_basic) do - openflow_basic_to_atom(0x40) - catch - _class, _reason -> 64 - end - - def to_atom(0x41, :openflow_basic) do - openflow_basic_to_atom(0x41) - catch - _class, _reason -> 65 - end - - def to_atom(0x42, :openflow_basic) do - openflow_basic_to_atom(0x42) - catch - _class, _reason -> 66 - end - - def to_atom(0x43, :openflow_basic) do - openflow_basic_to_atom(0x43) - catch - _class, _reason -> 67 - end - def to_atom(_, :openflow_basic) do throw(:bad_enum) end @@ -8433,6 +8063,22 @@ defmodule Openflow.Enums do throw(:bad_enum) end + def to_atom(0x8, :tun_gbp_flags) do + tun_gbp_flags_to_atom(0x8) + catch + _class, _reason -> 8 + end + + def to_atom(0x40, :tun_gbp_flags) do + tun_gbp_flags_to_atom(0x40) + catch + _class, _reason -> 64 + end + + def to_atom(_, :tun_gbp_flags) do + throw(:bad_enum) + end + def to_atom(0x1, :ct_state_flags) do ct_state_flags_to_atom(0x1) catch @@ -8591,90 +8237,16 @@ defmodule Openflow.Enums do _class, _reason -> 9 end + def to_atom(0xA, :nicira_ext_match) do + nicira_ext_match_to_atom(0xA) + catch + _class, _reason -> 10 + end + def to_atom(_, :nicira_ext_match) do throw(:bad_enum) end - def to_atom(0x0, :hp_ext_match) do - hp_ext_match_to_atom(0x0) - catch - _class, _reason -> 0 - end - - def to_atom(0x1, :hp_ext_match) do - hp_ext_match_to_atom(0x1) - catch - _class, _reason -> 1 - end - - def to_atom(0x2, :hp_ext_match) do - hp_ext_match_to_atom(0x2) - catch - _class, _reason -> 2 - end - - def to_atom(0x3, :hp_ext_match) do - hp_ext_match_to_atom(0x3) - catch - _class, _reason -> 3 - end - - def to_atom(0x4, :hp_ext_match) do - hp_ext_match_to_atom(0x4) - catch - _class, _reason -> 4 - end - - def to_atom(0x5, :hp_ext_match) do - hp_ext_match_to_atom(0x5) - catch - _class, _reason -> 5 - end - - def to_atom(0x6, :hp_ext_match) do - hp_ext_match_to_atom(0x6) - catch - _class, _reason -> 6 - end - - def to_atom(0x7, :hp_ext_match) do - hp_ext_match_to_atom(0x7) - catch - _class, _reason -> 7 - end - - def to_atom(0x8, :hp_ext_match) do - hp_ext_match_to_atom(0x8) - catch - _class, _reason -> 8 - end - - def to_atom(_, :hp_ext_match) do - throw(:bad_enum) - end - - def to_atom(0x1, :hp_custom_match_type) do - hp_custom_match_type_to_atom(0x1) - catch - _class, _reason -> 1 - end - - def to_atom(0x2, :hp_custom_match_type) do - hp_custom_match_type_to_atom(0x2) - catch - _class, _reason -> 2 - end - - def to_atom(0x3, :hp_custom_match_type) do - hp_custom_match_type_to_atom(0x3) - catch - _class, _reason -> 3 - end - - def to_atom(_, :hp_custom_match_type) do - throw(:bad_enum) - end - def to_atom(0x2A, :onf_ext_match) do onf_ext_match_to_atom(0x2A) catch @@ -11722,32 +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: 0x2A - def openflow_basic_to_int(:gre_flags), do: 0x2B - def openflow_basic_to_int(:gre_ver), do: 0x2C - def openflow_basic_to_int(:gre_protocol), do: 0x2D - def openflow_basic_to_int(:gre_key), do: 0x2E - def openflow_basic_to_int(:gre_seqnum), do: 0x2F - def openflow_basic_to_int(:lisp_flags), do: 0x30 - def openflow_basic_to_int(:lisp_nonce), do: 0x31 - def openflow_basic_to_int(:lisp_id), do: 0x32 - def openflow_basic_to_int(:vxlan_flags), do: 0x33 - def openflow_basic_to_int(:vxlan_vni), do: 0x34 - def openflow_basic_to_int(:mpls_data_first_nibble), do: 0x35 - def openflow_basic_to_int(:mpls_ach_version), do: 0x36 - def openflow_basic_to_int(:mpls_ach_channel), do: 0x37 - def openflow_basic_to_int(:mpls_pw_metadata), do: 0x38 - def openflow_basic_to_int(:mpls_cw_flags), do: 0x39 - def openflow_basic_to_int(:mpls_cw_fragment), do: 0x3A - def openflow_basic_to_int(:mpls_cw_len), do: 0x3B - def openflow_basic_to_int(:mpls_cw_seq_num), do: 0x3C - def openflow_basic_to_int(:gtpu_flags), do: 0x3D - def openflow_basic_to_int(:gtpu_ver), do: 0x3E - def openflow_basic_to_int(:gtpu_msg_type), do: 0x3F - def openflow_basic_to_int(:gtpu_teid), do: 0x40 - def openflow_basic_to_int(:gtpu_extn_hdr), do: 0x41 - def openflow_basic_to_int(:gtpu_extn_udp_port), do: 0x42 - def openflow_basic_to_int(:gtpu_extn_sci), do: 0x43 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 @@ -11790,38 +11336,12 @@ 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(0x2A), do: :packet_type - def openflow_basic_to_atom(0x2B), do: :gre_flags - def openflow_basic_to_atom(0x2C), do: :gre_ver - def openflow_basic_to_atom(0x2D), do: :gre_protocol - def openflow_basic_to_atom(0x2E), do: :gre_key - def openflow_basic_to_atom(0x2F), do: :gre_seqnum - def openflow_basic_to_atom(0x30), do: :lisp_flags - def openflow_basic_to_atom(0x31), do: :lisp_nonce - def openflow_basic_to_atom(0x32), do: :lisp_id - def openflow_basic_to_atom(0x33), do: :vxlan_flags - def openflow_basic_to_atom(0x34), do: :vxlan_vni - def openflow_basic_to_atom(0x35), do: :mpls_data_first_nibble - def openflow_basic_to_atom(0x36), do: :mpls_ach_version - def openflow_basic_to_atom(0x37), do: :mpls_ach_channel - def openflow_basic_to_atom(0x38), do: :mpls_pw_metadata - def openflow_basic_to_atom(0x39), do: :mpls_cw_flags - def openflow_basic_to_atom(0x3A), do: :mpls_cw_fragment - def openflow_basic_to_atom(0x3B), do: :mpls_cw_len - def openflow_basic_to_atom(0x3C), do: :mpls_cw_seq_num - def openflow_basic_to_atom(0x3D), do: :gtpu_flags - def openflow_basic_to_atom(0x3E), do: :gtpu_ver - def openflow_basic_to_atom(0x3F), do: :gtpu_msg_type - def openflow_basic_to_atom(0x40), do: :gtpu_teid - def openflow_basic_to_atom(0x41), do: :gtpu_extn_hdr - def openflow_basic_to_atom(0x42), do: :gtpu_extn_udp_port - def openflow_basic_to_atom(0x43), do: :gtpu_extn_sci def openflow_basic_to_atom(_), do: throw(:bad_enum) - def vlan_id_to_int(:present), do: 0x1000 - def vlan_id_to_int(:none), do: 0x0 + def vlan_id_to_int(:vid_present), do: 0x1000 + def vlan_id_to_int(:vid_none), do: 0x0 def vlan_id_to_int(_), do: throw(:bad_enum) - def vlan_id_to_atom(0x1000), do: :present - def vlan_id_to_atom(0x0), do: :none + def vlan_id_to_atom(0x1000), do: :vid_present + def vlan_id_to_atom(0x0), do: :vid_none def vlan_id_to_atom(_), do: throw(:bad_enum) def ipv6exthdr_flags_to_int(:nonext), do: 0x1 def ipv6exthdr_flags_to_int(:esp), do: 0x2 @@ -11863,6 +11383,12 @@ defmodule Openflow.Enums do def tcp_flags_to_atom(0x80), do: :cwr def tcp_flags_to_atom(0x100), do: :ns def tcp_flags_to_atom(_), do: throw(:bad_enum) + def tun_gbp_flags_to_int(:policy_applied), do: 0x8 + def tun_gbp_flags_to_int(:dont_learn), do: 0x40 + def tun_gbp_flags_to_int(_), do: throw(:bad_enum) + def tun_gbp_flags_to_atom(0x8), do: :policy_applied + def tun_gbp_flags_to_atom(0x40), do: :dont_learn + def tun_gbp_flags_to_atom(_), do: throw(:bad_enum) def ct_state_flags_to_int(:new), do: 0x1 def ct_state_flags_to_int(:est), do: 0x2 def ct_state_flags_to_int(:rel), do: 0x4 @@ -11908,6 +11434,7 @@ defmodule Openflow.Enums do 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 @@ -11918,35 +11445,8 @@ defmodule Openflow.Enums do 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 hp_ext_match_to_int(:hp_udp_src_port_range), do: 0x0 - def hp_ext_match_to_int(:hp_udp_dst_port_range), do: 0x1 - def hp_ext_match_to_int(:hp_tcp_src_port_range), do: 0x2 - def hp_ext_match_to_int(:hp_tcp_dst_port_range), do: 0x3 - def hp_ext_match_to_int(:hp_tcp_flags), do: 0x4 - def hp_ext_match_to_int(:hp_custom_1), do: 0x5 - def hp_ext_match_to_int(:hp_custom_2), do: 0x6 - def hp_ext_match_to_int(:hp_custom_3), do: 0x7 - def hp_ext_match_to_int(:hp_custom_4), do: 0x8 - def hp_ext_match_to_int(_), do: throw(:bad_enum) - def hp_ext_match_to_atom(0x0), do: :hp_udp_src_port_range - def hp_ext_match_to_atom(0x1), do: :hp_udp_dst_port_range - def hp_ext_match_to_atom(0x2), do: :hp_tcp_src_port_range - def hp_ext_match_to_atom(0x3), do: :hp_tcp_dst_port_range - def hp_ext_match_to_atom(0x4), do: :hp_tcp_flags - def hp_ext_match_to_atom(0x5), do: :hp_custom_1 - def hp_ext_match_to_atom(0x6), do: :hp_custom_2 - def hp_ext_match_to_atom(0x7), do: :hp_custom_3 - def hp_ext_match_to_atom(0x8), do: :hp_custom_4 - def hp_ext_match_to_atom(_), do: throw(:bad_enum) - def hp_custom_match_type_to_int(:l2_start), do: 0x1 - def hp_custom_match_type_to_int(:l3_start), do: 0x2 - def hp_custom_match_type_to_int(:l4_start), do: 0x3 - def hp_custom_match_type_to_int(_), do: throw(:bad_enum) - def hp_custom_match_type_to_atom(0x1), do: :l2_start - def hp_custom_match_type_to_atom(0x2), do: :l3_start - def hp_custom_match_type_to_atom(0x3), do: :l4_start - def hp_custom_match_type_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 @@ -12852,6 +12352,10 @@ defmodule Openflow.Enums do Openflow.Utils.int_to_flags([], int, enum_of(:tcp_flags)) end + def int_to_flags(int, :tun_gbp_flags) do + Openflow.Utils.int_to_flags([], int, enum_of(:tun_gbp_flags)) + end + def int_to_flags(int, :ct_state_flags) do Openflow.Utils.int_to_flags([], int, enum_of(:ct_state_flags)) end @@ -12864,14 +12368,6 @@ defmodule Openflow.Enums do Openflow.Utils.int_to_flags([], int, enum_of(:nicira_ext_match)) end - def int_to_flags(int, :hp_ext_match) do - Openflow.Utils.int_to_flags([], int, enum_of(:hp_ext_match)) - end - - def int_to_flags(int, :hp_custom_match_type) do - Openflow.Utils.int_to_flags([], int, enum_of(:hp_custom_match_type)) - end - def int_to_flags(int, :onf_ext_match) do Openflow.Utils.int_to_flags([], int, enum_of(:onf_ext_match)) end @@ -13240,6 +12736,10 @@ defmodule Openflow.Enums do Openflow.Utils.flags_to_int(0, flags, enum_of(:tcp_flags)) end + def flags_to_int(flags, :tun_gbp_flags) do + Openflow.Utils.flags_to_int(0, flags, enum_of(:tun_gbp_flags)) + end + def flags_to_int(flags, :ct_state_flags) do Openflow.Utils.flags_to_int(0, flags, enum_of(:ct_state_flags)) end @@ -13252,14 +12752,6 @@ defmodule Openflow.Enums do Openflow.Utils.flags_to_int(0, flags, enum_of(:nicira_ext_match)) end - def flags_to_int(flags, :hp_ext_match) do - Openflow.Utils.flags_to_int(0, flags, enum_of(:hp_ext_match)) - end - - def flags_to_int(flags, :hp_custom_match_type) do - Openflow.Utils.flags_to_int(0, flags, enum_of(:hp_custom_match_type)) - end - def flags_to_int(flags, :onf_ext_match) do Openflow.Utils.flags_to_int(0, flags, enum_of(:onf_ext_match)) end @@ -13978,36 +13470,10 @@ defmodule Openflow.Enums do pbb_isid: 37, tunnel_id: 38, ipv6_exthdr: 39, - pbb_uca: 41, - packet_type: 42, - gre_flags: 43, - gre_ver: 44, - gre_protocol: 45, - gre_key: 46, - gre_seqnum: 47, - lisp_flags: 48, - lisp_nonce: 49, - lisp_id: 50, - vxlan_flags: 51, - vxlan_vni: 52, - mpls_data_first_nibble: 53, - mpls_ach_version: 54, - mpls_ach_channel: 55, - mpls_pw_metadata: 56, - mpls_cw_flags: 57, - mpls_cw_fragment: 58, - mpls_cw_len: 59, - mpls_cw_seq_num: 60, - gtpu_flags: 61, - gtpu_ver: 62, - gtpu_msg_type: 63, - gtpu_teid: 64, - gtpu_extn_hdr: 65, - gtpu_extn_udp_port: 66, - gtpu_extn_sci: 67 + pbb_uca: 41 ] - defp enum_of(:vlan_id), do: [present: 4096, none: 0] + defp enum_of(:vlan_id), do: [vid_present: 4096, vid_none: 0] defp enum_of(:ipv6exthdr_flags), do: [ @@ -14025,6 +13491,8 @@ defmodule Openflow.Enums do defp enum_of(:tcp_flags), do: [fin: 1, syn: 2, rst: 4, psh: 8, ack: 16, urg: 32, ece: 64, cwr: 128, ns: 256] + defp enum_of(:tun_gbp_flags), do: [policy_applied: 8, dont_learn: 64] + defp enum_of(:ct_state_flags), do: [new: 1, est: 2, rel: 4, rep: 8, inv: 16, trk: 32, snat: 64, dnat: 128] @@ -14041,23 +13509,10 @@ defmodule Openflow.Enums do nsh_c1: 6, nsh_c2: 7, nsh_c3: 8, - nsh_c4: 9 + nsh_c4: 9, + nsh_ttl: 10 ] - defp enum_of(:hp_ext_match), - do: [ - hp_udp_src_port_range: 0, - hp_udp_dst_port_range: 1, - hp_tcp_src_port_range: 2, - hp_tcp_dst_port_range: 3, - hp_tcp_flags: 4, - hp_custom_1: 5, - hp_custom_2: 6, - hp_custom_3: 7, - hp_custom_4: 8 - ] - - defp enum_of(:hp_custom_match_type), do: [l2_start: 1, l3_start: 2, l4_start: 3] defp enum_of(:onf_ext_match), do: [onf_tcp_flags: 42, onf_actset_output: 43, onf_pbb_uca: 2560] 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] diff --git a/lib/openflow/match.ex b/lib/openflow/match.ex index 3cbf258..2f60a63 100644 --- a/lib/openflow/match.ex +++ b/lib/openflow/match.ex @@ -1,238 +1,891 @@ defmodule Openflow.Match do - @match_size 8 - @header_size 4 + @moduledoc false - defstruct( - type: :oxm, - fields: [] - ) + use Bitwise - alias __MODULE__ + defstruct(type: :oxm, fields: []) + @type t :: %__MODULE__{type: :oxm, fields: Keyword.t()} + + # Match Classes + + @type u8 :: 0..0xFF + @type u16 :: 0..0xFFFF + @type u24 :: 0..0xFFFFFF + @type u32 :: 0..0xFFFFFFFF + @type u64 :: 0..0xFFFFFFFFFFFFFFFF + @type u128 :: 0..0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + + @type eth_addr :: <<_::48>> + @type in_addr :: :inet.ip4_address() + @type in6_addr :: :inet.ip6_address() + + @spec new(Keyword.t()) :: t() def new(fields \\ []) do - oxm_fields = - fields - |> keyword_to_oxm_fields([]) - - %Match{type: :oxm, fields: oxm_fields} + %__MODULE__{type: :oxm, fields: fields} end - def read(binary) do - <<1::16, no_pad_len::16, binary1::binary>> = binary - padding_length = Openflow.Utils.pad_length(no_pad_len, 8) - match_field_len = no_pad_len - @header_size - - <> = binary1 - - {decode_fields(match_fields, []), rest} - end - - def to_binary(%Match{fields: fields}) do + @spec to_binary(t()) :: <<_::_*8>> + def to_binary(%__MODULE__{fields: fields} = match) do fields_bin = encode_fields(fields, <<>>) - length = byte_size(fields_bin) + @match_size - @header_size - type_int = Openflow.Enums.to_int(:oxm, :match_type) + length = byte_size(fields_bin) + 4 + type_int = Openflow.Enums.to_int(match.type, :match_type) padding = Openflow.Utils.padding(length, 8) <> end - def codec_header(oxm_field0) when is_atom(oxm_field0) do + def read(<<_::16, no_pad_len::16, tail::bytes>>) do + pad_len = Openflow.Utils.pad_length(no_pad_len, 8) + fields_len = no_pad_len - 4 + <> = tail + fields = decode_fields([], fields_bin) + {fields, rest} + end + + def codec_header(<<0xFFFF::16, oxm_field::7, has_mask::1, _len::8, exp_int::32>>) do + oxm_field = match_field({0xFFFF, exp_int}, oxm_field) + if has_mask == 1, do: :"masked_#{oxm_field}", else: oxm_field + end + + def codec_header(<>) do + oxm_field = match_field(oxm_class, oxm_field) + if has_mask == 1, do: :"masked_#{oxm_field}", else: oxm_field + end + + def codec_header(oxm_field) when is_atom(oxm_field) do + field_str = "#{oxm_field}" + has_mask = if String.match?(field_str, ~r/^masked_/), do: 1, else: 0 + oxm_field = - case has_mask(oxm_field0) do - 1 -> - string = to_string(oxm_field0) - "masked_" <> field = string - String.to_atom(field) + if has_mask == 1, do: :"#{String.replace(field_str, ~r/^masked_/, "")}", else: oxm_field - 0 -> - oxm_field0 - end - - case Openflow.Match.Field.vendor_of(oxm_field) do - oxm_class when oxm_class in [:nxm_0, :nxm_1, :openflow_basic, :packet_register] -> - oxm_class_int = Openflow.Enums.to_int(oxm_class, :oxm_class) + case match_class(oxm_field) 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(Openflow.Match.Field.n_bits_of(oxm_field), 8) - has_mask = has_mask(oxm_field0) + oxm_length = div(n_bits_of(oxm_field) + 6, 8) + <> + + oxm_class_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), 8) <> - - experimenter when experimenter in [:nicira_ext_match, :onf_ext_match, :hp_ext_match] -> - oxm_class_int = 0xFFFF - experimenter_int = Openflow.Enums.to_int(experimenter, :experimenter_oxm_vendors) - oxm_field_int = Openflow.Enums.to_int(oxm_field, experimenter) - oxm_length = div(Openflow.Match.Field.n_bits_of(oxm_field) + 4, 8) - has_mask = has_mask(oxm_field0) - <> end end - def codec_header(<>) do - oxm_class = Openflow.Enums.to_atom(oxm_class_int, :oxm_class) - - case oxm_has_mask do - 0 -> - Openflow.Enums.to_atom(oxm_field_int, oxm_class) - - 1 -> - field_str = - oxm_field_int - |> Openflow.Enums.to_atom(oxm_class) - |> to_string - - String.to_atom("masked_" <> field_str) - end + def n_bits_of(f) do + f + |> format_type() + |> bit_len() end - def codec_header( - <<0xFFFF::16, oxm_field_int::7, oxm_has_mask::1, _oxm_length::8, experimenter_int::32>> - ) do - experimenter = Openflow.Enums.to_atom(experimenter_int, :experimenter_oxm_vendors) - Openflow.Enums.to_atom(oxm_field_int, experimenter) + @spec decode_value(binary(), atom()) :: term() + def decode_value(v0, f) do + v = trim_heading_pad(v0, f) - case oxm_has_mask do - 0 -> - Openflow.Enums.to_atom(oxm_field_int, experimenter) - - 1 -> - field_str = - oxm_field_int - |> Openflow.Enums.to_atom(experimenter) - |> to_string - - String.to_atom("masked_" <> field_str) - end + f + |> format_type() + |> _decode_value(v) end - def header_size( - <<_oxm_class_int::16, _oxm_field_int::7, _oxm_has_mask::1, _oxm_length::8, _::bytes>> - ), - do: 4 + @spec encode_value(term(), atom()) :: binary() + def encode_value(v, f) do + f + |> format_type() + |> _encode_value(v) + end - def header_size( - <<0xFFFF::16, _oxm_field_int::7, _oxm_has_mask::1, _oxm_length::8, _exp_int::32, - _::bytes>> - ), - do: 8 + def header_size(<>) do + case oxm_header do + <<0xFFFF::16, _::16>> -> 8 + <<_oxm_class::16, _::16>> -> 4 + end + end # private functions - defp decode_fields(<<>>, acc), do: Enum.reverse(acc) + ## Encode + + defp encode_fields([field | rest], <>), + do: encode_fields(rest, <>) + + defp encode_fields([], <>), + do: acc + + defp encode_field({f, {v, m}}) do + t = format_type(f) + class = match_class(f) + field = match_field(class, f) + value = _encode_value(t, v) + mask = _encode_value(t, m) + oxm_header = oxm_header_w(class, field, byte_size(value)) + <> + end + + defp encode_field({f, v}) do + t = format_type(f) + class = match_class(f) + field = match_field(class, f) + value = _encode_value(t, v) + oxm_header = oxm_header(class, field, byte_size(value)) + <> + end + + ## Decode + + defp decode_fields(acc, <<>>), + do: Enum.reverse(acc) defp decode_fields( - <<0xFFFF::16, _::7, 1::1, length::8, vendor_int::32, field_int::16, binary::bytes>>, - acc + acc, + << + 0xFFFF::16, + _::7, + has_mask::1, + length::8, + body_bin::size(length)-bytes, + rest::bytes + >> ) do - length = length - 6 - field_len = div(length, 2) - <> = binary - experimenter = Openflow.Enums.to_atom(vendor_int, :experimenter_oxm_vendors) - field_name = Openflow.Enums.to_atom(field_int, experimenter) - value = Openflow.Match.Field.codec(value_bin, field_name) - mask = Openflow.Match.Field.codec(mask_bin, field_name) - decode_fields(rest, [{field_name, {value, mask}} | acc]) + 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) end - defp decode_fields( - <<0xFFFF::16, _::7, 0::1, length::8, vendor_int::32, field_int::16, binary::bytes>>, - acc - ) do - length = length - 6 - <> = binary - experimenter = Openflow.Enums.to_atom(vendor_int, :experimenter_oxm_vendors) - field_name = Openflow.Enums.to_atom(field_int, experimenter) - value = Openflow.Match.Field.codec(value_bin, field_name) - decode_fields(rest, [{field_name, value} | acc]) + defp decode_fields(acc, <>) do + <> = oxm_header + <> = tail + oxm_field = match_field(oxm_class, oxm_field) + field = decode_field(has_mask, oxm_field, body_bin) + decode_fields([field | acc], rest) end - defp decode_fields(<>, acc) do - field_len = div(length, 2) - <> = binary - class = Openflow.Enums.to_atom(class_int, :oxm_class) - field_name = Openflow.Enums.to_atom(field_int, class) - value = Openflow.Match.Field.codec(value_bin, field_name) - mask = Openflow.Match.Field.codec(mask_bin, field_name) - decode_fields(rest, [{field_name, {value, mask}} | acc]) + defp decode_field(1, oxm_field, binary) do + type = format_type(oxm_field) + length = div(byte_size(binary), 2) + <> = binary + value = _decode_value(type, value_bin) + mask = _decode_value(type, mask_bin) + {oxm_field, {value, mask}} end - defp decode_fields(<>, acc) do - <> = binary - class = Openflow.Enums.to_atom(class_int, :oxm_class) - field_name = Openflow.Enums.to_atom(field_int, class) - value = Openflow.Match.Field.codec(value_bin, field_name) - decode_fields(rest, [{field_name, value} | acc]) + defp decode_field(0, oxm_field, binary) do + type = format_type(oxm_field) + value = _decode_value(type, binary) + {oxm_field, value} end - defp encode_fields([], acc), do: acc + ## Encode Types - defp encode_fields([field | fields], acc) do - encode_fields(fields, <>) + defp _encode_value(:ofp13_port_no, v), + do: <> + + defp _encode_value(:ofp10_port_no, v), + do: <> + + defp _encode_value(:tcp_flags, v), + do: <> + + defp _encode_value(:ipv6exthdr_flags, v), + do: <> + + defp _encode_value(:tun_gbp_flags, v), + do: <> + + defp _encode_value(:ct_state_flags, v), + do: <> + + defp _encode_value(:mac, <>), do: mac + + defp _encode_value(:in_addr, {a1, a2, a3, a4}), do: <> + + defp _encode_value(:in6_addr, {a1, a2, a3, a4, a5, a6, a7, a8}), + do: << + a1::16, + a2::16, + a3::16, + a4::16, + a5::16, + a6::16, + a7::16, + a8::16 + >> + + defp _encode_value(:u8, v), do: <> + + defp _encode_value(:u16, v), do: <> + + defp _encode_value(:u24, v), do: <> + + defp _encode_value(:u32, v), do: <> + + defp _encode_value(:u64, v), do: <> + + defp _encode_value(:u128, v), do: <> + + defp _encode_value(:arbitrary, v), do: <> + + ## Decode types + + defp _decode_value(:ofp13_port_no, <>), + do: Openflow.Utils.get_enum(v, :openflow13_port_no) + + defp _decode_value(:ofp10_port_no, <>), + do: Openflow.Utils.get_enum(v, :openflow10_port_no) + + defp _decode_value(:tcp_flags, <>), + do: Openflow.Enums.int_to_flags(v, :tcp_flags) + + defp _decode_value(:ipv6exthdr_flags, <>), + do: Openflow.Enums.int_to_flags(v, :ipv6exthdr_flags) + + defp _decode_value(:tun_gbp_flags, <>), + do: Openflow.Enums.int_to_flags(v, :tun_gbp_flags) + + defp _decode_value(:ct_state_flags, <>), + do: Openflow.Enums.int_to_flags(v, :ct_state_flags) + + defp _decode_value(:mac, <>), + do: v + + defp _decode_value(:in_addr, <>), + do: {a1, a2, a3, a4} + + defp _decode_value(:in6_addr, << + a1::16, + a2::16, + a3::16, + a4::16, + a5::16, + a6::16, + a7::16, + a8::16 + >>), + do: {a1, a2, a3, a4, a5, a6, a7, a8} + + defp _decode_value(:u8, <>), do: v + + defp _decode_value(:u16, <>), do: v + + defp _decode_value(:u24, <>), do: v + + defp _decode_value(:u32, <>), do: v + + defp _decode_value(:u64, <>), do: v + + defp _decode_value(:u128, <>), do: v + + defp _decode_value(:arbitrary, <>), do: v + + ## Bit size + + defp bit_len(:ofp13_port_no), do: 32 + + defp bit_len(:ofp10_port_no), do: 16 + + defp bit_len(:tcp_flags), do: 16 + + defp bit_len(:ipv6exthdr_flags), do: 16 + + defp bit_len(:tun_gbp_flags), do: 8 + + defp bit_len(:ct_state_flags), do: 32 + + defp bit_len(:mac), do: 48 + + defp bit_len(:in_addr), do: 32 + + defp bit_len(:in6_addr), do: 128 + + defp bit_len(:u8), do: 8 + + defp bit_len(:u16), do: 16 + + defp bit_len(:u24), do: 24 + + defp bit_len(:u32), do: 32 + + defp bit_len(:u64), do: 64 + + defp bit_len(:u128), do: 128 + + defp bit_len(:arbitrary), do: 0 + + ## OXM Match classes + + @spec match_field(integer() | {integer(), integer()}, atom()) :: integer() + defp match_field({0xFFFF, exp}, f) do + class = Openflow.Utils.get_enum(exp, :experimenter_oxm_vendors) + Openflow.Utils.get_enum(f, class) end - defp encode_field(%{class: class, field: field, has_mask: true, value: value, mask: mask}) - when class == :nicira_ext_match or class == :onf_ext_match do - vendor_int = Openflow.Enums.to_int(class, :experimenter_oxm_vendors) - field_int = Openflow.Enums.to_int(field, class) - has_mask_int = 1 - length = byte_size(value) * 2 + 6 - - <<0xFFFF::16, 0::7, has_mask_int::1, length::8, vendor_int::32, field_int::16, value::bytes, - mask::bytes>> + defp match_field(c, f) do + class = Openflow.Utils.get_enum(c, :oxm_class) + Openflow.Utils.get_enum(f, class) end - defp encode_field(%{class: class, field: field, has_mask: false, value: value}) - when class == :nicira_ext_match or class == :onf_ext_match do - vendor_int = Openflow.Enums.to_int(class, :experimenter_oxm_vendors) - field_int = Openflow.Enums.to_int(field, class) - has_mask_int = 0 - length = byte_size(value) + 6 - <<0xFFFF::16, 0::7, has_mask_int::1, length::8, vendor_int::32, field_int::16, value::bytes>> - end + # OpenFlow Basic + defp match_class(f) + when f in [ + :in_port, + :in_phy_port, + :metadata, + :eth_dst, + :eth_src, + :eth_type, + :vlan_vid, + :vlan_pcp, + :ip_dscp, + :ip_ecn, + :ip_proto, + :ipv4_src, + :ipv4_dst, + :tcp_src, + :tcp_dst, + :udp_src, + :udp_dst, + :sctp_src, + :sctp_dst, + :icmpv4_type, + :icmpv4_code, + :arp_op, + :arp_spa, + :arp_tpa, + :arp_sha, + :arp_tha, + :ipv6_src, + :ipv6_dst, + :ipv6_flabel, + :icmpv6_type, + :icmpv6_code, + :ipv6_nd_target, + :ipv6_nd_sll, + :ipv6_nd_tll, + :mpls_label, + :mpls_tc, + :mpls_bos, + :pbb_isid, + :tunnel_id, + :ipv6_exthdr, + :pbb_uca + ], + do: 0x8000 - defp encode_field(%{class: class, field: field, has_mask: true, value: value, mask: mask}) do - class_int = Openflow.Enums.to_int(class, :oxm_class) - field_int = Openflow.Enums.to_int(field, class) - has_mask_int = 1 - length = byte_size(value) * 2 - <> - end + # PacketRegisters + defp match_class(f) + when f in [ + :xreg0, + :xreg1, + :xreg2, + :xreg3, + :xreg4, + :xreg5, + :xreg6, + :xreg7 + ], + do: 0x8001 - defp encode_field(%{class: class, field: field, has_mask: false, value: value}) do - class_int = Openflow.Enums.to_int(class, :oxm_class) - field_int = Openflow.Enums.to_int(field, class) - has_mask_int = 0 - length = byte_size(value) - <> - end + # NXM_0 + defp match_class(f) + when f in [ + :nx_in_port, + :nx_eth_dst, + :nx_eth_src, + :nx_eth_type, + :nx_vlan_tci, + :nx_ip_tos, + :nx_ip_proto, + :nx_ipv4_src, + :nx_ipv4_dst, + :nx_tcp_src, + :nx_tcp_dst, + :nx_udp_src, + :nx_udp_dst, + :nx_icmpv4_type, + :nx_icmpv4_code, + :nx_arp_op, + :nx_arp_spa, + :nx_arp_tpa, + :nx_tcp_flags + ], + do: 0x0000 - defp keyword_to_oxm_fields([], acc), do: Enum.reverse(acc) + # NXM_1 + defp match_class(f) + when f in [ + :reg0, + :reg1, + :reg2, + :reg3, + :reg4, + :reg5, + :reg6, + :reg7, + :reg8, + :reg9, + :reg10, + :reg11, + :reg12, + :reg13, + :reg14, + :reg15, + :tun_id, + :nx_arp_sha, + :nx_arp_tha, + :nx_ipv6_src, + :nx_ipv6_dst, + :nx_icmpv6_type, + :nx_icmpv6_code, + :nx_ipv6_nd_target, + :nx_ipv6_nd_sll, + :nx_ipv6_nd_tll, + :nx_ip_frag, + :nx_ipv6_label, + :nx_ip_ecn, + :nx_ip_ttl, + :nx_mpls_ttl, + :tun_src, + :tun_dst, + :pkt_mark, + :dp_hash, + :recirc_id, + :conj_id, + :tun_gbp_id, + :tun_gbp_flags, + :tun_metadata0, + :tun_metadata1, + :tun_metadata2, + :tun_metadata3, + :tun_metadata4, + :tun_metadata5, + :tun_metadata6, + :tun_metadata7, + :tun_metadata8, + :tun_metadata9, + :tun_metadata10, + :tun_metadata11, + :tun_metadata12, + :tun_metadata13, + :tun_metadata14, + :tun_metadata15, + :tun_metadata16, + :tun_metadata17, + :tun_metadata18, + :tun_metadata19, + :tun_metadata20, + :tun_metadata21, + :tun_metadata22, + :tun_metadata23, + :tun_metadata24, + :tun_metadata25, + :tun_metadata26, + :tun_metadata27, + :tun_metadata28, + :tun_metadata29, + :tun_metadata30, + :tun_metadata31, + :tun_metadata32, + :tun_metadata33, + :tun_metadata34, + :tun_metadata35, + :tun_metadata36, + :tun_metadata37, + :tun_metadata38, + :tun_metadata39, + :tun_metadata40, + :tun_metadata41, + :tun_metadata42, + :tun_metadata43, + :tun_metadata44, + :tun_metadata45, + :tun_metadata46, + :tun_metadata47, + :tun_metadata48, + :tun_metadata49, + :tun_metadata50, + :tun_metadata51, + :tun_metadata52, + :tun_metadata53, + :tun_metadata54, + :tun_metadata55, + :tun_metadata56, + :tun_metadata57, + :tun_metadata58, + :tun_metadata59, + :tun_metadata60, + :tun_metadata61, + :tun_metadata62, + :tun_metadata63, + :tun_flags, + :ct_state, + :ct_zone, + :ct_mark, + :ct_label, + :tun_ipv6_src, + :tun_ipv6_dst, + :xxreg0, + :xxreg1, + :xxreg2, + :xxreg3, + :xxreg4, + :xxreg5, + :xxreg6, + :xxreg7, + :ct_nw_proto, + :ct_nw_src, + :ct_nw_dst, + :ct_ipv6_src, + :ct_ipv6_dst, + :ct_tp_src, + :ct_tp_dst + ], + do: 0x0001 - defp keyword_to_oxm_fields([{field_name, field_value} | fields], acc) do - keyword_to_oxm_fields(fields, [oxm_field(field_name, field_value) | acc]) - end + # Nicira Ext + defp match_class(f) + when f in [ + :nsh_flags, + :nsh_mdtype, + :nsh_np, + :nsh_spi, + :nsh_si, + :nsh_c1, + :nsh_c2, + :nsh_c3, + :nsh_c4, + :nsh_ttl + ], + do: {0xFFFF, 0x00002320} - defp oxm_field(field_name, {value, mask}) do - value_bin = Openflow.Match.Field.codec(value, field_name) - mask_bin = Openflow.Match.Field.codec(mask, field_name) - match_class = Openflow.Match.Field.vendor_of(field_name) - %{class: match_class, field: field_name, has_mask: true, value: value_bin, mask: mask_bin} - end + # ONF Ext + defp match_class(f) + when f in [ + :onf_tcp_flags, + :onf_actset_output, + :onf_pbb_uca + ], + do: {0xFFFF, 0x4F4E4600} - defp oxm_field(field_name, value) do - value_bin = Openflow.Match.Field.codec(value, field_name) - match_class = Openflow.Match.Field.vendor_of(field_name) - %{class: match_class, field: field_name, has_mask: false, value: value_bin} - end + # Special types - def has_mask(oxm_field) when is_atom(oxm_field) do - has_mask? = - oxm_field - |> to_string - |> String.match?(~r/^masked_/) + defp format_type(t) + when t in [ + :in_port, + :in_phy_port, + :onf_actset_output + ], + do: :ofp13_port_no - if has_mask? do - 1 - else - 0 + defp format_type(t) + when t in [ + :nx_in_port + ], + do: :ofp10_port_no + + # Composite types + + defp format_type(t) + when t in [ + :nx_tcp_flags, + :onf_tcp_flags + ], + do: :tcp_flags + + defp format_type(t) + when t in [ + :ipv6_exthdr + ], + do: :ipv6exthdr_flags + + defp format_type(t) + when t in [ + :tun_gbp_flags + ], + do: :tun_gbp_flags + + defp format_type(t) + when t in [ + :ct_state + ], + do: :ct_state_flags + + defp format_type(t) + when t in [ + :eth_dst, + :eth_src, + :arp_sha, + :arp_tha, + :ipv6_nd_sll, + :ipv6_nd_tll, + :nx_eth_dst, + :nx_eth_src, + :nx_arp_sha, + :nx_arp_tha, + :nx_ipv6_nd_sll, + :nx_ipv6_nd_tll + ], + do: :mac + + defp format_type(t) + when t in [ + :ipv4_src, + :ipv4_dst, + :arp_spa, + :arp_tpa, + :nx_ipv4_src, + :nx_ipv4_dst, + :nx_arp_spa, + :nx_arp_tpa, + :tun_src, + :tun_dst, + :ct_nw_src, + :ct_nw_dst + ], + do: :in_addr + + defp format_type(t) + when t in [ + :ipv6_src, + :ipv6_dst, + :ipv6_nd_target, + :nx_ipv6_src, + :nx_ipv6_dst, + :nx_ipv6_nd_target, + :tun_ipv6_src, + :tun_ipv6_dst, + :ct_ipv6_src, + :ct_ipv6_dst + ], + do: :in6_addr + + # Scalar types + + defp format_type(t) + when t in [ + :vlan_pcp, + :ip_dscp, + :ip_ecn, + :ip_proto, + :icmpv4_code, + :icmpv4_type, + :icmpv6_code, + :icmpv6_type, + :mpls_tc, + :mpls_bos, + :nx_ip_tos, + :nx_ip_proto, + :nx_icmpv4_code, + :nx_icmpv4_type, + :nx_icmpv6_code, + :nx_icmpv6_type, + :nx_ip_frag, + :nx_ip_ecn, + :nx_ip_ttl, + :nx_mpls_ttl, + :ct_nw_proto, + :nsh_flags, + :nsh_mdtype, + :nsh_np, + :nsh_si, + :nsh_ttl, + :pbb_uca, + :onf_pbb_uca + ], + do: :u8 + + defp format_type(t) + when t in [ + :eth_type, + :vlan_vid, + :nx_vlan_tci, + :tcp_src, + :tcp_dst, + :udp_src, + :udp_dst, + :sctp_src, + :sctp_dst, + :arp_op, + :nx_eth_type, + :nx_tcp_src, + :nx_tcp_dst, + :nx_udp_src, + :nx_udp_dst, + :nx_arp_op, + :tun_gbp_id, + :tun_flags, + :ct_zone, + :ct_tp_src, + :ct_tp_dst + ], + do: :u16 + + defp format_type(t) + when t in [ + :pbb_isid + ], + do: :u24 + + defp format_type(t) + when t in [ + :ipv6_flabel, + :mpls_label, + :reg0, + :reg1, + :reg2, + :reg3, + :reg4, + :reg5, + :reg6, + :reg7, + :reg8, + :reg9, + :reg10, + :reg11, + :reg12, + :reg13, + :reg14, + :reg15, + :nx_ipv6_flabel, + :pkt_mark, + :dp_hash, + :recirc_id, + :conj_id, + :ct_mark, + :nsh_spi, + :nsh_c1, + :nsh_c2, + :nsh_c3, + :nsh_c4 + ], + do: :u32 + + defp format_type(t) + when t in [ + :metadata, + :tunnel_id, + :tun_id, + :xreg0, + :xreg1, + :xreg2, + :xreg3, + :xreg4, + :xreg5, + :xreg6, + :xreg7 + ], + do: :u64 + + defp format_type(t) + when t in [ + :ct_label, + :xxreg0, + :xxreg1, + :xxreg2, + :xxreg3, + :xxreg4, + :xxreg5, + :xxreg6, + :xxreg7 + ], + do: :u128 + + defp format_type(t) + when t in [ + :tun_metadata0, + :tun_metadata1, + :tun_metadata2, + :tun_metadata3, + :tun_metadata4, + :tun_metadata5, + :tun_metadata6, + :tun_metadata7, + :tun_metadata8, + :tun_metadata9, + :tun_metadata10, + :tun_metadata11, + :tun_metadata12, + :tun_metadata13, + :tun_metadata14, + :tun_metadata15, + :tun_metadata16, + :tun_metadata17, + :tun_metadata18, + :tun_metadata19, + :tun_metadata20, + :tun_metadata21, + :tun_metadata22, + :tun_metadata23, + :tun_metadata24, + :tun_metadata25, + :tun_metadata26, + :tun_metadata27, + :tun_metadata28, + :tun_metadata29, + :tun_metadata30, + :tun_metadata31, + :tun_metadata32, + :tun_metadata33, + :tun_metadata34, + :tun_metadata35, + :tun_metadata36, + :tun_metadata37, + :tun_metadata38, + :tun_metadata39, + :tun_metadata40, + :tun_metadata41, + :tun_metadata42, + :tun_metadata43, + :tun_metadata44, + :tun_metadata45, + :tun_metadata46, + :tun_metadata47, + :tun_metadata48, + :tun_metadata49, + :tun_metadata50, + :tun_metadata51, + :tun_metadata52, + :tun_metadata53, + :tun_metadata54, + :tun_metadata55, + :tun_metadata56, + :tun_metadata57, + :tun_metadata58, + :tun_metadata59, + :tun_metadata60, + :tun_metadata61, + :tun_metadata62, + :tun_metadata63 + ], + do: :arbitrary + + defp oxm_header__({class, exp}, field, has_mask, length), + do: <> + + defp oxm_header__(class, field, has_mask, length), + do: <> + + defp oxm_header(class, field, length), + do: oxm_header__(class, field, 0, length) + + defp oxm_header_w(class, field, length), + do: oxm_header__(class, field, 1, length * 2) + + defp trim_heading_pad(v0, f) do + case n_bits_of(f) do + n_bits when bit_size(v0) < n_bits -> + head_pad_len = n_bits - bit_size(v0) + <<0::size(head_pad_len), v0::bytes>> + + n_bits when bit_size(v0) > n_bits -> + head_pad_len = bit_size(v0) - n_bits + <<_::size(head_pad_len), value::size(n_bits)-bits>> = v0 + value + + _ -> + v0 end end end diff --git a/lib/openflow/match/field.ex b/lib/openflow/match/field.ex deleted file mode 100644 index 3cabbd4..0000000 --- a/lib/openflow/match/field.ex +++ /dev/null @@ -1,673 +0,0 @@ -defmodule Openflow.Match.Field do - def codec(value0, field) when is_binary(value0) do - {type, format} = format_of(field) - n_bits = n_bits_of(field) - bit_size = bit_size(value0) - - value = - if bit_size < n_bits do - head_pad_len = n_bits - bit_size - <<0::size(head_pad_len), value0::bytes>> - else - if bit_size > n_bits and type != :mac do - head_pad_len = bit_size - n_bits - <<_::size(head_pad_len), value::size(n_bits)-bits>> = value0 - value - else - value0 - end - end - - formatting(value, type, format) - end - - def codec(value, type) do - {type, format} = format_of(type) - formatting(value, type, format) - end - - def n_bits_of(field) do - field - |> format_of - |> bit_size_of - end - - def bit_size_of({:u8, _}), do: 8 - def bit_size_of({:u24, _}), do: 24 - def bit_size_of({:be16, _}), do: 16 - def bit_size_of({:be32, _}), do: 32 - def bit_size_of({:be64, _}), do: 64 - def bit_size_of({:be128, _}), do: 128 - def bit_size_of({:mac, _}), do: 48 - - # NXM0 - def vendor_of(:nx_in_port), do: :nxm_0 - def vendor_of(:nx_eth_dst), do: :nxm_0 - def vendor_of(:nx_eth_src), do: :nxm_0 - def vendor_of(:nx_eth_type), do: :nxm_0 - def vendor_of(:nx_vlan_tci), do: :nxm_0 - def vendor_of(:nx_ip_tos), do: :nxm_0 - def vendor_of(:nx_ip_proto), do: :nxm_0 - def vendor_of(:nx_ipv4_src), do: :nxm_0 - def vendor_of(:nx_ipv4_dst), do: :nxm_0 - def vendor_of(:nx_tcp_src), do: :nxm_0 - def vendor_of(:nx_tcp_dst), do: :nxm_0 - def vendor_of(:nx_udp_src), do: :nxm_0 - def vendor_of(:nx_udp_dst), do: :nxm_0 - def vendor_of(:nx_icmpv4_type), do: :nxm_0 - def vendor_of(:nx_icmpv4_code), do: :nxm_0 - def vendor_of(:nx_arp_op), do: :nxm_0 - def vendor_of(:nx_arp_spa), do: :nxm_0 - def vendor_of(:nx_arp_tpa), do: :nxm_0 - def vendor_of(:nx_tcp_flags), do: :nxm_0 - - # NXM1 - def vendor_of(:reg0), do: :nxm_1 - def vendor_of(:reg1), do: :nxm_1 - def vendor_of(:reg2), do: :nxm_1 - def vendor_of(:reg3), do: :nxm_1 - def vendor_of(:reg4), do: :nxm_1 - def vendor_of(:reg5), do: :nxm_1 - def vendor_of(:reg6), do: :nxm_1 - def vendor_of(:reg7), do: :nxm_1 - def vendor_of(:reg8), do: :nxm_1 - def vendor_of(:reg9), do: :nxm_1 - def vendor_of(:reg10), do: :nxm_1 - def vendor_of(:reg11), do: :nxm_1 - def vendor_of(:reg12), do: :nxm_1 - def vendor_of(:reg13), do: :nxm_1 - def vendor_of(:reg14), do: :nxm_1 - def vendor_of(:reg15), do: :nxm_1 - def vendor_of(:tun_id), do: :nxm_1 - def vendor_of(:nx_arp_sha), do: :nxm_1 - def vendor_of(:nx_arp_tha), do: :nxm_1 - def vendor_of(:nx_ipv6_src), do: :nxm_1 - def vendor_of(:nx_ipv6_dst), do: :nxm_1 - def vendor_of(:nx_icmpv6_type), do: :nxm_1 - def vendor_of(:nx_icmpv6_code), do: :nxm_1 - def vendor_of(:nx_ipv6_nd_target), do: :nxm_1 - def vendor_of(:nx_ipv6_nd_sll), do: :nxm_1 - def vendor_of(:nx_ipv6_nd_tll), do: :nxm_1 - def vendor_of(:nx_ip_frag), do: :nxm_1 - def vendor_of(:nx_ipv6_label), do: :nxm_1 - def vendor_of(:nx_ip_ecn), do: :nxm_1 - def vendor_of(:nx_ip_ttl), do: :nxm_1 - def vendor_of(:nx_mpls_ttl), do: :nxm_1 - def vendor_of(:tun_src), do: :nxm_1 - def vendor_of(:tun_dst), do: :nxm_1 - def vendor_of(:pkt_mark), do: :nxm_1 - def vendor_of(:dp_hash), do: :nxm_1 - def vendor_of(:recirc_id), do: :nxm_1 - def vendor_of(:conj_id), do: :nxm_1 - def vendor_of(:nx_tun_gbp_id), do: :nxm_1 - def vendor_of(:nx_tun_gbp_flags), do: :nxm_1 - def vendor_of(:tun_metadata0), do: :nxm_1 - def vendor_of(:tun_metadata1), do: :nxm_1 - def vendor_of(:tun_metadata2), do: :nxm_1 - def vendor_of(:tun_metadata3), do: :nxm_1 - def vendor_of(:tun_metadata4), do: :nxm_1 - def vendor_of(:tun_metadata5), do: :nxm_1 - def vendor_of(:tun_metadata6), do: :nxm_1 - def vendor_of(:tun_metadata7), do: :nxm_1 - def vendor_of(:tun_metadata8), do: :nxm_1 - def vendor_of(:tun_metadata9), do: :nxm_1 - def vendor_of(:tun_metadata10), do: :nxm_1 - def vendor_of(:tun_metadata11), do: :nxm_1 - def vendor_of(:tun_metadata12), do: :nxm_1 - def vendor_of(:tun_metadata13), do: :nxm_1 - def vendor_of(:tun_metadata14), do: :nxm_1 - def vendor_of(:tun_metadata15), do: :nxm_1 - def vendor_of(:tun_metadata16), do: :nxm_1 - def vendor_of(:tun_metadata17), do: :nxm_1 - def vendor_of(:tun_metadata18), do: :nxm_1 - def vendor_of(:tun_metadata19), do: :nxm_1 - def vendor_of(:tun_metadata20), do: :nxm_1 - def vendor_of(:tun_metadata21), do: :nxm_1 - def vendor_of(:tun_metadata22), do: :nxm_1 - def vendor_of(:tun_metadata23), do: :nxm_1 - def vendor_of(:tun_metadata24), do: :nxm_1 - def vendor_of(:tun_metadata25), do: :nxm_1 - def vendor_of(:tun_metadata26), do: :nxm_1 - def vendor_of(:tun_metadata27), do: :nxm_1 - def vendor_of(:tun_metadata28), do: :nxm_1 - def vendor_of(:tun_metadata29), do: :nxm_1 - def vendor_of(:tun_metadata30), do: :nxm_1 - def vendor_of(:tun_metadata31), do: :nxm_1 - def vendor_of(:tun_metadata32), do: :nxm_1 - def vendor_of(:tun_metadata33), do: :nxm_1 - def vendor_of(:tun_metadata34), do: :nxm_1 - def vendor_of(:tun_metadata35), do: :nxm_1 - def vendor_of(:tun_metadata36), do: :nxm_1 - def vendor_of(:tun_metadata37), do: :nxm_1 - def vendor_of(:tun_metadata38), do: :nxm_1 - def vendor_of(:tun_metadata39), do: :nxm_1 - def vendor_of(:tun_metadata40), do: :nxm_1 - def vendor_of(:tun_metadata41), do: :nxm_1 - def vendor_of(:tun_metadata42), do: :nxm_1 - def vendor_of(:tun_metadata43), do: :nxm_1 - def vendor_of(:tun_metadata44), do: :nxm_1 - def vendor_of(:tun_metadata45), do: :nxm_1 - def vendor_of(:tun_metadata46), do: :nxm_1 - def vendor_of(:tun_metadata47), do: :nxm_1 - def vendor_of(:tun_metadata48), do: :nxm_1 - def vendor_of(:tun_metadata49), do: :nxm_1 - def vendor_of(:tun_metadata50), do: :nxm_1 - def vendor_of(:tun_metadata51), do: :nxm_1 - def vendor_of(:tun_metadata52), do: :nxm_1 - def vendor_of(:tun_metadata53), do: :nxm_1 - def vendor_of(:tun_metadata54), do: :nxm_1 - def vendor_of(:tun_metadata55), do: :nxm_1 - def vendor_of(:tun_metadata56), do: :nxm_1 - def vendor_of(:tun_metadata57), do: :nxm_1 - def vendor_of(:tun_metadata58), do: :nxm_1 - def vendor_of(:tun_metadata59), do: :nxm_1 - def vendor_of(:tun_metadata60), do: :nxm_1 - def vendor_of(:tun_metadata61), do: :nxm_1 - def vendor_of(:tun_metadata62), do: :nxm_1 - def vendor_of(:tun_metadata63), do: :nxm_1 - def vendor_of(:tun_flags), do: :nxm_1 - def vendor_of(:ct_state), do: :nxm_1 - def vendor_of(:ct_zone), do: :nxm_1 - def vendor_of(:ct_mark), do: :nxm_1 - def vendor_of(:ct_label), do: :nxm_1 - def vendor_of(:tun_ipv6_src), do: :nxm_1 - def vendor_of(:tun_ipv6_dst), do: :nxm_1 - def vendor_of(:xxreg0), do: :nxm_1 - def vendor_of(:xxreg1), do: :nxm_1 - def vendor_of(:xxreg2), do: :nxm_1 - def vendor_of(:xxreg3), do: :nxm_1 - def vendor_of(:xxreg4), do: :nxm_1 - def vendor_of(:xxreg5), do: :nxm_1 - def vendor_of(:xxreg6), do: :nxm_1 - def vendor_of(:xxreg7), do: :nxm_1 - def vendor_of(:ct_ip_proto), do: :nxm_1 - def vendor_of(:ct_ipv4_src), do: :nxm_1 - def vendor_of(:ct_ipv4_dst), do: :nxm_1 - def vendor_of(:ct_ipv6_src), do: :nxm_1 - def vendor_of(:ct_ipv6_dst), do: :nxm_1 - def vendor_of(:ct_tp_src), do: :nxm_1 - def vendor_of(:ct_tp_dst), do: :nxm_1 - - # OpenFlow Basic - def vendor_of(:in_port), do: :openflow_basic - def vendor_of(:in_phy_port), do: :openflow_basic - def vendor_of(:metadata), do: :openflow_basic - def vendor_of(:eth_dst), do: :openflow_basic - def vendor_of(:eth_src), do: :openflow_basic - def vendor_of(:eth_type), do: :openflow_basic - def vendor_of(:vlan_vid), do: :openflow_basic - def vendor_of(:vlan_pcp), do: :openflow_basic - def vendor_of(:ip_dscp), do: :openflow_basic - def vendor_of(:ip_ecn), do: :openflow_basic - def vendor_of(:ip_proto), do: :openflow_basic - def vendor_of(:ipv4_src), do: :openflow_basic - def vendor_of(:ipv4_dst), do: :openflow_basic - def vendor_of(:tcp_src), do: :openflow_basic - def vendor_of(:tcp_dst), do: :openflow_basic - def vendor_of(:udp_src), do: :openflow_basic - def vendor_of(:udp_dst), do: :openflow_basic - def vendor_of(:sctp_src), do: :openflow_basic - def vendor_of(:sctp_dst), do: :openflow_basic - def vendor_of(:icmpv4_type), do: :openflow_basic - def vendor_of(:icmpv4_code), do: :openflow_basic - def vendor_of(:arp_op), do: :openflow_basic - def vendor_of(:arp_spa), do: :openflow_basic - def vendor_of(:arp_tpa), do: :openflow_basic - def vendor_of(:arp_sha), do: :openflow_basic - def vendor_of(:arp_tha), do: :openflow_basic - def vendor_of(:ipv6_src), do: :openflow_basic - def vendor_of(:ipv6_dst), do: :openflow_basic - def vendor_of(:ipv6_flabel), do: :openflow_basic - def vendor_of(:icmpv6_type), do: :openflow_basic - def vendor_of(:icmpv6_code), do: :openflow_basic - def vendor_of(:ipv6_nd_target), do: :openflow_basic - def vendor_of(:ipv6_nd_sll), do: :openflow_basic - def vendor_of(:ipv6_nd_tll), do: :openflow_basic - def vendor_of(:mpls_label), do: :openflow_basic - def vendor_of(:mpls_tc), do: :openflow_basic - def vendor_of(:mpls_bos), do: :openflow_basic - def vendor_of(:pbb_isid), do: :openflow_basic - def vendor_of(:tunnel_id), do: :openflow_basic - def vendor_of(:ipv6_exthdr), do: :openflow_basic - def vendor_of(:pbb_uca), do: :openflow_basic - def vendor_of(:packet_type), do: :openflow_basic - def vendor_of(:gre_flags), do: :openflow_basic - def vendor_of(:gre_ver), do: :openflow_basic - def vendor_of(:gre_protocol), do: :openflow_basic - def vendor_of(:gre_key), do: :openflow_basic - def vendor_of(:gre_seqnum), do: :openflow_basic - def vendor_of(:lisp_flags), do: :openflow_basic - def vendor_of(:lisp_nonce), do: :openflow_basic - def vendor_of(:lisp_id), do: :openflow_basic - def vendor_of(:vxlan_flags), do: :openflow_basic - def vendor_of(:vxlan_vni), do: :openflow_basic - def vendor_of(:mpls_data_first_nibble), do: :openflow_basic - def vendor_of(:mpls_ach_version), do: :openflow_basic - def vendor_of(:mpls_ach_channel), do: :openflow_basic - def vendor_of(:mpls_pw_metadata), do: :openflow_basic - def vendor_of(:mpls_cw_flags), do: :openflow_basic - def vendor_of(:mpls_cw_fragment), do: :openflow_basic - def vendor_of(:mpls_cw_len), do: :openflow_basic - def vendor_of(:mpls_cw_seq_num), do: :openflow_basic - def vendor_of(:gtpu_flags), do: :openflow_basic - def vendor_of(:gtpu_ver), do: :openflow_basic - def vendor_of(:gtpu_msg_type), do: :openflow_basic - def vendor_of(:gtpu_teid), do: :openflow_basic - def vendor_of(:gtpu_extn_hdr), do: :openflow_basic - def vendor_of(:gtpu_extn_udp_port), do: :openflow_basic - def vendor_of(:gtpu_extn_sci), do: :openflow_basic - - # Packet Register - def vendor_of(:xreg0), do: :packet_register - def vendor_of(:xreg1), do: :packet_register - def vendor_of(:xreg2), do: :packet_register - def vendor_of(:xreg3), do: :packet_register - def vendor_of(:xreg4), do: :packet_register - def vendor_of(:xreg5), do: :packet_register - def vendor_of(:xreg6), do: :packet_register - def vendor_of(:xreg7), do: :packet_register - - # Nicira Ext Match - def vendor_of(:nsh_flags), do: :nicira_ext_match - def vendor_of(:nsh_mdtype), do: :nicira_ext_match - def vendor_of(:nsh_np), do: :nicira_ext_match - def vendor_of(:nsh_spi), do: :nicira_ext_match - def vendor_of(:nsh_si), do: :nicira_ext_match - def vendor_of(:nsh_c1), do: :nicira_ext_match - def vendor_of(:nsh_c2), do: :nicira_ext_match - def vendor_of(:nsh_c3), do: :nicira_ext_match - def vendor_of(:nsh_c4), do: :nicira_ext_match - - # HP Ext Match - def vendor_of(:hp_udp_src_port_range), do: :hp_ext_match - def vendor_of(:hp_udp_dst_port_range), do: :hp_ext_match - def vendor_of(:hp_tcp_src_port_range), do: :hp_ext_match - def vendor_of(:hp_tcp_dst_port_range), do: :hp_ext_match - def vendor_of(:hp_tcp_flags), do: :hp_ext_match - def vendor_of(:hp_custom_1), do: :hp_ext_match - def vendor_of(:hp_custom_2), do: :hp_ext_match - def vendor_of(:hp_custom_3), do: :hp_ext_match - def vendor_of(:hp_custom_4), do: :hp_ext_match - - # ONF Ext Match - def vendor_of(:onf_tcp_flags), do: :onf_ext_match - def vendor_of(:onf_actset_output), do: :onf_ext_match - def vendor_of(:onf_pbb_uca), do: :onf_ext_match - - # NXM0 - def format_of(:nx_in_port), do: {:be16, :openflow10_port} - def format_of(:nx_eth_dst), do: {:mac, :ethernet} - def format_of(:nx_eth_src), do: {:mac, :ethernet} - def format_of(:nx_eth_type), do: {:be16, :hexadecimal} - def format_of(:nx_vlan_tci), do: {:be16, :hexadecimal} - def format_of(:nx_ip_tos), do: {:u8, :decimal} - def format_of(:nx_ip_proto), do: {:u8, :decimal} - def format_of(:nx_ipv4_src), do: {:be32, :ipv4} - def format_of(:nx_ipv4_dst), do: {:be32, :ipv4} - def format_of(:nx_tcp_src), do: {:be16, :decimal} - def format_of(:nx_tcp_dst), do: {:be16, :decimal} - def format_of(:nx_udp_src), do: {:be16, :decimal} - def format_of(:nx_udp_dst), do: {:be16, :decimal} - def format_of(:nx_icmpv4_type), do: {:u8, :decimal} - def format_of(:nx_icmpv4_code), do: {:u8, :decimal} - def format_of(:nx_arp_op), do: {:be16, :decimal} - def format_of(:nx_arp_spa), do: {:be32, :ipv4} - def format_of(:nx_arp_tpa), do: {:be32, :ipv4} - def format_of(:nx_tcp_flags), do: {:be16, :tcp_flags} - - # NXM1 - def format_of(:reg0), do: {:be32, :hexadecimal} - def format_of(:reg1), do: {:be32, :hexadecimal} - def format_of(:reg2), do: {:be32, :hexadecimal} - def format_of(:reg3), do: {:be32, :hexadecimal} - def format_of(:reg4), do: {:be32, :hexadecimal} - def format_of(:reg5), do: {:be32, :hexadecimal} - def format_of(:reg6), do: {:be32, :hexadecimal} - def format_of(:reg7), do: {:be32, :hexadecimal} - def format_of(:reg8), do: {:be32, :hexadecimal} - def format_of(:reg9), do: {:be32, :hexadecimal} - def format_of(:reg10), do: {:be32, :hexadecimal} - def format_of(:reg11), do: {:be32, :hexadecimal} - def format_of(:reg12), do: {:be32, :hexadecimal} - def format_of(:reg13), do: {:be32, :hexadecimal} - def format_of(:reg14), do: {:be32, :hexadecimal} - def format_of(:reg15), do: {:be32, :hexadecimal} - def format_of(:tun_id), do: {:be64, :hexadecimal} - def format_of(:nx_arp_sha), do: {:mac, :ethernet} - def format_of(:nx_arp_tha), do: {:mac, :ethernet} - def format_of(:nx_ipv6_src), do: {:be128, :ipv6} - def format_of(:nx_ipv6_dst), do: {:be128, :ipv6} - def format_of(:nx_icmpv6_type), do: {:u8, :decimal} - def format_of(:nx_icmpv6_code), do: {:u8, :decimal} - def format_of(:nx_ipv6_nd_target), do: {:be128, :ipv6} - def format_of(:nx_ipv6_nd_sll), do: {:mac, :ethernet} - def format_of(:nx_ipv6_nd_tll), do: {:mac, :ethernet} - def format_of(:nx_ip_frag), do: {:u8, :decimal} - def format_of(:nx_ipv6_label), do: {:be32, :hexadecimal} - def format_of(:nx_ip_ecn), do: {:u8, :decimal} - def format_of(:nx_ip_ttl), do: {:u8, :decimal} - def format_of(:nx_mpls_ttl), do: {:u8, :decimal} - def format_of(:tun_src), do: {:be32, :ipv4} - def format_of(:tun_dst), do: {:be32, :ipv4} - def format_of(:pkt_mark), do: {:be32, :hexadecimal} - def format_of(:dp_hash), do: {:be32, :hexadecimal} - def format_of(:recirc_id), do: {:be32, :hexadecimal} - def format_of(:conj_id), do: {:be32, :hexadecimal} - def format_of(:nx_tun_gbp_id), do: {:be16, :decimal} - def format_of(:nx_tun_gbp_flags), do: {:u8, :decimal} - def format_of(:tun_metadata0), do: {:dynamic, :bytes} - def format_of(:tun_metadata1), do: {:dynamic, :bytes} - def format_of(:tun_metadata2), do: {:dynamic, :bytes} - def format_of(:tun_metadata3), do: {:dynamic, :bytes} - def format_of(:tun_metadata4), do: {:dynamic, :bytes} - def format_of(:tun_metadata5), do: {:dynamic, :bytes} - def format_of(:tun_metadata6), do: {:dynamic, :bytes} - def format_of(:tun_metadata7), do: {:dynamic, :bytes} - def format_of(:tun_metadata8), do: {:dynamic, :bytes} - def format_of(:tun_metadata9), do: {:dynamic, :bytes} - def format_of(:tun_metadata10), do: {:dynamic, :bytes} - def format_of(:tun_metadata11), do: {:dynamic, :bytes} - def format_of(:tun_metadata12), do: {:dynamic, :bytes} - def format_of(:tun_metadata13), do: {:dynamic, :bytes} - def format_of(:tun_metadata14), do: {:dynamic, :bytes} - def format_of(:tun_metadata15), do: {:dynamic, :bytes} - def format_of(:tun_metadata16), do: {:dynamic, :bytes} - def format_of(:tun_metadata17), do: {:dynamic, :bytes} - def format_of(:tun_metadata18), do: {:dynamic, :bytes} - def format_of(:tun_metadata19), do: {:dynamic, :bytes} - def format_of(:tun_metadata20), do: {:dynamic, :bytes} - def format_of(:tun_metadata21), do: {:dynamic, :bytes} - def format_of(:tun_metadata22), do: {:dynamic, :bytes} - def format_of(:tun_metadata23), do: {:dynamic, :bytes} - def format_of(:tun_metadata24), do: {:dynamic, :bytes} - def format_of(:tun_metadata25), do: {:dynamic, :bytes} - def format_of(:tun_metadata26), do: {:dynamic, :bytes} - def format_of(:tun_metadata27), do: {:dynamic, :bytes} - def format_of(:tun_metadata28), do: {:dynamic, :bytes} - def format_of(:tun_metadata29), do: {:dynamic, :bytes} - def format_of(:tun_metadata30), do: {:dynamic, :bytes} - def format_of(:tun_metadata31), do: {:dynamic, :bytes} - def format_of(:tun_metadata32), do: {:dynamic, :bytes} - def format_of(:tun_metadata33), do: {:dynamic, :bytes} - def format_of(:tun_metadata34), do: {:dynamic, :bytes} - def format_of(:tun_metadata35), do: {:dynamic, :bytes} - def format_of(:tun_metadata36), do: {:dynamic, :bytes} - def format_of(:tun_metadata37), do: {:dynamic, :bytes} - def format_of(:tun_metadata38), do: {:dynamic, :bytes} - def format_of(:tun_metadata39), do: {:dynamic, :bytes} - def format_of(:tun_metadata40), do: {:dynamic, :bytes} - def format_of(:tun_metadata41), do: {:dynamic, :bytes} - def format_of(:tun_metadata42), do: {:dynamic, :bytes} - def format_of(:tun_metadata43), do: {:dynamic, :bytes} - def format_of(:tun_metadata44), do: {:dynamic, :bytes} - def format_of(:tun_metadata45), do: {:dynamic, :bytes} - def format_of(:tun_metadata46), do: {:dynamic, :bytes} - def format_of(:tun_metadata47), do: {:dynamic, :bytes} - def format_of(:tun_metadata48), do: {:dynamic, :bytes} - def format_of(:tun_metadata49), do: {:dynamic, :bytes} - def format_of(:tun_metadata50), do: {:dynamic, :bytes} - def format_of(:tun_metadata51), do: {:dynamic, :bytes} - def format_of(:tun_metadata52), do: {:dynamic, :bytes} - def format_of(:tun_metadata53), do: {:dynamic, :bytes} - def format_of(:tun_metadata54), do: {:dynamic, :bytes} - def format_of(:tun_metadata55), do: {:dynamic, :bytes} - def format_of(:tun_metadata56), do: {:dynamic, :bytes} - def format_of(:tun_metadata57), do: {:dynamic, :bytes} - def format_of(:tun_metadata58), do: {:dynamic, :bytes} - def format_of(:tun_metadata59), do: {:dynamic, :bytes} - def format_of(:tun_metadata60), do: {:dynamic, :bytes} - def format_of(:tun_metadata61), do: {:dynamic, :bytes} - def format_of(:tun_metadata62), do: {:dynamic, :bytes} - def format_of(:tun_metadata63), do: {:dynamic, :bytes} - def format_of(:tun_flags), do: {:be16, :decimal} - def format_of(:ct_state), do: {:be32, :ct_state} - def format_of(:ct_zone), do: {:be16, :hexadecimal} - def format_of(:ct_mark), do: {:be32, :hexadecimal} - def format_of(:ct_label), do: {:be128, :hexadecimal} - def format_of(:tun_ipv6_src), do: {:be128, :ipv6} - def format_of(:tun_ipv6_dst), do: {:be128, :ipv6} - def format_of(:xxreg0), do: {:be128, :hexadecimal} - def format_of(:xxreg1), do: {:be128, :hexadecimal} - def format_of(:xxreg2), do: {:be128, :hexadecimal} - def format_of(:xxreg3), do: {:be128, :hexadecimal} - def format_of(:xxreg4), do: {:be128, :hexadecimal} - def format_of(:xxreg5), do: {:be128, :hexadecimal} - def format_of(:xxreg6), do: {:be128, :hexadecimal} - def format_of(:xxreg7), do: {:be128, :hexadecimal} - def format_of(:ct_ip_proto), do: {:u8, :decimal} - def format_of(:ct_ipv4_src), do: {:be32, :ipv4} - def format_of(:ct_ipv4_dst), do: {:be32, :ipv4} - def format_of(:ct_ipv6_src), do: {:be128, :ipv6} - def format_of(:ct_ipv6_dst), do: {:be128, :ipv6} - def format_of(:ct_tp_src), do: {:be16, :decimal} - def format_of(:ct_tp_dst), do: {:be16, :decimal} - - # OpenFlow Basic - def format_of(:in_port), do: {:be32, :openflow13_port} - def format_of(:in_phy_port), do: {:be32, :openflow13_port} - def format_of(:metadata), do: {:be64, :hexadecimal} - def format_of(:eth_dst), do: {:mac, :ethernet} - def format_of(:eth_src), do: {:mac, :ethernet} - def format_of(:eth_type), do: {:be16, :hexadecimal} - def format_of(:vlan_vid), do: {:be16, :hexadecimal} - def format_of(:vlan_pcp), do: {:u8, :decimal} - def format_of(:ip_dscp), do: {:u8, :decimal} - def format_of(:ip_ecn), do: {:u8, :decimal} - def format_of(:ip_proto), do: {:u8, :decimal} - def format_of(:ipv4_src), do: {:be32, :ipv4} - def format_of(:ipv4_dst), do: {:be32, :ipv4} - def format_of(:tcp_src), do: {:be16, :decimal} - def format_of(:tcp_dst), do: {:be16, :decimal} - def format_of(:udp_src), do: {:be16, :decimal} - def format_of(:udp_dst), do: {:be16, :decimal} - def format_of(:sctp_src), do: {:be16, :decimal} - def format_of(:sctp_dst), do: {:be16, :decimal} - def format_of(:icmpv4_type), do: {:u8, :decimal} - def format_of(:icmpv4_code), do: {:u8, :decimal} - def format_of(:arp_op), do: {:be16, :decimal} - def format_of(:arp_spa), do: {:be32, :ipv4} - def format_of(:arp_tpa), do: {:be32, :ipv4} - def format_of(:arp_sha), do: {:mac, :ethernet} - def format_of(:arp_tha), do: {:mac, :ethernet} - def format_of(:ipv6_src), do: {:be128, :ipv6} - def format_of(:ipv6_dst), do: {:be128, :ipv6} - def format_of(:ipv6_flabel), do: {:be32, :hexadecimal} - def format_of(:icmpv6_type), do: {:u8, :decimal} - def format_of(:icmpv6_code), do: {:u8, :decimal} - def format_of(:ipv6_nd_target), do: {:be128, :ipv6} - def format_of(:ipv6_nd_sll), do: {:mac, :ethernet} - def format_of(:ipv6_nd_tll), do: {:mac, :ethernet} - def format_of(:mpls_label), do: {:be32, :decimal} - def format_of(:mpls_tc), do: {:u8, :decimal} - def format_of(:mpls_bos), do: {:u8, :decimal} - def format_of(:pbb_isid), do: {:u24, :decimal} - def format_of(:tunnel_id), do: {:be64, :hexadecimal} - def format_of(:ipv6_exthdr), do: {:be16, :ipv6exthdr_flags} - def format_of(:pbb_uca), do: {:u8, :decimal} - def format_of(:packet_type), do: {:be32, :decimal} - def format_of(:gre_flags), do: {:be16, :decimal} - def format_of(:gre_ver), do: {:u8, :decimal} - def format_of(:gre_protocol), do: {:be16, :decimal} - def format_of(:gre_key), do: {:be32, :decimal} - def format_of(:gre_seqnum), do: {:be32, :decimal} - def format_of(:lisp_flags), do: {:u8, :decimal} - def format_of(:lisp_nonce), do: {:u24, :decimal} - def format_of(:lisp_id), do: {:be32, :decimal} - def format_of(:vxlan_flags), do: {:u8, :decimal} - def format_of(:vxlan_vni), do: {:u24, :decimal} - def format_of(:mpls_data_first_nibble), do: {:u8, :decimal} - def format_of(:mpls_ach_version), do: {:u8, :decimal} - def format_of(:mpls_ach_channel), do: {:be16, :decimal} - def format_of(:mpls_pw_metadata), do: {:u8, :decimal} - def format_of(:mpls_cw_flags), do: {:u8, :decimal} - def format_of(:mpls_cw_fragment), do: {:u8, :decimal} - def format_of(:mpls_cw_len), do: {:u8, :decimal} - def format_of(:mpls_cw_seq_num), do: {:be16, :decimal} - def format_of(:gtpu_flags), do: {:u8, :decimal} - def format_of(:gtpu_ver), do: {:u8, :decimal} - def format_of(:gtpu_msg_type), do: {:u8, :decimal} - def format_of(:gtpu_teid), do: {:be32, :decimal} - def format_of(:gtpu_extn_hdr), do: {:u8, :decimal} - def format_of(:gtpu_extn_udp_port), do: {:be16, :decimal} - def format_of(:gtpu_extn_sci), do: {:be16, :decimal} - - # Packet Register - def format_of(:xreg0), do: {:be64, :hexadecimal} - def format_of(:xreg1), do: {:be64, :hexadecimal} - def format_of(:xreg2), do: {:be64, :hexadecimal} - def format_of(:xreg3), do: {:be64, :hexadecimal} - def format_of(:xreg4), do: {:be64, :hexadecimal} - def format_of(:xreg5), do: {:be64, :hexadecimal} - def format_of(:xreg6), do: {:be64, :hexadecimal} - def format_of(:xreg7), do: {:be64, :hexadecimal} - - # Nicira Ext Match - def format_of(:nsh_flags), do: {:u8, :decimal} - def format_of(:nsh_mdtype), do: {:u8, :decimal} - def format_of(:nsh_np), do: {:u8, :decimal} - def format_of(:nsh_spi), do: {:be32, :decimal} - def format_of(:nsh_si), do: {:be32, :decimal} - def format_of(:nsh_c1), do: {:be32, :decimal} - def format_of(:nsh_c2), do: {:be32, :decimal} - def format_of(:nsh_c3), do: {:be32, :decimal} - def format_of(:nsh_c4), do: {:be32, :decimal} - - # HP Ext Match - def format_of(:hp_udp_src_port_range), do: {:be32, :decimal} - def format_of(:hp_udp_dst_port_range), do: {:be32, :decimal} - def format_of(:hp_tcp_src_port_range), do: {:be32, :decimal} - def format_of(:hp_tcp_dst_port_range), do: {:be32, :decimal} - def format_of(:hp_tcp_flags), do: {:be16, :tcp_flags} - def format_of(:hp_custom_1), do: {:dynamic, :bytes} - def format_of(:hp_custom_2), do: {:dynamic, :bytes} - def format_of(:hp_custom_3), do: {:dynamic, :bytes} - def format_of(:hp_custom_4), do: {:dynamic, :bytes} - - # ONF Ext Match - def format_of(:onf_tcp_flags), do: {:be16, :tcp_flags} - def format_of(:onf_actset_output), do: {:be32, :openflow13_port} - def format_of(:onf_pbb_uca), do: {:u8, :decimal} - - # Formatting = decimal - def formatting(<>, :u8, :decimal), do: value - def formatting(value, :u8, :decimal) when is_integer(value), do: <> - def formatting(<>, :be16, :decimal), do: value - def formatting(value, :be16, :decimal) when is_integer(value), do: <> - def formatting(<>, :u24, :decimal), do: value - def formatting(value, :u24, :decimal) when is_integer(value), do: <> - def formatting(<>, :be32, :decimal), do: value - def formatting(value, :be32, :decimal) when is_integer(value), do: <> - def formatting(<>, :be64, :decimal), do: value - def formatting(value, :be64, :decimal) when is_integer(value), do: <> - def formatting(<>, :be128, :decimal), do: value - def formatting(value, :be128, :decimal) when is_integer(value), do: <> - - # Formatting = hexadecimal - def formatting(<>, :be16, :hexadecimal), do: value - def formatting(value, :be16, :hexadecimal) when is_integer(value), do: <> - - def formatting(<>, :u24, :hexadecimal), do: value - def formatting(value, :u24, :hexadecimal) when is_integer(value), do: <> - - def formatting(<>, :be32, :hexadecimal), do: value - def formatting(value, :be32, :hexadecimal) when is_integer(value), do: <> - - def formatting(<>, :be64, :hexadecimal), do: value - def formatting(value, :be64, :hexadecimal) when is_integer(value), do: <> - - def formatting(<>, :be128, :hexadecimal), do: value - def formatting(value, :be128, :hexadecimal) when is_integer(value), do: <> - - # Formatting = ethernet - def formatting(<>, :mac, :ethernet), do: Openflow.Utils.to_hex_string(value) - def formatting(value, :mac, :ethernet), do: <> - - # Formatting = IPv4 - def formatting(<>, :be32, :ipv4), do: {a1, a2, a3, a4} - def formatting({a1, a2, a3, a4}, :be32, :ipv4), do: <> - - # Formatting = IPv6 - def formatting( - <>, - :be128, - :ipv6 - ) do - {a1, a2, a3, a4, a5, a6, a7, a8} - end - - def formatting({a1, a2, a3, a4, a5, a6, a7, a8}, :be128, :ipv6) do - <> - end - - # Formatting = OpenFlow 1.0 port - def formatting(<>, :be16, :openflow10_port) do - try do - Openflow.Enums.to_atom(value, :openflow10_port_no) - catch - :bad_enum -> value - end - end - - def formatting(value, :be16, :openflow10_port) do - port_no = - try do - Openflow.Enums.to_int(value, :openflow10_port_no) - catch - :bad_enum -> value - end - - <> - end - - # Formatting = OpenFlow 1.3 port - def formatting(<>, :be32, :openflow13_port) do - try do - Openflow.Enums.to_atom(value, :openflow13_port_no) - catch - :bad_enum -> value - end - end - - def formatting(value, :be32, :openflow13_port) do - port_no = - try do - Openflow.Enums.to_int(value, :openflow13_port_no) - catch - :bad_enum -> value - end - - <> - end - - # TCP flags - def formatting(<>, :be16, :tcp_flags) do - Openflow.Enums.int_to_flags(value, :tcp_flags) - end - - def formatting(value, :be16, :tcp_flags) do - <> - end - - # CT State - def formatting(<>, :be32, :ct_state) do - Openflow.Enums.int_to_flags(value, :ct_state_flags) - end - - def formatting(value, :be32, :ct_state) do - <> - end - - # CT State - def formatting(<>, :be16, :ipv6exthdr_flags) do - Openflow.Enums.int_to_flags(value, :ipv6exthdr_flags) - end - - def formatting(value, :be16, :ipv6exthdr_flags) do - <> - end - - # Other - def formatting(value, _, _) do - value - end -end diff --git a/priv/openflow_enum_gen.exs b/priv/openflow_enum_gen.exs index 6d1da7a..ae370b7 100644 --- a/priv/openflow_enum_gen.exs +++ b/priv/openflow_enum_gen.exs @@ -508,39 +508,13 @@ enums = [ pbb_isid: 37, tunnel_id: 38, ipv6_exthdr: 39, - - # Lagopus extended match fields - pbb_uca: 41, - packet_type: 42, - gre_flags: 43, - gre_ver: 44, - gre_protocol: 45, - gre_key: 46, - gre_seqnum: 47, - lisp_flags: 48, - lisp_nonce: 49, - lisp_id: 50, - vxlan_flags: 51, - vxlan_vni: 52, - mpls_data_first_nibble: 53, - mpls_ach_version: 54, - mpls_ach_channel: 55, - mpls_pw_metadata: 56, - mpls_cw_flags: 57, - mpls_cw_fragment: 58, - mpls_cw_len: 59, - mpls_cw_seq_num: 60, - gtpu_flags: 61, - gtpu_ver: 62, - gtpu_msg_type: 63, - gtpu_teid: 64, - gtpu_extn_hdr: 65, - gtpu_extn_udp_port: 66, - gtpu_extn_sci: 67 + pbb_uca: 41 ], vlan_id: [ - present: 0x1000, - none: 0x0000 + # Bit that indicate that a VLAN id is set. + vid_present: 0x1000, + # No VLAN id was set. + vid_none: 0x0000 ], ipv6exthdr_flags: [ nonext: 1 <<< 0, @@ -564,6 +538,10 @@ enums = [ cwr: 1 <<< 7, ns: 1 <<< 8 ], + tun_gbp_flags: [ + policy_applied: 1 <<< 3, + dont_learn: 1 <<< 6 + ], ct_state_flags: [ # Beginning of a new connection. new: 1 <<< 0, @@ -601,23 +579,8 @@ enums = [ nsh_c1: 6, nsh_c2: 7, nsh_c3: 8, - nsh_c4: 9 - ], - hp_ext_match: [ - hp_udp_src_port_range: 0, - hp_udp_dst_port_range: 1, - hp_tcp_src_port_range: 2, - hp_tcp_dst_port_range: 3, - hp_tcp_flags: 4, - hp_custom_1: 5, - hp_custom_2: 6, - hp_custom_3: 7, - hp_custom_4: 8 - ], - hp_custom_match_type: [ - l2_start: 1, - l3_start: 2, - l4_start: 3 + nsh_c4: 9, + nsh_ttl: 10 ], onf_ext_match: [ onf_tcp_flags: 42, diff --git a/test/lib/openflow/ofp_flow_mod_test.exs b/test/lib/openflow/ofp_flow_mod_test.exs index ea8a5cd..aca8f69 100644 --- a/test/lib/openflow/ofp_flow_mod_test.exs +++ b/test/lib/openflow/ofp_flow_mod_test.exs @@ -36,7 +36,7 @@ defmodule OfpFlowModTest do assert fm.out_port == :any assert fm.out_group == :any assert fm.flags == [] - assert fm.match == Openflow.Match.new(eth_dst: "f20ba47df8ea") + assert fm.match == Openflow.Match.new(eth_dst: <<0xF20BA47DF8EA::48>>) assert fm.instructions == [ Openflow.Instruction.WriteActions.new([ @@ -60,7 +60,7 @@ defmodule OfpFlowModTest do Openflow.Action.Output.new(6) ]), Openflow.Instruction.ApplyActions.new([ - Openflow.Action.SetField.new(eth_src: "010203040506"), + Openflow.Action.SetField.new(eth_src: <<0x010203040506::48>>), Openflow.Action.SetField.new(onf_pbb_uca: 1) ]) ] @@ -84,7 +84,7 @@ defmodule OfpFlowModTest do assert fm.out_port == :any assert fm.out_group == :any assert fm.flags == [] - assert fm.match == Openflow.Match.new(in_port: 6, eth_src: "f20ba47df8ea") + assert fm.match == Openflow.Match.new(in_port: 6, eth_src: <<0xF20BA47DF8EA::48>>) assert fm.instructions == [Openflow.Instruction.GotoTable.new(1)] assert Openflow.to_binary(fm) == binary end @@ -104,7 +104,7 @@ defmodule OfpFlowModTest do assert fm.out_port == :any assert fm.out_group == :any assert fm.flags == [] - assert fm.match == Openflow.Match.new(eth_dst: "f20ba47df8ea") + assert fm.match == Openflow.Match.new(eth_dst: <<0xF20BA47DF8EA::48>>) assert fm.instructions == [ Openflow.Instruction.Meter.new(1), @@ -136,8 +136,8 @@ defmodule OfpFlowModTest do in_phy_port: 16_909_060, metadata: 283_686_952_306_183, eth_type: 2054, - eth_dst: "ffffffffffff", - eth_src: "f20ba47df8ea", + eth_dst: <<0xFFFFFFFFFFFF::48>>, + eth_src: <<0xF20BA47DF8EA::48>>, vlan_vid: 999, ip_dscp: 9, ip_ecn: 3, @@ -155,16 +155,16 @@ defmodule OfpFlowModTest do arp_op: 1, arp_spa: {10, 0, 0, 1}, arp_tpa: {10, 0, 0, 3}, - arp_sha: "f20ba47df8ea", - arp_tha: "000000000000", + 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: "00000000029a", - ipv6_nd_tll: "00000000022b", + ipv6_nd_sll: <<0x00000000029A::48>>, + ipv6_nd_tll: <<0x00000000022B::48>>, mpls_label: 624_485, mpls_tc: 5, mpls_bos: 1, @@ -199,7 +199,7 @@ defmodule OfpFlowModTest do assert fm.match == Openflow.Match.new( in_port: 43981, - eth_dst: "aabbcc998877", + eth_dst: <<0xAABBCC998877::48>>, eth_type: 2048, vlan_vid: 5095, ipv4_dst: {192, 168, 2, 1}, @@ -223,7 +223,11 @@ defmodule OfpFlowModTest do n_bits: 12 ), Openflow.Action.NxFlowSpecMatch.new(src: :nx_eth_src, dst: :nx_eth_dst), - Openflow.Action.NxFlowSpecLoad.new(src: 0, dst: :vlan_vid, n_bits: 12), + Openflow.Action.NxFlowSpecLoad.new( + src: 0, + dst: :vlan_vid, + n_bits: 12 + ), Openflow.Action.NxFlowSpecLoad.new(src: :tun_id, dst: :tun_id), Openflow.Action.NxFlowSpecOutput.new(src: :in_port) ] @@ -261,7 +265,7 @@ defmodule OfpFlowModTest do assert fm.match == Openflow.Match.new( in_port: 43981, - eth_dst: "aabbcc998877", + eth_dst: <<0xAABBCC998877::48>>, eth_type: 2048, vlan_vid: 5095, ipv4_dst: {192, 168, 2, 1}, diff --git a/test/lib/openflow/ofp_flow_removed_test.exs b/test/lib/openflow/ofp_flow_removed_test.exs index 056f78f..9454307 100644 --- a/test/lib/openflow/ofp_flow_removed_test.exs +++ b/test/lib/openflow/ofp_flow_removed_test.exs @@ -21,7 +21,7 @@ defmodule OfpFlowRemovedTest do assert flow_removed.hard_timeout == 0 assert flow_removed.packet_count == 1 assert flow_removed.byte_count == 86 - assert flow_removed.match == [eth_dst: "f20ba47df8ea"] + assert flow_removed.match == [eth_dst: <<0xF20BA47DF8EA::48>>] end test "with OFP_FLOW_REMOVED packet(with match fields)" do @@ -45,7 +45,7 @@ defmodule OfpFlowRemovedTest do assert flow_removed.match == [ in_port: 43_981, - eth_dst: "aabbcc998877", + eth_dst: <<0xAABBCC998877::48>>, eth_type: 2048, vlan_vid: 5095, ipv4_dst: {192, 168, 2, 1}, diff --git a/test/lib/openflow/ofp_flow_stats_test.exs b/test/lib/openflow/ofp_flow_stats_test.exs index 0eecc19..96fe3dc 100644 --- a/test/lib/openflow/ofp_flow_stats_test.exs +++ b/test/lib/openflow/ofp_flow_stats_test.exs @@ -75,7 +75,7 @@ defmodule OfpFlowStatsTest do hard_timeout: 0, idle_timeout: 0, instructions: [%Openflow.Instruction.GotoTable{table_id: 1}], - match: [in_port: 6, eth_src: "f20ba47df8ea"], + match: [in_port: 6, eth_src: <<0xF20BA47DF8EA::48>>], packet_count: 3, priority: 123, table_id: 0 @@ -114,7 +114,7 @@ defmodule OfpFlowStatsTest do }, %Openflow.Instruction.ApplyActions{ actions: [ - %Openflow.Action.SetField{field: [eth_src: "010203040506"]}, + %Openflow.Action.SetField{field: [eth_src: <<0x010203040506::48>>]}, %Openflow.Action.SetField{field: [onf_pbb_uca: 1]} ] }, diff --git a/test/lib/openflow/ofp_packet_in_test.exs b/test/lib/openflow/ofp_packet_in_test.exs index b39a9a8..5199fc2 100644 --- a/test/lib/openflow/ofp_packet_in_test.exs +++ b/test/lib/openflow/ofp_packet_in_test.exs @@ -18,13 +18,13 @@ defmodule OfpPacketInTest do assert pktin.match == [ eth_type: 2054, - eth_dst: "ffffffffffff", - eth_src: "f20ba47df8ea", + eth_dst: <<0xFFFFFFFFFFFF::48>>, + eth_src: <<0xF20BA47DF8EA::48>>, arp_op: 1, arp_spa: {10, 0, 0, 1}, arp_tpa: {10, 0, 0, 3}, - arp_sha: "f20ba47df8ea", - arp_tha: "000000000000" + arp_sha: <<0xF20BA47DF8EA::48>>, + arp_tha: <<0x000000000000::48>> ] end @@ -45,8 +45,8 @@ defmodule OfpPacketInTest do in_phy_port: 16_909_060, metadata: 283_686_952_306_183, eth_type: 2054, - eth_dst: "ffffffffffff", - eth_src: "f20ba47df8ea", + eth_dst: <<0xFFFFFFFFFFFF::48>>, + eth_src: <<0xF20BA47DF8EA::48>>, vlan_vid: 999, ip_dscp: 9, ip_ecn: 3, @@ -64,16 +64,16 @@ defmodule OfpPacketInTest do arp_op: 1, arp_spa: {10, 0, 0, 1}, arp_tpa: {10, 0, 0, 3}, - arp_sha: "f20ba47df8ea", - arp_tha: "000000000000", + 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: "00000000029a", - ipv6_nd_tll: "00000000022b", + ipv6_nd_sll: <<0x00000000029A::48>>, + ipv6_nd_tll: <<0x00000000022B::48>>, mpls_label: 624_485, mpls_tc: 5, mpls_bos: 1, diff --git a/test/lib/openflow/ofp_tables_features_test.exs b/test/lib/openflow/ofp_tables_features_test.exs index 46157f8..767393e 100644 --- a/test/lib/openflow/ofp_tables_features_test.exs +++ b/test/lib/openflow/ofp_tables_features_test.exs @@ -25,7 +25,9 @@ defmodule OfpTableFeaturesTest do "test/packet_data/4-56-ofp_table_features_reply.packet" |> File.read!() |> Openflow.read() - |> Kernel.elem(1) + |> Kernel.elem(0) + |> Kernel.==(:ok) + |> assert() end end end From da4165b670611d568128ee6ca00eee06e35f0481 Mon Sep 17 00:00:00 2001 From: Eishun Kondoh Date: Tue, 9 Jul 2019 12:00:58 +0900 Subject: [PATCH 04/12] mix: Version bump --- README.md | 2 +- mix.exs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 73629da..f011f1b 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Tres is a framework and set of helper libraries to develop OpenFlow controllers ```elixir def deps do [ - {:tres, "~> 0.1.1"} + {:tres, "~> 0.1.2"} ] end ``` diff --git a/mix.exs b/mix.exs index cf375e3..0ac30ca 100644 --- a/mix.exs +++ b/mix.exs @@ -8,7 +8,7 @@ defmodule Tres.Mixfile do def project do [ app: :tres, - version: "0.1.1", + version: "0.1.2", description: @description, elixir: "~> 1.8", package: package(), From ccb420cbce980d2d9330be7f79f0f86bd121c75d Mon Sep 17 00:00:00 2001 From: Eishun Kondoh Date: Tue, 9 Jul 2019 12:14:02 +0900 Subject: [PATCH 05/12] quality/travis: bump into OTP-22.x --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 097035a..ecbde71 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ language: elixir elixir: - "1.8.1" otp_release: - - "21.3.6" + - "22.0.5" before_install: - sudo apt-get install -y wget curl gdebi debhelper unbound From 6ce014ea91edf0f2a08afd55bdcebfa9cf8105d1 Mon Sep 17 00:00:00 2001 From: Eishun Kondoh Date: Mon, 22 Jul 2019 20:14:42 +0900 Subject: [PATCH 06/12] openflow/actions: Add nx_check_pkt_larger (#17) this action available since post-2.11 --- lib/openflow/actions/nx_check_pkt_larger.ex | 46 ++++++++++++++++++++ lib/openflow/enums.ex | 15 +++++++ lib/tres/messages.ex | 1 + priv/openflow_enum_gen.exs | 1 + test/lib/openflow/ofp_action_test.exs | 31 +++++++++++++ test/packet_data/nx_check_pkt_larger.raw | Bin 0 -> 32 bytes 6 files changed, 94 insertions(+) create mode 100644 lib/openflow/actions/nx_check_pkt_larger.ex create mode 100644 test/packet_data/nx_check_pkt_larger.raw diff --git a/lib/openflow/actions/nx_check_pkt_larger.ex b/lib/openflow/actions/nx_check_pkt_larger.ex new file mode 100644 index 0000000..ac0ecb6 --- /dev/null +++ b/lib/openflow/actions/nx_check_pkt_larger.ex @@ -0,0 +1,46 @@ +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/enums.ex b/lib/openflow/enums.ex index 6975a3d..61ff9e5 100644 --- a/lib/openflow/enums.ex +++ b/lib/openflow/enums.ex @@ -4417,6 +4417,12 @@ 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 @@ -9619,6 +9625,12 @@ 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 @@ -11888,6 +11900,7 @@ 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 @@ -11927,6 +11940,7 @@ 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 @@ -13742,6 +13756,7 @@ 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/tres/messages.ex b/lib/tres/messages.ex index 04810a2..2705465 100644 --- a/lib/tres/messages.ex +++ b/lib/tres/messages.ex @@ -117,6 +117,7 @@ defmodule Tres.Messages do alias Openflow.Action.NxEncap alias Openflow.Action.NxDecap alias Openflow.Action.NxDebugRecirc + alias Openflow.Action.NxCheckPktLarger alias Openflow.Action.NxFlowSpecMatch alias Openflow.Action.NxFlowSpecLoad diff --git a/priv/openflow_enum_gen.exs b/priv/openflow_enum_gen.exs index ae370b7..f6cdcb9 100644 --- a/priv/openflow_enum_gen.exs +++ b/priv/openflow_enum_gen.exs @@ -861,6 +861,7 @@ 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 f2c6296..dc24c96 100644 --- a/test/lib/openflow/ofp_action_test.exs +++ b/test/lib/openflow/ofp_action_test.exs @@ -1017,6 +1017,37 @@ 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/packet_data/nx_check_pkt_larger.raw b/test/packet_data/nx_check_pkt_larger.raw new file mode 100644 index 0000000000000000000000000000000000000000..adeeeeed74ca71f07ed41d3527e962c31145f4d0 GIT binary patch literal 32 ccmezWpFx3vL0N&pkRgSEfq{{Ug#iTs09H2w{r~^~ literal 0 HcmV?d00001 From 6dc3cfd500d7948d4c0edcc2ce226d1e3c7490db Mon Sep 17 00:00:00 2001 From: Eishun Kondoh Date: Wed, 24 Jul 2019 02:05:39 +0900 Subject: [PATCH 07/12] openflow/learn_flow_spec: Fix to use src field if dst field is omitted, as dst field. --- .../lib/nx_learning_switch.ex | 48 ++++++++++--------- lib/openflow/actions/nx_flow_spec_match.ex | 2 +- test/lib/openflow/ofp_action_test.exs | 17 ++++--- 3 files changed, 34 insertions(+), 33 deletions(-) diff --git a/examples/nx_learning_switch/lib/nx_learning_switch.ex b/examples/nx_learning_switch/lib/nx_learning_switch.ex index 2565ec2..9c3d9b9 100644 --- a/examples/nx_learning_switch/lib/nx_learning_switch.ex +++ b/examples/nx_learning_switch/lib/nx_learning_switch.ex @@ -56,29 +56,7 @@ defmodule NxLearningSwitch do send_flow_mod_add( datapath_id, table_id: 0, - 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) - ]) + instructions: l2_learning_instr() ) end @@ -90,4 +68,28 @@ 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/nx_flow_spec_match.ex b/lib/openflow/actions/nx_flow_spec_match.ex index d9b76b3..546aeb8 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/test/lib/openflow/ofp_action_test.exs b/test/lib/openflow/ofp_action_test.exs index dc24c96..1edc5d8 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, dst: :nx_vlan_tci, n_bits: 12), + Openflow.Action.NxFlowSpecMatch.new(src: :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, dst: :nx_vlan_tci, n_bits: 12), + Openflow.Action.NxFlowSpecMatch.new(src: :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,22 +846,21 @@ defmodule OfpActionTest do end test "with no option" do - assert_raise RuntimeError, ":dst must be specified", fn -> + assert_raise RuntimeError, ":src 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 From ca02fe7ed752bb70ad68945d5ba70ceabbcbeb99 Mon Sep 17 00:00:00 2001 From: Eishun Kondoh Date: Wed, 24 Jul 2019 02:38:45 +0900 Subject: [PATCH 08/12] openflow/actions: Improve readability of experimenter action codec --- lib/openflow/actions/experimenter.ex | 68 ++++++++++++++++++---------- 1 file changed, 44 insertions(+), 24 deletions(-) diff --git a/lib/openflow/actions/experimenter.ex b/lib/openflow/actions/experimenter.ex index 16b3302..4f7cf47 100644 --- a/lib/openflow/actions/experimenter.ex +++ b/lib/openflow/actions/experimenter.ex @@ -20,34 +20,54 @@ defmodule Openflow.Action.Experimenter do @spec pack_exp_header(binary()) :: binary() def pack_exp_header(exp_body) do - pad_length = - exp_body - |> Kernel.byte_size() - |> Kernel.+(4) - |> Openflow.Utils.padding(8) + pad_length = pad_length_of(exp_body) - length = - exp_body - |> byte_size() - |> Kernel.+(4) - |> Kernel.+(pad_length) - - <<0xFFFF::16, length::16, exp_body::bytes, 0::size(pad_length)-unit(8)>> + << + 0xFFFF::16, + length_of(exp_body, pad_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 - case Openflow.Utils.get_enum(exp_id, :action_vendor) do - vendor_id when is_integer(vendor_id) -> + 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) -> %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 From c81cf9e8ba57617c9e1d3ca1f6ba6420f8514983 Mon Sep 17 00:00:00 2001 From: Eishun Kondoh Date: Wed, 31 Jul 2019 18:37:22 +0900 Subject: [PATCH 09/12] openflow/field: Add support for OXM_OF_PACKET_TYPE --- lib/openflow/enums.ex | 17 ++++++++++++++++- lib/openflow/match.ex | 6 ++++-- priv/openflow_enum_gen.exs | 3 ++- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/lib/openflow/enums.ex b/lib/openflow/enums.ex index 61ff9e5..092f63c 100644 --- a/lib/openflow/enums.ex +++ b/lib/openflow/enums.ex @@ -2725,6 +2725,12 @@ 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 @@ -7933,6 +7939,12 @@ 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 @@ -11306,6 +11318,7 @@ 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 @@ -11348,6 +11361,7 @@ 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 @@ -13484,7 +13498,8 @@ defmodule Openflow.Enums do pbb_isid: 37, tunnel_id: 38, ipv6_exthdr: 39, - pbb_uca: 41 + pbb_uca: 41, + packet_type: 44 ] defp enum_of(:vlan_id), do: [vid_present: 4096, vid_none: 0] diff --git a/lib/openflow/match.ex b/lib/openflow/match.ex index 2f60a63..f7abea6 100644 --- a/lib/openflow/match.ex +++ b/lib/openflow/match.ex @@ -370,7 +370,8 @@ defmodule Openflow.Match do :pbb_isid, :tunnel_id, :ipv6_exthdr, - :pbb_uca + :pbb_uca, + :packet_type ], do: 0x8000 @@ -758,7 +759,8 @@ defmodule Openflow.Match do :nsh_c1, :nsh_c2, :nsh_c3, - :nsh_c4 + :nsh_c4, + :packet_type ], do: :u32 diff --git a/priv/openflow_enum_gen.exs b/priv/openflow_enum_gen.exs index f6cdcb9..a69900a 100644 --- a/priv/openflow_enum_gen.exs +++ b/priv/openflow_enum_gen.exs @@ -508,7 +508,8 @@ enums = [ pbb_isid: 37, tunnel_id: 38, ipv6_exthdr: 39, - pbb_uca: 41 + pbb_uca: 41, + packet_type: 44 ], vlan_id: [ # Bit that indicate that a VLAN id is set. From d8a17d2d94f029a502b02356dc05b1e0ecbb8561 Mon Sep 17 00:00:00 2001 From: Eishun Kondoh Date: Wed, 31 Jul 2019 20:34:00 +0900 Subject: [PATCH 10/12] openflow/field: Fix broken NXOXM/ONFOXM fields --- lib/openflow/enums.ex | 267 ++++++++++++++++------ lib/openflow/match.ex | 34 ++- priv/openflow_enum_gen.exs | 12 +- test/lib/openflow/ofp_flow_mod_test.exs | 122 ---------- test/lib/openflow/ofp_flow_stats_test.exs | 118 ---------- test/lib/openflow/ofp_packet_in_test.exs | 58 ----- 6 files changed, 227 insertions(+), 384 deletions(-) diff --git a/lib/openflow/enums.ex b/lib/openflow/enums.ex index 092f63c..7913581 100644 --- a/lib/openflow/enums.ex +++ b/lib/openflow/enums.ex @@ -1535,10 +1535,16 @@ defmodule Openflow.Enums do throw(:bad_enum) end - def to_int(:nicira_ext_match, :experimenter_oxm_vendors) do - experimenter_oxm_vendors_to_int(:nicira_ext_match) + def to_int(:nxoxm_nsh_match, :experimenter_oxm_vendors) do + experimenter_oxm_vendors_to_int(:nxoxm_nsh_match) catch - _class, _reason -> :nicira_ext_match + _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 end def to_int(:hp_ext_match, :experimenter_oxm_vendors) do @@ -2987,67 +2993,67 @@ defmodule Openflow.Enums do throw(:bad_enum) end - def to_int(:nsh_flags, :nicira_ext_match) do - nicira_ext_match_to_int(:nsh_flags) + def to_int(:nsh_flags, :nxoxm_nsh_match) do + nxoxm_nsh_match_to_int(:nsh_flags) catch _class, _reason -> :nsh_flags end - def to_int(:nsh_mdtype, :nicira_ext_match) do - nicira_ext_match_to_int(:nsh_mdtype) + def to_int(:nsh_mdtype, :nxoxm_nsh_match) do + nxoxm_nsh_match_to_int(:nsh_mdtype) catch _class, _reason -> :nsh_mdtype end - def to_int(:nsh_np, :nicira_ext_match) do - nicira_ext_match_to_int(:nsh_np) + def to_int(:nsh_np, :nxoxm_nsh_match) do + nxoxm_nsh_match_to_int(:nsh_np) catch _class, _reason -> :nsh_np end - def to_int(:nsh_spi, :nicira_ext_match) do - nicira_ext_match_to_int(:nsh_spi) + def to_int(:nsh_spi, :nxoxm_nsh_match) do + nxoxm_nsh_match_to_int(:nsh_spi) catch _class, _reason -> :nsh_spi end - def to_int(:nsh_si, :nicira_ext_match) do - nicira_ext_match_to_int(:nsh_si) + def to_int(:nsh_si, :nxoxm_nsh_match) do + nxoxm_nsh_match_to_int(:nsh_si) catch _class, _reason -> :nsh_si end - def to_int(:nsh_c1, :nicira_ext_match) do - nicira_ext_match_to_int(:nsh_c1) + def to_int(:nsh_c1, :nxoxm_nsh_match) do + nxoxm_nsh_match_to_int(:nsh_c1) catch _class, _reason -> :nsh_c1 end - def to_int(:nsh_c2, :nicira_ext_match) do - nicira_ext_match_to_int(:nsh_c2) + def to_int(:nsh_c2, :nxoxm_nsh_match) do + nxoxm_nsh_match_to_int(:nsh_c2) catch _class, _reason -> :nsh_c2 end - def to_int(:nsh_c3, :nicira_ext_match) do - nicira_ext_match_to_int(:nsh_c3) + def to_int(:nsh_c3, :nxoxm_nsh_match) do + nxoxm_nsh_match_to_int(:nsh_c3) catch _class, _reason -> :nsh_c3 end - def to_int(:nsh_c4, :nicira_ext_match) do - nicira_ext_match_to_int(:nsh_c4) + def to_int(:nsh_c4, :nxoxm_nsh_match) do + nxoxm_nsh_match_to_int(:nsh_c4) catch _class, _reason -> :nsh_c4 end - def to_int(:nsh_ttl, :nicira_ext_match) do - nicira_ext_match_to_int(:nsh_ttl) + def to_int(:nsh_ttl, :nxoxm_nsh_match) do + nxoxm_nsh_match_to_int(:nsh_ttl) catch _class, _reason -> :nsh_ttl end - def to_int(_int, :nicira_ext_match) do + def to_int(_int, :nxoxm_nsh_match) do throw(:bad_enum) end @@ -3073,6 +3079,40 @@ 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 @@ -6749,6 +6789,12 @@ 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 @@ -8201,67 +8247,67 @@ defmodule Openflow.Enums do throw(:bad_enum) end - def to_atom(0x1, :nicira_ext_match) do - nicira_ext_match_to_atom(0x1) + def to_atom(0x1, :nxoxm_nsh_match) do + nxoxm_nsh_match_to_atom(0x1) catch _class, _reason -> 1 end - def to_atom(0x2, :nicira_ext_match) do - nicira_ext_match_to_atom(0x2) + def to_atom(0x2, :nxoxm_nsh_match) do + nxoxm_nsh_match_to_atom(0x2) catch _class, _reason -> 2 end - def to_atom(0x3, :nicira_ext_match) do - nicira_ext_match_to_atom(0x3) + def to_atom(0x3, :nxoxm_nsh_match) do + nxoxm_nsh_match_to_atom(0x3) catch _class, _reason -> 3 end - def to_atom(0x4, :nicira_ext_match) do - nicira_ext_match_to_atom(0x4) + def to_atom(0x4, :nxoxm_nsh_match) do + nxoxm_nsh_match_to_atom(0x4) catch _class, _reason -> 4 end - def to_atom(0x5, :nicira_ext_match) do - nicira_ext_match_to_atom(0x5) + def to_atom(0x5, :nxoxm_nsh_match) do + nxoxm_nsh_match_to_atom(0x5) catch _class, _reason -> 5 end - def to_atom(0x6, :nicira_ext_match) do - nicira_ext_match_to_atom(0x6) + def to_atom(0x6, :nxoxm_nsh_match) do + nxoxm_nsh_match_to_atom(0x6) catch _class, _reason -> 6 end - def to_atom(0x7, :nicira_ext_match) do - nicira_ext_match_to_atom(0x7) + def to_atom(0x7, :nxoxm_nsh_match) do + nxoxm_nsh_match_to_atom(0x7) catch _class, _reason -> 7 end - def to_atom(0x8, :nicira_ext_match) do - nicira_ext_match_to_atom(0x8) + def to_atom(0x8, :nxoxm_nsh_match) do + nxoxm_nsh_match_to_atom(0x8) catch _class, _reason -> 8 end - def to_atom(0x9, :nicira_ext_match) do - nicira_ext_match_to_atom(0x9) + def to_atom(0x9, :nxoxm_nsh_match) do + nxoxm_nsh_match_to_atom(0x9) catch _class, _reason -> 9 end - def to_atom(0xA, :nicira_ext_match) do - nicira_ext_match_to_atom(0xA) + def to_atom(0xA, :nxoxm_nsh_match) do + nxoxm_nsh_match_to_atom(0xA) catch _class, _reason -> 10 end - def to_atom(_, :nicira_ext_match) do + def to_atom(_, :nxoxm_nsh_match) do throw(:bad_enum) end @@ -8287,6 +8333,40 @@ 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 @@ -10959,11 +11039,13 @@ 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(:nicira_ext_match), do: 0x2320 + 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(: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(0x2320), do: :nicira_ext_match + 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(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) @@ -11451,28 +11533,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 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 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 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 @@ -11481,6 +11563,18 @@ 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 @@ -12392,14 +12486,18 @@ defmodule Openflow.Enums do Openflow.Utils.int_to_flags([], int, enum_of(:packet_register)) end - def int_to_flags(int, :nicira_ext_match) do - Openflow.Utils.int_to_flags([], int, enum_of(:nicira_ext_match)) + def int_to_flags(int, :nxoxm_nsh_match) do + Openflow.Utils.int_to_flags([], int, enum_of(:nxoxm_nsh_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 @@ -12776,14 +12874,18 @@ defmodule Openflow.Enums do Openflow.Utils.flags_to_int(0, flags, enum_of(:packet_register)) end - def flags_to_int(flags, :nicira_ext_match) do - Openflow.Utils.flags_to_int(0, flags, enum_of(:nicira_ext_match)) + def flags_to_int(flags, :nxoxm_nsh_match) do + Openflow.Utils.flags_to_int(0, flags, enum_of(:nxoxm_nsh_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 @@ -13291,7 +13393,12 @@ defmodule Openflow.Enums do defp enum_of(:controller_max_len), do: [max: 65509, no_buffer: 65535] defp enum_of(:experimenter_oxm_vendors), - do: [nicira_ext_match: 8992, hp_ext_match: 9256, onf_ext_match: 1_330_529_792] + do: [ + nxoxm_nsh_match: 5_953_104, + nxoxm_match: 8992, + hp_ext_match: 9256, + onf_ext_match: 1_330_529_792 + ] defp enum_of(:match_type), do: [standard: 0, oxm: 1] @@ -13528,7 +13635,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(:nicira_ext_match), + defp enum_of(:nxoxm_nsh_match), do: [ nsh_flags: 1, nsh_mdtype: 2, @@ -13543,6 +13650,16 @@ 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] diff --git a/lib/openflow/match.ex b/lib/openflow/match.ex index f7abea6..b655c86 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) + 6, 8) - <> + oxm_length = div(n_bits_of(oxm_field) + 4, 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, - _::7, + field_int::7, has_mask::1, length::8, body_bin::size(length)-bytes, rest::bytes >> ) do - value_len = length - 6 - <> = body_bin + value_len = length - 4 + <> = 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) @@ -545,7 +545,7 @@ defmodule Openflow.Match do ], do: 0x0001 - # Nicira Ext + # Nicira NSH Ext defp match_class(f) when f in [ :nsh_flags, @@ -559,6 +559,17 @@ 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 @@ -693,7 +704,10 @@ defmodule Openflow.Match do :nsh_si, :nsh_ttl, :pbb_uca, - :onf_pbb_uca + :onf_pbb_uca, + :tun_erspan_ver, + :tun_erspan_dir, + :tun_erspan_hwid ], do: :u8 @@ -752,6 +766,7 @@ defmodule Openflow.Match do :nx_ipv6_flabel, :pkt_mark, :dp_hash, + :nxoxm_dp_hash, :recirc_id, :conj_id, :ct_mark, @@ -760,7 +775,8 @@ defmodule Openflow.Match do :nsh_c2, :nsh_c3, :nsh_c4, - :packet_type + :packet_type, + :tun_erspan_idx ], do: :u32 @@ -864,7 +880,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/priv/openflow_enum_gen.exs b/priv/openflow_enum_gen.exs index a69900a..beb1c3b 100644 --- a/priv/openflow_enum_gen.exs +++ b/priv/openflow_enum_gen.exs @@ -304,7 +304,8 @@ enums = [ no_buffer: 0xFFFF ], experimenter_oxm_vendors: [ - nicira_ext_match: 0x00002320, + nxoxm_nsh_match: 0x005AD650, + nxoxm_match: 0x00002320, hp_ext_match: 0x00002428, onf_ext_match: 0x4F4E4600 ], @@ -571,7 +572,7 @@ enums = [ xreg6: 6, xreg7: 7 ], - nicira_ext_match: [ + nxoxm_nsh_match: [ nsh_flags: 1, nsh_mdtype: 2, nsh_np: 3, @@ -588,6 +589,13 @@ 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 ], diff --git a/test/lib/openflow/ofp_flow_mod_test.exs b/test/lib/openflow/ofp_flow_mod_test.exs index aca8f69..2d593e6 100644 --- a/test/lib/openflow/ofp_flow_mod_test.exs +++ b/test/lib/openflow/ofp_flow_mod_test.exs @@ -12,62 +12,6 @@ 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) @@ -114,72 +58,6 @@ 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 96fe3dc..845e702 100644 --- a/test/lib/openflow/ofp_flow_stats_test.exs +++ b/test/lib/openflow/ofp_flow_stats_test.exs @@ -20,122 +20,4 @@ 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 5199fc2..37381e1 100644 --- a/test/lib/openflow/ofp_packet_in_test.exs +++ b/test/lib/openflow/ofp_packet_in_test.exs @@ -27,63 +27,5 @@ 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 From 479e85439a7acc95df0a1b877f746953dc786326 Mon Sep 17 00:00:00 2001 From: Eishun Kondoh Date: Wed, 31 Jul 2019 20:38:31 +0900 Subject: [PATCH 11/12] Version bump --- mix.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix.exs b/mix.exs index 0ac30ca..0bfb166 100644 --- a/mix.exs +++ b/mix.exs @@ -8,7 +8,7 @@ defmodule Tres.Mixfile do def project do [ app: :tres, - version: "0.1.2", + version: "0.1.3", description: @description, elixir: "~> 1.8", package: package(), From 1e3e7f78ba1aa4f184d4be70300e5f4703d50a2f Mon Sep 17 00:00:00 2001 From: Eishun Kondoh Date: Tue, 24 Sep 2019 18:00:34 +0900 Subject: [PATCH 12/12] tres/controller: Refactored to split aliases into actions and instructions respectively (#18) --- lib/tres/actions.ex | 82 ++++++++++++++++++++++++++++++++++++++++ lib/tres/controller.ex | 2 + lib/tres/instructions.ex | 16 ++++++++ lib/tres/messages.ex | 80 --------------------------------------- 4 files changed, 100 insertions(+), 80 deletions(-) create mode 100644 lib/tres/actions.ex create mode 100644 lib/tres/instructions.ex diff --git a/lib/tres/actions.ex b/lib/tres/actions.ex new file mode 100644 index 0000000..8ed6b45 --- /dev/null +++ b/lib/tres/actions.ex @@ -0,0 +1,82 @@ +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 323355e..34be717 100644 --- a/lib/tres/controller.ex +++ b/lib/tres/controller.ex @@ -10,7 +10,9 @@ 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 new file mode 100644 index 0000000..36a3908 --- /dev/null +++ b/lib/tres/instructions.ex @@ -0,0 +1,16 @@ +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 2705465..4a6fea8 100644 --- a/lib/tres/messages.ex +++ b/lib/tres/messages.ex @@ -43,86 +43,6 @@ 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.NxCheckPktLarger - - alias Openflow.Action.NxFlowSpecMatch - alias Openflow.Action.NxFlowSpecLoad - alias Openflow.Action.NxFlowSpecOutput - alias Tres.SwitchRegistry end end