All GTP re-archi done

This commit is contained in:
Sukchan Lee 2017-09-02 01:48:09 +09:00
parent 6ddaa2a91e
commit 3bef0ac82f
11 changed files with 165 additions and 306 deletions

View File

@ -637,9 +637,7 @@ status_t gtp_xact_receive(gtp_node_t *gnode, pkbuf_t *pkbuf,
new = gtp_xact_find_by_xid(gnode, h->type, GTP_SQN_TO_XID(h->sqn));
if (!new)
{
new = gtp_xact_remote_create(gnode, h->sqn);
}
d_assert(new, return CORE_ERROR, "Null param");
d_trace(3, "[%d] %s Receive peer %s:%d\n",

View File

@ -881,14 +881,14 @@ status_t mme_sgw_remove_all()
return CORE_OK;
}
mme_sgw_t* mme_sgw_find_by_node(mme_sgw_t *gnode)
mme_sgw_t* mme_sgw_find(c_uint32_t addr, c_uint16_t port)
{
mme_sgw_t *sgw = NULL;
sgw = mme_sgw_first();
while (sgw)
{
if (GTP_COMPARE_NODE(sgw, gnode))
if (sgw->addr == addr && sgw->port == port)
break;
sgw = mme_sgw_next(sgw);

View File

@ -321,7 +321,7 @@ CORE_DECLARE(status_t) mme_context_setup_trace_module(void);
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);
CORE_DECLARE(mme_sgw_t*) mme_sgw_find_by_node(gtp_node_t *gnode);
CORE_DECLARE(mme_sgw_t*) mme_sgw_find(c_uint32_t addr, c_uint16_t port);
CORE_DECLARE(mme_sgw_t*) mme_sgw_first(void);
CORE_DECLARE(mme_sgw_t*) mme_sgw_next(mme_sgw_t *sgw);

View File

@ -13,7 +13,8 @@ static int _gtpv2_c_recv_cb(net_sock_t *sock, void *data)
status_t rv;
event_t e;
pkbuf_t *pkbuf = NULL;
gtp_node_t gnode;
c_uint32_t addr;
c_uint16_t port;
mme_sgw_t *sgw = NULL;
d_assert(sock, return -1, "Null param");
@ -27,16 +28,17 @@ static int _gtpv2_c_recv_cb(net_sock_t *sock, void *data)
return -1;
}
gnode.addr = sock->remote.sin_addr.s_addr;
gnode.port = ntohs(sock->remote.sin_port);
gnode.sock = sock; /* is it needed? */
addr = sock->remote.sin_addr.s_addr;
port = ntohs(sock->remote.sin_port);
sgw = mme_sgw_find_by_node(&gnode);
sgw = mme_sgw_find(addr, port);
d_assert(sgw, return -1, "Can't find SGW from [%s:%d]",
INET_NTOP(&gnode.addr, buf), gnode.port);
INET_NTOP(&addr, buf), port);
sgw->sock = sock; /* Is it needed? */
d_trace(10, "S11_PDU is received from SGW[%s:%d]\n",
INET_NTOP(&gnode.addr, buf), gnode.port);
INET_NTOP(&addr, buf), port);
d_trace_hex(10, pkbuf->payload, pkbuf->len);
event_set(&e, MME_EVT_S11_MESSAGE);

View File

@ -37,9 +37,6 @@ status_t pgw_context_init()
pool_init(&pgw_ip_pool_pool, MAX_POOL_OF_SESS);
list_init(&self.s5c_node.local_list);
list_init(&self.s5c_node.remote_list);
self.sess_hash = hash_make();
context_initiaized = 1;
@ -52,9 +49,7 @@ status_t pgw_context_final()
d_assert(context_initiaized == 1, return CORE_ERROR,
"PGW context already has been finalized");
gtp_xact_delete_all(&self.s5c_node);
pgw_sess_remove_all();
pgw_sgw_remove_all();
d_assert(self.sess_hash, , "Null param");
@ -98,8 +93,6 @@ pgw_context_t* pgw_self()
static status_t pgw_context_prepare()
{
self.s5c_port = GTPV2_C_UDP_PORT;
self.s5c_node.port = GTPV2_C_UDP_PORT;
self.s5u_port = GTPV1_U_UDP_PORT;
return CORE_OK;
@ -113,12 +106,6 @@ static status_t pgw_context_validation()
context_self()->config.path);
return CORE_ERROR;
}
if (self.s5c_node.addr == 0)
{
d_error("No SGW.NEWORK.S5C_ADDR in '%s'",
context_self()->config.path);
return CORE_ERROR;
}
if (self.s5c_addr == 0)
{
d_error("No PGW.NEWORK.S5C_ADDR in '%s'",
@ -162,7 +149,6 @@ status_t pgw_context_parse_config()
typedef enum {
START, ROOT,
SGW_START, SGW_ROOT,
PGW_START, PGW_ROOT,
SKIP, STOP
} parse_state;
@ -170,7 +156,6 @@ status_t pgw_context_parse_config()
parse_state stack = STOP;
size_t root_tokens = 0;
size_t sgw_tokens = 0;
size_t pgw_tokens = 0;
size_t skip_tokens = 0;
int i, j, m, n;
@ -196,11 +181,7 @@ status_t pgw_context_parse_config()
}
case ROOT:
{
if (jsmntok_equal(json, t, "SGW") == 0)
{
state = SGW_START;
}
else if (jsmntok_equal(json, t, "PGW") == 0)
if (jsmntok_equal(json, t, "PGW") == 0)
{
state = PGW_START;
}
@ -215,53 +196,6 @@ status_t pgw_context_parse_config()
}
break;
}
case SGW_START:
{
state = SGW_ROOT;
sgw_tokens = t->size;
break;
}
case SGW_ROOT:
{
if (jsmntok_equal(json, t, "NETWORK") == 0)
{
m = 1;
size = 1;
if ((t+1)->type == JSMN_ARRAY)
{
m = 2;
}
for (arr = 0; arr < size; arr++)
{
for (n = 1; n > 0; m++, n--)
{
n += (t+m)->size;
if (jsmntok_equal(json, t+m, "S5C_ADDR") == 0)
{
char *v = jsmntok_to_string(json, t+m+1);
if (v) self.s5c_node.addr = inet_addr(v);
}
else if (jsmntok_equal(json, t+m, "S5C_PORT") == 0)
{
char *v = jsmntok_to_string(json, t+m+1);
if (v) self.s5c_node.port = atoi(v);
}
}
}
}
state = SKIP;
stack = SGW_ROOT;
skip_tokens = t->size;
sgw_tokens--;
if (sgw_tokens == 0) stack = ROOT;
break;
}
case PGW_START:
{
state = PGW_ROOT;
@ -529,14 +463,14 @@ status_t pgw_sgw_remove_all()
return CORE_OK;
}
pgw_sgw_t* pgw_sgw_find_by_node(pgw_sgw_t *gnode)
pgw_sgw_t* pgw_sgw_find(c_uint32_t addr, c_uint16_t port)
{
pgw_sgw_t *sgw = NULL;
sgw = pgw_sgw_first();
while (sgw)
{
if (GTP_COMPARE_NODE(sgw, gnode))
if (sgw->addr == addr && sgw->port == port)
break;
sgw = pgw_sgw_next(sgw);

View File

@ -25,7 +25,6 @@ typedef struct _pgw_context_t {
c_uint32_t s5c_addr; /* PGW S5-C local address */
c_uint32_t s5c_port; /* PGW S5-C local port */
net_sock_t* s5c_sock; /* PGW S5-C local listen socket */
gtp_node_t s5c_node; /* PGW S5-C remote GTPv2-C node */
c_uint32_t s5u_addr; /* PGW S5-U local address */
c_uint32_t s5u_port; /* PGW S5-U local port */
@ -121,7 +120,7 @@ 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_find(c_uint32_t addr, c_uint16_t port);
CORE_DECLARE(pgw_sgw_t*) pgw_sgw_first(void);
CORE_DECLARE(pgw_sgw_t*) pgw_sgw_next(pgw_sgw_t *sgw);

View File

@ -86,10 +86,11 @@ static int _gtpv2_c_recv_cb(net_sock_t *sock, void *data)
event_t e;
status_t rv;
pkbuf_t *pkbuf = NULL;
gtp_node_t *gnode = data;
c_uint32_t addr;
c_uint16_t port;
pgw_sgw_t *sgw = NULL;
d_assert(sock, return -1, "Null param");
d_assert(gnode, return -1, "Null param");
pkbuf = gtp_read(sock);
if (pkbuf == NULL)
@ -103,8 +104,22 @@ static int _gtpv2_c_recv_cb(net_sock_t *sock, void *data)
d_trace(10, "S5-C PDU received from PGW\n");
d_trace_hex(10, pkbuf->payload, pkbuf->len);
addr = sock->remote.sin_addr.s_addr;
port = ntohs(sock->remote.sin_port);
sgw = pgw_sgw_find(addr, port);
if (!sgw)
{
sgw = pgw_sgw_add();
d_assert(sgw, return -1, "Can't add MME-GTP node");
sgw->addr = addr;
sgw->port = port;
sgw->sock = sock;
}
event_set(&e, PGW_EVT_S5C_MESSAGE);
event_set_param1(&e, (c_uintptr_t)gnode);
event_set_param1(&e, (c_uintptr_t)sgw);
event_set_param2(&e, (c_uintptr_t)pkbuf);
rv = pgw_event_send(&e);
if (rv != CORE_OK)
@ -160,15 +175,13 @@ status_t pgw_gtp_open()
status_t rv;
rv = gtp_listen(&pgw_self()->s5c_sock, _gtpv2_c_recv_cb,
pgw_self()->s5c_addr, pgw_self()->s5c_port, &pgw_self()->s5c_node);
pgw_self()->s5c_addr, pgw_self()->s5c_port, NULL);
if (rv != CORE_OK)
{
d_error("Can't establish S5-C Path for PGW");
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

@ -39,12 +39,6 @@ status_t sgw_context_init()
index_init(&sgw_sess_pool, MAX_POOL_OF_SESS);
index_init(&sgw_bearer_pool, MAX_POOL_OF_BEARER);
list_init(&self.s11_node.local_list);
list_init(&self.s11_node.remote_list);
list_init(&self.s5c_node.local_list);
list_init(&self.s5c_node.remote_list);
self.imsi_ue_hash = hash_make();
context_initialized = 1;
@ -57,11 +51,7 @@ status_t sgw_context_final()
d_assert(context_initialized == 1, return CORE_ERROR,
"SGW context already has been finalized");
gtp_xact_delete_all(&self.s11_node);
gtp_xact_delete_all(&self.s5c_node);
sgw_ue_remove_all();
sgw_mme_remove_all();
sgw_pgw_remove_all();
@ -88,11 +78,7 @@ sgw_context_t* sgw_self()
static status_t sgw_context_prepare()
{
self.s11_port = GTPV2_C_UDP_PORT;
self.s11_node.port = GTPV2_C_UDP_PORT;
self.s5c_port = GTPV2_C_UDP_PORT;
self.s5c_node.port = GTPV2_C_UDP_PORT;
self.s1u_port = GTPV1_U_UDP_PORT;
self.s5u_port = GTPV1_U_UDP_PORT;
@ -101,18 +87,6 @@ static status_t sgw_context_prepare()
static status_t sgw_context_validation()
{
if (self.s11_node.addr == 0)
{
d_error("No MME.NEWORK.S11_ADDR in '%s'",
context_self()->config.path);
return CORE_ERROR;
}
if (self.s5c_node.addr == 0)
{
d_error("No PGW.NEWORK.S5C_ADDR in '%s'",
context_self()->config.path);
return CORE_ERROR;
}
if (self.s11_addr == 0)
{
d_error("No SGW.NEWORK.S11_ADDR in '%s'",
@ -150,18 +124,14 @@ status_t sgw_context_parse_config()
typedef enum {
START, ROOT,
MME_START, MME_ROOT,
SGW_START, SGW_ROOT,
PGW_START, PGW_ROOT,
SKIP, STOP
} parse_state;
parse_state state = START;
parse_state stack = STOP;
size_t root_tokens = 0;
size_t mme_tokens = 0;
size_t sgw_tokens = 0;
size_t pgw_tokens = 0;
size_t skip_tokens = 0;
int i, j, m, n;
int arr, size;
@ -186,18 +156,10 @@ status_t sgw_context_parse_config()
}
case ROOT:
{
if (jsmntok_equal(json, t, "MME") == 0)
{
state = MME_START;
}
else if (jsmntok_equal(json, t, "SGW") == 0)
if (jsmntok_equal(json, t, "SGW") == 0)
{
state = SGW_START;
}
else if (jsmntok_equal(json, t, "PGW") == 0)
{
state = PGW_START;
}
else
{
state = SKIP;
@ -209,53 +171,6 @@ status_t sgw_context_parse_config()
}
break;
}
case MME_START:
{
state = MME_ROOT;
mme_tokens = t->size;
break;
}
case MME_ROOT:
{
if (jsmntok_equal(json, t, "NETWORK") == 0)
{
m = 1;
size = 1;
if ((t+1)->type == JSMN_ARRAY)
{
m = 2;
}
for (arr = 0; arr < size; arr++)
{
for (n = 1; n > 0; m++, n--)
{
n += (t+m)->size;
if (jsmntok_equal(json, t+m, "S11_ADDR") == 0)
{
char *v = jsmntok_to_string(json, t+m+1);
if (v) self.s11_node.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) self.s11_node.port = atoi(v);
}
}
}
}
state = SKIP;
stack = MME_ROOT;
skip_tokens = t->size;
mme_tokens--;
if (mme_tokens == 0) stack = ROOT;
break;
}
case SGW_START:
{
state = SGW_ROOT;
@ -333,53 +248,6 @@ status_t sgw_context_parse_config()
if (sgw_tokens == 0) stack = ROOT;
break;
}
case PGW_START:
{
state = PGW_ROOT;
pgw_tokens = t->size;
break;
}
case PGW_ROOT:
{
if (jsmntok_equal(json, t, "NETWORK") == 0)
{
m = 1;
size = 1;
if ((t+1)->type == JSMN_ARRAY)
{
m = 2;
}
for (arr = 0; arr < size; arr++)
{
for (n = 1; n > 0; m++, n--)
{
n += (t+m)->size;
if (jsmntok_equal(json, t+m, "S5C_ADDR") == 0)
{
char *v = jsmntok_to_string(json, t+m+1);
if (v) self.s5c_node.addr = inet_addr(v);
}
else if (jsmntok_equal(json, t+m, "S5C_PORT") == 0)
{
char *v = jsmntok_to_string(json, t+m+1);
if (v) self.s5c_node.port = atoi(v);
}
}
}
}
state = SKIP;
stack = PGW_ROOT;
skip_tokens = t->size;
pgw_tokens--;
if (pgw_tokens == 0) stack = ROOT;
break;
}
case SKIP:
{
skip_tokens += t->size;
@ -449,64 +317,64 @@ status_t sgw_context_setup_trace_module()
sgw_mme_t* sgw_mme_add()
{
sgw_mme_t *sgw = NULL;
sgw_mme_t *mme = NULL;
pool_alloc_node(&sgw_mme_pool, &sgw);
d_assert(sgw, return NULL, "Null param");
pool_alloc_node(&sgw_mme_pool, &mme);
d_assert(mme, return NULL, "Null param");
memset(sgw, 0, sizeof(sgw_mme_t));
memset(mme, 0, sizeof(sgw_mme_t));
list_init(&sgw->local_list);
list_init(&sgw->remote_list);
list_init(&mme->local_list);
list_init(&mme->remote_list);
list_append(&self.mme_list, sgw);
list_append(&self.mme_list, mme);
return sgw;
return mme;
}
status_t sgw_mme_remove(sgw_mme_t *sgw)
status_t sgw_mme_remove(sgw_mme_t *mme)
{
d_assert(sgw, return CORE_ERROR, "Null param");
d_assert(mme, return CORE_ERROR, "Null param");
gtp_xact_delete_all(sgw);
gtp_xact_delete_all(mme);
list_remove(&self.mme_list, sgw);
pool_free_node(&sgw_mme_pool, sgw);
list_remove(&self.mme_list, mme);
pool_free_node(&sgw_mme_pool, mme);
return CORE_OK;
}
status_t sgw_mme_remove_all()
{
sgw_mme_t *sgw = NULL, *next_sgw = NULL;
sgw_mme_t *mme = NULL, *next_mme = NULL;
sgw = sgw_mme_first();
while (sgw)
mme = sgw_mme_first();
while (mme)
{
next_sgw = sgw_mme_next(sgw);
next_mme = sgw_mme_next(mme);
sgw_mme_remove(sgw);
sgw_mme_remove(mme);
sgw = next_sgw;
mme = next_mme;
}
return CORE_OK;
}
sgw_mme_t* sgw_mme_find_by_node(sgw_mme_t *gnode)
sgw_mme_t* sgw_mme_find(c_uint32_t addr, c_uint16_t port)
{
sgw_mme_t *sgw = NULL;
sgw_mme_t *mme = NULL;
sgw = sgw_mme_first();
while (sgw)
mme = sgw_mme_first();
while (mme)
{
if (GTP_COMPARE_NODE(sgw, gnode))
if (mme->addr == addr && mme->port == port)
break;
sgw = sgw_mme_next(sgw);
mme = sgw_mme_next(mme);
}
return sgw;
return mme;
}
sgw_mme_t* sgw_mme_first()
@ -514,71 +382,71 @@ sgw_mme_t* sgw_mme_first()
return list_first(&self.mme_list);
}
sgw_mme_t* sgw_mme_next(sgw_mme_t *sgw)
sgw_mme_t* sgw_mme_next(sgw_mme_t *mme)
{
return list_next(sgw);
return list_next(mme);
}
sgw_pgw_t* sgw_pgw_add()
{
sgw_pgw_t *sgw = NULL;
sgw_pgw_t *pgw = NULL;
pool_alloc_node(&sgw_pgw_pool, &sgw);
d_assert(sgw, return NULL, "Null param");
pool_alloc_node(&sgw_pgw_pool, &pgw);
d_assert(pgw, return NULL, "Null param");
memset(sgw, 0, sizeof(sgw_pgw_t));
memset(pgw, 0, sizeof(sgw_pgw_t));
list_init(&sgw->local_list);
list_init(&sgw->remote_list);
list_init(&pgw->local_list);
list_init(&pgw->remote_list);
list_append(&self.pgw_list, sgw);
list_append(&self.pgw_list, pgw);
return sgw;
return pgw;
}
status_t sgw_pgw_remove(sgw_pgw_t *sgw)
status_t sgw_pgw_remove(sgw_pgw_t *pgw)
{
d_assert(sgw, return CORE_ERROR, "Null param");
d_assert(pgw, return CORE_ERROR, "Null param");
gtp_xact_delete_all(sgw);
gtp_xact_delete_all(pgw);
list_remove(&self.pgw_list, sgw);
pool_free_node(&sgw_pgw_pool, sgw);
list_remove(&self.pgw_list, pgw);
pool_free_node(&sgw_pgw_pool, pgw);
return CORE_OK;
}
status_t sgw_pgw_remove_all()
{
sgw_pgw_t *sgw = NULL, *next_sgw = NULL;
sgw_pgw_t *pgw = NULL, *next_pgw = NULL;
sgw = sgw_pgw_first();
while (sgw)
pgw = sgw_pgw_first();
while (pgw)
{
next_sgw = sgw_pgw_next(sgw);
next_pgw = sgw_pgw_next(pgw);
sgw_pgw_remove(sgw);
sgw_pgw_remove(pgw);
sgw = next_sgw;
pgw = next_pgw;
}
return CORE_OK;
}
sgw_pgw_t* sgw_pgw_find_by_node(sgw_pgw_t *gnode)
sgw_pgw_t* sgw_pgw_find(c_uint32_t addr, c_uint16_t port)
{
sgw_pgw_t *sgw = NULL;
sgw_pgw_t *pgw = NULL;
sgw = sgw_pgw_first();
while (sgw)
pgw = sgw_pgw_first();
while (pgw)
{
if (GTP_COMPARE_NODE(sgw, gnode))
if (pgw->addr == addr && pgw->port == port)
break;
sgw = sgw_pgw_next(sgw);
pgw = sgw_pgw_next(pgw);
}
return sgw;
return pgw;
}
sgw_pgw_t* sgw_pgw_first()
@ -586,9 +454,9 @@ sgw_pgw_t* sgw_pgw_first()
return list_first(&self.pgw_list);
}
sgw_pgw_t* sgw_pgw_next(sgw_pgw_t *sgw)
sgw_pgw_t* sgw_pgw_next(sgw_pgw_t *pgw)
{
return list_next(sgw);
return list_next(pgw);
}
sgw_ue_t* sgw_ue_add(

View File

@ -25,12 +25,10 @@ typedef struct _sgw_context_t {
c_uint32_t s11_addr; /* SGW S11 local address */
c_uint32_t s11_port; /* SGW S11 local port */
net_sock_t* s11_sock; /* SGW S11 local listen socket */
gtp_node_t s11_node; /* MME S11 remote GTPv2-C node */
c_uint32_t s5c_addr; /* SGW S5-C local address */
c_uint32_t s5c_port; /* SGW S5-C local port */
net_sock_t* s5c_sock; /* SGW S5-C local listen socket */
gtp_node_t s5c_node; /* PGW S5-C remote GTPv2-C node */
c_uint32_t s1u_addr; /* SGW S1-U local address */
c_uint32_t s1u_port; /* SGW S1-U local port */
@ -85,6 +83,8 @@ typedef struct _sgw_sess_t {
list_t bearer_list;
/* Related Context */
sgw_mme_t *mme;
sgw_mme_t *pgw;
sgw_ue_t *sgw_ue;
} sgw_sess_t;
@ -138,18 +138,18 @@ 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(sgw_mme_t *mme);
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_find(c_uint32_t addr, c_uint16_t port);
CORE_DECLARE(sgw_mme_t*) sgw_mme_first(void);
CORE_DECLARE(sgw_mme_t*) sgw_mme_next(sgw_mme_t *sgw);
CORE_DECLARE(sgw_mme_t*) sgw_mme_next(sgw_mme_t *mme);
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(sgw_pgw_t *pgw);
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_find(c_uint32_t addr, c_uint16_t port);
CORE_DECLARE(sgw_pgw_t*) sgw_pgw_first(void);
CORE_DECLARE(sgw_pgw_t*) sgw_pgw_next(sgw_pgw_t *sgw);
CORE_DECLARE(sgw_pgw_t*) sgw_pgw_next(sgw_pgw_t *pgw);
CORE_DECLARE(sgw_ue_t*) sgw_ue_add(c_uint8_t *imsi, int imsi_len,
c_int8_t *apn, c_uint8_t id);

View File

@ -15,10 +15,12 @@ static int _gtpv2_c_recv_cb(net_sock_t *sock, void *data)
event_t e;
status_t rv;
pkbuf_t *pkbuf = NULL;
gtp_node_t *gnode = data;
c_uint32_t addr;
c_uint16_t port;
event_e event = (event_e)data;
d_assert(sock, return -1, "Null param");
d_assert(gnode, return -1, "Null param");
d_assert(data, return -1, "Null param");
pkbuf = gtp_read(sock);
if (pkbuf == NULL)
@ -29,23 +31,42 @@ static int _gtpv2_c_recv_cb(net_sock_t *sock, void *data)
return -1;
}
if (GTP_COMPARE_NODE(gnode, &sgw_self()->s11_node))
addr = sock->remote.sin_addr.s_addr;
port = ntohs(sock->remote.sin_port);
event_set(&e, event);
event_set_param2(&e, (c_uintptr_t)pkbuf);
if (event == SGW_EVT_S11_MESSAGE)
{
sgw_mme_t *mme = sgw_mme_find(addr, port);
if (!mme)
{
mme = sgw_mme_add();
d_assert(mme, return -1, "Can't add MME-GTP node");
mme->addr = addr;
mme->port = port;
mme->sock = sock;
}
d_trace(10, "S11 PDU received from MME\n");
event_set(&e, SGW_EVT_S11_MESSAGE);
event_set_param1(&e, (c_uintptr_t)mme);
}
else if (GTP_COMPARE_NODE(gnode, &sgw_self()->s5c_node))
else if (event == SGW_EVT_S5C_MESSAGE)
{
sgw_pgw_t *pgw = sgw_pgw_find(addr, port);
d_assert(pgw, return -1, "Can't add PGW-GTP node");
d_trace(10, "S5-C PDU received from PGW\n");
event_set(&e, SGW_EVT_S5C_MESSAGE);
event_set_param1(&e, (c_uintptr_t)pgw);
}
else
d_assert(0, pkbuf_free(pkbuf); return -1, "Unknown GTP-Node");
d_trace_hex(10, pkbuf->payload, pkbuf->len);
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)
{
@ -243,25 +264,23 @@ status_t sgw_gtp_open()
status_t rv;
rv = gtp_listen(&sgw_self()->s11_sock, _gtpv2_c_recv_cb,
sgw_self()->s11_addr, sgw_self()->s11_port, &sgw_self()->s11_node);
sgw_self()->s11_addr, sgw_self()->s11_port,
(void*)SGW_EVT_S11_MESSAGE);
if (rv != CORE_OK)
{
d_error("Can't establish S11 Path for SGW");
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);
sgw_self()->s5c_addr, sgw_self()->s5c_port,
(void*)SGW_EVT_S5C_MESSAGE);
if (rv != CORE_OK)
{
d_error("Can't establish S5-C Path for SGW");
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

@ -17,6 +17,10 @@ void sgw_handle_create_session_request(gtp_xact_t *s11_xact,
gtp_create_session_request_t *req = NULL;
pkbuf_t *pkbuf = NULL;
gtp_f_teid_t *mme_s11_teid = NULL;
gtp_f_teid_t *pgw_s5c_teid = NULL;
sgw_pgw_t *pgw = NULL;
c_uint32_t addr;
c_uint16_t port;
gtp_f_teid_t sgw_s5c_teid, sgw_s5u_teid;
gtp_xact_t *s5c_xact = NULL;
@ -49,6 +53,11 @@ void sgw_handle_create_session_request(gtp_xact_t *s11_xact,
d_error("No APN");
return;
}
if (req->pgw_s5_s8_address_for_control_plane_or_pmip.presence == 0)
{
d_error("No PGW IP");
return;
}
sess = sgw_sess_find_by_ebi(sgw_ue,
req->bearer_contexts_to_be_created.eps_bearer_id.u8);
@ -78,6 +87,26 @@ void sgw_handle_create_session_request(gtp_xact_t *s11_xact,
req->sender_f_teid_for_control_plane.len = GTP_F_TEID_IPV4_LEN;
/* Remove PGW-S5C */
pgw_s5c_teid = req->pgw_s5_s8_address_for_control_plane_or_pmip.data;
addr = pgw_s5c_teid->ipv4_addr;
port = GTPV2_C_UDP_PORT;
pgw = sgw_pgw_find(addr, port);
if (!pgw)
{
pgw = sgw_pgw_add();
d_assert(pgw, return, "Can't add PGW-GTP node");
pgw->addr = addr;
pgw->port = port;
pgw->sock = sgw_self()->s5c_sock;
}
/* Setup GTP Node */
sess->pgw = pgw;
sess->mme = s11_xact->gnode;
req->pgw_s5_s8_address_for_control_plane_or_pmip.presence = 0;
/* Send Data Plane(DL) : SGW-S5U */
@ -96,8 +125,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_node, &gtp_message->h, pkbuf);
s5c_xact = gtp_xact_local_create(sess->pgw, &gtp_message->h, pkbuf);
d_assert(s5c_xact, return, "Null param");
gtp_xact_associate(s11_xact, s5c_xact);
@ -207,8 +235,7 @@ void sgw_handle_delete_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_node, &gtp_message->h, pkbuf);
s5c_xact = gtp_xact_local_create(sess->pgw, &gtp_message->h, pkbuf);
d_assert(s5c_xact, return, "Null param");
gtp_xact_associate(s11_xact, s5c_xact);
@ -319,8 +346,7 @@ 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_node, &gtp_message.h, pkbuf);
xact = gtp_xact_local_create(sess->mme, &gtp_message.h, pkbuf);
d_assert(xact, return, "Null param");
rv = gtp_xact_commit(xact);