From 60804c79d6991a5d75059aa0ea9fb4f105dd5626 Mon Sep 17 00:00:00 2001 From: Sukchan Lee Date: Sun, 17 Dec 2017 05:50:24 +0000 Subject: [PATCH] subnet is tested --- src/pgw/pgw_context.c | 179 +++++++++++++++-------------------------- src/pgw/pgw_context.h | 42 +++++----- src/pgw/pgw_gtp_path.c | 4 + 3 files changed, 91 insertions(+), 134 deletions(-) diff --git a/src/pgw/pgw_context.c b/src/pgw/pgw_context.c index 061c6d297..34f7cb451 100644 --- a/src/pgw/pgw_context.c +++ b/src/pgw/pgw_context.c @@ -30,22 +30,10 @@ index_declare(pgw_bearer_pool, pgw_bearer_t, MAX_POOL_OF_BEARER); pool_declare(pgw_pf_pool, pgw_pf_t, MAX_POOL_OF_PF); -typedef struct _ue_pool_t { - int head, tail; - int size, avail; - mutex_id mut; - pgw_ue_ip_t *free[MAX_POOL_OF_SESS], pool[MAX_POOL_OF_SESS]; -} ue_pool_t; - -#define INVALID_POOL_INDEX MAX_NUM_OF_UE_POOL -static ue_pool_t ue_ip_pool[MAX_NUM_OF_UE_POOL]; - static int context_initiaized = 0; status_t pgw_context_init() { - int i; - d_assert(context_initiaized == 0, return CORE_ERROR, "PGW context already has been initialized"); @@ -70,9 +58,6 @@ 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_ip_pool[i], MAX_POOL_OF_UE); - self.sess_hash = hash_make(); context_initiaized = 1; @@ -82,8 +67,6 @@ status_t pgw_context_init() status_t pgw_context_final() { - int i; - d_assert(context_initiaized == 1, return CORE_ERROR, "PGW context already has been finalized"); @@ -98,19 +81,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)); - for (i = 0; i < MAX_NUM_OF_UE_POOL; i++) - { - if (pool_used(&ue_ip_pool[i])) - { - d_warn("[%d] %d not freed in ue_ip_pool[%d] in PGW-Context", - i, pool_used(&ue_ip_pool[i]), index_size(&ue_ip_pool[i])); - } - d_trace(3, "[%d] %d not freed in ue_ip_pool[%d] in PGW-Context\n", - i, pool_used(&ue_ip_pool[i]), index_size(&ue_ip_pool[i])); - - pool_final(&ue_ip_pool[i]); - } - pgw_dev_remove_all(); pgw_subnet_remove_all(); @@ -518,8 +488,6 @@ status_t pgw_context_parse_config() 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,); if (yaml_iter_type(&ue_pool_array) == YAML_MAPPING_NODE) { @@ -575,12 +543,6 @@ status_t pgw_context_parse_config() if (ipstr && mask_or_numbits) { - self.ue_pool[self.num_of_ue_pool].ipstr = ipstr; - self.ue_pool[self.num_of_ue_pool].mask_or_numbits = - 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,); @@ -1154,54 +1116,41 @@ pgw_pf_t* pgw_pf_next(pgw_pf_t *pf) status_t pgw_ue_pool_generate() { - status_t rv; - int i, j; + int j; + pgw_subnet_t *subnet = NULL; - for (i = 0; i < self.num_of_ue_pool; i++) + for (subnet = pgw_subnet_first(); subnet; subnet = pgw_subnet_next(subnet)) { int index = 0; - ipsubnet_t ipaddr, ipsub; - c_uint32_t prefixlen; c_uint32_t mask_count; c_uint32_t broadcast[4]; - rv = core_ipsubnet(&ipaddr, self.ue_pool[i].ipstr, NULL); - d_assert(rv == CORE_OK, return CORE_ERROR,); - - rv = core_ipsubnet(&ipsub, - self.ue_pool[i].ipstr, self.ue_pool[i].mask_or_numbits); - d_assert(rv == CORE_OK, return CORE_ERROR,); - - d_assert(self.ue_pool[i].mask_or_numbits, return CORE_ERROR,); - prefixlen = atoi(self.ue_pool[i].mask_or_numbits); - if (ipsub.family == AF_INET) + if (subnet->family == AF_INET) { - if (prefixlen == 32) + if (subnet->prefixlen == 32) mask_count = 1; - else if (prefixlen < 32) - mask_count = (0xffffffff >> prefixlen) + 1; + else if (subnet->prefixlen < 32) + mask_count = (0xffffffff >> subnet->prefixlen) + 1; else d_assert(0, return CORE_ERROR,); } - else if (ipsub.family == AF_INET6) + else if (subnet->family == AF_INET6) { - if (prefixlen == 128) + if (subnet->prefixlen == 128) mask_count = 1; - else if (prefixlen > 96 && prefixlen < 128) - mask_count = (0xffffffff >> (prefixlen - 96)) + 1; - else if (prefixlen <= 96) + else if (subnet->prefixlen > 96 && subnet->prefixlen < 128) + mask_count = (0xffffffff >> (subnet->prefixlen - 96)) + 1; + else if (subnet->prefixlen <= 96) mask_count = 0xffffffff; else d_assert(0, return CORE_ERROR,); } else d_assert(0, return CORE_ERROR,); - - self.ue_pool[i].family = ipsub.family; for (j = 0; j < 4; j++) { - broadcast[j] = ipsub.sub[j] + ~ipsub.mask[j]; + broadcast[j] = subnet->sub.sub[j] + ~subnet->sub.mask[j]; } for (j = 0; j < mask_count && index < MAX_POOL_OF_SESS; j++) @@ -1210,128 +1159,117 @@ status_t pgw_ue_pool_generate() int maxbytes = 0; int lastindex = 0; - ue_ip = &ue_ip_pool[i].pool[index]; + ue_ip = &subnet->pool.pool[index]; d_assert(ue_ip, return CORE_ERROR,); memset(ue_ip, 0, sizeof *ue_ip); - if (ipsub.family == AF_INET) + if (subnet->family == AF_INET) { maxbytes = 4; lastindex = 0; } - else if (ipsub.family == AF_INET6) + else if (subnet->family == AF_INET6) { maxbytes = 16; lastindex = 3; } - memcpy(ue_ip->addr, ipsub.sub, maxbytes); + memcpy(ue_ip->addr, subnet->sub.sub, maxbytes); ue_ip->addr[lastindex] += htonl(j); + ue_ip->subnet = subnet; /* Exclude Network Address */ - if (memcmp(ue_ip->addr, ipsub.sub, maxbytes) == 0) continue; + if (memcmp(ue_ip->addr, subnet->sub.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; + if (memcmp(ue_ip->addr, subnet->gw.sub, maxbytes) == 0) continue; index++; } - ue_ip_pool[i].size = ue_ip_pool[i].avail = index; + subnet->pool.size = subnet->pool.avail = index; } return CORE_OK; } -static c_uint8_t find_ue_pool_index(int family, const char *apn) +static pgw_subnet_t *find_subnet(int family, const char *apn) { - int i; - c_uint8_t pool_index = INVALID_POOL_INDEX; + pgw_subnet_t *subnet = NULL; - d_assert(apn, return INVALID_POOL_INDEX,); - d_assert(family == AF_INET || family == AF_INET6, - return INVALID_POOL_INDEX,); + d_assert(apn, return NULL,); + d_assert(family == AF_INET || family == AF_INET6, return NULL,); - for (i = 0; i < self.num_of_ue_pool; i++) + for (subnet = pgw_subnet_first(); subnet; subnet = pgw_subnet_next(subnet)) { - if (self.ue_pool[i].apn) + if (strlen(subnet->apn)) { - if (self.ue_pool[i].family == family && - strcmp(self.ue_pool[i].apn, apn) == 0 && - pool_avail(&ue_ip_pool[i])) + if (subnet->family == family && strcmp(subnet->apn, apn) == 0 && + pool_avail(&subnet->pool)) { - pool_index = i; - break; + return subnet; } } } - if (pool_index == INVALID_POOL_INDEX) + for (subnet = pgw_subnet_first(); subnet; subnet = pgw_subnet_next(subnet)) { - for (i = 0; i < self.num_of_ue_pool; i++) + if (strlen(subnet->apn) == 0) { - if (self.ue_pool[i].apn == NULL) + if (subnet->family == family && + pool_avail(&subnet->pool)) { - if (self.ue_pool[i].family == family && - pool_avail(&ue_ip_pool[i])) - { - pool_index = i; - break; - } + return subnet; } } } - if (pool_index == INVALID_POOL_INDEX) - { + if (subnet == NULL) d_error("CHECK CONFIGURATION: Cannot find UE Pool"); - return INVALID_POOL_INDEX; - } - return pool_index; + return subnet; } pgw_ue_ip_t *pgw_ue_ip_alloc(int family, const char *apn) { - c_uint8_t pool_index = INVALID_POOL_INDEX; + pgw_subnet_t *subnet = NULL; pgw_ue_ip_t *ue_ip = NULL; d_assert(apn, return NULL,); - pool_index = find_ue_pool_index(family, apn); - d_assert(pool_index < MAX_NUM_OF_UE_POOL, return NULL,); + subnet = find_subnet(family, apn); + d_assert(subnet, return NULL,); - pool_alloc_node(&ue_ip_pool[pool_index], &ue_ip); + pool_alloc_node(&subnet->pool, &ue_ip); d_assert(ue_ip, return NULL,); - ue_ip->index = pool_index; return ue_ip; } status_t pgw_ue_ip_free(pgw_ue_ip_t *ue_ip) { - c_uint8_t pool_index; + pgw_subnet_t *subnet = NULL; d_assert(ue_ip, return CORE_ERROR,); - pool_index = ue_ip->index; + subnet = ue_ip->subnet; - d_assert(pool_index < MAX_NUM_OF_UE_POOL, return CORE_ERROR,); - pool_free_node(&ue_ip_pool[pool_index], ue_ip); + d_assert(subnet, return CORE_ERROR,); + pool_free_node(&subnet->pool, ue_ip); return CORE_OK; } c_uint8_t pgw_ue_ip_prefixlen(pgw_ue_ip_t *ue_ip) { - d_assert(ue_ip, return CORE_ERROR,); + pgw_subnet_t *subnet = NULL; - c_uint8_t index = ue_ip->index; - d_assert(index < MAX_NUM_OF_UE_POOL, return CORE_ERROR,); - d_assert(pgw_self()->ue_pool[index].mask_or_numbits, - return CORE_ERROR,); - return atoi(pgw_self()->ue_pool[index].mask_or_numbits); + d_assert(ue_ip, return -1,); + subnet = ue_ip->subnet; + d_assert(subnet, return -1,); + + return subnet->prefixlen; } pgw_dev_t *pgw_dev_add(const char *ifname) @@ -1436,6 +1374,11 @@ pgw_subnet_t *pgw_subnet_add( if (apn) strcpy(subnet->apn, apn); + subnet->family = subnet->gw.family; + subnet->prefixlen = atoi(mask_or_numbits); + + pool_init(&subnet->pool, MAX_POOL_OF_UE); + list_append(&self.subnet_list, subnet); return subnet; @@ -1446,6 +1389,16 @@ status_t pgw_subnet_remove(pgw_subnet_t *subnet) d_assert(subnet, return CORE_ERROR, "Null param"); list_remove(&self.subnet_list, subnet); + + if (pool_used(&subnet->pool)) + { + d_warn("%d not freed in ue_ip_pool[%d] in PGW-Context", + pool_used(&subnet->pool), pool_size(&subnet->pool)); + } + d_trace(3, "%d not freed in ue_ip_pool[%d] in PGW-Context\n", + pool_used(&subnet->pool), pool_size(&subnet->pool)); + pool_final(&subnet->pool); + pool_free_node(&pgw_subnet_pool, subnet); return CORE_OK; diff --git a/src/pgw/pgw_context.h b/src/pgw/pgw_context.h index deb99a947..2f8b8518c 100644 --- a/src/pgw/pgw_context.h +++ b/src/pgw/pgw_context.h @@ -45,23 +45,10 @@ typedef struct _pgw_context_t { sock_id tun_sock; /* PGW Tun Interace for UE */ const char *tun_ifname; /* default : pgwtun */ -#define MAX_NUM_OF_UE_POOL 16 - struct { - const char *ipstr; /* IP : "172.16.0.1", "cafe::1", ... */ - const char *mask_or_numbits; /* MASK : "16, 64, ... */ - const char *apn; /* APN : "internet", "volte", .. */ - int family; /* AF_INET or AF_INET6 */ - } ue_pool[MAX_NUM_OF_UE_POOL]; - c_uint8_t num_of_ue_pool; - - struct { - c_uint32_t primary; - c_uint32_t secondary; - } old_dns; #define MAX_NUM_OF_DNS 2 - const char *dns[2]; /* Primary/Secondanry */ - const char *dns6[2]; /* Primary/Secondanry */ + const char *dns[MAX_NUM_OF_DNS]; /* Primary/Secondanry */ + const char *dns6[MAX_NUM_OF_DNS]; /* Primary/Secondanry */ list_t sgw_s5c_list; /* SGW GTPC Node List */ list_t sgw_s5u_list; /* SGW GTPU Node List */ @@ -70,6 +57,14 @@ typedef struct _pgw_context_t { hash_t *sess_hash; /* hash table (IMSI+APN) */ } pgw_context_t; +typedef struct _pgw_subnet_t pgw_subnet_t; +typedef struct _pgw_ue_ip_t { + c_uint32_t addr[4]; + + /* Related Context */ + pgw_subnet_t *subnet; +} pgw_ue_ip_t; + typedef struct _pgw_dev_t { lnode_t node; @@ -85,16 +80,21 @@ typedef struct _pgw_subnet_t { 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 */ + int family; /* AF_INET or AF_INET6 */ + c_uint8_t prefixlen; /* prefixlen */ + + struct { + int head, tail; + int size, avail; + mutex_id mut; + pgw_ue_ip_t *free[MAX_POOL_OF_SESS], pool[MAX_POOL_OF_SESS]; + } pool; + + /* Related Context */ pgw_dev_t *dev; } pgw_subnet_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 */ index_t index; /**< An index of this node */ diff --git a/src/pgw/pgw_gtp_path.c b/src/pgw/pgw_gtp_path.c index 9dab0958c..8a8502867 100644 --- a/src/pgw/pgw_gtp_path.c +++ b/src/pgw/pgw_gtp_path.c @@ -156,7 +156,9 @@ static int _gtpv1_u_recv_cb(sock_id sock, void *data) status_t pgw_gtp_open() { status_t rv; +#if 0 int i; +#endif int rc; rv = gtp_server_list(&pgw_self()->gtpc_list, _gtpv2_c_recv_cb); @@ -211,6 +213,7 @@ status_t pgw_gtp_open() /* Set P-to-P IP address with Netmask * Note that Linux will skip this configuration */ +#if 0 for (i = 0; i < pgw_self()->num_of_ue_pool; i++) { rc = tun_set_ip(pgw_self()->tun_sock, @@ -226,6 +229,7 @@ status_t pgw_gtp_open() return CORE_ERROR; } } +#endif rc = sock_register(pgw_self()->tun_sock, _gtpv1_tun_recv_cb, NULL); if (rc != 0)