pespin has uploaded this change for review. (
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 message.
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, 131 insertions(+), 13 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/erlang/osmo-epdg refs/changes/05/36305/1
diff --git a/src/aaa_diameter_swm.erl b/src/aaa_diameter_swm.erl
index 9fa656e..e084cb4 100644
--- a/src/aaa_diameter_swm.erl
+++ b/src/aaa_diameter_swm.erl
@@ -15,10 +15,15 @@
-export([code_change/3, terminate/2]).
-export([rx_auth_request/4,
+ rx_auth_answer/2,
rx_auth_compl_request/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_request/1,
+ tx_auth_response/2,
+ tx_auth_compl_response/2,
+ tx_session_termination_answer/2,
+ tx_as_request/1]).
-define(SERVER, ?MODULE).
@@ -32,6 +37,10 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Tx over emulated SWm wire:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+tx_auth_request(Imsi) ->
+ _Result = gen_server:call(?SERVER, {aar, Imsi}).
+
tx_auth_response(Imsi, Result) ->
_Result = gen_server:call(?SERVER, {epdg_auth_resp, Imsi, Result}).
@@ -50,6 +59,9 @@
rx_auth_request(Imsi, PdpTypeNr, Apn, EAP) ->
gen_server:cast(?SERVER, {epdg_auth_req, Imsi, PdpTypeNr, Apn, EAP}).
+rx_auth_answer(Imsi, Result) ->
+ gen_server:cast(?SERVER, {aaa, Imsi, Result}).
+
rx_auth_compl_request(Imsi, Apn) ->
gen_server:cast(?SERVER, {epdg_auth_compl_req, Imsi, Apn}).
@@ -59,6 +71,8 @@
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({aaa, Imsi, Result}, State) ->
+ case aaa_ue_fsm:get_pid_by_imsi(Imsi) of
+ Pid when is_pid(Pid) -> aaa_ue_fsm:ev_rx_swm_auth_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({aar, Imsi}, _From, State) ->
+ epdg_diameter_swm:rx_auth_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..4c7e7cc 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_auth_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_auth_answer(Pid, Result) ->
+ lager:info("ue_fsm ev_rx_swm_auth_answer~n", []),
+ try
+ gen_statem:call(Pid, {rx_swm_auth_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,17 @@
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) ->
+ case aaa_diameter_swm:tx_auth_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_auth_answer, Result}, Data) ->
+ lager:info("ue_fsm state_authenticated event=rx_swm_auth_answer ~p,
~p~n", [Result, Data]),
+ %% SWx PPA was already answered immediatelly 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..c85724a 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,10 +21,12 @@
-export([code_change/3, terminate/2]).
-export([tx_auth_request/4,
+ tx_auth_answer/2,
tx_auth_compl_request/2,
tx_session_termination_request/1,
tx_abort_session_answer/1]).
--export([rx_auth_response/2,
+-export([rx_auth_request/1,
+ rx_auth_response/2,
rx_auth_compl_response/2,
rx_session_termination_answer/2,
rx_abort_session_request/1]).
@@ -54,6 +57,11 @@
_ -> Result
end.
+tx_auth_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, {aaa, 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({aaa, Imsi, DiaRC}, {Pid, _Tag} = _From, State) ->
+ % we yet don't implement the Diameter SWm interface on the wire, we process the call
internally:
+ aaa_diameter_swm:rx_auth_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),
@@ -128,6 +141,25 @@
end,
{reply, Reply, State}.
+handle_cast({aar, Imsi}, State) ->
+ Sess = find_swm_session_by_imsi(Imsi, State),
+ case Sess of
+ #swm_session{imsi = Imsi} ->
+ case epdg_ue_fsm:received_swm_auth_request(Sess#swm_session.pid) of
+ ok ->
+ DiaResultCode = 2001, %% SUCCESS
+ aaa_diameter_swm:rx_auth_answer(Imsi, DiaResultCode);
+ _ ->
+ DiaResultCode = 5012, %% UNABLE_TO_COMPLY
+ aaa_diameter_swm:rx_auth_answer(Imsi, DiaResultCode)
+ end;
+ undefined ->
+ lager:notice("SWm Rx AAR: unknown swm-session ~p", [Imsi]),
+ DiaResultCode = 5002, %% UNKNOWN_SESSION_ID
+ aaa_diameter_swm:rx_auth_answer(Imsi, DiaResultCode)
+ end,
+ {noreply, State};
+
handle_cast({epdg_auth_resp, 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_auth_request(Imsi) ->
+ ok = gen_server:cast(?SERVER, {aar, 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..8046d1a 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_auth_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_auth_request(Pid) ->
+ lager:info("ue_fsm received_swm_auth_request~n", []),
+ try
+ gen_statem:call(Pid, received_swm_auth_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_auth_request, Data) ->
+ lager:info("ue_fsm state_authenticated event=received_swm_auth_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 synchrnously for now when returning from call:
+ %%epdg_diameter_swm:tx_auth_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},
--
To view, visit
https://gerrit.osmocom.org/c/erlang/osmo-epdg/+/36305?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: I4fe309ac54c61f134dbd471486c7d1a70731c9bb
Gerrit-Change-Number: 36305
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin(a)sysmocom.de>
Gerrit-MessageType: newchange