From 5d478e2488f8829b54e7a68bb0061cae1747a6d9 Mon Sep 17 00:00:00 2001 From: Pau Espin Pedrol Date: Thu, 12 May 2022 14:42:45 +0200 Subject: [PATCH] Pespin/pr (#1529) * [SMF] rename function s/gtp/gtp2/ * [SMF] Store GTPC version in session So far we always depended on an xact being present in the code path in order to know which kind of session it is (GTPv1C vs GTPv2C). Let's instead store that information in smf_sess_t so that we have it always available in an easy way. * [SMF] Move smf_sess_t GTPv1C specifics into gtp substruct * [SMF] Gy CCR: append 3GPP-NSAPI AVP --- lib/diameter/gy/message.c | 3 +++ lib/diameter/gy/message.h | 1 + src/smf/context.c | 4 +++- src/smf/context.h | 12 ++++++------ src/smf/gn-build.c | 2 +- src/smf/gn-handler.c | 2 +- src/smf/gy-path.c | 28 ++++++++++++++++++++++++++++ src/smf/smf-sm.c | 2 +- 8 files changed, 44 insertions(+), 10 deletions(-) diff --git a/lib/diameter/gy/message.c b/lib/diameter/gy/message.c index 920c365692..23ac5b4a26 100644 --- a/lib/diameter/gy/message.c +++ b/lib/diameter/gy/message.c @@ -53,6 +53,7 @@ struct dict_object *ogs_diam_gy_3gpp_pdp_type = NULL; struct dict_object *ogs_diam_gy_pdp_address = NULL; struct dict_object *ogs_diam_gy_sgsn_address = NULL; struct dict_object *ogs_diam_gy_ggsn_address = NULL; +struct dict_object *ogs_diam_gy_3gpp_nsapi = NULL; struct dict_object *ogs_diam_gy_feature_list_id = NULL; struct dict_object *ogs_diam_gy_feature_list = NULL; @@ -113,6 +114,8 @@ int ogs_diam_gy_init(void) CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "PDP-Address", &ogs_diam_gy_pdp_address); CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "SGSN-Address", &ogs_diam_gy_sgsn_address); CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "GGSN-Address", &ogs_diam_gy_ggsn_address); + CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "3GPP-NSAPI", &ogs_diam_gy_3gpp_nsapi); + CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Feature-List-ID", &ogs_diam_gy_feature_list_id); CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Feature-List", &ogs_diam_gy_feature_list); diff --git a/lib/diameter/gy/message.h b/lib/diameter/gy/message.h index e08e1a73c8..0f3210d562 100644 --- a/lib/diameter/gy/message.h +++ b/lib/diameter/gy/message.h @@ -104,6 +104,7 @@ extern struct dict_object *ogs_diam_gy_3gpp_pdp_type; extern struct dict_object *ogs_diam_gy_pdp_address; extern struct dict_object *ogs_diam_gy_sgsn_address; extern struct dict_object *ogs_diam_gy_ggsn_address; +extern struct dict_object *ogs_diam_gy_3gpp_nsapi; extern struct dict_object *ogs_diam_gy_feature_list_id; extern struct dict_object *ogs_diam_gy_feature_list; extern struct dict_object *ogs_diam_gy_qos_information; diff --git a/src/smf/context.c b/src/smf/context.c index 79efac178b..3663bb976d 100644 --- a/src/smf/context.c +++ b/src/smf/context.c @@ -1141,10 +1141,11 @@ smf_sess_t *smf_sess_add_by_gtp1_message(ogs_gtp1_message_t *message) } sess = smf_sess_add_by_apn(smf_ue, apn, req->rat_type.u8); + sess->gtp.version = 1; return sess; } -smf_sess_t *smf_sess_add_by_gtp_message(ogs_gtp2_message_t *message) +smf_sess_t *smf_sess_add_by_gtp2_message(ogs_gtp2_message_t *message) { smf_ue_t *smf_ue = NULL; smf_sess_t *sess = NULL; @@ -1204,6 +1205,7 @@ smf_sess_t *smf_sess_add_by_gtp_message(ogs_gtp2_message_t *message) } sess = smf_sess_add_by_apn(smf_ue, apn, req->rat_type.u8); + sess->gtp.version = 2; return sess; } diff --git a/src/smf/context.h b/src/smf/context.h index b05c174181..e4561f0e3a 100644 --- a/src/smf/context.h +++ b/src/smf/context.h @@ -312,16 +312,16 @@ typedef struct smf_sess_s { OpenAPI_rat_type_e sbi_rat_type; struct { + uint8_t version; /* GTPC version */ ogs_tlv_octet_t ue_pco; ogs_tlv_octet_t user_location_information; ogs_tlv_octet_t ue_timezone; bool create_session_response_apn_ambr; bool create_session_response_bearer_qos; - } gtp; /* Saved from S5-C */ - - struct { - uint8_t nsapi; - } gtp1; /* GTPv1C specific fields */ + struct { + uint8_t nsapi; + } v1; /* GTPv1C specific fields */ + } gtp; /* Saved from S5-C/Gn */ struct { uint64_t ul_octets; @@ -412,7 +412,7 @@ smf_ue_t *smf_ue_find_by_supi(char *supi); smf_ue_t *smf_ue_find_by_imsi(uint8_t *imsi, int imsi_len); smf_sess_t *smf_sess_add_by_gtp1_message(ogs_gtp1_message_t *message); -smf_sess_t *smf_sess_add_by_gtp_message(ogs_gtp2_message_t *message); +smf_sess_t *smf_sess_add_by_gtp2_message(ogs_gtp2_message_t *message); smf_sess_t *smf_sess_add_by_apn(smf_ue_t *smf_ue, char *apn, uint8_t rat_type); smf_sess_t *smf_sess_add_by_sbi_message(ogs_sbi_message_t *message); diff --git a/src/smf/gn-build.c b/src/smf/gn-build.c index 085ab38029..a064d3bca4 100644 --- a/src/smf/gn-build.c +++ b/src/smf/gn-build.c @@ -157,7 +157,7 @@ ogs_pkbuf_t *smf_gn_build_create_pdp_context_response( /* TODO: NSAPI ? */ rsp->nsapi.presence = 1; - rsp->nsapi.u8 = sess->gtp1.nsapi; + rsp->nsapi.u8 = sess->gtp.v1.nsapi; /* Charging ID */ rsp->charging_id.presence = 1; diff --git a/src/smf/gn-handler.c b/src/smf/gn-handler.c index 14597f41cc..665e00140f 100644 --- a/src/smf/gn-handler.c +++ b/src/smf/gn-handler.c @@ -118,7 +118,7 @@ uint8_t smf_gn_handle_create_pdp_context_request( ogs_assert(smf_ue); /* Store NSAPI */ - sess->gtp1.nsapi = req->nsapi.u8; + sess->gtp.v1.nsapi = req->nsapi.u8; /* Control Plane(DL) : SGW-S5C */ sess->sgw_s5c_teid = req->tunnel_endpoint_identifier_control_plane.u32; diff --git a/src/smf/gy-path.c b/src/smf/gy-path.c index c2cd79002c..577cd7b157 100644 --- a/src/smf/gy-path.c +++ b/src/smf/gy-path.c @@ -383,6 +383,34 @@ static void fill_service_information_ccr(smf_sess_t *sess, ret = fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2); ogs_assert(ret == 0); + /* 3GPP-NSAPI, 3GPP TS 29.061 16.4.7.2 10 */ + if (sess->gtp.version == 1) { + char nsapi_hex; + if (sess->gtp.v1.nsapi <= 9) + nsapi_hex = sess->gtp.v1.nsapi + '0'; + else + nsapi_hex = sess->gtp.v1.nsapi - 10 + 'A'; + ret = fd_msg_avp_new(ogs_diam_gy_3gpp_nsapi, 0, &avpch2); + ogs_assert(ret == 0); + val.os.data = (uint8_t *)&nsapi_hex; + val.os.len = 1; + ret = fd_msg_avp_setvalue(avpch2, &val); + ogs_assert(ret == 0); + ret = fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2); + ogs_assert(ret == 0); + } else { + /* GTPv2C: For PGW, EPS Bearer ID as specified in 3GPP TS 29.274 8.8 */ + smf_bearer_t *bearer = smf_default_bearer_in_sess(sess); + ret = fd_msg_avp_new(ogs_diam_gy_3gpp_nsapi, 0, &avpch2); + ogs_assert(ret == 0); + val.os.data = (uint8_t *)&bearer->ebi; + val.os.len = 1; + ret = fd_msg_avp_setvalue(avpch2, &val); + ogs_assert(ret == 0); + ret = fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2); + ogs_assert(ret == 0); + } + /* 3GPP-MS-Timezone */ if (sess->gtp.ue_timezone.presence && sess->gtp.ue_timezone.len && sess->gtp.ue_timezone.data) { diff --git a/src/smf/smf-sm.c b/src/smf/smf-sm.c index f4ab787ab0..f7ced1142d 100644 --- a/src/smf/smf-sm.c +++ b/src/smf/smf-sm.c @@ -132,7 +132,7 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e) case OGS_GTP2_CREATE_SESSION_REQUEST_TYPE: if (gtp2_message.h.teid == 0) { ogs_expect(!sess); - sess = smf_sess_add_by_gtp_message(>p2_message); + sess = smf_sess_add_by_gtp2_message(>p2_message); if (sess) OGS_SETUP_GTP_NODE(sess, gnode); }