mme->s1ap_sock is removed

This commit is contained in:
Sukchan Lee 2017-11-25 00:52:07 +09:00
parent 23fa36bc23
commit 61432a3070
9 changed files with 239 additions and 68 deletions

View File

@ -8,6 +8,8 @@ extern "C" {
#endif /* __cplusplus */
#define S1AP_SCTP_PORT 36412
#define GTPV2_C_UDP_PORT 2123
#define GTPV1_U_UDP_PORT 2152
#define SCTP_S1AP_PPID 18
#define SCTP_X2AP_PPID 27
@ -20,6 +22,9 @@ extern "C" {
#define MAX_NUM_OF_PF 16 /* Num of Packet Filter per Bearer */
#define MAX_NUM_OF_GTP_NODE 8
#define MAX_NUM_OF_SERVER 8
#define MAX_NUM_OF_CLINET 8
#define MAX_POOL_OF_UE (MAX_NUM_OF_ENB * MAX_NUM_OF_UE)
#define MAX_POOL_OF_SESS (MAX_POOL_OF_UE * MAX_NUM_OF_SESS)
#define MAX_POOL_OF_BEARER (MAX_POOL_OF_SESS * MAX_NUM_OF_BEARER)

View File

@ -9,9 +9,6 @@
extern "C" {
#endif /* __cplusplus */
#define GTPV2_C_UDP_PORT 2123
#define GTPV1_U_UDP_PORT 2152
/**
* This structure represents the commonalities of GTP node such as MME, SGW,
* PGW gateway. Some of members may not be used by the specific type of node */

View File

@ -19,9 +19,11 @@
static mme_context_t self;
pool_declare(mme_sgw_pool, mme_sgw_t, MAX_NUM_OF_GTP_NODE);
pool_declare(mme_s1ap_pool, mme_s1ap_t, MAX_NUM_OF_SERVER);
pool_declare(mme_sgw_pool, mme_sgw_t, MAX_NUM_OF_CLINET);
index_declare(mme_enb_pool, mme_enb_t, MAX_NUM_OF_ENB);
index_declare(mme_ue_pool, mme_ue_t, MAX_POOL_OF_UE);
index_declare(enb_ue_pool, enb_ue_t, MAX_POOL_OF_UE);
index_declare(mme_sess_pool, mme_sess_t, MAX_POOL_OF_SESS);
@ -37,7 +39,9 @@ status_t mme_context_init()
/* Initialize MME context */
memset(&self, 0, sizeof(mme_context_t));
pool_init(&mme_sgw_pool, MAX_NUM_OF_GTP_NODE);
pool_init(&mme_s1ap_pool, MAX_NUM_OF_SERVER);
list_init(&self.s1ap_list);
pool_init(&mme_sgw_pool, MAX_NUM_OF_CLINET);
list_init(&self.sgw_list);
index_init(&mme_enb_pool, MAX_NUM_OF_ENB);
@ -66,8 +70,11 @@ status_t mme_context_final()
d_assert(context_initialized == 1, return CORE_ERROR,
"MME context already has been finalized");
mme_s1ap_remove_all();
mme_sgw_remove_all();
mme_enb_remove_all();
mme_ue_remove_all();
d_assert(self.enb_sock_hash, , "Null param");
@ -92,6 +99,8 @@ status_t mme_context_final()
index_final(&mme_enb_pool);
pool_final(&mme_sgw_pool);
pool_final(&mme_s1ap_pool);
context_initialized = 0;
return CORE_OK;
@ -106,9 +115,6 @@ static status_t mme_context_prepare()
{
self.relative_capacity = 0xff;
#if 0
self.s1ap_port = S1AP_SCTP_PORT;
#endif
self.gtpc_port = GTPV2_C_UDP_PORT;
self.s5c_port = GTPV2_C_UDP_PORT;
@ -123,14 +129,12 @@ static status_t mme_context_validation()
context_self()->config.path);
return CORE_ERROR;
}
#if 0
if (self.s1ap_addr == 0)
if (mme_s1ap_first() == NULL)
{
d_error("No MME.NEWORK.S1AP_IPV4 in '%s'",
d_error("No MME.S1AP in '%s'",
context_self()->config.path);
return CORE_ERROR;
}
#endif
if (self.gtpc_addr == 0)
{
d_error("No MME.NEWORK.GTPC_IPV4 in '%s'",
@ -248,6 +252,91 @@ status_t mme_context_parse_config()
{
self.fd_conf_path = bson_iter_utf8(&mme_iter, &length);
}
else if (!strcmp(mme_key, "S1AP"))
{
int s1ap_index = 0;
bson_iter_t s1ap_array;
if (BSON_ITER_HOLDS_ARRAY(&mme_iter))
{
bson_iter_recurse(&mme_iter, &s1ap_array);
d_assert(bson_iter_next(&s1ap_array),
return CORE_ERROR,);
}
else if (BSON_ITER_HOLDS_DOCUMENT(&mme_iter))
{
memcpy(&s1ap_array, &mme_iter,
sizeof(s1ap_array));
}
else
d_assert(0, return CORE_ERROR,);
do
{
bson_iter_t s1ap_iter;
const char *s1ap_index_key =
bson_iter_key(&s1ap_array);
int domain = AF_UNSPEC;
const char *hostname = NULL;
c_uint16_t port = S1AP_SCTP_PORT;
mme_s1ap_t *s1ap = NULL;
d_assert(s1ap_index_key, return CORE_ERROR,);
if (BSON_ITER_HOLDS_ARRAY(&mme_iter))
s1ap_index = atoi(s1ap_index_key);
d_assert(s1ap_index < MAX_NUM_OF_SERVER,
return CORE_ERROR,
"GTP NODE Overflow : %d", s1ap_index);
bson_iter_recurse(&s1ap_array, &s1ap_iter);
while(bson_iter_next(&s1ap_iter))
{
const char *s1ap_key =
bson_iter_key(&s1ap_iter);
if (!strcmp(s1ap_key, "DOMAIN") &&
BSON_ITER_HOLDS_UTF8(&s1ap_iter))
{
const char *v =
bson_iter_utf8(&s1ap_iter, &length);
if (v)
{
if (!strcmp(v, "AF_INET") ||
!strcmp(v, "PF_INET"))
{
domain = AF_INET;
}
else if (!strcmp(v, "AF_INET6") ||
!strcmp(v, "PF_INET6"))
{
domain = AF_INET6;
}
else
{
d_warn("Unknown domain(%s)", v);
}
}
}
else if (!strcmp(s1ap_key, "HOSTNAME") &&
BSON_ITER_HOLDS_UTF8(&s1ap_iter))
{
hostname = bson_iter_utf8(&s1ap_iter, &length);
}
else if (!strcmp(s1ap_key, "PORT") &&
BSON_ITER_HOLDS_INT32(&s1ap_iter))
{
port = bson_iter_int32(&s1ap_iter);
}
}
s1ap = mme_s1ap_add(domain, hostname, port);
d_assert(s1ap, return CORE_ERROR,);
} while(
BSON_ITER_HOLDS_ARRAY(&mme_iter) &&
bson_iter_next(&s1ap_array));
}
else if (!strcmp(mme_key, "NETWORK"))
{
bson_iter_t network_iter;
@ -269,23 +358,7 @@ status_t mme_context_parse_config()
while(bson_iter_next(&network_iter))
{
const char *network_key = bson_iter_key(&network_iter);
if (!strcmp(network_key, "S1AP_IPV4") &&
BSON_ITER_HOLDS_UTF8(&network_iter))
{
#if 0
const char *v =
bson_iter_utf8(&network_iter, &length);
if (v) self.s1ap_addr = inet_addr(v);
#endif
}
else if (!strcmp(network_key, "S1AP_PORT") &&
BSON_ITER_HOLDS_INT32(&network_iter))
{
#if 0
self.s1ap_port = bson_iter_int32(&network_iter);
#endif
}
else if (!strcmp(network_key, "GTPC_IPV4") &&
if (!strcmp(network_key, "GTPC_IPV4") &&
BSON_ITER_HOLDS_UTF8(&network_iter))
{
const char *v =
@ -758,7 +831,7 @@ status_t mme_context_parse_config()
d_assert(network_index_key, return CORE_ERROR,);
if (BSON_ITER_HOLDS_ARRAY(&sgw_iter))
network_index = atoi(network_index_key);
d_assert(network_index < MAX_NUM_OF_GTP_NODE,
d_assert(network_index < MAX_NUM_OF_CLINET,
return CORE_ERROR,
"GTP NODE Overflow : %d", network_index);
@ -941,6 +1014,62 @@ status_t mme_context_setup_trace_module()
return CORE_OK;
}
mme_s1ap_t* mme_s1ap_add(
int domain, const char *hostname, c_uint16_t port)
{
mme_s1ap_t *s1ap = NULL;
pool_alloc_node(&mme_s1ap_pool, &s1ap);
d_assert(s1ap, return NULL, "Null param");
memset(s1ap, 0, sizeof(mme_s1ap_t));
s1ap->domain = domain;
s1ap->hostname = hostname;
s1ap->port = port;
list_append(&self.s1ap_list, s1ap);
return s1ap;
}
status_t mme_s1ap_remove(mme_s1ap_t *s1ap)
{
d_assert(s1ap, return CORE_ERROR, "Null param");
list_remove(&self.s1ap_list, s1ap);
pool_free_node(&mme_s1ap_pool, s1ap);
return CORE_OK;
}
status_t mme_s1ap_remove_all()
{
mme_s1ap_t *s1ap = NULL, *next_s1ap = NULL;
s1ap = mme_s1ap_first();
while (s1ap)
{
next_s1ap = mme_s1ap_next(s1ap);
mme_s1ap_remove(s1ap);
s1ap = next_s1ap;
}
return CORE_OK;
}
mme_s1ap_t* mme_s1ap_first()
{
return list_first(&self.s1ap_list);
}
mme_s1ap_t* mme_s1ap_next(mme_s1ap_t *s1ap)
{
return list_next(s1ap);
}
mme_sgw_t* mme_sgw_add()
{
mme_sgw_t *sgw = NULL;
@ -1124,15 +1253,16 @@ mme_enb_t *mme_enb_this(hash_index_t *hi)
int mme_enb_sock_type(sock_id sock)
{
mme_s1ap_t *s1ap = NULL;
d_assert(sock, return 0,);
if (mme_self()->s1ap_sock == sock)
for (s1ap = mme_s1ap_first(); s1ap; s1ap = mme_s1ap_next(s1ap))
{
return SOCK_SEQPACKET;
}
else
{
return SOCK_STREAM;
if (s1ap->sock == sock) return SOCK_SEQPACKET;
}
return SOCK_STREAM;
}

View File

@ -35,6 +35,7 @@ extern "C" {
typedef struct _enb_ue_t enb_ue_t;
typedef struct _mme_ue_t mme_ue_t;
typedef gtp_node_t mme_sgw_t;
typedef struct _served_gummei {
@ -50,15 +51,12 @@ typedef struct _served_gummei {
typedef struct _mme_context_t {
const char *fd_conf_path; /* MME freeDiameter conf path */
#if 0
c_uint32_t s1ap_addr; /* MME S1AP local address */
c_uint16_t s1ap_port; /* MME S1AP local port */
#endif
sock_id s1ap_sock; /* MME S1AP local listen socket */
list_t s1ap_list; /* MME S1AP Socket List */
list_t sgw_list; /* SGW GTP Node List */
c_uint32_t gtpc_addr; /* MME GTPC local address */
c_uint16_t gtpc_port; /* MME GTPC local port */
sock_id gtpc_sock; /* MME GTPC local listen socket */
sock_id gtpc_sock; /* MME GTPC local listen socket */
c_uint32_t s5c_addr; /* PGW S5C remote address */
c_uint16_t s5c_port; /* PGW S5C remote port */
@ -99,8 +97,6 @@ typedef struct _mme_context_t {
/* Timer value */
c_uint32_t t3413_value; /* Paging retry timer */
list_t sgw_list; /* SGW GTP Node List */
hash_t *enb_sock_hash; /* hash table for ENB Socket */
hash_t *enb_addr_hash; /* hash table for ENB Address */
hash_t *enb_id_hash; /* hash table for ENB-ID */
@ -109,6 +105,16 @@ typedef struct _mme_context_t {
hash_t *guti_ue_hash; /* hash table (GUTI : MME_UE) */
} mme_context_t;
typedef struct _mme_s1ap_t {
lnode_t node; /* A node of list_t */
int domain;
const char *hostname;
c_uint16_t port;
sock_id sock; /* MME S1AP Socket */
} mme_s1ap_t;
typedef struct _mme_enb_t {
lnode_t node; /* A node of list_t */
index_t index; /* An index of this node */
@ -439,6 +445,13 @@ CORE_DECLARE(mme_context_t*) mme_self(void);
CORE_DECLARE(status_t) mme_context_parse_config(void);
CORE_DECLARE(status_t) mme_context_setup_trace_module(void);
CORE_DECLARE(mme_s1ap_t*) mme_s1ap_add(
int domain, const char *hostname, c_uint16_t port);
CORE_DECLARE(status_t) mme_s1ap_remove(mme_s1ap_t *s1ap);
CORE_DECLARE(status_t) mme_s1ap_remove_all(void);
CORE_DECLARE(mme_s1ap_t*) mme_s1ap_first(void);
CORE_DECLARE(mme_s1ap_t*) mme_s1ap_next(mme_s1ap_t *s1ap);
CORE_DECLARE(mme_sgw_t*) mme_sgw_add(void);
CORE_DECLARE(status_t) mme_sgw_remove(mme_sgw_t *sgw);
CORE_DECLARE(status_t) mme_sgw_remove_all(void);

View File

@ -69,12 +69,11 @@ void mme_state_operational(fsm_t *s, event_t *e)
{
d_error("Can't close S11-GTP path");
}
rv = s1ap_close(mme_self()->s1ap_sock);
rv = s1ap_close();
if (rv != CORE_OK)
{
d_error("Can't close S1AP path");
}
mme_self()->s1ap_sock = 0;
break;
}

View File

@ -30,7 +30,7 @@ status_t s1ap_open(void)
rv = s1ap_server(&mme_self()->s1ap_sock, family, type, hostname, port);
if (rv != CORE_OK)
{
d_error("s1ap_server(%d:%d:%s:%d) failed",
d_error("s1ap_server %d:%d:[%s]:%d failed",
family, type, hostname, port);
return CORE_ERROR;
}
@ -59,7 +59,7 @@ status_t s1ap_server(sock_id *new,
addr = sock_local_addr_get(*new);
d_assert(addr, return CORE_ERROR,);
d_trace(1, "s1ap_server %s:%d\n", CORE_NTOP(addr, buf), CORE_PORT(addr));
d_trace(1, "s1ap_server [%s]:%d\n", CORE_NTOP(addr, buf), CORE_PORT(addr));
return CORE_OK;
}
@ -129,8 +129,8 @@ static int s1ap_accept_handler(sock_id id, void *data)
d_assert(addr, return -1,);
memcpy(addr, sock_remote_addr_get(new), sizeof(c_sockaddr_t));
d_trace(1, "eNB-S1 accepted[%s] in s1_path module\n",
CORE_NTOP(addr, buf));
d_trace(1, "eNB-S1 accepted[%s]:%d in s1_path module\n",
CORE_NTOP(addr, buf), CORE_PORT(addr));
event_set(&e, MME_EVT_S1AP_LO_ACCEPT);
event_set_param1(&e, (c_uintptr_t)new);

View File

@ -62,25 +62,34 @@ status_t s1ap_final()
status_t s1ap_open(void)
{
status_t rv;
int family = AF_INET;
int type = SOCK_SEQPACKET;
const char *hostname = NULL;
c_uint16_t port = S1AP_SCTP_PORT;
mme_s1ap_t *s1ap = NULL;
rv = s1ap_server(&mme_self()->s1ap_sock, family, type, hostname, port);
if (rv != CORE_OK)
for (s1ap = mme_s1ap_first(); s1ap; s1ap = mme_s1ap_next(s1ap))
{
d_error("s1ap_server(%d:%d:%s:%d) failed",
family, type, hostname, port);
return CORE_ERROR;
rv = s1ap_server(&s1ap->sock, s1ap->domain, type,
s1ap->hostname, s1ap->port);
if (rv != CORE_OK)
{
d_error("s1ap_server(%d:%d:[%s]:%d) failed",
s1ap->domain, type, s1ap->hostname, s1ap->port);
return CORE_ERROR;
}
}
return CORE_OK;
}
status_t s1ap_close()
{
return s1ap_delete(mme_self()->s1ap_sock);
mme_s1ap_t *s1ap = NULL;
for (s1ap = mme_s1ap_first(); s1ap; s1ap = mme_s1ap_next(s1ap))
{
s1ap_delete(s1ap->sock);
}
return CORE_OK;
}
status_t s1ap_delete(sock_id sock)
@ -108,7 +117,7 @@ status_t s1ap_server(sock_id *new,
if (s1ap_usrsctp_bind(*new, sa) == CORE_OK)
{
d_trace(1, "s1ap_server %s:%d\n", CORE_NTOP(sa, buf), port);
d_trace(1, "s1ap_server [%s]:%d\n", CORE_NTOP(sa, buf), port);
break;
}
@ -120,7 +129,7 @@ status_t s1ap_server(sock_id *new,
if (sa == NULL)
{
d_error("usrsctp bind(%d:%s:%d)", family, hostname, port);
d_error("usrsctp bind %d:[%s]:%d", family, hostname, port);
return CORE_ERROR;
}
@ -150,7 +159,7 @@ status_t s1ap_client(sock_id *new,
if (s1ap_usrsctp_connect(*new, sa) == CORE_OK)
{
d_trace(1, "s1ap_client %s:%d\n", CORE_NTOP(sa, buf), port);
d_trace(1, "s1ap_client [%s]:%d\n", CORE_NTOP(sa, buf), port);
break;
}
@ -162,7 +171,7 @@ status_t s1ap_client(sock_id *new,
if (sa == NULL)
{
d_error("s1ap_client(%d:%s:%d) failed", family, hostname, port);
d_error("s1ap_client %d:[%s]:%d failed", family, hostname, port);
return CORE_ERROR;
}
@ -301,12 +310,12 @@ static status_t s1ap_usrsctp_bind(sock_id id, c_sockaddr_t *sa)
if (usrsctp_bind(sock, &sa->sa, addrlen) != 0)
{
d_error("usrsctp_bind(%s:%d) failed",
d_error("usrsctp_bind [%s]:%d failed",
CORE_NTOP(sa, buf), CORE_PORT(sa));
return CORE_ERROR;
}
d_trace(3, "usrsctp_bind %s:%d\n", CORE_NTOP(sa, buf), CORE_PORT(sa));
d_trace(3, "usrsctp_bind [%s]:%d\n", CORE_NTOP(sa, buf), CORE_PORT(sa));
return CORE_OK;
}
@ -325,11 +334,11 @@ static status_t s1ap_usrsctp_connect(sock_id id, c_sockaddr_t *sa)
if (usrsctp_connect(sock, &sa->sa, addrlen) != 0)
{
d_error("usrsctp_connect(%s:%d)", CORE_NTOP(sa, buf), CORE_PORT(sa));
d_error("usrsctp_connect [%s]:%d", CORE_NTOP(sa, buf), CORE_PORT(sa));
return CORE_ERROR;
}
d_trace(3, "usrsctp_connect %s:%d\n", CORE_NTOP(sa, buf), CORE_PORT(sa));
d_trace(3, "usrsctp_connect [%s]:%d\n", CORE_NTOP(sa, buf), CORE_PORT(sa));
return CORE_OK;
}

View File

@ -21,6 +21,15 @@
{
"FD_CONF_PATH" : "mme.conf",
"DEFAULT_PAGING_DRX" : "v64",
"S1AP" :
[
{
"DOMAIN" : "AF_INET"
},
{
"DOMAIN" : "AF_INET6"
}
],
"NETWORK" :
{
"S1AP_IPV4" : "127.0.0.1",

View File

@ -29,6 +29,15 @@
{
"FD_CONF_PATH" : "mme.conf",
"DEFAULT_PAGING_DRX" : "v64",
"S1AP" :
[
{
"HOSTNAME" : "127.0.0.1"
},
{
"HOSTNAME" : "::1"
}
],
"NETWORK" :
{
"S1AP_IPV4" : "127.0.0.1",