pespin has submitted this change. ( https://gerrit.osmocom.org/c/erlang/osmo-epdg/+/36305?usp=email )
Change subject: Propagate SWx PPR as SWm Authorization Update towards ePDG ......................................................................
Propagate SWx PPR as SWm Authorization Update towards ePDG
With this commit ePDG is still not invoking the authorization procedure specified in 3GPP TS 29.273 7.1.2.2, but only ACKing the RAR message from 7.1.2.5.
Related: OS#6404, OS#6400. Change-Id: I4fe309ac54c61f134dbd471486c7d1a70731c9bb --- M src/aaa_diameter_swm.erl M src/aaa_diameter_swx_cb.erl M src/aaa_ue_fsm.erl M src/epdg_diameter_swm.erl M src/epdg_ue_fsm.erl 5 files changed, 147 insertions(+), 12 deletions(-)
Approvals: pespin: Looks good to me, approved Jenkins Builder: Verified laforge: Looks good to me, but someone else must approve
diff --git a/src/aaa_diameter_swm.erl b/src/aaa_diameter_swm.erl index 9fa656e..c7c87a5 100644 --- a/src/aaa_diameter_swm.erl +++ b/src/aaa_diameter_swm.erl @@ -16,9 +16,14 @@
-export([rx_auth_request/4, rx_auth_compl_request/2, + rx_reauth_answer/2, rx_session_termination_request/1, rx_abort_session_answer/1]). --export([tx_auth_response/2, tx_auth_compl_response/2, tx_session_termination_answer/2, tx_as_request/1]). +-export([tx_auth_response/2, + tx_auth_compl_response/2, + tx_reauth_request/1, + tx_session_termination_answer/2, + tx_as_request/1]).
-define(SERVER, ?MODULE).
@@ -32,12 +37,16 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Tx over emulated SWm wire: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + tx_auth_response(Imsi, Result) -> _Result = gen_server:call(?SERVER, {epdg_auth_resp, Imsi, Result}).
tx_auth_compl_response(Imsi, Result) -> _Result = gen_server:call(?SERVER, {epdg_auth_compl_resp, Imsi, Result}).
+tx_reauth_request(Imsi) -> + _Result = gen_server:call(?SERVER, {rar, Imsi}). + tx_session_termination_answer(Imsi, Result) -> _Result = gen_server:call(?SERVER, {sta, Imsi, Result}).
@@ -53,12 +62,17 @@ rx_auth_compl_request(Imsi, Apn) -> gen_server:cast(?SERVER, {epdg_auth_compl_req, Imsi, Apn}).
+rx_reauth_answer(Imsi, Result) -> + gen_server:cast(?SERVER, {raa, Imsi, Result}). + rx_session_termination_request(Imsi) -> gen_server:cast(?SERVER, {str, Imsi}).
rx_abort_session_answer(Imsi) -> gen_server:cast(?SERVER, {asa, Imsi}).
+%% handle_cast: Rx side + handle_cast({epdg_auth_req, Imsi, PdpTypeNr, Apn, EAP}, State) -> case aaa_ue_fsm:get_pid_by_imsi(Imsi) of undefined -> {ok, Pid} = aaa_ue_fsm:start(Imsi); @@ -77,6 +91,13 @@ end, {noreply, State};
+handle_cast({raa, Imsi, Result}, State) -> + case aaa_ue_fsm:get_pid_by_imsi(Imsi) of + Pid when is_pid(Pid) -> aaa_ue_fsm:ev_rx_swm_reauth_answer(Pid, Result); + undefined -> ok + end, + {noreply, State}; + handle_cast({str, Imsi}, State) -> case aaa_ue_fsm:get_pid_by_imsi(Imsi) of Pid when is_pid(Pid) -> @@ -111,6 +132,7 @@ error_logger:error_report(["unknown handle_info", {module, ?MODULE}, {info, Info}, {state, S}]), {noreply, S}.
+%% handle_call: Tx side handle_call({epdg_auth_resp, Imsi, Result}, _From, State) -> epdg_diameter_swm:rx_auth_response(Imsi, Result), {reply, ok, State}; @@ -119,6 +141,10 @@ epdg_diameter_swm:rx_auth_compl_response(Imsi, Result), {reply, ok, State};
+handle_call({rar, Imsi}, _From, State) -> + epdg_diameter_swm:rx_reauth_request(Imsi), + {reply, ok, State}; + handle_call({sta, Imsi, DiaRC}, _From, State) -> epdg_diameter_swm:rx_session_termination_answer(Imsi, DiaRC), {reply, ok, State}; diff --git a/src/aaa_diameter_swx_cb.erl b/src/aaa_diameter_swx_cb.erl index 93335a2..99d2ba3 100644 --- a/src/aaa_diameter_swx_cb.erl +++ b/src/aaa_diameter_swx_cb.erl @@ -81,14 +81,8 @@ 'Non-3GPP-User-Data' = N3UAopt} = Req, case aaa_ue_fsm:get_pid_by_imsi(Imsi) of Pid when is_pid(Pid) -> - _PGWAddresses = parse_pgw_addr_from_N3UA(N3UAopt), - %% TODO: in successful case, we want to validate how this prcoedure extends to other interfaces: - %% """ 3GPP TS 29.273 8.1.2.3.3: - %% After a successful user profile download, the 3GPP AAA Server shall - %% initiate re-authentication procedure as described - %% in clause 7.2.2.4 if the subscriber has previously been authenticated - %% and authorized to untrusted non-3GPP access. - %% """ + PGWAddresses = parse_pgw_addr_from_N3UA(N3UAopt), + aaa_ue_fsm:ev_rx_swx_ppr(Pid, {PGWAddresses}), Res = 2001, %% Success ERes = []; undefined -> diff --git a/src/aaa_ue_fsm.erl b/src/aaa_ue_fsm.erl index 9ec6a00..b32d6c0 100644 --- a/src/aaa_ue_fsm.erl +++ b/src/aaa_ue_fsm.erl @@ -42,8 +42,8 @@ -export([start/1, stop/1]). -export([init/1,callback_mode/0,terminate/3]). -export([get_server_name_by_imsi/1, get_pid_by_imsi/1]). --export([ev_rx_swm_auth_req/2, ev_rx_swm_auth_compl/2, ev_rx_swm_str/1, ev_rx_swm_asa/1, - ev_rx_swx_maa/2, ev_rx_swx_saa/2, ev_rx_swx_rtr/1, +-export([ev_rx_swm_auth_req/2, ev_rx_swm_reauth_answer/2, ev_rx_swm_auth_compl/2, 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_asa/2]). -export([state_new/3, state_wait_swx_maa/3, @@ -94,6 +94,14 @@ exit:Err -> {error, Err} end. +ev_rx_swm_reauth_answer(Pid, Result) -> + lager:info("ue_fsm ev_rx_swm_reauth_answer~n", []), + try + gen_statem:call(Pid, {rx_swm_reauth_answer, Result}) + catch + exit:Err -> + {error, Err} + end.
ev_rx_swm_auth_compl(Pid, Apn) -> lager:info("ue_fsm ev_rx_swm_auth_compl~n", []), @@ -140,6 +148,15 @@ {error, Err} end.
+ev_rx_swx_ppr(Pid, PGWAddresses) -> + lager:info("ue_fsm ev_rx_swx_ppr~n", []), + try + gen_statem:call(Pid, {rx_swx_ppr, PGWAddresses}) + catch + exit:Err -> + {error, Err} + end. + ev_rx_swx_rtr(Pid) -> lager:info("ue_fsm ev_rx_swx_rtr~n", []), try @@ -318,6 +335,21 @@ lager:info("ue_fsm state_authenticated event=rx_swm_auth_req {~p, ~p, ~p}, ~p~n", [PdpTypeNr, Apn, EAP, Data]), {next_state, state_new, Data, [postpone]};
+state_authenticated({call, From}, {rx_swx_ppr, _PGWAddresses}, Data) -> + %% 3GPP TS 29.273 8.1.2.3.3: + %% After a successful user profile download, the 3GPP AAA Server shall + %% initiate re-authentication procedure as described + %% in clause 7.2.2.4 + case aaa_diameter_swm:tx_reauth_request(Data#ue_fsm_data.imsi) of + ok -> {keep_state, Data, [{reply,From,ok}]}; + {error, Err} -> {keep_state, Data, [{reply,From,{error, Err}}]} + end; + +state_authenticated({call, From}, {rx_swm_reauth_answer, Result}, Data) -> + lager:info("ue_fsm state_authenticated event=rx_swm_reauth_answer ~p, ~p~n", [Result, Data]), + %% 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_swx_rtr, Data) -> lager:info("ue_fsm state_authenticated event=rx_swx_rtr ~p~n", [Data]), case {Data#ue_fsm_data.pgw_sess_active, Data#ue_fsm_data.epdg_sess_active} of diff --git a/src/epdg_diameter_swm.erl b/src/epdg_diameter_swm.erl index c060d17..d78407c 100644 --- a/src/epdg_diameter_swm.erl +++ b/src/epdg_diameter_swm.erl @@ -5,6 +5,7 @@ -behaviour(gen_server).
-include_lib("diameter_3gpp_ts29_273_swx.hrl"). +-include("conv.hrl").
-record(swm_state, { sessions = sets:new() @@ -20,11 +21,13 @@ -export([code_change/3, terminate/2]).
-export([tx_auth_request/4, + tx_reauth_answer/2, tx_auth_compl_request/2, tx_session_termination_request/1, tx_abort_session_answer/1]). -export([rx_auth_response/2, rx_auth_compl_response/2, + rx_reauth_request/1, rx_session_termination_answer/2, rx_abort_session_request/1]).
@@ -54,6 +57,11 @@ _ -> Result end.
+tx_reauth_answer(Imsi, DiaRC) -> + % In Diameter we use Imsi as strings, as done by diameter module. + ImsiStr = binary_to_list(Imsi), + _Result = gen_server:call(?SERVER, {raa, ImsiStr, DiaRC}). + % Rx "GSUP CEAI LU Req" is our way of saying Rx "Swm Diameter-EAP REQ (DER) with EAP AVP containing successuful auth": tx_auth_compl_request(Imsi, Apn) -> % In Diameter we use Imsi as strings, as done by diameter module. @@ -95,6 +103,11 @@ ok = aaa_diameter_swm:rx_auth_request(Imsi, PdpTypeNr, Apn, EAP), {reply, ok, State1};
+handle_call({raa, Imsi, DiaRC}, _From, State) -> + % we yet don't implement the Diameter SWm interface on the wire, we process the call internally: + aaa_diameter_swm:rx_reauth_answer(Imsi, DiaRC#epdg_dia_rc.result_code), + {reply, ok, State}; + handle_call({epdg_auth_compl_req, Imsi, Apn}, _From, State) -> % we yet don't implement the Diameter SWm interface on the wire, we process the call internally: Sess = find_swm_session_by_imsi(Imsi, State), @@ -148,6 +161,25 @@ end, {noreply, State};
+handle_cast({rar, Imsi}, State) -> + Sess = find_swm_session_by_imsi(Imsi, State), + case Sess of + #swm_session{imsi = Imsi} -> + case epdg_ue_fsm:received_swm_reauth_request(Sess#swm_session.pid) of + ok -> + DiaResultCode = 2001, %% SUCCESS + aaa_diameter_swm:rx_reauth_answer(Imsi, DiaResultCode); + _ -> + DiaResultCode = 5012, %% UNABLE_TO_COMPLY + aaa_diameter_swm:rx_reauth_answer(Imsi, DiaResultCode) + end; + undefined -> + lager:notice("SWm Rx AAR: unknown swm-session ~p", [Imsi]), + DiaResultCode = 5002, %% UNKNOWN_SESSION_ID + aaa_diameter_swm:rx_reauth_answer(Imsi, DiaResultCode) + end, + {noreply, State}; + handle_cast({sta, Imsi, Result}, State) -> Sess = find_swm_session_by_imsi(Imsi, State), case Sess of @@ -186,6 +218,10 @@ lager:info("terminating ~p with reason ~p~n", [?MODULE, Reason]).
%% Emulation from the wire (DIAMETER SWm), called from internal AAA Server: +rx_reauth_request(Imsi) -> + ok = gen_server:cast(?SERVER, {rar, Imsi}). + +%% Emulation from the wire (DIAMETER SWm), called from internal AAA Server: rx_auth_response(Imsi, Result) -> ok = gen_server:cast(?SERVER, {epdg_auth_resp, Imsi, Result}).
diff --git a/src/epdg_ue_fsm.erl b/src/epdg_ue_fsm.erl index 6b6f756..b75a865 100644 --- a/src/epdg_ue_fsm.erl +++ b/src/epdg_ue_fsm.erl @@ -44,7 +44,7 @@ -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_auth_response/2, received_swm_auth_compl_response/2, +-export([received_swm_reauth_request/1, received_swm_auth_response/2, received_swm_auth_compl_response/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, @@ -137,6 +137,15 @@ {error, Err} end.
+received_swm_reauth_request(Pid) -> + lager:info("ue_fsm received_swm_reauth_request~n", []), + try + gen_statem:call(Pid, received_swm_reauth_request) + catch + exit:Err -> + {error, Err} + end. + received_swm_auth_response(Pid, Result) -> lager:info("ue_fsm received_swm_auth_response ~p~n", [Result]), try @@ -327,6 +336,18 @@ Data#ue_fsm_data.pgw_rem_addr_list), {next_state, state_wait_create_session_resp, Data, [{reply,From,ok}]};
+state_authenticated({call, From}, received_swm_reauth_request, Data) -> + lager:info("ue_fsm state_authenticated event=received_swm_reauth_request, ~p~n", [Data]), + % TODO: 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. + % + % This is done synchronously for now when returning from call: + %%epdg_diameter_swm:tx_reauth_answer(Data#ue_fsm_data.imsi, #epdg_dia_rc{result_code = 2001}), + {keep_state, Data, [{reply,From,ok}]}; + 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}, @@ -396,6 +417,18 @@ Data1 = Data#ue_fsm_data{tun_pdp_ctx = undefined}, {next_state, state_new, Data1, [postpone]};
+state_active({call, From}, received_swm_reauth_request, Data) -> + lager:info("ue_fsm state_active event=received_swm_reauth_request, ~p~n", [Data]), + % TODO: 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. + % + % This is done synchronously for now when returning from call: + %%epdg_diameter_swm:tx_reauth_answer(Data#ue_fsm_data.imsi, #epdg_dia_rc{result_code = 2001}), + {keep_state, Data, [{reply,From,ok}]}; + 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),