openflow: Fix aggregate request

This commit is contained in:
Eishun Kondoh 2019-05-01 23:54:40 +09:00
parent c5e38155e1
commit b32cfff395
22 changed files with 71 additions and 44 deletions

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,52 @@
defmodule OfpBarrierTest do
use ExUnit.Case
doctest Openflow
describe "Openflow.Barrier.Request" do
test "generate and parse without argument" do
barrier = Openflow.Barrier.Request.new()
barrier
|> Openflow.to_binary()
|> Openflow.read()
|> Kernel.elem(1)
|> Kernel.==(barrier)
|> assert()
end
test "generate and parse with argument" do
barrier = Openflow.Barrier.Request.new(1)
barrier
|> Openflow.to_binary()
|> Openflow.read()
|> Kernel.elem(1)
|> Kernel.==(barrier)
|> assert()
end
end
describe "Openflow.Barrier.Reply" do
test "generate and parse without argument" do
barrier = Openflow.Barrier.Reply.new()
barrier
|> Openflow.to_binary()
|> Openflow.read()
|> Kernel.elem(1)
|> Kernel.==(barrier)
|> assert()
end
test "generate and parse with argument" do
barrier = Openflow.Barrier.Reply.new(1)
barrier
|> Openflow.to_binary()
|> Openflow.read()
|> Kernel.elem(1)
|> Kernel.==(barrier)
|> assert()
end
end
end

View file

@ -0,0 +1,110 @@
defmodule OfpEchoTest do
use ExUnit.Case
doctest Openflow
describe "Openflow.Echo.Request" do
test "with xid and data options" do
echo = Openflow.Echo.Request.new(xid: 1, data: "echo")
echo
|> Openflow.to_binary()
|> Openflow.read()
|> Kernel.elem(1)
|> Kernel.==(echo)
|> assert()
end
test "with data options" do
echo = Openflow.Echo.Request.new("echo")
echo
|> Openflow.to_binary()
|> Openflow.read()
|> Kernel.elem(1)
|> Kernel.==(echo)
|> assert()
end
end
describe "Openflow.Echo.Reply" do
test "with xid and data options" do
echo = Openflow.Echo.Reply.new(xid: 1, data: "echo")
echo
|> Openflow.to_binary()
|> Openflow.read()
|> Kernel.elem(1)
|> Kernel.==(echo)
|> assert()
end
test "with data options" do
echo = Openflow.Echo.Reply.new("echo")
echo
|> Openflow.to_binary()
|> Openflow.read()
|> Kernel.elem(1)
|> Kernel.==(echo)
|> assert()
end
end
describe "Openflow.read/1" do
test "with OFP_ECHO_REQUEST packet" do
{:ok, %Openflow.Echo.Request{} = echo, ""} =
"test/packet_data/ofp_echo_request.raw"
|> File.read!()
|> Openflow.read()
expect = Openflow.Echo.Request.new()
assert echo.version == expect.version
assert echo.xid == expect.xid
assert echo.data == expect.data
end
test "with OFP_ECHO_REPLY packet" do
{:ok, %Openflow.Echo.Reply{} = echo, ""} =
"test/packet_data/ofp_echo_reply.raw"
|> File.read!()
|> Openflow.read()
expect = Openflow.Echo.Reply.new()
assert echo.version == expect.version
assert echo.xid == expect.xid
assert echo.data == expect.data
end
end
describe "Openflow.to_binary/1" do
test "with %Openflow.Echo.Request{}" do
echo = %Openflow.Echo.Request{
version: 4,
xid: 0,
data: ""
}
expect =
"test/packet_data/ofp_echo_request.raw"
|> File.read!()
assert Openflow.to_binary(echo) == expect
end
test "with %Openflow.Echo.Reply{}" do
echo = %Openflow.Echo.Reply{
version: 4,
xid: 0,
data: ""
}
expect =
"test/packet_data/ofp_echo_reply.raw"
|> File.read!()
assert Openflow.to_binary(echo) == expect
end
end
end

View file

@ -0,0 +1,77 @@
defmodule OfpErrorTest do
use ExUnit.Case
doctest Openflow
describe "Openflow.read/1" do
test "with OFP_ERROR packet" do
{:ok, error, ""} =
"test/packet_data/ofp_error.raw"
|> File.read!()
|> Openflow.read()
assert error.version == 4
assert error.xid == 0
assert error.type == :bad_action
assert error.code == :unsupported_order
assert error.data == "fugafuga"
end
end
describe "Openflow.to_binary/1" do
test "with %Openflow.Error{}" do
error = %Openflow.ErrorMsg{
version: 4,
xid: 0,
type: :bad_action,
code: :unsupported_order,
data: "fugafuga"
}
expect =
"test/packet_data/ofp_error.raw"
|> File.read!()
assert Openflow.to_binary(error) == expect
end
test "with experimenter %Openflow.Error{}" do
error = %Openflow.ErrorMsg{
version: 4,
xid: 0,
type: :experimenter,
exp_type: 1,
experimenter: 0xDEADBEEF,
data: "hogehoge"
}
expect = <<
4,
1,
0,
24,
0,
0,
0,
0,
255,
255,
0,
1,
222,
173,
190,
239,
104,
111,
103,
101,
104,
111,
103,
101
>>
assert Openflow.to_binary(error) == expect
end
end
end

View file

@ -0,0 +1,73 @@
defmodule OfpFeaturesTest do
use ExUnit.Case
doctest Openflow
describe "Openflow.read/1" do
test "with OFP_FEATURES_REQUEST packet" do
{:ok, %Openflow.Features.Request{} = features, ""} =
"test/packet_data/ofp_features_request.raw"
|> File.read!()
|> Openflow.read()
expect = Openflow.Features.Request.new(0)
assert features.version == expect.version
assert features.xid == expect.xid
end
test "with OFP_FEATURES_REPLY packet" do
{:ok, %Openflow.Features.Reply{} = features, ""} =
"test/packet_data/ofp_features_reply.raw"
|> File.read!()
|> Openflow.read()
assert features.version == 4
assert features.xid == 0
assert features.datapath_id == "0000000000000001"
assert features.n_buffers == 255
assert features.n_tables == 255
assert features.aux_id == 0
assert features.capabilities == [
:flow_stats,
:table_stats,
:port_stats,
:group_stats,
:queue_stats
]
end
end
describe "Openflow.to_binary/1" do
test "with %Openflow.Features.Request{}" do
features = %Openflow.Features.Request{
version: 4,
xid: 0
}
expect =
"test/packet_data/ofp_features_request.raw"
|> File.read!()
assert Openflow.to_binary(features) == expect
end
end
test "with %Openflow.Features.Reply{}" do
features = %Openflow.Features.Reply{
version: 4,
xid: 0,
datapath_id: "0000000000000001",
n_buffers: 255,
n_tables: 255,
aux_id: 0,
capabilities: [:flow_stats, :table_stats, :port_stats, :group_stats, :queue_stats]
}
expect =
"test/packet_data/ofp_features_reply.raw"
|> File.read!()
assert Openflow.to_binary(features) == expect
end
end

View file

@ -0,0 +1,310 @@
defmodule OfpFlowModTest do
use ExUnit.Case
doctest Openflow
@flow_mod1 "test/packet_data/4-2-ofp_flow_mod.packet"
@flow_mod2 "test/packet_data/4-3-ofp_flow_mod.packet"
@flow_mod3 "test/packet_data/4-46-ofp_flow_mod.packet"
@flow_mod4 "test/packet_data/4-60-ofp_flow_mod.packet"
@flow_mod5 "test/packet_data/libofproto-OFP13-flow_mod.packet"
@flow_mod6 "test/packet_data/libofproto-OFP13-flow_mod.truncated64"
@flow_mod7 "test/packet_data/libofproto-OFP13-flow_mod_conjunction.packet"
@flow_mod8 "test/packet_data/libofproto-OFP13-flow_mod_match_conj.packet"
describe "Openflow.read/1" do
test "with OFP_FLOW_MOD packet(1)" do
binary = File.read!(@flow_mod1)
fm =
binary
|> Openflow.read()
|> elem(1)
|> Map.to_list()
|> Openflow.FlowMod.new()
|> Openflow.to_binary()
|> Openflow.read()
|> elem(1)
assert fm.cookie == 0
assert fm.cookie_mask == 0
assert fm.table_id == 1
assert fm.command == :add
assert fm.idle_timeout == 0
assert fm.hard_timeout == 0
assert fm.priority == 123
assert fm.buffer_id == 0xFFFF
assert fm.out_port == :any
assert fm.out_group == :any
assert fm.flags == []
assert fm.match == Openflow.Match.new(eth_dst: "f20ba47df8ea")
assert fm.instructions == [
Openflow.Instruction.WriteActions.new([
Openflow.Action.SetField.new(vlan_vid: 258),
Openflow.Action.CopyTtlOut.new(),
Openflow.Action.CopyTtlIn.new(),
Openflow.Action.CopyTtlIn.new(),
Openflow.Action.PopPbb.new(),
Openflow.Action.PushPbb.new(4660),
Openflow.Action.PopMpls.new(39030),
Openflow.Action.PushMpls.new(34887),
Openflow.Action.PopVlan.new(),
Openflow.Action.PushVlan.new(33024),
Openflow.Action.DecMplsTtl.new(),
Openflow.Action.SetMplsTtl.new(10),
Openflow.Action.DecNwTtl.new(),
Openflow.Action.SetNwTtl.new(10),
Openflow.Action.Experimenter.new(101, <<0, 1, 2, 3, 4, 5, 6, 7>>),
Openflow.Action.SetQueue.new(3),
Openflow.Action.Group.new(99),
Openflow.Action.Output.new(6)
]),
Openflow.Instruction.ApplyActions.new([
Openflow.Action.SetField.new(eth_src: "010203040506"),
Openflow.Action.SetField.new(onf_pbb_uca: 1)
])
]
assert Openflow.to_binary(fm) == binary
end
test "with OFP_FLOW_MOD packet(2)" do
binary = File.read!(@flow_mod2)
{:ok, fm, ""} = Openflow.read(binary)
assert fm.cookie == 0
assert fm.cookie_mask == 0
assert fm.table_id == 0
assert fm.cookie == 0
assert fm.command == :add
assert fm.idle_timeout == 0
assert fm.hard_timeout == 0
assert fm.priority == 123
assert fm.buffer_id == 0xFFFF
assert fm.out_port == :any
assert fm.out_group == :any
assert fm.flags == []
assert fm.match == Openflow.Match.new(in_port: 6, eth_src: "f20ba47df8ea")
assert fm.instructions == [Openflow.Instruction.GotoTable.new(1)]
assert Openflow.to_binary(fm) == binary
end
test "with OFP_FLOW_MOD packet(3)" do
binary = File.read!(@flow_mod3)
{:ok, fm, ""} = Openflow.read(binary)
assert fm.cookie == 0
assert fm.cookie_mask == 0
assert fm.table_id == 1
assert fm.command == :add
assert fm.idle_timeout == 0
assert fm.hard_timeout == 0
assert fm.priority == 123
assert fm.buffer_id == 0xFFFF
assert fm.out_port == :any
assert fm.out_group == :any
assert fm.flags == []
assert fm.match == Openflow.Match.new(eth_dst: "f20ba47df8ea")
assert fm.instructions == [
Openflow.Instruction.Meter.new(1),
Openflow.Instruction.WriteActions.new([Openflow.Action.Output.new(6)])
]
assert Openflow.to_binary(fm) == binary
end
test "with OFP_FLOW_MOD packet(4)" do
binary = File.read!(@flow_mod4)
{:ok, fm, ""} = Openflow.read(binary)
assert fm.cookie == 0
assert fm.cookie_mask == 0
assert fm.table_id == 1
assert fm.command == :add
assert fm.idle_timeout == 0
assert fm.hard_timeout == 0
assert fm.priority == 123
assert fm.buffer_id == 0xFFFF
assert fm.out_port == :any
assert fm.out_group == :any
assert fm.flags == []
assert fm.match ==
Openflow.Match.new(
in_port: 84_281_096,
in_phy_port: 16_909_060,
metadata: 283_686_952_306_183,
eth_type: 2054,
eth_dst: "ffffffffffff",
eth_src: "f20ba47df8ea",
vlan_vid: 999,
ip_dscp: 9,
ip_ecn: 3,
ip_proto: 99,
ipv4_src: {1, 2, 3, 4},
ipv4_dst: {1, 2, 3, 4},
tcp_src: 8080,
tcp_dst: 18_080,
udp_src: 28_080,
udp_dst: 55_936,
sctp_src: 48_080,
sctp_dst: 59_328,
icmpv4_type: 100,
icmpv4_code: 101,
arp_op: 1,
arp_spa: {10, 0, 0, 1},
arp_tpa: {10, 0, 0, 3},
arp_sha: "f20ba47df8ea",
arp_tha: "000000000000",
ipv6_src: {65152, 0, 0, 0, 61451, 42239, 65096, 10405},
ipv6_dst: {65152, 0, 0, 0, 61451, 42239, 65029, 47068},
ipv6_flabel: 541_473,
icmpv6_type: 200,
icmpv6_code: 201,
ipv6_nd_target: {65152, 0, 0, 0, 2656, 28415, 65151, 29927},
ipv6_nd_sll: "00000000029a",
ipv6_nd_tll: "00000000022b",
mpls_label: 624_485,
mpls_tc: 5,
mpls_bos: 1,
pbb_isid: 11_259_375,
tunnel_id: 651_061_555_542_690_057,
ipv6_exthdr: [:auth, :frag, :router, :hop, :unrep, :unseq],
onf_pbb_uca: 1,
tun_src: {1, 2, 3, 4},
tun_dst: {1, 2, 3, 4}
)
assert fm.instructions == []
assert Openflow.to_binary(fm) == binary
end
test "with OFP_FLOW_MOD packet(5)" do
binary = File.read!(@flow_mod5)
{:ok, fm, ""} = Openflow.read(binary)
assert fm.cookie == 0x123456789ABCDEF0
assert fm.cookie_mask == 0xFFFFFFFFFFFFFFFF
assert fm.table_id == 2
assert fm.command == :add
assert fm.idle_timeout == 0
assert fm.hard_timeout == 0
assert fm.priority == 0
assert fm.buffer_id == 0
assert fm.out_port == 0
assert fm.out_group == 0
assert fm.flags == []
assert fm.match ==
Openflow.Match.new(
in_port: 43981,
eth_dst: "aabbcc998877",
eth_type: 2048,
vlan_vid: 5095,
ipv4_dst: {192, 168, 2, 1},
tunnel_id: 50_000,
tun_src: {192, 168, 2, 3},
tun_dst: {192, 168, 2, 4}
)
assert fm.instructions == [
Openflow.Instruction.ApplyActions.new([
Openflow.Action.PopVlan.new(),
Openflow.Action.SetField.new(ipv4_dst: {192, 168, 2, 9}),
Openflow.Action.NxLearn.new(
hard_timeout: 300,
priority: 1,
table_id: 99,
flow_specs: [
Openflow.Action.NxFlowSpecMatch.new(
src: :vlan_vid,
dst: :vlan_vid,
n_bits: 12
),
Openflow.Action.NxFlowSpecMatch.new(src: :nx_eth_src, dst: :nx_eth_dst),
Openflow.Action.NxFlowSpecLoad.new(src: 0, dst: :vlan_vid, n_bits: 12),
Openflow.Action.NxFlowSpecLoad.new(src: :tun_id, dst: :tun_id),
Openflow.Action.NxFlowSpecOutput.new(src: :in_port)
]
)
]),
Openflow.Instruction.GotoTable.new(100)
]
assert Openflow.to_binary(fm) == binary
end
test "with OFP_FLOW_MOD packet(6)" do
{:error, :binary_too_small} =
@flow_mod6
|> File.read!()
|> Openflow.read()
end
test "with OFP_FLOW_MOD packet(7)" do
binary = File.read!(@flow_mod7)
{:ok, fm, ""} = Openflow.read(binary)
assert fm.cookie == 0x123456789ABCDEF0
assert fm.cookie_mask == 0xFFFFFFFFFFFFFFFF
assert fm.table_id == 4
assert fm.command == :add
assert fm.idle_timeout == 0
assert fm.hard_timeout == 0
assert fm.priority == 0
assert fm.buffer_id == 0
assert fm.out_port == 0
assert fm.out_group == 0
assert fm.flags == []
assert fm.match ==
Openflow.Match.new(
in_port: 43981,
eth_dst: "aabbcc998877",
eth_type: 2048,
vlan_vid: 5095,
ipv4_dst: {192, 168, 2, 1},
tunnel_id: 50_000,
tun_src: {192, 168, 2, 3},
tun_dst: {192, 168, 2, 4}
)
assert fm.instructions == [
Openflow.Instruction.ApplyActions.new([
Openflow.Action.NxConjunction.new(clause: 0, id: 0xABCDEF, n_clauses: 2)
])
]
assert Openflow.to_binary(fm) == binary
end
test "with OFP_FLOW_MOD packet(8)" do
binary = File.read!(@flow_mod8)
{:ok, fm, ""} = Openflow.read(binary)
assert fm.cookie == 0x123456789ABCDEF0
assert fm.cookie_mask == 0xFFFFFFFFFFFFFFFF
assert fm.table_id == 3
assert fm.command == :add
assert fm.idle_timeout == 0
assert fm.hard_timeout == 0
assert fm.priority == 0
assert fm.buffer_id == 0
assert fm.out_port == 0
assert fm.out_group == 0
assert fm.flags == []
assert fm.match == Openflow.Match.new(conj_id: 0xABCDEF)
assert fm.instructions == [
Openflow.Instruction.ApplyActions.new([
Openflow.Action.PopVlan.new(),
Openflow.Action.SetField.new(ipv4_dst: {192, 168, 2, 9})
]),
Openflow.Instruction.GotoTable.new(100)
]
assert Openflow.to_binary(fm) == binary
end
end
end

View file

@ -0,0 +1,58 @@
defmodule OfpFlowRemovedTest do
use ExUnit.Case
doctest Openflow
describe "Openflow.read/1" do
test "with OFP_FLOW_REMOVED packet(with a match field)" do
{:ok, flow_removed, ""} =
"test/packet_data/4-40-ofp_flow_removed.packet"
|> File.read!()
|> Openflow.read()
assert flow_removed.version == 4
assert flow_removed.xid == 0
assert flow_removed.cookie == 0
assert flow_removed.priority == 0xFFFF
assert flow_removed.reason == :idle_timeout
assert flow_removed.table_id == 0
assert flow_removed.duration_sec == 3
assert flow_removed.duration_nsec == 48_825_000
assert flow_removed.idle_timeout == 3
assert flow_removed.hard_timeout == 0
assert flow_removed.packet_count == 1
assert flow_removed.byte_count == 86
assert flow_removed.match == [eth_dst: "f20ba47df8ea"]
end
test "with OFP_FLOW_REMOVED packet(with match fields)" do
{:ok, flow_removed, ""} =
"test/packet_data/libofproto-OFP13-flow_removed.packet"
|> File.read!()
|> Openflow.read()
assert flow_removed.version == 4
assert flow_removed.xid == 0
assert flow_removed.cookie == 0x123456789ABCDEF0
assert flow_removed.priority == 100
assert flow_removed.reason == :idle_timeout
assert flow_removed.table_id == 1
assert flow_removed.duration_sec == 600
assert flow_removed.duration_nsec == 500
assert flow_removed.idle_timeout == 400
assert flow_removed.hard_timeout == 300
assert flow_removed.packet_count == 200
assert flow_removed.byte_count == 100
assert flow_removed.match == [
in_port: 43_981,
eth_dst: "aabbcc998877",
eth_type: 2048,
vlan_vid: 5095,
ipv4_dst: {192, 168, 2, 1},
tunnel_id: 50_000,
tun_src: {192, 168, 2, 3},
tun_dst: {192, 168, 2, 4}
]
end
end
end

View file

@ -0,0 +1,60 @@
defmodule OfpGetAsyncTest do
use ExUnit.Case
doctest Openflow
describe "Openflow.GetAsync.Request" do
test "generate and parse without argument" do
get_async = Openflow.GetAsync.Request.new()
get_async
|> Openflow.to_binary()
|> Openflow.read()
|> Kernel.elem(1)
|> Kernel.==(get_async)
|> assert()
end
test "generate and parse with argument" do
get_async = Openflow.GetAsync.Request.new(1)
get_async
|> Openflow.to_binary()
|> Openflow.read()
|> Kernel.elem(1)
|> Kernel.==(get_async)
|> assert()
end
end
describe "Openflow.GetAsync.Reply" do
test "generate and parse without argument" do
get_async = Openflow.GetAsync.Reply.new()
get_async
|> Openflow.to_binary()
|> Openflow.read()
|> Kernel.elem(1)
|> Kernel.==(get_async)
|> assert()
end
test "generate and parse with argument" do
get_async =
Openflow.GetAsync.Reply.new(
flow_removed_mask_master: [:idle_timeout, :hard_timeout, :delete, :group_delete],
flow_removed_mask_slave: [],
packet_in_mask_master: [:no_match, :action],
packet_in_mask_slave: [],
port_status_mask_master: [:add, :delete, :modify],
port_status_mask_slave: [:add, :delete, :modify]
)
get_async
|> Openflow.to_binary()
|> Openflow.read()
|> Kernel.elem(1)
|> Kernel.==(get_async)
|> assert()
end
end
end

View file

@ -0,0 +1,55 @@
defmodule OfpGetConfigTest do
use ExUnit.Case
doctest Openflow
describe "Openflow.read/1" do
test "with OFP_GET_CONFIG_REQUEST packet" do
{:ok, %Openflow.GetConfig.Request{} = config, ""} =
"test/packet_data/ofp_get_config_request.raw"
|> File.read!()
|> Openflow.read()
assert config.version == 4
assert config.xid == 0
end
test "with OFP_GET_CONFIG_REPLY packet" do
{:ok, %Openflow.GetConfig.Reply{} = config, ""} =
"test/packet_data/ofp_get_config_reply.raw"
|> File.read!()
|> Openflow.read()
assert config.version == 4
assert config.xid == 0
assert config.flags == []
assert config.miss_send_len == 128
end
end
describe "Openflow.to_binary/1" do
test "with %Openflow.GetConfig.Request{}" do
config = Openflow.GetConfig.Request.new(0)
expect =
"test/packet_data/ofp_get_config_request.raw"
|> File.read!()
assert Openflow.to_binary(config) == expect
end
test "with %Openflow.GetConfig.Reply{}" do
config = %Openflow.GetConfig.Reply{
version: 4,
xid: 0,
flags: [],
miss_send_len: 128
}
expect =
"test/packet_data/ofp_get_config_reply.raw"
|> File.read!()
assert Openflow.to_binary(config) == expect
end
end
end

View file

@ -0,0 +1,38 @@
defmodule OfpGroupModTest do
use ExUnit.Case
doctest Openflow
describe "Openflow.read/1" do
test "with OFP_GROUP_MOD packet" do
binary = File.read!("test/packet_data/4-21-ofp_group_mod.packet")
{:ok, _group_mod, ""} = Openflow.read(binary)
group_mod =
binary
|> Openflow.read()
|> elem(1)
|> Map.to_list()
|> Openflow.GroupMod.new()
|> Openflow.to_binary()
|> Openflow.read()
|> elem(1)
assert group_mod.version == 4
assert group_mod.xid == 0
assert group_mod.command == :add
assert group_mod.type == :all
assert group_mod.group_id == 1
assert group_mod.buckets == [
Openflow.Bucket.new(
weight: 1,
watch_port: 1,
watch_group: 1,
actions: [Openflow.Action.Output.new(2)]
)
]
assert Openflow.to_binary(group_mod) == binary
end
end
end

View file

@ -0,0 +1,29 @@
defmodule OfpHelloTest do
use ExUnit.Case
doctest Openflow
describe "Openflow.read/1" do
test "with OFP_HELLO packet" do
{:ok, hello, ""} =
"test/packet_data/ofp_hello.raw"
|> File.read!()
|> Openflow.read()
assert hello.version == 4
assert hello.xid == 0
assert hello.elements == [versionbitmap: [30, 10, 9, 3, 2, 1]]
end
end
describe "Openflow.to_binary/1" do
test "with %Openflow.Hello{}" do
hello = Openflow.Hello.new([30, 10, 9, 3, 2, 1])
expect =
"test/packet_data/ofp_hello.raw"
|> File.read!()
assert Openflow.to_binary(hello) == expect
end
end
end

View file

@ -0,0 +1,35 @@
defmodule OfpInstructionTest do
use ExUnit.Case
doctest Openflow
alias Openflow.Instruction.{
ApplyActions,
WriteActions,
ClearActions,
GotoTable,
WriteMetadata,
Meter,
Experimenter
}
describe "Openflow.Instruction" do
test "with all instructions parse and generate" do
instructions = [
ApplyActions.new([Openflow.Action.Output.new(:controller)]),
WriteActions.new([Openflow.Action.Output.new(5)]),
ClearActions.new(),
GotoTable.new(10),
WriteMetadata.new(value: 100, mask: 0xFFFFFFFFFFFFFFFF),
Meter.new(100),
Experimenter.new(0xCAFEBABE, "hogehoge"),
Experimenter.new(0xCAFEBABE)
]
instructions
|> Openflow.Instruction.to_binary()
|> Openflow.Instruction.read()
|> Kernel.==(instructions)
|> assert()
end
end
end

View file

@ -0,0 +1,44 @@
defmodule OfpMeterModTest do
use ExUnit.Case
doctest Openflow
describe "Openflow.MeterMod" do
test "with packet_data" do
meter_mod =
"test/packet_data/libofproto-OFP13-meter_mod.packet"
|> File.read!()
|> Openflow.read()
|> Kernel.elem(1)
|> Map.to_list()
|> Openflow.MeterMod.new()
|> Openflow.to_binary()
|> Openflow.read()
|> Kernel.elem(1)
expect =
Openflow.MeterMod.new(
xid: 0,
meter_id: 100,
command: :add,
flags: [:pktps, :burst, :stats],
bands: [
Openflow.MeterBand.Drop.new(
burst_size: 10,
rate: 1000
),
Openflow.MeterBand.Remark.new(
burst_size: 10,
prec_level: 1,
rate: 1000
)
]
)
assert expect.xid == meter_mod.xid
assert expect.meter_id == meter_mod.meter_id
assert expect.command == meter_mod.command
assert expect.flags == meter_mod.flags
assert expect.bands == meter_mod.bands
end
end
end

View file

@ -0,0 +1,23 @@
defmodule OfpPacketIn2Test do
use ExUnit.Case
doctest Openflow
describe "Openflow.read/1" do
test "with NX_PACKET_IN2 packet(with properties)" do
{:ok, pktin, ""} =
"test/packet_data/nx_packet_in2.raw"
|> File.read!()
|> Openflow.read()
assert pktin.version == 1
assert pktin.xid == 0
assert pktin.full_len == 64
assert pktin.table_id == 7
assert pktin.buffer_id == 0x114
assert pktin.cookie == 0xFEDCBA9876543210
assert pktin.reason == :action
assert pktin.metadata == [metadata: 0x5A5A5A5A5A5A5A5A]
assert pktin.userdata == <<1, 2, 3, 4, 5>>
end
end
end

View file

@ -0,0 +1,89 @@
defmodule OfpPacketInTest do
use ExUnit.Case
doctest Openflow
describe "Openflow.read/1" do
test "with OFP_PACKET_IN packet(with simple matches)" do
{:ok, pktin, ""} =
"test/packet_data/4-4-ofp_packet_in.packet"
|> File.read!()
|> Openflow.read()
assert pktin.version == 4
assert pktin.xid == 0
assert pktin.total_len == 42
assert pktin.table_id == 1
assert pktin.reason == :action
assert pktin.in_port == 6
assert pktin.match == [
eth_type: 2054,
eth_dst: "ffffffffffff",
eth_src: "f20ba47df8ea",
arp_op: 1,
arp_spa: {10, 0, 0, 1},
arp_tpa: {10, 0, 0, 3},
arp_sha: "f20ba47df8ea",
arp_tha: "000000000000"
]
end
test "with OFP_PACKET_IN packet(with complex matches)" do
{:ok, pktin, ""} =
"test/packet_data/4-59-ofp_packet_in.packet"
|> File.read!()
|> Openflow.read()
assert pktin.version == 4
assert pktin.xid == 0
assert pktin.total_len == 0
assert pktin.table_id == 200
assert pktin.reason == :no_match
assert pktin.in_port == 84_281_096
assert pktin.match == [
in_phy_port: 16_909_060,
metadata: 283_686_952_306_183,
eth_type: 2054,
eth_dst: "ffffffffffff",
eth_src: "f20ba47df8ea",
vlan_vid: 999,
ip_dscp: 9,
ip_ecn: 3,
ip_proto: 99,
ipv4_src: {1, 2, 3, 4},
ipv4_dst: {1, 2, 3, 4},
tcp_src: 8080,
tcp_dst: 18080,
udp_src: 28080,
udp_dst: 55936,
sctp_src: 48080,
sctp_dst: 59328,
icmpv4_type: 100,
icmpv4_code: 101,
arp_op: 1,
arp_spa: {10, 0, 0, 1},
arp_tpa: {10, 0, 0, 3},
arp_sha: "f20ba47df8ea",
arp_tha: "000000000000",
ipv6_src: {65152, 0, 0, 0, 61451, 42239, 65096, 10405},
ipv6_dst: {65152, 0, 0, 0, 61451, 42239, 65029, 47068},
ipv6_flabel: 541_473,
icmpv6_type: 200,
icmpv6_code: 201,
ipv6_nd_target: {65152, 0, 0, 0, 2656, 28415, 65151, 29927},
ipv6_nd_sll: "00000000029a",
ipv6_nd_tll: "00000000022b",
mpls_label: 624_485,
mpls_tc: 5,
mpls_bos: 1,
pbb_isid: 11_259_375,
tunnel_id: 651_061_555_542_690_057,
ipv6_exthdr: [:auth, :frag, :router, :hop, :unrep, :unseq],
onf_pbb_uca: 1,
tun_src: {1, 2, 3, 4},
tun_dst: {1, 2, 3, 4}
]
end
end
end

View file

@ -0,0 +1,134 @@
defmodule OfpPacketOutTest do
use ExUnit.Case
doctest Openflow
@packet <<
0xF2,
0x0B,
0xA4,
0xD0,
0x3F,
0x70,
0xF2,
0x0B,
0xA4,
0x7D,
0xF8,
0xEA,
0x08,
0x00,
0x45,
0x00,
0x00,
0x54,
0xF8,
0x1A,
0x00,
0x00,
0xFF,
0x01,
0xAF,
0x8B,
0x0A,
0x00,
0x00,
0x01,
0x0A,
0x00,
0x00,
0x02,
0x08,
0x00,
0x02,
0x08,
0xF7,
0x60,
0x00,
0x00,
0x31,
0xD6,
0x02,
0x00,
0x00,
0x00,
0x00,
0x00,
0xAB,
0x8D,
0x2D,
0x31,
0x00,
0x00,
0x00,
0x00,
0x10,
0x11,
0x12,
0x13,
0x14,
0x15,
0x16,
0x17,
0x18,
0x19,
0x1A,
0x1B,
0x1C,
0x1D,
0x1E,
0x1F,
0x20,
0x21,
0x22,
0x23,
0x24,
0x25,
0x26,
0x27,
0x28,
0x29,
0x2A,
0x2B,
0x2C,
0x2D,
0x2E,
0x2F,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00
>>
describe "Openflow.read/1" do
test "with OFP_PACKET_OUT packet" do
{:ok, pktout, ""} =
"test/packet_data/libofproto-OFP13-ofp_packet_out_packet_library.packet"
|> File.read!()
|> Openflow.read()
assert pktout.version == 4
assert pktout.xid == 0
assert pktout.buffer_id == :no_buffer
assert pktout.in_port == :controller
assert pktout.actions == [%Openflow.Action.Output{max_len: :no_buffer, port_number: :all}]
assert pktout.data == @packet
end
end
describe "Openflow.to_binary/1" do
pktout = %Openflow.PacketOut{
actions: [Openflow.Action.Output.new(port_number: :all)],
data: @packet
}
expect =
"test/packet_data/libofproto-OFP13-ofp_packet_out_packet_library.packet"
|> File.read!()
assert Openflow.to_binary(pktout) == expect
end
end

View file

@ -0,0 +1,34 @@
defmodule OfpPortModTest do
use ExUnit.Case
doctest Openflow
describe "Openflow.read/1" do
test "with OFP_PORT_MOD packet(1)" do
binary = File.read!("test/packet_data/4-22-ofp_port_mod.packet")
{:ok, port_mod, ""} = Openflow.read(binary)
assert port_mod.version == 4
assert port_mod.xid == 0
assert port_mod.number == 1
assert port_mod.hw_addr == "001100001111"
assert port_mod.config == []
assert port_mod.mask == []
assert port_mod.advertise == [:fiber]
assert Openflow.to_binary(port_mod) == binary
end
end
test "with OFP_PORT_MOD packet(2)" do
binary = File.read!("test/packet_data/libofproto-OFP13-port_mod.packet")
{:ok, port_mod, ""} = Openflow.read(binary)
assert port_mod.version == 4
assert port_mod.xid == 0
assert port_mod.number == 1
assert port_mod.hw_addr == "aabbcc998877"
assert port_mod.config == [:port_down]
assert port_mod.mask == [:port_down]
assert port_mod.advertise == [:"100mb_fd", :copper, :autoneg]
assert Openflow.to_binary(port_mod) == binary
end
end

View file

@ -0,0 +1,48 @@
defmodule OfpPortStatusTest do
use ExUnit.Case
doctest Openflow
describe "Openflow.read/1" do
test "with OFP_PORT_STATUS packet" do
{:ok, port_status, ""} =
"test/packet_data/libofproto-OFP13-port_status.packet"
|> File.read!()
|> Openflow.read()
assert port_status.version == 4
assert port_status.xid == 0
assert port_status.reason == :modify
assert port_status.port.number == 1
assert port_status.port.hw_addr == "ffffffffffff"
assert port_status.port.name == "eth0"
assert port_status.port.config == []
assert port_status.port.state == [:live]
assert port_status.port.current_features == [:"100mb_fd", :copper, :autoneg]
assert port_status.port.advertised_features == [:"100mb_fd", :copper, :autoneg]
assert port_status.port.peer_features == [:"100mb_fd", :copper, :autoneg]
assert port_status.port.current_speed == 50_000
assert port_status.port.max_speed == 100_000
end
test "with OFP_PORT_STATUS packet(with kanji port name)" do
{:ok, port_status, ""} =
"test/packet_data/4-39-ofp_port_status.packet"
|> File.read!()
|> Openflow.read()
assert port_status.version == 4
assert port_status.xid == 0
assert port_status.reason == :add
assert port_status.port.number == 7
assert port_status.port.hw_addr == "f20ba4d03f70"
assert port_status.port.name == "私のポート"
assert port_status.port.config == []
assert port_status.port.state == [:live]
assert port_status.port.current_features == [:"100mb_fd", :copper, :autoneg]
assert port_status.port.advertised_features == [:copper, :autoneg]
assert port_status.port.peer_features == [:"100mb_fd", :copper, :autoneg]
assert port_status.port.current_speed == 5_000
assert port_status.port.max_speed == 5_000
end
end
end

View file

@ -0,0 +1,35 @@
defmodule OfpSetConfigTest do
use ExUnit.Case
doctest Openflow
describe "Openflow.read/1" do
test "with OFP_SET_CONFIG packet" do
{:ok, %Openflow.SetConfig{} = config, ""} =
"test/packet_data/ofp_set_config.raw"
|> File.read!()
|> Openflow.read()
assert config.version == 4
assert config.xid == 0
assert config.flags == []
assert config.miss_send_len == 128
end
end
describe "Openflow.to_binary/1" do
test "with %Openflow.SetConfig{}" do
config = %Openflow.SetConfig{
version: 4,
xid: 0,
flags: [],
miss_send_len: 128
}
expect =
"test/packet_data/ofp_set_config.raw"
|> File.read!()
assert Openflow.to_binary(config) == expect
end
end
end

View file

@ -0,0 +1,28 @@
defmodule OfpTableModTest do
use ExUnit.Case
doctest Openflow
describe "Openflow.read/1" do
test "with OFP_TABLE_MOD packet(1)" do
binary = File.read!("test/packet_data/libofproto-OFP13-table_mod.packet")
{:ok, table_mod, ""} = Openflow.read(binary)
assert table_mod.version == 4
assert table_mod.xid == 0
assert table_mod.table_id == :all
assert table_mod.config == 0
assert Openflow.to_binary(table_mod) == binary
end
end
test "with OFP_TABLE_MOD packet(2)" do
binary = File.read!("test/packet_data/4-23-ofp_table_mod.packet")
{:ok, table_mod, ""} = Openflow.read(binary)
assert table_mod.version == 4
assert table_mod.xid == 0
assert table_mod.table_id == :all
assert table_mod.config == 0
assert Openflow.to_binary(table_mod) == binary
end
end