pgw dev/subnet context is added

This commit is contained in:
Sukchan Lee 2017-12-17 04:33:12 +00:00
parent f0f5a5ce31
commit 0cf2319b9c
2 changed files with 208 additions and 6 deletions

View File

@ -22,6 +22,9 @@
static pgw_context_t self;
pool_declare(pgw_dev_pool, pgw_dev_t, MAX_NUM_OF_DEV);
pool_declare(pgw_subnet_pool, pgw_subnet_t, MAX_NUM_OF_SUBNET);
index_declare(pgw_sess_pool, pgw_sess_t, MAX_POOL_OF_SESS);
index_declare(pgw_bearer_pool, pgw_bearer_t, MAX_POOL_OF_BEARER);
@ -57,6 +60,11 @@ status_t pgw_context_init()
list_init(&self.sgw_s5c_list);
list_init(&self.sgw_s5u_list);
list_init(&self.dev_list);
pool_init(&pgw_dev_pool, MAX_NUM_OF_DEV);
list_init(&self.subnet_list);
pool_init(&pgw_subnet_pool, MAX_NUM_OF_SUBNET);
index_init(&pgw_sess_pool, MAX_POOL_OF_SESS);
index_init(&pgw_bearer_pool, MAX_POOL_OF_BEARER);
@ -90,8 +98,6 @@ status_t pgw_context_final()
d_trace(3, "%d not freed in pgw_sess_pool[%d] in PGW-Context\n",
index_used(&pgw_sess_pool), index_size(&pgw_sess_pool));
pool_final(&pgw_pf_pool);
for (i = 0; i < MAX_NUM_OF_UE_POOL; i++)
{
if (pool_used(&ue_ip_pool[i]))
@ -105,8 +111,15 @@ status_t pgw_context_final()
pool_final(&ue_ip_pool[i]);
}
pgw_dev_remove_all();
pgw_subnet_remove_all();
index_final(&pgw_bearer_pool);
index_final(&pgw_sess_pool);
pool_final(&pgw_pf_pool);
pool_final(&pgw_dev_pool);
pool_final(&pgw_subnet_pool);
gtp_remove_all_nodes(&self.sgw_s5c_list);
gtp_remove_all_nodes(&self.sgw_s5u_list);
@ -499,9 +512,11 @@ status_t pgw_context_parse_config()
yaml_iter_recurse(&pgw_iter, &ue_pool_array);
do
{
pgw_subnet_t *subnet = NULL;
const char *ipstr = NULL;
const char *mask_or_numbits = NULL;
const char *apn = NULL;
const char *dev = self.tun_ifname;
d_assert(self.num_of_ue_pool <=
MAX_NUM_OF_UE_POOL, return CORE_ERROR,);
@ -550,6 +565,10 @@ status_t pgw_context_parse_config()
{
apn = yaml_iter_value(&ue_pool_iter);
}
else if (!strcmp(ue_pool_key, "dev"))
{
dev = yaml_iter_value(&ue_pool_iter);
}
else
d_warn("unknown key `%s`", ue_pool_key);
}
@ -561,6 +580,10 @@ status_t pgw_context_parse_config()
mask_or_numbits;
self.ue_pool[self.num_of_ue_pool].apn = apn;
self.num_of_ue_pool++;
subnet = pgw_subnet_add(
ipstr, mask_or_numbits, apn, dev);
d_assert(subnet, return CORE_ERROR,);
}
else
{
@ -1310,3 +1333,147 @@ c_uint8_t pgw_ue_ip_prefixlen(pgw_ue_ip_t *ue_ip)
return CORE_ERROR,);
return atoi(pgw_self()->ue_pool[index].mask_or_numbits);
}
pgw_dev_t *pgw_dev_add(const char *ifname)
{
pgw_dev_t *dev = NULL;
d_assert(ifname, return NULL,);
pool_alloc_node(&pgw_dev_pool, &dev);
d_assert(dev, return NULL,);
memset(dev, 0, sizeof *dev);
strcpy(dev->ifname, ifname);
list_append(&self.dev_list, dev);
return dev;
}
status_t pgw_dev_remove(pgw_dev_t *dev)
{
d_assert(dev, return CORE_ERROR, "Null param");
list_remove(&self.dev_list, dev);
pool_free_node(&pgw_dev_pool, dev);
return CORE_OK;
}
status_t pgw_dev_remove_all()
{
pgw_dev_t *dev = NULL, *next_dev = NULL;
dev = pgw_dev_first();
while (dev)
{
next_dev = pgw_dev_next(dev);
pgw_dev_remove(dev);
dev = next_dev;
}
return CORE_OK;
}
pgw_dev_t* pgw_dev_find_by_ifname(const char *ifname)
{
pgw_dev_t *dev = NULL;
d_assert(ifname, return NULL,);
dev = pgw_dev_first();
while (dev)
{
if (strcmp(dev->ifname, ifname) == 0)
return dev;
dev = pgw_dev_next(dev);
}
return CORE_OK;
}
pgw_dev_t* pgw_dev_first()
{
return list_first(&self.dev_list);
}
pgw_dev_t* pgw_dev_next(pgw_dev_t *dev)
{
return list_next(dev);
}
pgw_subnet_t *pgw_subnet_add(
const char *ipstr, const char *mask_or_numbits,
const char *apn, const char *ifname)
{
status_t rv;
pgw_dev_t *dev = NULL;
pgw_subnet_t *subnet = NULL;
d_assert(ipstr, return NULL,);
d_assert(mask_or_numbits, return NULL,);
d_assert(ifname, return NULL,);
dev = pgw_dev_find_by_ifname(ifname);
if (!dev)
dev = pgw_dev_add(ifname);
d_assert(dev, return NULL,);
pool_alloc_node(&pgw_subnet_pool, &subnet);
d_assert(subnet, return NULL,);
memset(subnet, 0, sizeof *subnet);
rv = core_ipsubnet(&subnet->gw, ipstr, NULL);
d_assert(rv == CORE_OK, return NULL,);
rv = core_ipsubnet(&subnet->sub, ipstr, mask_or_numbits);
d_assert(rv == CORE_OK, return NULL,);
if (apn)
strcpy(subnet->apn, apn);
list_append(&self.subnet_list, subnet);
return subnet;
}
status_t pgw_subnet_remove(pgw_subnet_t *subnet)
{
d_assert(subnet, return CORE_ERROR, "Null param");
list_remove(&self.subnet_list, subnet);
pool_free_node(&pgw_subnet_pool, subnet);
return CORE_OK;
}
status_t pgw_subnet_remove_all()
{
pgw_subnet_t *subnet = NULL, *next_subnet = NULL;
subnet = pgw_subnet_first();
while (subnet)
{
next_subnet = pgw_subnet_next(subnet);
pgw_subnet_remove(subnet);
subnet = next_subnet;
}
return CORE_OK;
}
pgw_subnet_t* pgw_subnet_first()
{
return list_first(&self.subnet_list);
}
pgw_subnet_t* pgw_subnet_next(pgw_subnet_t *subnet)
{
return list_next(subnet);
}

View File

@ -16,6 +16,9 @@
extern "C" {
#endif /* __cplusplus */
#define MAX_NUM_OF_DEV 16
#define MAX_NUM_OF_SUBNET 16
typedef struct _gtp_node_t gtp_node_t;
typedef struct _pgw_context_t {
@ -32,6 +35,9 @@ typedef struct _pgw_context_t {
list_t gtpu_list6; /* PGW GTPU IPv6 Server List */
c_sockaddr_t *gtpu_addr6; /* PGW GTPU IPv6 Address */
list_t dev_list; /* PGW Tun Device List */
list_t subnet_list; /* PGW UE Subnet List */
const char* fd_conf_path; /* PGW freeDiameter conf path */
msgq_id queue_id; /* Qsesssess for processing PGW control plane */
@ -64,11 +70,25 @@ typedef struct _pgw_context_t {
hash_t *sess_hash; /* hash table (IMSI+APN) */
} pgw_context_t;
typedef struct _pgw_ip_pool_t {
lnode_t node; /**< A node of list_t */
typedef struct _pgw_dev_t {
lnode_t node;
c_uint32_t ue_addr;
} pgw_ip_pool_t;
c_int8_t ifname[IFNAMSIZ];
sock_id sock;
c_uint8_t link_local_addr[IPV6_LEN];
} pgw_dev_t;
typedef struct _pgw_subnet_t {
lnode_t node;
ipsubnet_t sub; /* Subnet : cafe::0/64 */
ipsubnet_t gw; /* Gateway : cafe::1 */
c_int8_t apn[MAX_APN_LEN]; /* APN : "internet", "volte", .. */
int family; /* AF_INET or AF_INET6 */
pgw_dev_t *dev;
} pgw_subnet_t;
typedef struct _pgw_ue_ip_t {
c_uint8_t index; /* Pool index */
@ -223,6 +243,21 @@ 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);
CORE_DECLARE(c_uint8_t) pgw_ue_ip_prefixlen(pgw_ue_ip_t *ue_ip);
CORE_DECLARE(pgw_dev_t*) pgw_dev_add(const char *ifname);
CORE_DECLARE(status_t ) pgw_dev_remove(pgw_dev_t *dev);
CORE_DECLARE(status_t ) pgw_dev_remove_all();
CORE_DECLARE(pgw_dev_t*) pgw_dev_find_by_ifname(const char *ifname);
CORE_DECLARE(pgw_dev_t*) pgw_dev_first();
CORE_DECLARE(pgw_dev_t*) pgw_dev_next(pgw_dev_t *dev);
CORE_DECLARE(pgw_subnet_t*) pgw_subnet_add(
const char *ipstr, const char *mask_or_numbits,
const char *apn, const char *ifname);
CORE_DECLARE(status_t ) pgw_subnet_remove(pgw_subnet_t *subnet);
CORE_DECLARE(status_t ) pgw_subnet_remove_all();
CORE_DECLARE(pgw_subnet_t*) pgw_subnet_first();
CORE_DECLARE(pgw_subnet_t*) pgw_subnet_next(pgw_subnet_t *subnet);
#ifdef __cplusplus
}
#endif /* __cplusplus */