[SMF] Gy: Keep sending extra AVPs in INITIAL_REQUEST (#2721)

This commit splits filling Requested-Service-Unit, Used-Service-Unit and
QoS-Information into their own helper functions for better readibility,
and then partially reverts 125740727e,
where lots of AVPs were left out of INITIAL_REQUEST messagesi during the
changes made.
After looking through 3GPP TS 32.299 and rfc4006, it seems expected to
send Requested-Service-Unit only during INITIAL_REQUEST, and
Used-Service-Unit during UPDATE_REQUEST, so that part is kept.

However, I am not able to find clear indications that AVPs such as QoS
Information and RAT-Type should not be sent during INITIAL_REQUEST.
So, since we have the info, better set it already during
INITIAL_REQUEST, since the OCS may want to grant different resources
based on that information if available too.
This commit is contained in:
Pau Espin 2023-10-31 19:19:10 +01:00 committed by GitHub
parent 9e88579c4f
commit 9d7dc91f21
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 94 additions and 67 deletions

View File

@ -89,48 +89,44 @@ static void state_cleanup(struct sess_state *sess_data, os0_t sid, void *opaque)
ogs_thread_mutex_unlock(&sess_state_mutex);
}
/* TS 32.299 7.1.9 Multiple-Services-Credit-Control AVP for CCR */
static void fill_multiple_services_credit_control_ccr(smf_sess_t *sess,
uint32_t cc_request_type, struct msg *req)
/* Requested-Service-Unit, RFC4006 8.18 */
static void fill_requested_service_unit(smf_sess_t *sess, struct avp *parent_avp)
{
int ret;
union avp_value val;
struct avp *avp;
struct avp *avpch1, *avpch2, *avpch3;
struct avp *avpch1, *avpch2;
/* Multiple-Services-Credit-Control */
ret = fd_msg_avp_new(ogs_diam_gy_multiple_services_cc, 0, &avp);
ret = fd_msg_avp_new(ogs_diam_gy_requested_service_unit, 0, &avpch1);
ogs_assert(ret == 0);
/* Requested-Service-Unit, RFC4006 8.18 */
if (cc_request_type == OGS_DIAM_GY_CC_REQUEST_TYPE_INITIAL_REQUEST ||
cc_request_type == OGS_DIAM_GY_CC_REQUEST_TYPE_UPDATE_REQUEST) {
ret = fd_msg_avp_new(ogs_diam_gy_requested_service_unit, 0, &avpch1);
ogs_assert(ret == 0);
/* CC-Time, RFC4006 8.21 */
/* CC-Money, RFC4006 8.22. Not used in 3GPP. */
/* CC-Time, RFC4006 8.21 */
/* CC-Money, RFC4006 8.22. Not used in 3GPP. */
/* CC-Total-Octets, RFC4006 8.23 */
ret = fd_msg_avp_new(ogs_diam_gy_cc_total_octets, 0, &avpch2);
ogs_assert(ret == 0);
val.u64 = 1000000;
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);
/* CC-Total-Octets, RFC4006 8.23 */
ret = fd_msg_avp_new(ogs_diam_gy_cc_total_octets, 0, &avpch2);
ogs_assert(ret == 0);
val.u64 = 1000000;
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);
/* CC-Input-Octets, RFC4006 8.24 */
/* CC-Output-Octets, RFC4006 8.25 */
/* CC-Service-Specific-Units, RFC4006 8.26 */
/* CC-Input-Octets, RFC4006 8.24 */
/* CC-Output-Octets, RFC4006 8.25 */
/* CC-Service-Specific-Units, RFC4006 8.26 */
ret = fd_msg_avp_add(parent_avp, MSG_BRW_LAST_CHILD, avpch1);
ogs_assert(ret == 0);
}
ret = fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1);
ogs_assert(ret == 0);
}
/* Used-Service-Unit, RFC4006 8.18 */
static void fill_used_service_unit(smf_sess_t *sess,
uint32_t cc_request_type, struct avp *parent_avp)
{
int ret;
union avp_value val;
struct avp *avpch1, *avpch2;
if (cc_request_type != OGS_DIAM_GY_CC_REQUEST_TYPE_INITIAL_REQUEST) {
/* Used-Service-Unit, RFC4006 8.18 */
ret = fd_msg_avp_new(ogs_diam_gy_used_service_unit, 0, &avpch1);
ogs_assert(ret == 0);
@ -191,43 +187,17 @@ static void fill_multiple_services_credit_control_ccr(smf_sess_t *sess,
/* CC-Service-Specific-Units, RFC4006 8.26 */
ret = fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1);
ret = fd_msg_avp_add (parent_avp, MSG_BRW_LAST_CHILD, avpch1);
ogs_assert(ret == 0);
//bypass USU if we are in CCR INITIAL
}
/* Service-Identifier, RFC4006 8.28. Not used in Gy. */
/* Rating-Group */
/* QoS-Information */
static void fill_qos_information(smf_sess_t *sess, struct avp *parent_avp)
{
int ret;
union avp_value val;
struct avp *avpch1, *avpch2, *avpch3;
/* Reporting-Reason, TS 32.299 7.2.175 */
/* "values QHT, FINAL, VALIDITY_TIME, FORCED_REAUTHORISATION,
* RATING_CONDITION_CHANGE, UNUSED_QUOTA_TIMER apply for all quota types
* and are used directly in the Multiple-Services-Credit-Control AVP"
*/
if (cc_request_type == OGS_DIAM_GY_CC_REQUEST_TYPE_UPDATE_REQUEST ||
cc_request_type == OGS_DIAM_GY_CC_REQUEST_TYPE_TERMINATION_REQUEST) {
switch (sess->gy.reporting_reason) {
case OGS_DIAM_GY_REPORTING_REASON_QHT:
case OGS_DIAM_GY_REPORTING_REASON_FINAL:
case OGS_DIAM_GY_REPORTING_REASON_FORCED_REAUTHORISATION:
case OGS_DIAM_GY_REPORTING_REASON_VALIDITY_TIME:
case OGS_DIAM_GY_REPORTING_REASON_RATING_CONDITION_CHANGE:
case OGS_DIAM_GY_REPORTING_REASON_UNUSED_QUOTA_TIMER:
ret = fd_msg_avp_new(ogs_diam_gy_reporting_reason, 0, &avpch1);
ogs_assert(ret == 0);
val.u32 = sess->gy.reporting_reason;
ret = fd_msg_avp_setvalue (avpch1, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1);
ogs_assert(ret == 0);
break;
default:
break;
}
}
/* ... lots of AVPs ... */
/* QoS-Information */
ret = fd_msg_avp_new(ogs_diam_gx_qos_information, 0, &avpch1);
ogs_assert(ret == 0);
@ -295,8 +265,65 @@ static void fill_multiple_services_credit_control_ccr(smf_sess_t *sess,
ret = fd_msg_avp_add (avpch1, MSG_BRW_LAST_CHILD, avpch2);
ogs_assert(ret == 0);
}
ret = fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1);
ret = fd_msg_avp_add (parent_avp, MSG_BRW_LAST_CHILD, avpch1);
ogs_assert(ret == 0);
}
/* TS 32.299 7.1.9 Multiple-Services-Credit-Control AVP for CCR */
static void fill_multiple_services_credit_control_ccr(smf_sess_t *sess,
uint32_t cc_request_type, struct msg *req)
{
int ret;
union avp_value val;
struct avp *avp;
struct avp *avpch1;
/* Multiple-Services-Credit-Control */
ret = fd_msg_avp_new(ogs_diam_gy_multiple_services_cc, 0, &avp);
ogs_assert(ret == 0);
/* Requested-Service-Unit, RFC4006 8.18 */
if (cc_request_type == OGS_DIAM_GY_CC_REQUEST_TYPE_INITIAL_REQUEST ||
cc_request_type == OGS_DIAM_GY_CC_REQUEST_TYPE_UPDATE_REQUEST)
fill_requested_service_unit(sess, avp);
if (cc_request_type == OGS_DIAM_GY_CC_REQUEST_TYPE_UPDATE_REQUEST ||
cc_request_type == OGS_DIAM_GY_CC_REQUEST_TYPE_TERMINATION_REQUEST) {
/* Used-Service-Unit, RFC4006 8.18 */
fill_used_service_unit(sess, cc_request_type, avp);
/* Service-Identifier, RFC4006 8.28. Not used in Gy. */
/* Rating-Group */
/* Reporting-Reason, TS 32.299 7.2.175 */
/* "values QHT, FINAL, VALIDITY_TIME, FORCED_REAUTHORISATION,
* RATING_CONDITION_CHANGE, UNUSED_QUOTA_TIMER apply for all quota types
* and are used directly in the Multiple-Services-Credit-Control AVP"
*/
switch (sess->gy.reporting_reason) {
case OGS_DIAM_GY_REPORTING_REASON_QHT:
case OGS_DIAM_GY_REPORTING_REASON_FINAL:
case OGS_DIAM_GY_REPORTING_REASON_FORCED_REAUTHORISATION:
case OGS_DIAM_GY_REPORTING_REASON_VALIDITY_TIME:
case OGS_DIAM_GY_REPORTING_REASON_RATING_CONDITION_CHANGE:
case OGS_DIAM_GY_REPORTING_REASON_UNUSED_QUOTA_TIMER:
ret = fd_msg_avp_new(ogs_diam_gy_reporting_reason, 0, &avpch1);
ogs_assert(ret == 0);
val.u32 = sess->gy.reporting_reason;
ret = fd_msg_avp_setvalue (avpch1, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1);
ogs_assert(ret == 0);
break;
default:
break;
}
}
/* ... lots of AVPs ... */
/* QoS-Information */
fill_qos_information(sess, avp);
/* 3GPP-RAT-Type, TS 29.061 16.4.7.2 21 */
/* GGSN: TS 29.060 7.7.50, PGW: TS 29.274 8.17 */
@ -308,7 +335,7 @@ static void fill_multiple_services_credit_control_ccr(smf_sess_t *sess,
ogs_assert(ret == 0);
ret = fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1);
ogs_assert(ret == 0);
}
/* Multiple Services AVP add to req: */
ret = fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp);
ogs_assert(ret == 0);