tres/lib/openflow/buckets.ex
2017-11-13 22:52:53 +09:00

54 lines
1.9 KiB
Elixir

defmodule Openflow.Bucket do
defstruct(
weight: 0,
watch_port: 0,
watch_group: 0,
actions: []
)
alias __MODULE__
@header_size 16
def new(options) do
weight = Keyword.get(options, :weight, 0)
watch_port = Keyword.get(options, :watch_port, :any)
watch_group = Keyword.get(options, :watch_group, :any)
actions = Keyword.get(options, :actions, [])
%Bucket{weight: weight, watch_port: watch_port, watch_group: watch_group, actions: actions}
end
def read(buckets_bin) do
do_read([], buckets_bin)
end
def to_binary(buckets) do
to_binary("", buckets)
end
# private functions
defp do_read(acc, ""), do: Enum.reverse(acc)
defp do_read(acc, <<length::16, weight::16, watch_port_int::32,
watch_group_int::32, _::size(4)-unit(8), binary::bytes>>) do
actions_len = length - @header_size
<<actions_bin::size(actions_len)-bytes, rest::bytes>> = binary
watch_port = Openflow.Utils.get_enum(watch_port_int, :openflow13_port_no)
watch_group = Openflow.Utils.get_enum(watch_group_int, :group_id)
actions = Openflow.Action.read(actions_bin)
bucket = %Bucket{weight: weight, watch_port: watch_port, watch_group: watch_group, actions: actions}
do_read([bucket|acc], rest)
end
defp to_binary(acc, []), do: acc
defp to_binary(acc, [bucket|rest]) do
%Bucket{weight: weight, watch_port: watch_port, watch_group: watch_group, actions: actions} = bucket
watch_port_int = Openflow.Utils.get_enum(watch_port, :openflow13_port_no)
watch_group_int = Openflow.Utils.get_enum(watch_group, :group_id)
actions_bin = Openflow.Action.to_binary(actions)
length = byte_size(actions_bin) + @header_size
bucket_bin = <<length::16, weight::16, watch_port_int::32,
watch_group_int::32, 0::size(4)-unit(8), actions_bin::bytes>>
to_binary(<<acc::bytes, bucket_bin::bytes>>, rest)
end
end