forked from acouzens/open5gs
Improve GTP-U Performance for many UEs
This commit is contained in:
parent
81856afff9
commit
7c658091c5
|
@ -80,6 +80,8 @@ void pgw_context_init(void)
|
|||
ogs_pool_init(&pgw_pf_pool, ogs_config()->pool.pf);
|
||||
|
||||
self.sess_hash = ogs_hash_make();
|
||||
self.ipv4_hash = ogs_hash_make();
|
||||
self.ipv6_hash = ogs_hash_make();
|
||||
|
||||
ogs_list_init(&self.sess_list);
|
||||
|
||||
|
@ -97,6 +99,10 @@ void pgw_context_final(void)
|
|||
|
||||
ogs_assert(self.sess_hash);
|
||||
ogs_hash_destroy(self.sess_hash);
|
||||
ogs_assert(self.ipv4_hash);
|
||||
ogs_hash_destroy(self.ipv4_hash);
|
||||
ogs_assert(self.ipv6_hash);
|
||||
ogs_hash_destroy(self.ipv6_hash);
|
||||
|
||||
ogs_pool_final(&pgw_bearer_pool);
|
||||
ogs_pool_final(&pgw_sess_pool);
|
||||
|
@ -814,6 +820,7 @@ pgw_sess_t *pgw_sess_add(
|
|||
sess->ipv4 = pgw_ue_ip_alloc(AF_INET, apn, (uint8_t *)&(paa->addr));
|
||||
ogs_assert(sess->ipv4);
|
||||
sess->pdn.paa.addr = sess->ipv4->addr[0];
|
||||
ogs_hash_set(self.ipv4_hash, sess->ipv4->addr, OGS_IPV4_LEN, sess);
|
||||
} else if (pdn_type == OGS_GTP_PDN_TYPE_IPV6) {
|
||||
sess->ipv6 = pgw_ue_ip_alloc(AF_INET6, apn, (paa->addr6));
|
||||
ogs_assert(sess->ipv6);
|
||||
|
@ -823,6 +830,7 @@ pgw_sess_t *pgw_sess_add(
|
|||
|
||||
sess->pdn.paa.len = subnet6->prefixlen;
|
||||
memcpy(sess->pdn.paa.addr6, sess->ipv6->addr, OGS_IPV6_LEN);
|
||||
ogs_hash_set(self.ipv6_hash, sess->ipv6->addr, OGS_IPV6_LEN, sess);
|
||||
} else if (pdn_type == OGS_GTP_PDN_TYPE_IPV4V6) {
|
||||
sess->ipv4 = pgw_ue_ip_alloc(AF_INET, apn, (uint8_t *)&(paa->both.addr));
|
||||
ogs_assert(sess->ipv4);
|
||||
|
@ -835,6 +843,8 @@ pgw_sess_t *pgw_sess_add(
|
|||
sess->pdn.paa.both.addr = sess->ipv4->addr[0];
|
||||
sess->pdn.paa.both.len = subnet6->prefixlen;
|
||||
memcpy(sess->pdn.paa.both.addr6, sess->ipv6->addr, OGS_IPV6_LEN);
|
||||
ogs_hash_set(self.ipv4_hash, sess->ipv4->addr, OGS_IPV4_LEN, sess);
|
||||
ogs_hash_set(self.ipv6_hash, sess->ipv6->addr, OGS_IPV6_LEN, sess);
|
||||
} else
|
||||
ogs_assert_if_reached();
|
||||
|
||||
|
@ -864,10 +874,14 @@ int pgw_sess_remove(pgw_sess_t *sess)
|
|||
|
||||
ogs_hash_set(self.sess_hash, sess->hash_keybuf, sess->hash_keylen, NULL);
|
||||
|
||||
if (sess->ipv4)
|
||||
if (sess->ipv4) {
|
||||
ogs_hash_set(self.ipv4_hash, sess->ipv4->addr, OGS_IPV4_LEN, NULL);
|
||||
pgw_ue_ip_free(sess->ipv4);
|
||||
if (sess->ipv6)
|
||||
}
|
||||
if (sess->ipv6) {
|
||||
ogs_hash_set(self.ipv6_hash, sess->ipv6->addr, OGS_IPV6_LEN, NULL);
|
||||
pgw_ue_ip_free(sess->ipv6);
|
||||
}
|
||||
|
||||
pgw_bearer_remove_all(sess);
|
||||
|
||||
|
@ -909,6 +923,19 @@ pgw_sess_t *pgw_sess_find_by_imsi_apn(
|
|||
return (pgw_sess_t *)ogs_hash_get(self.sess_hash, keybuf, keylen);
|
||||
}
|
||||
|
||||
pgw_sess_t *pgw_sess_find_by_ipv4(uint32_t addr)
|
||||
{
|
||||
ogs_assert(self.ipv4_hash);
|
||||
return (pgw_sess_t *)ogs_hash_get(self.ipv4_hash, &addr, OGS_IPV4_LEN);
|
||||
}
|
||||
|
||||
pgw_sess_t *pgw_sess_find_by_ipv6(uint32_t *addr6)
|
||||
{
|
||||
ogs_assert(self.ipv6_hash);
|
||||
ogs_assert(addr6);
|
||||
return (pgw_sess_t *)ogs_hash_get(self.ipv6_hash, addr6, OGS_IPV6_LEN);
|
||||
}
|
||||
|
||||
pgw_sess_t *pgw_sess_add_by_message(ogs_gtp_message_t *message)
|
||||
{
|
||||
pgw_sess_t *sess = NULL;
|
||||
|
|
|
@ -88,6 +88,8 @@ typedef struct pgw_context_s {
|
|||
ogs_list_t ip_pool_list;
|
||||
|
||||
ogs_hash_t *sess_hash; /* hash table (IMSI+APN) */
|
||||
ogs_hash_t *ipv4_hash; /* hash table (IPv4 Address) */
|
||||
ogs_hash_t *ipv6_hash; /* hash table (IPv6 Address) */
|
||||
|
||||
ogs_list_t sess_list;
|
||||
} pgw_context_t;
|
||||
|
@ -246,6 +248,8 @@ void pgw_sess_remove_all(void);
|
|||
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);
|
||||
pgw_sess_t *pgw_sess_find_by_ipv4(uint32_t addr);
|
||||
pgw_sess_t *pgw_sess_find_by_ipv6(uint32_t *addr6);
|
||||
|
||||
pgw_bearer_t *pgw_bearer_add(pgw_sess_t *sess);
|
||||
int pgw_bearer_remove(pgw_bearer_t *bearer);
|
||||
|
|
|
@ -261,7 +261,9 @@ pgw_bearer_t *pgw_bearer_find_by_packet(ogs_pkbuf_t *pkt)
|
|||
|
||||
src_addr = &ip_h->ip_src.s_addr;
|
||||
dst_addr = &ip_h->ip_dst.s_addr;
|
||||
addr_len = 4;
|
||||
addr_len = OGS_IPV4_LEN;
|
||||
|
||||
sess = pgw_sess_find_by_ipv4(dst_addr[0]);
|
||||
} else if (ip_h->ip_v == 6) {
|
||||
ip_h = NULL;
|
||||
ip6_h = (struct ip6_hdr *)pkt->data;
|
||||
|
@ -270,8 +272,9 @@ pgw_bearer_t *pgw_bearer_find_by_packet(ogs_pkbuf_t *pkt)
|
|||
|
||||
src_addr = (uint32_t *)ip6_h->ip6_src.s6_addr;
|
||||
dst_addr = (uint32_t *)ip6_h->ip6_dst.s6_addr;
|
||||
addr_len = 16;
|
||||
addr_len = OGS_IPV6_LEN;
|
||||
|
||||
sess = pgw_sess_find_by_ipv6(dst_addr);
|
||||
} else
|
||||
ogs_error("Invalid IP version = %d", ip_h->ip_v);
|
||||
|
||||
|
@ -282,25 +285,17 @@ pgw_bearer_t *pgw_bearer_find_by_packet(ogs_pkbuf_t *pkt)
|
|||
ip_hlen, ntohl(dst_addr[0]), ntohl(dst_addr[1]),
|
||||
ntohl(dst_addr[2]), ntohl(dst_addr[3]));
|
||||
|
||||
|
||||
/* TODO: Need to use the method of FAST matching algorithm and
|
||||
* implementation .
|
||||
* Until be ready, linear searching will be use to find the bearer.
|
||||
*/
|
||||
|
||||
ogs_list_for_each(&pgw_self()->sess_list, sess) {
|
||||
if (sess->ipv4)
|
||||
ogs_debug("[PGW] PAA IPv4:%s",
|
||||
INET_NTOP(&sess->ipv4->addr, buf));
|
||||
if (sess->ipv6)
|
||||
ogs_debug("[PGW] PAA IPv6:%s",
|
||||
INET6_NTOP(&sess->ipv6->addr, buf));
|
||||
|
||||
if ((sess->ipv4 && memcmp(dst_addr, sess->ipv4->addr, addr_len) == 0) ||
|
||||
(sess->ipv6 && memcmp(dst_addr, sess->ipv6->addr, addr_len) == 0)) {
|
||||
if (sess) {
|
||||
pgw_bearer_t *default_bearer = NULL;
|
||||
pgw_bearer_t *bearer = NULL;
|
||||
|
||||
if (ip_h && sess->ipv4)
|
||||
ogs_debug("[PGW] PAA IPv4:%s",
|
||||
INET_NTOP(&sess->ipv4->addr, buf));
|
||||
if (ip6_h && sess->ipv6)
|
||||
ogs_debug("[PGW] PAA IPv6:%s",
|
||||
INET6_NTOP(&sess->ipv6->addr, buf));
|
||||
|
||||
/* Save the default bearer */
|
||||
default_bearer = pgw_default_bearer_in_sess(sess);
|
||||
ogs_assert(default_bearer);
|
||||
|
@ -438,10 +433,8 @@ pgw_bearer_t *pgw_bearer_find_by_packet(ogs_pkbuf_t *pkt)
|
|||
/* No need to match port */
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (pf) {
|
||||
|
@ -449,11 +442,11 @@ pgw_bearer_t *pgw_bearer_find_by_packet(ogs_pkbuf_t *pkt)
|
|||
ogs_debug("Found Dedicated Bearer : EBI[%d]", bearer->ebi);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return (bearer ? bearer : default_bearer);
|
||||
}
|
||||
} else {
|
||||
ogs_debug("[PGW] No Session");
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
|
|
@ -266,7 +266,7 @@ static void attach_test1(abts_case *tc, void *data)
|
|||
ABTS_PTR_NOTNULL(tc, recvbuf);
|
||||
ogs_pkbuf_free(recvbuf);
|
||||
|
||||
#if LINUX == 1
|
||||
#if __linux__
|
||||
rv = testgtpu_build_ping(&sendbuf, "cafe::2", "cafe::1");
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
rv = testenb_gtpu_send(gtpu, sendbuf);
|
||||
|
|
Loading…
Reference in New Issue