fixeria has submitted this change. ( https://gerrit.osmocom.org/c/erlang/osmo-s1gw/+/41619?usp=email )
Change subject: s1ap_proxy: signal GTP-U addr and eNB info to sctp_proxy ......................................................................
s1ap_proxy: signal GTP-U addr and eNB info to sctp_proxy
Move all interaction with the `enb_registry` and `gtpu_kpi` modules from `s1ap_proxy` to its parent process, `sctp_proxy`. This prepares for a follow-up change in which handling of the S1 SETUP procedure will be fully migrated to `sctp_proxy` - a prerequisite for proper MME pooling support.
Change-Id: I87e7d22a4bc5cb7816a167ac7dd29ea917594ce8 Related: SYS#7052 --- M src/s1ap_proxy.erl M src/sctp_proxy.erl M test/s1ap_proxy_test.erl 3 files changed, 78 insertions(+), 55 deletions(-)
Approvals: fixeria: Looks good to me, approved pespin: Looks good to me, but someone else must approve osmith: Looks good to me, but someone else must approve Jenkins Builder: Verified
diff --git a/src/s1ap_proxy.erl b/src/s1ap_proxy.erl index b5abad5..8d765d4 100644 --- a/src/s1ap_proxy.erl +++ b/src/s1ap_proxy.erl @@ -40,7 +40,7 @@ handle_call/3, handle_cast/2, terminate/2]). --export([start_link/2, +-export([start_link/1, process_pdu/2, fetch_erab/2, fetch_erab_list/1, @@ -69,8 +69,7 @@ -type plmn_id() :: {MCC :: nonempty_string(), MNC :: nonempty_string()}.
--record(proxy_state, {conn_info :: sctp_server:conn_info(), - enb_handle :: enb_registry:enb_handle(), +-record(proxy_state, {owner :: pid(), erabs :: dict:dict(K :: erab_uid(), V :: pid()), enb_id :: undefined | non_neg_integer(), @@ -100,12 +99,9 @@ %% public API %% ------------------------------------------------------------------
--spec start_link(EnbHandle, ConnInfo) -> Result - when EnbHandle :: enb_registry:enb_handle(), - ConnInfo :: sctp_server:conn_info(), - Result :: gen_server:start_ret(). -start_link(EnbHandle, ConnInfo) -> - gen_server:start_link(?MODULE, [EnbHandle, ConnInfo], []). +-spec start_link(pid()) -> gen_server:start_ret(). +start_link(Owner) -> + gen_server:start_link(?MODULE, [Owner], []).
-type process_pdu_result() :: {proxy_action(), binary()}. @@ -141,11 +137,10 @@ %% gen_server API %% ------------------------------------------------------------------
-init([EnbHandle, ConnInfo]) -> +init([Owner]) -> process_flag(trap_exit, true), - {ok, #proxy_state{enb_handle = EnbHandle, - conn_info = ConnInfo, - erabs = dict:new(), + {ok, #proxy_state{erabs = dict:new(), + owner = Owner, path = []}}.
@@ -379,9 +374,7 @@ handle_pdu({successfulOutcome, #'SuccessfulOutcome'{procedureCode = ?'id-S1Setup'}}, S) -> ?LOG_DEBUG("Processing S1 SETUP RESPONSE"), - enb_registry:enb_event(S#proxy_state.enb_handle, - {s1setup, enb_info(S)}), - gtpu_kpi_enb_register(S), + signal_enb_info(S), %% there's nothing to patch in this PDU, so we forward it as-is {forward, S};
@@ -756,8 +749,8 @@ #'E-RABSetupItemBearerSURes'{'e-RAB-ID' = ERABId, 'transportLayerAddress' = TLA_In, 'gTP-TEID' = << TEID_In:32/big >>} = C0, S) -> - %% indicate eNB's address to the gtpu_kpi module - gtpu_kpi_enb_set_addr({s1ap, tla_str(TLA_In)}), + %% signal eNB's GTP-U address to the parent process + signal_enb_addr(TLA_In, S), %% poke E-RAB FSM case erab_fsm_find(ERABId, S) of {ok, Pid} -> @@ -1045,8 +1038,8 @@ #'E-RABSetupItemCtxtSURes'{'e-RAB-ID' = ERABId, 'transportLayerAddress' = TLA_In, 'gTP-TEID' = << TEID_In:32/big >>} = C0, S) -> - %% indicate eNB's address to the gtpu_kpi module - gtpu_kpi_enb_set_addr({s1ap, tla_str(TLA_In)}), + %% signal eNB's GTP-U address to the parent process + signal_enb_addr(TLA_In, S), %% poke E-RAB FSM case erab_fsm_find(ERABId, S) of {ok, Pid} -> @@ -1112,8 +1105,8 @@ #'E-RABAdmittedItem'{'e-RAB-ID' = ERABId, 'transportLayerAddress' = TLA_In, 'gTP-TEID' = << TEID_In:32/big >>} = C0, S) -> - %% indicate eNB's address to the gtpu_kpi module - gtpu_kpi_enb_set_addr({s1ap, tla_str(TLA_In)}), + %% signal eNB's GTP-U address to the parent process + signal_enb_addr(TLA_In, S), %% poke E-RAB FSM case erab_fsm_find(ERABId, S) of {ok, Pid} -> @@ -1245,37 +1238,19 @@ dict:find(UID, ERABs).
--spec gtpu_kpi_enb_register(proxy_state()) -> ok. -gtpu_kpi_enb_register(#proxy_state{conn_info = ConnInfo} = S) -> - %% register eNB using its Global-eNB-ID - ok = gtpu_kpi:enb_register(genb_id_str(S)), - %% indicate UL/DL addresses - EnbAddr = inet:ntoa(maps:get(addr, ConnInfo)), - gtpu_kpi_enb_set_addr({sctp, EnbAddr}). - - --spec gtpu_kpi_enb_set_addr({Source, EnbAddr}) -> ok - when Source :: s1ap | sctp, - EnbAddr :: string(). -gtpu_kpi_enb_set_addr({Source, EnbAddr}) -> - gtpu_kpi_enb_set_addr(gtpu_kpi_ul_addr, {Source, ul, EnbAddr}), - gtpu_kpi_enb_set_addr(gtpu_kpi_dl_addr, {Source, dl, EnbAddr}), +%% Signal the eNB's GTP-U address to the parent process +-spec signal_enb_addr(binary(), proxy_state()) -> ok. +signal_enb_addr(TLA, #proxy_state{owner = Pid}) -> + %% TODO: optimize to send this only once + Pid ! {?MODULE, {enb_addr, tla_str(TLA)}}, ok.
--spec gtpu_kpi_enb_set_addr(EnvParam, {Source, ULDL, EnbAddr}) -> ok - when EnvParam :: atom(), - Source :: s1ap | sctp, - ULDL :: ul | dl, - EnbAddr :: string(). -gtpu_kpi_enb_set_addr(EnvParam, {Source, ULDL, EnbAddr}) -> - case osmo_s1gw:get_env(EnvParam, s1ap) of - Source -> - ?LOG_DEBUG("GTP-U KPI ~p address ~p learned from ~p", - [ULDL, EnbAddr, Source]), - gtpu_kpi:enb_set_addr({ULDL, EnbAddr}); - Mode -> - ?LOG_DEBUG("GTP-U KPI ~p address mode ~p != ~p", [ULDL, Mode, Source]) - end. +%% Signal eNB info to the parent process +-spec signal_enb_info(proxy_state()) -> ok. +signal_enb_info(#proxy_state{owner = Pid} = S) -> + Pid ! {?MODULE, {enb_info, enb_info(S)}}, + ok. +
%% vim:set ts=4 sw=4 et: diff --git a/src/sctp_proxy.erl b/src/sctp_proxy.erl index 0fbcbf5..60f0c11 100644 --- a/src/sctp_proxy.erl +++ b/src/sctp_proxy.erl @@ -69,6 +69,7 @@ tx_queue :: [binary()], sock :: undefined | gen_sctp:sctp_socket(), enb_handle :: enb_registry:enb_handle(), + genb_id_str :: undefined | string(), handler :: pid() %% s1ap_proxy process' pid }).
@@ -110,7 +111,7 @@
init([EnbConnInfo, MmeConnCfg]) -> {ok, EnbHandle} = enb_registry:enb_register(), - {ok, Pid} = s1ap_proxy:start_link(EnbHandle, EnbConnInfo), + {ok, Pid} = s1ap_proxy:start_link(self()), {ok, connecting, #state{enb_aid = maps:get(aid, EnbConnInfo), enb_conn_info = EnbConnInfo, @@ -209,6 +210,19 @@ sctp_send_from_mme(Data, S), {keep_state, S};
+%% eNB info indication from s1ap_proxy +connected(info, {s1ap_proxy, {enb_info, EnbInfo}}, + #state{enb_handle = EnbHandle} = S0) -> + enb_registry:enb_event(EnbHandle, {s1setup, EnbInfo}), + S1 = S0#state{genb_id_str = maps:get(genb_id_str, EnbInfo)}, + gtpu_kpi_enb_register(S1), + {keep_state, S1}; + +%% eNB's GTP-U address indication from s1ap_proxy +connected(info, {s1ap_proxy, {enb_addr, Addr}}, S) -> + gtpu_kpi_enb_set_addr({s1ap, Addr}), + {keep_state, S}; + connected(Event, EventData, S) -> handle_event(?FUNCTION_NAME, Event, EventData, S).
@@ -320,4 +334,40 @@ mme_aid => S#state.mme_aid}, maps:filter(fun(_K, V) -> V =/= undefined end, Info).
+ +-spec gtpu_kpi_enb_register(state()) -> ok. +gtpu_kpi_enb_register(#state{genb_id_str = GlobalENBId, + enb_conn_info = EnbConnInfo}) -> + %% register eNB using its Global-eNB-ID + ok = gtpu_kpi:enb_register(GlobalENBId), + %% indicate UL/DL addresses + EnbAddr = inet:ntoa(maps:get(addr, EnbConnInfo)), + gtpu_kpi_enb_set_addr({sctp, EnbAddr}). + + +-spec gtpu_kpi_enb_set_addr({Source, EnbAddr}) -> ok + when Source :: s1ap | sctp, + EnbAddr :: string(). +gtpu_kpi_enb_set_addr({Source, EnbAddr}) -> + gtpu_kpi_enb_set_addr(gtpu_kpi_ul_addr, {Source, ul, EnbAddr}), + gtpu_kpi_enb_set_addr(gtpu_kpi_dl_addr, {Source, dl, EnbAddr}), + ok. + + +-spec gtpu_kpi_enb_set_addr(EnvParam, {Source, ULDL, EnbAddr}) -> ok + when EnvParam :: atom(), + Source :: s1ap | sctp, + ULDL :: ul | dl, + EnbAddr :: string(). +gtpu_kpi_enb_set_addr(EnvParam, {Source, ULDL, EnbAddr}) -> + case osmo_s1gw:get_env(EnvParam, s1ap) of + Source -> + ?LOG_DEBUG("GTP-U KPI ~p address ~p learned from ~p", + [ULDL, EnbAddr, Source]), + gtpu_kpi:enb_set_addr({ULDL, EnbAddr}); + Mode -> + ?LOG_DEBUG("GTP-U KPI ~p address mode ~p != ~p", [ULDL, Mode, Source]) + end. + + %% vim:set ts=4 sw=4 et: diff --git a/test/s1ap_proxy_test.erl b/test/s1ap_proxy_test.erl index 8e05b99..e376304 100644 --- a/test/s1ap_proxy_test.erl +++ b/test/s1ap_proxy_test.erl @@ -31,9 +31,7 @@ enb_registry:start_link(), gtpu_kpi:start_link(#{enable => false}), {ok, EnbHandle} = enb_registry:enb_register(), - {ok, Pid} = s1ap_proxy:start_link(EnbHandle, - #{addr => {127,0,0,0}, - port => 1337}), + {ok, Pid} = s1ap_proxy:start_link(self()), ok = enb_registry:enb_unregister(EnbHandle), #{handler => Pid}.