Refactored nicira extended actions
This commit is contained in:
parent
efd08cf6dd
commit
ffcba91395
51 changed files with 1015 additions and 819 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -16,6 +16,23 @@ defmodule Openflow.Action.Experimenter do
|
|||
<<0xFFFF::16, length::16, exp_id::32, data::bytes>>
|
||||
end
|
||||
|
||||
@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)
|
||||
|
||||
length =
|
||||
exp_body
|
||||
|> byte_size()
|
||||
|> Kernel.+(4)
|
||||
|> Kernel.+(pad_length)
|
||||
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(pad_length)-unit(8)>>
|
||||
end
|
||||
|
||||
def read(<<0xFFFF::16, _length::16, exp_id::32, exp_type::16, data::bytes>>) do
|
||||
case Openflow.Utils.get_enum(exp_id, :action_vendor) do
|
||||
vendor_id when is_integer(vendor_id) ->
|
||||
|
|
|
|||
|
|
@ -12,8 +12,9 @@ defmodule Openflow.Action.NxBundle do
|
|||
@nxast 12
|
||||
|
||||
alias __MODULE__
|
||||
alias Openflow.Action.Experimenter
|
||||
|
||||
def new(options) do
|
||||
def new(options \\ []) do
|
||||
slaves = options[:slaves] || []
|
||||
|
||||
%NxBundle{
|
||||
|
|
@ -25,28 +26,25 @@ defmodule Openflow.Action.NxBundle do
|
|||
}
|
||||
end
|
||||
|
||||
def to_binary(%NxBundle{
|
||||
algorithm: alg,
|
||||
hash_field: hash_field,
|
||||
basis: basis,
|
||||
slave_type: slave_type,
|
||||
n_slaves: n_slaves,
|
||||
slaves: slaves
|
||||
}) do
|
||||
hash_field_int = Openflow.Enums.to_int(hash_field, :nx_hash_fields)
|
||||
alg_int = Openflow.Enums.to_int(alg, :nx_bd_algorithm)
|
||||
slave_type_bin = Openflow.Match.codec_header(slave_type)
|
||||
slaves_bin = codec_slaves(slaves)
|
||||
def to_binary(%NxBundle{} = bundle) do
|
||||
bundle_hash_field_int = Openflow.Enums.to_int(bundle.hash_field, :nx_hash_fields)
|
||||
bundle_alg_int = Openflow.Enums.to_int(bundle.algorithm, :nx_bd_algorithm)
|
||||
bundle_slave_type_bin = Openflow.Match.codec_header(bundle.slave_type)
|
||||
bundle_slaves_bin = codec_slaves(bundle.slaves)
|
||||
|
||||
body =
|
||||
<<alg_int::16, hash_field_int::16, basis::16, slave_type_bin::4-bytes, n_slaves::16, 0::16,
|
||||
0::size(4)-unit(8), 0::32, slaves_bin::bytes>>
|
||||
|
||||
exp_body = <<@experimenter::32, @nxast::16, body::bytes>>
|
||||
exp_body_size = byte_size(exp_body)
|
||||
padding_length = Openflow.Utils.padding(4 + exp_body_size, 8)
|
||||
length = 4 + exp_body_size + padding_length
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
Experimenter.pack_exp_header(<<
|
||||
@experimenter::32,
|
||||
@nxast::16,
|
||||
bundle_alg_int::16,
|
||||
bundle_hash_field_int::16,
|
||||
bundle.basis::16,
|
||||
bundle_slave_type_bin::4-bytes,
|
||||
bundle.n_slaves::16,
|
||||
0::size(2)-unit(8),
|
||||
0::size(4)-unit(8),
|
||||
0::size(4)-unit(8),
|
||||
bundle_slaves_bin::bytes
|
||||
>>)
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, body::bytes>>) do
|
||||
|
|
|
|||
|
|
@ -17,9 +17,10 @@ defmodule Openflow.Action.NxBundleLoad do
|
|||
@nxast 13
|
||||
|
||||
alias __MODULE__
|
||||
alias Openflow.Action.Experimenter
|
||||
|
||||
def new(options) do
|
||||
dst_field = options[:dst_field]
|
||||
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)
|
||||
slaves = options[:slaves] || []
|
||||
|
||||
|
|
@ -35,33 +36,27 @@ defmodule Openflow.Action.NxBundleLoad do
|
|||
}
|
||||
end
|
||||
|
||||
def to_binary(%NxBundleLoad{
|
||||
algorithm: alg,
|
||||
hash_field: hash_field,
|
||||
basis: basis,
|
||||
slave_type: slave_type,
|
||||
n_slaves: n_slaves,
|
||||
slaves: slaves,
|
||||
offset: ofs,
|
||||
n_bits: n_bits,
|
||||
dst_field: dst_field
|
||||
}) do
|
||||
hash_field_int = Openflow.Enums.to_int(hash_field, :nx_hash_fields)
|
||||
alg_int = Openflow.Enums.to_int(alg, :nx_bd_algorithm)
|
||||
slave_type_bin = Openflow.Match.codec_header(slave_type)
|
||||
slaves_bin = codec_slaves(slaves)
|
||||
ofs_nbits = ofs <<< 6 ||| n_bits - 1
|
||||
dst_field_bin = Openflow.Match.codec_header(dst_field)
|
||||
def to_binary(%NxBundleLoad{} = bundle_load) do
|
||||
hash_field_int = Openflow.Enums.to_int(bundle_load.hash_field, :nx_hash_fields)
|
||||
alg_int = Openflow.Enums.to_int(bundle_load.algorithm, :nx_bd_algorithm)
|
||||
slave_type_bin = Openflow.Match.codec_header(bundle_load.slave_type)
|
||||
slaves_bin = codec_slaves(bundle_load.slaves)
|
||||
ofs_nbits = bundle_load.offset <<< 6 ||| bundle_load.n_bits - 1
|
||||
dst_field_bin = Openflow.Match.codec_header(bundle_load.dst_field)
|
||||
|
||||
body =
|
||||
<<alg_int::16, hash_field_int::16, basis::16, slave_type_bin::4-bytes, n_slaves::16,
|
||||
ofs_nbits::16, dst_field_bin::4-bytes, 0::32, slaves_bin::bytes>>
|
||||
|
||||
exp_body = <<@experimenter::32, @nxast::16, body::bytes>>
|
||||
exp_body_size = byte_size(exp_body)
|
||||
padding_length = Openflow.Utils.padding(4 + exp_body_size, 8)
|
||||
length = 4 + exp_body_size + padding_length
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
Experimenter.pack_exp_header(<<
|
||||
@experimenter::32,
|
||||
@nxast::16,
|
||||
alg_int::16,
|
||||
hash_field_int::16,
|
||||
bundle_load.basis::16,
|
||||
slave_type_bin::4-bytes,
|
||||
bundle_load.n_slaves::16,
|
||||
ofs_nbits::16,
|
||||
dst_field_bin::4-bytes,
|
||||
0::32,
|
||||
slaves_bin::bytes
|
||||
>>)
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, body::bytes>>) do
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ defmodule Openflow.Action.NxClone do
|
|||
@nxast 42
|
||||
|
||||
alias __MODULE__
|
||||
alias Openflow.Action.Experimenter
|
||||
|
||||
def new(actions \\ []) do
|
||||
%NxClone{actions: actions}
|
||||
|
|
@ -12,11 +13,10 @@ defmodule Openflow.Action.NxClone do
|
|||
|
||||
def to_binary(%NxClone{actions: actions}) do
|
||||
actions_bin = Openflow.Action.to_binary(actions)
|
||||
exp_body = <<@experimenter::32, @nxast::16, 0::size(6)-unit(8), actions_bin::bytes>>
|
||||
exp_body_size = byte_size(exp_body)
|
||||
padding_length = Openflow.Utils.padding(4 + exp_body_size, 8)
|
||||
length = 4 + exp_body_size + padding_length
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
|
||||
Experimenter.pack_exp_header(
|
||||
<<@experimenter::32, @nxast::16, 0::size(6)-unit(8), actions_bin::bytes>>
|
||||
)
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, 0::size(6)-unit(8), actions_bin::bytes>>) do
|
||||
|
|
|
|||
|
|
@ -9,18 +9,27 @@ defmodule Openflow.Action.NxConjunction do
|
|||
@nxast 34
|
||||
|
||||
alias __MODULE__
|
||||
alias Openflow.Action.Experimenter
|
||||
|
||||
def new(options \\ []) do
|
||||
n_clauses = options[:n_clauses] || raise "n_clauses must be specified"
|
||||
n_clauses >= 2 || raise "n_clauses must be greater than 1"
|
||||
|
||||
def new(options) do
|
||||
%NxConjunction{
|
||||
clause: options[:clause] || 0,
|
||||
n_clauses: options[:n_clauses] || 0,
|
||||
clause: (options[:clause] || 0) + 1,
|
||||
n_clauses: n_clauses,
|
||||
id: options[:id] || 0
|
||||
}
|
||||
end
|
||||
|
||||
def to_binary(%NxConjunction{clause: clause, n_clauses: n_clauses, id: id}) do
|
||||
exp_body = <<@experimenter::32, @nxast::16, clause::8, n_clauses::8, id::32>>
|
||||
<<0xFFFF::16, 16::16, exp_body::bytes>>
|
||||
Experimenter.pack_exp_header(<<
|
||||
@experimenter::32,
|
||||
@nxast::16,
|
||||
clause::8,
|
||||
n_clauses::8,
|
||||
id::32
|
||||
>>)
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, clause::8, n_clauses::8, id::32>>) do
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ defmodule Openflow.Action.NxConntrack do
|
|||
@nxast 35
|
||||
|
||||
alias __MODULE__
|
||||
alias Openflow.Action.Experimenter
|
||||
|
||||
def new(options \\ []) do
|
||||
%NxConntrack{
|
||||
|
|
@ -30,36 +31,21 @@ defmodule Openflow.Action.NxConntrack do
|
|||
}
|
||||
end
|
||||
|
||||
def to_binary(%NxConntrack{
|
||||
flags: flags,
|
||||
zone_src: zone_src,
|
||||
zone_offset: zone_ofs,
|
||||
zone_n_bits: zone_n_bits,
|
||||
zone_imm: zone_imm,
|
||||
recirc_table: recirc_table,
|
||||
alg: alg,
|
||||
exec: exec
|
||||
}) do
|
||||
flags_int = Openflow.Enums.flags_to_int(flags, :nx_conntrack_flags)
|
||||
def to_binary(%NxConntrack{} = ct) do
|
||||
flags_int = Openflow.Enums.flags_to_int(ct.flags, :nx_conntrack_flags)
|
||||
ct_context_bin = ct_context_binary(ct)
|
||||
exec_bin = Openflow.Action.to_binary(ct.exec)
|
||||
|
||||
{src_bin, ofs_nbits} =
|
||||
if not is_nil(zone_src) do
|
||||
zone_src_bin = Openflow.Match.codec_header(zone_src)
|
||||
{zone_src_bin, zone_ofs <<< 6 ||| zone_n_bits - 1}
|
||||
else
|
||||
{<<0::32>>, zone_imm}
|
||||
end
|
||||
|
||||
exec_bin = Openflow.Action.to_binary(exec)
|
||||
|
||||
exp_body =
|
||||
<<@experimenter::32, @nxast::16, flags_int::16, src_bin::bytes, ofs_nbits::16,
|
||||
recirc_table::8, 0::size(3)-unit(8), alg::16, exec_bin::bytes>>
|
||||
|
||||
exp_body_size = byte_size(exp_body)
|
||||
padding_length = Openflow.Utils.padding(4 + exp_body_size, 8)
|
||||
length = 4 + exp_body_size + padding_length
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
Experimenter.pack_exp_header(<<
|
||||
@experimenter::32,
|
||||
@nxast::16,
|
||||
flags_int::16,
|
||||
ct_context_bin::bytes,
|
||||
ct.recirc_table::8,
|
||||
0::size(3)-unit(8),
|
||||
ct.alg::16,
|
||||
exec_bin::bytes
|
||||
>>)
|
||||
end
|
||||
|
||||
def read(
|
||||
|
|
@ -87,4 +73,15 @@ defmodule Openflow.Action.NxConntrack do
|
|||
%{ct | zone_src: zone_src, zone_offset: ofs, zone_n_bits: n_bits + 1}
|
||||
end
|
||||
end
|
||||
|
||||
# private functions
|
||||
|
||||
defp ct_context_binary(%NxConntrack{zone_src: nil} = ct),
|
||||
do: <<0::32, ct.zone_imm::16>>
|
||||
|
||||
defp ct_context_binary(%NxConntrack{} = ct) do
|
||||
zone_src_bin = Openflow.Match.codec_header(ct.zone_src)
|
||||
ofs_nbits = ct.zone_offset <<< 6 ||| ct.zone_n_bits - 1
|
||||
<<zone_src_bin::bytes, ofs_nbits::16>>
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -9,8 +9,9 @@ defmodule Openflow.Action.NxController do
|
|||
@nxast 20
|
||||
|
||||
alias __MODULE__
|
||||
alias Openflow.Action.Experimenter
|
||||
|
||||
def new(options) do
|
||||
def new(options \\ []) do
|
||||
%NxController{
|
||||
max_len: options[:max_len] || :no_buffer,
|
||||
id: options[:id] || 0,
|
||||
|
|
@ -18,14 +19,18 @@ defmodule Openflow.Action.NxController do
|
|||
}
|
||||
end
|
||||
|
||||
def to_binary(%NxController{max_len: max_len, id: controller_id, reason: reason}) do
|
||||
max_len_int = Openflow.Utils.get_enum(max_len, :controller_max_len)
|
||||
reason_int = Openflow.Enums.to_int(reason, :packet_in_reason)
|
||||
def to_binary(%NxController{} = controller) do
|
||||
max_len_int = Openflow.Utils.get_enum(controller.max_len, :controller_max_len)
|
||||
reason_int = Openflow.Enums.to_int(controller.reason, :packet_in_reason)
|
||||
|
||||
exp_body =
|
||||
<<@experimenter::32, @nxast::16, max_len_int::16, controller_id::16, reason_int::8, 0::8>>
|
||||
|
||||
<<0xFFFF::16, 16::16, exp_body::bytes>>
|
||||
Experimenter.pack_exp_header(<<
|
||||
@experimenter::32,
|
||||
@nxast::16,
|
||||
max_len_int::16,
|
||||
controller.id::16,
|
||||
reason_int::8,
|
||||
0::8
|
||||
>>)
|
||||
end
|
||||
|
||||
def read(
|
||||
|
|
|
|||
|
|
@ -23,8 +23,9 @@ defmodule Openflow.Action.NxController2 do
|
|||
@nx_ctlr_no_meter 0
|
||||
|
||||
alias __MODULE__
|
||||
alias Openflow.Action.Experimenter
|
||||
|
||||
def new(options) do
|
||||
def new(options \\ []) do
|
||||
%NxController2{
|
||||
max_len: options[:max_len] || :no_buffer,
|
||||
id: options[:id] || 0,
|
||||
|
|
@ -36,14 +37,14 @@ defmodule Openflow.Action.NxController2 do
|
|||
end
|
||||
|
||||
def to_binary(%NxController2{} = ctl) do
|
||||
ext_header = <<@experimenter::32, @nxast::16, 0::size(6)-unit(8)>>
|
||||
prop_keys = get_prop_key(ctl)
|
||||
props_bin = encode_prop("", prop_keys, ctl)
|
||||
exp_body = <<ext_header::bytes, props_bin::bytes>>
|
||||
exp_body_size = byte_size(exp_body)
|
||||
padding_length = Openflow.Utils.padding(4 + exp_body_size, 8)
|
||||
length = 4 + exp_body_size + padding_length
|
||||
<<0xFFFF::16, length::16, exp_body::bytes>>
|
||||
props_bin = encode_props(ctl)
|
||||
|
||||
Experimenter.pack_exp_header(<<
|
||||
@experimenter::32,
|
||||
@nxast::16,
|
||||
0::size(6)-unit(8),
|
||||
props_bin::bytes
|
||||
>>)
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, 0::size(6)-unit(8), body::bytes>>) do
|
||||
|
|
@ -53,101 +54,144 @@ defmodule Openflow.Action.NxController2 do
|
|||
|
||||
# private functions
|
||||
|
||||
defp get_prop_key(ctl) do
|
||||
defp encode_props(ctl) do
|
||||
ctl
|
||||
|> Map.from_struct()
|
||||
|> Enum.map(fn {k, v} -> if(not is_nil(v), do: k, else: nil) end)
|
||||
|> Enum.filter(fn v -> not is_nil(v) end)
|
||||
|> Enum.reduce(<<>>, &encode_prop/2)
|
||||
end
|
||||
|
||||
defp encode_prop(acc, [], _ctl), do: acc
|
||||
|
||||
defp encode_prop(acc, [prop | rest], ctl) do
|
||||
value = Map.get(ctl, prop)
|
||||
|
||||
prop_bin =
|
||||
cond do
|
||||
prop == :max_len and (value != :no_buffer or value < 0xFFFF) ->
|
||||
padding_length = 2
|
||||
prop_length = @prop_header_size + 2 + padding_length
|
||||
defp encode_prop({:max_len, value}, acc)
|
||||
when value != :no_buffer or value < 0xFFFF do
|
||||
pad_length = 2
|
||||
prop_length = @prop_header_size + 2 + pad_length
|
||||
max_len_int = Openflow.Utils.get_enum(value, :controller_max_len)
|
||||
<<@prop_max_len::16, prop_length::16, max_len_int::16, 0::size(padding_length)-unit(8)>>
|
||||
|
||||
prop == :id ->
|
||||
padding_length = 2
|
||||
prop_length = @prop_header_size + 2 + padding_length
|
||||
<<@prop_ctl_id::16, prop_length::16, value::16, 0::size(padding_length)-unit(8)>>
|
||||
<<
|
||||
acc::bytes,
|
||||
@prop_max_len::16,
|
||||
prop_length::16,
|
||||
max_len_int::16,
|
||||
0::size(pad_length)-unit(8)
|
||||
>>
|
||||
end
|
||||
|
||||
prop == :reason and value != :action ->
|
||||
defp encode_prop({:id, value}, acc) do
|
||||
pad_length = 2
|
||||
prop_length = @prop_header_size + 2 + pad_length
|
||||
|
||||
<<
|
||||
acc::bytes,
|
||||
@prop_ctl_id::16,
|
||||
prop_length::16,
|
||||
value::16,
|
||||
0::size(pad_length)-unit(8)
|
||||
>>
|
||||
end
|
||||
|
||||
defp encode_prop({:reason, reason}, acc)
|
||||
when reason != :action do
|
||||
padding_length = 3
|
||||
prop_length = @prop_header_size + 1 + padding_length
|
||||
reason_int = Openflow.Utils.get_enum(value, :packet_in_reason)
|
||||
<<@prop_reason::16, prop_length::16, reason_int::8, 0::size(padding_length)-unit(8)>>
|
||||
reason_int = Openflow.Utils.get_enum(reason, :packet_in_reason)
|
||||
|
||||
prop == :userdata and byte_size(value) > 0 ->
|
||||
prop_length = @prop_header_size + byte_size(value)
|
||||
padding_length = Openflow.Utils.padding(prop_length, 8)
|
||||
<<@prop_userdata::16, prop_length::16, value::bytes, 0::size(padding_length)-unit(8)>>
|
||||
|
||||
prop == :pause and value == true ->
|
||||
padding_length = 4
|
||||
prop_length = @prop_header_size + padding_length
|
||||
<<@prop_pause::16, prop_length::16, 0::size(padding_length)-unit(8)>>
|
||||
|
||||
prop == :meter_id and value != @nx_ctlr_no_meter ->
|
||||
prop_length = @prop_header_size + 4
|
||||
<<@prop_meter_id::16, prop_length::16, value::32>>
|
||||
|
||||
true ->
|
||||
""
|
||||
<<
|
||||
acc::bytes,
|
||||
@prop_reason::16,
|
||||
prop_length::16,
|
||||
reason_int::8,
|
||||
0::size(padding_length)-unit(8)
|
||||
>>
|
||||
end
|
||||
|
||||
encode_prop(<<acc::bytes, prop_bin::bytes>>, rest, ctl)
|
||||
defp encode_prop({:userdata, value}, acc)
|
||||
when byte_size(value) > 0 do
|
||||
prop_length = @prop_header_size + byte_size(value)
|
||||
padding_length = Openflow.Utils.padding(prop_length, 8)
|
||||
|
||||
<<
|
||||
acc::bytes,
|
||||
@prop_userdata::16,
|
||||
prop_length::16,
|
||||
value::bytes,
|
||||
0::size(padding_length)-unit(8)
|
||||
>>
|
||||
end
|
||||
|
||||
defp encode_prop({:pause, true}, acc) do
|
||||
padding_length = 4
|
||||
prop_length = @prop_header_size + padding_length
|
||||
|
||||
<<
|
||||
acc::bytes,
|
||||
@prop_pause::16,
|
||||
prop_length::16,
|
||||
0::size(padding_length)-unit(8)
|
||||
>>
|
||||
end
|
||||
|
||||
defp encode_prop({:meter_id, value}, acc)
|
||||
when value != @nx_ctlr_no_meter do
|
||||
prop_length = @prop_header_size + 4
|
||||
|
||||
<<
|
||||
acc::bytes,
|
||||
@prop_meter_id::16,
|
||||
prop_length::16,
|
||||
value::32
|
||||
>>
|
||||
end
|
||||
|
||||
defp encode_prop(_, acc) do
|
||||
acc
|
||||
end
|
||||
|
||||
defp decode_prop(ctl, ""), do: ctl
|
||||
|
||||
defp decode_prop(ctl, <<prop_type_int::16, _::bytes>> = bin) do
|
||||
prop_type = Openflow.Enums.to_atom(prop_type_int, :nx_action_controller2_prop_type)
|
||||
|
||||
case prop_type do
|
||||
:max_len ->
|
||||
<<@prop_max_len::16, _prop_length::16, max_len_int::16, _::size(2)-unit(8), rest::bytes>> =
|
||||
bin
|
||||
|
||||
defp decode_prop(
|
||||
ctl,
|
||||
<<
|
||||
@prop_max_len::16,
|
||||
_prop_length::16,
|
||||
max_len_int::16,
|
||||
_::size(2)-unit(8),
|
||||
rest::bytes
|
||||
>>
|
||||
) do
|
||||
max_len = Openflow.Utils.get_enum(max_len_int, :controller_max_len)
|
||||
decode_prop(struct(ctl, %{max_len: max_len}), rest)
|
||||
|
||||
:controller_id ->
|
||||
<<@prop_ctl_id::16, _prop_length::16, controller_id::16, _::size(2)-unit(8), rest::bytes>> =
|
||||
bin
|
||||
|
||||
decode_prop(struct(ctl, %{controller_id: controller_id}), rest)
|
||||
|
||||
:reason ->
|
||||
<<@prop_reason::16, _prop_length::16, reason_int::8, _::size(3)-unit(8), rest::bytes>> =
|
||||
bin
|
||||
decode_prop(%{ctl | max_len: max_len}, rest)
|
||||
end
|
||||
|
||||
defp decode_prop(
|
||||
ctl,
|
||||
<<@prop_reason::16, _prop_length::16, reason_int::8, _::size(3)-unit(8), rest::bytes>>
|
||||
) do
|
||||
reason = Openflow.Utils.get_enum(reason_int, :packet_in_reason)
|
||||
decode_prop(struct(ctl, %{reason: reason}), rest)
|
||||
decode_prop(%{ctl | reason: reason}, rest)
|
||||
end
|
||||
|
||||
:userdata ->
|
||||
<<@prop_userdata::16, prop_length::16, remains::bytes>> = bin
|
||||
defp decode_prop(
|
||||
ctl,
|
||||
<<@prop_ctl_id::16, _prop_length::16, controller_id::16, _::size(2)-unit(8),
|
||||
rest::bytes>>
|
||||
) do
|
||||
decode_prop(%{ctl | id: controller_id}, rest)
|
||||
end
|
||||
|
||||
defp decode_prop(
|
||||
ctl,
|
||||
<<@prop_userdata::16, prop_length::16, remains::bytes>>
|
||||
) do
|
||||
userdata_len = prop_length - 4
|
||||
padding_length = Openflow.Utils.padding(prop_length, 8)
|
||||
<<userdata::size(userdata_len)-bytes, _::size(padding_length)-unit(8), rest::bytes>> = remains
|
||||
decode_prop(%{ctl | userdata: userdata}, rest)
|
||||
end
|
||||
|
||||
<<userdata::size(userdata_len)-bytes, _::size(padding_length)-unit(8), rest::bytes>> =
|
||||
remains
|
||||
defp decode_prop(ctl, <<@prop_pause::16, _::16, 0::size(4)-unit(8), rest::bytes>>) do
|
||||
decode_prop(%{ctl | pause: true}, rest)
|
||||
end
|
||||
|
||||
decode_prop(struct(ctl, %{userdata: userdata}), rest)
|
||||
|
||||
:pause ->
|
||||
<<@prop_pause::16, _::16, 0::size(4)-unit(8), rest::bytes>> = bin
|
||||
decode_prop(struct(ctl, %{pause: true}), rest)
|
||||
|
||||
:meter_id ->
|
||||
<<@prop_meter_id::16, _::16, meter_id::32, rest::bytes>> = bin
|
||||
decode_prop(struct(ctl, %{meter_id: meter_id}), rest)
|
||||
end
|
||||
defp decode_prop(ctl, <<@prop_meter_id::16, _::16, meter_id::32, rest::bytes>>) do
|
||||
decode_prop(%{ctl | meter_id: meter_id}, rest)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -5,14 +5,19 @@ defmodule Openflow.Action.NxCtClear do
|
|||
@nxast 43
|
||||
|
||||
alias __MODULE__
|
||||
alias Openflow.Action.Experimenter
|
||||
|
||||
def new do
|
||||
%NxCtClear{}
|
||||
end
|
||||
|
||||
def to_binary(%NxCtClear{}) do
|
||||
exp_body = <<@experimenter::32, @nxast::16, 0::16, 0::size(4)-unit(8)>>
|
||||
<<0xFFFF::16, 16::16, exp_body::bytes>>
|
||||
Experimenter.pack_exp_header(<<
|
||||
@experimenter::32,
|
||||
@nxast::16,
|
||||
0::16,
|
||||
0::size(4)-unit(8)
|
||||
>>)
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, _::16, _::size(4)-unit(8)>>) do
|
||||
|
|
|
|||
|
|
@ -1,21 +0,0 @@
|
|||
defmodule Openflow.Action.NxDecMplsTtl do
|
||||
defstruct([])
|
||||
|
||||
@experimenter 0x00002320
|
||||
@nxast 26
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
def new do
|
||||
%NxDecMplsTtl{}
|
||||
end
|
||||
|
||||
def to_binary(%NxDecMplsTtl{}) do
|
||||
exp_body = <<@experimenter::32, @nxast::16, 0::size(6)-unit(8)>>
|
||||
<<0xFFFF::16, 16::16, exp_body::bytes>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, _::size(6)-unit(8)>>) do
|
||||
%NxDecMplsTtl{}
|
||||
end
|
||||
end
|
||||
|
|
@ -5,14 +5,18 @@ defmodule Openflow.Action.NxDecTtl do
|
|||
@nxast 18
|
||||
|
||||
alias __MODULE__
|
||||
alias Openflow.Action.Experimenter
|
||||
|
||||
def new do
|
||||
%NxDecTtl{}
|
||||
end
|
||||
|
||||
def to_binary(%NxDecTtl{}) do
|
||||
exp_body = <<@experimenter::32, @nxast::16, 0::size(6)-unit(8)>>
|
||||
<<0xFFFF::16, 16::16, exp_body::bytes>>
|
||||
Experimenter.pack_exp_header(<<
|
||||
@experimenter::32,
|
||||
@nxast::16,
|
||||
0::size(6)-unit(8)
|
||||
>>)
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, _::16, _::size(4)-unit(8)>>) do
|
||||
|
|
|
|||
|
|
@ -5,24 +5,23 @@ defmodule Openflow.Action.NxDecTtlCntIds do
|
|||
@nxast 21
|
||||
|
||||
alias __MODULE__
|
||||
alias Openflow.Action.Experimenter
|
||||
|
||||
def new(ids) do
|
||||
def new(ids \\ []) do
|
||||
%NxDecTtlCntIds{ids: ids}
|
||||
end
|
||||
|
||||
def to_binary(%NxDecTtlCntIds{ids: ids}) do
|
||||
n_controllers = length(ids)
|
||||
ids_bin = Enum.join(for(id <- ids, do: <<id::16>>), "")
|
||||
padding = Openflow.Utils.padding(n_controllers, 8)
|
||||
ids_bin = Enum.reduce(ids, <<>>, fn id, acc -> <<acc::bytes, id::16>> end)
|
||||
|
||||
exp_body =
|
||||
<<@experimenter::32, @nxast::16, n_controllers::16, 0::size(4)-unit(8), ids_bin::bytes,
|
||||
0::size(padding)-unit(8)>>
|
||||
|
||||
exp_body_size = byte_size(exp_body)
|
||||
padding_length = Openflow.Utils.padding(4 + exp_body_size, 8)
|
||||
length = 4 + exp_body_size + padding_length
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
Experimenter.pack_exp_header(<<
|
||||
@experimenter::32,
|
||||
@nxast::16,
|
||||
n_controllers::16,
|
||||
0::size(4)-unit(8),
|
||||
ids_bin::bytes
|
||||
>>)
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, n_controllers::16, body::bitstring>>) do
|
||||
|
|
|
|||
|
|
@ -5,17 +5,17 @@ defmodule Openflow.Action.NxExit do
|
|||
@nxast 17
|
||||
|
||||
alias __MODULE__
|
||||
alias Openflow.Action.Experimenter
|
||||
|
||||
def new do
|
||||
%NxExit{}
|
||||
end
|
||||
|
||||
def to_binary(%NxExit{}) do
|
||||
exp_body = <<@experimenter::32, @nxast::16, 0::48>>
|
||||
<<0xFFFF::16, 16::16, exp_body::bytes>>
|
||||
Experimenter.pack_exp_header(<<@experimenter::32, @nxast::16, 0::48>>)
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, 0::48>>) do
|
||||
def read(<<@experimenter::32, @nxast::16, 0::48, _::bytes>>) do
|
||||
%NxExit{}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -8,17 +8,22 @@ defmodule Openflow.Action.NxFinTimeout do
|
|||
@nxast 19
|
||||
|
||||
alias __MODULE__
|
||||
alias Openflow.Action.Experimenter
|
||||
|
||||
def new(options) do
|
||||
def new(options \\ []) do
|
||||
%NxFinTimeout{
|
||||
idle_timeout: options[:idle_timeout] || 0,
|
||||
hard_timeout: options[:hard_timeout] || 0
|
||||
}
|
||||
end
|
||||
|
||||
def to_binary(%NxFinTimeout{idle_timeout: fin_idle, hard_timeout: fin_hard}) do
|
||||
exp_body = <<@experimenter::32, @nxast::16, fin_idle::16, fin_hard::16>>
|
||||
<<0xFFFF::16, 16::16, exp_body::bytes, 0::size(2)-unit(8)>>
|
||||
def to_binary(%NxFinTimeout{} = fin_timeout) do
|
||||
Experimenter.pack_exp_header(<<
|
||||
@experimenter::32,
|
||||
@nxast::16,
|
||||
fin_timeout.idle_timeout::16,
|
||||
fin_timeout.hard_timeout::16
|
||||
>>)
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, fin_idle::16, fin_hard::16, _::size(2)-unit(8)>>) do
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ defmodule Openflow.Action.NxLearn do
|
|||
@nxast 16
|
||||
|
||||
alias __MODULE__
|
||||
alias Openflow.Action.Experimenter
|
||||
|
||||
def new(options) do
|
||||
%NxLearn{
|
||||
|
|
@ -30,28 +31,24 @@ defmodule Openflow.Action.NxLearn do
|
|||
}
|
||||
end
|
||||
|
||||
def to_binary(%NxLearn{
|
||||
idle_timeout: idle,
|
||||
hard_timeout: hard,
|
||||
priority: prio,
|
||||
cookie: cookie,
|
||||
flags: flags,
|
||||
table_id: table_id,
|
||||
fin_idle_timeout: fin_idle,
|
||||
fin_hard_timeout: fin_hard,
|
||||
flow_specs: flow_specs
|
||||
}) do
|
||||
flags_int = Openflow.Enums.flags_to_int(flags, :nx_learn_flag)
|
||||
flow_specs_bin = Openflow.Action.NxFlowSpec.to_binary(flow_specs)
|
||||
def to_binary(%NxLearn{} = learn) do
|
||||
learn_flags_int = Openflow.Enums.flags_to_int(learn.flags, :nx_learn_flag)
|
||||
flow_specs_bin = Openflow.Action.NxFlowSpec.to_binary(learn.flow_specs)
|
||||
|
||||
exp_body =
|
||||
<<@experimenter::32, @nxast::16, idle::16, hard::16, prio::16, cookie::64, flags_int::16,
|
||||
table_id::8, 0::size(1)-unit(8), fin_idle::16, fin_hard::16, flow_specs_bin::bitstring>>
|
||||
|
||||
exp_body_size = byte_size(exp_body)
|
||||
padding_length = Openflow.Utils.padding(4 + exp_body_size, 8)
|
||||
length = 4 + exp_body_size + padding_length
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
Experimenter.pack_exp_header(<<
|
||||
@experimenter::32,
|
||||
@nxast::16,
|
||||
learn.idle_timeout::16,
|
||||
learn.hard_timeout::16,
|
||||
learn.priority::16,
|
||||
learn.cookie::64,
|
||||
learn_flags_int::16,
|
||||
learn.table_id::8,
|
||||
0::8,
|
||||
learn.fin_idle_timeout::16,
|
||||
learn.fin_hard_timeout::16,
|
||||
flow_specs_bin::bitstring
|
||||
>>)
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, body::bitstring>>) do
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ defmodule Openflow.Action.NxLearn2 do
|
|||
@nxast 45
|
||||
|
||||
alias __MODULE__
|
||||
alias Openflow.Action.Experimenter
|
||||
|
||||
def new(options) do
|
||||
%NxLearn2{
|
||||
|
|
@ -36,40 +37,33 @@ defmodule Openflow.Action.NxLearn2 do
|
|||
}
|
||||
end
|
||||
|
||||
def to_binary(%NxLearn2{
|
||||
idle_timeout: idle,
|
||||
hard_timeout: hard,
|
||||
priority: prio,
|
||||
cookie: cookie,
|
||||
flags: flags,
|
||||
table_id: table_id,
|
||||
fin_idle_timeout: fin_idle,
|
||||
fin_hard_timeout: fin_hard,
|
||||
limit: limit,
|
||||
result_dst_offset: result_dst_ofs,
|
||||
result_dst: result_dst,
|
||||
flow_specs: flow_specs
|
||||
}) do
|
||||
flags_int = Openflow.Enums.flags_to_int(flags, :nx_learn_flag)
|
||||
def to_binary(%NxLearn2{} = learn) do
|
||||
learn_flags_int = Openflow.Enums.flags_to_int(learn.flags, :nx_learn_flag)
|
||||
learn_flow_specs_bin = Openflow.Action.NxFlowSpec.to_binary(learn.flow_specs)
|
||||
|
||||
result_dst_bin =
|
||||
if :write_result in flags do
|
||||
Openflow.Match.codec_header(result_dst)
|
||||
else
|
||||
""
|
||||
end
|
||||
learn_result_dst_bin =
|
||||
if :write_result in learn.flags,
|
||||
do: Openflow.Match.codec_header(learn.result_dst),
|
||||
else: <<>>
|
||||
|
||||
flow_specs_bin = Openflow.Action.NxFlowSpec.to_binary(flow_specs)
|
||||
|
||||
exp_body =
|
||||
<<@experimenter::32, @nxast::16, idle::16, hard::16, prio::16, cookie::64, flags_int::16,
|
||||
table_id::8, 0::size(1)-unit(8), fin_idle::16, fin_hard::16, limit::32,
|
||||
result_dst_ofs::16, 0::size(2)-unit(8), result_dst_bin::bytes, flow_specs_bin::bitstring>>
|
||||
|
||||
exp_body_size = byte_size(exp_body)
|
||||
padding_length = Openflow.Utils.padding(4 + exp_body_size, 8)
|
||||
length = 4 + exp_body_size + padding_length
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
Experimenter.pack_exp_header(<<
|
||||
@experimenter::32,
|
||||
@nxast::16,
|
||||
learn.idle_timeout::16,
|
||||
learn.hard_timeout::16,
|
||||
learn.priority::16,
|
||||
learn.cookie::64,
|
||||
learn_flags_int::16,
|
||||
learn.table_id::8,
|
||||
0::size(1)-unit(8),
|
||||
learn.fin_idle_timeout::16,
|
||||
learn.fin_hard_timeout::16,
|
||||
learn.limit::32,
|
||||
learn.result_dst_offset::16,
|
||||
0::size(2)-unit(8),
|
||||
learn_result_dst_bin::bytes,
|
||||
learn_flow_specs_bin::bitstring
|
||||
>>)
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, body::bytes>>) do
|
||||
|
|
|
|||
|
|
@ -16,54 +16,43 @@ defmodule Openflow.Action.NxMultipath do
|
|||
@nxast 10
|
||||
|
||||
alias __MODULE__
|
||||
alias Openflow.Action.Experimenter
|
||||
|
||||
def new(options) do
|
||||
hash_field = Keyword.get(options, :hash_field, :eth_src)
|
||||
basis = Keyword.get(options, :basis, 0)
|
||||
alg = Keyword.get(options, :algorithm, :modulo_n)
|
||||
max_link = Keyword.get(options, :max_link, 0)
|
||||
arg = Keyword.get(options, :argument, 0)
|
||||
dst_field = Keyword.get(options, :dst_field)
|
||||
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)
|
||||
n_bits = Keyword.get(options, :n_bits, default_n_bits)
|
||||
ofs = Keyword.get(options, :offset, 0)
|
||||
|
||||
%NxMultipath{
|
||||
hash_field: hash_field,
|
||||
basis: basis,
|
||||
algorithm: alg,
|
||||
max_link: max_link,
|
||||
offset: ofs,
|
||||
n_bits: n_bits,
|
||||
argument: arg,
|
||||
hash_field: options[:hash_field] || :eth_src,
|
||||
basis: options[:basis] || 0,
|
||||
algorithm: options[:algorithm] || :modulo_n,
|
||||
max_link: options[:max_link] || 0,
|
||||
offset: options[:offset] || 0,
|
||||
n_bits: options[:n_bits] || default_n_bits,
|
||||
argument: options[:argument] || 0,
|
||||
dst_field: dst_field
|
||||
}
|
||||
end
|
||||
|
||||
def to_binary(%NxMultipath{
|
||||
hash_field: hash_field,
|
||||
basis: basis,
|
||||
algorithm: alg,
|
||||
max_link: max_link,
|
||||
argument: arg,
|
||||
offset: ofs,
|
||||
n_bits: n_bits,
|
||||
dst_field: dst_field
|
||||
}) do
|
||||
hash_field_int = Openflow.Enums.to_int(hash_field, :nx_hash_fields)
|
||||
alg_int = Openflow.Enums.to_int(alg, :nx_mp_algorithm)
|
||||
dst_field_bin = Openflow.Match.codec_header(dst_field)
|
||||
ofs_nbits = ofs <<< 6 ||| n_bits - 1
|
||||
def to_binary(%NxMultipath{} = multipath) do
|
||||
hash_field_int = Openflow.Enums.to_int(multipath.hash_field, :nx_hash_fields)
|
||||
alg_int = Openflow.Enums.to_int(multipath.algorithm, :nx_mp_algorithm)
|
||||
dst_field_bin = Openflow.Match.codec_header(multipath.dst_field)
|
||||
ofs_nbits = multipath.offset <<< 6 ||| multipath.n_bits - 1
|
||||
|
||||
body =
|
||||
<<hash_field_int::16, basis::16, 0::size(2)-unit(8), alg_int::16, max_link::16, arg::32,
|
||||
0::size(2)-unit(8), ofs_nbits::16, dst_field_bin::4-bytes>>
|
||||
|
||||
exp_body = <<@experimenter::32, @nxast::16, body::bytes>>
|
||||
exp_body_size = byte_size(exp_body)
|
||||
padding_length = Openflow.Utils.padding(4 + exp_body_size, 8)
|
||||
length = 4 + exp_body_size + padding_length
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
Experimenter.pack_exp_header(<<
|
||||
@experimenter::32,
|
||||
@nxast::16,
|
||||
hash_field_int::16,
|
||||
multipath.basis::16,
|
||||
0::size(2)-unit(8),
|
||||
alg_int::16,
|
||||
multipath.max_link::16,
|
||||
multipath.argument::32,
|
||||
0::size(2)-unit(8),
|
||||
ofs_nbits::16,
|
||||
dst_field_bin::4-bytes
|
||||
>>)
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, body::bytes>>) do
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ defmodule Openflow.Action.NxNat do
|
|||
@nxast 36
|
||||
|
||||
alias __MODULE__
|
||||
alias Openflow.Action.Experimenter
|
||||
|
||||
def new(options \\ []) do
|
||||
flags = Keyword.get(options, :flags, [])
|
||||
|
|
@ -46,14 +47,14 @@ defmodule Openflow.Action.NxNat do
|
|||
ranges_bin = encode_ranges("", range_flags, nat)
|
||||
range_flags_int = Openflow.Enums.flags_to_int(range_flags, :nx_nat_range)
|
||||
|
||||
exp_body =
|
||||
<<@experimenter::32, @nxast::16, 0::size(2)-unit(8), flags_int::16, range_flags_int::16,
|
||||
ranges_bin::bytes>>
|
||||
|
||||
exp_body_size = byte_size(exp_body)
|
||||
padding_length = Openflow.Utils.padding(4 + exp_body_size, 8)
|
||||
length = 4 + exp_body_size + padding_length
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
Experimenter.pack_exp_header(<<
|
||||
@experimenter::32,
|
||||
@nxast::16,
|
||||
0::size(2)-unit(8),
|
||||
flags_int::16,
|
||||
range_flags_int::16,
|
||||
ranges_bin::bytes
|
||||
>>)
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, body::bytes>>) do
|
||||
|
|
|
|||
|
|
@ -5,18 +5,14 @@ defmodule Openflow.Action.NxNote do
|
|||
@nxast 8
|
||||
|
||||
alias __MODULE__
|
||||
alias Openflow.Action.Experimenter
|
||||
|
||||
def new(note) do
|
||||
%NxNote{note: note}
|
||||
end
|
||||
|
||||
def to_binary(%NxNote{note: note}) do
|
||||
padding = Openflow.Utils.padding(byte_size(note) + 2, 8)
|
||||
exp_body = <<@experimenter::32, @nxast::16, note::bytes, 0::size(padding)-unit(8)>>
|
||||
exp_body_size = byte_size(exp_body)
|
||||
padding_length = Openflow.Utils.padding(4 + exp_body_size, 8)
|
||||
length = 4 + exp_body_size + padding_length
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
Experimenter.pack_exp_header(<<@experimenter::32, @nxast::16, note::bytes>>)
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, note_bin::bytes>>) do
|
||||
|
|
|
|||
|
|
@ -12,26 +12,33 @@ defmodule Openflow.Action.NxOutputReg do
|
|||
@nxast 15
|
||||
|
||||
alias __MODULE__
|
||||
alias Openflow.Action.Experimenter
|
||||
|
||||
def new(options) do
|
||||
src_field = Keyword.get(options, :src_field)
|
||||
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)
|
||||
n_bits = Keyword.get(options, :n_bits, default_n_bits)
|
||||
ofs = Keyword.get(options, :offset, 0)
|
||||
max_len = Keyword.get(options, :max_len, :no_buffer)
|
||||
%NxOutputReg{n_bits: n_bits, offset: ofs, src_field: src_field, max_len: max_len}
|
||||
|
||||
%NxOutputReg{
|
||||
n_bits: options[:n_bits] || default_n_bits,
|
||||
offset: options[:offset] || 0,
|
||||
src_field: src_field,
|
||||
max_len: options[:max_len] || :no_buffer
|
||||
}
|
||||
end
|
||||
|
||||
def to_binary(%NxOutputReg{n_bits: n_bits, offset: ofs, src_field: src_field, max_len: max_len}) do
|
||||
src_field_bin = Openflow.Match.codec_header(src_field)
|
||||
ofs_nbits = ofs <<< 6 ||| n_bits - 1
|
||||
max_len = Openflow.Utils.get_enum(max_len, :controller_max_len)
|
||||
body = <<ofs_nbits::16, src_field_bin::4-bytes, max_len::16, 0::size(6)-unit(8)>>
|
||||
exp_body = <<@experimenter::32, @nxast::16, body::bytes>>
|
||||
exp_body_size = byte_size(exp_body)
|
||||
padding_length = Openflow.Utils.padding(4 + exp_body_size, 8)
|
||||
length = 4 + exp_body_size + padding_length
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
def to_binary(%NxOutputReg{} = output_reg) do
|
||||
src_field_bin = Openflow.Match.codec_header(output_reg.src_field)
|
||||
ofs_nbits = output_reg.offset <<< 6 ||| output_reg.n_bits - 1
|
||||
max_len = Openflow.Utils.get_enum(output_reg.max_len, :controller_max_len)
|
||||
|
||||
Experimenter.pack_exp_header(<<
|
||||
@experimenter::32,
|
||||
@nxast::16,
|
||||
ofs_nbits::16,
|
||||
src_field_bin::4-bytes,
|
||||
max_len::16,
|
||||
0::size(6)-unit(8)
|
||||
>>)
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, body::bytes>>) do
|
||||
|
|
|
|||
|
|
@ -12,27 +12,38 @@ defmodule Openflow.Action.NxOutputReg2 do
|
|||
@nxast 32
|
||||
|
||||
alias __MODULE__
|
||||
alias Openflow.Action.Experimenter
|
||||
|
||||
def new(options) do
|
||||
src_field = Keyword.get(options, :src_field)
|
||||
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)
|
||||
n_bits = Keyword.get(options, :n_bits, default_n_bits)
|
||||
ofs = Keyword.get(options, :offset, 0)
|
||||
max_len = Keyword.get(options, :max_len, :no_buffer)
|
||||
%NxOutputReg2{n_bits: n_bits, offset: ofs, src_field: src_field, max_len: max_len}
|
||||
|
||||
%NxOutputReg2{
|
||||
n_bits: options[:n_bits] || default_n_bits,
|
||||
offset: options[:offset] || 0,
|
||||
src_field: src_field,
|
||||
max_len: options[:max_len] || :no_buffer
|
||||
}
|
||||
end
|
||||
|
||||
def to_binary(%NxOutputReg2{n_bits: n_bits, offset: ofs, src_field: src_field, max_len: max_len}) do
|
||||
src_field_bin = Openflow.Match.codec_header(src_field)
|
||||
ofs_nbits = ofs <<< 6 ||| n_bits - 1
|
||||
max_len = Openflow.Utils.get_enum(max_len, :controller_max_len)
|
||||
padding = Openflow.Utils.padding(byte_size(src_field_bin), 10)
|
||||
body = <<ofs_nbits::16, max_len::16, src_field_bin::bytes, 0::size(padding)-unit(8)>>
|
||||
exp_body = <<@experimenter::32, @nxast::16, body::bytes>>
|
||||
exp_body_size = byte_size(exp_body)
|
||||
padding_length = Openflow.Utils.padding(4 + exp_body_size, 8)
|
||||
length = 4 + exp_body_size + padding_length
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
def to_binary(%NxOutputReg2{} = output_reg) do
|
||||
src_field_bin = Openflow.Match.codec_header(output_reg.src_field)
|
||||
ofs_nbits = output_reg.offset <<< 6 ||| output_reg.n_bits - 1
|
||||
max_len = Openflow.Utils.get_enum(output_reg.max_len, :controller_max_len)
|
||||
|
||||
padding =
|
||||
src_field_bin
|
||||
|> byte_size()
|
||||
|> Openflow.Utils.padding(10)
|
||||
|
||||
Experimenter.pack_exp_header(<<
|
||||
@experimenter::32,
|
||||
@nxast::16,
|
||||
ofs_nbits::16,
|
||||
max_len::16,
|
||||
src_field_bin::bytes,
|
||||
0::size(padding)-unit(8)
|
||||
>>)
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, body::bytes>>) do
|
||||
|
|
|
|||
|
|
@ -8,20 +8,27 @@ defmodule Openflow.Action.NxOutputTrunc do
|
|||
@nxast 39
|
||||
|
||||
alias __MODULE__
|
||||
alias Openflow.Action.Experimenter
|
||||
|
||||
def new(options) do
|
||||
port_no = Keyword.get(options, :port_number)
|
||||
max_len = Keyword.get(options, :max_len)
|
||||
%NxOutputTrunc{port_number: port_no, max_len: max_len}
|
||||
def new(options \\ []) do
|
||||
port_no = options[:port_no] || raise "port_no must be specified"
|
||||
max_len = options[:max_len] || raise "max_len must be specified"
|
||||
|
||||
%NxOutputTrunc{
|
||||
port_number: port_no,
|
||||
max_len: max_len
|
||||
}
|
||||
end
|
||||
|
||||
def to_binary(%NxOutputTrunc{port_number: port_no, max_len: max_len}) do
|
||||
port_no_int = Openflow.Utils.get_enum(port_no, :openflow10_port_no)
|
||||
exp_body = <<@experimenter::32, @nxast::16, port_no_int::16, max_len::32>>
|
||||
exp_body_size = byte_size(exp_body)
|
||||
padding_length = Openflow.Utils.padding(4 + exp_body_size, 8)
|
||||
length = 4 + exp_body_size + padding_length
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
|
||||
Experimenter.pack_exp_header(<<
|
||||
@experimenter::32,
|
||||
@nxast::16,
|
||||
port_no_int::16,
|
||||
max_len::32
|
||||
>>)
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, port_no_int::16, max_len::32>>) do
|
||||
|
|
|
|||
|
|
@ -4,18 +4,22 @@ defmodule Openflow.Action.NxPopMpls do
|
|||
@experimenter 0x00002320
|
||||
@nxast 24
|
||||
|
||||
alias __MODULE__
|
||||
@eth_p_mpls_uc 0x8847
|
||||
|
||||
def new(ethertype \\ 0x8847) do
|
||||
alias __MODULE__
|
||||
alias Openflow.Action.Experimenter
|
||||
|
||||
def new(ethertype \\ @eth_p_mpls_uc) do
|
||||
%NxPopMpls{ethertype: ethertype}
|
||||
end
|
||||
|
||||
def to_binary(%NxPopMpls{ethertype: ethertype}) do
|
||||
exp_body = <<@experimenter::32, @nxast::16, ethertype::16, 0::size(4)-unit(8)>>
|
||||
exp_body_size = byte_size(exp_body)
|
||||
padding_length = Openflow.Utils.padding(4 + exp_body_size, 8)
|
||||
length = 4 + exp_body_size + padding_length
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
Experimenter.pack_exp_header(<<
|
||||
@experimenter::32,
|
||||
@nxast::16,
|
||||
ethertype::16,
|
||||
0::size(4)-unit(8)
|
||||
>>)
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, ethertype::16, _::size(4)-unit(8)>>) do
|
||||
|
|
|
|||
|
|
@ -1,24 +0,0 @@
|
|||
defmodule Openflow.Action.NxPopQueue do
|
||||
defstruct([])
|
||||
|
||||
@experimenter 0x00002320
|
||||
@nxast 5
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
def new do
|
||||
%NxPopQueue{}
|
||||
end
|
||||
|
||||
def to_binary(%NxPopQueue{}) do
|
||||
exp_body = <<@experimenter::32, @nxast::16, 0::48>>
|
||||
exp_body_size = byte_size(exp_body)
|
||||
padding_length = Openflow.Utils.padding(4 + exp_body_size, 8)
|
||||
length = 4 + exp_body_size + padding_length
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, 0::size(6)-unit(8)>>) do
|
||||
%NxPopQueue{}
|
||||
end
|
||||
end
|
||||
|
|
@ -4,18 +4,22 @@ defmodule Openflow.Action.NxPushMpls do
|
|||
@experimenter 0x00002320
|
||||
@nxast 23
|
||||
|
||||
alias __MODULE__
|
||||
@eth_p_mpls_uc 0x8847
|
||||
|
||||
def new(ethertype \\ 0x8847) do
|
||||
alias __MODULE__
|
||||
alias Openflow.Action.Experimenter
|
||||
|
||||
def new(ethertype \\ @eth_p_mpls_uc) do
|
||||
%NxPushMpls{ethertype: ethertype}
|
||||
end
|
||||
|
||||
def to_binary(%NxPushMpls{ethertype: ethertype}) do
|
||||
exp_body = <<@experimenter::32, @nxast::16, ethertype::16, 0::size(4)-unit(8)>>
|
||||
exp_body_size = byte_size(exp_body)
|
||||
padding_length = Openflow.Utils.padding(4 + exp_body_size, 8)
|
||||
length = 4 + exp_body_size + padding_length
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
Experimenter.pack_exp_header(<<
|
||||
@experimenter::32,
|
||||
@nxast::16,
|
||||
ethertype::16,
|
||||
0::size(4)-unit(8)
|
||||
>>)
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, ethertype::16, _::size(4)-unit(8)>>) do
|
||||
|
|
|
|||
|
|
@ -12,28 +12,37 @@ defmodule Openflow.Action.NxRegLoad do
|
|||
@nxast 7
|
||||
|
||||
alias __MODULE__
|
||||
alias Openflow.Action.Experimenter
|
||||
|
||||
def new(options) do
|
||||
dst_field = Keyword.get(options, :dst_field)
|
||||
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)
|
||||
n_bits = Keyword.get(options, :n_bits, default_n_bits)
|
||||
ofs = Keyword.get(options, :offset, 0)
|
||||
value = Keyword.get(options, :value)
|
||||
%NxRegLoad{n_bits: n_bits, offset: ofs, dst_field: dst_field, value: value}
|
||||
|
||||
%NxRegLoad{
|
||||
n_bits: options[:n_bits] || default_n_bits,
|
||||
offset: options[:offset] || 0,
|
||||
dst_field: dst_field,
|
||||
value: value
|
||||
}
|
||||
end
|
||||
|
||||
def to_binary(%NxRegLoad{n_bits: n_bits, offset: ofs, dst_field: dst_field, value: value}) do
|
||||
dst_field_bin = Openflow.Match.codec_header(dst_field)
|
||||
value_bin0 = Openflow.Match.Field.codec(value, dst_field)
|
||||
tmp_value = :binary.decode_unsigned(value_bin0, :big)
|
||||
value_bin = <<tmp_value::64>>
|
||||
ofs_nbits = ofs <<< 6 ||| n_bits - 1
|
||||
body = <<ofs_nbits::16, dst_field_bin::4-bytes, value_bin::bytes>>
|
||||
exp_body = <<@experimenter::32, @nxast::16, body::bytes>>
|
||||
exp_body_size = byte_size(exp_body)
|
||||
padding_length = Openflow.Utils.padding(4 + exp_body_size, 8)
|
||||
length = 4 + exp_body_size + padding_length
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
def to_binary(%NxRegLoad{} = load) do
|
||||
ofs_nbits = load.offset <<< 6 ||| load.n_bits - 1
|
||||
dst_field_bin = Openflow.Match.codec_header(load.dst_field)
|
||||
|
||||
value_int =
|
||||
load.value
|
||||
|> Openflow.Match.Field.codec(load.dst_field)
|
||||
|> :binary.decode_unsigned(:big)
|
||||
|
||||
Experimenter.pack_exp_header(<<
|
||||
@experimenter::32,
|
||||
@nxast::16,
|
||||
ofs_nbits::16,
|
||||
dst_field_bin::4-bytes,
|
||||
value_int::size(8)-unit(8)
|
||||
>>)
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, body::bytes>>) do
|
||||
|
|
|
|||
|
|
@ -1,44 +1,38 @@
|
|||
defmodule Openflow.Action.NxRegLoad2 do
|
||||
defstruct(
|
||||
dst_field: nil,
|
||||
value: nil
|
||||
)
|
||||
defstruct(field: nil)
|
||||
|
||||
@experimenter 0x00002320
|
||||
@nxast 33
|
||||
|
||||
alias __MODULE__
|
||||
alias Openflow.Action.Experimenter
|
||||
|
||||
def new(options) do
|
||||
dst_field = Keyword.get(options, :dst_field)
|
||||
value = Keyword.get(options, :value)
|
||||
%NxRegLoad2{dst_field: dst_field, value: value}
|
||||
def new([{_field, _value}] = field) do
|
||||
%NxRegLoad2{field: field}
|
||||
end
|
||||
|
||||
def to_binary(%NxRegLoad2{dst_field: dst_field, value: value}) do
|
||||
def to_binary(%NxRegLoad2{field: field}) do
|
||||
match_bin =
|
||||
[{dst_field, value}]
|
||||
field
|
||||
|> Openflow.Match.new()
|
||||
|> Openflow.Match.to_binary()
|
||||
|
||||
<<1::16, _length::16, padded_field::bytes>> = match_bin
|
||||
patial_len = 4 + 4 + 2 + 6 + byte_size(padded_field)
|
||||
padding = Openflow.Utils.padding(patial_len, 8)
|
||||
<<1::16, length::16, padded_field::bytes>> = match_bin
|
||||
field_len = length - 4
|
||||
<<field_bin::size(field_len)-bytes, _::bytes>> = padded_field
|
||||
|
||||
exp_body =
|
||||
<<@experimenter::32, @nxast::16, 0::48, padded_field::bytes, 0::size(padding)-unit(8)>>
|
||||
|
||||
exp_body_size = byte_size(exp_body)
|
||||
padding_length = Openflow.Utils.padding(4 + exp_body_size, 8)
|
||||
length = 4 + exp_body_size + padding_length
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
Experimenter.pack_exp_header(<<
|
||||
@experimenter::32,
|
||||
@nxast::16,
|
||||
field_bin::bytes
|
||||
>>)
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, _::48, match_field_bin::bytes>>) do
|
||||
def read(<<@experimenter::32, @nxast::16, match_field_bin::bytes>>) do
|
||||
<<_class::16, _field::7, _hm::1, flen::8, _rest::bytes>> = match_field_bin
|
||||
match_len = 4 + 4 + flen
|
||||
match_bin = <<1::16, match_len::16, match_field_bin::bytes, 0::size(4)-unit(8)>>
|
||||
{[{dst_field, value} | _], _rest} = Openflow.Match.read(match_bin)
|
||||
%NxRegLoad2{dst_field: dst_field, value: value}
|
||||
match_bin = <<1::16, match_len::16, match_field_bin::bytes>>
|
||||
{[field | _], _rest} = Openflow.Match.read(match_bin)
|
||||
%NxRegLoad2{field: [field]}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -11,42 +11,35 @@ defmodule Openflow.Action.NxRegMove do
|
|||
@nxast 6
|
||||
|
||||
alias __MODULE__
|
||||
alias Openflow.Action.Experimenter
|
||||
|
||||
def new(options) do
|
||||
src_field = Keyword.get(options, :src_field)
|
||||
dst_field = Keyword.get(options, :dst_field)
|
||||
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)
|
||||
n_bits = Keyword.get(options, :n_bits, default_n_bits)
|
||||
src_ofs = Keyword.get(options, :src_offset, 0)
|
||||
dst_ofs = Keyword.get(options, :dst_offset, 0)
|
||||
|
||||
%NxRegMove{
|
||||
n_bits: n_bits,
|
||||
src_offset: src_ofs,
|
||||
dst_offset: dst_ofs,
|
||||
n_bits: options[:n_bits] || default_n_bits,
|
||||
src_offset: options[:src_offset] || 0,
|
||||
dst_offset: options[:dst_offset] || 0,
|
||||
src_field: src_field,
|
||||
dst_field: dst_field
|
||||
}
|
||||
end
|
||||
|
||||
def to_binary(%NxRegMove{
|
||||
n_bits: n_bits,
|
||||
src_offset: src_ofs,
|
||||
dst_offset: dst_ofs,
|
||||
src_field: src_field,
|
||||
dst_field: dst_field
|
||||
}) do
|
||||
src_field_bin = Openflow.Match.codec_header(src_field)
|
||||
dst_field_bin = Openflow.Match.codec_header(dst_field)
|
||||
def to_binary(%NxRegMove{} = move) do
|
||||
src_field_bin = Openflow.Match.codec_header(move.src_field)
|
||||
dst_field_bin = Openflow.Match.codec_header(move.dst_field)
|
||||
|
||||
body =
|
||||
<<n_bits::16, src_ofs::16, dst_ofs::16, src_field_bin::4-bytes, dst_field_bin::4-bytes>>
|
||||
|
||||
exp_body = <<@experimenter::32, @nxast::16, body::bytes>>
|
||||
exp_body_size = byte_size(exp_body)
|
||||
padding_length = Openflow.Utils.padding(4 + exp_body_size, 8)
|
||||
length = 4 + exp_body_size + padding_length
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
Experimenter.pack_exp_header(<<
|
||||
@experimenter::32,
|
||||
@nxast::16,
|
||||
move.n_bits::16,
|
||||
move.src_offset::16,
|
||||
move.dst_offset::16,
|
||||
src_field_bin::4-bytes,
|
||||
dst_field_bin::4-bytes
|
||||
>>)
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, body::bytes>>) do
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ defmodule Openflow.Action.NxResubmit do
|
|||
@nxast 1
|
||||
|
||||
alias __MODULE__
|
||||
alias Openflow.Action.Experimenter
|
||||
|
||||
def new(in_port \\ :in_port) do
|
||||
%NxResubmit{in_port: in_port}
|
||||
|
|
@ -12,11 +13,13 @@ defmodule Openflow.Action.NxResubmit do
|
|||
|
||||
def to_binary(%NxResubmit{in_port: in_port}) do
|
||||
in_port_int = Openflow.Utils.get_enum(in_port, :openflow10_port_no)
|
||||
exp_body = <<@experimenter::32, @nxast::16, in_port_int::16, 0::size(4)-unit(8)>>
|
||||
exp_body_size = byte_size(exp_body)
|
||||
padding_length = Openflow.Utils.padding(4 + exp_body_size, 8)
|
||||
length = 4 + exp_body_size + padding_length
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
|
||||
Experimenter.pack_exp_header(<<
|
||||
@experimenter::32,
|
||||
@nxast::16,
|
||||
in_port_int::16,
|
||||
0::size(4)-unit(8)
|
||||
>>)
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, in_port_int::16, _::size(4)-unit(8)>>) do
|
||||
|
|
|
|||
|
|
@ -5,25 +5,31 @@ defmodule Openflow.Action.NxResubmitTable do
|
|||
@nxast 14
|
||||
|
||||
alias __MODULE__
|
||||
alias Openflow.Action.Experimenter
|
||||
|
||||
def new(options \\ [])
|
||||
|
||||
def new(table_id) when is_atom(table_id) or is_integer(table_id) do
|
||||
new(table_id: table_id)
|
||||
end
|
||||
|
||||
def new(options) do
|
||||
in_port = Keyword.get(options, :in_port, :in_port)
|
||||
table_id = Keyword.get(options, :table_id, :all)
|
||||
in_port = options[:in_port] || :in_port
|
||||
table_id = options[:table_id] || :all
|
||||
%NxResubmitTable{in_port: in_port, table_id: table_id}
|
||||
end
|
||||
|
||||
def to_binary(%NxResubmitTable{in_port: in_port, table_id: table_id}) do
|
||||
in_port_int = Openflow.Utils.get_enum(in_port, :openflow10_port_no)
|
||||
table_id_int = Openflow.Utils.get_enum(table_id, :table_id)
|
||||
exp_body = <<@experimenter::32, @nxast::16, in_port_int::16, table_id_int::8, 0::24>>
|
||||
exp_body_size = byte_size(exp_body)
|
||||
padding_length = Openflow.Utils.padding(4 + exp_body_size, 8)
|
||||
length = 4 + exp_body_size + padding_length
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
def to_binary(%NxResubmitTable{} = resubmit_table) do
|
||||
in_port_int = Openflow.Utils.get_enum(resubmit_table.in_port, :openflow10_port_no)
|
||||
table_id_int = Openflow.Utils.get_enum(resubmit_table.table_id, :table_id)
|
||||
|
||||
Experimenter.pack_exp_header(<<
|
||||
@experimenter::32,
|
||||
@nxast::16,
|
||||
in_port_int::16,
|
||||
table_id_int::8,
|
||||
0::24
|
||||
>>)
|
||||
end
|
||||
|
||||
def read(
|
||||
|
|
|
|||
|
|
@ -5,21 +5,31 @@ defmodule Openflow.Action.NxResubmitTableCt do
|
|||
@nxast 44
|
||||
|
||||
alias __MODULE__
|
||||
alias Openflow.Action.Experimenter
|
||||
|
||||
def new(options) do
|
||||
in_port = Keyword.get(options, :in_port, :in_port)
|
||||
table_id = Keyword.get(options, :table_id, :all)
|
||||
def new(options \\ [])
|
||||
|
||||
def new(table_id) when is_atom(table_id) or is_integer(table_id) do
|
||||
new(table_id: table_id)
|
||||
end
|
||||
|
||||
def new(options) when is_list(options) do
|
||||
in_port = options[:in_port] || :in_port
|
||||
table_id = options[:table_id] || :all
|
||||
%NxResubmitTableCt{in_port: in_port, table_id: table_id}
|
||||
end
|
||||
|
||||
def to_binary(%NxResubmitTableCt{in_port: in_port, table_id: table_id}) do
|
||||
in_port_int = Openflow.Utils.get_enum(in_port, :openflow10_port_no)
|
||||
table_id_int = Openflow.Utils.get_enum(table_id, :table_id)
|
||||
exp_body = <<@experimenter::32, @nxast::16, in_port_int::16, table_id_int::8, 0::24>>
|
||||
exp_body_size = byte_size(exp_body)
|
||||
padding_length = Openflow.Utils.padding(4 + exp_body_size, 8)
|
||||
length = 4 + exp_body_size + padding_length
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
def to_binary(%NxResubmitTableCt{} = resubmit_table) do
|
||||
in_port_int = Openflow.Utils.get_enum(resubmit_table.in_port, :openflow10_port_no)
|
||||
table_id_int = Openflow.Utils.get_enum(resubmit_table.table_id, :table_id)
|
||||
|
||||
Experimenter.pack_exp_header(<<
|
||||
@experimenter::32,
|
||||
@nxast::16,
|
||||
in_port_int::16,
|
||||
table_id_int::8,
|
||||
0::24
|
||||
>>)
|
||||
end
|
||||
|
||||
def read(
|
||||
|
|
|
|||
|
|
@ -10,35 +10,26 @@ defmodule Openflow.Action.NxSample do
|
|||
@nxast 29
|
||||
|
||||
alias __MODULE__
|
||||
alias Openflow.Action.Experimenter
|
||||
|
||||
def new(options) do
|
||||
probability = Keyword.get(options, :probability, 0)
|
||||
collector_set_id = Keyword.get(options, :collector_set_id, 0)
|
||||
obs_domain_id = Keyword.get(options, :obs_domain_id, 0)
|
||||
obs_point_id = Keyword.get(options, :obs_point_id, 0)
|
||||
|
||||
def new(options \\ []) do
|
||||
%NxSample{
|
||||
probability: probability,
|
||||
collector_set_id: collector_set_id,
|
||||
obs_domain_id: obs_domain_id,
|
||||
obs_point_id: obs_point_id
|
||||
probability: options[:probability] || 0,
|
||||
collector_set_id: options[:collector_set_id] || 0,
|
||||
obs_domain_id: options[:obs_domain_id] || 0,
|
||||
obs_point_id: options[:obs_point_id] || 0
|
||||
}
|
||||
end
|
||||
|
||||
def to_binary(%NxSample{
|
||||
probability: probability,
|
||||
collector_set_id: collector_set_id,
|
||||
obs_domain_id: obs_domain_id,
|
||||
obs_point_id: obs_point_id
|
||||
}) do
|
||||
exp_body =
|
||||
<<@experimenter::32, @nxast::16, probability::16, collector_set_id::32, obs_domain_id::32,
|
||||
obs_point_id::32>>
|
||||
|
||||
exp_body_size = byte_size(exp_body)
|
||||
padding_length = Openflow.Utils.padding(4 + exp_body_size, 8)
|
||||
length = 4 + exp_body_size + padding_length
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
def to_binary(%NxSample{} = sample) do
|
||||
Experimenter.pack_exp_header(<<
|
||||
@experimenter::32,
|
||||
@nxast::16,
|
||||
sample.probability::16,
|
||||
sample.collector_set_id::32,
|
||||
sample.obs_domain_id::32,
|
||||
sample.obs_point_id::32
|
||||
>>)
|
||||
end
|
||||
|
||||
def read(
|
||||
|
|
|
|||
|
|
@ -11,44 +11,41 @@ defmodule Openflow.Action.NxSample2 do
|
|||
@nxast 38
|
||||
|
||||
alias __MODULE__
|
||||
alias Openflow.Action.Experimenter
|
||||
|
||||
def new(options) do
|
||||
probability = Keyword.get(options, :probability, 0)
|
||||
collector_set_id = Keyword.get(options, :collector_set_id, 0)
|
||||
obs_domain_id = Keyword.get(options, :obs_domain_id, 0)
|
||||
obs_point_id = Keyword.get(options, :obs_point_id, 0)
|
||||
sampling_port = Keyword.get(options, :sampling_port, 0)
|
||||
|
||||
def new(options \\ []) do
|
||||
%NxSample2{
|
||||
probability: probability,
|
||||
collector_set_id: collector_set_id,
|
||||
obs_domain_id: obs_domain_id,
|
||||
obs_point_id: obs_point_id,
|
||||
sampling_port: sampling_port
|
||||
probability: options[:probability] || 0,
|
||||
collector_set_id: options[:collector_set_id] || 0,
|
||||
obs_domain_id: options[:obs_domain_id] || 0,
|
||||
obs_point_id: options[:obs_point_id] || 0,
|
||||
sampling_port: options[:sampling_port] || 0
|
||||
}
|
||||
end
|
||||
|
||||
def to_binary(%NxSample2{
|
||||
probability: probability,
|
||||
collector_set_id: collector_set_id,
|
||||
obs_domain_id: obs_domain_id,
|
||||
obs_point_id: obs_point_id,
|
||||
sampling_port: sampling_port
|
||||
}) do
|
||||
exp_body =
|
||||
<<@experimenter::32, @nxast::16, probability::16, collector_set_id::32, obs_domain_id::32,
|
||||
obs_point_id::32, sampling_port::16, 0::size(6)-unit(8)>>
|
||||
|
||||
exp_body_size = byte_size(exp_body)
|
||||
padding_length = Openflow.Utils.padding(4 + exp_body_size, 8)
|
||||
length = 4 + exp_body_size + padding_length
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
def to_binary(%NxSample2{} = sample) do
|
||||
Experimenter.pack_exp_header(<<
|
||||
@experimenter::32,
|
||||
@nxast::16,
|
||||
sample.probability::16,
|
||||
sample.collector_set_id::32,
|
||||
sample.obs_domain_id::32,
|
||||
sample.obs_point_id::32,
|
||||
sample.sampling_port::16,
|
||||
0::size(6)-unit(8)
|
||||
>>)
|
||||
end
|
||||
|
||||
def read(
|
||||
<<@experimenter::32, @nxast::16, probability::16, collector_set_id::32, obs_domain_id::32,
|
||||
obs_point_id::32, sampling_port::16, 0::size(6)-unit(8)>>
|
||||
) do
|
||||
def read(<<
|
||||
@experimenter::32,
|
||||
@nxast::16,
|
||||
probability::16,
|
||||
collector_set_id::32,
|
||||
obs_domain_id::32,
|
||||
obs_point_id::32,
|
||||
sampling_port::16,
|
||||
_::size(6)-unit(8)
|
||||
>>) do
|
||||
%NxSample2{
|
||||
probability: probability,
|
||||
collector_set_id: collector_set_id,
|
||||
|
|
|
|||
|
|
@ -12,43 +12,33 @@ defmodule Openflow.Action.NxSample3 do
|
|||
@nxast 41
|
||||
|
||||
alias __MODULE__
|
||||
alias Openflow.Action.Experimenter
|
||||
|
||||
def new(options) do
|
||||
probability = Keyword.get(options, :probability, 0)
|
||||
collector_set_id = Keyword.get(options, :collector_set_id, 0)
|
||||
obs_domain_id = Keyword.get(options, :obs_domain_id, 0)
|
||||
obs_point_id = Keyword.get(options, :obs_point_id, 0)
|
||||
sampling_port = Keyword.get(options, :sampling_port, 0)
|
||||
direction = Keyword.get(options, :direction, :default)
|
||||
|
||||
def new(options \\ []) do
|
||||
%NxSample3{
|
||||
probability: probability,
|
||||
collector_set_id: collector_set_id,
|
||||
obs_domain_id: obs_domain_id,
|
||||
obs_point_id: obs_point_id,
|
||||
sampling_port: sampling_port,
|
||||
direction: direction
|
||||
probability: options[:probability] || 0,
|
||||
collector_set_id: options[:collector_set_id] || 0,
|
||||
obs_domain_id: options[:obs_domain_id] || 0,
|
||||
obs_point_id: options[:obs_point_id] || 0,
|
||||
sampling_port: options[:sampling_port] || 0,
|
||||
direction: options[:direction] || :default
|
||||
}
|
||||
end
|
||||
|
||||
def to_binary(%NxSample3{
|
||||
probability: probability,
|
||||
collector_set_id: collector_set_id,
|
||||
obs_domain_id: obs_domain_id,
|
||||
obs_point_id: obs_point_id,
|
||||
sampling_port: sampling_port,
|
||||
direction: direction
|
||||
}) do
|
||||
direction_int = Openflow.Enums.to_int(direction, :nx_action_sample_direction)
|
||||
def to_binary(%NxSample3{} = sample) do
|
||||
sample_direction_int = Openflow.Enums.to_int(sample.direction, :nx_action_sample_direction)
|
||||
|
||||
exp_body =
|
||||
<<@experimenter::32, @nxast::16, probability::16, collector_set_id::32, obs_domain_id::32,
|
||||
obs_point_id::32, sampling_port::16, direction_int::8, 0::size(5)-unit(8)>>
|
||||
|
||||
exp_body_size = byte_size(exp_body)
|
||||
padding_length = Openflow.Utils.padding(4 + exp_body_size, 8)
|
||||
length = 4 + exp_body_size + padding_length
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
Experimenter.pack_exp_header(<<
|
||||
@experimenter::32,
|
||||
@nxast::16,
|
||||
sample.probability::16,
|
||||
sample.collector_set_id::32,
|
||||
sample.obs_domain_id::32,
|
||||
sample.obs_point_id::32,
|
||||
sample.sampling_port::16,
|
||||
sample_direction_int::8,
|
||||
0::size(5)-unit(8)
|
||||
>>)
|
||||
end
|
||||
|
||||
def read(
|
||||
|
|
|
|||
|
|
@ -1,24 +0,0 @@
|
|||
defmodule Openflow.Action.NxSetMplsLabel do
|
||||
defstruct(label: 0)
|
||||
|
||||
@experimenter 0x00002320
|
||||
@nxast 30
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
def new(label) do
|
||||
%NxSetMplsLabel{label: label}
|
||||
end
|
||||
|
||||
def to_binary(%NxSetMplsLabel{label: label}) do
|
||||
exp_body = <<@experimenter::32, @nxast::16, 0::16, label::32>>
|
||||
exp_body_size = byte_size(exp_body)
|
||||
padding_length = Openflow.Utils.padding(4 + exp_body_size, 8)
|
||||
length = 4 + exp_body_size + padding_length
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, _::16, label::32>>) do
|
||||
%NxSetMplsLabel{label: label}
|
||||
end
|
||||
end
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
defmodule Openflow.Action.NxSetMplsTc do
|
||||
defstruct(tc: 0)
|
||||
|
||||
@experimenter 0x00002320
|
||||
@nxast 31
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
def new(tc) do
|
||||
%NxSetMplsTc{tc: tc}
|
||||
end
|
||||
|
||||
def to_binary(%NxSetMplsTc{tc: tc}) do
|
||||
exp_body = <<@experimenter::32, @nxast::16, tc::8, 0::size(5)-unit(8)>>
|
||||
exp_body_size = byte_size(exp_body)
|
||||
padding_length = Openflow.Utils.padding(4 + exp_body_size, 8)
|
||||
length = 4 + exp_body_size + padding_length
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, tc::8, _::size(5)-unit(8)>>) do
|
||||
%NxSetMplsTc{tc: tc}
|
||||
end
|
||||
end
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
defmodule Openflow.Action.NxSetMplsTtl do
|
||||
defstruct(ttl: 0)
|
||||
|
||||
@experimenter 0x00002320
|
||||
@nxast 25
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
def new(ttl) do
|
||||
%NxSetMplsTtl{ttl: ttl}
|
||||
end
|
||||
|
||||
def to_binary(%NxSetMplsTtl{ttl: ttl}) do
|
||||
exp_body = <<@experimenter::32, @nxast::16, ttl::8, 0::size(5)-unit(8)>>
|
||||
exp_body_size = byte_size(exp_body)
|
||||
padding_length = Openflow.Utils.padding(4 + exp_body_size, 8)
|
||||
length = 4 + exp_body_size + padding_length
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, ttl::8, _::size(5)-unit(8)>>) do
|
||||
%NxSetMplsTtl{ttl: ttl}
|
||||
end
|
||||
end
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
defmodule Openflow.Action.NxSetQueue do
|
||||
defstruct(queue_id: 0)
|
||||
|
||||
@experimenter 0x00002320
|
||||
@nxast 4
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
def new(queue_id) do
|
||||
%NxSetQueue{queue_id: queue_id}
|
||||
end
|
||||
|
||||
def to_binary(%NxSetQueue{queue_id: queue_id}) do
|
||||
exp_body = <<@experimenter::32, @nxast::16, 0::16, queue_id::32>>
|
||||
exp_body_size = byte_size(exp_body)
|
||||
padding_length = Openflow.Utils.padding(4 + exp_body_size, 8)
|
||||
length = 4 + exp_body_size + padding_length
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, 0::size(2)-unit(8), queue_id::32>>) do
|
||||
%NxSetQueue{queue_id: queue_id}
|
||||
end
|
||||
end
|
||||
|
|
@ -5,17 +5,19 @@ defmodule Openflow.Action.NxSetTunnel do
|
|||
@nxast 2
|
||||
|
||||
alias __MODULE__
|
||||
alias Openflow.Action.Experimenter
|
||||
|
||||
def new(tunnel_id) do
|
||||
%NxSetTunnel{tunnel_id: tunnel_id}
|
||||
end
|
||||
|
||||
def to_binary(%NxSetTunnel{tunnel_id: tunnel_id}) do
|
||||
exp_body = <<@experimenter::32, @nxast::16, 0::16, tunnel_id::32>>
|
||||
exp_body_size = byte_size(exp_body)
|
||||
padding_length = Openflow.Utils.padding(4 + exp_body_size, 8)
|
||||
length = 4 + exp_body_size + padding_length
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
Experimenter.pack_exp_header(<<
|
||||
@experimenter::32,
|
||||
@nxast::16,
|
||||
0::16,
|
||||
tunnel_id::32
|
||||
>>)
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, _::16, tunnel_id::32>>) do
|
||||
|
|
|
|||
|
|
@ -5,17 +5,19 @@ defmodule Openflow.Action.NxSetTunnel64 do
|
|||
@nxast 9
|
||||
|
||||
alias __MODULE__
|
||||
alias Openflow.Action.Experimenter
|
||||
|
||||
def new(tunnel_id) do
|
||||
%NxSetTunnel64{tunnel_id: tunnel_id}
|
||||
end
|
||||
|
||||
def to_binary(%NxSetTunnel64{tunnel_id: tunnel_id}) do
|
||||
exp_body = <<@experimenter::32, @nxast::16, 0::size(6)-unit(8), tunnel_id::64>>
|
||||
exp_body_size = byte_size(exp_body)
|
||||
padding_length = Openflow.Utils.padding(4 + exp_body_size, 8)
|
||||
length = 4 + exp_body_size + padding_length
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
Experimenter.pack_exp_header(<<
|
||||
@experimenter::32,
|
||||
@nxast::16,
|
||||
0::size(6)-unit(8),
|
||||
tunnel_id::64
|
||||
>>)
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, 0::size(6)-unit(8), tunnel_id::64>>) do
|
||||
|
|
|
|||
|
|
@ -9,26 +9,30 @@ defmodule Openflow.Action.NxStackPop do
|
|||
@nxast 28
|
||||
|
||||
alias __MODULE__
|
||||
alias Openflow.Action.Experimenter
|
||||
|
||||
def new(options) do
|
||||
field = Keyword.get(options, :field)
|
||||
field = options[:field] || raise "field must be specified"
|
||||
default_n_bits = Openflow.Match.Field.n_bits_of(field)
|
||||
n_bits = Keyword.get(options, :n_bits, default_n_bits)
|
||||
ofs = Keyword.get(options, :offset, 0)
|
||||
%NxStackPop{n_bits: n_bits, offset: ofs, field: field}
|
||||
|
||||
%NxStackPop{
|
||||
n_bits: options[:n_bits] || default_n_bits,
|
||||
offset: options[:offset] || 0,
|
||||
field: field
|
||||
}
|
||||
end
|
||||
|
||||
def to_binary(%NxStackPop{n_bits: n_bits, offset: ofs, field: field}) do
|
||||
field_bin = Openflow.Match.codec_header(field)
|
||||
def to_binary(%NxStackPop{} = stack_pop) do
|
||||
field_bin = Openflow.Match.codec_header(stack_pop.field)
|
||||
|
||||
exp_body =
|
||||
<<@experimenter::32, @nxast::16, ofs::16, field_bin::4-bytes, n_bits::16,
|
||||
0::size(6)-unit(8)>>
|
||||
|
||||
exp_body_size = byte_size(exp_body)
|
||||
padding_length = Openflow.Utils.padding(4 + exp_body_size, 8)
|
||||
length = 4 + exp_body_size + padding_length
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
Experimenter.pack_exp_header(<<
|
||||
@experimenter::32,
|
||||
@nxast::16,
|
||||
stack_pop.offset::16,
|
||||
field_bin::4-bytes,
|
||||
stack_pop.n_bits::16,
|
||||
0::size(6)-unit(8)
|
||||
>>)
|
||||
end
|
||||
|
||||
def read(
|
||||
|
|
|
|||
|
|
@ -9,26 +9,30 @@ defmodule Openflow.Action.NxStackPush do
|
|||
@nxast 27
|
||||
|
||||
alias __MODULE__
|
||||
alias Openflow.Action.Experimenter
|
||||
|
||||
def new(options) do
|
||||
field = Keyword.get(options, :field)
|
||||
field = options[:field] || raise "field must be specified"
|
||||
default_n_bits = Openflow.Match.Field.n_bits_of(field)
|
||||
n_bits = Keyword.get(options, :n_bits, default_n_bits)
|
||||
ofs = Keyword.get(options, :offset, 0)
|
||||
%NxStackPush{n_bits: n_bits, offset: ofs, field: field}
|
||||
|
||||
%NxStackPush{
|
||||
n_bits: options[:n_bits] || default_n_bits,
|
||||
offset: options[:offset] || 0,
|
||||
field: field
|
||||
}
|
||||
end
|
||||
|
||||
def to_binary(%NxStackPush{n_bits: n_bits, offset: ofs, field: field}) do
|
||||
field_bin = Openflow.Match.codec_header(field)
|
||||
def to_binary(%NxStackPush{} = stack_pop) do
|
||||
field_bin = Openflow.Match.codec_header(stack_pop.field)
|
||||
|
||||
exp_body =
|
||||
<<@experimenter::32, @nxast::16, ofs::16, field_bin::4-bytes, n_bits::16,
|
||||
0::size(6)-unit(8)>>
|
||||
|
||||
exp_body_size = byte_size(exp_body)
|
||||
padding_length = Openflow.Utils.padding(4 + exp_body_size, 8)
|
||||
length = 4 + exp_body_size + padding_length
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
Experimenter.pack_exp_header(<<
|
||||
@experimenter::32,
|
||||
@nxast::16,
|
||||
stack_pop.offset::16,
|
||||
field_bin::4-bytes,
|
||||
stack_pop.n_bits::16,
|
||||
0::size(6)-unit(8)
|
||||
>>)
|
||||
end
|
||||
|
||||
def read(
|
||||
|
|
|
|||
|
|
@ -8,25 +8,28 @@ defmodule Openflow.Action.NxWriteMetadata do
|
|||
@nxast 22
|
||||
|
||||
alias __MODULE__
|
||||
alias Openflow.Action.Experimenter
|
||||
|
||||
def new(options \\ [])
|
||||
|
||||
def new(metadata) when is_integer(metadata) do
|
||||
new(metadata: metadata)
|
||||
end
|
||||
|
||||
def new(options) when is_list(options) do
|
||||
metadata = Keyword.get(options, :metadata, 0)
|
||||
metadata_mask = Keyword.get(options, :metadata_mask, 0xFFFFFFFFFFFFFFFF)
|
||||
metadata = options[:metadata] || raise "metadata must be specified"
|
||||
metadata_mask = options[:metadata_mask] || 0xFFFFFFFFFFFFFFFF
|
||||
%NxWriteMetadata{metadata: metadata, metadata_mask: metadata_mask}
|
||||
end
|
||||
|
||||
def to_binary(%NxWriteMetadata{metadata: metadata, metadata_mask: metadata_mask}) do
|
||||
exp_body =
|
||||
<<@experimenter::32, @nxast::16, 0::size(6)-unit(8), metadata::64, metadata_mask::64>>
|
||||
|
||||
exp_body_size = byte_size(exp_body)
|
||||
padding_length = Openflow.Utils.padding(4 + exp_body_size, 8)
|
||||
length = 4 + exp_body_size + padding_length
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
Experimenter.pack_exp_header(<<
|
||||
@experimenter::32,
|
||||
@nxast::16,
|
||||
0::size(6)-unit(8),
|
||||
metadata::64,
|
||||
metadata_mask::64
|
||||
>>)
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, _::size(6)-unit(8), metadata::64, metadata_mask::64>>) do
|
||||
|
|
|
|||
|
|
@ -7,13 +7,13 @@ defmodule Openflow.Action.SetField do
|
|||
|
||||
def ofpat, do: 25
|
||||
|
||||
def new({_field, _value} = oxm_field) do
|
||||
def new([{_field, _value}] = oxm_field) do
|
||||
%SetField{field: oxm_field}
|
||||
end
|
||||
|
||||
def to_binary(%SetField{field: {field, value}}) do
|
||||
def to_binary(%SetField{field: field}) do
|
||||
match_bin =
|
||||
[{field, value}]
|
||||
field
|
||||
|> Openflow.Match.new()
|
||||
|> Openflow.Match.to_binary()
|
||||
|
||||
|
|
@ -29,6 +29,6 @@ defmodule Openflow.Action.SetField do
|
|||
match_len = 4 + 4 + flen
|
||||
match_bin = <<1::16, match_len::16, match_field_bin::bytes>>
|
||||
{[field | _], _rest} = Openflow.Match.read(match_bin)
|
||||
%SetField{field: field}
|
||||
%SetField{field: [field]}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -800,8 +800,8 @@ defmodule Openflow.EnumGen do
|
|||
nicira_ext_action: [
|
||||
{Openflow.Action.NxResubmit, 1},
|
||||
{Openflow.Action.NxSetTunnel, 2},
|
||||
{Openflow.Action.NxSetQueue, 4},
|
||||
{Openflow.Action.NxPopQueue, 5},
|
||||
# {Openflow.Action.NxSetQueue, 4}, Deprecated
|
||||
# {Openflow.Action.NxPopQueue, 5}, Deprecated
|
||||
{Openflow.Action.NxRegMove, 6},
|
||||
{Openflow.Action.NxRegLoad, 7},
|
||||
{Openflow.Action.NxNote, 8},
|
||||
|
|
@ -820,13 +820,13 @@ defmodule Openflow.EnumGen do
|
|||
{Openflow.Action.NxWriteMetadata, 22},
|
||||
{Openflow.Action.NxPushMpls, 23},
|
||||
{Openflow.Action.NxPopMpls, 24},
|
||||
{Openflow.Action.NxSetMplsTtl, 25},
|
||||
{Openflow.Action.NxDecMplsTtl, 26},
|
||||
# {Openflow.Action.NxSetMplsTtl, 25}, Deprecated
|
||||
# {Openflow.Action.NxDecMplsTtl, 26}, Deprecated
|
||||
{Openflow.Action.NxStackPush, 27},
|
||||
{Openflow.Action.NxStackPop, 28},
|
||||
{Openflow.Action.NxSample, 29},
|
||||
{Openflow.Action.NxSetMplsLabel, 30},
|
||||
{Openflow.Action.NxSetMplsTc, 31},
|
||||
# {Openflow.Action.NxSetMplsLabel, 30}, Deprecated
|
||||
# {Openflow.Action.NxSetMplsTc, 31}, Deprecated
|
||||
{Openflow.Action.NxOutputReg2, 32},
|
||||
{Openflow.Action.NxRegLoad2, 33},
|
||||
{Openflow.Action.NxConjunction, 34},
|
||||
|
|
|
|||
|
|
@ -38,11 +38,14 @@ defmodule Openflow.OnfBundleAdd do
|
|||
pad_length = Openflow.Utils.pad_length(length, 8)
|
||||
flags_int = Openflow.Enums.flags_to_int(bundle_add.flags, :bundle_flags)
|
||||
|
||||
<<@experimenter::32, @onf_type::32, bundle_id::32, 0::2-unit(8),
|
||||
flags_int::16, message_bin::bytes, 0::size(pad_length)-unit(8)>>
|
||||
<<@experimenter::32, @onf_type::32, bundle_id::32, 0::2-unit(8), flags_int::16,
|
||||
message_bin::bytes, 0::size(pad_length)-unit(8)>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @onf_type::32, bundle_id::32, _pad::16, flags_int::16, message_bin::bytes>>) do
|
||||
def read(
|
||||
<<@experimenter::32, @onf_type::32, bundle_id::32, _pad::16, flags_int::16,
|
||||
message_bin::bytes>>
|
||||
) do
|
||||
message = Openflow.read(message_bin)
|
||||
flags = Openflow.Enums.int_to_flags(flags_int, :bundle_flags)
|
||||
%OnfBundleAdd{bundle_id: bundle_id, flags: flags, message: message}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,13 @@ defmodule Tres.MessageHelper do
|
|||
send_message(flow_mod, datapath_id, Keyword.get(options, :blocking, false))
|
||||
|
||||
bundle_id when is_integer(bundle_id) ->
|
||||
bundle = Openflow.OnfBundleAdd.new(bundle_id: bundle_id, flags: options[:bundle_flags] || [], message: flow_mod)
|
||||
bundle =
|
||||
Openflow.OnfBundleAdd.new(
|
||||
bundle_id: bundle_id,
|
||||
flags: options[:bundle_flags] || [],
|
||||
message: flow_mod
|
||||
)
|
||||
|
||||
send_message(bundle, datapath_id, Keyword.get(options, :blocking, false))
|
||||
end
|
||||
end
|
||||
|
|
@ -48,7 +54,13 @@ defmodule Tres.MessageHelper do
|
|||
send_message(flow_mod, datapath_id, Keyword.get(options, :blocking, false))
|
||||
|
||||
bundle_id when is_integer(bundle_id) ->
|
||||
bundle = Openflow.OnfBundleAdd.new(bundle_id: bundle_id, flags: options[:bundle_flags] || [], message: flow_mod)
|
||||
bundle =
|
||||
Openflow.OnfBundleAdd.new(
|
||||
bundle_id: bundle_id,
|
||||
flags: options[:bundle_flags] || [],
|
||||
message: flow_mod
|
||||
)
|
||||
|
||||
send_message(bundle, datapath_id, Keyword.get(options, :blocking, false))
|
||||
end
|
||||
end
|
||||
|
|
@ -72,7 +84,13 @@ defmodule Tres.MessageHelper do
|
|||
send_message(flow_mod, datapath_id, Keyword.get(options, :blocking, false))
|
||||
|
||||
bundle_id when is_integer(bundle_id) ->
|
||||
bundle = Openflow.OnfBundleAdd.new(bundle_id: bundle_id, flags: options[:bundle_flags] || [], message: flow_mod)
|
||||
bundle =
|
||||
Openflow.OnfBundleAdd.new(
|
||||
bundle_id: bundle_id,
|
||||
flags: options[:bundle_flags] || [],
|
||||
message: flow_mod
|
||||
)
|
||||
|
||||
send_message(bundle, datapath_id, Keyword.get(options, :blocking, false))
|
||||
end
|
||||
end
|
||||
|
|
@ -127,7 +145,13 @@ defmodule Tres.MessageHelper do
|
|||
send_message(packet_out, datapath_id, Keyword.get(options, :blocking, false))
|
||||
|
||||
bundle_id when is_integer(bundle_id) ->
|
||||
bundle = Openflow.OnfBundleAdd.new(bundle_id: bundle_id, flags: options[:bundle_flags], message: packet_out)
|
||||
bundle =
|
||||
Openflow.OnfBundleAdd.new(
|
||||
bundle_id: bundle_id,
|
||||
flags: options[:bundle_flags],
|
||||
message: packet_out
|
||||
)
|
||||
|
||||
send_message(bundle, datapath_id, Keyword.get(options, :blocking, false))
|
||||
end
|
||||
end
|
||||
|
|
@ -147,7 +171,13 @@ defmodule Tres.MessageHelper do
|
|||
send_message(group_mod, datapath_id, Keyword.get(options, :blocking, false))
|
||||
|
||||
bundle_id when is_integer(bundle_id) ->
|
||||
bundle = Openflow.OnfBundleAdd.new(bundle_id: bundle_id, flags: options[:bundle_flags] || [], message: group_mod)
|
||||
bundle =
|
||||
Openflow.OnfBundleAdd.new(
|
||||
bundle_id: bundle_id,
|
||||
flags: options[:bundle_flags] || [],
|
||||
message: group_mod
|
||||
)
|
||||
|
||||
send_message(bundle, datapath_id, Keyword.get(options, :blocking, false))
|
||||
end
|
||||
end
|
||||
|
|
@ -165,7 +195,13 @@ defmodule Tres.MessageHelper do
|
|||
send_message(group_mod, datapath_id, Keyword.get(options, :blocking, false))
|
||||
|
||||
bundle_id when is_integer(bundle_id) ->
|
||||
bundle = Openflow.OnfBundleAdd.new(bundle_id: bundle_id, flags: options[:bundle_flags] || [], message: group_mod)
|
||||
bundle =
|
||||
Openflow.OnfBundleAdd.new(
|
||||
bundle_id: bundle_id,
|
||||
flags: options[:bundle_flags] || [],
|
||||
message: group_mod
|
||||
)
|
||||
|
||||
send_message(bundle, datapath_id, Keyword.get(options, :blocking, false))
|
||||
end
|
||||
end
|
||||
|
|
@ -185,7 +221,13 @@ defmodule Tres.MessageHelper do
|
|||
send_message(group_mod, datapath_id, Keyword.get(options, :blocking, false))
|
||||
|
||||
bundle_id when is_integer(bundle_id) ->
|
||||
bundle = Openflow.OnfBundleAdd.new(bundle_id: bundle_id, flags: options[:bundle_flags] || [], message: group_mod)
|
||||
bundle =
|
||||
Openflow.OnfBundleAdd.new(
|
||||
bundle_id: bundle_id,
|
||||
flags: options[:bundle_flags] || [],
|
||||
message: group_mod
|
||||
)
|
||||
|
||||
send_message(bundle, datapath_id, Keyword.get(options, :blocking, false))
|
||||
end
|
||||
end
|
||||
|
|
@ -246,25 +288,25 @@ defmodule Tres.MessageHelper do
|
|||
# ONF Bundle Control
|
||||
|
||||
defp onf_bundle_open(datapath_id, options \\ []) do
|
||||
options2 = Keyword.merge(options, [type: :open_request])
|
||||
options2 = Keyword.merge(options, type: :open_request)
|
||||
bundle = Openflow.OnfBundleControl.new(options2)
|
||||
send_message(bundle, datapath_id)
|
||||
end
|
||||
|
||||
defp onf_bundle_close(datapath_id, options) do
|
||||
options2 = Keyword.merge(options, [type: :close_request])
|
||||
options2 = Keyword.merge(options, type: :close_request)
|
||||
bundle = Openflow.OnfBundleControl.new(options2)
|
||||
send_message(bundle, datapath_id)
|
||||
end
|
||||
|
||||
defp onf_bundle_commit(datapath_id, options) do
|
||||
options2 = Keyword.merge(options, [type: :commit_request])
|
||||
options2 = Keyword.merge(options, type: :commit_request)
|
||||
bundle = Openflow.OnfBundleControl.new(options2)
|
||||
send_message(bundle, datapath_id)
|
||||
end
|
||||
|
||||
defp onf_bundle_discard(datapath_id, options) do
|
||||
options2 = Keyword.merge(options, [type: :discard_request])
|
||||
options2 = Keyword.merge(options, type: :discard_request)
|
||||
bundle = Openflow.OnfBundleControl.new(options2)
|
||||
send_message(bundle, datapath_id)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ defmodule OfpActionTest do
|
|||
use ExUnit.Case
|
||||
doctest Openflow
|
||||
|
||||
test "Openflow.Action.NxBundle" do
|
||||
describe "Openflow.Action.NxBundle" do
|
||||
test "with a binary" do
|
||||
test_file = "test/packet_data/nx_bundle.raw"
|
||||
packet = File.read!(test_file)
|
||||
actions = Openflow.Action.read(packet)
|
||||
|
|
@ -17,8 +18,10 @@ defmodule OfpActionTest do
|
|||
assert actions_bin == packet
|
||||
assert actions == [bundle]
|
||||
end
|
||||
end
|
||||
|
||||
test "Openflow.Action.NxBundleLoad" do
|
||||
describe "Openflow.Action.NxBundleLoad" do
|
||||
test "with a binary" do
|
||||
test_file = "test/packet_data/nx_bundle_load.raw"
|
||||
packet = File.read!(test_file)
|
||||
actions = Openflow.Action.read(packet)
|
||||
|
|
@ -35,6 +38,13 @@ defmodule OfpActionTest do
|
|||
assert actions == [bundle_load]
|
||||
end
|
||||
|
||||
test "with no option" do
|
||||
assert_raise RuntimeError, "dst_field must be specified", fn ->
|
||||
Openflow.Action.NxBundleLoad.new([])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test "Openflow.Action.NxController" do
|
||||
test_file = "test/packet_data/nx_controller.raw"
|
||||
packet = File.read!(test_file)
|
||||
|
|
@ -52,7 +62,8 @@ defmodule OfpActionTest do
|
|||
assert actions == [controller]
|
||||
end
|
||||
|
||||
test "Openflow.Action.NxController2" do
|
||||
describe "Openflow.Action.NxController2" do
|
||||
test "with packet data" do
|
||||
test_file = "test/packet_data/nx_controller2.raw"
|
||||
packet = File.read!(test_file)
|
||||
actions = Openflow.Action.read(packet)
|
||||
|
|
@ -60,12 +71,21 @@ defmodule OfpActionTest do
|
|||
controller2 =
|
||||
Openflow.Action.NxController2.new(
|
||||
max_len: 1234,
|
||||
id: 5678,
|
||||
reason: :invalid_ttl,
|
||||
userdata: <<1, 2, 3, 4, 5>>,
|
||||
pause: true
|
||||
)
|
||||
|
||||
assert actions == [controller2]
|
||||
|
||||
controller2
|
||||
|> Openflow.Action.NxController2.to_binary()
|
||||
|> Openflow.Action.read()
|
||||
|> Enum.at(0)
|
||||
|> Kernel.==(controller2)
|
||||
|> assert()
|
||||
end
|
||||
end
|
||||
|
||||
describe "Openflow.Action.NxConntrack" do
|
||||
|
|
@ -412,7 +432,9 @@ defmodule OfpActionTest do
|
|||
assert actions_bin == packet
|
||||
assert actions == [ct]
|
||||
end
|
||||
end
|
||||
|
||||
describe "Openflow.Action.NxCtClear" do
|
||||
test "with ct_clear" do
|
||||
test_file = "test/packet_data/nx_ct_clear.raw"
|
||||
packet = File.read!(test_file)
|
||||
|
|
@ -422,7 +444,9 @@ defmodule OfpActionTest do
|
|||
assert actions_bin == packet
|
||||
assert actions == [ct]
|
||||
end
|
||||
end
|
||||
|
||||
describe "Openflow.Action.NxDecTtl" do
|
||||
test "with dec_ttl" do
|
||||
test_file = "test/packet_data/nx_dec_ttl.raw"
|
||||
packet = File.read!(test_file)
|
||||
|
|
@ -432,7 +456,9 @@ defmodule OfpActionTest do
|
|||
assert actions_bin == packet
|
||||
assert actions == [dec_ttl]
|
||||
end
|
||||
end
|
||||
|
||||
describe "Openflow.Action.NxDecTtlCntIds" do
|
||||
test "with dec_ttl_cnt_ids" do
|
||||
test_file = "test/packet_data/nx_dec_ttl_cnt_ids.raw"
|
||||
packet = File.read!(test_file)
|
||||
|
|
@ -442,7 +468,9 @@ defmodule OfpActionTest do
|
|||
assert actions_bin == packet
|
||||
assert actions == [dec_ttl]
|
||||
end
|
||||
end
|
||||
|
||||
describe "Openflow.Action.NxExit" do
|
||||
test "with exit" do
|
||||
test_file = "test/packet_data/nx_exit.raw"
|
||||
packet = File.read!(test_file)
|
||||
|
|
@ -452,7 +480,9 @@ defmodule OfpActionTest do
|
|||
assert actions_bin == packet
|
||||
assert actions == [exit]
|
||||
end
|
||||
end
|
||||
|
||||
describe "Openflow.Action.NxFinTimeout" do
|
||||
test "with fin_timeout" do
|
||||
test_file = "test/packet_data/nx_fin_timeout.raw"
|
||||
packet = File.read!(test_file)
|
||||
|
|
@ -462,7 +492,9 @@ defmodule OfpActionTest do
|
|||
assert actions_bin == packet
|
||||
assert actions == [fin_timeout]
|
||||
end
|
||||
end
|
||||
|
||||
describe "Openflow.Action.NxLearn" do
|
||||
test "with learn" do
|
||||
test_file = "test/packet_data/nx_learn.raw"
|
||||
packet = File.read!(test_file)
|
||||
|
|
@ -489,7 +521,9 @@ defmodule OfpActionTest do
|
|||
assert actions_bin == packet
|
||||
assert actions == [learn]
|
||||
end
|
||||
end
|
||||
|
||||
describe "Openflow.Action.NxLearn2" do
|
||||
test "with learn2" do
|
||||
test_file = "test/packet_data/nx_learn2.raw"
|
||||
packet = File.read!(test_file)
|
||||
|
|
@ -519,7 +553,9 @@ defmodule OfpActionTest do
|
|||
assert actions_bin == packet
|
||||
assert actions == [learn2]
|
||||
end
|
||||
end
|
||||
|
||||
describe "Openflow.Action.NxMultipath" do
|
||||
test "with multipath" do
|
||||
test_file = "test/packet_data/nx_multipath.raw"
|
||||
packet = File.read!(test_file)
|
||||
|
|
@ -536,8 +572,10 @@ defmodule OfpActionTest do
|
|||
assert actions_bin == packet
|
||||
assert actions == [multipath]
|
||||
end
|
||||
end
|
||||
|
||||
test "with note" do
|
||||
describe "Openflow.Action.NxNote" do
|
||||
test "with note binary" do
|
||||
test_file = "test/packet_data/nx_note.raw"
|
||||
packet = File.read!(test_file)
|
||||
actions = Openflow.Action.read(packet)
|
||||
|
|
@ -546,8 +584,10 @@ defmodule OfpActionTest do
|
|||
assert actions_bin == packet
|
||||
assert actions == [note]
|
||||
end
|
||||
end
|
||||
|
||||
test "with output_reg" do
|
||||
describe "Openflow.Action.NxOutputReg" do
|
||||
test "with output_reg options src_field = reg1, n_bits = 6, offset = 5" do
|
||||
test_file = "test/packet_data/nx_output_reg.raw"
|
||||
packet = File.read!(test_file)
|
||||
actions = Openflow.Action.read(packet)
|
||||
|
|
@ -556,28 +596,35 @@ defmodule OfpActionTest do
|
|||
assert actions_bin == packet
|
||||
assert actions == [output_reg]
|
||||
end
|
||||
end
|
||||
|
||||
test "with output_trunc" do
|
||||
describe "Openflow.Action.NxOutputReg2" do
|
||||
test "with output_reg options src_field = reg1, n_bits = 6, offset = 5" do
|
||||
output_reg = Openflow.Action.NxOutputReg2.new(src_field: :reg1, n_bits: 6, offset: 5)
|
||||
|
||||
output_reg
|
||||
|> Openflow.Action.to_binary()
|
||||
|> Openflow.Action.read()
|
||||
|> Enum.at(0)
|
||||
|> Kernel.==(output_reg)
|
||||
|> assert()
|
||||
end
|
||||
end
|
||||
|
||||
describe "Openflow.Action.NxOutputTrunc" do
|
||||
test "with output_trunc options: packets output to port1 trunc in 100bytes" do
|
||||
test_file = "test/packet_data/nx_output_trunc.raw"
|
||||
packet = File.read!(test_file)
|
||||
actions = Openflow.Action.read(packet)
|
||||
output_trunc = Openflow.Action.NxOutputTrunc.new(port_number: 1, max_len: 100)
|
||||
output_trunc = Openflow.Action.NxOutputTrunc.new(port_no: 1, max_len: 100)
|
||||
actions_bin = Openflow.Action.to_binary(output_trunc)
|
||||
assert actions_bin == packet
|
||||
assert actions == [output_trunc]
|
||||
end
|
||||
|
||||
test "with pop_queue" do
|
||||
test_file = "test/packet_data/nx_pop_queue.raw"
|
||||
packet = File.read!(test_file)
|
||||
actions = Openflow.Action.read(packet)
|
||||
pop_queue = Openflow.Action.NxPopQueue.new()
|
||||
actions_bin = Openflow.Action.to_binary(pop_queue)
|
||||
assert actions_bin == packet
|
||||
assert actions == [pop_queue]
|
||||
end
|
||||
|
||||
test "with reg_load" do
|
||||
describe "Openflow.Action.NxRegLoad" do
|
||||
test "with options: load 0xf008 to vlan_tci" do
|
||||
test_file = "test/packet_data/nx_reg_load.raw"
|
||||
packet = File.read!(test_file)
|
||||
actions = Openflow.Action.read(packet)
|
||||
|
|
@ -586,8 +633,10 @@ defmodule OfpActionTest do
|
|||
assert actions_bin == packet
|
||||
assert actions == [reg_load]
|
||||
end
|
||||
end
|
||||
|
||||
test "with reg_move" do
|
||||
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"
|
||||
packet = File.read!(test_file)
|
||||
actions = Openflow.Action.read(packet)
|
||||
|
|
@ -596,17 +645,21 @@ defmodule OfpActionTest do
|
|||
assert actions_bin == packet
|
||||
assert actions == [reg_move]
|
||||
end
|
||||
end
|
||||
|
||||
test "with resubmit" do
|
||||
describe "Openflow.Action.NxResubmit" do
|
||||
test "with options: resubmit to table, search with the port_no" do
|
||||
test_file = "test/packet_data/nx_resubmit.raw"
|
||||
packet = File.read!(test_file)
|
||||
actions = Openflow.Action.read(packet)
|
||||
resubmit = Openflow.Action.NxResubmit.new(5)
|
||||
resubmit = Openflow.Action.NxResubmit.new(_port_no = 5)
|
||||
actions_bin = Openflow.Action.to_binary(resubmit)
|
||||
assert actions_bin == packet
|
||||
assert actions == [resubmit]
|
||||
end
|
||||
end
|
||||
|
||||
describe "Openflow.Action.NxResubmitTable" do
|
||||
test "with resubmit_table" do
|
||||
test_file = "test/packet_data/nx_resubmit_table.raw"
|
||||
packet = File.read!(test_file)
|
||||
|
|
@ -616,7 +669,9 @@ defmodule OfpActionTest do
|
|||
assert actions_bin == packet
|
||||
assert actions == [resubmit_table]
|
||||
end
|
||||
end
|
||||
|
||||
describe "Openflow.Action.NxResubmitTableCt" do
|
||||
test "with resubmit_table_ct" do
|
||||
test_file = "test/packet_data/nx_resubmit_table_ct.raw"
|
||||
packet = File.read!(test_file)
|
||||
|
|
@ -626,7 +681,9 @@ defmodule OfpActionTest do
|
|||
assert actions_bin == packet
|
||||
assert actions == [resubmit_table_ct]
|
||||
end
|
||||
end
|
||||
|
||||
describe "Openflow.Action.NxClone" do
|
||||
test "with clone(push_vlan:0x8100,set_field:5->vlan_vid,output:10)" do
|
||||
test_file = "test/packet_data/nx_clone.raw"
|
||||
packet = File.read!(test_file)
|
||||
|
|
@ -635,7 +692,7 @@ defmodule OfpActionTest do
|
|||
clone =
|
||||
Openflow.Action.NxClone.new([
|
||||
Openflow.Action.PushVlan.new(),
|
||||
Openflow.Action.SetField.new({:vlan_vid, 5}),
|
||||
Openflow.Action.SetField.new(vlan_vid: 5),
|
||||
Openflow.Action.Output.new(10)
|
||||
])
|
||||
|
||||
|
|
@ -644,4 +701,143 @@ defmodule OfpActionTest do
|
|||
assert actions == [clone]
|
||||
end
|
||||
end
|
||||
|
||||
describe "Openflow.Action.NxRegLoad2" do
|
||||
test "with set_field:0x1/0x1->reg1" do
|
||||
reg_load2 = Openflow.Action.NxRegLoad2.new(reg1: {1, 1})
|
||||
|
||||
reg_load2
|
||||
|> Openflow.Action.to_binary()
|
||||
|> Openflow.Action.read()
|
||||
|> Enum.at(0)
|
||||
|> Kernel.==(reg_load2)
|
||||
|> assert()
|
||||
end
|
||||
|
||||
test "with set_field:0x1->reg1" do
|
||||
reg_load2 = Openflow.Action.NxRegLoad2.new(reg1: 1)
|
||||
|
||||
reg_load2
|
||||
|> Openflow.Action.to_binary()
|
||||
|> Openflow.Action.read()
|
||||
|> Enum.at(0)
|
||||
|> Kernel.==(reg_load2)
|
||||
|> assert()
|
||||
end
|
||||
end
|
||||
|
||||
describe "Openflow.Action.NxStackPop" do
|
||||
test "with pop:NXM_NX_REG0[]" do
|
||||
pop = Openflow.Action.NxStackPop.new(field: :reg0)
|
||||
|
||||
assert pop.n_bits == 32
|
||||
assert pop.offset == 0
|
||||
|
||||
pop
|
||||
|> Openflow.Action.to_binary()
|
||||
|> Openflow.Action.read()
|
||||
|> Enum.at(0)
|
||||
|> Kernel.==(pop)
|
||||
|> assert()
|
||||
end
|
||||
|
||||
test "with pop:NXM_NX_REG0[1..31]" do
|
||||
pop = Openflow.Action.NxStackPop.new(field: :reg0, offset: 1, n_bits: 31)
|
||||
|
||||
assert pop.n_bits == 31
|
||||
assert pop.offset == 1
|
||||
|
||||
pop
|
||||
|> Openflow.Action.to_binary()
|
||||
|> Openflow.Action.read()
|
||||
|> Enum.at(0)
|
||||
|> Kernel.==(pop)
|
||||
|> assert()
|
||||
end
|
||||
end
|
||||
|
||||
describe "Openflow.Action.NxSetTunnel" do
|
||||
test "with set_tunnel:0x1" do
|
||||
set_tunnel = Openflow.Action.NxSetTunnel.new(1)
|
||||
|
||||
set_tunnel
|
||||
|> Openflow.Action.to_binary()
|
||||
|> Openflow.Action.read()
|
||||
|> Enum.at(0)
|
||||
|> Kernel.==(set_tunnel)
|
||||
|> assert()
|
||||
end
|
||||
end
|
||||
|
||||
describe "Openflow.Action.NxSetTunnel64" do
|
||||
test "with set_tunnel64:0x1" do
|
||||
set_tunnel = Openflow.Action.NxSetTunnel64.new(1)
|
||||
|
||||
set_tunnel
|
||||
|> Openflow.Action.to_binary()
|
||||
|> Openflow.Action.read()
|
||||
|> Enum.at(0)
|
||||
|> Kernel.==(set_tunnel)
|
||||
|> assert()
|
||||
end
|
||||
end
|
||||
|
||||
describe "Openflow.Action.NxWriteMetadata" do
|
||||
test "with write_metadata:0x1" do
|
||||
write_metadata = Openflow.Action.NxWriteMetadata.new(1)
|
||||
|
||||
write_metadata
|
||||
|> Openflow.Action.to_binary()
|
||||
|> Openflow.Action.read()
|
||||
|> Enum.at(0)
|
||||
|> Kernel.==(write_metadata)
|
||||
|> assert()
|
||||
end
|
||||
|
||||
test "with write_metadata:0x1/0x1" do
|
||||
write_metadata = Openflow.Action.NxWriteMetadata.new(metadata: 0x1, metadata_mask: 0x1)
|
||||
|
||||
write_metadata
|
||||
|> Openflow.Action.to_binary()
|
||||
|> Openflow.Action.read()
|
||||
|> Enum.at(0)
|
||||
|> Kernel.==(write_metadata)
|
||||
|> assert()
|
||||
end
|
||||
|
||||
test "with no options" do
|
||||
assert_raise RuntimeError, "metadata must be specified", fn ->
|
||||
Openflow.Action.NxWriteMetadata.new()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "Openflow.Action.NxConjunction" do
|
||||
test "with conjunction(0,1/2)" do
|
||||
conjunction = Openflow.Action.NxConjunction.new(clause: 0, n_clauses: 2)
|
||||
|
||||
assert conjunction.id == 0
|
||||
assert conjunction.clause == 1
|
||||
assert conjunction.n_clauses == 2
|
||||
|
||||
conjunction
|
||||
|> Openflow.Action.to_binary()
|
||||
|> Openflow.Action.read()
|
||||
|> Enum.at(0)
|
||||
|> Kernel.==(conjunction)
|
||||
|> assert()
|
||||
end
|
||||
end
|
||||
|
||||
test "with no n_clauses option" do
|
||||
assert_raise RuntimeError, "n_clauses must be specified", fn ->
|
||||
Openflow.Action.NxConjunction.new(id: 1, clause: 0)
|
||||
end
|
||||
end
|
||||
|
||||
test "with n_clauses option less than 2" do
|
||||
assert_raise RuntimeError, "n_clauses must be greater than 1", fn ->
|
||||
Openflow.Action.NxConjunction.new(id: 1, clause: 0, n_clauses: 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ defmodule OfpFlowModTest do
|
|||
|
||||
assert fm.instructions == [
|
||||
Openflow.Instruction.WriteActions.new([
|
||||
Openflow.Action.SetField.new({:vlan_vid, 258}),
|
||||
Openflow.Action.SetField.new(vlan_vid: 258),
|
||||
Openflow.Action.CopyTtlOut.new(),
|
||||
Openflow.Action.CopyTtlIn.new(),
|
||||
Openflow.Action.CopyTtlIn.new(),
|
||||
|
|
@ -51,8 +51,8 @@ defmodule OfpFlowModTest do
|
|||
Openflow.Action.Output.new(6)
|
||||
]),
|
||||
Openflow.Instruction.ApplyActions.new([
|
||||
Openflow.Action.SetField.new({:eth_src, "010203040506"}),
|
||||
Openflow.Action.SetField.new({:onf_pbb_uca, 1})
|
||||
Openflow.Action.SetField.new(eth_src: "010203040506"),
|
||||
Openflow.Action.SetField.new(onf_pbb_uca: 1)
|
||||
])
|
||||
]
|
||||
|
||||
|
|
@ -202,7 +202,7 @@ defmodule OfpFlowModTest do
|
|||
assert fm.instructions == [
|
||||
Openflow.Instruction.ApplyActions.new([
|
||||
Openflow.Action.PopVlan.new(),
|
||||
Openflow.Action.SetField.new({:ipv4_dst, {192, 168, 2, 9}}),
|
||||
Openflow.Action.SetField.new(ipv4_dst: {192, 168, 2, 9}),
|
||||
Openflow.Action.NxLearn.new(
|
||||
hard_timeout: 300,
|
||||
priority: 1,
|
||||
|
|
@ -263,7 +263,7 @@ defmodule OfpFlowModTest do
|
|||
|
||||
assert fm.instructions == [
|
||||
Openflow.Instruction.ApplyActions.new([
|
||||
Openflow.Action.NxConjunction.new(clause: 1, id: 0xABCDEF, n_clauses: 2)
|
||||
Openflow.Action.NxConjunction.new(clause: 0, id: 0xABCDEF, n_clauses: 2)
|
||||
])
|
||||
]
|
||||
|
||||
|
|
@ -290,7 +290,7 @@ defmodule OfpFlowModTest do
|
|||
assert fm.instructions == [
|
||||
Openflow.Instruction.ApplyActions.new([
|
||||
Openflow.Action.PopVlan.new(),
|
||||
Openflow.Action.SetField.new({:ipv4_dst, {192, 168, 2, 9}})
|
||||
Openflow.Action.SetField.new(ipv4_dst: {192, 168, 2, 9})
|
||||
]),
|
||||
Openflow.Instruction.GotoTable.new(100)
|
||||
]
|
||||
|
|
|
|||
BIN
test/packet_data/nx_reg_load2.raw
Normal file
BIN
test/packet_data/nx_reg_load2.raw
Normal file
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue