fixeria has uploaded this change for review. ( https://gerrit.osmocom.org/c/erlang/osmo-s1gw/+/40547?usp=email )
Change subject: s1ap_proxy: support using NFT KPI UL/DL address from SCTP ......................................................................
s1ap_proxy: support using NFT KPI UL/DL address from SCTP
In some deployments the source address of UL GTP-U packets may be different from the bind address indicated by an eNB during E-RAB establishment. Allow the operator to configure the source, from where UL/DL addresses are to be learned:
* s1ap - learn from S1AP PDUs (default), * sctp - learn from SCTP address of the eNB.
Change-Id: Iae92a42b0ccb1a4bc34f06d969f5270a304b1d3a Related: SYS#7307 --- M config/sys.config M src/s1ap_proxy.erl M src/sctp_proxy.erl 3 files changed, 52 insertions(+), 13 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/erlang/osmo-s1gw refs/changes/47/40547/1
diff --git a/config/sys.config b/config/sys.config index 57cb61c..ef5a7d7 100644 --- a/config/sys.config +++ b/config/sys.config @@ -23,6 +23,8 @@ %% Optional NFT KPI configuration %% {enft_kpi_enable, true}, %% whether to enable the NFT KPI module (default: false) %% {enft_kpi_table_name, "osmo-s1gw"}, %% the NFT table name to be used by this process +%% {enft_kpi_ul_addr, s1ap}, %% GTP-U UL address: s1ap | sctp (default: learn from S1AP) +%% {enft_kpi_dl_addr, s1ap}, %% GTP-U DL address: s1ap | sctp (default: learn from S1AP) %% {enft_kpi_interval, 3000} %% counter reporting interval (ms) ]}, %% ================================================================================ diff --git a/src/s1ap_proxy.erl b/src/s1ap_proxy.erl index 6f63e4c..2e2f464 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/0, +-export([start_link/1, process_pdu/2, fetch_erab/2, fetch_erab_list/1, @@ -70,7 +70,8 @@ -type plmn_id() :: {MCC :: nonempty_string(), MNC :: nonempty_string()}.
--record(proxy_state, {erabs :: dict:dict(), +-record(proxy_state, {conn_info :: sctp_server:conn_info(), + erabs :: dict:dict(), enb_id :: undefined | non_neg_integer(), plmn_id :: undefined | plmn_id(), mme_ue_id :: undefined | mme_ue_id(), @@ -89,9 +90,11 @@ %% public API %% ------------------------------------------------------------------
--spec start_link() -> gen_server:start_ret(). -start_link() -> - gen_server:start_link(?MODULE, [], []). +-spec start_link(ConnInfo) -> Result + when ConnInfo :: sctp_server:conn_info(), + Result :: gen_server:start_ret(). +start_link(ConnInfo) -> + gen_server:start_link(?MODULE, [ConnInfo], []).
-type process_pdu_result() :: {proxy_action(), binary()}. @@ -121,9 +124,10 @@ %% gen_server API %% ------------------------------------------------------------------
-init([]) -> +init([ConnInfo]) -> process_flag(trap_exit, true), - {ok, #proxy_state{erabs = dict:new(), + {ok, #proxy_state{conn_info = ConnInfo, + erabs = dict:new(), path = []}}.
@@ -325,10 +329,11 @@ handle_pdu({successfulOutcome, #'SuccessfulOutcome'{procedureCode = ?'id-S1Setup'}}, S) -> ?LOG_DEBUG("Processing S1 SETUP RESPONSE"), - ok = enft_kpi:enb_register(genb_id_str(S)), + enft_kpi_enb_register(S), %% there's nothing to patch in this PDU, so we forward it as-is {forward, S};
+ %% 9.1.3.1 E-RAB SETUP REQUEST handle_pdu({Outcome = initiatingMessage, #'InitiatingMessage'{procedureCode = ?'id-E-RABSetup', @@ -652,8 +657,7 @@ 'transportLayerAddress' = TLA_In, 'gTP-TEID' = << TEID_In:32/big >>} = C0, S) -> %% indicate eNB's address to the enft_kpi module - enft_kpi:enb_set_addr({ul, tla_str(TLA_In)}), - enft_kpi:enb_set_addr({dl, tla_str(TLA_In)}), + enft_kpi_enb_set_addr({s1ap, tla_str(TLA_In)}), %% poke E-RAB FSM case erab_fsm_find(ERABId, S) of {ok, Pid} -> @@ -942,8 +946,7 @@ 'transportLayerAddress' = TLA_In, 'gTP-TEID' = << TEID_In:32/big >>} = C0, S) -> %% indicate eNB's address to the enft_kpi module - enft_kpi:enb_set_addr({ul, tla_str(TLA_In)}), - enft_kpi:enb_set_addr({dl, tla_str(TLA_In)}), + enft_kpi_enb_set_addr({s1ap, tla_str(TLA_In)}), %% poke E-RAB FSM case erab_fsm_find(ERABId, S) of {ok, Pid} -> @@ -1051,4 +1054,38 @@ UID = erab_uid(RABId, S), dict:find(UID, ERABs).
+ +-spec enft_kpi_enb_register(proxy_state()) -> ok. +enft_kpi_enb_register(#proxy_state{conn_info = ConnInfo} = S) -> + %% register eNB using its Global-eNB-ID + ok = enft_kpi:enb_register(genb_id_str(S)), + %% indicate UL/DL addresses + EnbAddr = inet:ntoa(maps:get(addr, ConnInfo)), + enft_kpi_enb_set_addr({sctp, EnbAddr}). + + +-spec enft_kpi_enb_set_addr({Source, EnbAddr}) -> ok + when Source :: s1ap | sctp, + EnbAddr :: string(). +enft_kpi_enb_set_addr({Source, EnbAddr}) -> + enft_kpi_enb_set_addr(enft_kpi_ul_addr, {Source, ul, EnbAddr}), + enft_kpi_enb_set_addr(enft_kpi_dl_addr, {Source, dl, EnbAddr}), + ok. + + +-spec enft_kpi_enb_set_addr(EnvParam, {Source, ULDL, EnbAddr}) -> ok + when EnvParam :: atom(), + Source :: s1ap | sctp, + ULDL :: ul | dl, + EnbAddr :: string(). +enft_kpi_enb_set_addr(EnvParam, {Source, ULDL, EnbAddr}) -> + case osmo_s1gw:get_env(EnvParam, s1ap) of + Source -> + ?LOG_DEBUG("NFT KPI ~p address ~p learned from ~p", + [ULDL, EnbAddr, Source]), + enft_kpi:enb_set_addr({ULDL, EnbAddr}); + Mode -> + ?LOG_DEBUG("NFT KPI ~p address mode ~p != ~p", [ULDL, Mode, Source]) + end. + %% vim:set ts=4 sw=4 et: diff --git a/src/sctp_proxy.erl b/src/sctp_proxy.erl index 14c3a03..d475b20 100644 --- a/src/sctp_proxy.erl +++ b/src/sctp_proxy.erl @@ -85,7 +85,7 @@ %% ------------------------------------------------------------------
init([ConnInfo, ConnCfg]) -> - {ok, Pid} = s1ap_proxy:start_link(), + {ok, Pid} = s1ap_proxy:start_link(ConnInfo), {ok, connecting, #{enb_aid => maps:get(aid, ConnInfo), conn_cfg => ConnCfg,