Add patch_panel example

This commit is contained in:
Eishun Kondoh 2018-02-25 23:44:58 +09:00
parent b16cafbb5c
commit 51729542f3
12 changed files with 227 additions and 0 deletions

View file

@ -0,0 +1,81 @@
defmodule PatchPanel.Openflow.Controller do
use GenServer
use Tres.Controller
import Logger
defmodule State do
defstruct [:datapath_id]
end
def create_patch(datapath_id, port_a, port_b) do
case PatchPanel.Openflow.Registry.lookup_pid(datapath_id) do
nil ->
{:error, :not_found}
pid when is_pid(pid) ->
GenServer.call(pid, {:create, port_a, port_b})
end
end
def delete_patch(datapath_id, port_a, port_b) do
case PatchPanel.Openflow.Registry.lookup_pid(datapath_id) do
nil ->
{:error, :not_found}
pid when is_pid(pid) ->
GenServer.call(pid, {:delete, port_a, port_b})
end
end
def start_link({datapath_id, _aux_id}, _start_args) do
GenServer.start_link(__MODULE__, [datapath_id])
end
def init([datapath_id]) do
:ok = info("Switch Connected: datapath_id = #{datapath_id}")
{:ok, _} = PatchPanel.Openflow.Registry.register(datapath_id)
{:ok, %State{datapath_id: datapath_id}}
end
def handle_call({:create, port_a, port_b}, _from, %State{datapath_id: datapath_id} = state) do
:ok = add_flow_entries(datapath_id, port_a, port_b)
{:reply, :ok, state}
end
def handle_call({:delete, port_a, port_b}, _from, %State{datapath_id: datapath_id} = state) do
:ok = del_flow_entries(datapath_id, port_a, port_b)
{:reply, :ok, state}
end
def handle_info({:switch_disconnected, reason}, %State{datapath_id: datapath_id} = state) do
:ok = warn("#{datapath_id} disconnected: reason = #{inspect(reason)}")
:ok = PatchPanel.Openflow.Registry.unregister(datapath_id)
{:stop, :normal, state}
end
def handle_info(_info, state) do
{:noreply, state}
end
def terminate(reason, state) do
{reason, state}
end
# private functions
defp add_flow_entries(datapath_id, port_a, port_b) do
:ok = send_flow_mod_add(
datapath_id,
match: Match.new(in_port: port_a),
instructions: [ApplyActions.new(Output.new(port_b))]
)
:ok = send_flow_mod_add(
datapath_id,
match: Match.new(in_port: port_b),
instructions: [ApplyActions.new(Output.new(port_a))]
)
end
defp del_flow_entries(datapath_id, port_a, port_b) do
:ok = send_flow_mod_delete(datapath_id, match: Match.new(in_port: port_a))
:ok = send_flow_mod_delete(datapath_id, match: Match.new(in_port: port_b))
end
end

View file

@ -0,0 +1,16 @@
defmodule PatchPanel.Openflow.Registry do
def register(datapath_id) do
{:ok, _} = Registry.register(__MODULE__, datapath_id, [])
end
def unregister(datapath_id) do
:ok = Registry.unregister(__MODULE__, datapath_id)
end
def lookup_pid(datapath_id) do
case Registry.lookup(__MODULE__, datapath_id) do
[{pid, _}] -> pid
[] -> nil
end
end
end