new pool structure is implemented for supporting IPv6 and APN

This commit is contained in:
Sukchan Lee 2017-12-13 11:14:00 +09:00
parent 54636e1843
commit 2f407de0d4
2 changed files with 72 additions and 92 deletions

View File

@ -32,19 +32,11 @@ typedef struct _ue_pool_t {
int head, tail;
int size, avail;
mutex_id mut;
pgw_ip_t *free[MAX_POOL_OF_SESS], pool[MAX_POOL_OF_SESS];
pgw_ue_ip_t *free[MAX_POOL_OF_SESS], pool[MAX_POOL_OF_SESS];
} ue_pool_t;
typedef struct _ue_pool6_t {
int head, tail;
int size, avail;
mutex_id mut;
pgw_ip_t *free[MAX_POOL_OF_SESS], pool[MAX_POOL_OF_SESS];
} ue_pool6_t;
#define INVALID_POOL_INDEX MAX_NUM_OF_UE_POOL
static ue_pool_t ue_pool[MAX_NUM_OF_UE_POOL];
static ue_pool6_t ue_pool6[MAX_NUM_OF_UE_POOL];
static int context_initiaized = 0;
@ -73,10 +65,7 @@ status_t pgw_context_init()
pool_init(&pgw_pf_pool, MAX_POOL_OF_PF);
for (i = 0; i < MAX_NUM_OF_UE_POOL; i++)
{
pool_init(&ue_pool[i], MAX_POOL_OF_UE);
pool_init(&ue_pool6[i], MAX_POOL_OF_UE);
}
self.sess_hash = hash_make();
@ -120,8 +109,17 @@ status_t pgw_context_final()
for (i = 0; i < MAX_NUM_OF_UE_POOL; i++)
{
if (index_size(&ue_pool[i]) != pool_avail(&ue_pool[i]))
{
d_warn("[%d] %d not freed in ue_pool[%d] in PGW-Context",
i, index_size(&ue_pool[i]) - pool_avail(&ue_pool[i]),
index_size(&ue_pool[i]));
}
d_trace(3, "[%d] %d not freed in ue_pool[%d] in PGW-Context\n",
i, index_size(&ue_pool[i]) - pool_avail(&ue_pool[i]),
index_size(&ue_pool[i]));
pool_final(&ue_pool[i]);
pool_final(&ue_pool6[i]);
}
index_final(&pgw_bearer_pool);
@ -152,8 +150,6 @@ static status_t pgw_context_prepare()
self.gtpu_port = GTPV1_U_UDP_PORT;
self.tun_ifname = "pgwtun";
self.default_ue_pool_index = INVALID_POOL_INDEX;
self.default_ue_pool6_index = INVALID_POOL_INDEX;
return CORE_OK;
}
@ -1532,13 +1528,13 @@ status_t pgw_ue_pool_generate()
{
status_t rv;
int i, j;
int pool_index = 0;
for (i = 0; i < self.num_of_ue_pool; i++)
{
int pool_index = 0;
ipsubnet_t ipaddr, ipsub;
c_uint32_t bits;
c_uint32_t count;
c_uint32_t mask_count;
c_uint32_t broadcast[4];
rv = core_ipsubnet(&ipaddr, self.ue_pool[i].ipstr, NULL);
@ -1553,20 +1549,20 @@ status_t pgw_ue_pool_generate()
if (ipsub.family == AF_INET)
{
if (bits == 32)
count = 1;
mask_count = 1;
else if (bits < 32)
count = (0xffffffff >> bits) + 1;
mask_count = (0xffffffff >> bits) + 1;
else
d_assert(0, return CORE_ERROR,);
}
else if (ipsub.family == AF_INET6)
{
if (bits == 128)
count = 1;
mask_count = 1;
else if (bits > 96 && bits < 128)
count = (0xffffffff >> (bits - 96)) + 1;
mask_count = (0xffffffff >> (bits - 96)) + 1;
else if (bits <= 96)
count = 0xffffffff;
mask_count = 0xffffffff;
else
d_assert(0, return CORE_ERROR,);
}
@ -1580,31 +1576,43 @@ status_t pgw_ue_pool_generate()
broadcast[j] = ipsub.sub[j] + ~ipsub.mask[j];
}
for (j = 0; j < count && pool_index < MAX_POOL_OF_SESS; j++)
for (j = 0; j < mask_count && pool_index < MAX_POOL_OF_SESS; j++)
{
pgw_ue_ip_t *ue_ip = NULL;
int maxbytes = 0;
int lastindex = 0;
ue_ip = &ue_pool[i].pool[pool_index];
d_assert(ue_ip, return CORE_ERROR,);
memset(ue_ip, 0, sizeof *ue_ip);
if (ipsub.family == AF_INET)
{
pgw_ip_t *ip = &ue_pool[i].pool[pool_index];
ip->addr = ipaddr.sub[0] + htonl(j);
/* Exclude Network Address */
if (ip->addr == ipsub.sub[0]) continue;
/* Exclude Broadcast Address */
if (ip->addr == broadcast[0]) continue;
/* Exclude TUN IP Address */
if (ip->addr == ipaddr.sub[0]) continue;
maxbytes = 4;
lastindex = 0;
}
else if (ipsub.family == AF_INET6)
{
maxbytes = 16;
lastindex = 3;
}
else
d_assert(0, return CORE_ERROR,);
memcpy(ue_ip->addr, ipsub.sub, maxbytes);
ue_ip->addr[lastindex] += htonl(j);
/* Exclude Network Address */
if (memcmp(ue_ip->addr, ipsub.sub, maxbytes) == 0) continue;
/* Exclude Broadcast Address */
if (memcmp(ue_ip->addr, broadcast, maxbytes) == 0) continue;
/* Exclude TUN IP Address */
if (memcmp(ue_ip->addr, ipaddr.sub, maxbytes) == 0) continue;
pool_index++;
}
}
return CORE_OK;
}
@ -1632,10 +1640,17 @@ static c_uint8_t find_ue_pool_index(int family, const char *apn)
if (pool_index == INVALID_POOL_INDEX)
{
if (family == AF_INET)
pool_index = self.default_ue_pool_index;
else if (family == AF_INET6)
pool_index = self.default_ue_pool6_index;
for (i = 0; i < self.num_of_ue_pool; i++)
{
if (self.ue_pool[i].apn == NULL)
{
if (self.ue_pool[i].family == family)
{
pool_index = i;
break;
}
}
}
}
if (pool_index == INVALID_POOL_INDEX)
@ -1647,59 +1662,32 @@ static c_uint8_t find_ue_pool_index(int family, const char *apn)
return pool_index;
}
pgw_ip_t *pgw_addr_alloc(const char *apn)
pgw_ue_ip_t *pgw_ue_ip_alloc(int family, const char *apn)
{
c_uint8_t pool_index = INVALID_POOL_INDEX;
pgw_ip_t *ip = NULL;
pgw_ue_ip_t *ue_ip = NULL;
d_assert(apn, return NULL,);
pool_index = find_ue_pool_index(AF_INET, apn);
pool_index = find_ue_pool_index(family, apn);
d_assert(pool_index < MAX_NUM_OF_UE_POOL, return NULL,);
pool_alloc_node(&ue_pool[pool_index], &ip);
d_assert(ip, return NULL,);
memset(ip, 0, sizeof *ip);
ip->ipv4 = 1;
ip->index = pool_index;
pool_alloc_node(&ue_pool[pool_index], &ue_ip);
d_assert(ue_ip, return NULL,);
ue_ip->index = pool_index;
return ip;
return ue_ip;
}
pgw_ip_t *pgw_addr6_alloc(const char *apn)
{
c_uint8_t pool_index = INVALID_POOL_INDEX;
pgw_ip_t *ip = NULL;
d_assert(apn, return NULL,);
pool_index = find_ue_pool_index(AF_INET6, apn);
d_assert(pool_index < MAX_NUM_OF_UE_POOL, return NULL,);
pool_alloc_node(&ue_pool6[pool_index], &ip);
d_assert(ip, return NULL,);
memset(ip, 0, sizeof *ip);
ip->ipv6 = 1;
ip->index = pool_index;
return ip;
}
status_t pgw_addr_free(pgw_ip_t *ip)
status_t pgw_ue_ip_free(pgw_ue_ip_t *ue_ip)
{
c_uint8_t pool_index;
d_assert(ip, return CORE_ERROR,);
pool_index = ip->index;
d_assert(ue_ip, return CORE_ERROR,);
pool_index = ue_ip->index;
d_assert(pool_index < MAX_NUM_OF_UE_POOL, return CORE_ERROR,);
if (ip->ipv4 && ip->ipv6 == 0)
pool_free_node(&ue_pool[pool_index], ip);
else if (ip->ipv6 && ip->ipv4 == 0)
pool_free_node(&ue_pool6[pool_index], ip);
else
d_assert(0, return CORE_ERROR,);
pool_free_node(&ue_pool[pool_index], ue_ip);
return CORE_OK;
}

View File

@ -49,8 +49,6 @@ typedef struct _pgw_context_t {
int family; /* AF_INET or AF_INET6 */
} ue_pool[MAX_NUM_OF_UE_POOL];
c_uint8_t num_of_ue_pool;
c_uint8_t default_ue_pool_index; /* IPv4 Default Pool Index */
c_uint8_t default_ue_pool6_index; /* IPv6 Default Pool Index */
struct {
sock_id tun_link; /* PGW Tun Interace for U-plane */
@ -80,15 +78,10 @@ typedef struct _pgw_ip_pool_t {
c_uint32_t ue_addr;
} pgw_ip_pool_t;
typedef struct _pgw_ip_t {
ED3(c_uint8_t ipv4:1;,
c_uint8_t ipv6:1;,
c_uint8_t index:6;)
union {
c_uint32_t addr;
c_uint32_t addr6[4];
};
} pgw_ip_t;
typedef struct _pgw_ue_ip_t {
c_uint8_t index; /* Pool index */
c_uint32_t addr[4];
} pgw_ue_ip_t;
typedef struct _pgw_sess_t {
lnode_t node; /**< A node of list_t */
@ -231,9 +224,8 @@ CORE_DECLARE(pgw_ip_pool_t*) pgw_ip_pool_alloc();
CORE_DECLARE(status_t ) pgw_ip_pool_free(pgw_ip_pool_t *ip_pool);
CORE_DECLARE(status_t ) pgw_ue_pool_generate();
CORE_DECLARE(pgw_ip_t *) pgw_addr_alloc(const char *apn);
CORE_DECLARE(pgw_ip_t *) pgw_addr6_alloc(const char *apn);
CORE_DECLARE(status_t) pgw_addr_free(pgw_ip_t *ip);
CORE_DECLARE(pgw_ue_ip_t *) pgw_ue_ip_alloc(int family, const char *apn);
CORE_DECLARE(status_t) pgw_ue_ip_free(pgw_ue_ip_t *ip);
#ifdef __cplusplus
}