laforge has submitted this change. ( https://gerrit.osmocom.org/c/erlang/osmo-s1gw/+/37104?usp=email )
Change subject: s1ap_proxy: implement patching of INITIAL CONTEXT SETUP REQ/RSP ......................................................................
s1ap_proxy: implement patching of INITIAL CONTEXT SETUP REQ/RSP
Change-Id: Ia0d8f8d81756bcce5f518caee8887cf5822aaa08 --- M src/s1ap_proxy.erl M test/s1ap_proxy_test.erl 2 files changed, 132 insertions(+), 0 deletions(-)
Approvals: Jenkins Builder: Verified laforge: Looks good to me, approved osmith: Looks good to me, but someone else must approve
diff --git a/src/s1ap_proxy.erl b/src/s1ap_proxy.erl index 0c6cba0..82e4039 100644 --- a/src/s1ap_proxy.erl +++ b/src/s1ap_proxy.erl @@ -124,6 +124,26 @@ NewContent = Content#'E-RABModificationIndication'{protocolIEs = IEs2}, handle_pdu_new(Data, {Outcome, Pdu#'InitiatingMessage'{value = NewContent}});
+%% 9.1.4.1 INITIAL CONTEXT SETUP REQUEST +handle_pdu(Data, {Outcome = initiatingMessage, + #'InitiatingMessage'{procedureCode = ?'id-InitialContextSetup', + value = Content} = Pdu}) -> + logger:debug("Patching INITIAL CONTEXT SETUP REQUEST"), + IEs = handle_ies(Content#'InitialContextSetupRequest'.protocolIEs, + ?'id-E-RABToBeSetupListCtxtSUReq'), + NewContent = Content#'InitialContextSetupRequest'{protocolIEs = IEs}, + handle_pdu_new(Data, {Outcome, Pdu#'InitiatingMessage'{value = NewContent}}); + +%% 9.1.4.3 INITIAL CONTEXT SETUP RESPONSE +handle_pdu(Data, {Outcome = successfulOutcome, + #'SuccessfulOutcome'{procedureCode = ?'id-InitialContextSetup', + value = Content} = Pdu}) -> + logger:debug("Patching INITIAL CONTEXT SETUP RESPONSE"), + IEs = handle_ies(Content#'InitialContextSetupResponse'.protocolIEs, + ?'id-E-RABSetupListCtxtSURes'), + NewContent = Content#'InitialContextSetupResponse'{protocolIEs = IEs}, + handle_pdu_new(Data, {Outcome, Pdu#'SuccessfulOutcome'{value = NewContent}}); + %% Proxy all other messages unmodified handle_pdu(Data, _Pdu) -> Data. @@ -179,6 +199,30 @@ TLA = transp_layer_addr(mme_loc_addr), Content#'E-RABNotToBeModifiedItemBearerModInd'{transportLayerAddress = TLA};
+%% INITIAL CONTEXT SETUP REQUEST related IEs +handle_ie(#'ProtocolIE-Field'{id = ?'id-E-RABToBeSetupListCtxtSUReq', + value = Content}) -> + %% This IE contains a list of CtxtSUReq, so patch inner IEs + handle_ies(Content, ?'id-E-RABToBeSetupItemCtxtSUReq'); + +handle_ie(#'ProtocolIE-Field'{id = ?'id-E-RABToBeSetupItemCtxtSUReq', + value = Content}) -> + %% eNB -> MME direction: we pass our MME facing local address + TLA = transp_layer_addr(mme_loc_addr), + Content#'E-RABToBeSetupItemCtxtSUReq'{transportLayerAddress = TLA}; + +%% INITIAL CONTEXT SETUP RESPONSE related IEs +handle_ie(#'ProtocolIE-Field'{id = ?'id-E-RABSetupListCtxtSURes', + value = Content}) -> + %% This IE contains a list of CtxtSURes, so patch inner IEs + handle_ies(Content, ?'id-E-RABSetupItemCtxtSURes'); + +handle_ie(#'ProtocolIE-Field'{id = ?'id-E-RABSetupItemCtxtSURes', + value = Content}) -> + %% MME -> eNB direction: we pass our eNB facing local address + TLA = transp_layer_addr(s1gw_bind_addr), + Content#'E-RABSetupItemCtxtSURes'{transportLayerAddress = TLA}; + %% Catch-all variant, which should not be called normally handle_ie(#'ProtocolIE-Field'{value = Content} = IE) -> logger:error("[BUG] Unhandled S1AP IE: ~p", [IE]), diff --git a/test/s1ap_proxy_test.erl b/test/s1ap_proxy_test.erl index 4123085..e694197 100644 --- a/test/s1ap_proxy_test.erl +++ b/test/s1ap_proxy_test.erl @@ -110,4 +110,83 @@ application:set_env(osmo_s1gw, mme_loc_addr, ?EXP_ADDR_STR), ?assertEqual(ExpData, s1ap_proxy:handle_pdu(OrigData)).
+ +%% [eNB -> MME] INITIAL CONTEXT SETUP REQUEST +initial_context_setup_req_pdu(TLA, TEID) when is_binary(TLA), + is_binary(TEID) -> + << 16#00, 16#09, 16#00, 16#81, 16#10, 16#00, 16#00, 16#07, + 16#00, 16#00, 16#00, 16#02, 16#00, 16#01, 16#00, 16#08, + 16#00, 16#02, 16#00, 16#01, 16#00, 16#42, 16#00, 16#0a, + 16#18, 16#3b, 16#9a, 16#ca, 16#00, 16#60, 16#3b, 16#9a, + 16#ca, 16#00, 16#00, 16#18, 16#00, 16#80, 16#b5, 16#00, + 16#00, 16#34, 16#00, 16#80, 16#af, 16#45, 16#00, 16#09, + 16#20, 16#0f, 16#80, + TLA/bytes, %% transportLayerAddress (IPv4) + TEID/bytes, %% GTP-TEID + 16#80, 16#9f, 16#27, 16#bd, 16#de, + 16#61, 16#4e, 16#02, 16#07, 16#42, 16#02, 16#29, 16#06, + 16#40, 16#32, 16#f8, 16#10, 16#00, 16#01, 16#00, 16#6e, + 16#52, 16#05, 16#c1, 16#01, 16#09, 16#09, 16#08, 16#69, + 16#6e, 16#74, 16#65, 16#72, 16#6e, 16#65, 16#74, 16#05, + 16#01, 16#c0, 16#a8, 16#64, 16#02, 16#5e, 16#06, 16#fe, + 16#fe, 16#fa, 16#fa, 16#02, 16#02, 16#58, 16#32, 16#27, + 16#4d, 16#80, 16#80, 16#21, 16#10, 16#02, 16#00, 16#00, + 16#10, 16#81, 16#06, 16#08, 16#08, 16#08, 16#08, 16#83, + 16#06, 16#08, 16#08, 16#04, 16#04, 16#00, 16#0d, 16#04, + 16#08, 16#08, 16#08, 16#08, 16#00, 16#0d, 16#04, 16#08, + 16#08, 16#04, 16#04, 16#00, 16#03, 16#10, 16#20, 16#01, + 16#48, 16#60, 16#48, 16#60, 16#00, 16#00, 16#00, 16#00, + 16#00, 16#00, 16#00, 16#00, 16#88, 16#88, 16#00, 16#03, + 16#10, 16#20, 16#01, 16#48, 16#60, 16#48, 16#60, 16#00, + 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#88, + 16#44, 16#00, 16#10, 16#02, 16#05, 16#aa, 16#50, 16#0b, + 16#f6, 16#32, 16#f8, 16#10, 16#00, 16#02, 16#01, 16#c0, + 16#00, 16#02, 16#86, 16#13, 16#32, 16#f8, 16#10, 16#00, + 16#01, 16#23, 16#05, 16#f4, 16#04, 16#94, 16#25, 16#f8, + 16#64, 16#02, 16#01, 16#08, 16#00, 16#6b, 16#00, 16#05, + 16#1c, 16#00, 16#0e, 16#00, 16#00, 16#00, 16#49, 16#00, + 16#20, 16#57, 16#5d, 16#d3, 16#66, 16#69, 16#73, 16#4c, + 16#8c, 16#48, 16#42, 16#76, 16#5f, 16#fe, 16#f9, 16#bd, + 16#d5, 16#89, 16#08, 16#ae, 16#f6, 16#f4, 16#88, 16#62, + 16#22, 16#d7, 16#80, 16#fb, 16#36, 16#33, 16#d9, 16#9e, + 16#9f, 16#00, 16#c0, 16#40, 16#08, 16#35, 16#87, 16#61, + 16#10, 16#03, 16#ff, 16#ff, 16#74 + >>. + +initial_context_setup_req_test() -> + %% Original input data + TEID = << 16#00, 16#00, 16#71, 16#23 >>, + OrigTLA = << 16#c0, 16#a8, 16#02, 16#d2 >>, + OrigData = initial_context_setup_req_pdu(OrigTLA, TEID), + + %% Expected output data + ExpData = initial_context_setup_req_pdu(?EXP_ADDR_BIN, TEID), + + application:set_env(osmo_s1gw, mme_loc_addr, ?EXP_ADDR_STR), + ?assertEqual(ExpData, s1ap_proxy:handle_pdu(OrigData)). + + +%% [MME -> eNB] INITIAL CONTEXT SETUP RESPONSE +initial_context_setup_rsp_pdu(TLA, TEID) when is_binary(TLA), + is_binary(TEID) -> + << 16#20, 16#09, 16#00, 16#22, 16#00, 16#00, 16#03, 16#00, + 16#00, 16#40, 16#02, 16#00, 16#01, 16#00, 16#08, 16#40, + 16#02, 16#00, 16#01, 16#00, 16#33, 16#40, 16#0f, 16#00, + 16#00, 16#32, 16#40, 16#0a, 16#0a, 16#1f, + TLA/bytes, %% transportLayerAddress (IPv4) + TEID/bytes %% GTP-TEID + >>. + +initial_context_setup_rsp_test() -> + %% Original input data + TEID = << 16#00, 16#00, 16#00, 16#01 >>, + OrigTLA = << 16#c0, 16#a8, 16#02, 16#cb >>, + OrigData = initial_context_setup_rsp_pdu(OrigTLA, TEID), + + %% Expected output data + ExpData = initial_context_setup_rsp_pdu(?EXP_ADDR_BIN, TEID), + + application:set_env(osmo_s1gw, s1gw_bind_addr, ?EXP_ADDR_STR), + ?assertEqual(ExpData, s1ap_proxy:handle_pdu(OrigData)). + %% vim:set ts=4 sw=4 et: