pespin has submitted this change. (
https://gerrit.osmocom.org/c/erlang/osmo-epdg/+/36112?usp=email )
Change subject: s2b: Handle CreateSession with failed Cause
......................................................................
s2b: Handle CreateSession with failed Cause
Related: OS#6371
Change-Id: I7bc840e863c0a1eff3b1df2c42f6b1868dec8dae
---
M src/epdg_gtpc_s2b.erl
M src/epdg_ue_fsm.erl
M src/gsup_server.erl
M src/gtp_utils.erl
4 files changed, 89 insertions(+), 49 deletions(-)
Approvals:
Jenkins Builder: Verified
pespin: Looks good to me, approved
laforge: Looks good to me, but someone else must approve
diff --git a/src/epdg_gtpc_s2b.erl b/src/epdg_gtpc_s2b.erl
index cef9bab..b0a34bd 100644
--- a/src/epdg_gtpc_s2b.erl
+++ b/src/epdg_gtpc_s2b.erl
@@ -389,46 +389,13 @@
{noreply, State0};
Sess0 ->
% Do GTP specific msg parsing here, pass only relevant fields:
- #{{v2_fully_qualified_tunnel_endpoint_identifier,1} :=
- #v2_fully_qualified_tunnel_endpoint_identifier{
- interface_type = 32, %% "S2b PGW GTP-C"
- key = RemoteTEIC, ipv4 = _IPc4, ipv6 = _IPc6},
- {v2_pdn_address_allocation,0} := Paa,
- {v2_bearer_context,0} := #v2_bearer_context{instance = 0, group =
BearerIE}} = Resp#gtp.ie,
- % Parse BearerContext:
- #{{v2_eps_bearer_id,0} := #v2_eps_bearer_id{instance = 0, eps_bearer_id =
Ebi},
- {v2_fully_qualified_tunnel_endpoint_identifier,4} :=
- #v2_fully_qualified_tunnel_endpoint_identifier{
- interface_type = 33, %% "S2b-U PGW GTP-U"
- key = RemoteTEID, ipv4 = IPu4, ipv6 = IPu6}
- } = BearerIE,
- Bearer = gtp_session_find_bearer_by_ebi(Sess0, Ebi),
- Sess1 = gtp_session_update_bearer(Sess0, Bearer,
Bearer#gtp_bearer{remote_data_tei = RemoteTEID}),
- Sess2 = Sess1#gtp_session{remote_control_tei = RemoteTEIC},
- lager:info("s2b: Updated Session after create_session_response:
~p~n", [Sess2]),
- State1 = update_gtp_session(Sess0, Sess2, State0),
- case maps:find({v2_additional_protocol_configuration_options,0}, Resp#gtp.ie)
of
- {ok, APCO_dec} ->
- lager:debug("s2b: APCO_dec: ~p~n", [APCO_dec]),
- APCO =
gtp_packet:encode_protocol_config_opts(APCO_dec#v2_additional_protocol_configuration_options.config);
- error ->
- lager:notice("s2b: APCO not found in CreateSessionResp!~n",
[]),
- APCO = undefined
- end,
- ResInfo0 = #{
- apn => binary_to_list(Sess0#gtp_session.apn),
- eua => conv:gtp2_paa_to_epdg_eua(Paa),
- local_teid => Bearer#gtp_bearer.local_data_tei,
- remote_teid => RemoteTEID,
- remote_ipv4 => IPu4,
- remote_ipv6 => IPu6
- },
- case APCO of
- undefined -> ResInfo = ResInfo0;
- _ -> ResInfo = maps:put(apco, APCO, ResInfo0)
- end,
- epdg_ue_fsm:received_gtpc_create_session_response(Sess0#gtp_session.pid, {ok,
ResInfo}),
- {noreply, State1}
+ % First lookup Cause:
+ #{{v2_cause,0} := #v2_cause{instance = 0, v2_cause = GtpCauseAtom}} =
Resp#gtp.ie,
+ GtpCause = gtp_utils:enum_v2_cause(GtpCauseAtom),
+ case gtp_utils:v2_cause_successful(GtpCause) of
+ true -> rx_gtp_create_session_response_successful(Resp, Sess0, State0);
+ false -> rx_gtp_create_session_response_failure(GtpCause, Sess0, State0)
+ end
end;
rx_gtp(Resp = #gtp{version = v2, type = delete_session_response}, State0) ->
@@ -487,6 +454,54 @@
lager:error("S2b: UNIMPLEMENTED Rx: ~p~n", [Req]),
{noreply, State}.
+
+rx_gtp_create_session_response_successful(Resp, Sess0, State0) ->
+ #{{v2_fully_qualified_tunnel_endpoint_identifier,1} :=
+ #v2_fully_qualified_tunnel_endpoint_identifier{
+ interface_type = 32, %% "S2b PGW GTP-C"
+ key = RemoteTEIC, ipv4 = _IPc4, ipv6 = _IPc6},
+ {v2_pdn_address_allocation,0} := Paa,
+ {v2_bearer_context,0} := #v2_bearer_context{instance = 0, group = BearerIE}} =
Resp#gtp.ie,
+ % Parse BearerContext:
+ #{{v2_eps_bearer_id,0} := #v2_eps_bearer_id{instance = 0, eps_bearer_id = Ebi},
+ {v2_fully_qualified_tunnel_endpoint_identifier,4} :=
+ #v2_fully_qualified_tunnel_endpoint_identifier{
+ interface_type = 33, %% "S2b-U PGW GTP-U"
+ key = RemoteTEID, ipv4 = IPu4, ipv6 = IPu6}
+ } = BearerIE,
+ Bearer = gtp_session_find_bearer_by_ebi(Sess0, Ebi),
+ Sess1 = gtp_session_update_bearer(Sess0, Bearer, Bearer#gtp_bearer{remote_data_tei =
RemoteTEID}),
+ Sess2 = Sess1#gtp_session{remote_control_tei = RemoteTEIC},
+ lager:info("s2b: Updated Session after create_session_response: ~p~n",
[Sess2]),
+ State1 = update_gtp_session(Sess0, Sess2, State0),
+ case maps:find({v2_additional_protocol_configuration_options,0}, Resp#gtp.ie) of
+ {ok, APCO_dec} ->
+ lager:debug("s2b: APCO_dec: ~p~n", [APCO_dec]),
+ APCO =
gtp_packet:encode_protocol_config_opts(APCO_dec#v2_additional_protocol_configuration_options.config);
+ error ->
+ lager:notice("s2b: APCO not found in CreateSessionResp!~n", []),
+ APCO = undefined
+ end,
+ ResInfo0 = #{
+ apn => binary_to_list(Sess0#gtp_session.apn),
+ eua => conv:gtp2_paa_to_epdg_eua(Paa),
+ local_teid => Bearer#gtp_bearer.local_data_tei,
+ remote_teid => RemoteTEID,
+ remote_ipv4 => IPu4,
+ remote_ipv6 => IPu6
+ },
+ case APCO of
+ undefined -> ResInfo = ResInfo0;
+ _ -> ResInfo = maps:put(apco, APCO, ResInfo0)
+ end,
+ epdg_ue_fsm:received_gtpc_create_session_response(Sess0#gtp_session.pid, {ok,
ResInfo}),
+ {noreply, State1}.
+
+rx_gtp_create_session_response_failure(GtpCause, Sess, State0) ->
+ epdg_ue_fsm:received_gtpc_create_session_response(Sess#gtp_session.pid, {error,
GtpCause}),
+ State1 = delete_gtp_session(Sess, State0),
+ {noreply, State1}.
+
tx_gtp(Req, State) ->
lager:info("s2b: Tx ~p~n", [Req]),
Msg = gtp_packet:encode(Req),
diff --git a/src/epdg_ue_fsm.erl b/src/epdg_ue_fsm.erl
index cf4d280..439cb3f 100644
--- a/src/epdg_ue_fsm.erl
+++ b/src/epdg_ue_fsm.erl
@@ -36,6 +36,7 @@
-include_lib("osmo_gsup/include/gsup_protocol.hrl").
-include_lib("gtplib/include/gtp_packet.hrl").
+-include_lib("gtp_utils.hrl").
-include("conv.hrl").
-export([start_link/1, stop/1]).
@@ -288,11 +289,14 @@
eua = EUA, peer_addr = RemoteIPv4},
Ret = gtp_u_tun:create_pdp_context(TunPdpCtx),
lager:debug("gtp_u_tun:create_pdp_context(~p) returned ~p~n",
[ResInfo, Ret]),
- Data1 = Data#ue_fsm_data{tun_pdp_ctx = TunPdpCtx};
- _ -> Data1 = Data
- end,
- gsup_server:tunnel_response(Data1#ue_fsm_data.imsi, Result),
- {next_state, state_active, Data1, [{reply,From,ok}]};
+ Data1 = Data#ue_fsm_data{tun_pdp_ctx = TunPdpCtx},
+ gsup_server:tunnel_response(Data1#ue_fsm_data.imsi, Result),
+ {next_state, state_active, Data1, [{reply,From,ok}]};
+ {error, GtpCause} ->
+ GsupCause = conv:cause_gtp2gsup(GtpCause),
+ gsup_server:tunnel_response(Data#ue_fsm_data.imsi, {error, GsupCause}),
+ {next_state, state_authenticated, Data, [{reply,From,ok}]}
+ 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]),
@@ -300,7 +304,7 @@
state_wait_create_session_resp(state_timeout, create_session_timeout, Data) ->
lager:error("ue_fsm state_wait_create_session_resp: Timeout ~p, ~p~n",
[create_session_timeout, Data]),
- gsup_server:tunnel_response(Data#ue_fsm_data.imsi, {error,
create_session_timeout}),
+ gsup_server:tunnel_response(Data#ue_fsm_data.imsi, {error,
?GSUP_CAUSE_CONGESTION}),
{next_state, state_authenticated, Data}.
state_active(enter, _OldState, Data) ->
diff --git a/src/gsup_server.erl b/src/gsup_server.erl
index 1e5173e..3b69849 100644
--- a/src/gsup_server.erl
+++ b/src/gsup_server.erl
@@ -171,11 +171,11 @@
{ok, APCO} -> Resp = maps:put(pco, APCO, Resp0);
error -> Resp = Resp0
end;
- {error, _} ->
+ {error, GsupCause} ->
Resp = #{message_type => epdg_tunnel_error,
imsi => Imsi,
message_class => 5,
- cause => ?GSUP_CAUSE_NET_FAIL
+ cause => GsupCause
}
end,
tx_gsup(Socket, Resp),
diff --git a/src/gtp_utils.erl b/src/gtp_utils.erl
index 6098da2..0cca8d2 100644
--- a/src/gtp_utils.erl
+++ b/src/gtp_utils.erl
@@ -35,7 +35,9 @@
-module(gtp_utils).
-author('Alexander Couzens <lynxis(a)fe80.eu>')>').
--export([plmn_to_bin/3, enum_v2_cause/1]).
+-include_lib("gtp_utils.hrl").
+
+-export([plmn_to_bin/3, enum_v2_cause/1, v2_cause_successful/1]).
% ergw/apps/ergw/test/*.erl
@@ -125,3 +127,12 @@
enum_v2_cause(request_rejected_due_to_ue_capability) -> 127;
enum_v2_cause(s1_u_path_failure) -> 128;
enum_v2_cause('5gc_not_allowed') -> 129.
+
+
+-spec v2_cause_successful(integer()) -> boolean().
+
+v2_cause_successful(GtpCauseInt) ->
+ GtpCauseInt == ?GTP2_CAUSE_REQUEST_ACCEPTED orelse
+ GtpCauseInt == ?GTP2_CAUSE_REQUEST_ACCEPTED_PARTIALLY orelse
+ GtpCauseInt == ?GTP2_CAUSE_NEW_PDN_TYPE_DUE_TO_NETWORK_PREFERENCE orelse
+ GtpCauseInt == ?GTP2_CAUSE_NEW_PDN_TYPE_DUE_TO_SINGLE_ADDRESS_BEARER_ONLY.
--
To view, visit
https://gerrit.osmocom.org/c/erlang/osmo-epdg/+/36112?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: I7bc840e863c0a1eff3b1df2c42f6b1868dec8dae
Gerrit-Change-Number: 36112
Gerrit-PatchSet: 2
Gerrit-Owner: pespin <pespin(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: lynxis lazus <lynxis(a)fe80.eu>
Gerrit-Reviewer: pespin <pespin(a)sysmocom.de>
Gerrit-MessageType: merged