test: Add test case for NAT and optimized test-controller

This commit is contained in:
Eishun Kondoh 2017-11-29 21:35:15 +09:00
parent 43f15e7d63
commit cfc2152b7d
3 changed files with 224 additions and 86 deletions

View file

@ -20,8 +20,8 @@ defmodule Flay do
def init(args) do
state = init_controller(args)
init_bridge(state.datapath_id)
GenServer.cast(Flay, :desc_stats)
GenServer.cast(Flay, :flow_del)
{:ok, state}
end
@ -68,10 +68,16 @@ defmodule Flay do
end
def handle_info(%PortDesc.Reply{} = desc, state) do
GenServer.reply(state.reply_to, desc)
{:noreply, %{state|reply_to: nil}}
{:noreply, state}
end
def handle_info(%Desc.Reply{} = desc, state) do
IO.inspect(desc)
info(
"[#{__MODULE__}] Switch Desc: "
<> "mfr = #{desc.mfr_desc} "
<> "hw = #{desc.hw_desc} "
<> "sw = #{desc.sw_desc} "
)
init_bridge(state.datapath_id, desc)
{:noreply, state}
end
def handle_info(%Flow.Reply{} = desc, state) do
@ -127,7 +133,8 @@ defmodule Flay do
}
end
defp init_bridge(datapath_id) do
defp init_bridge(datapath_id, %Desc.Reply{mfr_desc: "Aruba"}) do
:ok = info("Transform flow table pipeline")
tables = [
TableFeatures.Body.new(
table_id: 0,
@ -180,17 +187,19 @@ defmodule Flay do
max_entries: 50,
config: [:table_miss_mask],
match: [
:in_port,
:eth_type,
:eth_src,
:vlan_vid,
:masked_eth_dst,
:vlan_vid,
:ip_proto,
:udp_dst,
:tcp_dst,
:ipv4_src,
:ipv4_dst,
:arp_spa,
:arp_tpa
],
wildcards: [
:in_port,
:eth_type,
:eth_src,
:masked_eth_dst,
@ -198,6 +207,10 @@ defmodule Flay do
:ip_proto,
:udp_dst,
:tcp_dst,
:ipv4_src,
:ipv4_dst,
:arp_spa,
:arp_tpa
],
instructions: [
Openflow.Instruction.GotoTable,
@ -221,4 +234,8 @@ defmodule Flay do
|> send_message(datapath_id)
send_flow_mod_delete(datapath_id, table_id: :all)
end
defp init_bridge(_datapath_id, _mfr) do
:ok = info("Flow pipeline profile is not defined")
:ok
end
end

View file

@ -5,10 +5,12 @@ defmodule FlogTest do
@listen_port 6653
@vlan_trunk_port "veth0" # FIXME:
@access_port "veth3" # FIXME:
@access_port1 "veth3" # FIXME:
@access_port2 "veth4" # FIXME:
@vlan_trunk_port_sniffer "veth1" # FIXME:
@access_port_sniffer "veth2" # FIXME:
@access_port1_sniffer "veth2" # FIXME:
@access_port2_sniffer "veth5" # FIXME:
@bootnet_vid 0x1000 ||| 5
@user_vid 0x1000 ||| 123
@ -26,6 +28,7 @@ defmodule FlogTest do
@gateway_ip {192,168,5,4}
@farm_gw_ip {192,168,255,254}
@farm_gw_mac "00000000000f"
@internet {8,8,8,8}
@trusted_macs [
"0800274d3297",
"0800274d3298",
@ -47,13 +50,15 @@ defmodule FlogTest do
wait_for_connected()
ports = get_ports_desc()
vlan_trunk = Enum.find(ports, fn(port) -> port.name == @vlan_trunk_port end)
port = Enum.find(ports, fn(port) -> port.name == @access_port end)
cookie = 0x2000000000000001
port = Enum.find(ports, fn(port) -> port.name == @access_port1 end)
port2 = Enum.find(ports, fn(port) -> port.name == @access_port2 end)
cookie = 0x1000000000000001
cookie2 = 0x2000000000000001
timeout = 32_678
options = [
vlan_trunk: vlan_trunk,
port: port,
port2: port2,
cookie: cookie,
cookie2: cookie2,
timeout: timeout
@ -69,11 +74,11 @@ defmodule FlogTest do
priority: 0
]
:ok = GenServer.cast(Flay, {:flow_install, options, self()})
refute_receive %Openflow.ErrorMsg{}, 2000
refute_receive %Openflow.ErrorMsg{}, 3000
end
test "Inject Packet(ARP)" do
{:ok, pid1} = Pf.start_link(@access_port_sniffer)
{:ok, pid1} = Pf.start_link(@access_port1_sniffer)
{:ok, pid2} = Pf.start_link(@vlan_trunk_port_sniffer)
shost = Openflow.Match.Field.codec(@mac, :eth_src)
@ -84,7 +89,7 @@ defmodule FlogTest do
arp(op: 1, sha: shost, sip: @client_ip, tip: @gateway_ip)
]
Pf.inject!(pid1, packet, payload)
refute_receive {@vlan_trunk_port_sniffer, [^packet, ^payload]}, 2000
refute_receive {@vlan_trunk_port_sniffer, ^packet}, 3000
Pf.stop(pid1)
Pf.stop(pid2)
end
@ -109,9 +114,9 @@ defmodule FlogTest do
match: match,
instructions: [ins]]
:ok = GenServer.cast(Flay, {:flow_install, options, self()})
refute_receive %Openflow.ErrorMsg{}, 2000
refute_receive %Openflow.ErrorMsg{}, 3000
{:ok, pid1} = Pf.start_link(@access_port_sniffer)
{:ok, pid1} = Pf.start_link(@access_port1_sniffer)
{:ok, pid2} = Pf.start_link(@vlan_trunk_port_sniffer)
shost = Openflow.Match.Field.codec(state.vlan_trunk.hw_addr, :eth_src)
@ -125,8 +130,8 @@ defmodule FlogTest do
Pf.inject!(pid2, packet)
in_port = state.vlan_trunk.number
assert_receive %Openflow.PacketIn{in_port: ^in_port}, 3000
refute_receive {@vlan_trunk_port_sniffer, [^packet, ""]}, 2000
refute_receive {@access_port_sniffer, [^packet, ""]}, 2000
refute_receive {@vlan_trunk_port_sniffer, [^packet, ""]}, 3000
refute_receive {@access_port1_sniffer, [^packet, ""]}, 3000
Pf.stop(pid1)
Pf.stop(pid2)
end
@ -143,27 +148,27 @@ defmodule FlogTest do
priority: 201,
match: match]
:ok = GenServer.cast(Flay, {:flow_install, options, self()})
refute_receive %Openflow.ErrorMsg{}, 2000
refute_receive %Openflow.ErrorMsg{}, 3000
end
end
end
describe("switch:uplink_escalation_flow:" <>
"table=0,priority=10,cookie=0x2000000000000000,arp,actions=controller") do
"table=0,priority=10,cookie=0x3000000000000000,arp,actions=controller") do
test "Install Flow", state do
match = Openflow.Match.new(eth_type: 0x0806)
action = Openflow.Action.Output.new(:controller)
ins = Openflow.Instruction.ApplyActions.new(action)
options =
[cookie: 0x2000000000000000,
[cookie: 0x3000000000000000,
table_id: 0,
priority: 10,
match: match,
instructions: [ins]]
:ok = GenServer.cast(Flay, {:flow_install, options, self()})
refute_receive %Openflow.ErrorMsg{}, 2000
refute_receive %Openflow.ErrorMsg{}, 3000
{:ok, pid1} = Pf.start_link(@access_port_sniffer)
{:ok, pid1} = Pf.start_link(@access_port1_sniffer)
{:ok, pid2} = Pf.start_link(@vlan_trunk_port_sniffer)
shost = Openflow.Match.Field.codec(@mac, :eth_src)
@ -176,28 +181,28 @@ defmodule FlogTest do
Pf.inject!(pid1, packet, payload)
in_port = state.port.number
assert_receive %Openflow.PacketIn{in_port: ^in_port}, 3000
refute_receive {@vlan_trunk_port_sniffer, [^packet, ^payload]}, 2000
refute_receive {@vlan_trunk_port_sniffer, ^packet}, 3000
Pf.stop(pid1)
Pf.stop(pid2)
end
end
describe("switch:uplink_escalation_flow:" <>
"table=0,priority=10,cookie=0x2000000000000000,udp,udp_dst=67,actions=controller") do
"table=0,priority=10,cookie=0x3000000000000000,udp,udp_dst=67,actions=controller") do
test "Install Flow", state do
match = Openflow.Match.new(eth_type: 0x0800, ip_proto: 17, udp_dst: 67)
action = Openflow.Action.Output.new(:controller)
ins = Openflow.Instruction.ApplyActions.new(action)
options =
[cookie: 0x2000000000000000,
[cookie: 0x3000000000000000,
table_id: 0,
priority: 10,
match: match,
instructions: [ins]]
:ok = GenServer.cast(Flay, {:flow_install, options, self()})
refute_receive %Openflow.ErrorMsg{}, 2000
refute_receive %Openflow.ErrorMsg{}, 3000
{:ok, pid1} = Pf.start_link(@access_port_sniffer)
{:ok, pid1} = Pf.start_link(@access_port1_sniffer)
{:ok, pid2} = Pf.start_link(@vlan_trunk_port_sniffer)
shost = Openflow.Match.Field.codec(@mac, :eth_src)
@ -216,27 +221,27 @@ defmodule FlogTest do
Pf.inject!(pid1, packet, <<payload::bytes>>)
in_port = state.port.number
assert_receive %Openflow.PacketIn{in_port: ^in_port}, 3000
refute_receive {@vlan_trunk_port_sniffer, [^packet, ^payload]}, 2000
refute_receive {@vlan_trunk_port_sniffer, ^packet}, 3000
Pf.stop(pid1)
Pf.stop(pid2)
end
end
describe("switch:uplink_escalation_flow:" <>
"table=0,priority=11,cookie=0x2000000000000000,in_port={trunk_port},actions=drop") do
"table=0,priority=11,cookie=0x3000000000000000,in_port={trunk_port},actions=drop") do
test "Install Flow", state do
match = Openflow.Match.new(in_port: state.vlan_trunk.number)
options =
[cookie: 0x2000000000000000,
[cookie: 0x3000000000000000,
table_id: 0,
priority: 11,
match: match]
:ok = GenServer.cast(Flay, {:flow_install, options, self()})
refute_receive %Openflow.ErrorMsg{}, 2000
refute_receive %Openflow.ErrorMsg{}, 3000
end
test "Inject Packet(ARP)" do
{:ok, pid1} = Pf.start_link(@access_port_sniffer)
{:ok, pid1} = Pf.start_link(@access_port1_sniffer)
{:ok, pid2} = Pf.start_link(@vlan_trunk_port_sniffer)
shost = Openflow.Match.Field.codec(@mac, :eth_src)
@ -247,7 +252,7 @@ defmodule FlogTest do
arp(op: 1, sha: shost, sip: @client_ip, tip: @gateway_ip)
]
Pf.inject!(pid2, packet, payload)
refute_receive {@access_port_sniffer, [^packet, ^payload]}, 2000
refute_receive {@access_port1_sniffer, ^packet}, 3000
Pf.stop(pid1)
Pf.stop(pid2)
end
@ -278,11 +283,11 @@ defmodule FlogTest do
match: match,
instructions: [ins]]
:ok = GenServer.cast(Flay, {:flow_install, options, self()})
refute_receive %Openflow.ErrorMsg{}, 2000
refute_receive %Openflow.ErrorMsg{}, 3000
end
test "Inject Packet(ARP)" do
{:ok, pid1} = Pf.start_link(@access_port_sniffer)
{:ok, pid1} = Pf.start_link(@access_port1_sniffer)
{:ok, pid2} = Pf.start_link(@vlan_trunk_port_sniffer)
shost = Openflow.Match.Field.codec(@mac, :eth_src)
@ -293,10 +298,9 @@ defmodule FlogTest do
ether(dhost: dhost, shost: shost, type: 0x8100),
{:"802.1q", 0, 0, 5, 0x0806},
arp(op: 1, sha: shost, sip: @client_ip, tip: @gateway_ip),
""
]
Pf.inject!(pid1, packet)
assert_receive {@vlan_trunk_port_sniffer, ^expect}, 2000
assert_receive {@vlan_trunk_port_sniffer, ^expect}, 3000
Pf.stop(pid1)
Pf.stop(pid2)
end
@ -315,6 +319,7 @@ defmodule FlogTest do
actions = [
Openflow.Action.PopVlan.new,
Openflow.Action.Output.new(state.port.number),
Openflow.Action.Output.new(state.port2.number),
]
ins = Openflow.Instruction.ApplyActions.new(actions)
options =
@ -327,12 +332,13 @@ defmodule FlogTest do
match: match,
instructions: [ins]]
:ok = GenServer.cast(Flay, {:flow_install, options, self()})
refute_receive %Openflow.ErrorMsg{}, 2000
refute_receive %Openflow.ErrorMsg{}, 3000
end
test "Inject Packet(ARP)" do
{:ok, pid1} = Pf.start_link(@access_port_sniffer)
{:ok, pid1} = Pf.start_link(@access_port1_sniffer)
{:ok, pid2} = Pf.start_link(@vlan_trunk_port_sniffer)
{:ok, pid3} = Pf.start_link(@access_port2_sniffer)
shost = Openflow.Match.Field.codec(@mac, :eth_src)
dhost = Openflow.Match.Field.codec(@bcast, :eth_dst)
@ -344,12 +350,13 @@ defmodule FlogTest do
expect = [
ether(dhost: dhost, shost: shost, type: 0x0806),
arp(op: 1, sha: shost, sip: @client_ip, tip: @gateway_ip),
""
]
Pf.inject!(pid2, packet)
assert_receive {@access_port_sniffer, ^expect}, 2000
assert_receive {@access_port1_sniffer, ^expect}, 3000
assert_receive {@access_port2_sniffer, ^expect}, 3000
Pf.stop(pid1)
Pf.stop(pid2)
Pf.stop(pid3)
end
end
@ -378,11 +385,11 @@ defmodule FlogTest do
match: match,
instructions: [ins]]
:ok = GenServer.cast(Flay, {:flow_install, options, self()})
refute_receive %Openflow.ErrorMsg{}, 2000
refute_receive %Openflow.ErrorMsg{}, 3000
end
test "Inject Packet(ARP)" do
{:ok, pid1} = Pf.start_link(@access_port_sniffer)
{:ok, pid1} = Pf.start_link(@access_port1_sniffer)
{:ok, pid2} = Pf.start_link(@vlan_trunk_port_sniffer)
shost = Openflow.Match.Field.codec(@sdl_vmac, :eth_src)
@ -390,15 +397,14 @@ defmodule FlogTest do
packet = [
ether(dhost: dhost, shost: shost, type: 0x8100),
{:"802.1q", 0, 0, 5, 0x0806},
arp(op: 1, sha: shost, tip: @client_ip, sip: @gateway_ip),
arp(op: 2, sha: shost, tip: @client_ip, sip: @gateway_ip),
]
expect = [
ether(dhost: dhost, shost: shost, type: 0x0806),
arp(op: 1, sha: shost, tip: @client_ip, sip: @gateway_ip),
""
arp(op: 2, sha: shost, tip: @client_ip, sip: @gateway_ip),
]
Pf.inject!(pid2, packet)
assert_receive {@access_port_sniffer, ^expect}, 2000
assert_receive {@access_port1_sniffer, ^expect}, 3000
Pf.stop(pid1)
Pf.stop(pid2)
end
@ -422,11 +428,11 @@ defmodule FlogTest do
hard_timeout: state.timeout,
match: match]
:ok = GenServer.cast(Flay, {:flow_install, options, self()})
refute_receive %Openflow.ErrorMsg{}, 2000
refute_receive %Openflow.ErrorMsg{}, 3000
end
test "Inject Packet(ARP)" do
{:ok, pid1} = Pf.start_link(@access_port_sniffer)
{:ok, pid1} = Pf.start_link(@access_port1_sniffer)
{:ok, pid2} = Pf.start_link(@vlan_trunk_port_sniffer)
shost = Openflow.Match.Field.codec(@mac, :eth_src)
@ -434,10 +440,10 @@ defmodule FlogTest do
payload = <<0::size(16)-unit(8)>>
packet = [
ether(dhost: dhost, shost: shost, type: 0x0806),
arp(op: 1, sha: shost, sip: @client_ip, tip: @gateway_ip)
arp(op: 2, sha: shost, sip: @client_ip, tip: @gateway_ip)
]
Pf.inject!(pid2, packet, payload)
refute_receive {@access_port_sniffer, [^packet, ^payload]}, 2000
refute_receive {@access_port1_sniffer, ^packet}, 3000
Pf.stop(pid1)
Pf.stop(pid2)
end
@ -470,13 +476,13 @@ defmodule FlogTest do
match: match,
instructions: [ins]]
:ok = GenServer.cast(Flay, {:flow_install, options, self()})
refute_receive %Openflow.ErrorMsg{}, 2000
refute_receive %Openflow.ErrorMsg{}, 3000
end
end
test "Inject Packet(ARP)" do
for trusted <- @trusted_macs do
{:ok, pid1} = Pf.start_link(@access_port_sniffer)
{:ok, pid1} = Pf.start_link(@access_port1_sniffer)
{:ok, pid2} = Pf.start_link(@vlan_trunk_port_sniffer)
shost = Openflow.Match.Field.codec(trusted, :eth_src)
@ -485,15 +491,14 @@ defmodule FlogTest do
packet = [
ether(dhost: dhost, shost: shost, type: 0x8100),
{:"802.1q", 0, 0, 5, 0x0806},
arp(op: 1, sha: shost, tha: dhost, tip: @client_ip, sip: @gateway_ip)
arp(op: 2, sha: shost, tha: dhost, tip: @client_ip, sip: @gateway_ip)
]
expect = [
ether(dhost: dhost, shost: shost, type: 0x0806),
arp(op: 1, sha: shost, tha: dhost, tip: @client_ip, sip: @gateway_ip),
payload
arp(op: 2, sha: shost, tha: dhost, tip: @client_ip, sip: @gateway_ip),
]
Pf.inject!(pid2, packet, payload)
assert_receive {@access_port_sniffer, ^expect}, 2000
assert_receive {@access_port1_sniffer, ^expect}, 3000
Pf.stop(pid1)
Pf.stop(pid2)
end
@ -516,7 +521,7 @@ defmodule FlogTest do
hard_timeout: state.timeout,
match: match]
:ok = GenServer.cast(Flay, {:flow_install, options, self()})
refute_receive %Openflow.ErrorMsg{}, 2000
refute_receive %Openflow.ErrorMsg{}, 3000
end
end
end
@ -536,7 +541,7 @@ defmodule FlogTest do
match: match,
instructions: ins]
:ok = GenServer.cast(Flay, {:flow_install, options, self()})
refute_receive %Openflow.ErrorMsg{}, 2000
refute_receive %Openflow.ErrorMsg{}, 3000
end
end
@ -563,7 +568,7 @@ defmodule FlogTest do
match: match,
instructions: ins]
:ok = GenServer.cast(Flay, {:flow_install, options, self()})
refute_receive %Openflow.ErrorMsg{}, 2000
refute_receive %Openflow.ErrorMsg{}, 3000
end
end
@ -591,11 +596,11 @@ defmodule FlogTest do
match: match,
instructions: [ins]]
:ok = GenServer.cast(Flay, {:flow_install, options, self()})
refute_receive %Openflow.ErrorMsg{}, 2000
refute_receive %Openflow.ErrorMsg{}, 3000
end
test "Inject Packet(TCP:443)" do
{:ok, pid1} = Pf.start_link(@access_port_sniffer)
{:ok, pid1} = Pf.start_link(@access_port1_sniffer)
{:ok, pid2} = Pf.start_link(@vlan_trunk_port_sniffer)
shost = Openflow.Match.Field.codec(@mac, :eth_src)
@ -615,9 +620,9 @@ defmodule FlogTest do
tcp_sum = :pkt.makesum([ipv4_header, tcp_header, payload])
ether_header = ether(dhost: dhost, shost: shost, type: 0x0800)
packet = [ether_header, ipv4_header, tcp(tcp_header, sum: tcp_sum)]
expect = [ether_header, ipv4_header, tcp(tcp_header, sum: tcp_sum), payload]
expect = [ether_header, ipv4_header, tcp(tcp_header, sum: tcp_sum)]
Pf.inject!(pid1, packet, <<payload::bytes>>)
assert_receive {@vlan_trunk_port_sniffer, ^expect}, 2000
assert_receive {@vlan_trunk_port_sniffer, ^expect}, 3000
Pf.stop(pid1)
Pf.stop(pid2)
end
@ -647,11 +652,11 @@ defmodule FlogTest do
match: match,
instructions: [ins]]
:ok = GenServer.cast(Flay, {:flow_install, options, self()})
refute_receive %Openflow.ErrorMsg{}, 2000
refute_receive %Openflow.ErrorMsg{}, 3000
end
test "Inject Packet(TCP:80)" do
{:ok, pid1} = Pf.start_link(@access_port_sniffer)
{:ok, pid1} = Pf.start_link(@access_port1_sniffer)
{:ok, pid2} = Pf.start_link(@vlan_trunk_port_sniffer)
shost = Openflow.Match.Field.codec(@mac, :eth_src)
@ -671,9 +676,9 @@ defmodule FlogTest do
tcp_sum = :pkt.makesum([ipv4_header, tcp_header, payload])
ether_header = ether(dhost: dhost, shost: shost, type: 0x0800)
packet = [ether_header, ipv4_header, tcp(tcp_header, sum: tcp_sum)]
expect = [ether_header, ipv4_header, tcp(tcp_header, sum: tcp_sum), payload]
expect = [ether_header, ipv4_header, tcp(tcp_header, sum: tcp_sum)]
Pf.inject!(pid1, packet, <<payload::bytes>>)
assert_receive {@vlan_trunk_port_sniffer, ^expect}, 2000
assert_receive {@vlan_trunk_port_sniffer, ^expect}, 3000
Pf.stop(pid1)
Pf.stop(pid2)
end
@ -693,7 +698,7 @@ defmodule FlogTest do
hard_timeout: state.timeout,
match: match]
:ok = GenServer.cast(Flay, {:flow_install, options, self()})
refute_receive %Openflow.ErrorMsg{}, 2000
refute_receive %Openflow.ErrorMsg{}, 3000
end
end
@ -714,7 +719,7 @@ defmodule FlogTest do
match: match,
instructions: ins]
:ok = GenServer.cast(Flay, {:flow_install, options, self()})
refute_receive %Openflow.ErrorMsg{}, 2000
refute_receive %Openflow.ErrorMsg{}, 3000
end
end
@ -722,7 +727,7 @@ defmodule FlogTest do
"idle_timeout={itimeout},hard_timeout={htimeout},send_flow_rem,vlan_vid=0x1000/0x1000,dl_dst={mac}," <>
"actions=strip_vlan,output:{port_no}") do
test "Install Flow", state do
match = Openflow.Match.new(vlan_vid: @vlan_present, eth_src: @mac)
match = Openflow.Match.new(vlan_vid: @vlan_present, eth_dst: @mac)
actions = [
Openflow.Action.PopVlan.new,
Openflow.Action.Output.new(state.port.number)]
@ -737,7 +742,25 @@ defmodule FlogTest do
match: match,
instructions: ins]
:ok = GenServer.cast(Flay, {:flow_install, options, self()})
refute_receive %Openflow.ErrorMsg{}, 2000
refute_receive %Openflow.ErrorMsg{}, 3000
end
test "Inject Packet(ARP)" do
{:ok, pid1} = Pf.start_link(@access_port1_sniffer)
{:ok, pid2} = Pf.start_link(@vlan_trunk_port_sniffer)
shost = Openflow.Match.Field.codec(@sdl_vmac, :eth_src)
dhost = Openflow.Match.Field.codec(@mac, :eth_dst)
vlan_ether_header = ether(dhost: dhost, shost: shost, type: 0x8100)
ether_header = ether(dhost: dhost, shost: shost, type: 0x0806)
vlan_header = {:"802.1q", 0, 1, 123, 0x0806}
arp_header = arp(op: 2, sha: shost, tha: dhost, tip: @client_ip, sip: @gateway_ip)
packet = [vlan_ether_header, vlan_header, arp_header]
expect = [ether_header, arp_header]
Pf.inject!(pid2, packet)
assert_receive {@access_port1_sniffer, ^expect}, 3000
Pf.stop(pid1)
Pf.stop(pid2)
end
end
@ -749,7 +772,8 @@ defmodule FlogTest do
actions = [
Openflow.Action.Output.new(state.vlan_trunk.number),
Openflow.Action.PopVlan.new,
Openflow.Action.Output.new(state.port.number)
Openflow.Action.Output.new(state.port.number),
Openflow.Action.Output.new(state.port2.number)
]
ins = [Openflow.Instruction.ApplyActions.new(actions)]
options =
@ -759,7 +783,51 @@ defmodule FlogTest do
match: match,
instructions: ins]
:ok = GenServer.cast(Flay, {:flow_install, options, self()})
refute_receive %Openflow.ErrorMsg{}, 2000
refute_receive %Openflow.ErrorMsg{}, 3000
end
test "Inject Packet(ARP) from VLAN TRUNK" do
{:ok, pid1} = Pf.start_link(@access_port1_sniffer)
{:ok, pid2} = Pf.start_link(@vlan_trunk_port_sniffer)
{:ok, pid3} = Pf.start_link(@access_port2_sniffer)
shost = Openflow.Match.Field.codec(@sdl_vmac, :eth_src)
dhost = Openflow.Match.Field.codec(@bcast, :eth_dst)
vlan_ether_header = ether(dhost: dhost, shost: shost, type: 0x8100)
ether_header = ether(dhost: dhost, shost: shost, type: 0x0806)
vlan_header = {:"802.1q", 0, 1, 123, 0x0806}
arp_header = arp(op: 1, sha: shost, tip: @client_ip, sip: @gateway_ip)
packet = [vlan_ether_header, vlan_header, arp_header]
Pf.inject!(pid2, packet)
expect = [ether_header, arp_header]
assert_receive {@access_port1_sniffer, ^expect}, 3000
assert_receive {@access_port2_sniffer, ^expect}, 3000
Pf.stop(pid1)
Pf.stop(pid2)
Pf.stop(pid3)
end
test "Inject Packet(ARP) from ACCESS" do
{:ok, pid1} = Pf.start_link(@access_port1_sniffer)
{:ok, pid2} = Pf.start_link(@vlan_trunk_port_sniffer)
{:ok, pid3} = Pf.start_link(@access_port2_sniffer)
shost = Openflow.Match.Field.codec(@mac, :eth_src)
dhost = Openflow.Match.Field.codec(@bcast, :eth_dst)
vlan_ether_header = ether(dhost: dhost, shost: shost, type: 0x8100)
ether_header = ether(dhost: dhost, shost: shost, type: 0x0806)
vlan_header = {:"802.1q", 0, 0, 123, 0x0806}
arp_header = arp(op: 1, sha: shost, tip: @client_ip, sip: @gateway_ip)
packet = [ether_header, arp_header]
Pf.inject!(pid1, packet)
expects = [
{@vlan_trunk_port_sniffer, [vlan_ether_header, vlan_header, arp_header]},
{@access_port2_sniffer, [ether_header, arp_header]}
]
:ok = assert_receives(expects)
Pf.stop(pid1)
Pf.stop(pid2)
Pf.stop(pid3)
end
end
@ -780,7 +848,7 @@ defmodule FlogTest do
match: match,
instructions: ins]
:ok = GenServer.cast(Flay, {:flow_install, options, self()})
refute_receive %Openflow.ErrorMsg{}, 2000
refute_receive %Openflow.ErrorMsg{}, 3000
end
end
@ -799,8 +867,9 @@ defmodule FlogTest do
Openflow.Action.SetField.new({:eth_dst, @farm_gw_mac}),
Openflow.Action.SetField.new({:arp_spa, @client_farm_ip}),
Openflow.Action.SetField.new({:arp_tpa, @farm_gw_ip}),
Openflow.Action.PushVlan.new,
Openflow.Action.SetField.new({:vlan_vid, @user_vid}),
# Following is not work properly in "SwitchNode" configuration.
# Openflow.Action.PushVlan.new,
# Openflow.Action.SetField.new({:vlan_vid, @user_vid}),
Openflow.Action.Output.new(state.vlan_trunk.number),
]
ins = [Openflow.Instruction.ApplyActions.new(actions)]
@ -812,7 +881,7 @@ defmodule FlogTest do
match: match,
instructions: ins]
:ok = GenServer.cast(Flay, {:flow_install, options, self()})
refute_receive %Openflow.ErrorMsg{}, 2000
refute_receive %Openflow.ErrorMsg{}, 3000
end
end
@ -825,12 +894,13 @@ defmodule FlogTest do
eth_src: @mac,
eth_type: 0x0800,
ipv4_src: @client_ip,
ipv4_dst: {8,8,8,8}
ipv4_dst: @internet
)
actions = [
Openflow.Action.SetField.new({:eth_dst, @farm_gw_mac}),
Openflow.Action.PushVlan.new,
Openflow.Action.SetField.new({:vlan_vid, @user_vid}),
# Following is not work properly in "SwitchNode" configuration.
# Openflow.Action.PushVlan.new,
# Openflow.Action.SetField.new({:vlan_vid, @user_vid}),
Openflow.Action.SetField.new({:ipv4_src, @client_farm_ip}),
Openflow.Action.Output.new(state.vlan_trunk.number),
]
@ -843,12 +913,62 @@ defmodule FlogTest do
match: match,
instructions: ins]
:ok = GenServer.cast(Flay, {:flow_install, options, self()})
refute_receive %Openflow.ErrorMsg{}, 2000
refute_receive %Openflow.ErrorMsg{}, 3000
end
test "Inject Packet(TCP:80)" do
{:ok, pid1} = Pf.start_link(@access_port1_sniffer)
{:ok, pid2} = Pf.start_link(@vlan_trunk_port_sniffer)
shost = Openflow.Match.Field.codec(@mac, :eth_src)
dhost = Openflow.Match.Field.codec(@sdl_vmac, :eth_dst)
payload = ""
tcp_header = tcp(
sport: 53_688,
dport: 80,
seqno: 1_488_352_223,
off: 10,
syn: 1,
win: 29_200,
opt: <<2, 4, 5, 180, 4, 2, 8, 10, 156, 30, 232, 154, 0, 0, 0, 0, 1, 3, 3, 7>>
)
ipv4_header = ipv4(saddr: @client_ip, daddr: @internet, p: 6, len: 60)
tcp_sum = :pkt.makesum([ipv4_header, tcp_header, payload])
ether_header = ether(dhost: dhost, shost: shost, type: 0x0800)
packet = [ether_header, ipv4_header, tcp(tcp_header, sum: tcp_sum)]
Pf.inject!(pid1, packet, <<payload::bytes>>)
shost = Openflow.Match.Field.codec(@mac, :eth_src)
dhost = Openflow.Match.Field.codec(@farm_gw_mac, :eth_dst)
ether_header = ether(dhost: dhost, shost: shost, type: 0x8100)
vlan_header = {:"802.1q", 0, 0, 123, 0x0800}
ipv4_header = ipv4(saddr: @client_farm_ip, daddr: @internet, p: 6, len: 60)
tcp_sum = :pkt.makesum([ipv4_header, tcp_header, payload])
expect = [ether_header, vlan_header, ipv4(ipv4_header, sum: 1544), tcp(tcp_header, sum: tcp_sum)]
assert_receives([{@vlan_trunk_port_sniffer, expect}], 5000)
Pf.stop(pid1)
Pf.stop(pid2)
end
end
# private functions
defp assert_receives(expects, timeout \\ 1000) do
assert_receives(expects, length(expects), timeout)
end
defp assert_receives(_expects, 0, _timeout), do: :ok
defp assert_receives(expects, count, timeout) do
receive do
message ->
assert(message in expects)
assert_receives(expects, count - 1, timeout)
after timeout ->
flunk("Timeout")
end
end
defp setup_applications do
Application.put_env(:tres, :protocol, :tcp, persistent: true)
Application.put_env(:tres, :port, @listen_port, persistent: true)
@ -875,7 +995,7 @@ defmodule FlogTest do
defp flow_del_by_cookie(context) do
:ok = GenServer.cast(Flay, {:flow_del, context.cookie})
:timer.sleep 2000
:timer.sleep 3000
end
defp get_ports_desc do

View file

@ -56,8 +56,9 @@ defmodule Pf do
end
def handle_info({:packet, _dlt, _time, _len, data}, state) do
pkt = :pkt.decapsulate(data)
send(state.tester_pid, {to_string(state.ifname), pkt})
packet = :pkt.decapsulate(data)
packet_len = length(packet)
send(state.tester_pid, {to_string(state.ifname), Enum.take(packet, packet_len - 1)})
{:noreply, state}
end
def handle_info(_info, state) do