Create Multiple Session for same IMSI (#203)

This commit is contained in:
Sukchan Lee 2019-06-30 12:46:02 +09:00
parent 16fdc0d989
commit de8ae9823a
8 changed files with 40 additions and 159 deletions

View File

@ -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 */

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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));

View File

@ -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;

View File

@ -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);

View File

@ -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] = {