Formatted

This commit is contained in:
Eishun Kondoh 2018-01-30 22:47:31 +09:00
parent 5fc01a9bec
commit 7635272fbd
150 changed files with 5055 additions and 4032 deletions

View file

@ -1,13 +1,14 @@
defmodule Openflow.Multipart.Aggregate.Reply do
defstruct(
version: 4,
xid: 0,
datapath_id: nil, # virtual field
aux_id: nil,
flags: [],
version: 4,
xid: 0,
# virtual field
datapath_id: nil,
aux_id: nil,
flags: [],
packet_count: 0,
byte_count: 0,
flow_count: 0
byte_count: 0,
flow_count: 0
)
alias __MODULE__

View file

@ -1,15 +1,16 @@
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: []
version: 4,
xid: 0,
# virtual field
datapath_id: nil,
flags: [],
table_id: :all,
out_port: :any,
out_group: :any,
cookie: 0,
cookie_mask: 0,
match: []
)
alias __MODULE__
@ -23,44 +24,55 @@ defmodule Openflow.Multipart.Aggregate.Request do
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}
%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
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}
%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
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>>
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

View file

@ -1,31 +1,36 @@
defmodule Openflow.Multipart.Desc.Reply do
defstruct(
version: 4,
xid: 0,
datapath_id: nil, # virtual field
aux_id: nil,
flags: [],
mfr_desc: "",
hw_desc: "",
sw_desc: "",
serial_num: "",
dp_desc: ""
version: 4,
xid: 0,
# virtual field
datapath_id: nil,
aux_id: nil,
flags: [],
mfr_desc: "",
hw_desc: "",
sw_desc: "",
serial_num: "",
dp_desc: ""
)
alias __MODULE__
@desc_str_len 256
@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)}
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

View file

@ -1,8 +1,9 @@
defmodule Openflow.Multipart.Desc.Request do
defstruct(
version: 4,
xid: 0,
datapath_id: nil, # virtual field
version: 4,
xid: 0,
# virtual field
datapath_id: nil,
flags: []
)

View file

@ -1,11 +1,12 @@
defmodule Openflow.Multipart.Flow.Reply do
defstruct(
version: 4,
xid: 0,
datapath_id: nil, # virtual field
aux_id: nil,
flags: [],
flows: []
version: 4,
xid: 0,
# virtual field
datapath_id: nil,
aux_id: nil,
flags: [],
flows: []
)
alias __MODULE__
@ -22,29 +23,32 @@ defmodule Openflow.Multipart.Flow.Reply do
end
def append_body(%Reply{flows: flows} = message, %Reply{flags: [:more], flows: continue}) do
%{message|flows: [continue|flows]}
%{message | flows: [continue | flows]}
end
def append_body(%Reply{flows: flows} = message, %Reply{flags: [], flows: continue}) do
new_flows = [continue|flows]
|> Enum.reverse
|> List.flatten
%{message|flows: new_flows}
new_flows =
[continue | flows]
|> Enum.reverse()
|> List.flatten()
%{message | flows: new_flows}
end
end
defmodule Openflow.Multipart.FlowStats do
defstruct(
table_id: 0,
duration_sec: 0,
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: [],
priority: 0,
idle_timeout: 0,
hard_timeout: 0,
flags: 0,
cookie: 0,
packet_count: 0,
byte_count: 0,
match: [],
instructions: []
)
@ -57,30 +61,35 @@ defmodule Openflow.Multipart.FlowStats do
# 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)
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
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}
%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

View file

@ -1,15 +1,16 @@
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: []
version: 4,
xid: 0,
# virtual field
datapath_id: nil,
flags: [],
table_id: :all,
out_port: :any,
out_group: :any,
cookie: 0,
cookie_mask: 0,
match: []
)
alias __MODULE__
@ -22,45 +23,56 @@ defmodule Openflow.Multipart.Flow.Request do
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, Openflow.Match.new)
%Request{table_id: table_id,
out_port: out_port,
out_group: out_group,
cookie: cookie,
cookie_mask: cookie_mask,
match: match}
match = Keyword.get(options, :match, Openflow.Match.new())
%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
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}
%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
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>>
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

View file

@ -1,11 +1,12 @@
defmodule Openflow.Multipart.Group.Reply do
defstruct(
version: 4,
xid: 0,
datapath_id: nil, # virtual field
aux_id: nil,
flags: [],
groups: []
version: 4,
xid: 0,
# virtual field
datapath_id: nil,
aux_id: nil,
flags: [],
groups: []
)
alias __MODULE__
@ -22,25 +23,28 @@ defmodule Openflow.Multipart.Group.Reply do
end
def append_body(%Reply{groups: groups} = message, %Reply{flags: [:more], groups: continue}) do
%{message|groups: [continue|groups]}
%{message | groups: [continue | groups]}
end
def append_body(%Reply{groups: groups} = message, %Reply{flags: [], groups: continue}) do
new_groups = [continue|groups]
|> Enum.reverse
|> List.flatten
%{message|groups: new_groups}
new_groups =
[continue | groups]
|> Enum.reverse()
|> List.flatten()
%{message | groups: new_groups}
end
end
defmodule Openflow.Multipart.Group do
defstruct(
group_id: 0,
ref_count: 0,
packet_count: 0,
byte_count: 0,
duration_sec: 0,
group_id: 0,
ref_count: 0,
packet_count: 0,
byte_count: 0,
duration_sec: 0,
duration_nsec: 0,
bucket_stats: []
bucket_stats: []
)
@ofp_group_stats_size 40
@ -54,27 +58,32 @@ defmodule Openflow.Multipart.Group do
# 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)
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
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}
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

View file

@ -1,10 +1,11 @@
defmodule Openflow.Multipart.Group.Request do
defstruct(
version: 4,
xid: 0,
datapath_id: nil, # virtual field
version: 4,
xid: 0,
# virtual field
datapath_id: nil,
flags: [],
group_id: :all
group_id: :all
)
alias __MODULE__

View file

@ -1,10 +1,11 @@
defmodule Openflow.Multipart.GroupDesc.Reply do
defstruct(
version: 4,
xid: 0,
datapath_id: nil, # virtual field
flags: [],
groups: []
version: 4,
xid: 0,
# virtual field
datapath_id: nil,
flags: [],
groups: []
)
alias __MODULE__
@ -21,21 +22,24 @@ defmodule Openflow.Multipart.GroupDesc.Reply do
end
def append_body(%Reply{groups: groups} = message, %Reply{flags: [:more], groups: continue}) do
%{message|groups: [continue|groups]}
%{message | groups: [continue | groups]}
end
def append_body(%Reply{groups: groups} = message, %Reply{flags: [], groups: continue}) do
new_groups = [continue|groups]
|> Enum.reverse
|> List.flatten
%{message|groups: new_groups}
new_groups =
[continue | groups]
|> Enum.reverse()
|> List.flatten()
%{message | groups: new_groups}
end
end
defmodule Openflow.Multipart.GroupDescStats do
defstruct(
type: :all,
group_id: 0,
buckets: []
type: :all,
group_id: 0,
buckets: []
)
alias __MODULE__
@ -49,9 +53,10 @@ defmodule Openflow.Multipart.GroupDescStats do
# 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)
do_read([codec(group_stats_bin) | acc], rest)
end
defp codec(<<length::16, type_int::8, _::8, group_id::32, tail::bytes>>) do

View file

@ -1,8 +1,9 @@
defmodule Openflow.Multipart.GroupDesc.Request do
defstruct(
version: 4,
xid: 0,
datapath_id: nil, # virtual field
version: 4,
xid: 0,
# virtual field
datapath_id: nil,
flags: []
)

View file

@ -1,45 +1,47 @@
defmodule Openflow.Multipart.GroupFeatures.Reply do
defstruct(
version: 4,
xid: 0,
datapath_id: nil, # virtual field
aux_id: nil,
flags: [],
types: 0,
version: 4,
xid: 0,
# virtual field
datapath_id: nil,
aux_id: nil,
flags: [],
types: 0,
capabilities: [],
max_groups_for_all: 0,
max_groups_for_select: 0,
max_groups_for_indirect: 0,
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
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
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}
%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

View file

@ -1,8 +1,9 @@
defmodule Openflow.Multipart.GroupFeatures.Request do
defstruct(
version: 4,
xid: 0,
datapath_id: nil, # virtual field
version: 4,
xid: 0,
# virtual field
datapath_id: nil,
flags: []
)

View file

@ -1,11 +1,12 @@
defmodule Openflow.Multipart.Meter.Reply do
defstruct(
version: 4,
xid: 0,
datapath_id: nil, # virtual field
aux_id: nil,
flags: [],
meters: []
version: 4,
xid: 0,
# virtual field
datapath_id: nil,
aux_id: nil,
flags: [],
meters: []
)
alias __MODULE__
@ -18,25 +19,28 @@ defmodule Openflow.Multipart.Meter.Reply do
end
def append_body(%Reply{meters: meters} = message, %Reply{flags: [:more], meters: continue}) do
%{message|meters: [continue|meters]}
%{message | meters: [continue | meters]}
end
def append_body(%Reply{meters: meters} = message, %Reply{flags: [], meters: continue}) do
new_meters = [continue|meters]
|> Enum.reverse
|> List.flatten
%{message|meters: new_meters}
new_meters =
[continue | meters]
|> Enum.reverse()
|> List.flatten()
%{message | meters: new_meters}
end
end
defmodule Openflow.Multipart.Meter do
defstruct(
meter_id: 0,
flow_count: 0,
meter_id: 0,
flow_count: 0,
packet_in_count: 0,
byte_in_count: 0,
duration_sec: 0,
duration_nsec: 0,
band_stats: []
byte_in_count: 0,
duration_sec: 0,
duration_nsec: 0,
band_stats: []
)
@ofp_meter_stats_size 40
@ -50,25 +54,32 @@ defmodule Openflow.Multipart.Meter do
# 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)
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
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}
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

View file

@ -1,10 +1,11 @@
defmodule Openflow.Multipart.Meter.Request do
defstruct(
version: 4,
xid: 0,
datapath_id: nil, # virtual field
version: 4,
xid: 0,
# virtual field
datapath_id: nil,
flags: [],
meter_id: :all
meter_id: :all
)
alias __MODULE__

View file

@ -1,10 +1,11 @@
defmodule Openflow.Multipart.MeterConfig.Request do
defstruct(
version: 4,
xid: 0,
datapath_id: nil, # virtual field
version: 4,
xid: 0,
# virtual field
datapath_id: nil,
flags: [],
meter_id: :all
meter_id: :all
)
alias __MODULE__

View file

@ -1,11 +1,12 @@
defmodule Openflow.Multipart.PortDesc.Reply do
defstruct(
version: 4,
xid: 0,
datapath_id: nil, # virtual field
aux_id: nil,
flags: [],
ports: []
version: 4,
xid: 0,
# virtual field
datapath_id: nil,
aux_id: nil,
flags: [],
ports: []
)
alias __MODULE__
@ -17,17 +18,20 @@ defmodule Openflow.Multipart.PortDesc.Reply do
end
def read(<<ports_bin::bytes>>) do
ports = for (<<port_bin::64-bytes <- ports_bin>>), do: Openflow.Port.read(port_bin)
ports = for <<port_bin::64-bytes <- ports_bin>>, do: Openflow.Port.read(port_bin)
%Reply{ports: Enum.reverse(ports)}
end
def append_body(%Reply{ports: ports} = message, %Reply{flags: [:more], ports: continue}) do
%{message|ports: [continue|ports]}
%{message | ports: [continue | ports]}
end
def append_body(%Reply{ports: ports} = message, %Reply{flags: [], ports: continue}) do
new_ports = [continue|ports]
|> Enum.reverse
|> List.flatten
%{message|ports: new_ports}
new_ports =
[continue | ports]
|> Enum.reverse()
|> List.flatten()
%{message | ports: new_ports}
end
end

View file

@ -1,8 +1,9 @@
defmodule Openflow.Multipart.PortDesc.Request do
defstruct(
version: 4,
xid: 0,
datapath_id: nil, # virtual field
version: 4,
xid: 0,
# virtual field
datapath_id: nil,
flags: []
)

View file

@ -1,11 +1,12 @@
defmodule Openflow.Multipart.PortStats.Reply do
defstruct(
version: 4,
xid: 0,
datapath_id: nil, # virtual field
aux_id: nil,
flags: [],
ports: []
version: 4,
xid: 0,
# virtual field
datapath_id: nil,
aux_id: nil,
flags: [],
ports: []
)
alias __MODULE__
@ -22,32 +23,35 @@ defmodule Openflow.Multipart.PortStats.Reply do
end
def append_body(%Reply{ports: ports} = message, %Reply{flags: [:more], ports: continue}) do
%{message|ports: [continue|ports]}
%{message | ports: [continue | ports]}
end
def append_body(%Reply{ports: ports} = message, %Reply{flags: [], ports: continue}) do
new_ports = [continue|ports]
|> Enum.reverse
|> List.flatten
%{message|ports: new_ports}
new_ports =
[continue | ports]
|> Enum.reverse()
|> List.flatten()
%{message | ports: new_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,
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
)
@ -60,30 +64,33 @@ defmodule Openflow.Multipart.PortStats do
# 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)
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}
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

View file

@ -1,8 +1,9 @@
defmodule Openflow.Multipart.PortStats.Request do
defstruct(
version: 4,
xid: 0,
datapath_id: nil, # virtual field
version: 4,
xid: 0,
# virtual field
datapath_id: nil,
flags: [],
port_number: :any
)

View file

@ -1,11 +1,12 @@
defmodule Openflow.Multipart.Queue.Reply do
defstruct(
version: 4,
xid: 0,
datapath_id: nil, # virtual field
aux_id: nil,
flags: [],
queues: []
version: 4,
xid: 0,
# virtual field
datapath_id: nil,
aux_id: nil,
flags: [],
queues: []
)
alias __MODULE__
@ -22,24 +23,27 @@ defmodule Openflow.Multipart.Queue.Reply do
end
def append_body(%Reply{queues: queues} = message, %Reply{flags: [:more], queues: continue}) do
%{message|queues: [continue|queues]}
%{message | queues: [continue | queues]}
end
def append_body(%Reply{queues: queues} = message, %Reply{flags: [], queues: continue}) do
new_queues = [continue|queues]
|> Enum.reverse
|> List.flatten
%{message|queues: new_queues}
new_queues =
[continue | queues]
|> Enum.reverse()
|> List.flatten()
%{message | queues: new_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,
port_number: 0,
queue_id: 0,
tx_bytes: 0,
tx_packets: 0,
tx_errors: 0,
duration_sec: 0,
duration_nsec: 0
)
@ -52,19 +56,23 @@ defmodule Openflow.Multipart.Queue do
# 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)
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}
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

View file

@ -1,11 +1,12 @@
defmodule Openflow.Multipart.Queue.Request do
defstruct(
version: 4,
xid: 0,
datapath_id: nil, # virtual field
version: 4,
xid: 0,
# virtual field
datapath_id: nil,
flags: [],
port_number: :any,
queue_id: :all
queue_id: :all
)
alias __MODULE__

View file

@ -5,15 +5,17 @@ defmodule Openflow.Multipart.Reply 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}
%{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

View file

@ -5,15 +5,17 @@ defmodule Openflow.Multipart.Request 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}
%{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

View file

@ -1,11 +1,12 @@
defmodule Openflow.Multipart.Table.Reply do
defstruct(
version: 4,
xid: 0,
datapath_id: nil, # virtual field
aux_id: nil,
flags: [],
tables: []
version: 4,
xid: 0,
# virtual field
datapath_id: nil,
aux_id: nil,
flags: [],
tables: []
)
alias __MODULE__
@ -18,21 +19,24 @@ defmodule Openflow.Multipart.Table.Reply do
end
def append_body(%Reply{tables: tables} = message, %Reply{flags: [:more], tables: continue}) do
%{message|tables: [continue|tables]}
%{message | tables: [continue | tables]}
end
def append_body(%Reply{tables: tables} = message, %Reply{flags: [], tables: continue}) do
new_tables = [continue|tables]
|> Enum.reverse
|> List.flatten
%{message|tables: new_tables}
new_tables =
[continue | tables]
|> Enum.reverse()
|> List.flatten()
%{message | tables: new_tables}
end
end
defmodule Openflow.Multipart.TableStats do
defstruct(
table_id: 0,
active_count: 0,
lookup_count: 0,
table_id: 0,
active_count: 0,
lookup_count: 0,
matched_count: 0
)
@ -45,12 +49,20 @@ defmodule Openflow.Multipart.TableStats do
# 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)
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}
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

View file

@ -1,8 +1,9 @@
defmodule Openflow.Multipart.Table.Request do
defstruct(
version: 4,
xid: 0,
datapath_id: nil, # virtual field
version: 4,
xid: 0,
# virtual field
datapath_id: nil,
flags: []
)

View file

@ -1,46 +1,44 @@
defmodule Openflow.Multipart.TableFeatures.Body do
defstruct [
table_id: 0,
name: "",
metadata_match: 0,
metadata_write: 0,
config: [],
max_entries: 0,
instructions: nil,
instructions_miss: nil,
next_tables: nil,
next_tables_miss: nil,
write_actions: nil,
write_actions_miss: nil,
apply_actions: nil,
apply_actions_miss: nil,
match: nil,
wildcards: nil,
write_setfield: nil,
write_setfield_miss: nil,
apply_setfield: nil,
apply_setfield_miss: nil
]
defstruct table_id: 0,
name: "",
metadata_match: 0,
metadata_write: 0,
config: [],
max_entries: 0,
instructions: nil,
instructions_miss: nil,
next_tables: nil,
next_tables_miss: nil,
write_actions: nil,
write_actions_miss: nil,
apply_actions: nil,
apply_actions_miss: nil,
match: nil,
wildcards: nil,
write_setfield: nil,
write_setfield_miss: nil,
apply_setfield: nil,
apply_setfield_miss: nil
alias __MODULE__
@max_table_name_len 32
@prop_header_length 4
@max_table_name_len 32
@prop_header_length 4
@table_features_length 64
@instructions 0
@instructions_miss 1
@next_tables 2
@next_tables_miss 3
@write_actions 4
@write_actions_miss 5
@apply_actions 6
@apply_actions_miss 7
@match 8
@wildcards 10
@write_setfield 12
@instructions 0
@instructions_miss 1
@next_tables 2
@next_tables_miss 3
@write_actions 4
@write_actions_miss 5
@apply_actions 6
@apply_actions_miss 7
@match 8
@wildcards 10
@write_setfield 12
@write_setfield_miss 13
@apply_setfield 14
@apply_setfield 14
@apply_setfield_miss 15
@prop_keys [
@ -62,25 +60,25 @@ defmodule Openflow.Multipart.TableFeatures.Body do
def new(options) do
%Body{
table_id: options[:table_id] || 0,
name: options[:name] || "",
metadata_match: options[:metadata_match] || 0,
metadata_write: options[:metadata_write] || 0,
config: options[:config] || [],
max_entries: options[:max_entries] || 0,
instructions: options[:instructions],
instructions_miss: options[:instructions_miss],
next_tables: options[:next_tables],
next_tables_miss: options[:next_tables_miss],
write_actions: options[:write_actions],
write_actions_miss: options[:write_actions_miss],
apply_actions: options[:apply_actions],
apply_actions_miss: options[:apply_actions_miss],
match: options[:match],
wildcards: options[:wildcards],
write_setfield: options[:write_setfield],
table_id: options[:table_id] || 0,
name: options[:name] || "",
metadata_match: options[:metadata_match] || 0,
metadata_write: options[:metadata_write] || 0,
config: options[:config] || [],
max_entries: options[:max_entries] || 0,
instructions: options[:instructions],
instructions_miss: options[:instructions_miss],
next_tables: options[:next_tables],
next_tables_miss: options[:next_tables_miss],
write_actions: options[:write_actions],
write_actions_miss: options[:write_actions_miss],
apply_actions: options[:apply_actions],
apply_actions_miss: options[:apply_actions_miss],
match: options[:match],
wildcards: options[:wildcards],
write_setfield: options[:write_setfield],
write_setfield_miss: options[:write_setfield_miss],
apply_setfield: options[:apply_setfield],
apply_setfield: options[:apply_setfield],
apply_setfield_miss: options[:apply_setfield_miss]
}
end
@ -96,102 +94,120 @@ defmodule Openflow.Multipart.TableFeatures.Body do
# private functions
defp do_to_binary(acc, []), do: acc
defp do_to_binary(acc, [table|rest]) do
do_to_binary(<<acc::bytes, (encode(table))::bytes>>, rest)
defp do_to_binary(acc, [table | rest]) do
do_to_binary(<<acc::bytes, encode(table)::bytes>>, rest)
end
defp do_read(acc, ""), do: Enum.reverse(acc)
defp do_read(acc, <<length::16, _::bytes>> = binary) do
<<features_bin::size(length)-bytes, rest::bytes>> = binary
do_read([decode(features_bin)|acc], rest)
do_read([decode(features_bin) | acc], rest)
end
defp decode(<<_length::16, table_id::8, _::size(5)-unit(8),
name_bin::size(@max_table_name_len)-bytes,
metadata_match::64, metadata_write::64,
config_int::32, max_entries::32, props_bin::bytes>>) do
defp decode(
<<_length::16, table_id::8, _::size(5)-unit(8),
name_bin::size(@max_table_name_len)-bytes, metadata_match::64, metadata_write::64,
config_int::32, max_entries::32, props_bin::bytes>>
) do
name = Openflow.Utils.decode_string(name_bin)
config = Openflow.Enums.int_to_flags(config_int, :table_config)
body = %Body{table_id: table_id,
name: name,
metadata_match: metadata_match,
metadata_write: metadata_write,
config: config,
max_entries: max_entries}
body = %Body{
table_id: table_id,
name: name,
metadata_match: metadata_match,
metadata_write: metadata_write,
config: config,
max_entries: max_entries
}
decode_props(body, props_bin)
end
defp encode(table) do
filter_fn = fn(key) -> not is_nil(Map.get(table, key)) end
filter_fn = fn key -> not is_nil(Map.get(table, key)) end
keys = Enum.filter(@prop_keys, filter_fn)
props_bin = encode_props("", table, keys)
length = @table_features_length + byte_size(props_bin)
%Body{table_id: table_id,
name: name,
metadata_match: metadata_match,
metadata_write: metadata_write,
config: config,
max_entries: max_entries} = table
%Body{
table_id: table_id,
name: name,
metadata_match: metadata_match,
metadata_write: metadata_write,
config: config,
max_entries: max_entries
} = table
config_int = Openflow.Enums.flags_to_int(config, :table_config)
name_bin = Openflow.Utils.encode_string(name, @max_table_name_len)
<<length::16, table_id::8, 0::size(5)-unit(8),
name_bin::bytes, metadata_match::64, metadata_write::64,
config_int::32, max_entries::32, props_bin::bytes>>
<<length::16, table_id::8, 0::size(5)-unit(8), name_bin::bytes, metadata_match::64,
metadata_write::64, config_int::32, max_entries::32, props_bin::bytes>>
end
defp decode_props(body, ""), do: body
defp decode_props(body, <<type_int::16, length::16, tail::bytes>>)
when type_int == @instructions or type_int == @instructions_miss do
when type_int == @instructions or type_int == @instructions_miss do
pad_length = Openflow.Utils.pad_length(length, 8)
value_length = length - @prop_header_length
<<instructions_bin::size(value_length)-bytes, _::size(pad_length)-unit(8), rest::bytes>> = tail
<<instructions_bin::size(value_length)-bytes, _::size(pad_length)-unit(8), rest::bytes>> =
tail
instructions = decode_instructions([], instructions_bin)
type = Openflow.Enums.to_atom(type_int, :table_feature_prop_type)
body
|> struct(%{type => instructions})
|> decode_props(rest)
end
defp decode_props(body, <<type_int::16, length::16, tail::bytes>>)
when type_int == @next_tables or type_int == @next_tables_miss do
when type_int == @next_tables or type_int == @next_tables_miss do
pad_length = Openflow.Utils.pad_length(length, 8)
value_length = length - @prop_header_length
<<next_tables_bin::size(value_length)-bytes, _::size(pad_length)-unit(8), rest::bytes>> = tail
next_tables = for <<table_id::8 <- next_tables_bin>>, do: table_id
type = Openflow.Enums.to_atom(type_int, :table_feature_prop_type)
body
|> struct(%{type => next_tables})
|> decode_props(rest)
end
defp decode_props(body, <<type_int::16, length::16, tail::bytes>>)
when type_int == @write_actions or
type_int == @write_actions_miss or
type_int == @apply_actions or
type_int == @apply_actions_miss do
when type_int == @write_actions or type_int == @write_actions_miss or
type_int == @apply_actions or type_int == @apply_actions_miss do
pad_length = Openflow.Utils.pad_length(length, 8)
value_length = length - @prop_header_length
<<actions_bin::size(value_length)-bytes, _::size(pad_length)-unit(8), rest::bytes>> = tail
actions = decode_actions([], actions_bin)
type = Openflow.Enums.to_atom(type_int, :table_feature_prop_type)
body
|> struct(%{type => actions})
|> decode_props(rest)
end
defp decode_props(body, <<type_int::16, length::16, tail::bytes>>)
when type_int == @match or
type_int == @wildcards or
type_int == @write_setfield or
type_int == @write_setfield_miss or
type_int == @apply_setfield or
type_int == @apply_setfield_miss do
when type_int == @match or type_int == @wildcards or type_int == @write_setfield or
type_int == @write_setfield_miss or type_int == @apply_setfield or
type_int == @apply_setfield_miss do
pad_length = Openflow.Utils.pad_length(length, 8)
value_length = length - @prop_header_length
<<matches_bin::size(value_length)-bytes, _::size(pad_length)-unit(8), rest::bytes>> = tail
matches = decode_matches([], matches_bin)
type = Openflow.Enums.to_atom(type_int, :table_feature_prop_type)
body
|> struct(%{type => matches})
|> decode_props(rest)
end
defp decode_props(body, <<_type_int::16, length::16, tail::bytes>>) do
pad_length = Openflow.Utils.pad_length(length, 8)
value_length = length - @prop_header_length
@ -200,8 +216,9 @@ defmodule Openflow.Multipart.TableFeatures.Body do
end
defp encode_props(acc, _table, []), do: acc
defp encode_props(acc, table, [type|rest])
when type == :instructions or type == :instructions_miss do
defp encode_props(acc, table, [type | rest])
when type == :instructions or type == :instructions_miss do
type_int = Openflow.Enums.to_int(type, :table_feature_prop_type)
instructions_bin = encode_instructions("", Map.get(table, type))
length = @prop_header_length + byte_size(instructions_bin)
@ -209,8 +226,9 @@ defmodule Openflow.Multipart.TableFeatures.Body do
body = <<instructions_bin::bytes, 0::size(pad_length)-unit(8)>>
encode_props(<<acc::bytes, type_int::16, length::16, body::bytes>>, table, rest)
end
defp encode_props(acc, table, [type|rest])
when type == :next_tables or type == :next_tables_miss do
defp encode_props(acc, table, [type | rest])
when type == :next_tables or type == :next_tables_miss do
type_int = Openflow.Enums.to_int(type, :table_feature_prop_type)
next_tables_bin = to_string(Map.get(table, type))
length = @prop_header_length + byte_size(next_tables_bin)
@ -218,11 +236,10 @@ defmodule Openflow.Multipart.TableFeatures.Body do
body = <<next_tables_bin::bytes, 0::size(pad_length)-unit(8)>>
encode_props(<<acc::bytes, type_int::16, length::16, body::bytes>>, table, rest)
end
defp encode_props(acc, table, [type|rest])
when (type == :write_actions or
type == :write_actions_miss or
type == :apply_actions or
type == :apply_actions_miss) do
defp encode_props(acc, table, [type | rest])
when type == :write_actions or type == :write_actions_miss or type == :apply_actions or
type == :apply_actions_miss do
type_int = Openflow.Enums.to_int(type, :table_feature_prop_type)
actions_bin = encode_actions("", Map.get(table, type))
length = @prop_header_length + byte_size(actions_bin)
@ -230,13 +247,11 @@ defmodule Openflow.Multipart.TableFeatures.Body do
body = <<actions_bin::bytes, 0::size(pad_length)-unit(8)>>
encode_props(<<acc::bytes, type_int::16, length::16, body::bytes>>, table, rest)
end
defp encode_props(acc, table, [type|rest])
when (type == :match or
type == :wildcards or
type == :write_setfield or
type == :write_setfield_miss or
type == :apply_setfield or
type == :apply_setfield_miss) do
defp encode_props(acc, table, [type | rest])
when type == :match or type == :wildcards or type == :write_setfield or
type == :write_setfield_miss or type == :apply_setfield or
type == :apply_setfield_miss do
type_int = Openflow.Enums.to_int(type, :table_feature_prop_type)
matches_bin = encode_matches("", Map.get(table, type))
length = @prop_header_length + byte_size(matches_bin)
@ -246,51 +261,61 @@ defmodule Openflow.Multipart.TableFeatures.Body do
end
defp decode_instructions(acc, ""), do: Enum.reverse(acc)
defp decode_instructions(acc, <<0xffff::16, _::16, exp_id::32, rest::bytes>>) do
decode_instructions([Openflow.Instruction.Experimenter.new(exp_id)|acc], rest)
defp decode_instructions(acc, <<0xFFFF::16, _::16, exp_id::32, rest::bytes>>) do
decode_instructions([Openflow.Instruction.Experimenter.new(exp_id) | acc], rest)
end
defp decode_instructions(acc, <<type_int::16, _::16, rest::bytes>>) do
instruction = Openflow.Enums.to_atom(type_int, :instruction_type)
decode_instructions([instruction|acc], rest)
decode_instructions([instruction | acc], rest)
end
defp encode_instructions(acc, []), do: acc
defp encode_instructions(acc, [%Openflow.Instruction.Experimenter{exp_id: exp_id}|rest]) do
encode_instructions(<<acc::bytes, 0xffff::16, 8::16, exp_id::32>>, rest)
defp encode_instructions(acc, [%Openflow.Instruction.Experimenter{exp_id: exp_id} | rest]) do
encode_instructions(<<acc::bytes, 0xFFFF::16, 8::16, exp_id::32>>, rest)
end
defp encode_instructions(acc, [type|rest]) do
defp encode_instructions(acc, [type | rest]) do
type_int = Openflow.Enums.to_int(type, :instruction_type)
encode_instructions(<<acc::bytes, type_int::16, 4::16>>, rest)
end
defp decode_actions(acc, ""), do: Enum.reverse(acc)
defp decode_actions(acc, <<0xffff::16, _::16, exp_id::32, rest::bytes>>) do
decode_actions([Openflow.Action.Experimenter.new(exp_id)|acc], rest)
defp decode_actions(acc, <<0xFFFF::16, _::16, exp_id::32, rest::bytes>>) do
decode_actions([Openflow.Action.Experimenter.new(exp_id) | acc], rest)
end
defp decode_actions(acc, <<type_int::16, _::16, rest::bytes>>) do
action = Openflow.Enums.to_atom(type_int, :action_type)
decode_actions([action|acc], rest)
decode_actions([action | acc], rest)
end
defp encode_actions(acc, []), do: acc
defp encode_actions(acc, [%Openflow.Action.Experimenter{exp_id: exp_id}|rest]) do
encode_actions(<<acc::bytes, 0xffff::16, 8::16, exp_id::32>>, rest)
defp encode_actions(acc, [%Openflow.Action.Experimenter{exp_id: exp_id} | rest]) do
encode_actions(<<acc::bytes, 0xFFFF::16, 8::16, exp_id::32>>, rest)
end
defp encode_actions(acc, [type|rest]) do
defp encode_actions(acc, [type | rest]) do
type_int = Openflow.Enums.to_int(type, :action_type)
encode_actions(<<acc::bytes, type_int::16, 4::16>>, rest)
end
defp decode_matches(acc, ""), do: Enum.reverse(acc)
defp decode_matches(acc, binary) do
length = Openflow.Match.header_size(binary)
<<header_bin::size(length)-bytes, rest::bytes>> = binary
field = Openflow.Match.codec_header(header_bin)
decode_matches([field|acc], rest)
decode_matches([field | acc], rest)
end
defp encode_matches(acc, []), do: acc
defp encode_matches(acc, [field|rest]) do
defp encode_matches(acc, [field | rest]) do
header_bin = Openflow.Match.codec_header(field)
encode_matches(<<acc::bytes, header_bin::bytes>>, rest)
end

View file

@ -1,11 +1,12 @@
defmodule Openflow.Multipart.TableFeatures.Reply do
defstruct(
version: 4,
xid: 0,
datapath_id: nil, # virtual field
aux_id: nil,
flags: [],
tables: []
version: 4,
xid: 0,
# virtual field
datapath_id: nil,
aux_id: nil,
flags: [],
tables: []
)
alias __MODULE__
@ -30,12 +31,15 @@ defmodule Openflow.Multipart.TableFeatures.Reply do
end
def append_body(%Reply{tables: tables} = message, %Reply{flags: [:more], tables: continue}) do
%{message|tables: [continue|tables]}
%{message | tables: [continue | tables]}
end
def append_body(%Reply{tables: tables} = message, %Reply{flags: [], tables: continue}) do
new_tables = [continue|tables]
|> Enum.reverse
|> List.flatten
%{message|tables: new_tables}
new_tables =
[continue | tables]
|> Enum.reverse()
|> List.flatten()
%{message | tables: new_tables}
end
end

View file

@ -1,11 +1,12 @@
defmodule Openflow.Multipart.TableFeatures.Request do
defstruct(
version: 4,
xid: 0,
datapath_id: nil, # virtual field
aux_id: nil,
flags: [],
tables: []
version: 4,
xid: 0,
# virtual field
datapath_id: nil,
aux_id: nil,
flags: [],
tables: []
)
alias __MODULE__
@ -30,12 +31,15 @@ defmodule Openflow.Multipart.TableFeatures.Request do
end
def append_body(%Request{tables: tables} = message, %Request{flags: [:more], tables: continue}) do
%{message|tables: [continue|tables]}
%{message | tables: [continue | tables]}
end
def append_body(%Request{tables: tables} = message, %Request{flags: [], tables: continue}) do
new_tables = [continue|tables]
|> Enum.reverse
|> List.flatten
%{message|tables: new_tables}
new_tables =
[continue | tables]
|> Enum.reverse()
|> List.flatten()
%{message | tables: new_tables}
end
end