pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/erlang/osmo-epdg/+/35901?usp=email )
Change subject: Make PDP-Type and APN from GSUP AuthInfoReq available through all layers ......................................................................
Make PDP-Type and APN from GSUP AuthInfoReq available through all layers
Change-Id: I3f29b00f57f433f8623b9f0a5048c83985e5cced --- M src/aaa_diameter_swm.erl M src/aaa_diameter_swx.erl M src/aaa_ue_fsm.erl M src/epdg_diameter_swm.erl M src/epdg_ue_fsm.erl M src/gsup_server.erl 6 files changed, 72 insertions(+), 30 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/erlang/osmo-epdg refs/changes/01/35901/1
diff --git a/src/aaa_diameter_swm.erl b/src/aaa_diameter_swm.erl index ee3a8cb..7fdc247 100644 --- a/src/aaa_diameter_swm.erl +++ b/src/aaa_diameter_swm.erl @@ -20,7 +20,7 @@ -export([init/1, handle_call/3, handle_cast/2, handle_info/2]). -export([code_change/3, terminate/2]).
--export([auth_request/1, auth_compl_request/2, session_termination_request/1]). +-export([auth_request/3, auth_compl_request/2, session_termination_request/1]). -export([auth_response/2, auth_compl_response/2, session_termination_answer/2]).
-define(SERVER, ?MODULE). @@ -47,8 +47,8 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Rx from emulated SWm wire: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -auth_request(Imsi) -> - gen_server:cast(?SERVER, {epdg_auth_req, Imsi}). +auth_request(Imsi, PdpTypeNr, Apn) -> + gen_server:cast(?SERVER, {epdg_auth_req, Imsi, PdpTypeNr, Apn}).
auth_compl_request(Imsi, Apn) -> gen_server:cast(?SERVER, {epdg_auth_compl_req, Imsi, Apn}). @@ -56,9 +56,9 @@ session_termination_request(Imsi) -> gen_server:cast(?SERVER, {str, Imsi}).
-handle_cast({epdg_auth_req, Imsi}, State0) -> +handle_cast({epdg_auth_req, Imsi, PdpTypeNr, Apn}, State0) -> {Sess, State1} = find_or_new_swm_session(Imsi, State0), - aaa_ue_fsm:ev_swm_auth_req(Sess#swm_session.pid), + aaa_ue_fsm:ev_swm_auth_req(Sess#swm_session.pid, {PdpTypeNr, Apn}), {noreply, State1};
handle_cast({epdg_auth_compl_req, Imsi, Apn}, State) -> diff --git a/src/aaa_diameter_swx.erl b/src/aaa_diameter_swx.erl index 1db5809..6b8523c 100644 --- a/src/aaa_diameter_swx.erl +++ b/src/aaa_diameter_swx.erl @@ -49,7 +49,7 @@ %% gen_server Function Exports -export([init/1, handle_call/3, handle_cast/2, handle_info/2]). -export([code_change/3]). --export([multimedia_auth_request/6]). +-export([multimedia_auth_request/7]). -export([server_assignment_request/3]). -export([test/0, test/1]).
@@ -136,11 +136,11 @@ test("001011234567890").
test(IMSI) -> - multimedia_auth_request(IMSI, 3, "EAP-AKA", 1, [], []). + multimedia_auth_request(IMSI, 3, "EAP-AKA", 1, [], [], 33).
-multimedia_auth_request(IMSI, NumAuthItems, AuthScheme, RAT, CKey, IntegrityKey) -> +multimedia_auth_request(IMSI, NumAuthItems, AuthScheme, RAT, CKey, IntegrityKey, PdpTypeNr) -> gen_server:call(?SERVER, - {mar, {IMSI, NumAuthItems, AuthScheme, RAT, CKey, IntegrityKey}}). + {mar, {IMSI, NumAuthItems, AuthScheme, RAT, CKey, IntegrityKey, PdpTypeNr}}). % APN is optional and should be [] server_assignment_request(IMSI, Type, APN) -> gen_server:call(?SERVER, @@ -181,8 +181,28 @@ parse_saa(Saa) -> {unknown_err, []}.
-handle_call({mar, {IMSI, NumAuthItems, AuthScheme, RAT, CKey, IntegrityKey}}, {Pid, _Tag} = _From, State) -> +handle_call({mar, {IMSI, NumAuthItems, AuthScheme, RAT, CKey, IntegrityKey, PdpTypeNr}}, {Pid, _Tag} = _From, State) -> SessionId = diameter:session_id(application:get_env(?ENV_APP_NAME, origin_host, ?ENV_DEFAULT_ORIG_HOST)), + % RFC 4005 6.11.1 Framed-IP-Address AVP: + % "0xFFFFFFFE indicates that the NAS should select an address for the user + % (e.g., assigned from a pool of addresses kept by the NAS)." + %Ipv4Dyn = 16#FFFFFFFE, + case PdpTypeNr of + % FIXME: For some reason encoding when not empty fails... + %16#21 -> + % IPv4Opt = <Ipv4Dyn:32>, + % IPv6Opt = []; + %16#57 -> + % IPv4Opt = [], + % IPv6Opt = <<>>; + %16#8d -> + % IPv4Opt = <Ipv4Dyn:32>, + % IPv6Opt = <<>>; + _ -> + IPv4Opt = [], + IPv6Opt = [] + end, + lager:debug("Swx MAR: IPv4Opt=~p IPv6Opt=~p~n", [IPv4Opt, IPv6Opt]),% MAR = #'MAR'{'Vendor-Specific-Application-Id' = #'Vendor-Specific-Application-Id'{ 'Vendor-Id' = ?VENDOR_ID_3GPP, 'Auth-Application-Id' = [?DIAMETER_APP_ID_SWX]}, @@ -192,7 +212,10 @@ 'SIP-Auth-Data-Item' = #'SIP-Auth-Data-Item'{ 'SIP-Authentication-Scheme' = [AuthScheme], 'Confidentiality-Key' = CKey, - 'Integrity-Key' = IntegrityKey}, + 'Integrity-Key' = IntegrityKey, + 'Framed-IP-Address' = IPv4Opt, + 'Framed-IPv6-Prefix' = IPv6Opt + }, 'SIP-Number-Auth-Items' = NumAuthItems, 'RAT-Type' = RAT }, diff --git a/src/aaa_ue_fsm.erl b/src/aaa_ue_fsm.erl index 5cdb553..e982d57 100644 --- a/src/aaa_ue_fsm.erl +++ b/src/aaa_ue_fsm.erl @@ -41,7 +41,7 @@ -export([start_link/1]). -export([init/1,callback_mode/0,terminate/3]). -export([get_server_name_by_imsi/1, get_pid_by_imsi/1]). --export([ev_swm_auth_req/1, ev_swm_auth_compl/2, ev_rx_swm_str/1, ev_rx_swx_maa/2, ev_rx_swx_saa/2, +-export([ev_swm_auth_req/2, ev_swm_auth_compl/2, ev_rx_swm_str/1, ev_rx_swx_maa/2, ev_rx_swx_saa/2, ev_rx_s6b_aar/2, ev_rx_s6b_str/1]). -export([state_new/3, state_wait_swx_maa/3, state_wait_swx_saa/3, state_authenticated/3, state_authenticated_wait_swx_saa/3]).
@@ -66,10 +66,10 @@ lager:info("ue_fsm start_link(~p)~n", [ServerName]), gen_statem:start_link({local, ServerName}, ?MODULE, Imsi, [{debug, [trace]}]).
-ev_swm_auth_req(Pid) -> +ev_swm_auth_req(Pid, {PdpTypeNr, Apn}) -> lager:info("ue_fsm ev_swm_auth_req~n", []), try - gen_statem:call(Pid, swm_auth_req) + gen_statem:call(Pid, {swm_auth_req, PdpTypeNr, Apn}) catch exit:Err -> {error, Err} @@ -152,12 +152,12 @@ state_new(enter, _OldState, Data) -> {keep_state, Data};
-state_new({call, From}, swm_auth_req, Data) -> - lager:info("ue_fsm state_new event=swm_auth_req, ~p~n", [Data]), +state_new({call, From}, {swm_auth_req, PdpTypeNr, Apn}, Data) -> + lager:info("ue_fsm state_new event=swm_auth_req {~p, ~p}, ~p~n", [PdpTypeNr, Apn, Data]), % request the diameter code for a tuple CKey = [], IntegrityKey = [], - case aaa_diameter_swx:multimedia_auth_request(Data#ue_fsm_data.imsi, 1, "EAP-AKA", 1, CKey, IntegrityKey) of + case aaa_diameter_swx:multimedia_auth_request(Data#ue_fsm_data.imsi, 1, "EAP-AKA", 1, CKey, IntegrityKey, PdpTypeNr) of ok -> {next_state, state_wait_swx_maa, Data, [{reply,From,ok}]}; {error, Err} -> {keep_state, Data, [{reply,From,{error, Err}}]} end; diff --git a/src/epdg_diameter_swm.erl b/src/epdg_diameter_swm.erl index 800df44..9b010d9 100644 --- a/src/epdg_diameter_swm.erl +++ b/src/epdg_diameter_swm.erl @@ -19,7 +19,7 @@ -export([init/1, handle_call/3, handle_cast/2, handle_info/2]). -export([code_change/3, terminate/2]).
--export([auth_request/1, auth_compl_request/2, session_termination_request/1]). +-export([auth_request/3, auth_compl_request/2, session_termination_request/1]). -export([auth_response/2, auth_compl_response/2, session_termination_answer/2]).
-define(SERVER, ?MODULE). @@ -33,10 +33,13 @@ {ok, #swm_state{}}.
-auth_request(Imsi) -> +auth_request(Imsi, PdpTypeNr, Apn) -> % In Diameter we use Imsi as strings, as done by diameter module. ImsiStr = binary_to_list(Imsi), - Result = gen_server:call(?SERVER, {epdg_auth_req, ImsiStr}), + % epdg_auth_req: Swm Diameter message Diameter-EAP-Request 3GPP TS 29.273 7.2.2.1.1 + % PdpTypeNr: SWm Diameter AVP "UE-Local-IP-Address" + % Apn: SWm Diameter AVP "Service-Selection" + Result = gen_server:call(?SERVER, {epdg_auth_req, ImsiStr, PdpTypeNr, Apn}), case Result of {ok, _Mar} -> epdg_ue_fsm:received_swm_auth_response(self(), Result), @@ -68,10 +71,10 @@ _ -> Result end.
-handle_call({epdg_auth_req, Imsi}, {Pid, _Tag} = _From, State0) -> +handle_call({epdg_auth_req, Imsi, PdpTypeNr, Apn}, {Pid, _Tag} = _From, State0) -> % we yet don't implement the Diameter SWm interface on the wire, we process the call internally: {_Sess, State1} = find_or_new_swm_session(Imsi, Pid, State0), - ok = aaa_diameter_swm:auth_request(Imsi), + ok = aaa_diameter_swm:auth_request(Imsi, PdpTypeNr, Apn), {reply, ok, State1};
handle_call({epdg_auth_compl_req, Imsi, Apn}, _From, State) -> diff --git a/src/epdg_ue_fsm.erl b/src/epdg_ue_fsm.erl index 711f695..9221c79 100644 --- a/src/epdg_ue_fsm.erl +++ b/src/epdg_ue_fsm.erl @@ -40,7 +40,7 @@ -export([start_link/1, stop/1]). -export([init/1,callback_mode/0,terminate/3]). -export([get_server_name_by_imsi/1, get_pid_by_imsi/1]). --export([auth_request/1, lu_request/1, tunnel_request/1, purge_ms_request/1]). +-export([auth_request/2, lu_request/1, tunnel_request/1, purge_ms_request/1]). -export([received_swm_auth_response/2, received_swm_auth_compl_response/2, received_swm_session_termination_answer/2]). -export([received_gtpc_create_session_response/2, received_gtpc_delete_session_response/2, received_gtpc_delete_bearer_request/1]). -export([state_new/3, state_wait_auth_resp/3, state_authenticating/3, state_authenticated/3, @@ -69,10 +69,10 @@ stop(SrvRef) -> gen_statem:stop(SrvRef).
-auth_request(Pid) -> +auth_request(Pid, {PdpTypeNr, Apn}) -> lager:info("ue_fsm auth_request~n", []), try - gen_statem:call(Pid, auth_request) + gen_statem:call(Pid, {auth_request, PdpTypeNr, Apn}) catch exit:Err -> {error, Err} @@ -183,9 +183,9 @@ state_new(enter, _OldState, Data) -> {keep_state, Data};
-state_new({call, From}, auth_request, Data) -> - lager:info("ue_fsm state_new event=auth_request, ~p~n", [Data]), - case epdg_diameter_swm:auth_request(Data#ue_fsm_data.imsi) of +state_new({call, From}, {auth_request, PdpTypeNr, Apn}, Data) -> + lager:info("ue_fsm state_new event=auth_request {~p, ~p}, ~p~n", [PdpTypeNr, Apn, Data]), + case epdg_diameter_swm:auth_request(Data#ue_fsm_data.imsi, PdpTypeNr, Apn) of ok -> {next_state, state_wait_auth_resp, Data, [{reply,From,ok}]}; {error, Err} -> {stop_and_reply, Err, Data, [{reply,From,{error,Err}}]} end; diff --git a/src/gsup_server.erl b/src/gsup_server.erl index 8a070bf..799d6df 100644 --- a/src/gsup_server.erl +++ b/src/gsup_server.erl @@ -231,9 +231,16 @@ {noreply, S#gsups_state{socket=Socket}};
% send auth info / requesting authentication tuples -handle_info({ipa, Socket, ?IPAC_PROTO_EXT_GSUP, _GsupMsgRx = #{message_type := send_auth_info_req, imsi := Imsi}}, State0) -> +handle_info({ipa, Socket, ?IPAC_PROTO_EXT_GSUP, GsupMsgRx = #{message_type := send_auth_info_req, imsi := Imsi}}, State0) -> + #{pdp_info_list := [PdpInfo]} = GsupMsgRx, + #{pdp_context_id := _PDPCtxId, + pdp_address := #{address := #{}, + pdp_type_nr := PdpTypeNr, + pdp_type_org := 241}, + access_point_name := Apn + } = PdpInfo, {UE, State1} = find_or_new_gsups_ue(Imsi, State0), - case epdg_ue_fsm:auth_request(UE#gsups_ue.pid) of + case epdg_ue_fsm:auth_request(UE#gsups_ue.pid, {PdpTypeNr, Apn}) of ok -> State2 = State1; {error, Err} -> lager:error("Auth Req for Imsi ~p failed: ~p~n", [Imsi, Err]),