From de8ae9823a13ca69beb3e448555c9f426f49001b Mon Sep 17 00:00:00 2001 From: Sukchan Lee Date: Sun, 30 Jun 2019 12:46:02 +0900 Subject: [PATCH] Create Multiple Session for same IMSI (#203) --- src/mme/mme-context.h | 6 ++-- src/pgw/pgw-context.c | 70 +++++--------------------------------- src/pgw/pgw-context.h | 17 +++------ src/pgw/pgw-gtp-path.c | 6 ++-- src/pgw/pgw-ipfw.c | 8 ++--- src/sgw/sgw-context.c | 63 +++++----------------------------- src/sgw/sgw-context.h | 27 ++++++--------- tests/common/test-packet.c | 2 +- 8 files changed, 40 insertions(+), 159 deletions(-) diff --git a/src/mme/mme-context.h b/src/mme/mme-context.h index af44819f9..72a1d50bf 100644 --- a/src/mme/mme-context.h +++ b/src/mme/mme-context.h @@ -227,7 +227,7 @@ typedef struct mme_enb_s { } mme_enb_t; struct enb_ue_s { - ogs_lnode_t node; /* A node of list_t */ + ogs_lnode_t lnode; /* UE identity */ #define INVALID_UE_S1AP_ID 0xffffffff /* Initial value of enb_ue_s1ap_id */ @@ -474,7 +474,7 @@ struct mme_ue_s { (__mME)->session_context_will_deleted = 0; \ } while(0) typedef struct mme_sess_s { - ogs_lnode_t node; /* A node of list_t */ + ogs_lnode_t lnode; uint8_t pti; /* Procedure Trasaction Identity */ @@ -532,7 +532,7 @@ typedef struct mme_sess_s { (__bEARER)->sgw_ul_teid = 0; \ } while(0) typedef struct mme_bearer_s { - ogs_lnode_t node; /* A node of list_t */ + ogs_lnode_t lnode; ogs_fsm_t sm; /* State Machine */ uint8_t ebi; /* EPS Bearer ID */ diff --git a/src/pgw/pgw-context.c b/src/pgw/pgw-context.c index 0b7c4ae21..afbb93b93 100644 --- a/src/pgw/pgw-context.c +++ b/src/pgw/pgw-context.c @@ -78,7 +78,7 @@ void pgw_context_init() ogs_pool_init(&pgw_pf_pool, context_self()->pool.pf); - self.sess_hash = ogs_hash_make(); + ogs_list_init(&self.sess_list); context_initiaized = 1; } @@ -89,9 +89,6 @@ void pgw_context_final() pgw_sess_remove_all(); - ogs_assert(self.sess_hash); - ogs_hash_destroy(self.sess_hash); - pgw_dev_remove_all(); pgw_subnet_remove_all(); @@ -714,16 +711,6 @@ int pgw_context_parse_config() return OGS_OK; } -static void *sess_hash_keygen(uint8_t *out, int *out_len, - uint8_t *imsi, int imsi_len, char *apn) -{ - memcpy(out, imsi, imsi_len); - ogs_cpystrn((char*)(out+imsi_len), apn, MAX_APN_LEN+1); - *out_len = imsi_len+strlen((char*)(out+imsi_len)); - - return out; -} - pgw_sess_t *pgw_sess_add( uint8_t *imsi, int imsi_len, char *apn, uint8_t pdn_type, uint8_t ebi) @@ -794,20 +781,16 @@ pgw_sess_t *pgw_sess_add( sess->ipv4 ? INET_NTOP(&sess->ipv4->addr, buf1) : "", sess->ipv6 ? INET6_NTOP(&sess->ipv6->addr, buf2) : ""); - /* Generate Hash Key : IMSI + APN */ - sess_hash_keygen(sess->hash_keybuf, &sess->hash_keylen, - imsi, imsi_len, apn); - ogs_hash_set(self.sess_hash, sess->hash_keybuf, sess->hash_keylen, sess); + ogs_list_add(&self.sess_list, sess); return sess; } int pgw_sess_remove(pgw_sess_t *sess) { - ogs_assert(self.sess_hash); ogs_assert(sess); - ogs_hash_set(self.sess_hash, sess->hash_keybuf, sess->hash_keylen, NULL); + ogs_list_remove(&self.sess_list, sess); if (sess->ipv4) pgw_ue_ip_free(sess->ipv4); @@ -823,13 +806,10 @@ int pgw_sess_remove(pgw_sess_t *sess) void pgw_sess_remove_all() { - ogs_hash_index_t *hi = NULL; - pgw_sess_t *sess = NULL; + pgw_sess_t *sess = NULL, *next = NULL;; - for (hi = pgw_sess_first(); hi; hi = pgw_sess_next(hi)) { - sess = pgw_sess_this(hi); + ogs_list_for_each_safe(&self.sess_list, next, sess) pgw_sess_remove(sess); - } } pgw_sess_t *pgw_sess_find(uint32_t index) @@ -843,18 +823,6 @@ pgw_sess_t *pgw_sess_find_by_teid(uint32_t teid) return pgw_sess_find(teid); } -pgw_sess_t *pgw_sess_find_by_imsi_apn( - uint8_t *imsi, int imsi_len, char *apn) -{ - uint8_t keybuf[MAX_IMSI_LEN+MAX_APN_LEN+1]; - int keylen = 0; - - ogs_assert(self.sess_hash); - - sess_hash_keygen(keybuf, &keylen, imsi, imsi_len, apn); - return (pgw_sess_t *)ogs_hash_get(self.sess_hash, keybuf, keylen); -} - gtp_node_t *pgw_sgw_add_by_message(gtp_message_t *message) { int rv; @@ -919,34 +887,14 @@ pgw_sess_t *pgw_sess_add_by_message(gtp_message_t *message) apn, req->pdn_type.u8, req->bearer_contexts_to_be_created.eps_bearer_id.u8); - sess = pgw_sess_find_by_imsi_apn(req->imsi.data, req->imsi.len, apn); - if (!sess) { - sess = pgw_sess_add(req->imsi.data, req->imsi.len, apn, - req->pdn_type.u8, - req->bearer_contexts_to_be_created.eps_bearer_id.u8); - ogs_assert(sess); - } + sess = pgw_sess_add(req->imsi.data, req->imsi.len, apn, + req->pdn_type.u8, + req->bearer_contexts_to_be_created.eps_bearer_id.u8); + ogs_assert(sess); return sess; } -ogs_hash_index_t *pgw_sess_first() -{ - ogs_assert(self.sess_hash); - return ogs_hash_first(self.sess_hash); -} - -ogs_hash_index_t *pgw_sess_next(ogs_hash_index_t *hi) -{ - return ogs_hash_next(hi); -} - -pgw_sess_t *pgw_sess_this(ogs_hash_index_t *hi) -{ - ogs_assert(hi); - return ogs_hash_this_val(hi); -} - pgw_bearer_t *pgw_bearer_add(pgw_sess_t *sess) { pgw_bearer_t *bearer = NULL; diff --git a/src/pgw/pgw-context.h b/src/pgw/pgw-context.h index 3ff9ea385..21af8bef8 100644 --- a/src/pgw/pgw-context.h +++ b/src/pgw/pgw-context.h @@ -83,7 +83,7 @@ typedef struct pgw_context_s { ogs_list_t sgw_s5u_list; /* SGW GTPU Node List */ ogs_list_t ip_pool_list; - ogs_hash_t *sess_hash; /* hash table (IMSI+APN) */ + ogs_list_t sess_list; } pgw_context_t; typedef struct pgw_subnet_s pgw_subnet_t; @@ -95,7 +95,7 @@ typedef struct pgw_ue_ip_s { } pgw_ue_ip_t; typedef struct pgw_dev_s { - ogs_lnode_t node; + ogs_lnode_t lnode; char ifname[IFNAMSIZ]; ogs_socket_t fd; @@ -120,6 +120,7 @@ typedef struct pgw_subnet_s { } pgw_subnet_t; typedef struct pgw_sess_s { + ogs_lnode_t lnode; uint32_t index; /**< An index of this node */ uint32_t pgw_s5c_teid; /* PGW-S5C-TEID is derived from INDEX */ @@ -141,10 +142,6 @@ typedef struct pgw_sess_s { tai_t tai; e_cgi_t e_cgi; - /* Hash Key : IMSI+APN */ - uint8_t hash_keybuf[MAX_IMSI_LEN+MAX_APN_LEN+1]; - int hash_keylen; - ogs_list_t bearer_list; /* Related Context */ @@ -152,7 +149,7 @@ typedef struct pgw_sess_s { } pgw_sess_t; typedef struct pgw_bearer_s { - ogs_lnode_t node; /**< A node of list_t */ + ogs_lnode_t lnode; /**< A node of list_t */ uint32_t index; uint8_t ebi; @@ -202,7 +199,7 @@ ED5(uint8_t ipv4_local:1;, } pgw_rule_t; typedef struct pgw_pf_s { - ogs_lnode_t node; + ogs_lnode_t lnode; ED3(uint8_t spare:2;, uint8_t direction:2;, @@ -228,10 +225,6 @@ int pgw_sess_remove(pgw_sess_t *sess); void pgw_sess_remove_all(); pgw_sess_t *pgw_sess_find(uint32_t index); pgw_sess_t *pgw_sess_find_by_teid(uint32_t teid); -pgw_sess_t *pgw_sess_find_by_imsi_apn(uint8_t *imsi, int imsi_len, char *apn); -ogs_hash_index_t *pgw_sess_first(); -ogs_hash_index_t *pgw_sess_next(ogs_hash_index_t *hi); -pgw_sess_t *pgw_sess_this(ogs_hash_index_t *hi); pgw_bearer_t *pgw_bearer_add(pgw_sess_t *sess); int pgw_bearer_remove(pgw_bearer_t *bearer); diff --git a/src/pgw/pgw-gtp-path.c b/src/pgw/pgw-gtp-path.c index be8d9425f..3ecafe791 100644 --- a/src/pgw/pgw-gtp-path.c +++ b/src/pgw/pgw-gtp-path.c @@ -342,12 +342,10 @@ static int pgw_gtp_handle_multicast(ogs_pkbuf_t *recvbuf) if (IN6_IS_ADDR_MULTICAST(&ip6_dst)) #endif { - ogs_hash_index_t *hi = NULL; + pgw_sess_t *sess = NULL; /* IPv6 Multicast */ - for (hi = pgw_sess_first(); hi; hi = pgw_sess_next(hi)) { - pgw_sess_t *sess = pgw_sess_this(hi); - ogs_assert(sess); + ogs_list_for_each(&pgw_self()->sess_list, sess) { if (sess->ipv6) { /* PDN IPv6 is avaiable */ pgw_bearer_t *bearer = pgw_default_bearer_in_sess(sess); diff --git a/src/pgw/pgw-ipfw.c b/src/pgw/pgw-ipfw.c index f8d7ae2d0..24cc6dd3b 100644 --- a/src/pgw/pgw-ipfw.c +++ b/src/pgw/pgw-ipfw.c @@ -244,7 +244,6 @@ static int decode_ipv6_header( pgw_bearer_t *pgw_bearer_find_by_packet(ogs_pkbuf_t *pkt) { - ogs_hash_index_t *hi = NULL; struct ip *ip_h = NULL; struct ip6_hdr *ip6_h = NULL; uint32_t *src_addr = NULL; @@ -253,6 +252,7 @@ pgw_bearer_t *pgw_bearer_find_by_packet(ogs_pkbuf_t *pkt) uint8_t proto = 0; uint16_t ip_hlen = 0; char buf[OGS_ADDRSTRLEN]; + pgw_sess_t *sess = NULL; ogs_assert(pkt); ogs_assert(pkt->len); @@ -298,11 +298,7 @@ pgw_bearer_t *pgw_bearer_find_by_packet(ogs_pkbuf_t *pkt) * Until be ready, linear searching will be use to find the bearer. */ - for (hi = pgw_sess_first(); hi; hi = pgw_sess_next(hi)) - { - pgw_sess_t *sess = pgw_sess_this(hi); - ogs_assert(sess); - + ogs_list_for_each(&pgw_self()->sess_list, sess) { if (sess->ipv4) ogs_debug("[PGW] PAA IPv4:%s", INET_NTOP(&sess->ipv4->addr, buf)); diff --git a/src/sgw/sgw-context.c b/src/sgw/sgw-context.c index 29cd6ebda..ecc977c58 100644 --- a/src/sgw/sgw-context.c +++ b/src/sgw/sgw-context.c @@ -64,7 +64,7 @@ void sgw_context_init() ogs_pool_init(&sgw_bearer_pool, context_self()->pool.bearer); ogs_pool_init(&sgw_tunnel_pool, context_self()->pool.tunnel); - self.imsi_ue_hash = ogs_hash_make(); + ogs_list_init(&self.sgw_ue_list); context_initialized = 1; } @@ -75,9 +75,6 @@ void sgw_context_final() sgw_ue_remove_all(); - ogs_assert(self.imsi_ue_hash); - ogs_hash_destroy(self.imsi_ue_hash); - ogs_pool_final(&sgw_tunnel_pool); ogs_pool_final(&sgw_bearer_pool); ogs_pool_final(&sgw_sess_pool); @@ -447,11 +444,8 @@ sgw_ue_t *sgw_ue_add_by_message(gtp_message_t *message) ogs_trace("sgw_ue_add_by_message() - IMSI "); ogs_log_hexdump(OGS_LOG_TRACE, req->imsi.data, req->imsi.len); - sgw_ue = sgw_ue_find_by_imsi(req->imsi.data, req->imsi.len); - if (!sgw_ue) { - sgw_ue = sgw_ue_add(req->imsi.data, req->imsi.len); - ogs_assert(sgw_ue); - } + sgw_ue = sgw_ue_add(req->imsi.data, req->imsi.len); + ogs_assert(sgw_ue); return sgw_ue; } @@ -477,7 +471,7 @@ sgw_ue_t *sgw_ue_add(uint8_t *imsi, int imsi_len) ogs_list_init(&sgw_ue->sess_list); - ogs_hash_set(self.imsi_ue_hash, sgw_ue->imsi, sgw_ue->imsi_len, sgw_ue); + ogs_list_add(&self.sgw_ue_list, sgw_ue); return sgw_ue; } @@ -486,10 +480,8 @@ int sgw_ue_remove(sgw_ue_t *sgw_ue) { ogs_assert(sgw_ue); - /* Clear hash table */ - if (sgw_ue->imsi_len != 0) - ogs_hash_set(self.imsi_ue_hash, sgw_ue->imsi, sgw_ue->imsi_len, NULL); - + ogs_list_remove(&self.sgw_ue_list, sgw_ue); + sgw_sess_remove_all(sgw_ue); ogs_pool_free(&sgw_ue_pool, sgw_ue); @@ -499,32 +491,10 @@ int sgw_ue_remove(sgw_ue_t *sgw_ue) void sgw_ue_remove_all() { - ogs_hash_index_t *hi = NULL; - sgw_ue_t *sgw_ue = NULL; + sgw_ue_t *sgw_ue = NULL, *next = NULL;; - for (hi = sgw_ue_first(); hi; hi = sgw_ue_next(hi)) { - sgw_ue = sgw_ue_this(hi); + ogs_list_for_each_safe(&self.sgw_ue_list, next, sgw_ue) sgw_ue_remove(sgw_ue); - } -} - -sgw_ue_t *sgw_ue_find_by_imsi_bcd(char *imsi_bcd) -{ - uint8_t imsi[MAX_IMSI_LEN]; - int imsi_len = 0; - - ogs_assert(imsi_bcd); - - ogs_bcd_to_buffer(imsi_bcd, imsi, &imsi_len); - - return sgw_ue_find_by_imsi(imsi, imsi_len); -} - -sgw_ue_t *sgw_ue_find_by_imsi(uint8_t *imsi, int imsi_len) -{ - ogs_assert(imsi && imsi_len); - - return (sgw_ue_t *)ogs_hash_get(self.imsi_ue_hash, imsi, imsi_len); } sgw_ue_t *sgw_ue_find_by_teid(uint32_t teid) @@ -532,23 +502,6 @@ sgw_ue_t *sgw_ue_find_by_teid(uint32_t teid) return ogs_pool_find(&sgw_ue_pool, teid); } -ogs_hash_index_t *sgw_ue_first() -{ - ogs_assert(self.imsi_ue_hash); - return ogs_hash_first(self.imsi_ue_hash); -} - -ogs_hash_index_t *sgw_ue_next(ogs_hash_index_t *hi) -{ - return ogs_hash_next(hi); -} - -sgw_ue_t *sgw_ue_this(ogs_hash_index_t *hi) -{ - ogs_assert(hi); - return ogs_hash_this_val(hi); -} - sgw_sess_t *sgw_sess_add(sgw_ue_t *sgw_ue, char *apn, uint8_t ebi) { sgw_sess_t *sess = NULL; diff --git a/src/sgw/sgw-context.h b/src/sgw/sgw-context.h index 868ab44a0..625662717 100644 --- a/src/sgw/sgw-context.h +++ b/src/sgw/sgw-context.h @@ -65,10 +65,12 @@ typedef struct sgw_context_s { ogs_list_t enb_s1u_list; /* eNB GTPU Node List */ ogs_list_t pgw_s5u_list; /* PGW GTPU Node List */ - ogs_hash_t *imsi_ue_hash; /* hash table (IMSI : SGW_UE) */ + ogs_list_t sgw_ue_list; /* SGW_UE List */ } sgw_context_t; typedef struct sgw_ue_s { + ogs_lnode_t lnode; + uint32_t sgw_s11_teid; /* SGW-S11-TEID is derived from INDEX */ uint32_t mme_s11_teid; /* MME-S11-TEID is received from MME */ @@ -92,7 +94,7 @@ typedef struct sgw_ue_s { } sgw_ue_t; typedef struct sgw_sess_s { - ogs_lnode_t node; /* A node of list_t */ + ogs_lnode_t lnode; /* A node of list_t */ /* * SGW-S5C-TEID = INDEX | 0x80000000 @@ -115,7 +117,7 @@ typedef struct sgw_sess_s { } sgw_sess_t; typedef struct sgw_bearer_s { - ogs_lnode_t node; /**< A node of list_t */ + ogs_lnode_t lnode; uint8_t ebi; @@ -135,7 +137,7 @@ typedef struct sgw_bearer_s { } sgw_bearer_t; typedef struct sgw_tunnel_s { - ogs_lnode_t node; /**< A node of list_t */ + ogs_lnode_t lnode; uint8_t interface_type; @@ -149,32 +151,23 @@ typedef struct sgw_tunnel_s { void sgw_context_init(void); void sgw_context_final(void); -sgw_context_t* sgw_self(void); +sgw_context_t *sgw_self(void); int sgw_context_parse_config(void); gtp_node_t *sgw_mme_add_by_message(gtp_message_t *message); sgw_ue_t *sgw_ue_add_by_message(gtp_message_t *message); +sgw_ue_t *sgw_ue_find_by_teid(uint32_t teid); sgw_ue_t *sgw_ue_add(uint8_t *imsi, int imsi_len); int sgw_ue_remove(sgw_ue_t *sgw_ue); void sgw_ue_remove_all(); -sgw_ue_t *sgw_ue_find_by_imsi(uint8_t *imsi, int imsi_len); -sgw_ue_t *sgw_ue_find_by_imsi_bcd(char *imsi_bcd); -sgw_ue_t *sgw_ue_find_by_teid(uint32_t teid); - -ogs_hash_index_t *sgw_ue_first(); -ogs_hash_index_t *sgw_ue_next(ogs_hash_index_t *hi); -sgw_ue_t *sgw_ue_this(ogs_hash_index_t *hi); - sgw_sess_t *sgw_sess_add(sgw_ue_t *sgw_ue, char *apn, uint8_t ebi); int sgw_sess_remove(sgw_sess_t *sess); void sgw_sess_remove_all(sgw_ue_t *sgw_ue); -sgw_sess_t *sgw_sess_find_by_apn( - sgw_ue_t *sgw_ue, char *apn); -sgw_sess_t *sgw_sess_find_by_ebi( - sgw_ue_t *sgw_ue, uint8_t ebi); +sgw_sess_t *sgw_sess_find_by_apn(sgw_ue_t *sgw_ue, char *apn); +sgw_sess_t *sgw_sess_find_by_ebi(sgw_ue_t *sgw_ue, uint8_t ebi); sgw_sess_t *sgw_sess_find_by_teid(uint32_t teid); sgw_sess_t *sgw_sess_first(sgw_ue_t *sgw_ue); sgw_sess_t *sgw_sess_next(sgw_sess_t *sess); diff --git a/tests/common/test-packet.c b/tests/common/test-packet.c index 66f4cb42e..e0488ceb6 100644 --- a/tests/common/test-packet.c +++ b/tests/common/test-packet.c @@ -1577,7 +1577,7 @@ int tests1ap_build_ue_context_release_complete(ogs_pkbuf_t **pkbuf, int i) "", /* 21 */ - "2017000f00000200 00400200d1000840 0200d1", + "2017000f00000200 00400200d0000840 0200d0", "", }; uint16_t len[TESTS1AP_MAX_MESSAGE] = {