Support all TFT code (#358)

This commit is contained in:
Sukchan Lee 2020-01-28 18:26:10 +09:00
parent 7c658091c5
commit 5d99df4036
3 changed files with 45 additions and 25 deletions

View File

@ -295,12 +295,24 @@ int16_t ogs_gtp_parse_tft(ogs_gtp_tft_t *tft, ogs_tlv_octet_t *octet)
memcpy(&tft->flags, (unsigned char *)octet->data+size, sizeof(tft->flags));
size++;
if (tft->code == OGS_GTP_TFT_CODE_IGNORE_THIS_IE) {
ogs_error("Invalid TFT Code(Spare)");
return size;
}
if (tft->code == OGS_GTP_TFT_CODE_NO_TFT_OPERATION ||
tft->code == OGS_GTP_TFT_CODE_DELETE_EXISTING_TFT)
return size;
for (i = 0; i < tft->num_of_packet_filter; i++) {
ogs_assert(size+sizeof(tft->pf[i].flags) <= octet->len);
memcpy(&tft->pf[i].flags, (unsigned char *)octet->data+size,
sizeof(tft->pf[i].flags));
size += sizeof(tft->pf[i].flags);
if (tft->code == OGS_GTP_TFT_CODE_DELETE_PACKET_FILTERS_FROM_EXISTING)
continue;
ogs_assert(size+sizeof(tft->pf[i].precedence) <= octet->len);
memcpy(&tft->pf[i].precedence, (unsigned char *)octet->data+size,
sizeof(tft->pf[i].precedence));
@ -440,6 +452,8 @@ int16_t ogs_gtp_build_tft(
ogs_assert(data);
ogs_assert(data_len >= OGS_GTP_MAX_TRAFFIC_FLOW_TEMPLATE);
ogs_assert(tft->code != OGS_GTP_TFT_CODE_IGNORE_THIS_IE);
octet->data = data;
memcpy(&target, tft, sizeof(ogs_gtp_tft_t));
@ -448,12 +462,19 @@ int16_t ogs_gtp_build_tft(
sizeof(target.flags));
size += sizeof(target.flags);
if (tft->code == OGS_GTP_TFT_CODE_NO_TFT_OPERATION ||
tft->code == OGS_GTP_TFT_CODE_DELETE_EXISTING_TFT)
return size;
for (i = 0; i < target.num_of_packet_filter; i++) {
ogs_assert(size + sizeof(target.pf[i].flags) <= data_len);
memcpy((unsigned char *)octet->data + size, &target.pf[i].flags,
sizeof(target.pf[i].flags));
size += sizeof(target.pf[i].flags);
if (tft->code == OGS_GTP_TFT_CODE_DELETE_PACKET_FILTERS_FROM_EXISTING)
continue;
ogs_assert(size + sizeof(target.pf[i].precedence) <= data_len);
memcpy((unsigned char *)octet->data + size, &target.pf[i].precedence,
sizeof(target.pf[i].precedence));

View File

@ -273,8 +273,8 @@ static void bearer_binding(pgw_sess_t *sess, ogs_diam_gx_message_t *gx_message)
ogs_assert(strcmp(bearer->name, pcc_rule->name) == 0);
if (pcc_rule->num_of_flow) {
/* 'Create new TFT' is only supported.
* As such, all previous flows are removed
/* We'll use always 'Create new TFT'.
* Therefore, all previous flows are removed
* and replaced by the new flow */
pgw_pf_remove_all(bearer);
}
@ -295,8 +295,8 @@ static void bearer_binding(pgw_sess_t *sess, ogs_diam_gx_message_t *gx_message)
}
if (pcc_rule->num_of_flow == 0 && qos_presence == 0) {
ogs_warn("[IGNORE] Update Bearer Request : "
"Both QoS and TFT are NULL");
ogs_warn("No need to send 'Update Bearer Request'");
ogs_warn(" - Both QoS and TFT are same as before");
continue;
}
}

View File

@ -453,11 +453,13 @@ void pgw_s5c_handle_bearer_resource_command(
{
int rv;
uint8_t cause_value = 0;
int i;
ogs_gtp_header_t h;
ogs_pkbuf_t *pkbuf = NULL;
pgw_bearer_t *bearer = NULL;
pgw_pf_t *pf = NULL;
int16_t decoded;
ogs_gtp_tft_t tft;
@ -510,18 +512,15 @@ void pgw_s5c_handle_bearer_resource_command(
if (tft.code == OGS_GTP_TFT_CODE_NO_TFT_OPERATION) {
/* No operation */
} else if (tft.code == OGS_GTP_TFT_CODE_DELETE_EXISTING_TFT) {
pgw_pf_remove_all(bearer);
tft_presence = 1;
} else if (tft.code ==
OGS_GTP_TFT_CODE_REPLACE_PACKET_FILTERS_IN_EXISTING) {
int i;
for (i = 0; i < tft.num_of_packet_filter; i++) {
int num_of_comp = 0;
pgw_pf_t *pf = NULL;
pf = pgw_pf_find_by_id(bearer, tft.pf[i].identifier+1);
if (pf) {
num_of_comp = reconfigure_packet_filter(pf, &tft, i);
if (num_of_comp < 0) {
if (reconfigure_packet_filter(pf, &tft, i) < 0) {
ogs_gtp_send_error_message(
xact, sess ? sess->sgw_s5c_teid : 0,
OGS_GTP_BEARER_RESOURCE_FAILURE_INDICATION_TYPE,
@ -530,22 +529,21 @@ void pgw_s5c_handle_bearer_resource_command(
}
}
if (num_of_comp > 0) tft_presence = 1;
tft_presence = 1;
}
} else if (tft.code ==
OGS_GTP_TFT_CODE_ADD_PACKET_FILTERS_TO_EXISTING_TFT) {
int i;
for (i = 0; i < tft.num_of_packet_filter; i++) {
int num_of_comp = 0;
pgw_pf_t *pf = NULL;
OGS_GTP_TFT_CODE_ADD_PACKET_FILTERS_TO_EXISTING_TFT ||
tft.code == OGS_GTP_TFT_CODE_CREATE_NEW_TFT) {
if (tft.code == OGS_GTP_TFT_CODE_CREATE_NEW_TFT)
pgw_pf_remove_all(bearer);
for (i = 0; i < tft.num_of_packet_filter; i++) {
pf = pgw_pf_find_by_id(bearer, tft.pf[i].identifier+1);
if (!pf)
pf = pgw_pf_add(bearer, tft.pf[i].precedence);
ogs_assert(pf);
num_of_comp = reconfigure_packet_filter(pf, &tft, i);
if (num_of_comp < 0) {
if (reconfigure_packet_filter(pf, &tft, i) < 0) {
ogs_gtp_send_error_message(
xact, sess ? sess->sgw_s5c_teid : 0,
OGS_GTP_BEARER_RESOURCE_FAILURE_INDICATION_TYPE,
@ -553,16 +551,17 @@ void pgw_s5c_handle_bearer_resource_command(
return;
}
if (num_of_comp > 0) tft_presence = 1;
tft_presence = 1;
}
} else if (tft.code ==
OGS_GTP_TFT_CODE_DELETE_PACKET_FILTERS_FROM_EXISTING) {
for (i = 0; i < tft.num_of_packet_filter; i++) {
pf = pgw_pf_find_by_id(bearer, tft.pf[i].identifier+1);
if (pf)
pgw_pf_remove(pf);
/* TODO */
ogs_gtp_send_error_message(xact, sess ? sess->sgw_s5c_teid : 0,
OGS_GTP_BEARER_RESOURCE_FAILURE_INDICATION_TYPE,
OGS_GTP_CAUSE_SERVICE_NOT_SUPPORTED);
return;
tft_presence = 1;
}
}
if (cmd->flow_quality_of_service.presence) {