mirror of
https://github.com/open5gs/open5gs.git
synced 2025-11-02 13:03:31 +00:00
pgw dev/subnet context is added
This commit is contained in:
@@ -22,6 +22,9 @@
|
|||||||
|
|
||||||
static pgw_context_t self;
|
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_sess_pool, pgw_sess_t, MAX_POOL_OF_SESS);
|
||||||
index_declare(pgw_bearer_pool, pgw_bearer_t, MAX_POOL_OF_BEARER);
|
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_s5c_list);
|
||||||
list_init(&self.sgw_s5u_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_sess_pool, MAX_POOL_OF_SESS);
|
||||||
index_init(&pgw_bearer_pool, MAX_POOL_OF_BEARER);
|
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",
|
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));
|
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++)
|
for (i = 0; i < MAX_NUM_OF_UE_POOL; i++)
|
||||||
{
|
{
|
||||||
if (pool_used(&ue_ip_pool[i]))
|
if (pool_used(&ue_ip_pool[i]))
|
||||||
@@ -105,8 +111,15 @@ status_t pgw_context_final()
|
|||||||
pool_final(&ue_ip_pool[i]);
|
pool_final(&ue_ip_pool[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pgw_dev_remove_all();
|
||||||
|
pgw_subnet_remove_all();
|
||||||
|
|
||||||
index_final(&pgw_bearer_pool);
|
index_final(&pgw_bearer_pool);
|
||||||
index_final(&pgw_sess_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_s5c_list);
|
||||||
gtp_remove_all_nodes(&self.sgw_s5u_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);
|
yaml_iter_recurse(&pgw_iter, &ue_pool_array);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
pgw_subnet_t *subnet = NULL;
|
||||||
const char *ipstr = NULL;
|
const char *ipstr = NULL;
|
||||||
const char *mask_or_numbits = NULL;
|
const char *mask_or_numbits = NULL;
|
||||||
const char *apn = NULL;
|
const char *apn = NULL;
|
||||||
|
const char *dev = self.tun_ifname;
|
||||||
|
|
||||||
d_assert(self.num_of_ue_pool <=
|
d_assert(self.num_of_ue_pool <=
|
||||||
MAX_NUM_OF_UE_POOL, return CORE_ERROR,);
|
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);
|
apn = yaml_iter_value(&ue_pool_iter);
|
||||||
}
|
}
|
||||||
|
else if (!strcmp(ue_pool_key, "dev"))
|
||||||
|
{
|
||||||
|
dev = yaml_iter_value(&ue_pool_iter);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
d_warn("unknown key `%s`", ue_pool_key);
|
d_warn("unknown key `%s`", ue_pool_key);
|
||||||
}
|
}
|
||||||
@@ -561,6 +580,10 @@ status_t pgw_context_parse_config()
|
|||||||
mask_or_numbits;
|
mask_or_numbits;
|
||||||
self.ue_pool[self.num_of_ue_pool].apn = apn;
|
self.ue_pool[self.num_of_ue_pool].apn = apn;
|
||||||
self.num_of_ue_pool++;
|
self.num_of_ue_pool++;
|
||||||
|
|
||||||
|
subnet = pgw_subnet_add(
|
||||||
|
ipstr, mask_or_numbits, apn, dev);
|
||||||
|
d_assert(subnet, return CORE_ERROR,);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1310,3 +1333,147 @@ c_uint8_t pgw_ue_ip_prefixlen(pgw_ue_ip_t *ue_ip)
|
|||||||
return CORE_ERROR,);
|
return CORE_ERROR,);
|
||||||
return atoi(pgw_self()->ue_pool[index].mask_or_numbits);
|
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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,6 +16,9 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
#define MAX_NUM_OF_DEV 16
|
||||||
|
#define MAX_NUM_OF_SUBNET 16
|
||||||
|
|
||||||
typedef struct _gtp_node_t gtp_node_t;
|
typedef struct _gtp_node_t gtp_node_t;
|
||||||
|
|
||||||
typedef struct _pgw_context_t {
|
typedef struct _pgw_context_t {
|
||||||
@@ -32,6 +35,9 @@ typedef struct _pgw_context_t {
|
|||||||
list_t gtpu_list6; /* PGW GTPU IPv6 Server List */
|
list_t gtpu_list6; /* PGW GTPU IPv6 Server List */
|
||||||
c_sockaddr_t *gtpu_addr6; /* PGW GTPU IPv6 Address */
|
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 */
|
const char* fd_conf_path; /* PGW freeDiameter conf path */
|
||||||
|
|
||||||
msgq_id queue_id; /* Qsesssess for processing PGW control plane */
|
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) */
|
hash_t *sess_hash; /* hash table (IMSI+APN) */
|
||||||
} pgw_context_t;
|
} pgw_context_t;
|
||||||
|
|
||||||
typedef struct _pgw_ip_pool_t {
|
typedef struct _pgw_dev_t {
|
||||||
lnode_t node; /**< A node of list_t */
|
lnode_t node;
|
||||||
|
|
||||||
c_uint32_t ue_addr;
|
c_int8_t ifname[IFNAMSIZ];
|
||||||
} pgw_ip_pool_t;
|
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 {
|
typedef struct _pgw_ue_ip_t {
|
||||||
c_uint8_t index; /* Pool index */
|
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(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(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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|||||||
Reference in New Issue
Block a user