forked from acouzens/open5gs
Create Multiple Session for same IMSI (#203)
This commit is contained in:
parent
16fdc0d989
commit
de8ae9823a
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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] = {
|
||||
|
|
Loading…
Reference in New Issue