socket descriptor is in GTP Node structure for simple interface

This commit is contained in:
Sukchan Lee 2017-09-02 00:11:49 +09:00
parent 038bb7037d
commit 6ddaa2a91e
20 changed files with 357 additions and 101 deletions

View File

@ -11,6 +11,7 @@ extern "C" {
#define MAX_NUM_OF_UE 128
#define MAX_NUM_OF_SESS 4
#define MAX_NUM_OF_BEARER 4
#define MAX_NUM_OF_GTP_NODE 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)

View File

@ -76,14 +76,16 @@ pkbuf_t *gtp_read(net_sock_t *sock)
}
}
status_t gtp_send(net_sock_t *sock, gtp_node_t *gnode, pkbuf_t *pkbuf)
status_t gtp_send(gtp_node_t *gnode, pkbuf_t *pkbuf)
{
char buf[INET_ADDRSTRLEN];
ssize_t sent;
net_sock_t *sock = NULL;
d_assert(sock, return CORE_ERROR, "Null param");
d_assert(gnode, return CORE_ERROR, "Null param");
d_assert(pkbuf, return CORE_ERROR, "Null param");
sock = gnode->sock;
d_assert(sock, return CORE_ERROR, "Null param");
sent = net_sendto(sock, pkbuf->payload, pkbuf->len,
gnode->addr, gnode->port);

View File

@ -23,6 +23,7 @@ typedef struct _gtp_node_t {
c_uint32_t addr; /**< Network byte order IP Address */
c_uint16_t port; /**< Host byte order Port number */
net_sock_t *sock; /**< Socket Descriptor */
list_t local_list;
list_t remote_list;
@ -33,8 +34,7 @@ CORE_DECLARE(status_t) gtp_listen(net_sock_t **sock,
CORE_DECLARE(status_t) gtp_close(net_sock_t *sock);
CORE_DECLARE(pkbuf_t *) gtp_read(net_sock_t *sock);
CORE_DECLARE(status_t) gtp_send(net_sock_t *sock,
gtp_node_t *gnode, pkbuf_t *pkbuf);
CORE_DECLARE(status_t) gtp_send(gtp_node_t *gnode, pkbuf_t *pkbuf);
CORE_DECLARE(pkbuf_t*) gtp_handle_echo_req(pkbuf_t *pkt);
#ifdef __cplusplus

View File

@ -73,14 +73,13 @@ status_t gtp_xact_final(void)
return CORE_OK;
}
gtp_xact_t *gtp_xact_local_create(net_sock_t *sock,
gtp_xact_t *gtp_xact_local_create(
gtp_node_t *gnode, gtp_header_t *hdesc, pkbuf_t *pkbuf)
{
status_t rv;
char buf[INET_ADDRSTRLEN];
gtp_xact_t *xact = NULL;
d_assert(sock, return NULL, "Null param");
d_assert(gnode, return NULL, "Null param");
index_alloc(&gtp_xact_pool, &xact);
@ -88,7 +87,6 @@ gtp_xact_t *gtp_xact_local_create(net_sock_t *sock,
xact->org = GTP_LOCAL_ORIGINATOR;
xact->xid = NEXT_ID(g_xact_id, GTP_MIN_XACT_ID, GTP_MAX_XACT_ID);
xact->sock = sock;
xact->gnode = gnode;
if (g_response_event)
@ -121,13 +119,11 @@ gtp_xact_t *gtp_xact_local_create(net_sock_t *sock,
return xact;
}
gtp_xact_t *gtp_xact_remote_create(
net_sock_t *sock, gtp_node_t *gnode, c_uint32_t sqn)
gtp_xact_t *gtp_xact_remote_create(gtp_node_t *gnode, c_uint32_t sqn)
{
char buf[INET_ADDRSTRLEN];
gtp_xact_t *xact = NULL;
d_assert(sock, return NULL, "Null param");
d_assert(gnode, return NULL, "Null param");
index_alloc(&gtp_xact_pool, &xact);
@ -135,7 +131,6 @@ gtp_xact_t *gtp_xact_remote_create(
xact->org = GTP_REMOTE_ORIGINATOR;
xact->xid = GTP_SQN_TO_XID(sqn);
xact->sock = sock;
xact->gnode = gnode;
if (g_response_event)
@ -191,7 +186,6 @@ status_t gtp_xact_update_tx(gtp_xact_t *xact,
gtp_header_t *h = NULL;
d_assert(xact, return CORE_ERROR, "Null param");
d_assert(xact->sock, return CORE_ERROR, "Null param");
d_assert(xact->gnode, return CORE_ERROR, "Null param");
d_assert(hdesc, return CORE_ERROR, "Null param");
d_assert(pkbuf, return CORE_ERROR, "Null param");
@ -321,7 +315,7 @@ status_t gtp_xact_update_rx(gtp_xact_t *xact, c_uint8_t type)
xact->gnode->port,
xact->org == GTP_LOCAL_ORIGINATOR ?
"LOCAL " : "REMOTE");
rv = gtp_send(xact->sock, xact->gnode, pkbuf);
rv = gtp_send(xact->gnode, pkbuf);
d_assert(rv == CORE_OK, return CORE_ERROR,
"gtp_send error");
}
@ -388,7 +382,7 @@ status_t gtp_xact_update_rx(gtp_xact_t *xact, c_uint8_t type)
xact->gnode->port,
xact->org == GTP_LOCAL_ORIGINATOR ?
"LOCAL " : "REMOTE");
rv = gtp_send(xact->sock, xact->gnode, pkbuf);
rv = gtp_send(xact->gnode, pkbuf);
d_assert(rv == CORE_OK, return CORE_ERROR,
"gtp_send error");
}
@ -459,7 +453,6 @@ status_t gtp_xact_commit(gtp_xact_t *xact)
gtp_xact_stage_t stage;
d_assert(xact, return CORE_ERROR, "Null param");
d_assert(xact->sock, return CORE_ERROR, "Null param");
d_assert(xact->gnode, return CORE_ERROR, "Null param");
d_trace(3, "[%d] %s Commit peer %s:%d\n",
@ -559,7 +552,7 @@ status_t gtp_xact_commit(gtp_xact_t *xact)
pkbuf = xact->seq[xact->step-1].pkbuf;
d_assert(pkbuf, return CORE_ERROR, "Null param");
rv = gtp_send(xact->sock, xact->gnode, pkbuf);
rv = gtp_send(xact->gnode, pkbuf);
d_assert(rv == CORE_OK, return CORE_ERROR, "gtp_send error");
return CORE_OK;
@ -573,7 +566,6 @@ status_t gtp_xact_timeout(index_t index, c_uintptr_t event)
d_assert(index, goto out, "Invalid Index");
xact = index_find(&gtp_xact_pool, index);
d_assert(xact, goto out, "Null param");
d_assert(xact->sock, goto out, "Null param");
d_assert(xact->gnode, goto out, "Null param");
if (event == g_response_event)
@ -593,7 +585,7 @@ status_t gtp_xact_timeout(index_t index, c_uintptr_t event)
pkbuf = xact->seq[xact->step-1].pkbuf;
d_assert(pkbuf, return CORE_ERROR, "Null param");
d_assert(gtp_send(xact->sock, xact->gnode, pkbuf) == CORE_OK,
d_assert(gtp_send(xact->gnode, pkbuf) == CORE_OK,
goto out, "gtp_send error");
}
else
@ -629,8 +621,7 @@ out:
return CORE_ERROR;
}
status_t gtp_xact_receive(
net_sock_t *sock, gtp_node_t *gnode, pkbuf_t *pkbuf,
status_t gtp_xact_receive(gtp_node_t *gnode, pkbuf_t *pkbuf,
gtp_xact_t **xact, gtp_message_t *message)
{
char buf[INET_ADDRSTRLEN];
@ -638,7 +629,6 @@ status_t gtp_xact_receive(
gtp_xact_t *new = NULL;
gtp_header_t *h = NULL;
d_assert(sock, return CORE_ERROR, "Null param");
d_assert(gnode, return CORE_ERROR, "Null param");
d_assert(pkbuf, return CORE_ERROR, "Null param");
d_assert(pkbuf->payload, return CORE_ERROR, "Null param");
@ -648,7 +638,7 @@ status_t gtp_xact_receive(
new = gtp_xact_find_by_xid(gnode, h->type, GTP_SQN_TO_XID(h->sqn));
if (!new)
{
new = gtp_xact_remote_create(sock, gnode, h->sqn);
new = gtp_xact_remote_create(gnode, h->sqn);
}
d_assert(new, return CORE_ERROR, "Null param");

View File

@ -27,8 +27,6 @@ typedef struct _gtp_xact_t {
local or remote */
c_uint32_t xid; /**< Transaction ID */
net_sock_t *sock; /**< GTP Socket */
gtp_node_t *gnode; /**< Relevant GTP node context */
int step; /**< Current step in the sequence.
@ -62,10 +60,10 @@ CORE_DECLARE(status_t) gtp_xact_init(tm_service_t *tm_service,
c_uintptr_t response_event, c_uintptr_t duplicated_event);
CORE_DECLARE(status_t) gtp_xact_final(void);
CORE_DECLARE(gtp_xact_t *) gtp_xact_local_create(net_sock_t *sock,
CORE_DECLARE(gtp_xact_t *) gtp_xact_local_create(
gtp_node_t *gnode, gtp_header_t *hdesc, pkbuf_t *pkbuf);
CORE_DECLARE(gtp_xact_t *) gtp_xact_remote_create(
net_sock_t *sock, gtp_node_t *gnode, c_uint32_t sqn);
gtp_node_t *gnode, c_uint32_t sqn);
CORE_DECLARE(void) gtp_xact_delete_all(gtp_node_t *gnode);
CORE_DECLARE(status_t) gtp_xact_update_tx(gtp_xact_t *xact,
@ -76,7 +74,7 @@ CORE_DECLARE(status_t) gtp_xact_commit(gtp_xact_t *xact);
CORE_DECLARE(status_t) gtp_xact_timeout(index_t index, c_uintptr_t event);
CORE_DECLARE(status_t) gtp_xact_receive(
net_sock_t *sock, gtp_node_t *gnode, pkbuf_t *pkbuf,
gtp_node_t *gnode, pkbuf_t *pkbuf,
gtp_xact_t **xact, gtp_message_t *gtp_message);
CORE_DECLARE(gtp_xact_t *) gtp_xact_find(index_t index);

View File

@ -15,13 +15,11 @@
#define MAX_CELL_PER_ENB 8
#define MAX_NUM_OF_SGW 8
#define S1AP_SCTP_PORT 36412
static mme_context_t self;
pool_declare(mme_sgw_pool, mme_sgw_t, MAX_NUM_OF_SGW);
pool_declare(mme_sgw_pool, mme_sgw_t, MAX_NUM_OF_GTP_NODE);
index_declare(mme_enb_pool, mme_enb_t, MAX_NUM_OF_ENB);
index_declare(mme_ue_pool, mme_ue_t, MAX_POOL_OF_UE);
@ -39,7 +37,7 @@ status_t mme_context_init()
/* Initialize MME context */
memset(&self, 0, sizeof(mme_context_t));
pool_init(&mme_sgw_pool, MAX_NUM_OF_SGW);
pool_init(&mme_sgw_pool, MAX_NUM_OF_GTP_NODE);
list_init(&self.sgw_list);
index_init(&mme_enb_pool, MAX_NUM_OF_ENB);
@ -139,7 +137,7 @@ static status_t mme_context_validation()
}
while(sgw)
{
if (sgw->gnode.addr == 0)
if (sgw->addr == 0)
{
d_error("No SGW.NEWORK.S11_ADDR in '%s'",
context_self()->config.path);
@ -640,7 +638,7 @@ status_t mme_context_parse_config()
mme_sgw_t *sgw = mme_sgw_add();
d_assert(sgw, return CORE_ERROR,
"Can't add SGW context");
sgw->gnode.port = GTPV2_C_UDP_PORT;
sgw->port = GTPV2_C_UDP_PORT;
for (n = 1; n > 0; m++, n--)
{
@ -649,12 +647,12 @@ status_t mme_context_parse_config()
if (jsmntok_equal(json, t+m, "S11_ADDR") == 0)
{
char *v = jsmntok_to_string(json, t+m+1);
if (v) sgw->gnode.addr = inet_addr(v);
if (v) sgw->addr = inet_addr(v);
}
else if (jsmntok_equal(json, t+m, "S11_PORT") == 0)
{
char *v = jsmntok_to_string(json, t+m+1);
if (v) sgw->gnode.port = atoi(v);
if (v) sgw->port = atoi(v);
}
}
}
@ -846,8 +844,8 @@ mme_sgw_t* mme_sgw_add()
memset(sgw, 0, sizeof(mme_sgw_t));
list_init(&sgw->gnode.local_list);
list_init(&sgw->gnode.remote_list);
list_init(&sgw->local_list);
list_init(&sgw->remote_list);
list_append(&self.sgw_list, sgw);
@ -858,7 +856,7 @@ status_t mme_sgw_remove(mme_sgw_t *sgw)
{
d_assert(sgw, return CORE_ERROR, "Null param");
gtp_xact_delete_all(&sgw->gnode);
gtp_xact_delete_all(sgw);
list_remove(&self.sgw_list, sgw);
pool_free_node(&mme_sgw_pool, sgw);
@ -883,14 +881,14 @@ status_t mme_sgw_remove_all()
return CORE_OK;
}
mme_sgw_t* mme_sgw_find_by_node(gtp_node_t *gnode)
mme_sgw_t* mme_sgw_find_by_node(mme_sgw_t *gnode)
{
mme_sgw_t *sgw = NULL;
sgw = mme_sgw_first();
while (sgw)
{
if (GTP_COMPARE_NODE(&sgw->gnode, gnode))
if (GTP_COMPARE_NODE(sgw, gnode))
break;
sgw = mme_sgw_next(sgw);

View File

@ -33,6 +33,10 @@ extern "C" {
#define MAX_NUM_OF_TAC 256
#define MAX_NUM_OF_BPLMN 6
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 {
c_uint32_t num_of_plmn_id;
plmn_id_t plmn_id[MAX_PLMN_ID];
@ -55,7 +59,7 @@ typedef struct _mme_context_t {
net_sock_t *s11_sock; /* MME S11 local listen socket */
c_uint32_t s5c_addr; /* PGW S5C remote address */
c_uint16_t s5c_port; /* MME S5C remote port */
c_uint16_t s5c_port; /* PGW S5C remote port */
msgq_id queue_id; /* Queue for processing MME control plane */
tm_service_t tm_service; /* Timer Service */
@ -91,19 +95,14 @@ typedef struct _mme_context_t {
/* Timer value */
c_uint32_t t3413_value; /* Paging retry timer */
list_t sgw_list;
list_t enb_list;
list_t sgw_list; /* SGW GTP Node List */
list_t enb_list; /* eNB S1AP Node List */
hash_t *mme_ue_s1ap_id_hash; /* hash table for MME-UE-S1AP-ID */
hash_t *imsi_ue_hash; /* hash table (IMSI : MME_UE) */
hash_t *guti_ue_hash; /* hash table (GUTI : MME_UE) */
} mme_context_t;
typedef struct _mme_sgw_t {
gtp_node_t gnode; /* SGW S11 remote GTPv2-C node */
} mme_sgw_t;
typedef struct _mme_enb_t {
lnode_t node; /* A node of list_t */
index_t index; /* An index of this node */
@ -119,9 +118,6 @@ typedef struct _mme_enb_t {
} mme_enb_t;
typedef struct _enb_ue_t enb_ue_t;
typedef struct _mme_ue_t mme_ue_t;
struct _enb_ue_t {
lnode_t node; /* A node of list_t */
index_t index; /* An index of this node */

View File

@ -29,6 +29,7 @@ static int _gtpv2_c_recv_cb(net_sock_t *sock, void *data)
gnode.addr = sock->remote.sin_addr.s_addr;
gnode.port = ntohs(sock->remote.sin_port);
gnode.sock = sock; /* is it needed? */
sgw = mme_sgw_find_by_node(&gnode);
d_assert(sgw, return -1, "Can't find SGW from [%s:%d]",
@ -39,9 +40,8 @@ static int _gtpv2_c_recv_cb(net_sock_t *sock, void *data)
d_trace_hex(10, pkbuf->payload, pkbuf->len);
event_set(&e, MME_EVT_S11_MESSAGE);
event_set_param1(&e, (c_uintptr_t)sock);
event_set_param2(&e, (c_uintptr_t)sgw);
event_set_param3(&e, (c_uintptr_t)pkbuf);
event_set_param1(&e, (c_uintptr_t)sgw);
event_set_param2(&e, (c_uintptr_t)pkbuf);
rv = mme_event_send(&e);
if (rv != CORE_OK)
{
@ -55,6 +55,7 @@ static int _gtpv2_c_recv_cb(net_sock_t *sock, void *data)
status_t mme_gtp_open()
{
status_t rv;
mme_sgw_t *sgw = mme_sgw_first();
rv = gtp_listen(&mme_self()->s11_sock, _gtpv2_c_recv_cb,
mme_self()->s11_addr, mme_self()->s11_port, NULL);
@ -64,6 +65,13 @@ status_t mme_gtp_open()
return rv;
}
/* socket descriptor needs in gnode when packet is sending initilly */
while(sgw)
{
sgw->sock = mme_self()->s11_sock;
sgw = mme_sgw_next(sgw);
}
return CORE_OK;
}

View File

@ -37,8 +37,7 @@ void mme_s11_handle_create_session_request(mme_sess_t *sess)
d_assert(rv == CORE_OK, return,
"S11 build error");
xact = gtp_xact_local_create(mme_self()->s11_sock, (gtp_node_t *)sess->sgw,
&h, pkbuf);
xact = gtp_xact_local_create(sess->sgw, &h, pkbuf);
d_assert(xact, return, "Null param");
GTP_XACT_STORE_SESSION(xact, sess);
@ -141,8 +140,7 @@ void mme_s11_handle_delete_all_sessions_request_in_ue(mme_ue_t *mme_ue)
rv = mme_s11_build_delete_session_request(&s11buf, h.type, sess);
d_assert(rv == CORE_OK, return, "S11 build error");
xact = gtp_xact_local_create(
mme_self()->s11_sock, (gtp_node_t *)sess->sgw, &h, s11buf);
xact = gtp_xact_local_create(sess->sgw, &h, s11buf);
d_assert(xact, return, "Null param");
GTP_XACT_STORE_SESSION(xact, sess);

View File

@ -262,19 +262,17 @@ void mme_state_operational(fsm_t *s, event_t *e)
case MME_EVT_S11_MESSAGE:
{
status_t rv;
net_sock_t *sock = (net_sock_t *)event_get_param1(e);
gtp_node_t *gnode = (gtp_node_t *)event_get_param2(e);
pkbuf_t *pkbuf = (pkbuf_t *)event_get_param3(e);
gtp_node_t *gnode = (gtp_node_t *)event_get_param1(e);
pkbuf_t *pkbuf = (pkbuf_t *)event_get_param2(e);
gtp_xact_t *xact = NULL;
gtp_message_t message;
mme_ue_t *mme_ue = NULL;
enb_ue_t *enb_ue = NULL;
d_assert(pkbuf, break, "Null param");
d_assert(sock, pkbuf_free(pkbuf); break, "Null param");
d_assert(gnode, pkbuf_free(pkbuf); break, "Null param");
rv = gtp_xact_receive(sock, gnode, pkbuf, &xact, &message);
rv = gtp_xact_receive(gnode, pkbuf, &xact, &message);
if (rv != CORE_OK)
break;

View File

@ -424,8 +424,7 @@ void s1ap_handle_initial_context_setup_response(
rv = mme_s11_build_modify_bearer_request(&pkbuf, h.type, bearer);
d_assert(rv == CORE_OK, return, "S11 build error");
xact = gtp_xact_local_create(
mme_self()->s11_sock, (gtp_node_t *)sess->sgw, &h, pkbuf);
xact = gtp_xact_local_create(sess->sgw, &h, pkbuf);
d_assert(xact, return, "Null param");
rv = gtp_xact_commit(xact);
@ -480,9 +479,7 @@ void s1ap_handle_ue_context_release_request(
&pkbuf, h.type);
d_assert(rv == CORE_OK, return, "S11 build error");
xact = gtp_xact_local_create(
mme_self()->s11_sock, (gtp_node_t *)sess->sgw,
&h, pkbuf);
xact = gtp_xact_local_create(sess->sgw, &h, pkbuf);
d_assert(xact, return, "Null param");
rv = gtp_xact_commit(xact);

View File

@ -13,6 +13,8 @@
static pgw_context_t self;
pool_declare(pgw_sgw_pool, pgw_sgw_t, MAX_NUM_OF_GTP_NODE);
index_declare(pgw_sess_pool, pgw_sess_t, MAX_POOL_OF_SESS);
index_declare(pgw_bearer_pool, pgw_bearer_t, MAX_POOL_OF_BEARER);
@ -27,6 +29,9 @@ status_t pgw_context_init()
memset(&self, 0, sizeof(pgw_context_t));
pool_init(&pgw_sgw_pool, MAX_NUM_OF_GTP_NODE);
list_init(&self.sgw_list);
index_init(&pgw_sess_pool, MAX_POOL_OF_SESS);
index_init(&pgw_bearer_pool, MAX_POOL_OF_BEARER);
@ -50,6 +55,8 @@ status_t pgw_context_final()
gtp_xact_delete_all(&self.s5c_node);
pgw_sess_remove_all();
pgw_sgw_remove_all();
d_assert(self.sess_hash, , "Null param");
hash_destroy(self.sess_hash);
@ -76,6 +83,8 @@ status_t pgw_context_final()
index_final(&pgw_bearer_pool);
index_final(&pgw_sess_pool);
pool_final(&pgw_sgw_pool);
context_initiaized = 0;
return CORE_OK;
@ -474,6 +483,78 @@ status_t pgw_context_setup_trace_module()
return CORE_OK;
}
pgw_sgw_t* pgw_sgw_add()
{
pgw_sgw_t *sgw = NULL;
pool_alloc_node(&pgw_sgw_pool, &sgw);
d_assert(sgw, return NULL, "Null param");
memset(sgw, 0, sizeof(pgw_sgw_t));
list_init(&sgw->local_list);
list_init(&sgw->remote_list);
list_append(&self.sgw_list, sgw);
return sgw;
}
status_t pgw_sgw_remove(pgw_sgw_t *sgw)
{
d_assert(sgw, return CORE_ERROR, "Null param");
gtp_xact_delete_all(sgw);
list_remove(&self.sgw_list, sgw);
pool_free_node(&pgw_sgw_pool, sgw);
return CORE_OK;
}
status_t pgw_sgw_remove_all()
{
pgw_sgw_t *sgw = NULL, *next_sgw = NULL;
sgw = pgw_sgw_first();
while (sgw)
{
next_sgw = pgw_sgw_next(sgw);
pgw_sgw_remove(sgw);
sgw = next_sgw;
}
return CORE_OK;
}
pgw_sgw_t* pgw_sgw_find_by_node(pgw_sgw_t *gnode)
{
pgw_sgw_t *sgw = NULL;
sgw = pgw_sgw_first();
while (sgw)
{
if (GTP_COMPARE_NODE(sgw, gnode))
break;
sgw = pgw_sgw_next(sgw);
}
return sgw;
}
pgw_sgw_t* pgw_sgw_first()
{
return list_first(&self.sgw_list);
}
pgw_sgw_t* pgw_sgw_next(pgw_sgw_t *sgw)
{
return list_next(sgw);
}
static void *sess_hash_keygen(c_uint8_t *out, int *out_len,
c_uint8_t *imsi, int imsi_len, c_int8_t *apn)
{

View File

@ -17,6 +17,8 @@
extern "C" {
#endif /* __cplusplus */
typedef gtp_node_t pgw_sgw_t;
typedef struct _pgw_context_t {
c_uint32_t pgw_addr; /* PGW local address */
@ -46,6 +48,7 @@ typedef struct _pgw_context_t {
c_uint32_t primary_dns_addr;
c_uint32_t secondary_dns_addr;
list_t sgw_list; /* SGW GTP Node List */
list_t ip_pool_list;
hash_t *sess_hash; /* hash table (IMSI+APN) */
@ -115,6 +118,13 @@ CORE_DECLARE(pgw_context_t*) pgw_self(void);
CORE_DECLARE(status_t) pgw_context_parse_config(void);
CORE_DECLARE(status_t) pgw_context_setup_trace_module(void);
CORE_DECLARE(pgw_sgw_t*) pgw_sgw_add(void);
CORE_DECLARE(status_t) pgw_sgw_remove(pgw_sgw_t *sgw);
CORE_DECLARE(status_t) pgw_sgw_remove_all(void);
CORE_DECLARE(pgw_sgw_t*) pgw_sgw_find_by_node(gtp_node_t *gnode);
CORE_DECLARE(pgw_sgw_t*) pgw_sgw_first(void);
CORE_DECLARE(pgw_sgw_t*) pgw_sgw_next(pgw_sgw_t *sgw);
CORE_DECLARE(pgw_sess_t*) pgw_sess_add(
c_uint8_t *imsi, int imsi_len, c_int8_t *apn, c_uint8_t id);
CORE_DECLARE(status_t ) pgw_sess_remove(pgw_sess_t *sess);

View File

@ -64,11 +64,12 @@ static int _gtpv1_tun_recv_cb(net_link_t *net_link, void *data)
/* Send to SGW */
gnode.addr = bearer->sgw_s5u_addr;
gnode.port = GTPV1_U_UDP_PORT;
gnode.sock = pgw_self()->s5u_sock;
d_trace(50, "Send S5U PDU (teid = 0x%x)to SGW(%s)\n",
bearer->sgw_s5u_teid,
INET_NTOP(&gnode.addr, buf));
rv = gtp_send(pgw_self()->s5u_sock, &gnode, recvbuf);
rv = gtp_send(&gnode, recvbuf);
}
else
{
@ -103,9 +104,8 @@ static int _gtpv2_c_recv_cb(net_sock_t *sock, void *data)
d_trace_hex(10, pkbuf->payload, pkbuf->len);
event_set(&e, PGW_EVT_S5C_MESSAGE);
event_set_param1(&e, (c_uintptr_t)sock);
event_set_param2(&e, (c_uintptr_t)gnode);
event_set_param3(&e, (c_uintptr_t)pkbuf);
event_set_param1(&e, (c_uintptr_t)gnode);
event_set_param2(&e, (c_uintptr_t)pkbuf);
rv = pgw_event_send(&e);
if (rv != CORE_OK)
{
@ -167,6 +167,8 @@ status_t pgw_gtp_open()
return rv;
}
pgw_self()->s5c_node.sock = pgw_self()->s5c_sock;
rv = gtp_listen(&pgw_self()->s5u_sock, _gtpv1_u_recv_cb,
pgw_self()->s5u_addr, pgw_self()->s5u_port, NULL);
if (rv != CORE_OK)

View File

@ -63,9 +63,8 @@ void pgw_state_operational(fsm_t *s, event_t *e)
case PGW_EVT_S5C_MESSAGE:
{
status_t rv;
net_sock_t *sock = (net_sock_t *)event_get_param1(e);
gtp_node_t *gnode = (gtp_node_t *)event_get_param2(e);
pkbuf_t *recvbuf = (pkbuf_t *)event_get_param3(e);
gtp_node_t *gnode = (gtp_node_t *)event_get_param1(e);
pkbuf_t *recvbuf = (pkbuf_t *)event_get_param2(e);
pkbuf_t *copybuf = NULL;
c_uint16_t copybuf_len = 0;
gtp_xact_t *xact = NULL;
@ -73,7 +72,6 @@ void pgw_state_operational(fsm_t *s, event_t *e)
pgw_sess_t *sess = NULL;
d_assert(recvbuf, break, "Null param");
d_assert(sock, pkbuf_free(recvbuf); break, "Null param");
d_assert(gnode, pkbuf_free(recvbuf); break, "Null param");
copybuf_len = sizeof(gtp_message_t);
@ -82,7 +80,7 @@ void pgw_state_operational(fsm_t *s, event_t *e)
message = copybuf->payload;
d_assert(message, break, "Null param");
rv = gtp_xact_receive(sock, gnode, recvbuf, &xact, message);
rv = gtp_xact_receive(gnode, recvbuf, &xact, message);
if (rv != CORE_OK)
break;

View File

@ -12,6 +12,9 @@
#include "context.h"
#include "sgw_context.h"
pool_declare(sgw_mme_pool, sgw_mme_t, MAX_NUM_OF_GTP_NODE);
pool_declare(sgw_pgw_pool, sgw_pgw_t, MAX_NUM_OF_GTP_NODE);
static sgw_context_t self;
index_declare(sgw_ue_pool, sgw_ue_t, MAX_POOL_OF_UE);
@ -27,6 +30,11 @@ status_t sgw_context_init()
memset(&self, 0, sizeof(sgw_context_t));
pool_init(&sgw_mme_pool, MAX_NUM_OF_GTP_NODE);
list_init(&self.mme_list);
pool_init(&sgw_pgw_pool, MAX_NUM_OF_GTP_NODE);
list_init(&self.pgw_list);
index_init(&sgw_ue_pool, MAX_POOL_OF_UE);
index_init(&sgw_sess_pool, MAX_POOL_OF_SESS);
index_init(&sgw_bearer_pool, MAX_POOL_OF_BEARER);
@ -54,6 +62,9 @@ status_t sgw_context_final()
sgw_ue_remove_all();
sgw_mme_remove_all();
sgw_pgw_remove_all();
d_assert(self.imsi_ue_hash, , "Null param");
hash_destroy(self.imsi_ue_hash);
@ -61,6 +72,9 @@ status_t sgw_context_final()
index_final(&sgw_sess_pool);
index_final(&sgw_ue_pool);
pool_final(&sgw_mme_pool);
pool_final(&sgw_pgw_pool);
context_initialized = 0;
return CORE_OK;
@ -433,6 +447,150 @@ status_t sgw_context_setup_trace_module()
return CORE_OK;
}
sgw_mme_t* sgw_mme_add()
{
sgw_mme_t *sgw = NULL;
pool_alloc_node(&sgw_mme_pool, &sgw);
d_assert(sgw, return NULL, "Null param");
memset(sgw, 0, sizeof(sgw_mme_t));
list_init(&sgw->local_list);
list_init(&sgw->remote_list);
list_append(&self.mme_list, sgw);
return sgw;
}
status_t sgw_mme_remove(sgw_mme_t *sgw)
{
d_assert(sgw, return CORE_ERROR, "Null param");
gtp_xact_delete_all(sgw);
list_remove(&self.mme_list, sgw);
pool_free_node(&sgw_mme_pool, sgw);
return CORE_OK;
}
status_t sgw_mme_remove_all()
{
sgw_mme_t *sgw = NULL, *next_sgw = NULL;
sgw = sgw_mme_first();
while (sgw)
{
next_sgw = sgw_mme_next(sgw);
sgw_mme_remove(sgw);
sgw = next_sgw;
}
return CORE_OK;
}
sgw_mme_t* sgw_mme_find_by_node(sgw_mme_t *gnode)
{
sgw_mme_t *sgw = NULL;
sgw = sgw_mme_first();
while (sgw)
{
if (GTP_COMPARE_NODE(sgw, gnode))
break;
sgw = sgw_mme_next(sgw);
}
return sgw;
}
sgw_mme_t* sgw_mme_first()
{
return list_first(&self.mme_list);
}
sgw_mme_t* sgw_mme_next(sgw_mme_t *sgw)
{
return list_next(sgw);
}
sgw_pgw_t* sgw_pgw_add()
{
sgw_pgw_t *sgw = NULL;
pool_alloc_node(&sgw_pgw_pool, &sgw);
d_assert(sgw, return NULL, "Null param");
memset(sgw, 0, sizeof(sgw_pgw_t));
list_init(&sgw->local_list);
list_init(&sgw->remote_list);
list_append(&self.pgw_list, sgw);
return sgw;
}
status_t sgw_pgw_remove(sgw_pgw_t *sgw)
{
d_assert(sgw, return CORE_ERROR, "Null param");
gtp_xact_delete_all(sgw);
list_remove(&self.pgw_list, sgw);
pool_free_node(&sgw_pgw_pool, sgw);
return CORE_OK;
}
status_t sgw_pgw_remove_all()
{
sgw_pgw_t *sgw = NULL, *next_sgw = NULL;
sgw = sgw_pgw_first();
while (sgw)
{
next_sgw = sgw_pgw_next(sgw);
sgw_pgw_remove(sgw);
sgw = next_sgw;
}
return CORE_OK;
}
sgw_pgw_t* sgw_pgw_find_by_node(sgw_pgw_t *gnode)
{
sgw_pgw_t *sgw = NULL;
sgw = sgw_pgw_first();
while (sgw)
{
if (GTP_COMPARE_NODE(sgw, gnode))
break;
sgw = sgw_pgw_next(sgw);
}
return sgw;
}
sgw_pgw_t* sgw_pgw_first()
{
return list_first(&self.pgw_list);
}
sgw_pgw_t* sgw_pgw_next(sgw_pgw_t *sgw)
{
return list_next(sgw);
}
sgw_ue_t* sgw_ue_add(
c_uint8_t *imsi, int imsi_len, c_int8_t *apn, c_uint8_t ebi)
{

View File

@ -16,6 +16,9 @@
extern "C" {
#endif /* __cplusplus */
typedef gtp_node_t sgw_mme_t;
typedef gtp_node_t sgw_pgw_t;
typedef struct _sgw_context_t {
c_uint32_t sgw_addr; /* SGW local address */
@ -40,6 +43,9 @@ typedef struct _sgw_context_t {
msgq_id queue_id; /* Queue for processing SGW control plane */
tm_service_t tm_service; /* Timer Service */
list_t mme_list; /* MME GTP Node List */
list_t pgw_list; /* PGW GTP Node List */
hash_t *imsi_ue_hash; /* hash table (IMSI : SGW_UE) */
} sgw_context_t;
@ -131,6 +137,20 @@ CORE_DECLARE(sgw_context_t*) sgw_self(void);
CORE_DECLARE(status_t) sgw_context_parse_config(void);
CORE_DECLARE(status_t) sgw_context_setup_trace_module(void);
CORE_DECLARE(sgw_mme_t*) sgw_mme_add(void);
CORE_DECLARE(status_t) sgw_mme_remove(sgw_mme_t *sgw);
CORE_DECLARE(status_t) sgw_mme_remove_all(void);
CORE_DECLARE(sgw_mme_t*) sgw_mme_find_by_node(gtp_node_t *gnode);
CORE_DECLARE(sgw_mme_t*) sgw_mme_first(void);
CORE_DECLARE(sgw_mme_t*) sgw_mme_next(sgw_mme_t *sgw);
CORE_DECLARE(sgw_pgw_t*) sgw_pgw_add(void);
CORE_DECLARE(status_t) sgw_pgw_remove(sgw_pgw_t *sgw);
CORE_DECLARE(status_t) sgw_pgw_remove_all(void);
CORE_DECLARE(sgw_pgw_t*) sgw_pgw_find_by_node(gtp_node_t *gnode);
CORE_DECLARE(sgw_pgw_t*) sgw_pgw_first(void);
CORE_DECLARE(sgw_pgw_t*) sgw_pgw_next(sgw_pgw_t *sgw);
CORE_DECLARE(sgw_ue_t*) sgw_ue_add(c_uint8_t *imsi, int imsi_len,
c_int8_t *apn, c_uint8_t id);
CORE_DECLARE(status_t) sgw_ue_remove(sgw_ue_t *sgw_ue);

View File

@ -44,9 +44,8 @@ static int _gtpv2_c_recv_cb(net_sock_t *sock, void *data)
d_trace_hex(10, pkbuf->payload, pkbuf->len);
event_set_param1(&e, (c_uintptr_t)sock);
event_set_param2(&e, (c_uintptr_t)gnode);
event_set_param3(&e, (c_uintptr_t)pkbuf);
event_set_param1(&e, (c_uintptr_t)gnode);
event_set_param2(&e, (c_uintptr_t)pkbuf);
rv = sgw_event_send(&e);
if (rv != CORE_OK)
{
@ -94,8 +93,9 @@ static int _gtpv1_s5u_recv_cb(net_sock_t *sock, void *data)
gnode.addr = sock->remote.sin_addr.s_addr;
gnode.port = GTPV1_U_UDP_PORT;
gnode.sock = sgw_self()->s5u_sock;
gtp_send(sgw_self()->s5u_sock, &gnode, echo_rsp);
gtp_send(&gnode, echo_rsp);
pkbuf_free(echo_rsp);
}
}
@ -115,6 +115,7 @@ static int _gtpv1_s5u_recv_cb(net_sock_t *sock, void *data)
gnode.addr = bearer->enb_s1u_addr;
gnode.port = GTPV1_U_UDP_PORT;
gnode.sock = sgw_self()->s1u_sock;
/* If there is buffered packet, send it first */
if (bearer->num_buffered_pkt)
@ -126,14 +127,13 @@ static int _gtpv1_s5u_recv_cb(net_sock_t *sock, void *data)
(gtp_header_t *)bearer->buffered_pkts[i]->payload;
gtp_h->teid = htonl(bearer->enb_s1u_teid);
gtp_send(sgw_self()->s1u_sock, &gnode,
bearer->buffered_pkts[i]);
gtp_send(&gnode, bearer->buffered_pkts[i]);
pkbuf_free(bearer->buffered_pkts[i]);
}
bearer->num_buffered_pkt = 0;
}
gtp_send(sgw_self()->s1u_sock, &gnode, pkbuf);
gtp_send(&gnode, pkbuf);
}
else
{
@ -209,8 +209,9 @@ static int _gtpv1_s1u_recv_cb(net_sock_t *sock, void *data)
gnode.addr = sock->remote.sin_addr.s_addr;
gnode.port = GTPV1_U_UDP_PORT;
gnode.sock = sgw_self()->s1u_sock;
gtp_send(sgw_self()->s1u_sock, &gnode, echo_rsp);
gtp_send(&gnode, echo_rsp);
pkbuf_free(echo_rsp);
}
}
@ -227,8 +228,9 @@ static int _gtpv1_s1u_recv_cb(net_sock_t *sock, void *data)
gnode.addr = bearer->pgw_s5u_addr;
gnode.port = GTPV1_U_UDP_PORT;
gnode.sock = sgw_self()->s5u_sock;
gtp_send(sgw_self()->s5u_sock, &gnode, pkbuf);
gtp_send(&gnode, pkbuf);
}
}
@ -248,6 +250,8 @@ status_t sgw_gtp_open()
return rv;
}
sgw_self()->s11_node.sock = sgw_self()->s11_sock;
rv = gtp_listen(&sgw_self()->s5c_sock, _gtpv2_c_recv_cb,
sgw_self()->s5c_addr, sgw_self()->s5c_port, &sgw_self()->s5c_node);
if (rv != CORE_OK)
@ -256,6 +260,8 @@ status_t sgw_gtp_open()
return rv;
}
sgw_self()->s5c_node.sock = sgw_self()->s5c_sock;
rv = gtp_listen(&sgw_self()->s5u_sock, _gtpv1_s5u_recv_cb,
sgw_self()->s5u_addr, sgw_self()->s5u_port, NULL);
if (rv != CORE_OK)

View File

@ -96,7 +96,7 @@ void sgw_handle_create_session_request(gtp_xact_t *s11_xact,
rv = gtp_build_msg(&pkbuf, gtp_message);
d_assert(rv == CORE_OK, return, "gtp build failed");
s5c_xact = gtp_xact_local_create(sgw_self()->s5c_sock,
s5c_xact = gtp_xact_local_create(
&sgw_self()->s5c_node, &gtp_message->h, pkbuf);
d_assert(s5c_xact, return, "Null param");
@ -208,8 +208,7 @@ void sgw_handle_delete_session_request(gtp_xact_t *s11_xact,
d_assert(rv == CORE_OK, return, "gtp build failed");
s5c_xact = gtp_xact_local_create(
sgw_self()->s5c_sock, &sgw_self()->s5c_node,
&gtp_message->h, pkbuf);
&sgw_self()->s5c_node, &gtp_message->h, pkbuf);
d_assert(s5c_xact, return, "Null param");
gtp_xact_associate(s11_xact, s5c_xact);
@ -320,8 +319,8 @@ void sgw_handle_lo_dldata_notification(sgw_bearer_t *bearer)
rv = gtp_build_msg(&pkbuf, &gtp_message);
d_assert(rv == CORE_OK, return, "gtp build failed");
xact = gtp_xact_local_create(sgw_self()->s11_sock, &sgw_self()->s11_node,
&gtp_message.h, pkbuf);
xact = gtp_xact_local_create(
&sgw_self()->s11_node, &gtp_message.h, pkbuf);
d_assert(xact, return, "Null param");
rv = gtp_xact_commit(xact);

View File

@ -56,18 +56,16 @@ void sgw_state_operational(fsm_t *s, event_t *e)
case SGW_EVT_S11_MESSAGE:
{
status_t rv;
net_sock_t *sock = (net_sock_t *)event_get_param1(e);
gtp_node_t *gnode = (gtp_node_t *)event_get_param2(e);
pkbuf_t *pkbuf = (pkbuf_t *)event_get_param3(e);
gtp_node_t *gnode = (gtp_node_t *)event_get_param1(e);
pkbuf_t *pkbuf = (pkbuf_t *)event_get_param2(e);
gtp_xact_t *xact = NULL;
gtp_message_t message;
sgw_ue_t *sgw_ue = NULL;
d_assert(pkbuf, break, "Null param");
d_assert(sock, pkbuf_free(pkbuf); break, "Null param");
d_assert(gnode, pkbuf_free(pkbuf); break, "Null param");
rv = gtp_xact_receive(sock, gnode, pkbuf, &xact, &message);
rv = gtp_xact_receive(gnode, pkbuf, &xact, &message);
if (rv != CORE_OK)
break;
@ -107,18 +105,16 @@ void sgw_state_operational(fsm_t *s, event_t *e)
case SGW_EVT_S5C_MESSAGE:
{
status_t rv;
net_sock_t *sock = (net_sock_t *)event_get_param1(e);
gtp_node_t *gnode = (gtp_node_t *)event_get_param2(e);
pkbuf_t *pkbuf = (pkbuf_t *)event_get_param3(e);
gtp_node_t *gnode = (gtp_node_t *)event_get_param1(e);
pkbuf_t *pkbuf = (pkbuf_t *)event_get_param2(e);
gtp_xact_t *xact = NULL;
gtp_message_t message;
sgw_sess_t *sess = NULL;
d_assert(pkbuf, break, "Null param");
d_assert(sock, pkbuf_free(pkbuf); break, "Null param");
d_assert(gnode, pkbuf_free(pkbuf); break, "Null param");
rv = gtp_xact_receive(sock, gnode, pkbuf, &xact, &message);
rv = gtp_xact_receive(gnode, pkbuf, &xact, &message);
if (rv != CORE_OK)
break;