tres/lib/openflow/actions/nx_flow_spec_output.ex
2019-05-05 23:39:45 +09:00

51 lines
1.3 KiB
Elixir

defmodule Openflow.Action.NxFlowSpecOutput do
defstruct(
n_bits: 0,
src: nil,
src_offset: 0
)
@learn_src_field 0
@learn_dst 2
alias __MODULE__
@type t :: %NxFlowSpecOutput{
n_bits: non_neg_integer(),
src: atom(),
src_offset: non_neg_integer()
}
@spec new(src: atom(), n_bits: non_neg_integer(), src_offset: non_neg_integer()) :: t()
def new(options \\ []) do
src = options[:src] || raise ":src must be specified"
n_bits = options[:n_bits] || Openflow.Match.Field.n_bits_of(src)
%NxFlowSpecOutput{n_bits: n_bits, src: src, src_offset: options[:src_offset] || 0}
end
@spec to_binary(t()) :: binary()
def to_binary(%NxFlowSpecOutput{} = flow_spec) do
<<
0::2,
@learn_src_field::1,
@learn_dst::2,
flow_spec.n_bits::11,
Openflow.Match.codec_header(flow_spec.src)::4-bytes,
flow_spec.src_offset::16
>>
end
@spec read(binary()) :: {t(), binary()}
def read(
<<0::2, @learn_src_field::1, @learn_dst::2, n_bits::11, src_bin::4-bytes, src_ofs::16,
rest::bitstring>>
) do
flow_spec = %NxFlowSpecOutput{
n_bits: n_bits,
src: Openflow.Match.codec_header(src_bin),
src_offset: src_ofs
}
{flow_spec, rest}
end
end