pespin has uploaded this change for review.
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, 87 insertions(+), 48 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/erlang/osmo-epdg refs/changes/12/36112/1
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..bb6d10a 100644
--- a/src/epdg_ue_fsm.erl
+++ b/src/epdg_ue_fsm.erl
@@ -288,11 +288,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]),
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@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 change 36112. To unsubscribe, or for help writing mail filters, visit settings.