Formatted
This commit is contained in:
parent
5fc01a9bec
commit
7635272fbd
150 changed files with 5055 additions and 4032 deletions
|
|
@ -5,7 +5,7 @@ defmodule Openflow.Action.Experimenter do
|
|||
|
||||
@experimter_size 8
|
||||
|
||||
def ofpat, do: 0xffff
|
||||
def ofpat, do: 0xFFFF
|
||||
|
||||
def new(exp_id, data \\ "") do
|
||||
%Experimenter{exp_id: exp_id, data: data}
|
||||
|
|
@ -13,17 +13,19 @@ defmodule Openflow.Action.Experimenter do
|
|||
|
||||
def to_binary(%Experimenter{exp_id: exp_id, data: data}) do
|
||||
length = @experimter_size + byte_size(data)
|
||||
<<0xffff::16, length::16, exp_id::32, data::bytes>>
|
||||
<<0xFFFF::16, length::16, exp_id::32, data::bytes>>
|
||||
end
|
||||
|
||||
def read(<<0xffff::16, _length::16, exp_id::32, exp_type::16, data::bytes>>) do
|
||||
def read(<<0xFFFF::16, _length::16, exp_id::32, exp_type::16, data::bytes>>) do
|
||||
case Openflow.Utils.get_enum(exp_id, :action_vendor) do
|
||||
vendor_id when is_integer(vendor_id) ->
|
||||
%Experimenter{exp_id: exp_id, data: <<exp_type::16, data::bytes>>}
|
||||
|
||||
vendor when is_atom(vendor) ->
|
||||
case Openflow.Utils.get_enum(exp_type, vendor) do
|
||||
codec when is_atom(codec) ->
|
||||
codec.read(<<exp_id::32, exp_type::16, data::bytes>>)
|
||||
|
||||
exp_type when is_integer(exp_type) ->
|
||||
%Experimenter{exp_id: exp_id, data: <<exp_type::16, data::bytes>>}
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
defmodule Openflow.Action.NxBundle do
|
||||
defstruct(
|
||||
algorithm: :active_backup,
|
||||
algorithm: :active_backup,
|
||||
hash_field: :eth_src,
|
||||
basis: 0,
|
||||
basis: 0,
|
||||
slave_type: :nx_in_port,
|
||||
n_slaves: 0,
|
||||
slaves: []
|
||||
n_slaves: 0,
|
||||
slaves: []
|
||||
)
|
||||
|
||||
@experimenter 0x00002320
|
||||
|
|
@ -15,36 +15,44 @@ defmodule Openflow.Action.NxBundle do
|
|||
|
||||
def new(options) do
|
||||
slaves = options[:slaves] || []
|
||||
%NxBundle{algorithm: options[:algorithm] || :active_backup,
|
||||
hash_field: options[:hash_field] || :eth_src,
|
||||
basis: options[:basis] || 0,
|
||||
n_slaves: length(slaves),
|
||||
slaves: slaves}
|
||||
|
||||
%NxBundle{
|
||||
algorithm: options[:algorithm] || :active_backup,
|
||||
hash_field: options[:hash_field] || :eth_src,
|
||||
basis: options[:basis] || 0,
|
||||
n_slaves: length(slaves),
|
||||
slaves: slaves
|
||||
}
|
||||
end
|
||||
|
||||
def to_binary(%NxBundle{algorithm: alg,
|
||||
hash_field: hash_field,
|
||||
basis: basis,
|
||||
slave_type: slave_type,
|
||||
n_slaves: n_slaves,
|
||||
slaves: slaves}) do
|
||||
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)
|
||||
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>>
|
||||
|
||||
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)
|
||||
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)>>
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, body::bytes>>) do
|
||||
<<alg_int::16, hash_field_int::16, basis::16,
|
||||
slave_type_bin::4-bytes, n_slaves::16, _::16, _::32, _::32, rest::bytes>> = body
|
||||
<<alg_int::16, hash_field_int::16, basis::16, slave_type_bin::4-bytes, n_slaves::16, _::16,
|
||||
_::32, _::32, rest::bytes>> = body
|
||||
|
||||
slave_len = n_slaves * 2
|
||||
<<slaves_bin::size(slave_len)-bytes, _::bytes>> = rest
|
||||
alg = Openflow.Enums.to_atom(alg_int, :nx_bd_algorithm)
|
||||
|
|
@ -52,23 +60,29 @@ defmodule Openflow.Action.NxBundle do
|
|||
slave_type = Openflow.Match.codec_header(slave_type_bin)
|
||||
slaves = codec_slaves(slaves_bin)
|
||||
n_slaves = length(slaves)
|
||||
%NxBundle{algorithm: alg,
|
||||
hash_field: hash_field,
|
||||
basis: basis,
|
||||
slave_type: slave_type,
|
||||
n_slaves: n_slaves,
|
||||
slaves: slaves}
|
||||
|
||||
%NxBundle{
|
||||
algorithm: alg,
|
||||
hash_field: hash_field,
|
||||
basis: basis,
|
||||
slave_type: slave_type,
|
||||
n_slaves: n_slaves,
|
||||
slaves: slaves
|
||||
}
|
||||
end
|
||||
|
||||
# private functions
|
||||
|
||||
defp codec_slaves(slaves) when is_list(slaves) do
|
||||
slaves1 = for slave <- slaves do
|
||||
slave_int = Openflow.Utils.get_enum(slave, :openflow10_port_no)
|
||||
<<slave_int::16>>
|
||||
end
|
||||
slaves1 =
|
||||
for slave <- slaves do
|
||||
slave_int = Openflow.Utils.get_enum(slave, :openflow10_port_no)
|
||||
<<slave_int::16>>
|
||||
end
|
||||
|
||||
Enum.join(slaves1, "")
|
||||
end
|
||||
|
||||
defp codec_slaves(slaves) when is_binary(slaves) do
|
||||
for <<slave_int::16 <- slaves>> do
|
||||
Openflow.Utils.get_enum(slave_int, :openflow10_port_no)
|
||||
|
|
|
|||
|
|
@ -2,15 +2,15 @@ defmodule Openflow.Action.NxBundleLoad do
|
|||
import Bitwise
|
||||
|
||||
defstruct(
|
||||
algorithm: :active_backup,
|
||||
algorithm: :active_backup,
|
||||
hash_field: :eth_src,
|
||||
basis: 0,
|
||||
basis: 0,
|
||||
slave_type: :nx_in_port,
|
||||
n_slaves: 0,
|
||||
slaves: [],
|
||||
offset: 0,
|
||||
n_bits: 0,
|
||||
dst_field: nil
|
||||
n_slaves: 0,
|
||||
slaves: [],
|
||||
offset: 0,
|
||||
n_bits: 0,
|
||||
dst_field: nil
|
||||
)
|
||||
|
||||
@experimenter 0x00002320
|
||||
|
|
@ -22,45 +22,52 @@ defmodule Openflow.Action.NxBundleLoad do
|
|||
dst_field = options[:dst_field]
|
||||
default_n_bits = Openflow.Match.Field.n_bits_of(dst_field)
|
||||
slaves = options[:slaves] || []
|
||||
%NxBundleLoad{algorithm: options[:algorithm] || :active_backup,
|
||||
hash_field: options[:hash_field] || :eth_src,
|
||||
basis: options[:basis] || 0,
|
||||
n_slaves: length(slaves),
|
||||
slaves: slaves,
|
||||
offset: options[:offset] || 0,
|
||||
n_bits: options[:n_bits] || default_n_bits,
|
||||
dst_field: options[:dst_field]}
|
||||
|
||||
%NxBundleLoad{
|
||||
algorithm: options[:algorithm] || :active_backup,
|
||||
hash_field: options[:hash_field] || :eth_src,
|
||||
basis: options[:basis] || 0,
|
||||
n_slaves: length(slaves),
|
||||
slaves: slaves,
|
||||
offset: options[:offset] || 0,
|
||||
n_bits: options[:n_bits] || default_n_bits,
|
||||
dst_field: options[:dst_field]
|
||||
}
|
||||
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
|
||||
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)
|
||||
ofs_nbits = ofs <<< 6 ||| n_bits - 1
|
||||
dst_field_bin = Openflow.Match.codec_header(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>>
|
||||
|
||||
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)
|
||||
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)>>
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, body::bytes>>) do
|
||||
<<alg_int::16, hash_field_int::16, basis::16,
|
||||
slave_type_bin::4-bytes, n_slaves::16, ofs::10, n_bits::6,
|
||||
dst_field_bin::4-bytes, _reserved::32, rest::bytes>> = body
|
||||
<<alg_int::16, hash_field_int::16, basis::16, slave_type_bin::4-bytes, n_slaves::16, ofs::10,
|
||||
n_bits::6, dst_field_bin::4-bytes, _reserved::32, rest::bytes>> = body
|
||||
|
||||
slave_len = n_slaves * 2
|
||||
<<slaves_bin::size(slave_len)-bytes, _::bytes>> = rest
|
||||
alg = Openflow.Enums.to_atom(alg_int, :nx_bd_algorithm)
|
||||
|
|
@ -69,26 +76,32 @@ defmodule Openflow.Action.NxBundleLoad do
|
|||
slaves = codec_slaves(slaves_bin)
|
||||
n_slaves = length(slaves)
|
||||
dst_field = Openflow.Match.codec_header(dst_field_bin)
|
||||
%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 + 1,
|
||||
dst_field: dst_field}
|
||||
|
||||
%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 + 1,
|
||||
dst_field: dst_field
|
||||
}
|
||||
end
|
||||
|
||||
# private functions
|
||||
|
||||
defp codec_slaves(slaves) when is_list(slaves) do
|
||||
slaves1 = for slave <- slaves do
|
||||
slave_int = Openflow.Utils.get_enum(slave, :openflow10_port_no)
|
||||
<<slave_int::16>>
|
||||
end
|
||||
slaves1 =
|
||||
for slave <- slaves do
|
||||
slave_int = Openflow.Utils.get_enum(slave, :openflow10_port_no)
|
||||
<<slave_int::16>>
|
||||
end
|
||||
|
||||
Enum.join(slaves1, "")
|
||||
end
|
||||
|
||||
defp codec_slaves(slaves) when is_binary(slaves) do
|
||||
for <<slave_int::16 <- slaves>> do
|
||||
Openflow.Utils.get_enum(slave_int, :openflow10_port_no)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
defmodule Openflow.Action.NxClone do
|
||||
defstruct(
|
||||
actions: []
|
||||
)
|
||||
defstruct(actions: [])
|
||||
|
||||
@experimenter 0x00002320
|
||||
@nxast 42
|
||||
|
|
@ -15,10 +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)
|
||||
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)>>
|
||||
<<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), actions_bin::bytes>>) do
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
defmodule Openflow.Action.NxConjunction do
|
||||
defstruct(
|
||||
clause: 0,
|
||||
clause: 0,
|
||||
n_clauses: 0,
|
||||
id: 0
|
||||
id: 0
|
||||
)
|
||||
|
||||
@experimenter 0x00002320
|
||||
|
|
@ -11,14 +11,16 @@ defmodule Openflow.Action.NxConjunction do
|
|||
alias __MODULE__
|
||||
|
||||
def new(options) do
|
||||
%NxConjunction{clause: options[:clause] || 0,
|
||||
n_clauses: options[:n_clauses] || 0,
|
||||
id: options[:id] || 0}
|
||||
%NxConjunction{
|
||||
clause: options[:clause] || 0,
|
||||
n_clauses: options[:n_clauses] || 0,
|
||||
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>>
|
||||
<<0xFFFF::16, 16::16, exp_body::bytes>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, clause::8, n_clauses::8, id::32>>) do
|
||||
|
|
|
|||
|
|
@ -2,14 +2,14 @@ defmodule Openflow.Action.NxConntrack do
|
|||
import Bitwise
|
||||
|
||||
defstruct(
|
||||
flags: [],
|
||||
zone_src: nil,
|
||||
zone_imm: 0,
|
||||
zone_offset: nil,
|
||||
zone_n_bits: nil,
|
||||
flags: [],
|
||||
zone_src: nil,
|
||||
zone_imm: 0,
|
||||
zone_offset: nil,
|
||||
zone_n_bits: nil,
|
||||
recirc_table: 255,
|
||||
alg: 0,
|
||||
exec: []
|
||||
alg: 0,
|
||||
exec: []
|
||||
)
|
||||
|
||||
@experimenter 0x00002320
|
||||
|
|
@ -18,61 +18,73 @@ defmodule Openflow.Action.NxConntrack do
|
|||
alias __MODULE__
|
||||
|
||||
def new(options \\ []) do
|
||||
%NxConntrack{flags: options[:flags] || [],
|
||||
zone_src: options[:zone_src],
|
||||
zone_imm: options[:zone_imm] || 0,
|
||||
zone_offset: options[:zone_offset],
|
||||
zone_n_bits: options[:zone_n_bits],
|
||||
recirc_table: options[:recirc_table] || 255,
|
||||
alg: options[:alg] || 0,
|
||||
exec: options[:exec] || []}
|
||||
%NxConntrack{
|
||||
flags: options[:flags] || [],
|
||||
zone_src: options[:zone_src],
|
||||
zone_imm: options[:zone_imm] || 0,
|
||||
zone_offset: options[:zone_offset],
|
||||
zone_n_bits: options[:zone_n_bits],
|
||||
recirc_table: options[:recirc_table] || 255,
|
||||
alg: options[:alg] || 0,
|
||||
exec: options[:exec] || []
|
||||
}
|
||||
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,
|
||||
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
|
||||
alg: alg,
|
||||
exec: exec
|
||||
}) do
|
||||
flags_int = Openflow.Enums.flags_to_int(flags, :nx_conntrack_flags)
|
||||
{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
|
||||
|
||||
{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)
|
||||
|
||||
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)>>
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, flags_int::16,
|
||||
src_bin::4-bytes, ofs_nbits::16-bits, recirc_table::8,
|
||||
_::size(3)-unit(8), alg::16, exec_bin::bytes>>) do
|
||||
def read(
|
||||
<<@experimenter::32, @nxast::16, flags_int::16, src_bin::4-bytes, ofs_nbits::16-bits,
|
||||
recirc_table::8, _::size(3)-unit(8), alg::16, exec_bin::bytes>>
|
||||
) do
|
||||
flags = Openflow.Enums.int_to_flags(flags_int, :nx_conntrack_flags)
|
||||
exec = Openflow.Action.read(exec_bin)
|
||||
|
||||
ct = %NxConntrack{
|
||||
flags: flags,
|
||||
flags: flags,
|
||||
recirc_table: recirc_table,
|
||||
alg: alg,
|
||||
exec: exec
|
||||
alg: alg,
|
||||
exec: exec
|
||||
}
|
||||
|
||||
case src_bin do
|
||||
<<0::32>> ->
|
||||
<<zone_imm::16>> = ofs_nbits
|
||||
%{ct|zone_imm: zone_imm}
|
||||
%{ct | zone_imm: zone_imm}
|
||||
|
||||
binary when is_binary(binary) ->
|
||||
zone_src = Openflow.Match.codec_header(binary)
|
||||
<<ofs::10, n_bits::6>> = ofs_nbits
|
||||
%{ct|zone_src: zone_src, zone_offset: ofs, zone_n_bits: n_bits + 1}
|
||||
%{ct | zone_src: zone_src, zone_offset: ofs, zone_n_bits: n_bits + 1}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -11,19 +11,27 @@ defmodule Openflow.Action.NxController do
|
|||
alias __MODULE__
|
||||
|
||||
def new(options) do
|
||||
%NxController{max_len: options[:max_len] || :no_buffer,
|
||||
id: options[:id] || 0,
|
||||
reason: options[:reason] || :action}
|
||||
%NxController{
|
||||
max_len: options[:max_len] || :no_buffer,
|
||||
id: options[:id] || 0,
|
||||
reason: options[:reason] || :action
|
||||
}
|
||||
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)
|
||||
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>>
|
||||
|
||||
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>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, max_len_int::16, controller_id::16, reason_int::8, _::bytes>>) do
|
||||
def read(
|
||||
<<@experimenter::32, @nxast::16, max_len_int::16, controller_id::16, reason_int::8,
|
||||
_::bytes>>
|
||||
) do
|
||||
max_len = Openflow.Utils.get_enum(max_len_int, :controller_max_len)
|
||||
reason = Openflow.Enums.to_atom(reason_int, :packet_in_reason)
|
||||
%NxController{max_len: max_len, id: controller_id, reason: reason}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
defmodule Openflow.Action.NxController2 do
|
||||
defstruct(
|
||||
max_len: :no_buffer,
|
||||
id: 0,
|
||||
reason: :action,
|
||||
max_len: :no_buffer,
|
||||
id: 0,
|
||||
reason: :action,
|
||||
userdata: "",
|
||||
pause: false
|
||||
pause: false
|
||||
)
|
||||
|
||||
@experimenter 0x00002320
|
||||
|
|
@ -12,20 +12,22 @@ defmodule Openflow.Action.NxController2 do
|
|||
|
||||
@prop_header_size 4
|
||||
|
||||
@prop_max_len 0
|
||||
@prop_ctl_id 1
|
||||
@prop_reason 2
|
||||
@prop_max_len 0
|
||||
@prop_ctl_id 1
|
||||
@prop_reason 2
|
||||
@prop_userdata 3
|
||||
@prop_pause 4
|
||||
@prop_pause 4
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
def new(options) do
|
||||
%NxController2{max_len: options[:max_len] || :no_buffer,
|
||||
id: options[:id] || 0,
|
||||
reason: options[:reason] || :action,
|
||||
userdata: options[:userdata],
|
||||
pause: options[:pause] || false}
|
||||
%NxController2{
|
||||
max_len: options[:max_len] || :no_buffer,
|
||||
id: options[:id] || 0,
|
||||
reason: options[:reason] || :action,
|
||||
userdata: options[:userdata],
|
||||
pause: options[:pause] || false
|
||||
}
|
||||
end
|
||||
|
||||
def to_binary(%NxController2{} = ctl) do
|
||||
|
|
@ -33,10 +35,10 @@ defmodule Openflow.Action.NxController2 do
|
|||
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)
|
||||
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>>
|
||||
<<0xFFFF::16, length::16, exp_body::bytes>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, 0::size(6)-unit(8), body::bytes>>) do
|
||||
|
|
@ -48,64 +50,88 @@ defmodule Openflow.Action.NxController2 do
|
|||
|
||||
defp get_prop_key(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)
|
||||
|> 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)
|
||||
end
|
||||
|
||||
defp encode_prop(acc, [], _ctl), do: acc
|
||||
defp encode_prop(acc, [prop|rest], ctl) do
|
||||
|
||||
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
|
||||
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)>>
|
||||
prop == :reason and value != :action ->
|
||||
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)>>
|
||||
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)>>
|
||||
true ->
|
||||
""
|
||||
end
|
||||
|
||||
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
|
||||
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)>>
|
||||
|
||||
prop == :reason and value != :action ->
|
||||
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)>>
|
||||
|
||||
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)>>
|
||||
|
||||
true ->
|
||||
""
|
||||
end
|
||||
|
||||
encode_prop(<<acc::bytes, prop_bin::bytes>>, rest, ctl)
|
||||
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
|
||||
<<@prop_max_len::16, _prop_length::16, max_len_int::16, _::size(2)-unit(8), rest::bytes>> =
|
||||
bin
|
||||
|
||||
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
|
||||
<<@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
|
||||
<<@prop_reason::16, _prop_length::16, reason_int::8, _::size(3)-unit(8), rest::bytes>> =
|
||||
bin
|
||||
|
||||
reason = Openflow.Utils.get_enum(reason_int, :packet_in_reason)
|
||||
decode_prop(struct(ctl, %{reason: reason}), rest)
|
||||
|
||||
:userdata ->
|
||||
<<@prop_userdata::16, prop_length::16, remains::bytes>> = bin
|
||||
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
|
||||
|
||||
<<userdata::size(userdata_len)-bytes, _::size(padding_length)-unit(8), rest::bytes>> =
|
||||
remains
|
||||
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ defmodule Openflow.Action.NxCtClear do
|
|||
|
||||
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>>
|
||||
<<0xFFFF::16, 16::16, exp_body::bytes>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, _::16, _::size(4)-unit(8)>>) do
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ defmodule Openflow.Action.NxDecMplsTtl do
|
|||
|
||||
def to_binary(%NxDecMplsTtl{}) do
|
||||
exp_body = <<@experimenter::32, @nxast::16, 0::size(6)-unit(8)>>
|
||||
<<0xffff::16, 16::16, exp_body::bytes>>
|
||||
<<0xFFFF::16, 16::16, exp_body::bytes>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, _::size(6)-unit(8)>>) do
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ defmodule Openflow.Action.NxDecTtl do
|
|||
|
||||
def to_binary(%NxDecTtl{}) do
|
||||
exp_body = <<@experimenter::32, @nxast::16, 0::size(6)-unit(8)>>
|
||||
<<0xffff::16, 16::16, exp_body::bytes>>
|
||||
<<0xFFFF::16, 16::16, exp_body::bytes>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, _::16, _::size(4)-unit(8)>>) do
|
||||
|
|
|
|||
|
|
@ -12,14 +12,17 @@ defmodule Openflow.Action.NxDecTtlCntIds do
|
|||
|
||||
def to_binary(%NxDecTtlCntIds{ids: ids}) do
|
||||
n_controllers = length(ids)
|
||||
ids_bin = Enum.join((for id <- ids, do: <<id::16>>), "")
|
||||
ids_bin = Enum.join(for(id <- ids, do: <<id::16>>), "")
|
||||
padding = Openflow.Utils.padding(n_controllers, 8)
|
||||
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)
|
||||
|
||||
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)>>
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, n_controllers::16, body::bitstring>>) do
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ defmodule Openflow.Action.NxExit do
|
|||
|
||||
def to_binary(%NxExit{}) do
|
||||
exp_body = <<@experimenter::32, @nxast::16, 0::48>>
|
||||
<<0xffff::16, 16::16, exp_body::bytes>>
|
||||
<<0xFFFF::16, 16::16, exp_body::bytes>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, 0::48>>) do
|
||||
|
|
|
|||
|
|
@ -10,13 +10,15 @@ defmodule Openflow.Action.NxFinTimeout do
|
|||
alias __MODULE__
|
||||
|
||||
def new(options) do
|
||||
%NxFinTimeout{idle_timeout: options[:idle_timeout] || 0,
|
||||
hard_timeout: options[:hard_timeout] || 0}
|
||||
%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)>>
|
||||
<<0xFFFF::16, 16::16, exp_body::bytes, 0::size(2)-unit(8)>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, fin_idle::16, fin_hard::16, _::size(2)-unit(8)>>) do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
defmodule Openflow.Action.NxFlowSpec do
|
||||
|
||||
def read(flow_spec_bin) do
|
||||
do_read([], flow_spec_bin)
|
||||
end
|
||||
|
|
@ -7,6 +6,7 @@ defmodule Openflow.Action.NxFlowSpec do
|
|||
def to_binary(flow_specs) when is_list(flow_specs) do
|
||||
to_binary(<<>>, flow_specs)
|
||||
end
|
||||
|
||||
def to_binary(flow_spec) do
|
||||
to_binary([flow_spec])
|
||||
end
|
||||
|
|
@ -15,15 +15,17 @@ defmodule Openflow.Action.NxFlowSpec do
|
|||
|
||||
defp do_read(acc, <<>>), do: Enum.reverse(acc)
|
||||
defp do_read(acc, <<0::16, _::bitstring>>), do: Enum.reverse(acc)
|
||||
|
||||
defp do_read(acc, <<_::2, _::1, type::2, _::bitstring>> = binary) do
|
||||
codec = Openflow.Enums.to_atom(type, :nx_flow_spec_type)
|
||||
{flow_spec, rest} = codec.read(binary)
|
||||
do_read([flow_spec|acc], rest)
|
||||
do_read([flow_spec | acc], rest)
|
||||
end
|
||||
|
||||
defp to_binary(acc, []), do: acc
|
||||
defp to_binary(acc, [flow_spec|rest]) do
|
||||
|
||||
defp to_binary(acc, [flow_spec | rest]) do
|
||||
codec = flow_spec.__struct__
|
||||
to_binary(<<acc::bytes, (codec.to_binary(flow_spec))::bytes>>, rest)
|
||||
to_binary(<<acc::bytes, codec.to_binary(flow_spec)::bytes>>, rest)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,67 +2,80 @@ defmodule Openflow.Action.NxFlowSpecLoad do
|
|||
defstruct(
|
||||
src: nil,
|
||||
dst: nil,
|
||||
n_bits: 0,
|
||||
n_bits: 0,
|
||||
src_offset: 0,
|
||||
dst_offset: 0
|
||||
)
|
||||
|
||||
@learn_src_field 0
|
||||
@learn_src_field 0
|
||||
@learn_src_immediate 1
|
||||
@learn_dst 1
|
||||
@learn_dst 1
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
def new(options) do
|
||||
dst = options[:dst]
|
||||
n_bits = options[:n_bits] || Openflow.Match.Field.n_bits_of(dst)
|
||||
%NxFlowSpecLoad{src: options[:src],
|
||||
dst: dst,
|
||||
n_bits: n_bits,
|
||||
src_offset: options[:src_offset] || 0,
|
||||
dst_offset: options[:dst_offset] || 0}
|
||||
|
||||
%NxFlowSpecLoad{
|
||||
src: options[:src],
|
||||
dst: dst,
|
||||
n_bits: n_bits,
|
||||
src_offset: options[:src_offset] || 0,
|
||||
dst_offset: options[:dst_offset] || 0
|
||||
}
|
||||
end
|
||||
|
||||
def to_binary(%NxFlowSpecLoad{} = fsm) do
|
||||
%NxFlowSpecLoad{
|
||||
dst: dst_field,
|
||||
n_bits: n_bits,
|
||||
dst: dst_field,
|
||||
n_bits: n_bits,
|
||||
src_offset: src_ofs,
|
||||
dst_offset: dst_ofs
|
||||
} = fsm
|
||||
|
||||
{src_code, src_bin} = codec_src(fsm)
|
||||
dst_bin = Openflow.Match.codec_header(dst_field)
|
||||
|
||||
case src_code do
|
||||
@learn_src_immediate ->
|
||||
<<0::2, src_code::1, @learn_dst::2, n_bits::11,
|
||||
src_bin::bytes, dst_bin::4-bytes, dst_ofs::16>>
|
||||
<<0::2, src_code::1, @learn_dst::2, n_bits::11, src_bin::bytes, dst_bin::4-bytes,
|
||||
dst_ofs::16>>
|
||||
|
||||
@learn_src_field ->
|
||||
<<0::2, src_code::1, @learn_dst::2, n_bits::11,
|
||||
src_bin::4-bytes, src_ofs::16, dst_bin::4-bytes, dst_ofs::16>>
|
||||
<<0::2, src_code::1, @learn_dst::2, n_bits::11, src_bin::4-bytes, src_ofs::16,
|
||||
dst_bin::4-bytes, dst_ofs::16>>
|
||||
end
|
||||
end
|
||||
|
||||
def read(<<_::2, @learn_src_field::1, @learn_dst::2, n_bits::11, src_bin::4-bytes,
|
||||
src_ofs::16, dst_bin::4-bytes, dst_ofs::16, rest::bitstring>>) do
|
||||
def read(
|
||||
<<_::2, @learn_src_field::1, @learn_dst::2, n_bits::11, src_bin::4-bytes, src_ofs::16,
|
||||
dst_bin::4-bytes, dst_ofs::16, rest::bitstring>>
|
||||
) do
|
||||
src = Openflow.Match.codec_header(src_bin)
|
||||
dst = Openflow.Match.codec_header(dst_bin)
|
||||
flow_spec = %NxFlowSpecLoad{src: src,
|
||||
dst: dst,
|
||||
n_bits: n_bits,
|
||||
src_offset: src_ofs,
|
||||
dst_offset: dst_ofs}
|
||||
|
||||
flow_spec = %NxFlowSpecLoad{
|
||||
src: src,
|
||||
dst: dst,
|
||||
n_bits: n_bits,
|
||||
src_offset: src_ofs,
|
||||
dst_offset: dst_ofs
|
||||
}
|
||||
|
||||
{flow_spec, rest}
|
||||
end
|
||||
|
||||
def read(<<_::2, @learn_src_immediate::1, @learn_dst::2, n_bits::11, binary::bitstring>>) do
|
||||
rounded_up_len = Openflow.Utils.pad_length(n_bits, 8)
|
||||
rounded_up_nbits = n_bits + rounded_up_len
|
||||
<<src_bin::size(rounded_up_nbits)-bits, dst_bin::4-bytes, dst_ofs::16, rest::bitstring>> = binary
|
||||
|
||||
<<src_bin::size(rounded_up_nbits)-bits, dst_bin::4-bytes, dst_ofs::16, rest::bitstring>> =
|
||||
binary
|
||||
|
||||
dst = Openflow.Match.codec_header(dst_bin)
|
||||
src = Openflow.Match.Field.codec(src_bin, dst)
|
||||
flow_spec = %NxFlowSpecLoad{src: src,
|
||||
dst: dst,
|
||||
n_bits: n_bits,
|
||||
dst_offset: dst_ofs}
|
||||
flow_spec = %NxFlowSpecLoad{src: src, dst: dst, n_bits: n_bits, dst_offset: dst_ofs}
|
||||
{flow_spec, rest}
|
||||
end
|
||||
|
||||
|
|
@ -72,6 +85,7 @@ defmodule Openflow.Action.NxFlowSpecLoad do
|
|||
src_bin = Openflow.Match.codec_header(src_field)
|
||||
{@learn_src_field, src_bin}
|
||||
end
|
||||
|
||||
defp codec_src(%NxFlowSpecLoad{src: src, dst: dst_field}) do
|
||||
src_bin = Openflow.Match.Field.codec(src, dst_field)
|
||||
{@learn_src_immediate, src_bin}
|
||||
|
|
|
|||
|
|
@ -2,67 +2,80 @@ defmodule Openflow.Action.NxFlowSpecMatch do
|
|||
defstruct(
|
||||
src: nil,
|
||||
dst: nil,
|
||||
n_bits: 0,
|
||||
n_bits: 0,
|
||||
src_offset: 0,
|
||||
dst_offset: 0
|
||||
)
|
||||
|
||||
@learn_src_field 0
|
||||
@learn_src_field 0
|
||||
@learn_src_immediate 1
|
||||
@learn_dst 0
|
||||
@learn_dst 0
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
def new(options) do
|
||||
dst = options[:dst]
|
||||
n_bits = options[:n_bits] || Openflow.Match.Field.n_bits_of(dst)
|
||||
%NxFlowSpecMatch{src: options[:src],
|
||||
dst: dst,
|
||||
n_bits: n_bits,
|
||||
src_offset: options[:src_offset] || 0,
|
||||
dst_offset: options[:dst_offset] || 0}
|
||||
|
||||
%NxFlowSpecMatch{
|
||||
src: options[:src],
|
||||
dst: dst,
|
||||
n_bits: n_bits,
|
||||
src_offset: options[:src_offset] || 0,
|
||||
dst_offset: options[:dst_offset] || 0
|
||||
}
|
||||
end
|
||||
|
||||
def to_binary(%NxFlowSpecMatch{} = fsm) do
|
||||
%NxFlowSpecMatch{
|
||||
dst: dst_field,
|
||||
n_bits: n_bits,
|
||||
dst: dst_field,
|
||||
n_bits: n_bits,
|
||||
src_offset: src_ofs,
|
||||
dst_offset: dst_ofs
|
||||
} = fsm
|
||||
|
||||
{src_code, src_bin} = codec_src(fsm)
|
||||
dst_bin = Openflow.Match.codec_header(dst_field)
|
||||
|
||||
case src_code do
|
||||
@learn_src_immediate ->
|
||||
<<0::2, src_code::1, @learn_dst::2, n_bits::11,
|
||||
src_bin::bytes, dst_bin::4-bytes, dst_ofs::16>>
|
||||
<<0::2, src_code::1, @learn_dst::2, n_bits::11, src_bin::bytes, dst_bin::4-bytes,
|
||||
dst_ofs::16>>
|
||||
|
||||
@learn_src_field ->
|
||||
<<0::2, src_code::1, @learn_dst::2, n_bits::11,
|
||||
src_bin::bytes, src_ofs::16, dst_bin::4-bytes, dst_ofs::16>>
|
||||
<<0::2, src_code::1, @learn_dst::2, n_bits::11, src_bin::bytes, src_ofs::16,
|
||||
dst_bin::4-bytes, dst_ofs::16>>
|
||||
end
|
||||
end
|
||||
|
||||
def read(<<_::2, @learn_src_field::1, @learn_dst::2, n_bits::11, src_bin::4-bytes,
|
||||
src_ofs::16, dst_bin::4-bytes, dst_ofs::16, rest::bitstring>>) do
|
||||
def read(
|
||||
<<_::2, @learn_src_field::1, @learn_dst::2, n_bits::11, src_bin::4-bytes, src_ofs::16,
|
||||
dst_bin::4-bytes, dst_ofs::16, rest::bitstring>>
|
||||
) do
|
||||
src = Openflow.Match.codec_header(src_bin)
|
||||
dst = Openflow.Match.codec_header(dst_bin)
|
||||
flow_spec = %NxFlowSpecMatch{src: src,
|
||||
dst: dst,
|
||||
n_bits: n_bits,
|
||||
src_offset: src_ofs,
|
||||
dst_offset: dst_ofs}
|
||||
|
||||
flow_spec = %NxFlowSpecMatch{
|
||||
src: src,
|
||||
dst: dst,
|
||||
n_bits: n_bits,
|
||||
src_offset: src_ofs,
|
||||
dst_offset: dst_ofs
|
||||
}
|
||||
|
||||
{flow_spec, rest}
|
||||
end
|
||||
|
||||
def read(<<_::2, @learn_src_immediate::1, @learn_dst::2, n_bits::11, binary::bitstring>>) do
|
||||
rounded_up_len = Openflow.Utils.pad_length(n_bits, 8)
|
||||
rounded_up_nbits = n_bits + rounded_up_len
|
||||
<<src_bin::size(rounded_up_nbits)-bits, dst_bin::4-bytes, dst_ofs::16, rest::bitstring>> = binary
|
||||
|
||||
<<src_bin::size(rounded_up_nbits)-bits, dst_bin::4-bytes, dst_ofs::16, rest::bitstring>> =
|
||||
binary
|
||||
|
||||
dst = Openflow.Match.codec_header(dst_bin)
|
||||
src = Openflow.Match.Field.codec(src_bin, dst)
|
||||
flow_spec = %NxFlowSpecMatch{src: src,
|
||||
dst: dst,
|
||||
n_bits: n_bits,
|
||||
dst_offset: dst_ofs}
|
||||
flow_spec = %NxFlowSpecMatch{src: src, dst: dst, n_bits: n_bits, dst_offset: dst_ofs}
|
||||
{flow_spec, rest}
|
||||
end
|
||||
|
||||
|
|
@ -72,6 +85,7 @@ defmodule Openflow.Action.NxFlowSpecMatch do
|
|||
src_bin = Openflow.Match.codec_header(src_field)
|
||||
{@learn_src_field, src_bin}
|
||||
end
|
||||
|
||||
defp codec_src(%NxFlowSpecMatch{src: src, dst: dst_field}) do
|
||||
src_bin = Openflow.Match.Field.codec(src, dst_field)
|
||||
{@learn_src_immediate, src_bin}
|
||||
|
|
|
|||
|
|
@ -5,32 +5,28 @@ defmodule Openflow.Action.NxFlowSpecOutput do
|
|||
src_offset: 0
|
||||
)
|
||||
|
||||
@learn_src_field 0
|
||||
@learn_dst 2
|
||||
@learn_src_field 0
|
||||
@learn_dst 2
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
def new(options) do
|
||||
src = options[:src]
|
||||
n_bits = options[:n_bits] || Openflow.Match.Field.n_bits_of(src)
|
||||
%NxFlowSpecOutput{n_bits: n_bits,
|
||||
src: src,
|
||||
src_offset: options[:src_offset] || 0}
|
||||
%NxFlowSpecOutput{n_bits: n_bits, src: src, src_offset: options[:src_offset] || 0}
|
||||
end
|
||||
|
||||
def to_binary(%NxFlowSpecOutput{n_bits: n_bits,
|
||||
src: src,
|
||||
src_offset: src_ofs}) do
|
||||
def to_binary(%NxFlowSpecOutput{n_bits: n_bits, src: src, src_offset: src_ofs}) do
|
||||
src_bin = Openflow.Match.codec_header(src)
|
||||
<<0::2, @learn_src_field::1, @learn_dst::2, n_bits::11, src_bin::4-bytes, src_ofs::16>>
|
||||
end
|
||||
|
||||
def read(<<0::2, @learn_src_field::1, @learn_dst::2,
|
||||
n_bits::11, src_bin::4-bytes, src_ofs::16, rest::bitstring>>) do
|
||||
def read(
|
||||
<<0::2, @learn_src_field::1, @learn_dst::2, n_bits::11, src_bin::4-bytes, src_ofs::16,
|
||||
rest::bitstring>>
|
||||
) do
|
||||
src = Openflow.Match.codec_header(src_bin)
|
||||
flow_spec = %NxFlowSpecOutput{n_bits: n_bits,
|
||||
src: src,
|
||||
src_offset: src_ofs}
|
||||
flow_spec = %NxFlowSpecOutput{n_bits: n_bits, src: src, src_offset: src_ofs}
|
||||
{flow_spec, rest}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -17,53 +17,60 @@ defmodule Openflow.Action.NxLearn do
|
|||
alias __MODULE__
|
||||
|
||||
def new(options) do
|
||||
%NxLearn{idle_timeout: options[:idle_timeout] || 0,
|
||||
hard_timeout: options[:hard_timeout] || 0,
|
||||
priority: options[:priority] || 0,
|
||||
cookie: options[:cookie] || 0,
|
||||
flags: options[:flags] || [],
|
||||
table_id: options[:table_id] || 0xff,
|
||||
fin_idle_timeout: options[:fin_idle_timeout] || 0,
|
||||
fin_hard_timeout: options[:fin_hard_timeout] || 0,
|
||||
flow_specs: options[:flow_specs] || []}
|
||||
%NxLearn{
|
||||
idle_timeout: options[:idle_timeout] || 0,
|
||||
hard_timeout: options[:hard_timeout] || 0,
|
||||
priority: options[:priority] || 0,
|
||||
cookie: options[:cookie] || 0,
|
||||
flags: options[:flags] || [],
|
||||
table_id: options[:table_id] || 0xFF,
|
||||
fin_idle_timeout: options[:fin_idle_timeout] || 0,
|
||||
fin_hard_timeout: options[:fin_hard_timeout] || 0,
|
||||
flow_specs: options[:flow_specs] || []
|
||||
}
|
||||
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
|
||||
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)
|
||||
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)
|
||||
|
||||
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)>>
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, body::bitstring>>) do
|
||||
<<idle::16, hard::16,
|
||||
prio::16, cookie::64, flags_int::16, table_id::8,
|
||||
_pad::size(1)-unit(8), fin_idle::16, fin_hard::16,
|
||||
flow_specs_bin::bitstring>> = body
|
||||
<<idle::16, hard::16, prio::16, cookie::64, flags_int::16, table_id::8, _pad::size(1)-unit(8),
|
||||
fin_idle::16, fin_hard::16, flow_specs_bin::bitstring>> = body
|
||||
|
||||
flags = Openflow.Enums.int_to_flags(flags_int, :nx_learn_flag)
|
||||
flow_specs = Openflow.Action.NxFlowSpec.read(flow_specs_bin)
|
||||
%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}
|
||||
|
||||
%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
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -20,65 +20,77 @@ defmodule Openflow.Action.NxLearn2 do
|
|||
alias __MODULE__
|
||||
|
||||
def new(options) do
|
||||
%NxLearn2{idle_timeout: options[:idle_timeout] || 0,
|
||||
hard_timeout: options[:hard_timeout] || 0,
|
||||
priority: options[:priority] || 0,
|
||||
cookie: options[:cookie] || 0,
|
||||
flags: options[:flags] || [],
|
||||
table_id: options[:table_id] || 0xff,
|
||||
fin_idle_timeout: options[:fin_idle_timeout] || 0,
|
||||
fin_hard_timeout: options[:fin_hard_timeout] || 0,
|
||||
limit: options[:limit] || 0,
|
||||
result_dst_offset: options[:result_dst_offset] || 0,
|
||||
result_dst: options[:result_dst],
|
||||
flow_specs: options[:flow_specs] || []}
|
||||
%NxLearn2{
|
||||
idle_timeout: options[:idle_timeout] || 0,
|
||||
hard_timeout: options[:hard_timeout] || 0,
|
||||
priority: options[:priority] || 0,
|
||||
cookie: options[:cookie] || 0,
|
||||
flags: options[:flags] || [],
|
||||
table_id: options[:table_id] || 0xFF,
|
||||
fin_idle_timeout: options[:fin_idle_timeout] || 0,
|
||||
fin_hard_timeout: options[:fin_hard_timeout] || 0,
|
||||
limit: options[:limit] || 0,
|
||||
result_dst_offset: options[:result_dst_offset] || 0,
|
||||
result_dst: options[:result_dst],
|
||||
flow_specs: options[:flow_specs] || []
|
||||
}
|
||||
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
|
||||
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)
|
||||
result_dst_bin = if :write_result in flags do
|
||||
Openflow.Match.codec_header(result_dst)
|
||||
else
|
||||
""
|
||||
end
|
||||
|
||||
result_dst_bin =
|
||||
if :write_result in flags do
|
||||
Openflow.Match.codec_header(result_dst)
|
||||
else
|
||||
""
|
||||
end
|
||||
|
||||
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)
|
||||
|
||||
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)>>
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, body::bytes>>) do
|
||||
<<idle::16, hard::16, prio::16, cookie::64, flags_int::16, table_id::8,
|
||||
0::8, fin_idle::16, fin_hard::16, limit::32,
|
||||
result_dst_ofs::16, 0::size(2)-unit(8), rest::bytes>> = body
|
||||
<<idle::16, hard::16, prio::16, cookie::64, flags_int::16, table_id::8, 0::8, fin_idle::16,
|
||||
fin_hard::16, limit::32, result_dst_ofs::16, 0::size(2)-unit(8), rest::bytes>> = body
|
||||
|
||||
flags = Openflow.Enums.int_to_flags(flags_int, :nx_learn_flag)
|
||||
learn = %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}
|
||||
|
||||
learn = %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
|
||||
}
|
||||
|
||||
if :write_result in flags do
|
||||
header_size = Openflow.Match.header_size(rest)
|
||||
<<result_dst_bin::size(header_size)-bytes, flow_specs_bin::bytes>> = rest
|
||||
|
|
|
|||
|
|
@ -3,13 +3,13 @@ defmodule Openflow.Action.NxMultipath do
|
|||
|
||||
defstruct(
|
||||
hash_field: :eth_src,
|
||||
basis: 0,
|
||||
algorithm: :modulo_n,
|
||||
max_link: 0,
|
||||
argument: 0,
|
||||
offset: 0,
|
||||
n_bits: 0,
|
||||
dst_field: nil
|
||||
basis: 0,
|
||||
algorithm: :modulo_n,
|
||||
max_link: 0,
|
||||
argument: 0,
|
||||
offset: 0,
|
||||
n_bits: 0,
|
||||
dst_field: nil
|
||||
)
|
||||
|
||||
@experimenter 0x00002320
|
||||
|
|
@ -27,52 +27,62 @@ defmodule Openflow.Action.NxMultipath do
|
|||
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,
|
||||
dst_field: dst_field}
|
||||
|
||||
%NxMultipath{
|
||||
hash_field: hash_field,
|
||||
basis: basis,
|
||||
algorithm: alg,
|
||||
max_link: max_link,
|
||||
offset: ofs,
|
||||
n_bits: n_bits,
|
||||
argument: arg,
|
||||
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
|
||||
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)
|
||||
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>>
|
||||
ofs_nbits = ofs <<< 6 ||| 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)
|
||||
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)>>
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, body::bytes>>) do
|
||||
<<hash_field_int::16, basis::16, _::size(2)-unit(8),
|
||||
alg_int::16, max_link::16, arg::32, _::size(2)-unit(8),
|
||||
ofs::10, n_bits::6, dst_field_bin::4-bytes>> = body
|
||||
<<hash_field_int::16, basis::16, _::size(2)-unit(8), alg_int::16, max_link::16, arg::32,
|
||||
_::size(2)-unit(8), ofs::10, n_bits::6, dst_field_bin::4-bytes>> = body
|
||||
|
||||
hash_field = Openflow.Enums.to_atom(hash_field_int, :nx_hash_fields)
|
||||
alg = Openflow.Enums.to_atom(alg_int, :nx_mp_algorithm)
|
||||
dst_field = Openflow.Match.codec_header(dst_field_bin)
|
||||
%NxMultipath{hash_field: hash_field,
|
||||
basis: basis,
|
||||
algorithm: alg,
|
||||
max_link: max_link,
|
||||
argument: arg,
|
||||
offset: ofs,
|
||||
n_bits: n_bits + 1,
|
||||
dst_field: dst_field}
|
||||
|
||||
%NxMultipath{
|
||||
hash_field: hash_field,
|
||||
basis: basis,
|
||||
algorithm: alg,
|
||||
max_link: max_link,
|
||||
argument: arg,
|
||||
offset: ofs,
|
||||
n_bits: n_bits + 1,
|
||||
dst_field: dst_field
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
defmodule Openflow.Action.NxNat do
|
||||
defstruct(
|
||||
flags: [],
|
||||
ipv4_min: nil,
|
||||
ipv4_max: nil,
|
||||
ipv6_min: nil,
|
||||
ipv6_max: nil,
|
||||
flags: [],
|
||||
ipv4_min: nil,
|
||||
ipv4_max: nil,
|
||||
ipv6_min: nil,
|
||||
ipv6_max: nil,
|
||||
proto_min: nil,
|
||||
proto_max: nil
|
||||
)
|
||||
|
|
@ -22,30 +22,38 @@ defmodule Openflow.Action.NxNat do
|
|||
ipv6_max = Keyword.get(options, :ipv6_max)
|
||||
proto_min = Keyword.get(options, :proto_min)
|
||||
proto_max = Keyword.get(options, :proto_max)
|
||||
%NxNat{flags: flags,
|
||||
ipv4_min: ipv4_min,
|
||||
ipv4_max: ipv4_max,
|
||||
ipv6_min: ipv6_min,
|
||||
ipv6_max: ipv6_max,
|
||||
proto_min: proto_min,
|
||||
proto_max: proto_max}
|
||||
|
||||
%NxNat{
|
||||
flags: flags,
|
||||
ipv4_min: ipv4_min,
|
||||
ipv4_max: ipv4_max,
|
||||
ipv6_min: ipv6_min,
|
||||
ipv6_max: ipv6_max,
|
||||
proto_min: proto_min,
|
||||
proto_max: proto_max
|
||||
}
|
||||
end
|
||||
|
||||
def to_binary(%NxNat{flags: flags} = nat) do
|
||||
flags_int = Openflow.Enums.flags_to_int(flags, :nx_nat_flags)
|
||||
|
||||
range_flags =
|
||||
nat
|
||||
|> get_ranges
|
||||
|> Openflow.Enums.flags_to_int(:nx_nat_range)
|
||||
|> Openflow.Enums.int_to_flags(:nx_nat_range)
|
||||
|
||||
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)
|
||||
|
||||
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)>>
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, body::bytes>>) do
|
||||
|
|
@ -59,33 +67,43 @@ defmodule Openflow.Action.NxNat do
|
|||
|
||||
defp get_ranges(nat) do
|
||||
nat
|
||||
|> Map.from_struct
|
||||
|> Map.from_struct()
|
||||
|> Map.delete(:flags)
|
||||
|> 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.map(fn {k, v} -> if(not is_nil(v), do: k, else: nil) end)
|
||||
|> Enum.filter(fn v -> not is_nil(v) end)
|
||||
end
|
||||
|
||||
defp encode_ranges(acc, [], _nat), do: acc
|
||||
defp encode_ranges(acc, [range|rest], nat) do
|
||||
|
||||
defp encode_ranges(acc, [range | rest], nat) do
|
||||
cond do
|
||||
range == :ipv4_min or range == :ipv4_max ->
|
||||
case Map.get(nat, range) do
|
||||
{a1, a2, a3, a4} ->
|
||||
{a1, a2, a3, a4} ->
|
||||
encode_ranges(<<acc::bytes, a1, a2, a3, a4>>, rest, nat)
|
||||
|
||||
"" ->
|
||||
encode_ranges(<<acc::bytes>>, rest, nat)
|
||||
end
|
||||
|
||||
range == :ipv6_min or range == :ipv6_max ->
|
||||
case Map.get(nat, range) do
|
||||
{a1, a2, a3, a4, a5, a6, a7, a8} ->
|
||||
encode_ranges(<<acc::bytes, a1::16, a2::16, a3::16, a4::16, a5::16, a6::16, a7::16, a8::16>>, rest, nat)
|
||||
encode_ranges(
|
||||
<<acc::bytes, a1::16, a2::16, a3::16, a4::16, a5::16, a6::16, a7::16, a8::16>>,
|
||||
rest,
|
||||
nat
|
||||
)
|
||||
|
||||
"" ->
|
||||
encode_ranges(<<acc::bytes>>, rest, nat)
|
||||
end
|
||||
|
||||
range == :proto_min or range == :proto_max ->
|
||||
case Map.get(nat, range) do
|
||||
proto when is_integer(proto) and proto in (1..0xffff) ->
|
||||
proto when is_integer(proto) and proto in 1..0xFFFF ->
|
||||
encode_ranges(<<acc::bytes, proto::16>>, rest, nat)
|
||||
|
||||
_ ->
|
||||
encode_ranges(<<acc::bytes>>, rest, nat)
|
||||
end
|
||||
|
|
@ -93,26 +111,32 @@ defmodule Openflow.Action.NxNat do
|
|||
end
|
||||
|
||||
defp decode_ranges(nat, [], _), do: nat
|
||||
defp decode_ranges(nat, [range|ranges], bin) do
|
||||
|
||||
defp decode_ranges(nat, [range | ranges], bin) do
|
||||
cond do
|
||||
range == :ipv4_min or range == :ipv4_max ->
|
||||
case bin do
|
||||
<<a1, a2, a3, a4, rest::bytes>> ->
|
||||
decode_ranges(struct(nat, %{range => {a1, a2, a3, a4}}), ranges, rest)
|
||||
|
||||
rest ->
|
||||
decode_ranges(struct(nat, %{range => ""}), ranges, rest)
|
||||
end
|
||||
|
||||
range == :ipv6_min or range == :ipv6_max ->
|
||||
case bin do
|
||||
<<a1::16, a2::16, a3::16, a4::16, a5::16, a6::16, a7::16, a8::16, rest::bytes>> ->
|
||||
decode_ranges(struct(nat, %{range => {a1, a2, a3, a4, a5, a6, a7, a8}}), ranges, rest)
|
||||
|
||||
rest ->
|
||||
decode_ranges(struct(nat, %{range => ""}), ranges, rest)
|
||||
end
|
||||
|
||||
range == :proto_min or range == :proto_max ->
|
||||
case bin do
|
||||
<<proto::16, rest::bytes>> when proto in (1..0xffff) ->
|
||||
<<proto::16, rest::bytes>> when proto in 1..0xFFFF ->
|
||||
decode_ranges(struct(nat, %{range => proto}), ranges, rest)
|
||||
|
||||
rest ->
|
||||
decode_ranges(struct(nat, %{range => ""}), ranges, rest)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ defmodule Openflow.Action.NxNote do
|
|||
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)
|
||||
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)>>
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, note_bin::bytes>>) do
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@ defmodule Openflow.Action.NxOutputReg do
|
|||
import Bitwise
|
||||
|
||||
defstruct(
|
||||
n_bits: 0,
|
||||
offset: 0,
|
||||
src_field: nil,
|
||||
max_len: :no_buffer
|
||||
n_bits: 0,
|
||||
offset: 0,
|
||||
src_field: nil,
|
||||
max_len: :no_buffer
|
||||
)
|
||||
|
||||
@experimenter 0x00002320
|
||||
|
|
@ -19,34 +19,25 @@ defmodule Openflow.Action.NxOutputReg do
|
|||
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: n_bits, offset: ofs, src_field: src_field, max_len: max_len}
|
||||
end
|
||||
|
||||
def to_binary(%NxOutputReg{n_bits: n_bits,
|
||||
offset: ofs,
|
||||
src_field: src_field,
|
||||
max_len: max_len}) do
|
||||
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)
|
||||
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)
|
||||
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)>>
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, body::bytes>>) do
|
||||
<<ofs::10, n_bits::6, src_field_bin::4-bytes, max_len::16, _::size(6)-unit(8)>> = body
|
||||
src_field = Openflow.Match.codec_header(src_field_bin)
|
||||
max_len = Openflow.Utils.get_enum(max_len, :controller_max_len)
|
||||
%NxOutputReg{n_bits: n_bits + 1,
|
||||
offset: ofs,
|
||||
src_field: src_field,
|
||||
max_len: max_len}
|
||||
%NxOutputReg{n_bits: n_bits + 1, offset: ofs, src_field: src_field, max_len: max_len}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@ defmodule Openflow.Action.NxOutputReg2 do
|
|||
import Bitwise
|
||||
|
||||
defstruct(
|
||||
n_bits: 0,
|
||||
offset: 0,
|
||||
src_field: nil,
|
||||
max_len: :no_buffer
|
||||
n_bits: 0,
|
||||
offset: 0,
|
||||
src_field: nil,
|
||||
max_len: :no_buffer
|
||||
)
|
||||
|
||||
@experimenter 0x00002320
|
||||
|
|
@ -24,28 +24,31 @@ defmodule Openflow.Action.NxOutputReg2 do
|
|||
|
||||
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)
|
||||
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)
|
||||
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)>>
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, body::bytes>>) do
|
||||
<<ofs::10, n_bits::6, max_len::16, oxm_header::4-bytes, rest::bitstring>> = body
|
||||
exp_size = match_header_size(oxm_header) - 4
|
||||
<<experimenter_int::size(exp_size)-unit(8), _padding::bytes>> = rest
|
||||
src_field = Openflow.Match.codec_header(<<oxm_header::bytes, experimenter_int::size(exp_size)-unit(8)>>)
|
||||
|
||||
src_field =
|
||||
Openflow.Match.codec_header(<<oxm_header::bytes, experimenter_int::size(exp_size)-unit(8)>>)
|
||||
|
||||
max_len = Openflow.Utils.get_enum(max_len, :controller_max_len)
|
||||
%NxOutputReg2{n_bits: n_bits + 1, offset: ofs, src_field: src_field, max_len: max_len}
|
||||
end
|
||||
|
||||
# private functions
|
||||
|
||||
defp match_header_size(<<0xffff::16, _::bytes>>), do: 8
|
||||
defp match_header_size(<<_::16, _::bytes>>), do: 4
|
||||
defp match_header_size(<<0xFFFF::16, _::bytes>>), do: 8
|
||||
defp match_header_size(<<_::16, _::bytes>>), do: 4
|
||||
end
|
||||
|
|
|
|||
|
|
@ -18,10 +18,10 @@ defmodule Openflow.Action.NxOutputTrunc do
|
|||
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)
|
||||
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)>>
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, port_no_int::16, max_len::32>>) do
|
||||
|
|
|
|||
|
|
@ -12,10 +12,10 @@ defmodule Openflow.Action.NxPopMpls do
|
|||
|
||||
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)
|
||||
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)>>
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, ethertype::16, _::size(4)-unit(8)>>) do
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ defmodule Openflow.Action.NxPopQueue do
|
|||
|
||||
@experimenter 0x00002320
|
||||
@nxast 5
|
||||
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
def new do
|
||||
|
|
@ -12,10 +12,10 @@ defmodule Openflow.Action.NxPopQueue do
|
|||
|
||||
def to_binary(%NxPopQueue{}) do
|
||||
exp_body = <<@experimenter::32, @nxast::16, 0::48>>
|
||||
exp_body_size = byte_size(exp_body)
|
||||
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)>>
|
||||
<<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
|
||||
|
|
|
|||
|
|
@ -12,10 +12,10 @@ defmodule Openflow.Action.NxPushMpls do
|
|||
|
||||
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)
|
||||
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)>>
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, ethertype::16, _::size(4)-unit(8)>>) do
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@ defmodule Openflow.Action.NxRegLoad do
|
|||
import Bitwise
|
||||
|
||||
defstruct(
|
||||
n_bits: 0,
|
||||
offset: 0,
|
||||
dst_field: nil,
|
||||
value: nil
|
||||
n_bits: 0,
|
||||
offset: 0,
|
||||
dst_field: nil,
|
||||
value: nil
|
||||
)
|
||||
|
||||
@experimenter 0x00002320
|
||||
|
|
@ -19,36 +19,27 @@ defmodule Openflow.Action.NxRegLoad do
|
|||
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: n_bits, offset: ofs, dst_field: dst_field, value: value}
|
||||
end
|
||||
|
||||
def to_binary(%NxRegLoad{n_bits: n_bits,
|
||||
offset: ofs,
|
||||
dst_field: dst_field,
|
||||
value: value}) do
|
||||
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)
|
||||
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)
|
||||
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)>>
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, body::bytes>>) do
|
||||
<<ofs::10, n_bits::6, dst_field_bin::4-bytes, value_bin::bytes>> = body
|
||||
dst_field = Openflow.Match.codec_header(dst_field_bin)
|
||||
value = Openflow.Match.Field.codec(value_bin, dst_field)
|
||||
%NxRegLoad{n_bits: n_bits + 1,
|
||||
offset: ofs,
|
||||
dst_field: dst_field,
|
||||
value: value}
|
||||
%NxRegLoad{n_bits: n_bits + 1, offset: ofs, dst_field: dst_field, value: value}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
defmodule Openflow.Action.NxRegLoad2 do
|
||||
defstruct(
|
||||
dst_field: nil,
|
||||
value: nil
|
||||
dst_field: nil,
|
||||
value: nil
|
||||
)
|
||||
|
||||
@experimenter 0x00002320
|
||||
|
|
@ -18,23 +18,27 @@ defmodule Openflow.Action.NxRegLoad2 do
|
|||
def to_binary(%NxRegLoad2{dst_field: dst_field, value: value}) do
|
||||
match_bin =
|
||||
[{dst_field, value}]
|
||||
|> Openflow.Match.new
|
||||
|> Openflow.Match.to_binary
|
||||
|> 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)
|
||||
exp_body = <<@experimenter::32, @nxast::16, 0::48, padded_field::bytes, 0::size(padding)-unit(8)>>
|
||||
exp_body_size = byte_size(exp_body)
|
||||
|
||||
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)>>
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, _::48, 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)
|
||||
{[{dst_field, value} | _], _rest} = Openflow.Match.read(match_bin)
|
||||
%NxRegLoad2{dst_field: dst_field, value: value}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
defmodule Openflow.Action.NxRegMove do
|
||||
defstruct(
|
||||
n_bits: 0,
|
||||
n_bits: 0,
|
||||
src_offset: 0,
|
||||
dst_offset: 0,
|
||||
src_field: nil,
|
||||
dst_field: nil
|
||||
src_field: nil,
|
||||
dst_field: nil
|
||||
)
|
||||
|
||||
@experimenter 0x00002320
|
||||
|
|
@ -19,38 +19,49 @@ defmodule Openflow.Action.NxRegMove do
|
|||
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,
|
||||
src_field: src_field,
|
||||
dst_field: dst_field}
|
||||
|
||||
%NxRegMove{
|
||||
n_bits: n_bits,
|
||||
src_offset: src_ofs,
|
||||
dst_offset: dst_ofs,
|
||||
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
|
||||
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)
|
||||
body = <<n_bits::16, src_ofs::16, dst_ofs::16,
|
||||
src_field_bin::4-bytes, dst_field_bin::4-bytes>>
|
||||
|
||||
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)
|
||||
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)>>
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, body::bytes>>) do
|
||||
<<n_bits::16, src_ofs::16, dst_ofs::16,
|
||||
src_field_bin::4-bytes, dst_field_bin::4-bytes>> = body
|
||||
<<n_bits::16, src_ofs::16, dst_ofs::16, src_field_bin::4-bytes, dst_field_bin::4-bytes>> =
|
||||
body
|
||||
|
||||
src_field = Openflow.Match.codec_header(src_field_bin)
|
||||
dst_field = Openflow.Match.codec_header(dst_field_bin)
|
||||
%NxRegMove{n_bits: n_bits,
|
||||
src_offset: src_ofs,
|
||||
dst_offset: dst_ofs,
|
||||
src_field: src_field,
|
||||
dst_field: dst_field}
|
||||
|
||||
%NxRegMove{
|
||||
n_bits: n_bits,
|
||||
src_offset: src_ofs,
|
||||
dst_offset: dst_ofs,
|
||||
src_field: src_field,
|
||||
dst_field: dst_field
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
defmodule Openflow.Action.NxResubmit do
|
||||
defstruct([in_port: :in_port])
|
||||
defstruct(in_port: :in_port)
|
||||
|
||||
@experimenter 0x00002320
|
||||
@nxast 1
|
||||
|
|
@ -13,10 +13,10 @@ 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)
|
||||
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)>>
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, in_port_int::16, _::size(4)-unit(8)>>) do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
defmodule Openflow.Action.NxResubmitTable do
|
||||
defstruct([in_port: :in_port, table_id: :all])
|
||||
defstruct(in_port: :in_port, table_id: :all)
|
||||
|
||||
@experimenter 0x00002320
|
||||
@nxast 14
|
||||
|
|
@ -9,6 +9,7 @@ defmodule Openflow.Action.NxResubmitTable do
|
|||
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)
|
||||
|
|
@ -19,13 +20,15 @@ defmodule Openflow.Action.NxResubmitTable 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)
|
||||
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)>>
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, in_port_int::16, table_id_int::8, 0::size(3)-unit(8)>>) do
|
||||
def read(
|
||||
<<@experimenter::32, @nxast::16, in_port_int::16, table_id_int::8, 0::size(3)-unit(8)>>
|
||||
) do
|
||||
in_port = Openflow.Utils.get_enum(in_port_int, :openflow10_port_no)
|
||||
table_id = Openflow.Utils.get_enum(table_id_int, :table_id)
|
||||
%NxResubmitTable{in_port: in_port, table_id: table_id}
|
||||
|
|
|
|||
|
|
@ -16,13 +16,15 @@ defmodule Openflow.Action.NxResubmitTableCt 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)
|
||||
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
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, in_port_int::16, table_id_int::8, 0::size(3)-unit(8)>>) do
|
||||
def read(
|
||||
<<@experimenter::32, @nxast::16, in_port_int::16, table_id_int::8, 0::size(3)-unit(8)>>
|
||||
) do
|
||||
in_port = Openflow.Utils.get_enum(in_port_int, :openflow10_port_no)
|
||||
table_id = Openflow.Utils.get_enum(table_id_int, :table_id)
|
||||
%NxResubmitTableCt{in_port: in_port, table_id: table_id}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
defmodule Openflow.Action.NxSample do
|
||||
defstruct(
|
||||
probability: 0,
|
||||
probability: 0,
|
||||
collector_set_id: 0,
|
||||
obs_domain_id: 0,
|
||||
obs_point_id: 0
|
||||
obs_domain_id: 0,
|
||||
obs_point_id: 0
|
||||
)
|
||||
|
||||
@experimenter 0x00002320
|
||||
|
|
@ -16,29 +16,40 @@ defmodule Openflow.Action.NxSample do
|
|||
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)
|
||||
%NxSample{probability: probability,
|
||||
collector_set_id: collector_set_id,
|
||||
obs_domain_id: obs_domain_id,
|
||||
obs_point_id: obs_point_id}
|
||||
|
||||
%NxSample{
|
||||
probability: probability,
|
||||
collector_set_id: collector_set_id,
|
||||
obs_domain_id: obs_domain_id,
|
||||
obs_point_id: obs_point_id
|
||||
}
|
||||
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)
|
||||
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)>>
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, probability::16,
|
||||
collector_set_id::32, obs_domain_id::32, obs_point_id::32>>) do
|
||||
%NxSample{probability: probability,
|
||||
collector_set_id: collector_set_id,
|
||||
obs_domain_id: obs_domain_id,
|
||||
obs_point_id: obs_point_id}
|
||||
def read(
|
||||
<<@experimenter::32, @nxast::16, probability::16, collector_set_id::32, obs_domain_id::32,
|
||||
obs_point_id::32>>
|
||||
) do
|
||||
%NxSample{
|
||||
probability: probability,
|
||||
collector_set_id: collector_set_id,
|
||||
obs_domain_id: obs_domain_id,
|
||||
obs_point_id: obs_point_id
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
defmodule Openflow.Action.NxSample2 do
|
||||
defstruct(
|
||||
probability: 0,
|
||||
probability: 0,
|
||||
collector_set_id: 0,
|
||||
obs_domain_id: 0,
|
||||
obs_point_id: 0,
|
||||
sampling_port: 0
|
||||
obs_domain_id: 0,
|
||||
obs_point_id: 0,
|
||||
sampling_port: 0
|
||||
)
|
||||
|
||||
@experimenter 0x00002320
|
||||
|
|
@ -18,32 +18,43 @@ defmodule Openflow.Action.NxSample2 do
|
|||
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)
|
||||
%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}
|
||||
|
||||
%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
|
||||
}
|
||||
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)
|
||||
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)>>
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-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
|
||||
%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}
|
||||
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
|
||||
%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
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
defmodule Openflow.Action.NxSample3 do
|
||||
defstruct(
|
||||
probability: 0,
|
||||
probability: 0,
|
||||
collector_set_id: 0,
|
||||
obs_domain_id: 0,
|
||||
obs_point_id: 0,
|
||||
sampling_port: 0,
|
||||
direction: :default
|
||||
obs_domain_id: 0,
|
||||
obs_point_id: 0,
|
||||
sampling_port: 0,
|
||||
direction: :default
|
||||
)
|
||||
|
||||
@experimenter 0x00002320
|
||||
|
|
@ -20,37 +20,50 @@ defmodule Openflow.Action.NxSample3 do
|
|||
obs_point_id = Keyword.get(options, :obs_point_id, 0)
|
||||
sampling_port = Keyword.get(options, :sampling_port, 0)
|
||||
direction = Keyword.get(options, :direction, :default)
|
||||
%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}
|
||||
|
||||
%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
|
||||
}
|
||||
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
|
||||
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)
|
||||
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)
|
||||
|
||||
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)>>
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-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, direction_int::8, 0::size(5)-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, direction_int::8, 0::size(5)-unit(8)>>
|
||||
) do
|
||||
direction = Openflow.Enums.to_atom(direction_int, :nx_action_sample_direction)
|
||||
%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}
|
||||
|
||||
%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
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -12,10 +12,10 @@ defmodule Openflow.Action.NxSetMplsLabel do
|
|||
|
||||
def to_binary(%NxSetMplsLabel{label: label}) do
|
||||
exp_body = <<@experimenter::32, @nxast::16, 0::16, label::32>>
|
||||
exp_body_size = byte_size(exp_body)
|
||||
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)>>
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, _::16, label::32>>) do
|
||||
|
|
|
|||
|
|
@ -12,10 +12,10 @@ defmodule Openflow.Action.NxSetMplsTc do
|
|||
|
||||
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)
|
||||
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)>>
|
||||
<<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
|
||||
|
|
|
|||
|
|
@ -12,10 +12,10 @@ defmodule Openflow.Action.NxSetMplsTtl do
|
|||
|
||||
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)
|
||||
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)>>
|
||||
<<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
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
defmodule Openflow.Action.NxSetQueue do
|
||||
defstruct([queue_id: 0])
|
||||
defstruct(queue_id: 0)
|
||||
|
||||
@experimenter 0x00002320
|
||||
@nxast 4
|
||||
|
|
@ -12,10 +12,10 @@ defmodule Openflow.Action.NxSetQueue do
|
|||
|
||||
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)
|
||||
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)>>
|
||||
<<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
|
||||
|
|
|
|||
|
|
@ -12,10 +12,10 @@ defmodule Openflow.Action.NxSetTunnel do
|
|||
|
||||
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)
|
||||
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)>>
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, _::16, tunnel_id::32>>) do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
defmodule Openflow.Action.NxSetTunnel64 do
|
||||
defstruct([tunnel_id: 0])
|
||||
defstruct(tunnel_id: 0)
|
||||
|
||||
@experimenter 0x00002320
|
||||
@nxast 9
|
||||
|
|
@ -12,10 +12,10 @@ defmodule Openflow.Action.NxSetTunnel64 do
|
|||
|
||||
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)
|
||||
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)>>
|
||||
<<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), tunnel_id::64>>) do
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
defmodule Openflow.Action.NxStackPop do
|
||||
defstruct(
|
||||
n_bits: 0,
|
||||
offset: 0,
|
||||
field: nil
|
||||
n_bits: 0,
|
||||
offset: 0,
|
||||
field: nil
|
||||
)
|
||||
|
||||
@experimenter 0x00002320
|
||||
|
|
@ -20,16 +20,21 @@ defmodule Openflow.Action.NxStackPop do
|
|||
|
||||
def to_binary(%NxStackPop{n_bits: n_bits, offset: ofs, field: field}) do
|
||||
field_bin = Openflow.Match.codec_header(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)
|
||||
|
||||
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)>>
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, ofs::16,
|
||||
field_bin::4-bytes, n_bits::16, _::size(6)-unit(8)>>) do
|
||||
def read(
|
||||
<<@experimenter::32, @nxast::16, ofs::16, field_bin::4-bytes, n_bits::16,
|
||||
_::size(6)-unit(8)>>
|
||||
) do
|
||||
field = Openflow.Match.codec_header(field_bin)
|
||||
%NxStackPop{n_bits: n_bits, offset: ofs, field: field}
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
defmodule Openflow.Action.NxStackPush do
|
||||
defstruct(
|
||||
n_bits: 0,
|
||||
offset: 0,
|
||||
field: nil
|
||||
n_bits: 0,
|
||||
offset: 0,
|
||||
field: nil
|
||||
)
|
||||
|
||||
@experimenter 0x00002320
|
||||
|
|
@ -20,16 +20,21 @@ defmodule Openflow.Action.NxStackPush do
|
|||
|
||||
def to_binary(%NxStackPush{n_bits: n_bits, offset: ofs, field: field}) do
|
||||
field_bin = Openflow.Match.codec_header(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)
|
||||
|
||||
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)>>
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, ofs::16,
|
||||
field_bin::4-bytes, n_bits::16, _::size(6)-unit(8)>>) do
|
||||
def read(
|
||||
<<@experimenter::32, @nxast::16, ofs::16, field_bin::4-bytes, n_bits::16,
|
||||
_::size(6)-unit(8)>>
|
||||
) do
|
||||
field = Openflow.Match.codec_header(field_bin)
|
||||
%NxStackPush{n_bits: n_bits, offset: ofs, field: field}
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
defmodule Openflow.Action.NxWriteMetadata do
|
||||
defstruct(
|
||||
metadata: 0,
|
||||
metadata_mask: 0xffffffffffffffff
|
||||
metadata_mask: 0xFFFFFFFFFFFFFFFF
|
||||
)
|
||||
|
||||
@experimenter 0x00002320
|
||||
|
|
@ -12,18 +12,21 @@ defmodule Openflow.Action.NxWriteMetadata do
|
|||
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_mask = Keyword.get(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)
|
||||
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)>>
|
||||
<<0xFFFF::16, length::16, exp_body::bytes, 0::size(padding_length)-unit(8)>>
|
||||
end
|
||||
|
||||
def read(<<@experimenter::32, @nxast::16, _::size(6)-unit(8), metadata::64, metadata_mask::64>>) do
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ defmodule Openflow.Action.Output do
|
|||
def new(port) when not is_list(port) do
|
||||
new(port_number: port)
|
||||
end
|
||||
|
||||
def new(options) when is_list(options) do
|
||||
port_no = Keyword.get(options, :port_number)
|
||||
max_len = Keyword.get(options, :max_len, :no_buffer)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
defmodule Openflow.Action.PushPbb do
|
||||
defstruct(ethertype: 0x88e7)
|
||||
defstruct(ethertype: 0x88E7)
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ defmodule Openflow.Action.SetField do
|
|||
def to_binary(%SetField{field: {field, value}}) do
|
||||
match_bin =
|
||||
[{field, value}]
|
||||
|> Openflow.Match.new
|
||||
|> Openflow.Match.to_binary
|
||||
|> Openflow.Match.new()
|
||||
|> Openflow.Match.to_binary()
|
||||
|
||||
<<1::16, _length::16, padded_field::bytes>> = match_bin
|
||||
patial_len = @set_field_size - 4 + byte_size(padded_field)
|
||||
|
|
@ -28,7 +28,7 @@ defmodule Openflow.Action.SetField 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>>
|
||||
{[field|_], _rest} = Openflow.Match.read(match_bin)
|
||||
{[field | _], _rest} = Openflow.Match.read(match_bin)
|
||||
%SetField{field: field}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue