Formatted
This commit is contained in:
parent
5fc01a9bec
commit
7635272fbd
150 changed files with 5055 additions and 4032 deletions
|
|
@ -1,11 +1,11 @@
|
|||
defmodule Openflow.Match do
|
||||
@match_size 8
|
||||
@match_size 8
|
||||
@header_size 4
|
||||
|
||||
defstruct([
|
||||
type: :oxm,
|
||||
defstruct(
|
||||
type: :oxm,
|
||||
fields: []
|
||||
])
|
||||
)
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
|
|
@ -13,6 +13,7 @@ defmodule Openflow.Match do
|
|||
oxm_fields =
|
||||
fields
|
||||
|> keyword_to_oxm_fields([])
|
||||
|
||||
%Match{type: :oxm, fields: oxm_fields}
|
||||
end
|
||||
|
||||
|
|
@ -20,7 +21,10 @@ defmodule Openflow.Match do
|
|||
<<1::16, no_pad_len::16, binary1::binary>> = binary
|
||||
padding_length = Openflow.Utils.pad_length(no_pad_len, 8)
|
||||
match_field_len = no_pad_len - @header_size
|
||||
<<match_fields::size(match_field_len)-binary, _::size(padding_length)-unit(8), rest::bitstring>> = binary1
|
||||
|
||||
<<match_fields::size(match_field_len)-binary, _::size(padding_length)-unit(8),
|
||||
rest::bitstring>> = binary1
|
||||
|
||||
{decode_fields(match_fields, []), rest}
|
||||
end
|
||||
|
||||
|
|
@ -33,14 +37,17 @@ defmodule Openflow.Match do
|
|||
end
|
||||
|
||||
def codec_header(oxm_field0) when is_atom(oxm_field0) do
|
||||
oxm_field = case has_mask(oxm_field0) do
|
||||
1 ->
|
||||
string = to_string(oxm_field0)
|
||||
"masked_" <> field = string
|
||||
String.to_atom(field)
|
||||
0 ->
|
||||
oxm_field0
|
||||
end
|
||||
oxm_field =
|
||||
case has_mask(oxm_field0) do
|
||||
1 ->
|
||||
string = to_string(oxm_field0)
|
||||
"masked_" <> field = string
|
||||
String.to_atom(field)
|
||||
|
||||
0 ->
|
||||
oxm_field0
|
||||
end
|
||||
|
||||
case Openflow.Match.Field.vendor_of(oxm_field) do
|
||||
oxm_class when oxm_class in [:nxm_0, :nxm_1, :openflow_basic, :packet_register] ->
|
||||
oxm_class_int = Openflow.Enums.to_int(oxm_class, :oxm_class)
|
||||
|
|
@ -48,8 +55,9 @@ defmodule Openflow.Match do
|
|||
oxm_length = div(Openflow.Match.Field.n_bits_of(oxm_field), 8)
|
||||
has_mask = has_mask(oxm_field0)
|
||||
<<oxm_class_int::16, oxm_field_int::7, has_mask::1, oxm_length::8>>
|
||||
|
||||
experimenter when experimenter in [:nicira_ext_match, :onf_ext_match, :hp_ext_match] ->
|
||||
oxm_class_int = 0xffff
|
||||
oxm_class_int = 0xFFFF
|
||||
experimenter_int = Openflow.Enums.to_int(experimenter, :experimenter_oxm_vendors)
|
||||
oxm_field_int = Openflow.Enums.to_int(oxm_field, experimenter)
|
||||
oxm_length = div(Openflow.Match.Field.n_bits_of(oxm_field) + 4, 8)
|
||||
|
|
@ -57,41 +65,63 @@ defmodule Openflow.Match do
|
|||
<<oxm_class_int::16, oxm_field_int::7, has_mask::1, oxm_length::8, experimenter_int::32>>
|
||||
end
|
||||
end
|
||||
|
||||
def codec_header(<<oxm_class_int::16, oxm_field_int::7, oxm_has_mask::1, _oxm_length::8>>) do
|
||||
oxm_class = Openflow.Enums.to_atom(oxm_class_int, :oxm_class)
|
||||
|
||||
case oxm_has_mask do
|
||||
0 -> Openflow.Enums.to_atom(oxm_field_int, oxm_class)
|
||||
0 ->
|
||||
Openflow.Enums.to_atom(oxm_field_int, oxm_class)
|
||||
|
||||
1 ->
|
||||
field_str =
|
||||
oxm_field_int
|
||||
|> Openflow.Enums.to_atom(oxm_class)
|
||||
|> to_string
|
||||
|
||||
String.to_atom("masked_" <> field_str)
|
||||
end
|
||||
end
|
||||
def codec_header(<<0xffff::16, oxm_field_int::7, oxm_has_mask::1, _oxm_length::8, experimenter_int::32>>) do
|
||||
|
||||
def codec_header(
|
||||
<<0xFFFF::16, oxm_field_int::7, oxm_has_mask::1, _oxm_length::8, experimenter_int::32>>
|
||||
) do
|
||||
experimenter = Openflow.Enums.to_atom(experimenter_int, :experimenter_oxm_vendors)
|
||||
Openflow.Enums.to_atom(oxm_field_int, experimenter)
|
||||
|
||||
case oxm_has_mask do
|
||||
0 -> Openflow.Enums.to_atom(oxm_field_int, experimenter)
|
||||
0 ->
|
||||
Openflow.Enums.to_atom(oxm_field_int, experimenter)
|
||||
|
||||
1 ->
|
||||
field_str =
|
||||
oxm_field_int
|
||||
|> Openflow.Enums.to_atom(experimenter)
|
||||
|> to_string
|
||||
|
||||
String.to_atom("masked_" <> field_str)
|
||||
end
|
||||
end
|
||||
|
||||
def header_size(<<_oxm_class_int::16, _oxm_field_int::7, _oxm_has_mask::1, _oxm_length::8, _::bytes>>),
|
||||
do: 4
|
||||
def header_size(<<0xffff::16, _oxm_field_int::7, _oxm_has_mask::1, _oxm_length::8, _exp_int::32, _::bytes>>),
|
||||
do: 8
|
||||
def header_size(
|
||||
<<_oxm_class_int::16, _oxm_field_int::7, _oxm_has_mask::1, _oxm_length::8, _::bytes>>
|
||||
),
|
||||
do: 4
|
||||
|
||||
def header_size(
|
||||
<<0xFFFF::16, _oxm_field_int::7, _oxm_has_mask::1, _oxm_length::8, _exp_int::32,
|
||||
_::bytes>>
|
||||
),
|
||||
do: 8
|
||||
|
||||
# private functions
|
||||
|
||||
defp decode_fields(<<>>, acc), do: Enum.reverse(acc)
|
||||
defp decode_fields(<<0xffff::16, _::7, 1::1, length::8, vendor_int::32, field_int::16, binary::bytes>>, acc) do
|
||||
|
||||
defp decode_fields(
|
||||
<<0xFFFF::16, _::7, 1::1, length::8, vendor_int::32, field_int::16, binary::bytes>>,
|
||||
acc
|
||||
) do
|
||||
length = length - 6
|
||||
field_len = div(length, 2)
|
||||
<<value_bin::size(field_len)-bytes, mask_bin::size(field_len)-bytes, rest::bytes>> = binary
|
||||
|
|
@ -99,16 +129,21 @@ defmodule Openflow.Match do
|
|||
field_name = Openflow.Enums.to_atom(field_int, experimenter)
|
||||
value = Openflow.Match.Field.codec(value_bin, field_name)
|
||||
mask = Openflow.Match.Field.codec(mask_bin, field_name)
|
||||
decode_fields(rest, [{field_name, {value, mask}}|acc])
|
||||
decode_fields(rest, [{field_name, {value, mask}} | acc])
|
||||
end
|
||||
defp decode_fields(<<0xffff::16, _::7, 0::1, length::8, vendor_int::32, field_int::16, binary::bytes>>, acc) do
|
||||
|
||||
defp decode_fields(
|
||||
<<0xFFFF::16, _::7, 0::1, length::8, vendor_int::32, field_int::16, binary::bytes>>,
|
||||
acc
|
||||
) do
|
||||
length = length - 6
|
||||
<<value_bin::size(length)-bytes, rest::bytes>> = binary
|
||||
experimenter = Openflow.Enums.to_atom(vendor_int, :experimenter_oxm_vendors)
|
||||
field_name = Openflow.Enums.to_atom(field_int, experimenter)
|
||||
value = Openflow.Match.Field.codec(value_bin, field_name)
|
||||
decode_fields(rest, [{field_name, value}|acc])
|
||||
decode_fields(rest, [{field_name, value} | acc])
|
||||
end
|
||||
|
||||
defp decode_fields(<<class_int::16, field_int::7, 1::1, length::8, binary::bytes>>, acc) do
|
||||
field_len = div(length, 2)
|
||||
<<value_bin::size(field_len)-bytes, mask_bin::size(field_len)-bytes, rest::bytes>> = binary
|
||||
|
|
@ -116,37 +151,43 @@ defmodule Openflow.Match do
|
|||
field_name = Openflow.Enums.to_atom(field_int, class)
|
||||
value = Openflow.Match.Field.codec(value_bin, field_name)
|
||||
mask = Openflow.Match.Field.codec(mask_bin, field_name)
|
||||
decode_fields(rest, [{field_name, {value, mask}}|acc])
|
||||
decode_fields(rest, [{field_name, {value, mask}} | acc])
|
||||
end
|
||||
|
||||
defp decode_fields(<<class_int::16, field_int::7, 0::1, length::8, binary::bytes>>, acc) do
|
||||
<<value_bin::size(length)-bytes, rest::bytes>> = binary
|
||||
class = Openflow.Enums.to_atom(class_int, :oxm_class)
|
||||
field_name = Openflow.Enums.to_atom(field_int, class)
|
||||
value = Openflow.Match.Field.codec(value_bin, field_name)
|
||||
decode_fields(rest, [{field_name, value}|acc])
|
||||
decode_fields(rest, [{field_name, value} | acc])
|
||||
end
|
||||
|
||||
defp encode_fields([], acc), do: acc
|
||||
defp encode_fields([field|fields], acc) do
|
||||
encode_fields(fields, <<acc::bytes, (encode_field(field))::bytes>>)
|
||||
|
||||
defp encode_fields([field | fields], acc) do
|
||||
encode_fields(fields, <<acc::bytes, encode_field(field)::bytes>>)
|
||||
end
|
||||
|
||||
defp encode_field(%{class: class, field: field, has_mask: true, value: value, mask: mask})
|
||||
when class == :nicira_ext_match or class == :onf_ext_match do
|
||||
when class == :nicira_ext_match or class == :onf_ext_match do
|
||||
vendor_int = Openflow.Enums.to_int(class, :experimenter_oxm_vendors)
|
||||
field_int = Openflow.Enums.to_int(field, class)
|
||||
has_mask_int = 1
|
||||
length = (byte_size(value) * 2) + 6
|
||||
<<0xffff::16, 0::7, has_mask_int::1, length::8, vendor_int::32, field_int::16, value::bytes, mask::bytes>>
|
||||
length = byte_size(value) * 2 + 6
|
||||
|
||||
<<0xFFFF::16, 0::7, has_mask_int::1, length::8, vendor_int::32, field_int::16, value::bytes,
|
||||
mask::bytes>>
|
||||
end
|
||||
|
||||
defp encode_field(%{class: class, field: field, has_mask: false, value: value})
|
||||
when class == :nicira_ext_match or class == :onf_ext_match do
|
||||
when class == :nicira_ext_match or class == :onf_ext_match do
|
||||
vendor_int = Openflow.Enums.to_int(class, :experimenter_oxm_vendors)
|
||||
field_int = Openflow.Enums.to_int(field, class)
|
||||
has_mask_int = 0
|
||||
length = byte_size(value) + 6
|
||||
<<0xffff::16, 0::7, has_mask_int::1, length::8, vendor_int::32, field_int::16, value::bytes>>
|
||||
<<0xFFFF::16, 0::7, has_mask_int::1, length::8, vendor_int::32, field_int::16, value::bytes>>
|
||||
end
|
||||
|
||||
defp encode_field(%{class: class, field: field, has_mask: true, value: value, mask: mask}) do
|
||||
class_int = Openflow.Enums.to_int(class, :oxm_class)
|
||||
field_int = Openflow.Enums.to_int(field, class)
|
||||
|
|
@ -154,6 +195,7 @@ defmodule Openflow.Match do
|
|||
length = byte_size(value) * 2
|
||||
<<class_int::16, field_int::7, has_mask_int::1, length::8, value::bytes, mask::bytes>>
|
||||
end
|
||||
|
||||
defp encode_field(%{class: class, field: field, has_mask: false, value: value}) do
|
||||
class_int = Openflow.Enums.to_int(class, :oxm_class)
|
||||
field_int = Openflow.Enums.to_int(field, class)
|
||||
|
|
@ -163,8 +205,9 @@ defmodule Openflow.Match do
|
|||
end
|
||||
|
||||
defp keyword_to_oxm_fields([], acc), do: Enum.reverse(acc)
|
||||
defp keyword_to_oxm_fields([{field_name, field_value}|fields], acc) do
|
||||
keyword_to_oxm_fields(fields, [oxm_field(field_name, field_value)|acc])
|
||||
|
||||
defp keyword_to_oxm_fields([{field_name, field_value} | fields], acc) do
|
||||
keyword_to_oxm_fields(fields, [oxm_field(field_name, field_value) | acc])
|
||||
end
|
||||
|
||||
defp oxm_field(field_name, {value, mask}) do
|
||||
|
|
@ -173,6 +216,7 @@ defmodule Openflow.Match do
|
|||
match_class = Openflow.Match.Field.vendor_of(field_name)
|
||||
%{class: match_class, field: field_name, has_mask: true, value: value_bin, mask: mask_bin}
|
||||
end
|
||||
|
||||
defp oxm_field(field_name, value) do
|
||||
value_bin = Openflow.Match.Field.codec(value, field_name)
|
||||
match_class = Openflow.Match.Field.vendor_of(field_name)
|
||||
|
|
@ -184,6 +228,7 @@ defmodule Openflow.Match do
|
|||
oxm_field
|
||||
|> to_string
|
||||
|> String.match?(~r/^masked_/)
|
||||
|
||||
if has_mask? do
|
||||
1
|
||||
else
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue