Loading src/te/apps/epce/src/epce_server.erl +45 −23 Original line number Original line Diff line number Diff line Loading @@ -67,8 +67,8 @@ get_flows() -> update_flow(FlowId, LabelStack) -> update_flow(FlowId, LabelStack) -> gen_server:call(?MODULE, {update_flow, FlowId, LabelStack}). gen_server:call(?MODULE, {update_flow, FlowId, LabelStack}). initiate_flow(Name, FromAddr, ToAddr, BindingLabel) -> initiate_flow(Name, From, To, BindingLabel) -> gen_server:call(?MODULE, {initiate_flow, Name, FromAddr, ToAddr, gen_server:call(?MODULE, {initiate_flow, Name, From, To, BindingLabel}, ?LARGE_TIMEOUT). BindingLabel}, ?LARGE_TIMEOUT). Loading Loading @@ -111,8 +111,14 @@ handle_call({update_flow, FlowId, Labels}, From, {noreply, State} {noreply, State} end end end; end; handle_call({initiate_flow, Name, FromAddr, ToAddr, Binding}, From, handle_call({initiate_flow, Name, FromKey, ToKey, Binding}, From, #state{sessions = SessMap} = State) -> #state{sessions = SessMap} = State) -> case {pcc_address(FromKey), pcc_address(ToKey)} of {{error, Reason}, _} -> {reply, {error, Reason}, State}; {_, {error, Reason}} -> {reply, {error, Reason}, State}; {{ok, FromAddr}, {ok, ToAddr}} -> case maps:find(FromAddr, SessMap) of case maps:find(FromAddr, SessMap) of error -> {reply, {error, session_not_found}, State}; error -> {reply, {error, session_not_found}, State}; {ok, #sess{pid = Pid}} -> {ok, #sess{pid = Pid}} -> Loading @@ -120,11 +126,12 @@ handle_call({initiate_flow, Name, FromAddr, ToAddr, Binding}, From, {error, Reason} -> {error, Reason} -> {reply, {error, Reason}, State}; {reply, {error, Reason}, State}; {ok, Labels} -> {ok, Labels} -> InitRoute = routeinit_from_labels(Name, FromAddr, ToAddr, InitRoute = routeinit_from_labels(Name, FromAddr, [], Binding, Labels), ToAddr, [], Binding, Labels), session_initiate_flow(State, Pid, InitRoute, From), session_initiate_flow(State, Pid, InitRoute, From), {noreply, State} {noreply, State} end end end end; end; handle_call({session_opened, Id, Caps, Pid}, _From, handle_call({session_opened, Id, Caps, Pid}, _From, #state{sessions = SessMap, sess_pids = SessPids} = State) -> #state{sessions = SessMap, sess_pids = SessPids} = State) -> Loading Loading @@ -227,17 +234,32 @@ terminate(_Reason, _State) -> %%% INTERNAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% INTERNAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% compute_path(From, To) -> ted_index(Id) when is_binary(Id) -> id; case epce_ted:compute_path(pcc_address, From, To) of ted_index({_, _, _, _}) -> pcc_address. {ok, Devices} -> Labels = tl([L || #{mpls_label := L} <- Devices, L =/= undefined]), pcc_address(Key) -> logger:debug("Route from ~p to ~p: ~p", [From, To, Labels]), case epce_ted:lookup(ted_index(Key), Key) of {ok, Labels}; {error, Reason} -> {error, Reason} -> logger:warning("Failed to find a PCC address for router ~p: ~p", [Key, Reason]), {error, router_not_found}; {ok, #{pcc_address := Addr}} -> {ok, Addr} end. compute_path(From, To) when is_binary(From), is_binary(To) -> compute_path_result(From, To, epce_ted:compute_path(id, From, To)); compute_path({_, _, _, _} = From, {_, _, _, _} = To) -> compute_path_result(From, To, epce_ted:compute_path(pcc_address, From, To)). compute_path_result(From, To, {error, Reason}) -> logger:warning("Failed to find a route from ~p to ~p: ~p", logger:warning("Failed to find a route from ~p to ~p: ~p", [From, To, Reason]), [From, To, Reason]), {error, route_not_found} {error, route_not_found}; end. compute_path_result(From, To, {ok, Devices}) -> Labels = tl([L || #{mpls_label := L} <- Devices, L =/= undefined]), logger:debug("Route from ~p to ~p: ~p", [From, To, Labels]), {ok, Labels}. routereq_from_labels(Source, Destination, Constraints, Labels) -> routereq_from_labels(Source, Destination, Constraints, Labels) -> #{ #{ Loading src/te/apps/epce/src/epce_ted.erl +20 −0 Original line number Original line Diff line number Diff line Loading @@ -19,6 +19,7 @@ -export([link_updated/2]). -export([link_updated/2]). -export([link_deleted/1]). -export([link_deleted/1]). -export([compute_path/3]). -export([compute_path/3]). -export([lookup/2]). -export([get_graph/0]). -export([get_graph/0]). Loading Loading @@ -69,6 +70,12 @@ compute_path(Index, From, To) compute_path(Index, _From, _To) -> compute_path(Index, _From, _To) -> {error, {invalid_index, Index}}. {error, {invalid_index, Index}}. lookup(Index, Key) when Index =:= id; Index =:= pcc_address -> gen_server:call(?MODULE, {lookup, Index, Key}); lookup(Index, _Key) -> {error, {invalid_index, Index}}. get_graph() -> get_graph() -> gen_server:call(?MODULE, get_graph). gen_server:call(?MODULE, get_graph). Loading Loading @@ -106,6 +113,13 @@ handle_call({compute_path, Index, From, To}, _From, #state{graph = G} = State) - {error, Reason} -> {error, Reason} -> {reply, {error, Reason}, State} {reply, {error, Reason}, State} end; end; handle_call({lookup, Index, Key}, _From, #state{graph = G} = State) -> case as_ids(State, Index, [Key]) of {ok, [Id]} -> {reply, do_lookup(G, Id), State}; {error, Reason} -> {reply, {error, Reason}, State} end; handle_call(get_graph, _From, #state{graph = G} = State) -> handle_call(get_graph, _From, #state{graph = G} = State) -> {reply, G, State}; {reply, G, State}; handle_call(Request, _From, State) -> handle_call(Request, _From, State) -> Loading Loading @@ -193,6 +207,12 @@ do_compute_path(G, FromId, ToId) -> Ids -> {ok, retrieve_devices(G, Ids, [])} Ids -> {ok, retrieve_devices(G, Ids, [])} end. end. do_lookup(G, Id) -> case digraph:vertex(G, Id) of {_, Info} -> {ok, Info}; false -> {error, not_found} end. retrieve_devices(_G, [], Acc) -> retrieve_devices(_G, [], Acc) -> lists:reverse(Acc); lists:reverse(Acc); retrieve_devices(G, [Id | Rest], Acc) -> retrieve_devices(G, [Id | Rest], Acc) -> Loading src/te/apps/tfte/src/tfte.app.src +1 −0 Original line number Original line Diff line number Diff line Loading @@ -7,6 +7,7 @@ [kernel, [kernel, stdlib, stdlib, tfpb, tfpb, jsx, epce epce ]}, ]}, {env,[]}, {env,[]}, Loading src/te/apps/tfte/src/tfte_server.erl +59 −0 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,8 @@ -export([context_event/1]). -export([context_event/1]). -export([topology_ready/1]). -export([topology_ready/1]). -export([topology_event/1]). -export([topology_event/1]). -export([request_lsp/1]). -export([delete_lsp/1]). % Behaviour gen_statem functions % Behaviour gen_statem functions -export([init/1]). -export([init/1]). Loading @@ -28,6 +30,7 @@ %%% Records %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Records %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -record(data, { -record(data, { services = #{} }). }). Loading @@ -51,6 +54,12 @@ topology_ready(Topology) -> topology_event(Event) -> topology_event(Event) -> gen_statem:cast(?MODULE, {topology_event, Event}). gen_statem:cast(?MODULE, {topology_event, Event}). request_lsp(ServiceMap) -> gen_statem:cast(?MODULE, {request_lsp, ServiceMap}). delete_lsp(ServiceId) -> gen_statem:cast(?MODULE, {delete_lsp, ServiceId}). %%% BEHAVIOUR gen_statem FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% BEHAVIOUR gen_statem FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Loading Loading @@ -83,6 +92,17 @@ handle_event(cast, {topology_ready, _Topology}, ready, _Data) -> handle_event(cast, {topology_event, _Event}, ready, _Data) -> handle_event(cast, {topology_event, _Event}, ready, _Data) -> ?LOG_DEBUG("Teraflow topology event: ~p", [_Event]), ?LOG_DEBUG("Teraflow topology event: ~p", [_Event]), keep_state_and_data; keep_state_and_data; handle_event({call, _From}, {request_lsp, ServiceMap}, ready, Data) -> #{service_id := ServiceId} = ServiceMap, ?LOG_DEBUG("Teraflow service ~s requested its LSPs", [format_service_id(ServiceId)]), {Result, Data2} = do_request_lsp(Data, ServiceMap), {keep_state, Data2, [{reply, Result}]}; handle_event(cast, {delete_lsp, ServiceId}, ready, Data) -> ?LOG_DEBUG("Teraflow service ~s delete its LSPs", [format_service_id(ServiceId)]), {Result, Data2} = do_delete_lsp(Data, ServiceId), {keep_state, Data2, [{reply, Result}]}; %-- ANY STATE ------------------------------------------------------------------ %-- ANY STATE ------------------------------------------------------------------ handle_event(EventType, EventContent, State, Data) -> handle_event(EventType, EventContent, State, Data) -> ?LOG_WARNING(Data, "Unexpected ~w event in state ~w: ~w", ?LOG_WARNING(Data, "Unexpected ~w event in state ~w: ~w", Loading @@ -98,3 +118,42 @@ code_change(_OldVsn, OldState, OldData, _Extra) -> %%% INTERNAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% INTERNAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% format_service_id(#{context_id := #{context_uuid := #{uuid := ContextName}}, service_uuid := #{uuid := ServiceUUID}}) -> iolist_to_binary(io_lib:format("~s:~s", [ContextName, ServiceUUID])). do_request_lsp(#data{services = Services} = Data, #{service_type := 'SERVICETYPE_TE'} = ServiceMap) -> #{service_config := Config, service_endpoint_ids := Endpoints, service_id := ServiceId} = ServiceMap, #{binding_label := BindingLabel1, symbolic_name := SymbolicName1} = tfte_util:custom_config(Config, <<"/lsp-fw">>), #{binding_label := BindingLabel2, symbolic_name := SymbolicName2} = tfte_util:custom_config(Config, <<"/lsp-bw">>), [#{device_id := #{device_uuid := #{uuid := Id1}}}, #{device_id := #{device_uuid := #{uuid := Id2}}}] = Endpoints, case epce_server:initiate_flow(SymbolicName1, Id1, Id2, BindingLabel1) of {error, Reason} -> ?LOG_ERROR("Error while setting up service ~s forward LSP: ~p", [format_service_id(ServiceId), Reason]), {'SERVICESTATUS_UNDEFINED', Data}; {ok, ForwardFlow} -> case epce_server:initiate_flow(SymbolicName2, Id2, Id1, BindingLabel2) of {error, Reason} -> ?LOG_ERROR("Error while setting up service ~s backward LSP: ~p", [format_service_id(ServiceId), Reason]), %TODO: Cleanup forward flow ? {'SERVICESTATUS_UNDEFINED', Data}; {ok, BackwardFlow} -> ServiceData = {ServiceMap, ForwardFlow, BackwardFlow}, Services2 = Services#{ServiceId => ServiceData}, Data2 = Data#data{services = Services2}, {'SERVICESTATUS_ACTIVE', Data2} end end. do_delete_lsp(Data, ServiceId) -> ?LOG_INFO("LSP DELETION REQUESTED ~p", [ServiceId]), {'SERVICESTATUS_UNDEFINED', Data}. No newline at end of file src/te/apps/tfte/src/tfte_te_service.erl +16 −7 Original line number Original line Diff line number Diff line Loading @@ -6,6 +6,7 @@ %%% INCLUDES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% INCLUDES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -include_lib("grpcbox/include/grpcbox.hrl"). -include_lib("grpcbox/include/grpcbox.hrl"). -include_lib("kernel/include/logger.hrl"). %%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Loading @@ -18,14 +19,22 @@ %%% BEHAVIOUR te_te_service_bhvr CALLBACK FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% BEHAVIOUR te_te_service_bhvr CALLBACK FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%% request_lsp(_Ctx, _Service) -> request_lsp(_Ctx, Service) -> {error, {?GRPC_STATUS_UNIMPLEMENTED, <<"Not yet implemented">>}, ?LOG_ERROR("Requesting LSP: ~p", [Service]), #{headers => #{}, trailers => #{}}}. try tfte_server:request_lsp(Service) catch E:R:S -> ?LOG_ERROR("Error while requesting LSP: ~p:~p ~p", [E, R, S]), 'SERVICESTATUS_UNDEFINED' end. update_lsp(_Ctx, _Service) -> update_lsp(_Ctx, _ServiceId) -> {error, {?GRPC_STATUS_UNIMPLEMENTED, <<"Not yet implemented">>}, {error, {?GRPC_STATUS_UNIMPLEMENTED, <<"Not yet implemented">>}, #{headers => #{}, trailers => #{}}}. #{headers => #{}, trailers => #{}}}. delete_lsp(_Ctx, _Service) -> delete_lsp(_Ctx, ServiceId) -> {error, {?GRPC_STATUS_UNIMPLEMENTED, <<"Not yet implemented">>}, ?LOG_ERROR("Deleting LSP: ~p", [ServiceId]), #{headers => #{}, trailers => #{}}}. try tfte_server:delete_lsp(ServiceId) catch E:R:S -> ?LOG_ERROR("Error while deleting LSP: ~p:~p ~p", [E, R, S]), 'SERVICESTATUS_UNDEFINED' end. Loading
src/te/apps/epce/src/epce_server.erl +45 −23 Original line number Original line Diff line number Diff line Loading @@ -67,8 +67,8 @@ get_flows() -> update_flow(FlowId, LabelStack) -> update_flow(FlowId, LabelStack) -> gen_server:call(?MODULE, {update_flow, FlowId, LabelStack}). gen_server:call(?MODULE, {update_flow, FlowId, LabelStack}). initiate_flow(Name, FromAddr, ToAddr, BindingLabel) -> initiate_flow(Name, From, To, BindingLabel) -> gen_server:call(?MODULE, {initiate_flow, Name, FromAddr, ToAddr, gen_server:call(?MODULE, {initiate_flow, Name, From, To, BindingLabel}, ?LARGE_TIMEOUT). BindingLabel}, ?LARGE_TIMEOUT). Loading Loading @@ -111,8 +111,14 @@ handle_call({update_flow, FlowId, Labels}, From, {noreply, State} {noreply, State} end end end; end; handle_call({initiate_flow, Name, FromAddr, ToAddr, Binding}, From, handle_call({initiate_flow, Name, FromKey, ToKey, Binding}, From, #state{sessions = SessMap} = State) -> #state{sessions = SessMap} = State) -> case {pcc_address(FromKey), pcc_address(ToKey)} of {{error, Reason}, _} -> {reply, {error, Reason}, State}; {_, {error, Reason}} -> {reply, {error, Reason}, State}; {{ok, FromAddr}, {ok, ToAddr}} -> case maps:find(FromAddr, SessMap) of case maps:find(FromAddr, SessMap) of error -> {reply, {error, session_not_found}, State}; error -> {reply, {error, session_not_found}, State}; {ok, #sess{pid = Pid}} -> {ok, #sess{pid = Pid}} -> Loading @@ -120,11 +126,12 @@ handle_call({initiate_flow, Name, FromAddr, ToAddr, Binding}, From, {error, Reason} -> {error, Reason} -> {reply, {error, Reason}, State}; {reply, {error, Reason}, State}; {ok, Labels} -> {ok, Labels} -> InitRoute = routeinit_from_labels(Name, FromAddr, ToAddr, InitRoute = routeinit_from_labels(Name, FromAddr, [], Binding, Labels), ToAddr, [], Binding, Labels), session_initiate_flow(State, Pid, InitRoute, From), session_initiate_flow(State, Pid, InitRoute, From), {noreply, State} {noreply, State} end end end end; end; handle_call({session_opened, Id, Caps, Pid}, _From, handle_call({session_opened, Id, Caps, Pid}, _From, #state{sessions = SessMap, sess_pids = SessPids} = State) -> #state{sessions = SessMap, sess_pids = SessPids} = State) -> Loading Loading @@ -227,17 +234,32 @@ terminate(_Reason, _State) -> %%% INTERNAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% INTERNAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% compute_path(From, To) -> ted_index(Id) when is_binary(Id) -> id; case epce_ted:compute_path(pcc_address, From, To) of ted_index({_, _, _, _}) -> pcc_address. {ok, Devices} -> Labels = tl([L || #{mpls_label := L} <- Devices, L =/= undefined]), pcc_address(Key) -> logger:debug("Route from ~p to ~p: ~p", [From, To, Labels]), case epce_ted:lookup(ted_index(Key), Key) of {ok, Labels}; {error, Reason} -> {error, Reason} -> logger:warning("Failed to find a PCC address for router ~p: ~p", [Key, Reason]), {error, router_not_found}; {ok, #{pcc_address := Addr}} -> {ok, Addr} end. compute_path(From, To) when is_binary(From), is_binary(To) -> compute_path_result(From, To, epce_ted:compute_path(id, From, To)); compute_path({_, _, _, _} = From, {_, _, _, _} = To) -> compute_path_result(From, To, epce_ted:compute_path(pcc_address, From, To)). compute_path_result(From, To, {error, Reason}) -> logger:warning("Failed to find a route from ~p to ~p: ~p", logger:warning("Failed to find a route from ~p to ~p: ~p", [From, To, Reason]), [From, To, Reason]), {error, route_not_found} {error, route_not_found}; end. compute_path_result(From, To, {ok, Devices}) -> Labels = tl([L || #{mpls_label := L} <- Devices, L =/= undefined]), logger:debug("Route from ~p to ~p: ~p", [From, To, Labels]), {ok, Labels}. routereq_from_labels(Source, Destination, Constraints, Labels) -> routereq_from_labels(Source, Destination, Constraints, Labels) -> #{ #{ Loading
src/te/apps/epce/src/epce_ted.erl +20 −0 Original line number Original line Diff line number Diff line Loading @@ -19,6 +19,7 @@ -export([link_updated/2]). -export([link_updated/2]). -export([link_deleted/1]). -export([link_deleted/1]). -export([compute_path/3]). -export([compute_path/3]). -export([lookup/2]). -export([get_graph/0]). -export([get_graph/0]). Loading Loading @@ -69,6 +70,12 @@ compute_path(Index, From, To) compute_path(Index, _From, _To) -> compute_path(Index, _From, _To) -> {error, {invalid_index, Index}}. {error, {invalid_index, Index}}. lookup(Index, Key) when Index =:= id; Index =:= pcc_address -> gen_server:call(?MODULE, {lookup, Index, Key}); lookup(Index, _Key) -> {error, {invalid_index, Index}}. get_graph() -> get_graph() -> gen_server:call(?MODULE, get_graph). gen_server:call(?MODULE, get_graph). Loading Loading @@ -106,6 +113,13 @@ handle_call({compute_path, Index, From, To}, _From, #state{graph = G} = State) - {error, Reason} -> {error, Reason} -> {reply, {error, Reason}, State} {reply, {error, Reason}, State} end; end; handle_call({lookup, Index, Key}, _From, #state{graph = G} = State) -> case as_ids(State, Index, [Key]) of {ok, [Id]} -> {reply, do_lookup(G, Id), State}; {error, Reason} -> {reply, {error, Reason}, State} end; handle_call(get_graph, _From, #state{graph = G} = State) -> handle_call(get_graph, _From, #state{graph = G} = State) -> {reply, G, State}; {reply, G, State}; handle_call(Request, _From, State) -> handle_call(Request, _From, State) -> Loading Loading @@ -193,6 +207,12 @@ do_compute_path(G, FromId, ToId) -> Ids -> {ok, retrieve_devices(G, Ids, [])} Ids -> {ok, retrieve_devices(G, Ids, [])} end. end. do_lookup(G, Id) -> case digraph:vertex(G, Id) of {_, Info} -> {ok, Info}; false -> {error, not_found} end. retrieve_devices(_G, [], Acc) -> retrieve_devices(_G, [], Acc) -> lists:reverse(Acc); lists:reverse(Acc); retrieve_devices(G, [Id | Rest], Acc) -> retrieve_devices(G, [Id | Rest], Acc) -> Loading
src/te/apps/tfte/src/tfte.app.src +1 −0 Original line number Original line Diff line number Diff line Loading @@ -7,6 +7,7 @@ [kernel, [kernel, stdlib, stdlib, tfpb, tfpb, jsx, epce epce ]}, ]}, {env,[]}, {env,[]}, Loading
src/te/apps/tfte/src/tfte_server.erl +59 −0 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,8 @@ -export([context_event/1]). -export([context_event/1]). -export([topology_ready/1]). -export([topology_ready/1]). -export([topology_event/1]). -export([topology_event/1]). -export([request_lsp/1]). -export([delete_lsp/1]). % Behaviour gen_statem functions % Behaviour gen_statem functions -export([init/1]). -export([init/1]). Loading @@ -28,6 +30,7 @@ %%% Records %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Records %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -record(data, { -record(data, { services = #{} }). }). Loading @@ -51,6 +54,12 @@ topology_ready(Topology) -> topology_event(Event) -> topology_event(Event) -> gen_statem:cast(?MODULE, {topology_event, Event}). gen_statem:cast(?MODULE, {topology_event, Event}). request_lsp(ServiceMap) -> gen_statem:cast(?MODULE, {request_lsp, ServiceMap}). delete_lsp(ServiceId) -> gen_statem:cast(?MODULE, {delete_lsp, ServiceId}). %%% BEHAVIOUR gen_statem FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% BEHAVIOUR gen_statem FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Loading Loading @@ -83,6 +92,17 @@ handle_event(cast, {topology_ready, _Topology}, ready, _Data) -> handle_event(cast, {topology_event, _Event}, ready, _Data) -> handle_event(cast, {topology_event, _Event}, ready, _Data) -> ?LOG_DEBUG("Teraflow topology event: ~p", [_Event]), ?LOG_DEBUG("Teraflow topology event: ~p", [_Event]), keep_state_and_data; keep_state_and_data; handle_event({call, _From}, {request_lsp, ServiceMap}, ready, Data) -> #{service_id := ServiceId} = ServiceMap, ?LOG_DEBUG("Teraflow service ~s requested its LSPs", [format_service_id(ServiceId)]), {Result, Data2} = do_request_lsp(Data, ServiceMap), {keep_state, Data2, [{reply, Result}]}; handle_event(cast, {delete_lsp, ServiceId}, ready, Data) -> ?LOG_DEBUG("Teraflow service ~s delete its LSPs", [format_service_id(ServiceId)]), {Result, Data2} = do_delete_lsp(Data, ServiceId), {keep_state, Data2, [{reply, Result}]}; %-- ANY STATE ------------------------------------------------------------------ %-- ANY STATE ------------------------------------------------------------------ handle_event(EventType, EventContent, State, Data) -> handle_event(EventType, EventContent, State, Data) -> ?LOG_WARNING(Data, "Unexpected ~w event in state ~w: ~w", ?LOG_WARNING(Data, "Unexpected ~w event in state ~w: ~w", Loading @@ -98,3 +118,42 @@ code_change(_OldVsn, OldState, OldData, _Extra) -> %%% INTERNAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% INTERNAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% format_service_id(#{context_id := #{context_uuid := #{uuid := ContextName}}, service_uuid := #{uuid := ServiceUUID}}) -> iolist_to_binary(io_lib:format("~s:~s", [ContextName, ServiceUUID])). do_request_lsp(#data{services = Services} = Data, #{service_type := 'SERVICETYPE_TE'} = ServiceMap) -> #{service_config := Config, service_endpoint_ids := Endpoints, service_id := ServiceId} = ServiceMap, #{binding_label := BindingLabel1, symbolic_name := SymbolicName1} = tfte_util:custom_config(Config, <<"/lsp-fw">>), #{binding_label := BindingLabel2, symbolic_name := SymbolicName2} = tfte_util:custom_config(Config, <<"/lsp-bw">>), [#{device_id := #{device_uuid := #{uuid := Id1}}}, #{device_id := #{device_uuid := #{uuid := Id2}}}] = Endpoints, case epce_server:initiate_flow(SymbolicName1, Id1, Id2, BindingLabel1) of {error, Reason} -> ?LOG_ERROR("Error while setting up service ~s forward LSP: ~p", [format_service_id(ServiceId), Reason]), {'SERVICESTATUS_UNDEFINED', Data}; {ok, ForwardFlow} -> case epce_server:initiate_flow(SymbolicName2, Id2, Id1, BindingLabel2) of {error, Reason} -> ?LOG_ERROR("Error while setting up service ~s backward LSP: ~p", [format_service_id(ServiceId), Reason]), %TODO: Cleanup forward flow ? {'SERVICESTATUS_UNDEFINED', Data}; {ok, BackwardFlow} -> ServiceData = {ServiceMap, ForwardFlow, BackwardFlow}, Services2 = Services#{ServiceId => ServiceData}, Data2 = Data#data{services = Services2}, {'SERVICESTATUS_ACTIVE', Data2} end end. do_delete_lsp(Data, ServiceId) -> ?LOG_INFO("LSP DELETION REQUESTED ~p", [ServiceId]), {'SERVICESTATUS_UNDEFINED', Data}. No newline at end of file
src/te/apps/tfte/src/tfte_te_service.erl +16 −7 Original line number Original line Diff line number Diff line Loading @@ -6,6 +6,7 @@ %%% INCLUDES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% INCLUDES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -include_lib("grpcbox/include/grpcbox.hrl"). -include_lib("grpcbox/include/grpcbox.hrl"). -include_lib("kernel/include/logger.hrl"). %%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Loading @@ -18,14 +19,22 @@ %%% BEHAVIOUR te_te_service_bhvr CALLBACK FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% BEHAVIOUR te_te_service_bhvr CALLBACK FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%% request_lsp(_Ctx, _Service) -> request_lsp(_Ctx, Service) -> {error, {?GRPC_STATUS_UNIMPLEMENTED, <<"Not yet implemented">>}, ?LOG_ERROR("Requesting LSP: ~p", [Service]), #{headers => #{}, trailers => #{}}}. try tfte_server:request_lsp(Service) catch E:R:S -> ?LOG_ERROR("Error while requesting LSP: ~p:~p ~p", [E, R, S]), 'SERVICESTATUS_UNDEFINED' end. update_lsp(_Ctx, _Service) -> update_lsp(_Ctx, _ServiceId) -> {error, {?GRPC_STATUS_UNIMPLEMENTED, <<"Not yet implemented">>}, {error, {?GRPC_STATUS_UNIMPLEMENTED, <<"Not yet implemented">>}, #{headers => #{}, trailers => #{}}}. #{headers => #{}, trailers => #{}}}. delete_lsp(_Ctx, _Service) -> delete_lsp(_Ctx, ServiceId) -> {error, {?GRPC_STATUS_UNIMPLEMENTED, <<"Not yet implemented">>}, ?LOG_ERROR("Deleting LSP: ~p", [ServiceId]), #{headers => #{}, trailers => #{}}}. try tfte_server:delete_lsp(ServiceId) catch E:R:S -> ?LOG_ERROR("Error while deleting LSP: ~p:~p ~p", [E, R, S]), 'SERVICESTATUS_UNDEFINED' end.