diff --git a/lib/tres/secure_channel.ex b/lib/tres/secure_channel.ex index 48fd016..31d0852 100644 --- a/lib/tres/secure_channel.ex +++ b/lib/tres/secure_channel.ex @@ -4,6 +4,7 @@ defmodule Tres.SecureChannel do import Logger alias :tres_xact_kv, as: XACT_KV + alias :queue, as: Queue alias Tres.SecureChannelState alias Tres.SwitchRegistry alias Tres.MessageHandlerSup @@ -171,7 +172,14 @@ defmodule Tres.SecureChannel do XACT_KV.delete(state_data.xact_kv_ref, message.xid) end end - :keep_state_and_data + {next_actions, action_queue} = + case Queue.out(state_data.action_queue) do + {:empty, action_queue} -> + {[], action_queue} + {{:value, next_action}, action_queue} -> + {[{:next_event, :internal, next_action}], action_queue} + end + {:keep_state, %{state_data|action_queue: action_queue}, next_actions} end defp handle_CONNECTED(:internal, {:openflow, message}, state_data) do %SecureChannelState{datapath_id: dpid, aux_id: aux_id} = state_data @@ -181,7 +189,7 @@ defmodule Tres.SecureChannel do |> handle_message(new_message, state_data) :keep_state_and_data end - defp handle_CONNECTED(:cast, {:send_message, message}, state_data) do + defp handle_CONNECTED(:internal, {:send_message, message}, state_data) do xid = SecureChannelState.increment_transaction_id(state_data.xid) messages = [ %{message|xid: xid}, @@ -191,6 +199,19 @@ defmodule Tres.SecureChannel do send_message(messages, state_data) :keep_state_and_data end + defp handle_CONNECTED(:cast, {:send_message, message} = action, state_data) do + if Queue.is_empty(state_data.action_queue) do + xid = SecureChannelState.increment_transaction_id(state_data.xid) + messages = [ + %{message|xid: xid}, + %{Openflow.Barrier.Request.new|xid: xid} + ] + XACT_KV.insert(state_data.xact_kv_ref, xid, message) + send_message(messages, state_data) + end + action_queue = Queue.in(action, state_data.action_queue) + {:keep_state, %{state_data|action_queue: action_queue}} + end defp handle_message(_in_xact = true, message, state_data) do case XACT_KV.get(state_data.xact_kv_ref, message.xid) do diff --git a/lib/tres/secure_channel_state.ex b/lib/tres/secure_channel_state.ex index e3f8873..71f04ff 100644 --- a/lib/tres/secure_channel_state.ex +++ b/lib/tres/secure_channel_state.ex @@ -17,7 +17,8 @@ defmodule Tres.SecureChannelState do ping_timer_ref: nil, ping_fail_count: 0, last_received: 0, - xact_kv_ref: nil + xact_kv_ref: nil, + action_queue: :queue.new ) alias __MODULE__ diff --git a/test/flay.ex b/test/flay.ex index f166928..65ab055 100644 --- a/test/flay.ex +++ b/test/flay.ex @@ -132,48 +132,10 @@ defmodule Flay do tables = [ TableFeatures.Body.new( table_id: 0, - max_entries: 2000, - instructions: [ - Openflow.Instruction.ApplyActions, - Openflow.Instruction.GotoTable - ], - next_tables: [1], - apply_actions: [ - Openflow.Action.Output, - Openflow.Action.PushVlan, - Openflow.Action.PopVlan, - Openflow.Action.SetField - ], - match: [ - :in_port, :eth_src, :eth_dst, :eth_type, :vlan_vid, - :ip_proto, :ipv4_src, :ipv4_dst, :tcp_dst,:udp_dst - ], - apply_setfield: [ - :eth_src, :eth_dst, :vlan_vid - ] - ), - TableFeatures.Body.new( - table_id: 0, - max_entries: 2000, - instructions: [ - Openflow.Instruction.ApplyActions - ], - next_tables: [], - apply_actions: [ - Openflow.Action.Output, - Openflow.Action.PushVlan, - Openflow.Action.PopVlan, - Openflow.Action.SetField - ], - match: [ - :in_port, :eth_src, :eth_dst, :eth_type, :vlan_vid, - :ip_proto, :ipv4_src, :ipv4_dst, :tcp_dst,:udp_dst - ], - apply_setfield: [ - :eth_src, :eth_dst, :vlan_vid, :ipv4_src, :ipv4_dst, - :arp_spa, :arp_tpa, :arp_tha - ] - ), + name: "Custom L2 Src", + max_entries: 8192, + config: [:table_miss_mask] + ) ] TableFeatures.Request.new(tables) |> send_message(datapath_id)