[SMF] UpdatePDPContext: forward update of remote TEID+IPaddr to UPF (#1383)
* [SMF] typo fixes in commented code * [SMF] Fix early err return handling UpdatePDPContextRequest * [SMF] UpdatePDPContext: forward update of remote TEID+IPaddr to UPF Updating the remote GTP-U IP address and/or TEID on the GGSN is a common practice, used for instance by an SGSN in a UTRAN network to connect an HNB(GW) to exchange GTP-U directly with the GGSN. It is also used in general when doing handovers. When receiving a UpdatePDPContext with the new address, we need to forward the update to the UPF so that it takes it into account when forwarding packets. This patch only implements updating the information towards the UPF when GTPv1C is used. Similar approach for GTPv2C (upon receival of Modify Bearer Request) is still unimplemented. Related: https://github.com/open5gs/open5gs/issues/1367
This commit is contained in:
parent
af3db1770f
commit
5ad1b188e4
|
@ -299,7 +299,7 @@ void smf_gn_handle_update_pdp_context_request(
|
|||
uint8_t cause_value = OGS_GTP1_CAUSE_REQUEST_ACCEPTED;
|
||||
|
||||
ogs_gtp1_header_t h;
|
||||
ogs_pkbuf_t *pkbuf = NULL;
|
||||
ogs_pfcp_pdr_t *pdr = NULL;
|
||||
smf_bearer_t *bearer = NULL;
|
||||
smf_ue_t *smf_ue = NULL;
|
||||
|
||||
|
@ -356,6 +356,7 @@ void smf_gn_handle_update_pdp_context_request(
|
|||
ogs_gtp1_send_error_message(xact, sess->sgw_s5c_teid,
|
||||
OGS_GTP1_UPDATE_PDP_CONTEXT_RESPONSE_TYPE,
|
||||
OGS_GTP1_CAUSE_NON_EXISTENT);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -386,12 +387,43 @@ void smf_gn_handle_update_pdp_context_request(
|
|||
h.type = OGS_GTP1_UPDATE_PDP_CONTEXT_RESPONSE_TYPE;
|
||||
h.teid = sess->sgw_s5c_teid;
|
||||
|
||||
pkbuf = smf_gn_build_update_pdp_context_response(h.type, sess, bearer);
|
||||
ogs_expect_or_return(pkbuf);
|
||||
/* Set bearer so it's accessible later when handling PFCP Session Modification Response */
|
||||
xact->data = bearer;
|
||||
|
||||
rv = ogs_gtp1_xact_update_tx(xact, &h, pkbuf);
|
||||
ogs_expect_or_return(rv == OGS_OK);
|
||||
/* Update remote TEID and GTP-U IP address on the UPF. UpdatePDPContextResp
|
||||
* will be sent when UPF answers back this request
|
||||
*/
|
||||
ogs_list_for_each(&sess->pfcp.pdr_list, pdr) {
|
||||
ogs_pfcp_far_t *far = pdr->far;
|
||||
ogs_assert(far);
|
||||
|
||||
rv = ogs_gtp_xact_commit(xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
if (pdr->src_if != OGS_PFCP_INTERFACE_CORE ||
|
||||
far->dst_if != OGS_PFCP_INTERFACE_ACCESS)
|
||||
continue;
|
||||
if (!(far->apply_action & OGS_PFCP_APPLY_ACTION_FORW))
|
||||
continue;
|
||||
|
||||
if (pdr->id == bearer->dl_pdr->id) {
|
||||
rv = ogs_pfcp_ip_to_outer_header_creation(&bearer->sgw_s5u_ip,
|
||||
&far->outer_header_creation,
|
||||
&far->outer_header_creation_len);
|
||||
ogs_assert(rv == OGS_OK);
|
||||
far->outer_header_creation.teid = bearer->sgw_s5u_teid;
|
||||
}
|
||||
}
|
||||
|
||||
rv = smf_epc_pfcp_send_session_modification_request(sess, xact,
|
||||
OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_ACTIVATE,
|
||||
OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED,
|
||||
OGS_GTP1_CAUSE_REACTIACTION_REQUESTED);
|
||||
ogs_assert(rv == OGS_OK);
|
||||
|
||||
/* TODO: TS 29.061: Upon reception of an UpdatePDPContextRequest from the
|
||||
SGSN, the GGSN may send an Accounting Request (Interim) to the Diameter
|
||||
server to update the necessary information related to this PDP context. */
|
||||
/* The P-GW need not wait for the Diameter Accounting Answer message from
|
||||
the Diameter server before sending the response for the triggering
|
||||
signalling message (e.g. Modify Bearer Response). The P-GW may delete the
|
||||
bearer if the Accounting Answer is not received from the Diameter
|
||||
server.*/
|
||||
}
|
||||
|
|
|
@ -361,7 +361,7 @@ int smf_gtp1_send_delete_pdp_context_response(
|
|||
}
|
||||
|
||||
#if 0
|
||||
int smf_gtp_send_update_pdp_context_request(
|
||||
int smf_gtp1_send_update_pdp_context_request(
|
||||
smf_bearer_t *bearer, uint8_t pti, uint8_t cause_value)
|
||||
{
|
||||
int rv;
|
||||
|
@ -376,7 +376,7 @@ int smf_gtp_send_update_pdp_context_request(
|
|||
sess = bearer->sess;
|
||||
ogs_assert(sess);
|
||||
|
||||
memset(&h, 0, sizeof(ogs_gtp_header_t));
|
||||
memset(&h, 0, sizeof(ogs_gtp1_header_t));
|
||||
h.type = OGS_GTP1_UPDATE_PDP_CONTEXT_REQUEST_TYPE;
|
||||
h.teid = sess->sgw_s5c_teid;
|
||||
|
||||
|
@ -395,6 +395,38 @@ int smf_gtp_send_update_pdp_context_request(
|
|||
}
|
||||
#endif
|
||||
|
||||
int smf_gtp1_send_update_pdp_context_response(
|
||||
smf_bearer_t *bearer, ogs_gtp_xact_t *xact)
|
||||
{
|
||||
int rv;
|
||||
|
||||
ogs_gtp1_header_t h;
|
||||
ogs_pkbuf_t *pkbuf = NULL;
|
||||
|
||||
smf_sess_t *sess = NULL;
|
||||
|
||||
ogs_assert(bearer);
|
||||
ogs_assert(xact);
|
||||
sess = bearer->sess;
|
||||
ogs_assert(sess);
|
||||
|
||||
memset(&h, 0, sizeof(ogs_gtp1_header_t));
|
||||
h.type = OGS_GTP1_UPDATE_PDP_CONTEXT_RESPONSE_TYPE;
|
||||
h.teid = sess->sgw_s5c_teid;
|
||||
|
||||
pkbuf = smf_gn_build_update_pdp_context_response(
|
||||
h.type, sess, bearer);
|
||||
ogs_expect_or_return_val(pkbuf, OGS_ERROR);
|
||||
|
||||
rv = ogs_gtp1_xact_update_tx(xact, &h, pkbuf);
|
||||
ogs_expect_or_return_val(rv == OGS_OK, OGS_ERROR);
|
||||
|
||||
rv = ogs_gtp_xact_commit(xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
int smf_gtp_send_create_session_response(
|
||||
smf_sess_t *sess, ogs_gtp_xact_t *xact)
|
||||
{
|
||||
|
|
|
@ -33,8 +33,10 @@ int smf_gtp1_send_create_pdp_context_response(
|
|||
smf_sess_t *sess, ogs_gtp_xact_t *xact);
|
||||
int smf_gtp1_send_delete_pdp_context_response(
|
||||
smf_sess_t *sess, ogs_gtp_xact_t *xact);
|
||||
int smf_gtp_send_update_pdp_context_request(
|
||||
int smf_gtp1_send_update_pdp_context_request(
|
||||
smf_bearer_t *bearer, uint8_t pti, uint8_t cause_value);
|
||||
int smf_gtp1_send_update_pdp_context_response(
|
||||
smf_bearer_t *bearer, ogs_gtp_xact_t *xact);
|
||||
|
||||
int smf_gtp_send_create_session_response(
|
||||
smf_sess_t *sess, ogs_gtp_xact_t *xact);
|
||||
|
|
|
@ -1105,7 +1105,13 @@ void smf_epc_n4_handle_session_modification_response(
|
|||
}
|
||||
|
||||
} else if (flags & OGS_PFCP_MODIFY_ACTIVATE) {
|
||||
/* Nothing */
|
||||
/* SMF send Update PDP Context Response (GTPv1C) to SGSN */
|
||||
if (gtp_xact->gtp_version == 1) {
|
||||
bearer = gtp_xact->data;
|
||||
smf_gtp1_send_update_pdp_context_response(bearer, gtp_xact);
|
||||
} else {
|
||||
/* TODO: SMF send Modify Bearer Response (GTPv2C) to SGWC */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -423,6 +423,10 @@ void smf_s5c_handle_modify_bearer_request(
|
|||
ogs_debug(" SGW_S5C_TEID[0x%x] SMF_N4_TEID[0x%x]",
|
||||
sess->sgw_s5c_teid, sess->smf_n4_teid);
|
||||
|
||||
/* TODO: Update remote GTP-U IP addr + TEID in the UPF through PFCP, similar
|
||||
* to what is done in smf_gn_handle_update_pdp_context_request()
|
||||
*/
|
||||
|
||||
memset(&h, 0, sizeof(ogs_gtp_header_t));
|
||||
h.type = OGS_GTP_MODIFY_BEARER_RESPONSE_TYPE;
|
||||
h.teid = sess->sgw_s5c_teid;
|
||||
|
|
Loading…
Reference in New Issue