P-GW respond to DIAMETER error from PCRF(#403)
This commit is contained in:
parent
63809a3677
commit
5009876c16
|
@ -146,6 +146,8 @@ typedef struct ogs_diam_gx_message_s {
|
|||
#define OGS_DIAM_GX_DIAMETER_ADC_RULE_EVENT 5148
|
||||
#define OGS_DIAM_GX_DIAMETER_ERROR_NBIFOM_NOT_AUTHORIZED 5149
|
||||
uint32_t result_code;
|
||||
uint32_t *err;
|
||||
uint32_t *exp_err;
|
||||
|
||||
#define OGS_DIAM_GX_CC_REQUEST_TYPE_INITIAL_REQUEST 1
|
||||
#define OGS_DIAM_GX_CC_REQUEST_TYPE_UPDATE_REQUEST 2
|
||||
|
|
|
@ -67,7 +67,6 @@ static uint8_t emm_cause_from_diameter(
|
|||
case ER_DIAMETER_MISSING_AVP: /* 5005 */
|
||||
case ER_DIAMETER_RESOURCES_EXCEEDED: /* 5006 */
|
||||
case ER_DIAMETER_AVP_OCCURS_TOO_MANY_TIMES: /* 5009 */
|
||||
default: /* FIXME: only permanent */
|
||||
return EMM_CAUSE_NETWORK_FAILURE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -530,6 +530,7 @@ static void pgw_gx_cca_cb(void *data, struct msg **msg)
|
|||
ret = fd_msg_avp_hdr(avp, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
gx_message->result_code = hdr->avp_value->i32;
|
||||
gx_message->err = &gx_message->result_code;
|
||||
ogs_debug(" Result Code: %d", hdr->avp_value->i32);
|
||||
} else {
|
||||
ret = fd_msg_search_avp(*msg, ogs_diam_experimental_result, &avp);
|
||||
|
@ -541,6 +542,7 @@ static void pgw_gx_cca_cb(void *data, struct msg **msg)
|
|||
ret = fd_msg_avp_hdr(avpch1, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
gx_message->result_code = hdr->avp_value->i32;
|
||||
gx_message->exp_err = &gx_message->result_code;
|
||||
ogs_debug(" Experimental Result Code: %d",
|
||||
gx_message->result_code);
|
||||
}
|
||||
|
|
|
@ -42,6 +42,24 @@ static void timeout(ogs_gtp_xact_t *xact, void *data)
|
|||
"Message-Type[%d]", sess->sgw_s5c_teid, sess->pgw_s5c_teid, type);
|
||||
}
|
||||
|
||||
static uint8_t gtp_cause_from_diameter(
|
||||
const uint32_t *dia_err, const uint32_t *dia_exp_err)
|
||||
{
|
||||
if (dia_exp_err) {
|
||||
}
|
||||
if (dia_err) {
|
||||
switch (*dia_err) {
|
||||
case OGS_DIAM_UNKNOWN_SESSION_ID:
|
||||
return OGS_GTP_CAUSE_APN_ACCESS_DENIED_NO_SUBSCRIPTION;
|
||||
}
|
||||
}
|
||||
|
||||
ogs_error("Unexpected Diameter Result Code %d/%d, defaulting to severe "
|
||||
"network failure",
|
||||
dia_err ? *dia_err : -1, dia_exp_err ? *dia_exp_err : -1);
|
||||
return OGS_GTP_CAUSE_UE_NOT_AUTHORISED_BY_OCS_OR_EXTERNAL_AAA_SERVER;
|
||||
}
|
||||
|
||||
void pgw_gx_handle_cca_initial_request(
|
||||
pgw_sess_t *sess, ogs_diam_gx_message_t *gx_message,
|
||||
ogs_gtp_xact_t *xact, ogs_gtp_create_session_request_t *req)
|
||||
|
@ -55,6 +73,19 @@ void pgw_gx_handle_cca_initial_request(
|
|||
ogs_assert(xact);
|
||||
ogs_assert(req);
|
||||
|
||||
ogs_debug("[PGW] Create Session Response");
|
||||
ogs_debug(" SGW_S5C_TEID[0x%x] PGW_S5C_TEID[0x%x]",
|
||||
sess->sgw_s5c_teid, sess->pgw_s5c_teid);
|
||||
|
||||
if (gx_message->result_code != ER_DIAMETER_SUCCESS) {
|
||||
uint8_t cause_value = gtp_cause_from_diameter(
|
||||
gx_message->err, gx_message->exp_err);
|
||||
|
||||
ogs_gtp_send_error_message(xact, sess ? sess->sgw_s5c_teid : 0,
|
||||
OGS_GTP_CREATE_SESSION_RESPONSE_TYPE, cause_value);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Send Create Session Request with Creating Default Bearer */
|
||||
memset(&h, 0, sizeof(ogs_gtp_header_t));
|
||||
h.type = OGS_GTP_CREATE_SESSION_RESPONSE_TYPE;
|
||||
|
@ -97,6 +128,15 @@ void pgw_gx_handle_cca_termination_request(
|
|||
/* Remove a pgw session */
|
||||
pgw_sess_remove(sess);
|
||||
|
||||
if (gx_message->result_code != ER_DIAMETER_SUCCESS) {
|
||||
uint8_t cause_value = gtp_cause_from_diameter(
|
||||
gx_message->err, gx_message->exp_err);
|
||||
|
||||
ogs_gtp_send_error_message(xact, sgw_s5c_teid,
|
||||
OGS_GTP_DELETE_SESSION_RESPONSE_TYPE, cause_value);
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&h, 0, sizeof(ogs_gtp_header_t));
|
||||
h.type = OGS_GTP_DELETE_SESSION_RESPONSE_TYPE;
|
||||
h.teid = sgw_s5c_teid;
|
||||
|
|
|
@ -199,26 +199,24 @@ void pgw_state_operational(ogs_fsm_t *s, pgw_event_t *e)
|
|||
gtpbuf = e->gtpbuf;
|
||||
ogs_assert(gtpbuf);
|
||||
message = (ogs_gtp_message_t *)gtpbuf->data;
|
||||
ogs_assert(message);
|
||||
|
||||
if (gx_message->result_code == ER_DIAMETER_SUCCESS) {
|
||||
switch(gx_message->cc_request_type) {
|
||||
case OGS_DIAM_GX_CC_REQUEST_TYPE_INITIAL_REQUEST:
|
||||
pgw_gx_handle_cca_initial_request(
|
||||
sess, gx_message, xact,
|
||||
&message->create_session_request);
|
||||
break;
|
||||
case OGS_DIAM_GX_CC_REQUEST_TYPE_TERMINATION_REQUEST:
|
||||
pgw_gx_handle_cca_termination_request(
|
||||
sess, gx_message, xact,
|
||||
&message->delete_session_request);
|
||||
break;
|
||||
default:
|
||||
ogs_error("Not implemented(%d)",
|
||||
gx_message->cc_request_type);
|
||||
break;
|
||||
}
|
||||
} else
|
||||
ogs_error("Diameter Error(%d)", gx_message->result_code);
|
||||
switch(message->h.type) {
|
||||
case OGS_GTP_CREATE_SESSION_REQUEST_TYPE:
|
||||
pgw_gx_handle_cca_initial_request(
|
||||
sess, gx_message, xact,
|
||||
&message->create_session_request);
|
||||
break;
|
||||
case OGS_GTP_DELETE_SESSION_REQUEST_TYPE:
|
||||
pgw_gx_handle_cca_termination_request(
|
||||
sess, gx_message, xact,
|
||||
&message->delete_session_request);
|
||||
break;
|
||||
default:
|
||||
ogs_error("Not implemented(%d)",
|
||||
gx_message->cc_request_type);
|
||||
break;
|
||||
}
|
||||
|
||||
ogs_pkbuf_free(gtpbuf);
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue