Attempt to fix #548 problem

This commit is contained in:
Sukchan Lee 2020-09-04 23:36:51 -04:00
parent 054c3c0a63
commit d02aa8b21b
11 changed files with 252 additions and 91 deletions

View File

@ -1307,35 +1307,6 @@ int ogs_pfcp_ue_pool_generate(void)
return OGS_OK;
}
static ogs_pfcp_subnet_t *find_subnet(int family, const char *apn)
{
ogs_pfcp_subnet_t *subnet = NULL;
ogs_assert(apn);
ogs_assert(family == AF_INET || family == AF_INET6);
ogs_list_for_each(&self.subnet_list, subnet) {
if ((subnet->family == AF_UNSPEC || subnet->family == family) &&
(strlen(subnet->apn) == 0 ||
(strlen(subnet->apn) && strcmp(subnet->apn, apn) == 0))) {
return subnet;
}
}
if (subnet == NULL) {
ogs_error("CHECK CONFIGURATION: Cannot find subnet [family:%d, apn:%s]",
family, apn);
ogs_error("smf");
ogs_error(" pdn:");
if (family == AF_INET)
ogs_error(" - addr: 10.45.0.1/16");
else if (family == AF_INET6)
ogs_error(" - addr: cafe:1::1/64");
}
return subnet;
}
ogs_pfcp_ue_ip_t *ogs_pfcp_ue_ip_alloc(
int family, const char *apn, uint8_t *addr)
{
@ -1346,8 +1317,20 @@ ogs_pfcp_ue_ip_t *ogs_pfcp_ue_ip_alloc(
size_t maxbytes = 0;
ogs_assert(apn);
subnet = find_subnet(family, apn);
ogs_assert(subnet);
subnet = ogs_pfcp_find_subnet(family, apn);
if (subnet == NULL) {
ogs_error("CHECK CONFIGURATION: Cannot find subnet [family:%d, apn:%s]",
family, apn);
ogs_error("smf");
ogs_error(" pdn:");
if (family == AF_INET)
ogs_error(" - addr: 10.45.0.1/16");
else if (family == AF_INET6)
ogs_error(" - addr: cafe::1/64");
ogs_assert_if_reached();
return NULL;
}
memset(zero, 0, sizeof zero);
if (family == AF_INET) {
@ -1503,6 +1486,23 @@ void ogs_pfcp_subnet_remove_all(void)
ogs_pfcp_subnet_remove(subnet);
}
ogs_pfcp_subnet_t *ogs_pfcp_find_subnet(int family, const char *apn)
{
ogs_pfcp_subnet_t *subnet = NULL;
ogs_assert(apn);
ogs_assert(family == AF_INET || family == AF_INET6);
ogs_list_for_each(&self.subnet_list, subnet) {
if ((subnet->family == AF_UNSPEC || subnet->family == family) &&
(strlen(subnet->apn) == 0 ||
(strlen(subnet->apn) && strcmp(subnet->apn, apn) == 0)))
break;
}
return subnet;
}
void ogs_pfcp_pool_init(ogs_pfcp_sess_t *sess)
{
ogs_index_init(&sess->pdr_pool, OGS_MAX_NUM_OF_PDR);

View File

@ -361,6 +361,7 @@ ogs_pfcp_subnet_t *ogs_pfcp_subnet_add(
ogs_pfcp_subnet_t *ogs_pfcp_subnet_next(ogs_pfcp_subnet_t *subnet);
void ogs_pfcp_subnet_remove(ogs_pfcp_subnet_t *subnet);
void ogs_pfcp_subnet_remove_all(void);
ogs_pfcp_subnet_t *ogs_pfcp_find_subnet(int family, const char *apn);
void ogs_pfcp_pool_init(ogs_pfcp_sess_t *sess);
void ogs_pfcp_pool_final(ogs_pfcp_sess_t *sess);

View File

@ -31,6 +31,14 @@ static OGS_POOL(amf_sess_pool, amf_sess_t);
static int context_initialized = 0;
static int num_of_ran_ue = 0;
static int num_of_amf_sess = 0;
static void stats_add_ran_ue(void);
static void stats_remove_ran_ue(void);
static void stats_add_amf_session(void);
static void stats_remove_amf_session(void);
void amf_context_init(void)
{
ogs_assert(context_initialized == 0);
@ -854,6 +862,9 @@ amf_gnb_t *amf_gnb_add(ogs_sock_t *sock, ogs_sockaddr_t *addr)
ogs_list_add(&self.gnb_list, gnb);
ogs_info("[Added] Number of gNBs is now %d",
ogs_list_count(&self.gnb_list));
return gnb;
}
@ -885,6 +896,9 @@ int amf_gnb_remove(amf_gnb_t *gnb)
ogs_pool_free(&amf_gnb_pool, gnb);
ogs_info("[Removed] Number of gNBs is now %d",
ogs_list_count(&self.gnb_list));
return OGS_OK;
}
@ -970,6 +984,8 @@ ran_ue_t *ran_ue_add(amf_gnb_t *gnb, uint32_t ran_ue_ngap_id)
ogs_list_add(&gnb->ran_ue_list, ran_ue);
stats_add_ran_ue();
return ran_ue;
}
@ -986,6 +1002,8 @@ void ran_ue_remove(ran_ue_t *ran_ue)
ogs_timer_delete(ran_ue->t_ng_holding);
ogs_pool_free(&ran_ue_pool, ran_ue);
stats_remove_ran_ue();
}
void ran_ue_remove_in_gnb(amf_gnb_t *gnb)
@ -1132,6 +1150,9 @@ amf_ue_t *amf_ue_add(ran_ue_t *ran_ue)
ogs_list_add(&self.amf_ue_list, amf_ue);
ogs_info("[Added] Number of AMF-UEs is now %d",
ogs_list_count(&self.amf_ue_list));
return amf_ue;
}
@ -1198,6 +1219,9 @@ void amf_ue_remove(amf_ue_t *amf_ue)
amf_sess_remove_all(amf_ue);
ogs_pool_free(&amf_ue_pool, amf_ue);
ogs_info("[Removed] Number of AMF-UEs is now %d",
ogs_list_count(&self.amf_ue_list));
}
void amf_ue_remove_all()
@ -1478,6 +1502,8 @@ amf_sess_t *amf_sess_add(amf_ue_t *amf_ue, uint8_t psi)
ogs_list_add(&amf_ue->sess_list, sess);
stats_add_amf_session();
return sess;
}
@ -1506,6 +1532,8 @@ void amf_sess_remove(amf_sess_t *sess)
OGS_TLV_CLEAR_DATA(&sess->pgw_pco);
ogs_pool_free(&amf_sess_pool, sess);
stats_remove_amf_session();
}
void amf_sess_remove_all(amf_ue_t *amf_ue)
@ -1713,3 +1741,27 @@ uint8_t amf_selected_enc_algorithm(amf_ue_t *amf_ue)
return 0;
}
static void stats_add_ran_ue(void)
{
num_of_ran_ue = num_of_ran_ue + 1;
ogs_info("[Added] Number of gNB-UEs is now %d", num_of_ran_ue);
}
static void stats_remove_ran_ue(void)
{
num_of_ran_ue = num_of_ran_ue - 1;
ogs_info("[Removed] Number of gNB-UEs is now %d", num_of_ran_ue);
}
static void stats_add_amf_session(void)
{
num_of_amf_sess = num_of_amf_sess + 1;
ogs_info("[Added] Number of AMF-Sessions is now %d", num_of_amf_sess);
}
static void stats_remove_amf_session(void)
{
num_of_amf_sess = num_of_amf_sess - 1;
ogs_info("[Removed] Number of AMF-Sessions is now %d", num_of_amf_sess);
}

View File

@ -49,42 +49,13 @@ static OGS_POOL(mme_bearer_pool, mme_bearer_t);
static int context_initialized = 0;
int num_ues = 0;
int num_enbs = 0;
int num_mme_sessions = 0;
void stats_add_ue(void) {
num_ues = num_ues + 1;
ogs_info("Added a UE. Number of UEs is now %d", num_ues);
}
void stats_remove_ue(void) {
num_ues = num_ues - 1;
ogs_info("Removed a UE. Number of UEs is now %d", num_ues);
}
void stats_add_enb(void) {
num_enbs = num_enbs + 1;
ogs_info("Added a eNB. Number of eNBs is now %d", num_enbs);
}
void stats_remove_enb(void) {
num_enbs = num_enbs - 1;
ogs_info("Removed a eNB. Number of eNBs is now %d", num_enbs);
}
void stats_add_mme_session(void) {
num_mme_sessions = num_mme_sessions + 1;
ogs_info("Added a session. Number of sessions is now %d",
num_mme_sessions);
}
void stats_remove_mme_session(void) {
num_mme_sessions = num_mme_sessions - 1;
ogs_info("Removed a session. Number of sessions is now %d",
num_mme_sessions);
}
static int num_of_enb_ue = 0;
static int num_of_mme_sess = 0;
static void stats_add_enb_ue(void);
static void stats_remove_enb_ue(void);
static void stats_add_mme_session(void);
static void stats_remove_mme_session(void);
void mme_context_init()
{
@ -1937,7 +1908,8 @@ mme_enb_t *mme_enb_add(ogs_sock_t *sock, ogs_sockaddr_t *addr)
ogs_list_add(&self.enb_list, enb);
stats_add_enb();
ogs_info("[Added] Number of eNBs is now %d",
ogs_list_count(&self.enb_list));
return enb;
}
@ -1970,7 +1942,8 @@ int mme_enb_remove(mme_enb_t *enb)
ogs_pool_free(&mme_enb_pool, enb);
stats_remove_enb();
ogs_info("[Removed] Number of eNBs is now %d",
ogs_list_count(&self.enb_list));
return OGS_OK;
}
@ -2057,26 +2030,29 @@ enb_ue_t *enb_ue_add(mme_enb_t *enb, uint32_t enb_ue_s1ap_id)
ogs_list_add(&enb->enb_ue_list, enb_ue);
stats_add_ue();
stats_add_enb_ue();
return enb_ue;
}
void enb_ue_remove(enb_ue_t *enb_ue)
{
mme_enb_t *enb = NULL;
ogs_assert(enb_ue);
ogs_assert(enb_ue->enb);
enb = enb_ue->enb;
ogs_assert(enb);
/* De-associate S1 with NAS/EMM */
enb_ue_deassociate(enb_ue);
ogs_list_remove(&enb_ue->enb->enb_ue_list, enb_ue);
ogs_list_remove(&enb->enb_ue_list, enb_ue);
ogs_timer_delete(enb_ue->t_s1_holding);
stats_remove_ue();
ogs_pool_free(&enb_ue_pool, enb_ue);
stats_remove_enb_ue();
}
void enb_ue_remove_in_enb(mme_enb_t *enb)
@ -2288,6 +2264,9 @@ mme_ue_t *mme_ue_add(enb_ue_t *enb_ue)
ogs_list_add(&self.mme_ue_list, mme_ue);
ogs_info("[Added] Number of MME-UEs is now %d",
ogs_list_count(&self.mme_ue_list));
return mme_ue;
}
@ -2341,6 +2320,9 @@ void mme_ue_remove(mme_ue_t *mme_ue)
mme_ebi_pool_final(mme_ue);
ogs_pool_free(&mme_ue_pool, mme_ue);
ogs_info("[Removed] Number of MME-UEs is now %d",
ogs_list_count(&self.mme_ue_list));
}
void mme_ue_remove_all()
@ -2678,10 +2660,13 @@ mme_sess_t *mme_sess_add(mme_ue_t *mme_ue, uint8_t pti)
void mme_sess_remove(mme_sess_t *sess)
{
mme_ue_t *mme_ue = NULL;
ogs_assert(sess);
ogs_assert(sess->mme_ue);
mme_ue = sess->mme_ue;
ogs_assert(mme_ue);
ogs_list_remove(&sess->mme_ue->sess_list, sess);
ogs_list_remove(&mme_ue->sess_list, sess);
mme_bearer_remove_all(sess);
@ -3302,3 +3287,27 @@ uint8_t mme_selected_enc_algorithm(mme_ue_t *mme_ue)
return 0;
}
static void stats_add_enb_ue(void)
{
num_of_enb_ue = num_of_enb_ue + 1;
ogs_info("[Added] Number of eNB-UEs is now %d", num_of_enb_ue);
}
static void stats_remove_enb_ue(void)
{
num_of_enb_ue = num_of_enb_ue - 1;
ogs_info("[Removed] Number of eNB-UEs is now %d", num_of_enb_ue);
}
static void stats_add_mme_session(void)
{
num_of_mme_sess = num_of_mme_sess + 1;
ogs_info("[Added] Number of MME-Sessions is now %d", num_of_mme_sess);
}
static void stats_remove_mme_session(void)
{
num_of_mme_sess = num_of_mme_sess - 1;
ogs_info("[Removed] Number of MME-Sessions is now %d", num_of_mme_sess);
}

View File

@ -796,13 +796,6 @@ void mme_ebi_pool_clear(mme_ue_t *mme_ue);
uint8_t mme_selected_int_algorithm(mme_ue_t *mme_ue);
uint8_t mme_selected_enc_algorithm(mme_ue_t *mme_ue);
void stats_add_ue(void);
void stats_remove_ue(void);
void stats_add_enb(void);
void stats_remove_enb(void);
void stats_add_mme_session(void);
void stats_remove_mme_session(void);
#ifdef __cplusplus
}
#endif

View File

@ -295,7 +295,16 @@ static void mme_s6a_aia_cb(void *data, struct msg **msg)
}
if (s6a_message->result_code != ER_DIAMETER_SUCCESS) {
ogs_warn("ERROR DIAMETER Result Code(%d)", s6a_message->result_code);
if (s6a_message->err)
ogs_warn(" Result Code: %d", s6a_message->result_code);
else if (s6a_message->exp_err)
ogs_warn(" Experimental Result Code: %d",
s6a_message->result_code);
else {
ogs_fatal("ERROR DIAMETER Result Code(%d)",
s6a_message->result_code);
ogs_assert_if_reached();
}
goto out;
}

View File

@ -37,11 +37,14 @@
/* 3GPP TS 29.272 Annex A; Table !.a:
* Mapping from S6a error codes to NAS Cause Codes */
static uint8_t emm_cause_from_diameter(
const uint32_t *dia_err, const uint32_t *dia_exp_err)
mme_ue_t *mme_ue, const uint32_t *dia_err, const uint32_t *dia_exp_err)
{
ogs_assert(mme_ue);
if (dia_exp_err) {
switch (*dia_exp_err) {
case OGS_DIAM_S6A_ERROR_USER_UNKNOWN: /* 5001 */
ogs_warn("[%s] User Unknown in HSS DB", mme_ue->imsi_bcd);
return EMM_CAUSE_EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED;
case OGS_DIAM_S6A_ERROR_UNKNOWN_EPS_SUBSCRIPTION: /* 5420 */
/* FIXME: Error diagnostic? */
@ -443,11 +446,12 @@ void mme_state_operational(ogs_fsm_t *s, mme_event_t *e)
* However, e.g. 5004 has different meaning
* if used in result-code than in experimental-result-code */
uint8_t emm_cause = emm_cause_from_diameter(
s6a_message->err, s6a_message->exp_err);
mme_ue, s6a_message->err, s6a_message->exp_err);
ogs_warn("[%s] Attach reject [EMM_CAUSE:%d]",
mme_ue->imsi_bcd, emm_cause);
nas_eps_send_attach_reject(mme_ue,
emm_cause, ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED);
ogs_warn("EMM_CAUSE : %d", emm_cause);
enb_ue = mme_ue->enb_ue;
ogs_assert(enb_ue);
@ -598,6 +602,12 @@ void mme_state_operational(ogs_fsm_t *s, mme_event_t *e)
xact, mme_ue, &gtp_message.release_access_bearers_response);
break;
case OGS_GTP_DOWNLINK_DATA_NOTIFICATION_TYPE:
if (!mme_ue) {
if (gtp_message.h.teid_presence)
ogs_warn("TEID[%d]", gtp_message.h.teid);
else
ogs_warn("No TEID presence");
}
mme_s11_handle_downlink_data_notification(
xact, mme_ue, &gtp_message.downlink_data_notification);

View File

@ -32,6 +32,11 @@ static OGS_POOL(sgwc_tunnel_pool, sgwc_tunnel_t);
static int context_initialized = 0;
static int num_of_sgwc_sess = 0;
static void stats_add_sgwc_session(void);
static void stats_remove_sgwc_session(void);
void sgwc_context_init(void)
{
ogs_assert(context_initialized == 0);
@ -325,6 +330,9 @@ sgwc_ue_t *sgwc_ue_add(uint8_t *imsi, int imsi_len)
ogs_list_add(&self.sgw_ue_list, sgwc_ue);
ogs_info("[Added] Number of SGWC-UEs is now %d",
ogs_list_count(&self.sgw_ue_list));
return sgwc_ue;
}
@ -340,6 +348,9 @@ int sgwc_ue_remove(sgwc_ue_t *sgwc_ue)
ogs_pool_free(&sgwc_ue_pool, sgwc_ue);
ogs_info("[Removed] Number of SGWC-UEs is now %d",
ogs_list_count(&self.sgw_ue_list));
return OGS_OK;
}
@ -405,6 +416,8 @@ sgwc_sess_t *sgwc_sess_add(sgwc_ue_t *sgwc_ue, char *apn)
ogs_list_add(&sgwc_ue->sess_list, sess);
stats_add_sgwc_session();
return sess;
}
@ -490,6 +503,8 @@ int sgwc_sess_remove(sgwc_sess_t *sess)
ogs_pool_free(&sgwc_sess_pool, sess);
stats_remove_sgwc_session();
return OGS_OK;
}
@ -814,3 +829,15 @@ sgwc_tunnel_t *sgwc_ul_tunnel_in_bearer(sgwc_bearer_t *bearer)
return sgwc_tunnel_find_by_interface_type(bearer,
OGS_GTP_F_TEID_S1_U_SGW_GTP_U);
}
static void stats_add_sgwc_session(void)
{
num_of_sgwc_sess = num_of_sgwc_sess + 1;
ogs_info("[Added] Number of SGWC-Sessions is now %d", num_of_sgwc_sess);
}
static void stats_remove_sgwc_session(void)
{
num_of_sgwc_sess = num_of_sgwc_sess - 1;
ogs_info("[Removed] Number of SGWC-Sessions is now %d", num_of_sgwc_sess);
}

View File

@ -392,7 +392,7 @@ sgwu_sess_t *sgwu_sess_add(ogs_pfcp_f_seid_t *cp_f_seid,
ogs_list_add(&self.sess_list, sess);
ogs_info("Added a session. Number of active sessions is now %d",
ogs_info("[Added] Number of SGWU-Sessions is now %d",
ogs_list_count(&self.sess_list));
return sess;
@ -412,7 +412,7 @@ int sgwu_sess_remove(sgwu_sess_t *sess)
ogs_pool_free(&sgwu_sess_pool, sess);
ogs_info("Removed a session. Number of active sessions is now %d",
ogs_info("[Removed] Number of SGWU-sessions is now %d",
ogs_list_count(&self.sess_list));
return OGS_OK;

View File

@ -31,6 +31,11 @@ static OGS_POOL(smf_bearer_pool, smf_bearer_t);
static int context_initialized = 0;
static int num_of_smf_sess = 0;
static void stats_add_smf_session(void);
static void stats_remove_smf_session(void);
void smf_context_init(void)
{
ogs_assert(context_initialized == 0);
@ -517,6 +522,9 @@ smf_ue_t *smf_ue_add_by_supi(char *supi)
ogs_list_add(&self.smf_ue_list, smf_ue);
ogs_info("[Added] Number of SMF-UEs is now %d",
ogs_list_count(&self.smf_ue_list));
return smf_ue;
}
@ -540,6 +548,9 @@ smf_ue_t *smf_ue_add_by_imsi(uint8_t *imsi, int imsi_len)
ogs_list_add(&self.smf_ue_list, smf_ue);
ogs_info("[Added] Number of SMF-UEs is now %d",
ogs_list_count(&self.smf_ue_list));
return smf_ue;
}
@ -561,6 +572,9 @@ void smf_ue_remove(smf_ue_t *smf_ue)
smf_sess_remove_all(smf_ue);
ogs_pool_free(&smf_ue_pool, smf_ue);
ogs_info("[Removed] Number of SMF-UEs is now %d",
ogs_list_count(&self.smf_ue_list));
}
void smf_ue_remove_all(void)
@ -694,6 +708,8 @@ smf_sess_t *smf_sess_add_by_apn(smf_ue_t *smf_ue, char *apn)
ogs_list_add(&smf_ue->sess_list, sess);
stats_add_smf_session();
return sess;
}
@ -808,6 +824,8 @@ smf_sess_t *smf_sess_add_by_psi(smf_ue_t *smf_ue, uint8_t psi)
ogs_list_add(&smf_ue->sess_list, sess);
stats_add_smf_session();
return sess;
}
@ -860,6 +878,32 @@ void smf_sess_set_ue_ip(smf_sess_t *sess)
smf_ue = sess->smf_ue;
ogs_assert(smf_ue);
if (sess->pdn.pdn_type == OGS_PDU_SESSION_TYPE_IPV4V6) {
/*
* This is the case when the HSS is set to IPv4v6 and
* the UE requests IPv4v6.
*
* At this time, it was changed to operate normally
* even when SMF has no IPv4 or IPv6 subnet.
*
* If there is no IPv6 subnet, only IPv4 IP address is assigned.
* If there is no IPv4 subnet, only IPv6 IP address is assigned.
* If there are IPv4/IPv6 subnet, IPv4/IPv6 IP address are assigned.
*/
ogs_pfcp_subnet_t *subnet = NULL;
ogs_pfcp_subnet_t *subnet6 = NULL;
subnet = ogs_pfcp_find_subnet(AF_INET, sess->pdn.apn);
subnet6 = ogs_pfcp_find_subnet(AF_INET6, sess->pdn.apn);
if (subnet != NULL && subnet6 == NULL)
sess->pdn.pdn_type = OGS_PDU_SESSION_TYPE_IPV4;
else if (subnet == NULL && subnet6 != NULL)
sess->pdn.pdn_type = OGS_PDU_SESSION_TYPE_IPV6;
}
sess->pdn.paa.pdn_type = sess->pdn.pdn_type;
ogs_assert(sess->pdn.pdn_type);
@ -911,8 +955,10 @@ void smf_sess_set_ue_ip(smf_sess_t *sess)
sess->ipv4->addr, OGS_IPV4_LEN, sess);
ogs_hash_set(smf_self()->ipv6_hash,
sess->ipv6->addr, OGS_IPV6_LEN, sess);
} else
} else {
ogs_fatal("Invalid sess->pdn.pdn_type[%d]", sess->pdn.pdn_type);
ogs_assert_if_reached();
}
}
void smf_sess_remove(smf_sess_t *sess)
@ -978,6 +1024,8 @@ void smf_sess_remove(smf_sess_t *sess)
smf_qfi_pool_final(sess);
ogs_pool_free(&smf_sess_pool, sess);
stats_remove_smf_session();
}
void smf_sess_remove_all(smf_ue_t *smf_ue)
@ -1685,3 +1733,15 @@ void smf_qfi_pool_final(smf_sess_t *sess)
{
ogs_index_final(&sess->qfi_pool);
}
static void stats_add_smf_session(void)
{
num_of_smf_sess = num_of_smf_sess + 1;
ogs_info("[Added] Number of SMF-Sessions is now %d", num_of_smf_sess);
}
static void stats_remove_smf_session(void)
{
num_of_smf_sess = num_of_smf_sess - 1;
ogs_info("[Removed] Number of SMF-Sessions is now %d", num_of_smf_sess);
}

View File

@ -456,7 +456,7 @@ upf_sess_t *upf_sess_add(ogs_pfcp_f_seid_t *cp_f_seid,
ogs_list_add(&self.sess_list, sess);
ogs_info("Added a session. Number of active sessions is now %d",
ogs_info("[Added] Number of UPF-Sessions is now %d",
ogs_list_count(&self.sess_list));
return sess;
@ -489,7 +489,7 @@ int upf_sess_remove(upf_sess_t *sess)
ogs_pool_free(&upf_sess_pool, sess);
ogs_info("Removed a session. Number of active sessions is now %d",
ogs_info("[Removed] Number of UPF-sessions is now %d",
ogs_list_count(&self.sess_list));
return OGS_OK;