Skip to content

Commit

Permalink
fix(amf): handle and proper response the error code from subscriberdb…
Browse files Browse the repository at this point in the history
… during authentication

Signed-off-by: RahulKalsangra <rahul.kalsangra@wavelabs.ai>
  • Loading branch information
RahulKalsangra committed Feb 8, 2022
1 parent 6353e41 commit 1f3b25d
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ struct amf_procedures_t;
#define PDUE_SESSION_RELEASE_TIMER_MSECS 16000

#define MAX_PAGING_RETRY_COUNT 4
#define AUTHENTICATION_COUNTER_MAX_RETRY 5
// Header length boundaries of 5GS Mobility Management messages
#define AMF_HEADER_LENGTH sizeof(amf_msg_header)

Expand All @@ -105,7 +106,7 @@ struct amf_procedures_t;
#define PDU_ADDR_IPV4_LEN 0x4
#define GNB_IPV4_ADDR_LEN 4
#define GNB_TEID_LEN 4

#define DIAMETER_TOO_BUSY 3004
#define NON_AMF_3GPP_ACCESS 2
#define AMF_3GPP_ACCESS_AND_NON_AMF_3GPP_ACCESS 3

Expand Down Expand Up @@ -350,6 +351,9 @@ typedef struct amf_context_s {
apn_config_profile_t apn_config_profile;

amf_nas_message_decode_status_t decode_status;
nas5g_timer_t auth_retry_timer;
int auth_retry_interval = 1000;
uint8_t auth_retry_count = 0;
} amf_context_t;

// Amf-Map Declarations:
Expand Down
46 changes: 40 additions & 6 deletions lte/gateway/c/core/oai/tasks/amf/amf_authentication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@ static int start_authentication_information_procedure(

int rc = RETURNerror;
char imsi_str[IMSI_BCD_DIGITS_MAX + 1];
uint8_t snni[40] = {0};

amf_ue_ngap_id_t ue_id =
PARENT_STRUCT(amf_context, ue_m5gmm_context_s, amf_context)
Expand All @@ -121,31 +120,66 @@ static int start_authentication_information_procedure(
auth_info_proc->ue_id = ue_id;
auth_info_proc->resync = auth_info_proc->request_sent;

bool is_initial_req = !(auth_info_proc->request_sent);
auth_info_proc->request_sent = true;
auth_proc->auts = bstrcpy(auts);

rc = amf_authentication_request_sent(ue_id);
if (rc != RETURNok) {
OAILOG_FUNC_RETURN(LOG_NAS_AMF, rc);
}

OAILOG_FUNC_RETURN(LOG_NAS_AMF, RETURNok);
}

int amf_authentication_request_sent(amf_ue_ngap_id_t ue_id) {
OAILOG_INFO(
LOG_AMF_APP, "inside amf_authentication_request_sent"); // need to remove
ue_m5gmm_context_s* ue_mm_context = NULL;
amf_context_t* amf_context = NULL;
char imsi_str[IMSI_BCD_DIGITS_MAX + 1];
int rc = RETURNerror;
ue_mm_context = amf_ue_context_exists_amf_ue_ngap_id(ue_id);
uint8_t snni[40] = {0};
if (!ue_mm_context) {
OAILOG_WARNING(
LOG_NAS_AMF,
"AMF-PROC - Failed authentication request the UE due to NULL"
"ue_mm_context\n");
OAILOG_FUNC_RETURN(LOG_NAS_AMF, rc);
}
amf_context = &ue_mm_context->amf_context;
nas5g_amf_auth_proc_t* auth_proc =
get_nas5g_common_procedure_authentication(amf_context);

if (!auth_proc) {
OAILOG_WARNING(LOG_NAS_AMF, "authentication procedure not present\n");
OAILOG_FUNC_RETURN(LOG_NAS_AMF, rc);
}
IMSI64_TO_STRING(amf_context->imsi64, imsi_str, IMSI_LENGTH);

rc = calculate_amf_serving_network_name(amf_context, snni);
if (rc != RETURNok) {
OAILOG_FUNC_RETURN(LOG_NAS_AMF, rc);
}

nas5g_auth_info_proc_t* auth_info_proc =
get_nas5g_cn_procedure_auth_info(amf_context);
bool is_initial_req = !(auth_info_proc->request_sent);
auth_info_proc->request_sent = true;
if (is_initial_req) {
OAILOG_INFO(
LOG_AMF_APP,
"Sending msg(grpc) to :[subscriberdb] for ue: [%s] auth-info\n",
imsi_str);
AMFClientServicer::getInstance().get_subs_auth_info(
imsi_str, IMSI_LENGTH, reinterpret_cast<const char*>(snni), ue_id);
} else if (auts->data) {
} else if (auth_proc->auts) {
OAILOG_INFO(
LOG_AMF_APP,
"Sending msg(grpc) to :[subscriberdb] for ue: [%s] auth-info-resync\n",
imsi_str);
AMFClientServicer::getInstance().get_subs_auth_info_resync(
imsi_str, IMSI_LENGTH, reinterpret_cast<const char*>(snni), auts->data,
RAND_LENGTH_OCTETS + AUTS_LENGTH, ue_id);
imsi_str, IMSI_LENGTH, reinterpret_cast<const char*>(snni),
auth_proc->auts, RAND_LENGTH_OCTETS + AUTS_LENGTH, ue_id);
}

OAILOG_FUNC_RETURN(LOG_NAS_AMF, RETURNok);
Expand Down
3 changes: 2 additions & 1 deletion lte/gateway/c/core/oai/tasks/amf/amf_authentication.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ typedef struct nas5g_amf_auth_proc_s {
int amf_cause;
int retry_sync_failure;
#define MAX_SYNC_FAILURES 2
bstring auts;
} nas5g_amf_auth_proc_t;

typedef struct nas5g_auth_info_proc_s {
Expand Down Expand Up @@ -77,7 +78,7 @@ int amf_send_authentication_request(

// To be called when authentication is successful from subscriberdb
int amf_authentication_proc_success(amf_context_t* amf_context);

int amf_authentication_request_sent(amf_ue_ngap_id_t ue_id);
int amf_nas_proc_authentication_info_answer(itti_amf_subs_auth_info_ans_t* aia);
nas5g_amf_auth_proc_t* get_nas5g_common_procedure_authentication(
const amf_context_t* const ctxt);
Expand Down
83 changes: 72 additions & 11 deletions lte/gateway/c/core/oai/tasks/amf/nas_proc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ extern task_zmq_ctx_s amf_app_task_zmq_ctx;
AmfMsg amf_msg_obj;
extern std::unordered_map<imsi64_t, guti_and_amf_id_t> amf_supi_guti_map;
static int identification_t3570_handler(zloop_t* loop, int timer_id, void* arg);
static int subs_auth_retry(zloop_t* loop, int timer_id, void* output);
int nas_proc_establish_ind(
const amf_ue_ngap_id_t ue_id, const bool is_mm_ctx_new,
const tai_t originating_tai, const ecgi_t ecgi,
Expand Down Expand Up @@ -412,10 +413,60 @@ int amf_nas_proc_auth_param_res(
OAILOG_FUNC_RETURN(LOG_NAS_AMF, rc);
}

static int subs_auth_retry(zloop_t* loop, int timer_id, void* arg) {
amf_ue_ngap_id_t ue_id = 0;
char snni[40] = {0};
uint32_t mcc = 0;
uint32_t mnc = 0;
uint32_t mnc_digit_length = 0;
amf_context_t* amf_ctxt_p = NULL;
int amf_cause = -1;
nas5g_auth_info_proc_t* auth_info_proc = NULL;
int rc = RETURNerror;
ue_m5gmm_context_s* ue_mm_context = NULL;
char imsi_str[IMSI_BCD_DIGITS_MAX + 1];
if (!amf_pop_timer_arg(timer_id, &ue_id)) {
OAILOG_WARNING(
LOG_AMF_APP,
"auth_retry_timer: Invalid Timer Id expiration, Timer Id: %d \n",
timer_id);
OAILOG_FUNC_RETURN(LOG_NAS_AMF, RETURNok);
}
ue_mm_context = amf_ue_context_exists_amf_ue_ngap_id(ue_id);
amf_ctxt_p = &ue_mm_context->amf_context;
amf_ctxt_p->auth_retry_count++;
OAILOG_ERROR(
LOG_AMF_APP, "auth_retry_timer: Incrementing auth_retry_count to %d\n",
amf_ctxt_p->auth_retry_count);
amf_ctxt_p->auth_retry_interval = 2 * amf_ctxt_p->auth_retry_interval;
if (amf_ctxt_p->auth_retry_count < AUTHENTICATION_COUNTER_MAX_RETRY) {
rc = amf_authentication_request_sent(ue_id);
amf_ctxt_p->auth_retry_timer.id = amf_app_start_timer(
amf_ctxt_p->auth_retry_interval, TIMER_REPEAT_ONCE, subs_auth_retry,
ue_id);
} else {
auth_info_proc = get_nas5g_cn_procedure_auth_info(amf_ctxt_p);
OAILOG_ERROR(
LOG_NAS_AMF,
"auth_retry_timer is expired . Authentication reject with cause "
"AMF_UE_ILLEGAL\n");
amf_cause = AMF_UE_ILLEGAL;

rc = amf_proc_registration_reject(ue_id, amf_cause);
if (auth_info_proc) {
nas5g_delete_cn_procedure(amf_ctxt_p, &auth_info_proc->cn_proc);
}

amf_free_ue_context(ue_mm_context);
}

return rc;
}

int amf_nas_proc_authentication_info_answer(
itti_amf_subs_auth_info_ans_t* aia) {
imsi64_t imsi64 = INVALID_IMSI64;
int rc = RETURNerror;
int rc = RETURNok;
amf_context_t* amf_ctxt_p = NULL;
ue_m5gmm_context_s* ue_5gmm_context_p = NULL;
int amf_cause = -1;
Expand Down Expand Up @@ -445,7 +496,6 @@ int amf_nas_proc_authentication_info_answer(
"Received Authentication Information Answer from Subscriberdb for"
" UE ID = " AMF_UE_NGAP_ID_FMT,
amf_ue_ngap_id);

if (aia->auth_info.nb_of_vectors) {
/*
* Check that list is not empty and contain at most MAX_EPS_AUTH_VECTORS
Expand All @@ -466,17 +516,28 @@ int amf_nas_proc_authentication_info_answer(
aia->auth_info.m5gauth_vector);
} else {
/* Get Auth Info Pro */
auth_info_proc = get_nas5g_cn_procedure_auth_info(amf_ctxt_p);
OAILOG_ERROR(
LOG_NAS_AMF, "nb_of_vectors received is zero from subscriberdb");
amf_cause = AMF_UE_ILLEGAL;
rc = amf_proc_registration_reject(amf_ue_ngap_id, amf_cause);
if (auth_info_proc) {
nas5g_delete_cn_procedure(amf_ctxt_p, &auth_info_proc->cn_proc);
auth_info_proc = get_nas5g_cn_procedure_auth_info(amf_ctxt_p);
amf_ctxt_p->auth_retry_count = 0;
if (aia->result != DIAMETER_TOO_BUSY) {
auth_info_proc = get_nas5g_cn_procedure_auth_info(amf_ctxt_p);
OAILOG_ERROR(
LOG_NAS_AMF,
"result=%d, nb_of_vectors received is zero from subscriberdb",
aia->result);
amf_cause = AMF_UE_ILLEGAL;
rc = amf_proc_registration_reject(amf_ue_ngap_id, amf_cause);
if (auth_info_proc) {
nas5g_delete_cn_procedure(amf_ctxt_p, &auth_info_proc->cn_proc);
}
amf_free_ue_context(ue_5gmm_context_p);
return rc;
} else {
amf_ctxt_p->auth_retry_timer.id = amf_app_start_timer(
amf_ctxt_p->auth_retry_interval, TIMER_REPEAT_ONCE, subs_auth_retry,
aia->ue_id);
rc = RETURNok;
}
amf_free_ue_context(ue_5gmm_context_p);
}

OAILOG_FUNC_RETURN(LOG_NAS_AMF, rc);
}

Expand Down
36 changes: 36 additions & 0 deletions lte/gateway/c/core/oai/test/amf/test_amf_procedures.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1149,4 +1149,40 @@ TEST_F(AMFAppProcedureTest, TestPDUv4v6SessionSetup) {
EXPECT_TRUE(rc == RETURNok);
EXPECT_TRUE(expected_Ids == AMFClientServicer::getInstance().msgtype_stack);
}
TEST_F(AMFAppProcedureTest, TestAuthFailureFromSubscribeDbLock) {
amf_ue_ngap_id_t ue_id = 0;
amf_context_t* amf_ctxt_p = NULL;
nas5g_auth_info_proc_t* auth_info_proc = NULL;
ue_m5gmm_context_s* ue_context_p = nullptr;
std::vector<MessagesIds> expected_Ids{
AMF_APP_NGAP_AMF_UE_ID_NOTIFICATION, // new registration notification
// indication to ngap
NGAP_NAS_DL_DATA_REQ, // Registration Reject
NGAP_UE_CONTEXT_RELEASE_COMMAND // UEContextReleaseCommand
};

/* Send the initial UE message */
imsi64_t imsi64 = 0;
imsi64 = send_initial_ue_message_no_tmsi(
amf_app_desc_p, 36, 1, 1, 0, plmn, initial_ue_message_hexbuf,
sizeof(initial_ue_message_hexbuf));

/* Check if UE Context is created with correct imsi */
EXPECT_TRUE(get_ue_id_from_imsi(amf_app_desc_p, imsi64, &ue_id));

/* Send the authentication response message from subscriberdb */
itti_amf_subs_auth_info_ans_t aia_itti_msg = {};
strncpy(aia_itti_msg.imsi, imsi.c_str(), imsi.size());
aia_itti_msg.imsi_length = imsi.size();
aia_itti_msg.result = DIAMETER_TOO_BUSY;
int rc = RETURNerror;
rc = amf_nas_proc_authentication_info_answer(&aia_itti_msg);
EXPECT_TRUE(rc == RETURNok);
ue_context_p = amf_ue_context_exists_amf_ue_ngap_id(ue_id);
amf_ctxt_p = &ue_context_p->amf_context;
auth_info_proc = get_nas5g_cn_procedure_auth_info(amf_ctxt_p);
nas5g_delete_cn_procedure(amf_ctxt_p, &auth_info_proc->cn_proc);
amf_free_ue_context(ue_context_p);
}

} // namespace magma5g

0 comments on commit 1f3b25d

Please sign in to comment.