pespin has submitted this change. (
https://gerrit.osmocom.org/c/erlang/osmo-epdg/+/36340?usp=email )
Change subject: epdg: Trigger AAR+AAA upon rx of RAR
......................................................................
epdg: Trigger AAR+AAA upon rx of RAR
Related: OS#6406
Change-Id: I478b781e65eb5dd0cce5b51c75a1aa592b6555bc
---
M src/aaa_diameter_swm.erl
M src/aaa_ue_fsm.erl
M src/epdg_diameter_swm.erl
M src/epdg_ue_fsm.erl
4 files changed, 150 insertions(+), 17 deletions(-)
Approvals:
Jenkins Builder: Verified
pespin: Looks good to me, approved
diff --git a/src/aaa_diameter_swm.erl b/src/aaa_diameter_swm.erl
index fadff7e..0f5e279 100644
--- a/src/aaa_diameter_swm.erl
+++ b/src/aaa_diameter_swm.erl
@@ -17,6 +17,7 @@
-export([rx_der_auth_request/4,
rx_der_auth_compl_request/2,
rx_reauth_answer/2,
+ rx_auth_request/1,
rx_session_termination_request/1,
rx_abort_session_answer/1]).
-export([tx_dea_auth_response/2,
@@ -65,6 +66,10 @@
rx_reauth_answer(Imsi, Result) ->
gen_server:cast(?SERVER, {raa, Imsi, Result}).
+% 3GPP TS 29.273 7.2.2.1.3 Diameter-AA-Request (AAR) Command
+rx_auth_request(Imsi) ->
+ gen_server:cast(?SERVER, {aar, Imsi}).
+
rx_session_termination_request(Imsi) ->
gen_server:cast(?SERVER, {str, Imsi}).
@@ -98,6 +103,22 @@
end,
{noreply, State};
+handle_cast({aar, Imsi}, State) ->
+ case aaa_ue_fsm:get_pid_by_imsi(Imsi) of
+ Pid when is_pid(Pid) ->
+ case aaa_ue_fsm:ev_rx_swm_auth_request(Pid) of
+ ok ->
+ epdg_diameter_swm:rx_auth_answer(Imsi, ok);
+ _ ->
+ RC_UNABLE_TO_COMPLY=5012,
+ epdg_diameter_swm:rx_auth_answer(Imsi, {error, RC_UNABLE_TO_COMPLY})
+ end;
+ undefined ->
+ RC_USER_UNKNOWN=5030,
+ epdg_diameter_swm:rx_auth_answer(Imsi, {error, RC_USER_UNKNOWN})
+ end,
+ {noreply, State};
+
handle_cast({str, Imsi}, State) ->
case aaa_ue_fsm:get_pid_by_imsi(Imsi) of
Pid when is_pid(Pid) ->
diff --git a/src/aaa_ue_fsm.erl b/src/aaa_ue_fsm.erl
index abbe40e..968c7bd 100644
--- a/src/aaa_ue_fsm.erl
+++ b/src/aaa_ue_fsm.erl
@@ -43,7 +43,8 @@
-export([init/1,callback_mode/0,terminate/3]).
-export([get_server_name_by_imsi/1, get_pid_by_imsi/1]).
-export([ev_rx_swm_der_auth_req/2, ev_rx_swm_der_auth_compl/2,
- ev_rx_swm_reauth_answer/2, ev_rx_swm_str/1, ev_rx_swm_asa/1,
+ ev_rx_swm_reauth_answer/2, ev_rx_swm_auth_request/1,
+ ev_rx_swm_str/1, ev_rx_swm_asa/1,
ev_rx_swx_maa/2, ev_rx_swx_saa/2, ev_rx_swx_ppr/2, ev_rx_swx_rtr/1,
ev_rx_s6b_aar/2, ev_rx_s6b_str/1, ev_rx_s6b_raa/2, ev_rx_s6b_asa/2]).
-export([state_new/3,
@@ -104,6 +105,15 @@
{error, Err}
end.
+ev_rx_swm_auth_request(Pid) ->
+ lager:info("ue_fsm ev_rx_swm_auth_request~n", []),
+ try
+ gen_statem:call(Pid, rx_swm_auth_request)
+ catch
+ exit:Err ->
+ {error, Err}
+ end.
+
ev_rx_swm_der_auth_compl(Pid, Apn) ->
lager:info("ue_fsm ev_rx_swm_der_auth_compl~n", []),
try
@@ -371,6 +381,11 @@
%% SWx PPA was already answered immediately when PPR was received, nothing to do
here.
{keep_state, Data, [{reply,From,ok}]};
+state_authenticated({call, From}, rx_swm_auth_request, Data) ->
+ lager:info("ue_fsm state_authenticated event=rx_swm_auth_request,
~p~n", [Data]),
+ %% answer is trnamsitted when returning ok:
+ {keep_state, Data, [{reply,From,ok}]};
+
state_authenticated({call, From}, {rx_s6b_raa, Result}, Data) ->
lager:info("ue_fsm state_authenticated event=rx_s6b_raa ~p, ~p~n",
[Result, Data]),
%% SWx PPA was already answered immediately when PPR was received, nothing to do
here.
diff --git a/src/epdg_diameter_swm.erl b/src/epdg_diameter_swm.erl
index cdf572f..ba5893c 100644
--- a/src/epdg_diameter_swm.erl
+++ b/src/epdg_diameter_swm.erl
@@ -15,13 +15,15 @@
-export([code_change/3, terminate/2]).
-export([tx_der_auth_request/4,
- tx_reauth_answer/2,
tx_der_auth_compl_request/2,
+ tx_reauth_answer/2,
+ tx_auth_req/1,
tx_session_termination_request/1,
tx_abort_session_answer/1]).
-export([rx_dea_auth_response/2,
rx_dea_auth_compl_response/2,
rx_reauth_request/1,
+ rx_auth_answer/2,
rx_session_termination_answer/2,
rx_abort_session_request/1]).
@@ -56,6 +58,12 @@
ImsiStr = binary_to_list(Imsi),
ok = gen_server:cast(?SERVER, {tx_dia, {der_auth_compl_req, ImsiStr, Apn}}).
+% 3GPP TS 29.273 7.1.2.2
+tx_auth_req(Imsi) ->
+ % In Diameter we use Imsi as strings, as done by diameter module.
+ ImsiStr = binary_to_list(Imsi),
+ ok = gen_server:cast(?SERVER, {tx_dia, {aar, ImsiStr}}).
+
% 3GPP TS 29.273 7.1.2.3
tx_session_termination_request(Imsi) ->
% In Diameter we use Imsi as strings, as done by diameter module.
@@ -73,6 +81,10 @@
ok = gen_server:cast(?SERVER, {rx_dia, {rar, Imsi}}).
%% Emulation from the wire (DIAMETER SWm), called from internal AAA Server:
+rx_auth_answer(Imsi, Result) ->
+ ok = gen_server:cast(?SERVER, {rx_dia, {aaa, Imsi, Result}}).
+
+%% Emulation from the wire (DIAMETER SWm), called from internal AAA Server:
rx_dea_auth_response(Imsi, Result) ->
ok = gen_server:cast(?SERVER, {rx_dia, {dea_auth_resp, Imsi, Result}}).
@@ -113,6 +125,12 @@
aaa_diameter_swm:rx_der_auth_compl_request(Imsi, Apn),
{noreply, State};
+% 3GPP TS 29.273 7.2.2.1.3 Diameter-AA-Request (AAR) Command
+handle_cast({tx_dia, {aar, Imsi}}, State) ->
+ % we yet don't implement the Diameter SWm interface on the wire, we process the call
internally:
+ aaa_diameter_swm:rx_auth_request(Imsi),
+ {noreply, State};
+
handle_cast({tx_dia, {str, Imsi}}, State) ->
% we yet don't implement the Diameter SWm interface on the wire, we process the call
internally:
aaa_diameter_swm:rx_session_termination_request(Imsi),
@@ -155,6 +173,16 @@
end,
{noreply, State};
+handle_cast({rx_dia, {aaa, ImsiStr, Result}}, State) ->
+ Imsi = list_to_binary(ImsiStr),
+ case epdg_ue_fsm:get_pid_by_imsi(Imsi) of
+ Pid when is_pid(Pid) ->
+ epdg_ue_fsm:received_swm_auth_answer(Pid, Result);
+ undefined ->
+ lager:notice("SWm Rx RAR: unknown swm-session ~p", [Imsi])
+ end,
+ {noreply, State};
+
handle_cast({rx_dia, {sta, ImsiStr, Result}}, State) ->
Imsi = list_to_binary(ImsiStr),
case epdg_ue_fsm:get_pid_by_imsi(Imsi) of
diff --git a/src/epdg_ue_fsm.erl b/src/epdg_ue_fsm.erl
index 8a0c16e..4a090e9 100644
--- a/src/epdg_ue_fsm.erl
+++ b/src/epdg_ue_fsm.erl
@@ -44,7 +44,8 @@
-export([get_server_name_by_imsi/1, get_pid_by_imsi/1]).
-export([auth_request/2, lu_request/1, tunnel_request/2, purge_ms_request/1,
cancel_location_result/1]).
--export([received_swm_reauth_request/1, received_swm_dea_auth_response/2,
received_swm_dea_auth_compl_response/2,
+-export([received_swm_reauth_request/1, received_swm_dea_auth_response/2,
+ received_swm_dea_auth_compl_response/2, received_swm_auth_answer/2,
received_swm_session_termination_answer/2,
received_swm_abort_session_request/1]).
-export([received_gtpc_create_session_response/2,
received_gtpc_delete_session_response/2, received_gtpc_delete_bearer_request/1]).
-export([state_new/3,
@@ -69,7 +70,9 @@
pgw_rem_addr_list = [] :: list(),
tun_pdp_ctx :: epdg_tun_pdp_ctx,
tear_down_gsup_needed = false :: boolean(), %% need to send GSUP
PurgeMSResp after STR+STA?
- tear_down_gsup_cause = 0 :: integer()
+ tear_down_gsup_cause = 0 :: integer(),
+ tear_down_s2b_needed = false :: boolean(), %% need to send S2b
DeleteSessionReq
+ tear_down_tx_swm_asa_needed = false :: boolean() %% need to send SWm ASA
}).
get_server_name_by_imsi(Imsi) ->
@@ -147,6 +150,15 @@
{error, Err}
end.
+received_swm_auth_answer(Pid, Result) ->
+lager:info("ue_fsm received_swm_auth_answer~n", []),
+try
+gen_statem:call(Pid, {received_swm_auth_answer, Result})
+catch
+exit:Err ->
+ {error, Err}
+end.
+
received_swm_dea_auth_response(Pid, Result) ->
lager:info("ue_fsm received_swm_dea_auth_response ~p~n", [Result]),
try
@@ -342,13 +354,26 @@
state_authenticated({call, From}, received_swm_reauth_request, Data) ->
lager:info("ue_fsm state_authenticated event=received_swm_reauth_request,
~p~n", [Data]),
epdg_diameter_swm:tx_reauth_answer(Data#ue_fsm_data.imsi,
#epdg_dia_rc{result_code = 2001}),
- % TODO: 3GPP TS 29.273 7.1.2.5.1:
+ % 3GPP TS 29.273 7.1.2.5.1:
% Upon receiving the re-authorization request, the ePDG shall immediately invoke
the authorization procedure
% specified in 7.1.2.2 for the session indicated in the request. This procedure
is based on the Diameter
% commands AA-Request (AAR) and AA-Answer (AAA) specified in IETF RFC 4005 [4].
Information
% element contents for these messages are shown in tables 7.1.2.2.1/1 and
7.1.2.2.1/2.
+ epdg_diameter_swm:tx_auth_req(Data#ue_fsm_data.imsi),
{keep_state, Data, [{reply,From,ok}]};
+
+state_authenticated({call, From}, {received_swm_auth_answer, Result}, Data) ->
+ lager:info("ue_fsm state_authenticated event=received_swm_auth_answer(~p),
~p~n", [Result, Data]),
+ case Result of
+ ok ->
+ {keep_state, Data, [{reply,From,ok}]};
+ _ ->
+ Data1 = Data#ue_fsm_data{tear_down_gsup_needed = false,
+ tear_down_s2b_needed = false},
+ {next_state, state_dereg_net_initiated_wait_cancel_location_res, Data1,
[{reply,From,ok}]}
+ end;
+
state_authenticated({call, From}, purge_ms_request, Data) ->
lager:info("ue_fsm state_authenticated event=purge_ms_request, ~p~n",
[Data]),
Data1 = Data#ue_fsm_data{tear_down_gsup_needed = true},
@@ -397,7 +422,7 @@
end;
state_wait_create_session_resp({call, From}, Event, Data) ->
- lager:error("ue_fsm state_wait_delete_session_resp: Unexpected call event
~p, ~p~n", [Event, Data]),
+ lager:error("ue_fsm state_wait_create_session_resp: Unexpected call event
~p, ~p~n", [Event, Data]),
{keep_state, Data, [{reply,From,{error,unexpected_event}}]};
state_wait_create_session_resp(state_timeout, create_session_timeout, Data) ->
@@ -421,13 +446,28 @@
state_active({call, From}, received_swm_reauth_request, Data) ->
lager:info("ue_fsm state_active event=received_swm_reauth_request,
~p~n", [Data]),
epdg_diameter_swm:tx_reauth_answer(Data#ue_fsm_data.imsi,
#epdg_dia_rc{result_code = 2001}),
- % TODO: 3GPP TS 29.273 7.1.2.5.1:
+ % 3GPP TS 29.273 7.1.2.5.1:
% Upon receiving the re-authorization request, the ePDG shall immediately invoke
the authorization procedure
% specified in 7.1.2.2 for the session indicated in the request. This procedure
is based on the Diameter
% commands AA-Request (AAR) and AA-Answer (AAA) specified in IETF RFC 4005 [4].
Information
% element contents for these messages are shown in tables 7.1.2.2.1/1 and
7.1.2.2.1/2.
+ epdg_diameter_swm:tx_auth_req(Data#ue_fsm_data.imsi),
{keep_state, Data, [{reply,From,ok}]};
+state_active({call, From}, {received_swm_auth_answer, Result}, Data) ->
+ lager:info("ue_fsm state_active event=received_swm_auth_answer(~p),
~p~n", [Result, Data]),
+ case Result of
+ ok ->
+ {keep_state, Data, [{reply,From,ok}]};
+ _ ->
+ gtp_u_tun:delete_pdp_context(Data#ue_fsm_data.tun_pdp_ctx),
+ Data1 = Data#ue_fsm_data{tun_pdp_ctx = undefined,
+ tear_down_gsup_needed = false,
+ tear_down_s2b_needed = true,
+ tear_down_tx_swm_asa_needed = false},
+ {next_state, state_dereg_net_initiated_wait_cancel_location_res, Data1,
[{reply,From,ok}]}
+ end;
+
state_active({call, From}, purge_ms_request, Data) ->
lager:info("ue_fsm state_active event=purge_ms_request, ~p~n",
[Data]),
gtp_u_tun:delete_pdp_context(Data#ue_fsm_data.tun_pdp_ctx),
@@ -440,14 +480,20 @@
state_active({call, From}, received_gtpc_delete_bearer_request, Data) ->
lager:info("ue_fsm state_active event=received_gtpc_delete_bearer_request,
~p~n", [Data]),
gtp_u_tun:delete_pdp_context(Data#ue_fsm_data.tun_pdp_ctx),
- Data1 = Data#ue_fsm_data{tun_pdp_ctx = undefined, tear_down_gsup_needed =
false},
+ Data1 = Data#ue_fsm_data{tun_pdp_ctx = undefined,
+ tear_down_gsup_needed = false,
+ tear_down_s2b_needed = false,
+ tear_down_tx_swm_asa_needed = false},
{next_state, state_dereg_pgw_initiated_wait_cancel_location_res, Data1,
[{reply,From,ok}]};
%%% network (HSS/AAA) initiated de-registation requested:
state_active({call, From}, received_swm_asr, Data) ->
lager:info("ue_fsm state_active event=received_swm_asr, ~p~n",
[Data]),
gtp_u_tun:delete_pdp_context(Data#ue_fsm_data.tun_pdp_ctx),
- Data1 = Data#ue_fsm_data{tun_pdp_ctx = undefined, tear_down_gsup_needed =
false},
+ Data1 = Data#ue_fsm_data{tun_pdp_ctx = undefined,
+ tear_down_gsup_needed = false,
+ tear_down_s2b_needed = true,
+ tear_down_tx_swm_asa_needed = true},
{next_state, state_dereg_net_initiated_wait_cancel_location_res, Data1,
[{reply,From,ok}]};
state_active({call, From}, Event, Data) ->
@@ -575,13 +621,26 @@
%% have triggered GTPCv1 Delete Session Req against PGW.
%% Wait for GTPCv1 Delete Session Response, ssend SWm ASA to AAAA and terminate FSM.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+tx_swm_asa_if_needed(Data) ->
+ case Data#ue_fsm_data.tear_down_tx_swm_asa_needed of
+ true ->
+ epdg_diameter_swm:tx_abort_session_answer(Data#ue_fsm_data.imsi);
+ false -> lager:debug("Skip sending SWm ASA", [])
+ end.
+
state_dereg_net_initiated_wait_s2b_delete_session_resp(enter, _OldState, Data) ->
- case epdg_gtpc_s2b:delete_session_req(Data#ue_fsm_data.imsi) of
- ok ->
- {keep_state, Data,
{state_timeout,?TIMEOUT_VAL_WAIT_GTP_ANSWER,s2b_delete_session_timeout}};
- {error, Err} ->
- epdg_diameter_swm:tx_abort_session_answer(Data#ue_fsm_data.imsi),
- {stop, {error,Err}}
+ case Data#ue_fsm_data.tear_down_s2b_needed of
+ true ->
+ case epdg_gtpc_s2b:delete_session_req(Data#ue_fsm_data.imsi) of
+ ok ->
+ {keep_state, Data,
{state_timeout,?TIMEOUT_VAL_WAIT_GTP_ANSWER,s2b_delete_session_timeout}};
+ {error, Err} ->
+ tx_swm_asa_if_needed(Data),
+ {stop, {error,Err}}
+ end;
+ false ->
+ tx_swm_asa_if_needed(Data),
+ {stop, normal}
end;
state_dereg_net_initiated_wait_s2b_delete_session_resp({call, From},
{received_gtpc_delete_session_response, _Resp = #gtp{version = v2, type =
delete_session_response, ie = IEs}}, Data) ->
@@ -589,7 +648,7 @@
#{{v2_cause,0} := CauseIE} = IEs,
GtpCause = gtp_utils:enum_v2_cause(CauseIE#v2_cause.v2_cause),
lager:debug("Cause: GTP_atom=~p -> GTP_int=~p~n",
[CauseIE#v2_cause.v2_cause, GtpCause]),
- epdg_diameter_swm:tx_abort_session_answer(Data#ue_fsm_data.imsi),
+ tx_swm_asa_if_needed(Data),
{stop_and_reply, normal, [{reply,From,ok}], Data};
state_dereg_net_initiated_wait_s2b_delete_session_resp({call, From}, Event, Data) ->
@@ -599,5 +658,5 @@
state_dereg_net_initiated_wait_s2b_delete_session_resp(state_timeout,
s2b_delete_session_timeout, Data) ->
lager:error("ue_fsm state_dereg_net_initiated_wait_s2b_delete_session_resp:
Timeout ~p, ~p~n", [s2b_delete_session_timeout, Data]),
- epdg_diameter_swm:tx_abort_session_answer(Data#ue_fsm_data.imsi),
+ tx_swm_asa_if_needed(Data),
{stop, normal}.
--
To view, visit
https://gerrit.osmocom.org/c/erlang/osmo-epdg/+/36340?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: erlang/osmo-epdg
Gerrit-Branch: master
Gerrit-Change-Id: I478b781e65eb5dd0cce5b51c75a1aa592b6555bc
Gerrit-Change-Number: 36340
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: pespin <pespin(a)sysmocom.de>
Gerrit-MessageType: merged