Openflow parser
This commit is contained in:
parent
70b0d8919e
commit
fc02a678de
338 changed files with 9081 additions and 0 deletions
19
lib/openflow/multipart/aggregate/reply.ex
Normal file
19
lib/openflow/multipart/aggregate/reply.ex
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
defmodule Openflow.Multipart.Aggregate.Reply do
|
||||
defstruct(
|
||||
version: 4,
|
||||
xid: 0,
|
||||
datapath_id: nil, # virtual field
|
||||
flags: [],
|
||||
packet_count: 0,
|
||||
byte_count: 0,
|
||||
flow_count: 0
|
||||
)
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
def ofp_type, do: 18
|
||||
|
||||
def read(<<packet_count::64, byte_count::64, flow_count::32, _::size(4)-unit(8)>>) do
|
||||
%Reply{packet_count: packet_count, byte_count: byte_count, flow_count: flow_count}
|
||||
end
|
||||
end
|
||||
67
lib/openflow/multipart/aggregate/request.ex
Normal file
67
lib/openflow/multipart/aggregate/request.ex
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
defmodule Openflow.Multipart.Aggregate.Request do
|
||||
defstruct(
|
||||
version: 4,
|
||||
xid: 0,
|
||||
datapath_id: nil, # virtual field
|
||||
flags: [],
|
||||
table_id: :all,
|
||||
out_port: :any,
|
||||
out_group: :any,
|
||||
cookie: 0,
|
||||
cookie_mask: 0,
|
||||
match: []
|
||||
)
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
def ofp_type, do: 18
|
||||
|
||||
def new(options) do
|
||||
table_id = Keyword.get(options, :table_id, :all)
|
||||
out_port = Keyword.get(options, :out_port, :any)
|
||||
out_group = Keyword.get(options, :out_group, :any)
|
||||
cookie = Keyword.get(options, :cookie, 0)
|
||||
cookie_mask = Keyword.get(options, :cookie, 0)
|
||||
match = Keyword.get(options, :match, [])
|
||||
%Request{table_id: table_id,
|
||||
out_port: out_port,
|
||||
out_group: out_group,
|
||||
cookie: cookie,
|
||||
cookie_mask: cookie_mask,
|
||||
match: match}
|
||||
end
|
||||
|
||||
def read(<<table_id_int::8, _::size(3)-unit(8),
|
||||
out_port_int::32, out_group_int::32,
|
||||
_::size(4)-unit(8), cookie::64,
|
||||
cookie_mask::64, match_bin::bytes>>) do
|
||||
table_id = Openflow.Utils.get_enum(table_id_int, :table_id)
|
||||
out_port = Openflow.Utils.get_enum(out_port_int, :openflow13_port_no)
|
||||
out_group = Openflow.Utils.get_enum(out_group_int, :group_id)
|
||||
{match, _rest} = Openflow.Match.read(match_bin)
|
||||
%Request{table_id: table_id,
|
||||
out_port: out_port,
|
||||
out_group: out_group,
|
||||
cookie: cookie,
|
||||
cookie_mask: cookie_mask,
|
||||
match: match}
|
||||
end
|
||||
|
||||
def to_binary(%Request{table_id: table_id,
|
||||
out_port: out_port,
|
||||
out_group: out_group,
|
||||
cookie: cookie,
|
||||
cookie_mask: cookie_mask,
|
||||
match: match} = msg) do
|
||||
table_id_int = Openflow.Utils.get_enum(table_id, :table_id)
|
||||
out_port_int = Openflow.Utils.get_enum(out_port, :openflow13_port_no)
|
||||
out_group_int = Openflow.Utils.get_enum(out_group, :group_id)
|
||||
match_bin = Openflow.Match.to_binary(match)
|
||||
body_bin = <<table_id_int::8, 0::size(3)-unit(8),
|
||||
out_port_int::32, out_group_int::32,
|
||||
0::size(4)-unit(8), cookie::64,
|
||||
cookie_mask::64, match_bin::bytes>>
|
||||
header_bin = Openflow.Multipart.Request.header(msg)
|
||||
<<header_bin::bytes, body_bin::bytes>>
|
||||
end
|
||||
end
|
||||
30
lib/openflow/multipart/desc/reply.ex
Normal file
30
lib/openflow/multipart/desc/reply.ex
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
defmodule Openflow.Multipart.Desc.Reply do
|
||||
defstruct(
|
||||
version: 4,
|
||||
xid: 0,
|
||||
datapath_id: nil, # virtual field
|
||||
flags: [],
|
||||
mfr_desc: "",
|
||||
hw_desc: "",
|
||||
sw_desc: "",
|
||||
serial_num: "",
|
||||
dp_desc: ""
|
||||
)
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
@desc_str_len 256
|
||||
@serial_num_len 32
|
||||
|
||||
def ofp_type, do: 19
|
||||
|
||||
def read(<<mfr_desc::size(@desc_str_len)-bytes, hw_desc::size(@desc_str_len)-bytes,
|
||||
sw_desc::size(@desc_str_len)-bytes, serial_num::size(@serial_num_len)-bytes,
|
||||
dp_desc::size(@desc_str_len)-bytes>>) do
|
||||
%Reply{mfr_desc: Openflow.Utils.decode_string(mfr_desc),
|
||||
hw_desc: Openflow.Utils.decode_string(hw_desc),
|
||||
sw_desc: Openflow.Utils.decode_string(sw_desc),
|
||||
serial_num: Openflow.Utils.decode_string(serial_num),
|
||||
dp_desc: Openflow.Utils.decode_string(dp_desc)}
|
||||
end
|
||||
end
|
||||
24
lib/openflow/multipart/desc/request.ex
Normal file
24
lib/openflow/multipart/desc/request.ex
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
defmodule Openflow.Multipart.Desc.Request do
|
||||
defstruct(
|
||||
version: 4,
|
||||
xid: 0,
|
||||
datapath_id: nil, # virtual field
|
||||
flags: []
|
||||
)
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
def ofp_type, do: 18
|
||||
|
||||
def new do
|
||||
%Request{}
|
||||
end
|
||||
|
||||
def read("") do
|
||||
%Request{}
|
||||
end
|
||||
|
||||
def to_binary(%Request{} = msg) do
|
||||
Openflow.Multipart.Request.header(msg)
|
||||
end
|
||||
end
|
||||
75
lib/openflow/multipart/flow/reply.ex
Normal file
75
lib/openflow/multipart/flow/reply.ex
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
defmodule Openflow.Multipart.Flow.Reply do
|
||||
defstruct(
|
||||
version: 4,
|
||||
xid: 0,
|
||||
datapath_id: nil, # virtual field
|
||||
flags: [],
|
||||
flows: []
|
||||
)
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
def ofp_type, do: 18
|
||||
|
||||
def new(flows \\ []) do
|
||||
%Reply{flows: flows}
|
||||
end
|
||||
|
||||
def read(<<flows_bin::bytes>>) do
|
||||
flows = Openflow.Multipart.FlowStats.read(flows_bin)
|
||||
%Reply{flows: flows}
|
||||
end
|
||||
end
|
||||
|
||||
defmodule Openflow.Multipart.FlowStats do
|
||||
defstruct(
|
||||
table_id: 0,
|
||||
duration_sec: 0,
|
||||
duration_nsec: 0,
|
||||
priority: 0,
|
||||
idle_timeout: 0,
|
||||
hard_timeout: 0,
|
||||
flags: 0,
|
||||
cookie: 0,
|
||||
packet_count: 0,
|
||||
byte_count: 0,
|
||||
match: [],
|
||||
instructions: []
|
||||
)
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
def read(binary) do
|
||||
do_read([], binary)
|
||||
end
|
||||
|
||||
# private functions
|
||||
|
||||
defp do_read(acc, ""), do: Enum.reverse(acc)
|
||||
defp do_read(acc, <<length::16, _tail::bytes>> = binary) do
|
||||
<<flow_stats_bin::size(length)-bytes, rest::bytes>> = binary
|
||||
do_read([codec(flow_stats_bin)|acc], rest)
|
||||
end
|
||||
|
||||
defp codec(<<_length::16, table_id_int::8, 0::8, duration_sec::32,
|
||||
duration_nsec::32, priority::16, idle::16, hard::16,
|
||||
flags_int::16, _::size(4)-unit(8), cookie::64,
|
||||
packet_count::64, byte_count::64, tail::bytes>>) do
|
||||
{match, instructions_bin} = Openflow.Match.read(tail)
|
||||
table_id = Openflow.Utils.get_enum(table_id_int, :table_id)
|
||||
flags = Openflow.Enums.int_to_flags(flags_int, :flow_mod_flags)
|
||||
instructions = Openflow.Instruction.read(instructions_bin)
|
||||
%FlowStats{table_id: table_id,
|
||||
duration_sec: duration_sec,
|
||||
duration_nsec: duration_nsec,
|
||||
priority: priority,
|
||||
idle_timeout: idle,
|
||||
hard_timeout: hard,
|
||||
flags: flags,
|
||||
cookie: cookie,
|
||||
packet_count: packet_count,
|
||||
byte_count: byte_count,
|
||||
match: match,
|
||||
instructions: instructions}
|
||||
end
|
||||
end
|
||||
67
lib/openflow/multipart/flow/request.ex
Normal file
67
lib/openflow/multipart/flow/request.ex
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
defmodule Openflow.Multipart.Flow.Request do
|
||||
defstruct(
|
||||
version: 4,
|
||||
xid: 0,
|
||||
datapath_id: nil, # virtual field
|
||||
flags: [],
|
||||
table_id: :all,
|
||||
out_port: :any,
|
||||
out_group: :any,
|
||||
cookie: 0,
|
||||
cookie_mask: 0,
|
||||
match: []
|
||||
)
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
def ofp_type, do: 18
|
||||
|
||||
def new(options) do
|
||||
table_id = Keyword.get(options, :table_id, :all)
|
||||
out_port = Keyword.get(options, :out_port, :any)
|
||||
out_group = Keyword.get(options, :out_group, :any)
|
||||
cookie = Keyword.get(options, :cookie, 0)
|
||||
cookie_mask = Keyword.get(options, :cookie, 0)
|
||||
match = Keyword.get(options, :match, [])
|
||||
%Request{table_id: table_id,
|
||||
out_port: out_port,
|
||||
out_group: out_group,
|
||||
cookie: cookie,
|
||||
cookie_mask: cookie_mask,
|
||||
match: match}
|
||||
end
|
||||
|
||||
def read(<<table_id_int::8, _::size(3)-unit(8),
|
||||
out_port_int::32, out_group_int::32,
|
||||
_::size(4)-unit(8), cookie::64,
|
||||
cookie_mask::64, match_bin::bytes>>) do
|
||||
table_id = Openflow.Utils.get_enum(table_id_int, :table_id)
|
||||
out_port = Openflow.Utils.get_enum(out_port_int, :openflow13_port_no)
|
||||
out_group = Openflow.Utils.get_enum(out_group_int, :group_id)
|
||||
{match, _rest} = Openflow.Match.read(match_bin)
|
||||
%Request{table_id: table_id,
|
||||
out_port: out_port,
|
||||
out_group: out_group,
|
||||
cookie: cookie,
|
||||
cookie_mask: cookie_mask,
|
||||
match: match}
|
||||
end
|
||||
|
||||
def to_binary(%Request{table_id: table_id,
|
||||
out_port: out_port,
|
||||
out_group: out_group,
|
||||
cookie: cookie,
|
||||
cookie_mask: cookie_mask,
|
||||
match: match} = msg) do
|
||||
table_id_int = Openflow.Utils.get_enum(table_id, :table_id)
|
||||
out_port_int = Openflow.Utils.get_enum(out_port, :openflow13_port_no)
|
||||
out_group_int = Openflow.Utils.get_enum(out_group, :group_id)
|
||||
match_bin = Openflow.Match.to_binary(match)
|
||||
body_bin = <<table_id_int::8, 0::size(3)-unit(8),
|
||||
out_port_int::32, out_group_int::32,
|
||||
0::size(4)-unit(8), cookie::64,
|
||||
cookie_mask::64, match_bin::bytes>>
|
||||
header_bin = Openflow.Multipart.Request.header(msg)
|
||||
<<header_bin::bytes, body_bin::bytes>>
|
||||
end
|
||||
end
|
||||
1
lib/openflow/multipart/group/ *Minibuf-1*
Normal file
1
lib/openflow/multipart/group/ *Minibuf-1*
Normal file
|
|
@ -0,0 +1 @@
|
|||
Replace regexp Queue with: Group
|
||||
1
lib/openflow/multipart/group/.# *Minibuf-1*
Symbolic link
1
lib/openflow/multipart/group/.# *Minibuf-1*
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
shun159@shun159.8967:1509553730
|
||||
69
lib/openflow/multipart/group/reply.ex
Normal file
69
lib/openflow/multipart/group/reply.ex
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
defmodule Openflow.Multipart.Group.Reply do
|
||||
defstruct(
|
||||
version: 4,
|
||||
xid: 0,
|
||||
datapath_id: nil, # virtual field
|
||||
flags: [],
|
||||
groups: []
|
||||
)
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
def ofp_type, do: 18
|
||||
|
||||
def new(groups \\ []) do
|
||||
%Reply{groups: groups}
|
||||
end
|
||||
|
||||
def read(<<groups_bin::bytes>>) do
|
||||
groups = Openflow.Multipart.Group.read(groups_bin)
|
||||
%Reply{groups: groups}
|
||||
end
|
||||
end
|
||||
|
||||
defmodule Openflow.Multipart.Group do
|
||||
defstruct(
|
||||
group_id: 0,
|
||||
ref_count: 0,
|
||||
packet_count: 0,
|
||||
byte_count: 0,
|
||||
duration_sec: 0,
|
||||
duration_nsec: 0,
|
||||
bucket_stats: []
|
||||
)
|
||||
|
||||
@ofp_group_stats_size 40
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
def read(binary) do
|
||||
do_read([], binary)
|
||||
end
|
||||
|
||||
# private functions
|
||||
|
||||
defp do_read(acc, ""), do: Enum.reverse(acc)
|
||||
defp do_read(acc, <<length::16, _binary::bytes>> = binary) do
|
||||
<<group_bin::size(length)-bytes, rest::bytes>> = binary
|
||||
do_read([codec(group_bin)|acc], rest)
|
||||
end
|
||||
|
||||
defp codec(<<length::16, _::size(2)-unit(8),
|
||||
group_id::32, ref_count::32,
|
||||
_::size(4)-unit(8), packet_count::64,
|
||||
byte_count::64, duration_sec::32,
|
||||
duration_nsec::32, tail::bytes>>) do
|
||||
bucket_stats_size = length - @ofp_group_stats_size
|
||||
<<bucket_stats_bin::size(bucket_stats_size)-bytes, _rest::bytes>> = tail
|
||||
bucket_stats = for <<packet_count::64, byte_count::64 <- bucket_stats_bin>> do
|
||||
%{packet_count: packet_count, byte_count: byte_count}
|
||||
end
|
||||
%Group{group_id: group_id,
|
||||
ref_count: ref_count,
|
||||
packet_count: packet_count,
|
||||
byte_count: byte_count,
|
||||
duration_sec: duration_sec,
|
||||
duration_nsec: duration_nsec,
|
||||
bucket_stats: bucket_stats}
|
||||
end
|
||||
end
|
||||
29
lib/openflow/multipart/group/request.ex
Normal file
29
lib/openflow/multipart/group/request.ex
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
defmodule Openflow.Multipart.Group.Request do
|
||||
defstruct(
|
||||
version: 4,
|
||||
xid: 0,
|
||||
datapath_id: nil, # virtual field
|
||||
flags: [],
|
||||
group_id: :all
|
||||
)
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
def ofp_type, do: 18
|
||||
|
||||
def new(group_id \\ :all) do
|
||||
%Request{group_id: group_id}
|
||||
end
|
||||
|
||||
def read(<<group_id_int::32, _::size(4)-unit(8)>>) do
|
||||
group_id = Openflow.Utils.get_enum(group_id_int, :group_id)
|
||||
%Request{group_id: group_id}
|
||||
end
|
||||
|
||||
def to_binary(%Request{group_id: group_id} = msg) do
|
||||
group_id_int = Openflow.Utils.get_enum(group_id, :group_id)
|
||||
body_bin = <<group_id_int::32, 0::size(4)-unit(8)>>
|
||||
header_bin = Openflow.Multipart.Request.header(msg)
|
||||
<<header_bin::bytes, body_bin::bytes>>
|
||||
end
|
||||
end
|
||||
54
lib/openflow/multipart/group_desc/reply.ex
Normal file
54
lib/openflow/multipart/group_desc/reply.ex
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
defmodule Openflow.Multipart.GroupDesc.Reply do
|
||||
defstruct(
|
||||
version: 4,
|
||||
xid: 0,
|
||||
datapath_id: nil, # virtual field
|
||||
flags: [],
|
||||
groups: []
|
||||
)
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
def ofp_type, do: 18
|
||||
|
||||
def new(groups \\ []) do
|
||||
%Reply{groups: groups}
|
||||
end
|
||||
|
||||
def read(<<groups_bin::bytes>>) do
|
||||
groups = Openflow.Multipart.GroupDescStats.read(groups_bin)
|
||||
%Reply{groups: groups}
|
||||
end
|
||||
end
|
||||
|
||||
defmodule Openflow.Multipart.GroupDescStats do
|
||||
defstruct(
|
||||
type: :all,
|
||||
group_id: 0,
|
||||
buckets: []
|
||||
)
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
@ofp_group_desc_size 8
|
||||
|
||||
def read(binary) do
|
||||
do_read([], binary)
|
||||
end
|
||||
|
||||
# private functions
|
||||
|
||||
defp do_read(acc, ""), do: Enum.reverse(acc)
|
||||
defp do_read(acc, <<length::16, _tail::bytes>> = binary) do
|
||||
<<group_stats_bin::size(length)-bytes, rest::bytes>> = binary
|
||||
do_read([codec(group_stats_bin)|acc], rest)
|
||||
end
|
||||
|
||||
defp codec(<<length::16, type_int::8, _::8, group_id::32, tail::bytes>>) do
|
||||
buckets_bin_len = length - @ofp_group_desc_size
|
||||
<<buckets_bin::size(buckets_bin_len)-bytes, _::bytes>> = tail
|
||||
type = Openflow.Enums.to_atom(type_int, :group_type)
|
||||
buckets = Openflow.Bucket.read(buckets_bin)
|
||||
%GroupDescStats{type: type, group_id: group_id, buckets: buckets}
|
||||
end
|
||||
end
|
||||
24
lib/openflow/multipart/group_desc/request.ex
Normal file
24
lib/openflow/multipart/group_desc/request.ex
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
defmodule Openflow.Multipart.GroupDesc.Request do
|
||||
defstruct(
|
||||
version: 4,
|
||||
xid: 0,
|
||||
datapath_id: nil, # virtual field
|
||||
flags: []
|
||||
)
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
def ofp_type, do: 18
|
||||
|
||||
def new do
|
||||
%Request{}
|
||||
end
|
||||
|
||||
def read("") do
|
||||
%Request{}
|
||||
end
|
||||
|
||||
def to_binary(%Request{} = msg) do
|
||||
Openflow.Multipart.Request.header(msg)
|
||||
end
|
||||
end
|
||||
44
lib/openflow/multipart/group_features/reply.ex
Normal file
44
lib/openflow/multipart/group_features/reply.ex
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
defmodule Openflow.Multipart.GroupFeatures.Reply do
|
||||
defstruct(
|
||||
version: 4,
|
||||
xid: 0,
|
||||
datapath_id: nil, # virtual field
|
||||
flags: [],
|
||||
types: 0,
|
||||
capabilities: [],
|
||||
max_groups_for_all: 0,
|
||||
max_groups_for_select: 0,
|
||||
max_groups_for_indirect: 0,
|
||||
max_groups_for_fast_failover: 0,
|
||||
actions_for_all: 0,
|
||||
actions_for_select: 0,
|
||||
actions_for_indirect: 0,
|
||||
actions_for_fast_failover: 0
|
||||
)
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
def ofp_type, do: 18
|
||||
|
||||
def read(<<types_int::32, capabilities_int::32,
|
||||
max_groups_for_all_int::32,
|
||||
max_groups_for_select_int::32,
|
||||
max_groups_for_indirect_int::32,
|
||||
max_groups_for_fast_failover_int::32,
|
||||
actions_for_all_int::32,
|
||||
actions_for_select_int::32,
|
||||
actions_for_indirect_int::32,
|
||||
actions_for_fast_failover_int::32>>) do
|
||||
capabilities = Openflow.Enums.int_to_flags(capabilities_int, :group_capabilities)
|
||||
%Reply{types: types_int,
|
||||
capabilities: capabilities,
|
||||
max_groups_for_all: max_groups_for_all_int,
|
||||
max_groups_for_select: max_groups_for_select_int,
|
||||
max_groups_for_indirect: max_groups_for_indirect_int,
|
||||
max_groups_for_fast_failover: max_groups_for_fast_failover_int,
|
||||
actions_for_all: actions_for_all_int,
|
||||
actions_for_select: actions_for_select_int,
|
||||
actions_for_indirect: actions_for_indirect_int,
|
||||
actions_for_fast_failover: actions_for_fast_failover_int}
|
||||
end
|
||||
end
|
||||
24
lib/openflow/multipart/group_features/request.ex
Normal file
24
lib/openflow/multipart/group_features/request.ex
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
defmodule Openflow.Multipart.GroupFeatures.Request do
|
||||
defstruct(
|
||||
version: 4,
|
||||
xid: 0,
|
||||
datapath_id: nil, # virtual field
|
||||
flags: []
|
||||
)
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
def ofp_type, do: 18
|
||||
|
||||
def new do
|
||||
%Request{}
|
||||
end
|
||||
|
||||
def read("") do
|
||||
%Request{}
|
||||
end
|
||||
|
||||
def to_binary(%Request{} = msg) do
|
||||
Openflow.Multipart.Request.header(msg)
|
||||
end
|
||||
end
|
||||
63
lib/openflow/multipart/meter/reply.ex
Normal file
63
lib/openflow/multipart/meter/reply.ex
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
defmodule Openflow.Multipart.Meter.Reply do
|
||||
defstruct(
|
||||
version: 4,
|
||||
xid: 0,
|
||||
datapath_id: nil, # virtual field
|
||||
flags: [],
|
||||
meters: []
|
||||
)
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
def ofp_type, do: 18
|
||||
|
||||
def read(<<meters_bin::bytes>>) do
|
||||
meters = Openflow.Multipart.Meter.read(meters_bin)
|
||||
%Reply{meters: meters}
|
||||
end
|
||||
end
|
||||
|
||||
defmodule Openflow.Multipart.Meter do
|
||||
defstruct(
|
||||
meter_id: 0,
|
||||
flow_count: 0,
|
||||
packet_in_count: 0,
|
||||
byte_in_count: 0,
|
||||
duration_sec: 0,
|
||||
duration_nsec: 0,
|
||||
band_stats: []
|
||||
)
|
||||
|
||||
@ofp_meter_stats_size 40
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
def read(binary) do
|
||||
do_read([], binary)
|
||||
end
|
||||
|
||||
# private functions
|
||||
|
||||
defp do_read(acc, ""), do: Enum.reverse(acc)
|
||||
defp do_read(acc, <<_::32, length::16, _binary::bytes>> = binary) do
|
||||
<<meter_bin::size(length)-bytes, rest::bytes>> = binary
|
||||
do_read([codec(meter_bin)|acc], rest)
|
||||
end
|
||||
|
||||
defp codec(<<meter_id::32, length::16, _::size(6)-unit(8),
|
||||
flow_count::32, packet_in_count::64, byte_in_count::64,
|
||||
duration_sec::32, duration_nsec::32, tail::bytes>>) do
|
||||
band_stats_size = length - @ofp_meter_stats_size
|
||||
<<band_stats_bin::size(band_stats_size)-bytes, _rest::bytes>> = tail
|
||||
band_stats = for <<packet_band_count::64, byte_band_count::64 <- band_stats_bin>> do
|
||||
%{packet_band_count: packet_band_count,byte_band_count: byte_band_count}
|
||||
end
|
||||
%Meter{meter_id: meter_id,
|
||||
flow_count: flow_count,
|
||||
packet_in_count: packet_in_count,
|
||||
byte_in_count: byte_in_count,
|
||||
duration_sec: duration_sec,
|
||||
duration_nsec: duration_nsec,
|
||||
band_stats: band_stats}
|
||||
end
|
||||
end
|
||||
29
lib/openflow/multipart/meter/request.ex
Normal file
29
lib/openflow/multipart/meter/request.ex
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
defmodule Openflow.Multipart.Meter.Request do
|
||||
defstruct(
|
||||
version: 4,
|
||||
xid: 0,
|
||||
datapath_id: nil, # virtual field
|
||||
flags: [],
|
||||
meter_id: :all
|
||||
)
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
def ofp_type, do: 18
|
||||
|
||||
def new(meter_id \\ :all) do
|
||||
%Request{meter_id: meter_id}
|
||||
end
|
||||
|
||||
def read(<<meter_id_int::32, _::size(4)-unit(8)>>) do
|
||||
meter_id = Openflow.Utils.get_enum(meter_id_int, :meter_id)
|
||||
%Request{meter_id: meter_id}
|
||||
end
|
||||
|
||||
def to_binary(%Request{meter_id: meter_id} = msg) do
|
||||
meter_id_int = Openflow.Utils.get_enum(meter_id, :meter_id)
|
||||
body_bin = <<meter_id_int::32, 0::size(4)-unit(8)>>
|
||||
header_bin = Openflow.Multipart.Request.header(msg)
|
||||
<<header_bin::bytes, body_bin::bytes>>
|
||||
end
|
||||
end
|
||||
29
lib/openflow/multipart/meter_config/request.ex
Normal file
29
lib/openflow/multipart/meter_config/request.ex
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
defmodule Openflow.Multipart.MeterConfig.Request do
|
||||
defstruct(
|
||||
version: 4,
|
||||
xid: 0,
|
||||
datapath_id: nil, # virtual field
|
||||
flags: [],
|
||||
meter_id: :all
|
||||
)
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
def ofp_type, do: 18
|
||||
|
||||
def new(meter_id \\ :all) do
|
||||
%Request{meter_id: meter_id}
|
||||
end
|
||||
|
||||
def read(<<meter_id_int::32, _::size(4)-unit(8)>>) do
|
||||
meter_id = Openflow.Utils.get_enum(meter_id_int, :meter_id)
|
||||
%Request{meter_id: meter_id}
|
||||
end
|
||||
|
||||
def to_binary(%Request{meter_id: meter_id} = msg) do
|
||||
meter_id_int = Openflow.Utils.get_enum(meter_id, :meter_id)
|
||||
body_bin = <<meter_id_int::32, 0::size(4)-unit(8)>>
|
||||
header_bin = Openflow.Multipart.Request.header(msg)
|
||||
<<header_bin::bytes, body_bin::bytes>>
|
||||
end
|
||||
end
|
||||
78
lib/openflow/multipart/port_stats/reply.ex
Normal file
78
lib/openflow/multipart/port_stats/reply.ex
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
defmodule Openflow.Multipart.PortStats.Reply do
|
||||
defstruct(
|
||||
version: 4,
|
||||
xid: 0,
|
||||
datapath_id: nil, # virtual field
|
||||
flags: [],
|
||||
ports: []
|
||||
)
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
def ofp_type, do: 18
|
||||
|
||||
def new(ports \\ []) do
|
||||
%Reply{ports: ports}
|
||||
end
|
||||
|
||||
def read(<<ports_bin::bytes>>) do
|
||||
ports = Openflow.Multipart.PortStats.read(ports_bin)
|
||||
%Reply{ports: ports}
|
||||
end
|
||||
end
|
||||
|
||||
defmodule Openflow.Multipart.PortStats do
|
||||
defstruct(
|
||||
port_number: 0,
|
||||
rx_packets: 0,
|
||||
tx_packets: 0,
|
||||
rx_bytes: 0,
|
||||
tx_bytes: 0,
|
||||
rx_dropped: 0,
|
||||
tx_dropped: 0,
|
||||
rx_errors: 0,
|
||||
tx_errors: 0,
|
||||
rx_frame_err: 0,
|
||||
rx_over_err: 0,
|
||||
rx_crc_err: 0,
|
||||
collisions: 0,
|
||||
duration_sec: 0,
|
||||
duration_nsec: 0
|
||||
)
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
def read(binary) do
|
||||
do_read([], binary)
|
||||
end
|
||||
|
||||
# private functions
|
||||
|
||||
defp do_read(acc, ""), do: Enum.reverse(acc)
|
||||
defp do_read(acc, <<port_stats_bin::112-bytes, rest::bytes>>) do
|
||||
do_read([codec(port_stats_bin)|acc], rest)
|
||||
end
|
||||
|
||||
defp codec(<<port_no::32, _::size(4)-unit(8), rx_packets::64,
|
||||
tx_packets::64, rx_bytes::64, tx_bytes::64,
|
||||
rx_dropped::64, tx_dropped::64, rx_errors::64,
|
||||
tx_errors::64, rx_frame_err::64, rx_over_err::64,
|
||||
rx_crc_err::64, collisions::64,
|
||||
duration_sec::32, duration_nsec::32>>) do
|
||||
%PortStats{port_number: port_no,
|
||||
rx_packets: rx_packets,
|
||||
tx_packets: tx_packets,
|
||||
rx_bytes: rx_bytes,
|
||||
tx_bytes: tx_bytes,
|
||||
rx_dropped: rx_dropped,
|
||||
tx_dropped: tx_dropped,
|
||||
rx_errors: rx_errors,
|
||||
tx_errors: tx_errors,
|
||||
rx_frame_err: rx_frame_err,
|
||||
rx_over_err: rx_over_err,
|
||||
rx_crc_err: rx_crc_err,
|
||||
collisions: collisions,
|
||||
duration_sec: duration_sec,
|
||||
duration_nsec: duration_nsec}
|
||||
end
|
||||
end
|
||||
29
lib/openflow/multipart/port_stats/request.ex
Normal file
29
lib/openflow/multipart/port_stats/request.ex
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
defmodule Openflow.Multipart.PortStats.Request do
|
||||
defstruct(
|
||||
version: 4,
|
||||
xid: 0,
|
||||
datapath_id: nil, # virtual field
|
||||
flags: [],
|
||||
port_number: :any
|
||||
)
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
def ofp_type, do: 18
|
||||
|
||||
def new(port_no \\ :any) do
|
||||
%Request{port_number: port_no}
|
||||
end
|
||||
|
||||
def read(<<port_no_int::32, _::size(4)-unit(8)>>) do
|
||||
port_no = Openflow.Utils.get_enum(port_no_int, :openflow13_port_no)
|
||||
%Request{port_number: port_no}
|
||||
end
|
||||
|
||||
def to_binary(%Request{port_number: port_no} = msg) do
|
||||
port_no_int = Openflow.Utils.get_enum(port_no, :openflow13_port_no)
|
||||
body_bin = <<port_no_int::32, 0::size(4)-unit(8)>>
|
||||
header_bin = Openflow.Multipart.Request.header(msg)
|
||||
<<header_bin::bytes, body_bin::bytes>>
|
||||
end
|
||||
end
|
||||
59
lib/openflow/multipart/queue/reply.ex
Normal file
59
lib/openflow/multipart/queue/reply.ex
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
defmodule Openflow.Multipart.Queue.Reply do
|
||||
defstruct(
|
||||
version: 4,
|
||||
xid: 0,
|
||||
datapath_id: nil, # virtual field
|
||||
flags: [],
|
||||
queues: []
|
||||
)
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
def ofp_type, do: 18
|
||||
|
||||
def new(queues \\ []) do
|
||||
%Reply{queues: queues}
|
||||
end
|
||||
|
||||
def read(<<queues_bin::bytes>>) do
|
||||
queues = Openflow.Multipart.Queue.read(queues_bin)
|
||||
%Reply{queues: queues}
|
||||
end
|
||||
end
|
||||
|
||||
defmodule Openflow.Multipart.Queue do
|
||||
defstruct(
|
||||
port_number: 0,
|
||||
queue_id: 0,
|
||||
tx_bytes: 0,
|
||||
tx_packets: 0,
|
||||
tx_errors: 0,
|
||||
duration_sec: 0,
|
||||
duration_nsec: 0
|
||||
)
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
def read(binary) do
|
||||
do_read([], binary)
|
||||
end
|
||||
|
||||
# private functions
|
||||
|
||||
defp do_read(acc, ""), do: Enum.reverse(acc)
|
||||
defp do_read(acc, <<queue_bin::40-bytes, rest::bytes>>) do
|
||||
do_read([codec(queue_bin)|acc], rest)
|
||||
end
|
||||
|
||||
defp codec(<<port_no::32, queue_id::32, tx_bytes::64,
|
||||
tx_packets::64, tx_errors::64,
|
||||
duration_sec::32, duration_nsec::32>>) do
|
||||
%Queue{port_number: port_no,
|
||||
queue_id: queue_id,
|
||||
tx_bytes: tx_bytes,
|
||||
tx_packets: tx_packets,
|
||||
tx_errors: tx_errors,
|
||||
duration_sec: duration_sec,
|
||||
duration_nsec: duration_nsec}
|
||||
end
|
||||
end
|
||||
34
lib/openflow/multipart/queue/request.ex
Normal file
34
lib/openflow/multipart/queue/request.ex
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
defmodule Openflow.Multipart.Queue.Request do
|
||||
defstruct(
|
||||
version: 4,
|
||||
xid: 0,
|
||||
datapath_id: nil, # virtual field
|
||||
flags: [],
|
||||
port_number: :any,
|
||||
queue_id: :all
|
||||
)
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
def ofp_type, do: 18
|
||||
|
||||
def new(options) do
|
||||
port_no = Keyword.get(options, :port_number, :any)
|
||||
queue_id = Keyword.get(options, :queue_id, :all)
|
||||
%Request{port_number: port_no, queue_id: queue_id}
|
||||
end
|
||||
|
||||
def read(<<port_no_int::32, queue_id_int::32>>) do
|
||||
port_no = Openflow.Utils.get_enum(port_no_int, :openflow13_port_no)
|
||||
queue_id = Openflow.Utils.get_enum(queue_id_int, :queue_id)
|
||||
%Request{port_number: port_no, queue_id: queue_id}
|
||||
end
|
||||
|
||||
def to_binary(%Request{port_number: port_no, queue_id: queue_id} = msg) do
|
||||
port_no_int = Openflow.Utils.get_enum(port_no, :openflow13_port_no)
|
||||
queue_id_int = Openflow.Utils.get_enum(queue_id, :queue_id)
|
||||
body_bin = <<port_no_int::32, queue_id_int::32>>
|
||||
header_bin = Openflow.Multipart.Request.header(msg)
|
||||
<<header_bin::bytes, body_bin::bytes>>
|
||||
end
|
||||
end
|
||||
27
lib/openflow/multipart/reply.ex
Normal file
27
lib/openflow/multipart/reply.ex
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
defmodule Openflow.Multipart.Reply do
|
||||
def ofp_type, do: 19
|
||||
|
||||
def read(<<type_int::16, flags_int::16, _::size(4)-unit(8), reply_bin::bytes>>) do
|
||||
codec = Openflow.Enums.to_atom(type_int, :multipart_reply_codec)
|
||||
flags = Openflow.Enums.int_to_flags(flags_int, :multipart_reply_flags)
|
||||
reply = codec.read(reply_bin)
|
||||
%{reply|flags: flags}
|
||||
end
|
||||
|
||||
def to_binary(%{__struct__: codec, flags: flags} = msg) do
|
||||
flags_int = Openflow.Enums.flags_to_int(flags, :multipart_reply_flags)
|
||||
type_int = Openflow.Enums.to_int(codec, :multipart_reply_codec)
|
||||
case codec.to_binary(msg) do
|
||||
reply_bin when is_binary(reply_bin) ->
|
||||
<<type_int::16, flags_int::16, 0::size(4)-unit(8), reply_bin::bytes>>
|
||||
{:error, reason} ->
|
||||
{:error, reason}
|
||||
end
|
||||
end
|
||||
|
||||
def header(%{__struct__: codec, flags: flags}) do
|
||||
flags_int = Openflow.Enums.flags_to_int(flags, :multipart_reply_flags)
|
||||
type_int = Openflow.Enums.to_int(codec, :multipart_reply_codec)
|
||||
<<type_int::16, flags_int::16, 0::size(4)-unit(8)>>
|
||||
end
|
||||
end
|
||||
27
lib/openflow/multipart/request.ex
Normal file
27
lib/openflow/multipart/request.ex
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
defmodule Openflow.Multipart.Request do
|
||||
def ofp_type, do: 18
|
||||
|
||||
def read(<<type_int::16, flags_int::16, _::size(4)-unit(8), request_bin::bytes>>) do
|
||||
codec = Openflow.Enums.to_atom(type_int, :multipart_request_codec)
|
||||
flags = Openflow.Enums.int_to_flags(flags_int, :multipart_request_flags)
|
||||
request = codec.read(request_bin)
|
||||
%{request|flags: flags}
|
||||
end
|
||||
|
||||
def to_binary(%{__struct__: codec, flags: flags} = msg) do
|
||||
flags_int = Openflow.Enums.flags_to_int(flags, :multipart_request_flags)
|
||||
type_int = Openflow.Enums.to_int(codec, :multipart_request_codec)
|
||||
case codec.to_binary(msg) do
|
||||
request_bin when is_binary(request_bin) ->
|
||||
<<type_int::16, flags_int::16, 0::size(4)-unit(8), request_bin::bytes>>
|
||||
{:error, reason} ->
|
||||
{:error, reason}
|
||||
end
|
||||
end
|
||||
|
||||
def header(%{__struct__: codec, flags: flags}) do
|
||||
flags_int = Openflow.Enums.flags_to_int(flags, :multipart_request_flags)
|
||||
type_int = Openflow.Enums.to_int(codec, :multipart_request_codec)
|
||||
<<type_int::16, flags_int::16, 0::size(4)-unit(8)>>
|
||||
end
|
||||
end
|
||||
45
lib/openflow/multipart/table/reply.ex
Normal file
45
lib/openflow/multipart/table/reply.ex
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
defmodule Openflow.Multipart.Table.Reply do
|
||||
defstruct(
|
||||
version: 4,
|
||||
xid: 0,
|
||||
datapath_id: nil, # virtual field
|
||||
flags: [],
|
||||
tables: []
|
||||
)
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
def ofp_type, do: 18
|
||||
|
||||
def read(<<tables_bin::bytes>>) do
|
||||
tables = Openflow.Multipart.TableStats.read(tables_bin)
|
||||
%Reply{tables: tables}
|
||||
end
|
||||
end
|
||||
|
||||
defmodule Openflow.Multipart.TableStats do
|
||||
defstruct(
|
||||
table_id: 0,
|
||||
active_count: 0,
|
||||
lookup_count: 0,
|
||||
matched_count: 0
|
||||
)
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
def read(binary) do
|
||||
do_read([], binary)
|
||||
end
|
||||
|
||||
# private functions
|
||||
|
||||
defp do_read(acc, ""), do: Enum.reverse(acc)
|
||||
defp do_read(acc, <<table_stats_bin::24-bytes, rest::bytes>>) do
|
||||
do_read([codec(table_stats_bin)|acc], rest)
|
||||
end
|
||||
|
||||
defp codec(<<table_id::8, _::size(3)-unit(8), active_count::32, lookup_count::64, matched_count::64>>) do
|
||||
%TableStats{table_id: table_id, active_count: active_count,
|
||||
lookup_count: lookup_count, matched_count: matched_count}
|
||||
end
|
||||
end
|
||||
24
lib/openflow/multipart/table/request.ex
Normal file
24
lib/openflow/multipart/table/request.ex
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
defmodule Openflow.Multipart.Table.Request do
|
||||
defstruct(
|
||||
version: 4,
|
||||
xid: 0,
|
||||
datapath_id: nil, # virtual field
|
||||
flags: []
|
||||
)
|
||||
|
||||
alias __MODULE__
|
||||
|
||||
def ofp_type, do: 18
|
||||
|
||||
def new do
|
||||
%Request{}
|
||||
end
|
||||
|
||||
def read("") do
|
||||
%Request{}
|
||||
end
|
||||
|
||||
def to_binary(%Request{} = msg) do
|
||||
Openflow.Multipart.Request.header(msg)
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue