secure_channel: Use counter module for transaction id

This commit is contained in:
Eishun Kondoh 2018-12-12 01:25:59 +09:00
parent 97b957742f
commit 4ea72c73b4
11 changed files with 74 additions and 45 deletions

2
.gitignore vendored
View file

@ -21,3 +21,5 @@ erl_crash.dump
# Examples
*/polaris/*
/bin/enum_gen

Binary file not shown.

View file

@ -11,7 +11,7 @@ config :tres,
callback_args: []
config :logger,
level: :info,
format: "$date $time [$level] $metadata$message\n",
metadata: [:application],
level: :debug,
format: "$date $time [$level] $message\n",
metadata: [],
handle_otp_reports: true

View file

@ -5,7 +5,7 @@ defmodule LeaderExample.Leader do
require Logger
def start_link([datapath_id, args]) do
def start_link(datapath_id, args) do
:locks_leader.start_link(__MODULE__, [datapath_id, args], [])
end

View file

@ -22,7 +22,7 @@ defmodule LearningSwitch.Ofctl do
]
end
def start_link([datapath_id, args]) do
def start_link(datapath_id, args) do
GenServer.start_link(__MODULE__, [datapath_id, args])
end

View file

@ -26,7 +26,7 @@ defmodule PatchPanel.Openflow.Controller do
end
end
def start_link([{datapath_id, _aux_id}, _start_args]) do
def start_link({datapath_id, _aux_id}, _start_args) do
GenServer.start_link(__MODULE__, [datapath_id])
end

View file

@ -21,7 +21,7 @@ defmodule SimpleRouter.Openflow.Controller do
]
end
def start_link([{datapath_id, _aux_id}, _start_args]) do
def start_link({datapath_id, _aux_id}, _start_args) do
GenServer.start_link(__MODULE__, [datapath_id])
end

View file

@ -10,13 +10,13 @@ defmodule Tres.ExampleHandler do
conn_ref: nil
end
def start_link([datapath, args]) do
def start_link(datapath, args) do
GenServer.start_link(__MODULE__, [datapath, args])
end
def init([{datapath_id, aux_id}, _args]) do
info(
"[#{__MODULE__}] Switch Ready: " <>
"Switch Ready: " <>
"datapath_id: #{datapath_id} " <> "aux_id: #{aux_id} " <> "on #{inspect(self())}"
)
@ -36,14 +36,19 @@ defmodule Tres.ExampleHandler do
{:noreply, state}
end
def handle_info({:switch_disconnected, _reason}, state) do
:ok = warn("Switch disconnected")
{:stop, :normal, state}
end
def handle_info({:switch_hang, _datapath_id}, state) do
:ok = warn("[#{__MODULE__}] Switch possible hang: datapath_id: #{state.datapath_id}")
:ok = warn("Switch possible hang: datapath_id: #{state.datapath_id}")
{:noreply, state}
end
# `Catch all` function is required.
def handle_info(info, state) do
:ok = warn("[#{__MODULE__}] unhandled message #{inspect(info)}: #{state.datapath_id}")
:ok = warn("unhandled message #{inspect(info)}: #{state.datapath_id}")
{:noreply, state}
end
@ -61,7 +66,7 @@ defmodule Tres.ExampleHandler do
defp handle_desc_stats_reply(desc, datapath_id) do
info(
"[#{__MODULE__}] Switch Desc: " <>
"Switch Desc: " <>
"mfr = #{desc.mfr_desc} " <>
"hw = #{desc.hw_desc} " <> "sw = #{desc.sw_desc} " <> "for #{datapath_id}"
)
@ -70,7 +75,7 @@ defmodule Tres.ExampleHandler do
defp handle_port_desc_stats_reply(port_desc, datapath_id) do
for port <- port_desc.ports do
info(
"[#{__MODULE__}] Switch has port: " <>
"Switch has port: " <>
"number = #{port.number} " <>
"hw_addr = #{port.hw_addr} " <>
"name = #{port.name} " <>

View file

@ -1,34 +1,19 @@
defmodule Tres.MessageHandlerSup do
use Supervisor
def start_link() do
Supervisor.start_link(__MODULE__, [], name: __MODULE__)
end
def init(_init_args) do
children = []
Supervisor.init(
children,
strategy: :one_for_one,
max_restarts: 5,
max_seconds: 10
)
end
# API functions
def start_child(dpid) do
{cb_mod, _cb_args} = Tres.Utils.get_callback_module()
child_spec = cb_mod.handler_spec(dpid)
{:ok, pid} = Supervisor.start_child(__MODULE__, child_spec)
{_cb_mod, cb_args} = Tres.Utils.get_callback_module()
{:ok, pid} = Supervisor.start_child(__MODULE__, [dpid, cb_args])
:ok = Tres.SwitchRegistry.register_handler_pid(dpid, pid)
{:ok, pid}
end
def terminate_child(dpid) do
{cb_mod, _cb_args} = Tres.Utils.get_callback_module()
child_spec = cb_mod.handler_spec(dpid)
_ = Supervisor.terminate_child(__MODULE__, child_spec[:id])
_ = Supervisor.delete_child(__MODULE__, child_spec[:id])
_ = Supervisor.terminate_child(__MODULE__, {cb_mod, dpid})
_ = Supervisor.delete_child(__MODULE__, {cb_mod, dpid})
end
@spec count_handlers() :: non_neg_integer()
@ -36,4 +21,37 @@ defmodule Tres.MessageHandlerSup do
count_value = Supervisor.count_children(__MODULE__)
count_value[:active]
end
def start_link do
Supervisor.start_link(__MODULE__, [], name: __MODULE__)
end
# supervisor callback functions
@impl Supervisor
def init(_init_args) do
children = [handler_spec()]
Supervisor.init(
children,
strategy: :simple_one_for_one,
max_restarts: 10,
max_seconds: 10
)
end
# private functions
defp handler_spec do
{cb_mod, _cb_args} = Tres.Utils.get_callback_module()
%{
id: :undefined,
start: {cb_mod, :start_link, []},
restart: :temporary,
shutdown: 5000,
type: :worker,
modules: [cb_mod]
}
end
end

View file

@ -56,6 +56,7 @@ defmodule Tres.SecureChannel do
end
def handle_event(:info, {:tcp_closed, socket}, _state, %State{socket: socket} = state_data) do
:ok = debug("TCP disconnected with #{state_data.ip_addr}:#{state_data.port}")
close_connection(:tcp_closed, state_data)
end
@ -609,7 +610,6 @@ defmodule Tres.SecureChannel do
defp close_connection(:handler_error, state_data) do
debug("connection terminated: Got handler error")
_ = send(state_data.handler_pid, {:switch_disconnected, :handler_error})
{:stop, :normal, %{state_data | socket: nil}}
end
@ -627,6 +627,7 @@ defmodule Tres.SecureChannel do
defp close_connection({:handler_down, reason}, state_data) do
debug("connection terminated: Handler process down by #{inspect(reason)}")
_ = send(state_data.handler_pid, {:switch_disconnected, :handler_error})
{:stop, :normal, %{state_data | socket: nil}}
end

View file

@ -1,4 +1,6 @@
defmodule Tres.SecureChannelState do
use Bitwise
defstruct(
handler_pid: nil,
handler_ref: nil,
@ -43,26 +45,27 @@ defmodule Tres.SecureChannelState do
}
end
def increment_transaction_id(table_ref) do
:ets.update_counter(table_ref, :datapath_xid, {2, 1, 0xFFFFFFFF, 0})
@spec increment_transaction_id(:counters.counters_ref()) :: integer()
def increment_transaction_id(counter_ref) do
:ok = :counters.add(counter_ref, 1, 1)
get_transaction_id(counter_ref)
end
def set_transaction_id(table_ref, xid) do
:ets.insert(table_ref, {:datapath_xid, xid})
@spec set_transaction_id(:counters.counters_ref(), integer()) :: integer()
def set_transaction_id(counter_ref, xid) do
:ok = :counters.put(counter_ref, 1, xid)
get_transaction_id(counter_ref)
end
def get_transaction_id(table_ref) do
case :ets.lookup(table_ref, :datapath_xid) do
[{_, xid} | _] -> xid
end
@spec get_transaction_id(:counters.counters_ref()) :: integer()
def get_transaction_id(counter_ref) do
:counters.get(counter_ref, 1) &&& 0xffffffff
end
# private functions
@spec create_counter() :: reference()
defp create_counter do
table_ref = :ets.new(:xid_counter, [:set, :private])
_ = :ets.insert(table_ref, {:datapath_xid, 0})
{:ok, table_ref}
{:ok, :counters.new(1, [])}
end
end