GTP Peer Node finding method is changed.

Before : received IP address from UDP socket
After : Based on TEID. Initially, finding from Sender F-TEID
This commit is contained in:
Sukchan Lee
2017-11-21 14:52:07 +09:00
parent 21d2ca34f6
commit 7151a98f41
14 changed files with 174 additions and 358 deletions

View File

@@ -660,18 +660,14 @@ out:
return CORE_ERROR;
}
status_t gtp_xact_receive(gtp_node_t *gnode, pkbuf_t *pkbuf,
gtp_xact_t **xact, gtp_message_t *message)
status_t gtp_xact_receive(
gtp_node_t *gnode, gtp_header_t *h, gtp_xact_t **xact)
{
char buf[INET_ADDRSTRLEN];
status_t rv;
gtp_xact_t *new = NULL;
gtp_header_t *h = NULL;
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");
h = pkbuf->payload;
d_assert(h, return CORE_ERROR, "Null param");
new = gtp_xact_find_by_xid(gnode, h->type, GTP_SQN_TO_XID(h->sqn));
@@ -687,14 +683,9 @@ status_t gtp_xact_receive(gtp_node_t *gnode, pkbuf_t *pkbuf,
rv = gtp_xact_update_rx(new, h->type);
if (rv != CORE_OK)
{
pkbuf_free(pkbuf);
return rv;
}
rv = gtp_parse_msg(message, pkbuf);
d_assert(rv == CORE_OK,
pkbuf_free(pkbuf); return CORE_ERROR, "parse error");
*xact = new;
return CORE_OK;
}

View File

@@ -74,8 +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(
gtp_node_t *gnode, pkbuf_t *pkbuf,
gtp_xact_t **xact, gtp_message_t *gtp_message);
gtp_node_t *gnode, gtp_header_t *h, gtp_xact_t **xact);
CORE_DECLARE(gtp_xact_t *) gtp_xact_find(index_t index);
CORE_DECLARE(gtp_xact_t *)gtp_xact_find_by_xid(

View File

@@ -35,9 +35,7 @@ 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)addr);
event_set_param2(&e, (c_uintptr_t)port);
event_set_param3(&e, (c_uintptr_t)pkbuf);
event_set_param1(&e, (c_uintptr_t)pkbuf);
rv = mme_event_send(&e);
if (rv != CORE_OK)
{

View File

@@ -344,28 +344,26 @@ void mme_state_operational(fsm_t *s, event_t *e)
case MME_EVT_S11_MESSAGE:
{
status_t rv;
gtp_node_t *gnode = NULL;
c_uint32_t addr = (c_uint32_t)event_get_param1(e);
c_uint16_t port = (c_uint16_t)event_get_param2(e);
pkbuf_t *pkbuf = (pkbuf_t *)event_get_param3(e);
pkbuf_t *pkbuf = (pkbuf_t *)event_get_param1(e);
gtp_xact_t *xact = NULL;
gtp_message_t message;
mme_ue_t *mme_ue = NULL;
d_assert(pkbuf, break, "Null param");
gnode = mme_sgw_find(addr, port);
d_assert(gnode, pkbuf_free(pkbuf); break, "Null param");
rv = gtp_xact_receive(gnode, pkbuf, &xact, &message);
if (rv != CORE_OK)
break;
d_assert(xact, return, "Null param");
rv = gtp_parse_msg(&message, pkbuf);
d_assert(rv == CORE_OK, pkbuf_free(pkbuf); break, "parse error");
mme_ue = mme_ue_find_by_teid(message.h.teid);
d_assert(mme_ue, pkbuf_free(pkbuf); break,
"No UE Context(TEID:%d)", message.h.teid);
rv = gtp_xact_receive(mme_ue->sgw, &message.h, &xact);
if (rv != CORE_OK)
{
pkbuf_free(pkbuf);
break;
}
switch(message.h.type)
{
case GTP_CREATE_SESSION_RESPONSE_TYPE:

View File

@@ -469,11 +469,14 @@ static void *sess_hash_keygen(c_uint8_t *out, int *out_len,
return out;
}
pgw_sess_t *pgw_sess_add(
pgw_sess_t *pgw_sess_add(gtp_f_teid_t *sgw_s5c_teid,
c_uint8_t *imsi, int imsi_len, c_int8_t *apn, c_uint8_t ebi)
{
pgw_sess_t *sess = NULL;
pgw_bearer_t *bearer = NULL;
pgw_sgw_t *sgw = NULL;
c_uint32_t addr = 0;
c_uint16_t port = 0;
index_alloc(&pgw_sess_pool, &sess);
d_assert(sess, return NULL, "Null param");
@@ -486,6 +489,22 @@ pgw_sess_t *pgw_sess_add(
memcpy(sess->imsi, imsi, sess->imsi_len);
core_buffer_to_bcd(sess->imsi, sess->imsi_len, sess->imsi_bcd);
addr = sgw_s5c_teid->ipv4_addr;
port = GTPV2_C_UDP_PORT;
sgw = pgw_sgw_find(addr, port);
if (!sgw)
{
sgw = pgw_sgw_add();
d_assert(sgw, return NULL, "Can't add SGW-GTP node");
sgw->addr = addr;
sgw->port = port;
sgw->sock = pgw_self()->gtpc_sock;
}
/* Setup GTP Node between PGW and SGW */
CONNECT_SGW_GTP_NODE(sess, sgw);
/* Set APN */
core_cpystrn(sess->pdn.apn, apn, MAX_APN_LEN+1);
@@ -570,23 +589,41 @@ pgw_sess_t *pgw_sess_find_or_add_by_message(gtp_message_t *gtp_message)
gtp_create_session_request_t *req = &gtp_message->create_session_request;
c_int8_t apn[MAX_APN_LEN];
if (req->sender_f_teid_for_control_plane.presence == 0)
if (req->imsi.presence == 0)
{
d_error("No IMSI");
return NULL;
}
if (req->sender_f_teid_for_control_plane.presence == 0)
{
d_error("No Sender F-TEID");
return NULL;
}
if (req->access_point_name.presence == 0)
{
d_error("No APN");
return NULL;
}
if (req->bearer_contexts_to_be_created.presence == 0)
{
d_error("No Bearer");
return NULL;
}
if (req->bearer_contexts_to_be_created.eps_bearer_id.presence == 0)
{
d_error("No EPS Bearer ID");
return NULL;
}
apn_parse(apn, req->access_point_name.data, req->access_point_name.len);
sess = pgw_sess_find_by_imsi_apn(req->imsi.data, req->imsi.len, apn);
if (!sess)
{
sess = pgw_sess_add(req->imsi.data, req->imsi.len, apn,
sess = pgw_sess_add(
req->sender_f_teid_for_control_plane.data,
req->imsi.data, req->imsi.len, apn,
req->bearer_contexts_to_be_created.eps_bearer_id.u8);
d_assert(sess, return NULL, "No Session Context");
}

View File

@@ -92,11 +92,11 @@ typedef struct _pgw_sess_t {
list_t bearer_list;
/* Related Context */
#define CONNECT_SGW_GTP_NODE(__sESS, __xACT) \
#define CONNECT_SGW_GTP_NODE(__sESS, __gNODE) \
do { \
d_assert((__sESS), return, "Null param"); \
d_assert((__xACT), return, "Null param"); \
(__sESS)->sgw = (__xACT)->gnode; \
d_assert((__sESS), return NULL, "Null param"); \
d_assert((__gNODE), return NULL, "Null param"); \
(__sESS)->sgw = (__gNODE); \
} while(0)
pgw_sgw_t *sgw;
} pgw_sess_t;
@@ -175,8 +175,8 @@ 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);
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(pgw_sess_t*) pgw_sess_add(gtp_f_teid_t *sgw_s5c_teid,
c_uint8_t *imsi, int imsi_len, c_int8_t *apn, c_uint8_t ebi);
CORE_DECLARE(status_t ) pgw_sess_remove(pgw_sess_t *sess);
CORE_DECLARE(status_t ) pgw_sess_remove_all();
CORE_DECLARE(pgw_sess_t*) pgw_sess_find(index_t index);

View File

@@ -86,9 +86,6 @@ static int _gtpv2_c_recv_cb(net_sock_t *sock, void *data)
event_t e;
status_t rv;
pkbuf_t *pkbuf = NULL;
c_uint32_t addr;
c_uint16_t port;
pgw_sgw_t *sgw = NULL;
d_assert(sock, return -1, "Null param");
@@ -104,23 +101,8 @@ 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)sgw);
event_set_param2(&e, (c_uintptr_t)pkbuf);
event_set_param1(&e, (c_uintptr_t)pkbuf);
rv = pgw_event_send(&e);
if (rv != CORE_OK)
{

View File

@@ -23,9 +23,6 @@ void pgw_gx_handle_cca_initial_request(
d_assert(cca_message, return, "Null param");
d_assert(req, return, "Null param");
/* Setup GTP Node between PGW and SGW */
CONNECT_SGW_GTP_NODE(sess, xact);
/* Send Create Session Request with Creating Default Bearer */
memset(&h, 0, sizeof(gtp_header_t));
h.type = GTP_CREATE_SESSION_RESPONSE_TYPE;

View File

@@ -63,8 +63,7 @@ void pgw_state_operational(fsm_t *s, event_t *e)
case PGW_EVT_S5C_MESSAGE:
{
status_t rv;
gtp_node_t *gnode = (gtp_node_t *)event_get_param1(e);
pkbuf_t *recvbuf = (pkbuf_t *)event_get_param2(e);
pkbuf_t *recvbuf = (pkbuf_t *)event_get_param1(e);
pkbuf_t *copybuf = NULL;
c_uint16_t copybuf_len = 0;
gtp_xact_t *xact = NULL;
@@ -72,7 +71,6 @@ void pgw_state_operational(fsm_t *s, event_t *e)
pgw_sess_t *sess = NULL;
d_assert(recvbuf, break, "Null param");
d_assert(gnode, pkbuf_free(recvbuf); break, "Null param");
copybuf_len = sizeof(gtp_message_t);
copybuf = pkbuf_alloc(0, copybuf_len);
@@ -80,15 +78,26 @@ void pgw_state_operational(fsm_t *s, event_t *e)
message = copybuf->payload;
d_assert(message, break, "Null param");
rv = gtp_xact_receive(gnode, recvbuf, &xact, message);
if (rv != CORE_OK)
break;
rv = gtp_parse_msg(message, recvbuf);
d_assert(rv == CORE_OK,
pkbuf_free(recvbuf); pkbuf_free(copybuf); break,
"parse error");
if (message->h.type == GTP_CREATE_SESSION_REQUEST_TYPE)
sess = pgw_sess_find_or_add_by_message(message);
else
sess = pgw_sess_find_by_teid(message->h.teid);
d_assert(sess, pkbuf_free(recvbuf); break, "No Session Context");
d_assert(sess,
pkbuf_free(recvbuf); pkbuf_free(copybuf); break,
"No Session Context");
rv = gtp_xact_receive(sess->sgw, &message->h, &xact);
if (rv != CORE_OK)
{
pkbuf_free(recvbuf);
pkbuf_free(copybuf);
break;
}
switch(message->h.type)
{
@@ -97,24 +106,22 @@ void pgw_state_operational(fsm_t *s, event_t *e)
xact, sess, &message->create_session_request);
pgw_gx_send_ccr(xact, sess, copybuf,
GX_CC_REQUEST_TYPE_INITIAL_REQUEST);
goto out;
break;
case GTP_DELETE_SESSION_REQUEST_TYPE:
pgw_s5c_handle_delete_session_request(
xact, sess, &message->delete_session_request);
pgw_gx_send_ccr(xact, sess, copybuf,
GX_CC_REQUEST_TYPE_TERMINATION_REQUEST);
goto out;
break;
case GTP_CREATE_BEARER_RESPONSE_TYPE:
pgw_s5c_handle_create_bearer_response(
xact, sess, &message->create_bearer_response);
pkbuf_free(copybuf);
break;
default:
d_warn("Not implmeneted(type:%d)", message->h.type);
break;
}
pkbuf_free(copybuf);
out:
pkbuf_free(recvbuf);
break;
}

View File

@@ -377,11 +377,20 @@ sgw_pgw_t* sgw_pgw_next(sgw_pgw_t *pgw)
return list_next(pgw);
}
sgw_ue_t* sgw_ue_add(
sgw_ue_t* sgw_ue_add(gtp_f_teid_t *mme_s11_teid,
c_uint8_t *imsi, int imsi_len, c_int8_t *apn, c_uint8_t ebi)
{
sgw_ue_t *sgw_ue = NULL;
sgw_sess_t *sess = NULL;
sgw_mme_t *mme = NULL;
c_uint32_t addr = 0;
c_uint16_t port = 0;
d_assert(mme_s11_teid, return NULL, "Null param");
d_assert(imsi, return NULL, "Null param");
d_assert(imsi_len, return NULL, "Null param");
d_assert(apn, return NULL, "Null param");
d_assert(ebi, return NULL, "Null param");
index_alloc(&sgw_ue_pool, &sgw_ue);
d_assert(sgw_ue, return NULL, "Null param");
@@ -389,6 +398,21 @@ sgw_ue_t* sgw_ue_add(
sgw_ue->sgw_s11_teid = sgw_ue->index;
sgw_ue->sgw_s11_addr = sgw_self()->gtpc_addr;
addr = mme_s11_teid->ipv4_addr;
port = GTPV2_C_UDP_PORT;
mme = sgw_mme_find(addr, port);
if (!mme)
{
mme = sgw_mme_add();
d_assert(mme, return NULL, "Can't add MME-GTP node");
mme->addr = addr;
mme->port = port;
mme->sock = sgw_self()->gtpc_sock;
}
CONNECT_MME_GTP_NODE(sgw_ue, mme);
/* Set IMSI */
sgw_ue->imsi_len = imsi_len;
memcpy(sgw_ue->imsi, imsi, sgw_ue->imsi_len);
@@ -433,7 +457,7 @@ status_t sgw_ue_remove_all()
return CORE_OK;
}
sgw_ue_t* sgw_ue_find(index_t index)
static sgw_ue_t* sgw_ue_find(index_t index)
{
d_assert(index, return NULL, "Invalid index = 0x%x", index);
return index_find(&sgw_ue_pool, index);
@@ -469,24 +493,42 @@ sgw_ue_t *sgw_ue_find_or_add_by_message(gtp_message_t *gtp_message)
gtp_create_session_request_t *req = &gtp_message->create_session_request;
if (req->sender_f_teid_for_control_plane.presence == 0)
if (req->imsi.presence == 0)
{
d_error("No IMSI");
return NULL;
}
if (req->sender_f_teid_for_control_plane.presence == 0)
{
d_error("No Sender F-TEID");
return NULL;
}
if (req->access_point_name.presence == 0)
{
d_error("No APN");
return NULL;
}
if (req->bearer_contexts_to_be_created.presence == 0)
{
d_error("No Bearer");
return NULL;
}
if (req->bearer_contexts_to_be_created.eps_bearer_id.presence == 0)
{
d_error("No EPS Bearer ID");
return NULL;
}
sgw_ue = sgw_ue_find_by_imsi(req->imsi.data, req->imsi.len);
if (!sgw_ue)
{
c_int8_t apn[MAX_APN_LEN];
apn_parse(apn, req->access_point_name.data, req->access_point_name.len);
sgw_ue = sgw_ue_add(req->imsi.data, req->imsi.len, apn,
sgw_ue = sgw_ue_add(
req->sender_f_teid_for_control_plane.data,
req->imsi.data, req->imsi.len, apn,
req->bearer_contexts_to_be_created.eps_bearer_id.u8);
d_assert(sgw_ue, return NULL, "No UE Context");
}
@@ -523,7 +565,7 @@ sgw_sess_t *sgw_sess_add(
index_alloc(&sgw_sess_pool, &sess);
d_assert(sess, return NULL, "Null param");
sess->sgw_s5c_teid = sess->index;
sess->sgw_s5c_teid = SGW_S5C_INDEX_TO_TEID(sess->index);
sess->sgw_s5c_addr = sgw_self()->gtpc_addr;
/* Set APN */
@@ -574,7 +616,7 @@ status_t sgw_sess_remove_all(sgw_ue_t *sgw_ue)
return CORE_OK;
}
sgw_sess_t* sgw_sess_find(index_t index)
static sgw_sess_t* sgw_sess_find(index_t index)
{
d_assert(index, return NULL, "Invalid Index");
return index_find(&sgw_sess_pool, index);
@@ -582,7 +624,7 @@ sgw_sess_t* sgw_sess_find(index_t index)
sgw_sess_t* sgw_sess_find_by_teid(c_uint32_t teid)
{
return sgw_sess_find(teid);
return sgw_sess_find(SGW_S5C_TEID_TO_INDEX(teid));
}
sgw_sess_t* sgw_sess_find_by_apn(sgw_ue_t *sgw_ue, c_int8_t *apn)

View File

@@ -8,6 +8,7 @@
#include "core_hash.h"
#include "gtp_xact.h"
#include "gtp_types.h"
#include "types.h"
#include "sgw_sm.h"
@@ -65,11 +66,11 @@ typedef struct _sgw_ue_t {
list_t sess_list;
#define CONNECT_MME_GTP_NODE(__sGW, __xACT) \
#define CONNECT_MME_GTP_NODE(__sGW, __gNODE) \
do { \
d_assert((__sGW), return, "Null param"); \
d_assert((__xACT), return, "Null param"); \
(__sGW)->mme = (__xACT)->gnode; \
d_assert((__sGW), return NULL, "Null param"); \
d_assert((__gNODE), return NULL, "Null param"); \
(__sGW)->mme = (__gNODE); \
} while(0)
sgw_mme_t *mme;
} sgw_ue_t;
@@ -79,7 +80,12 @@ typedef struct _sgw_sess_t {
index_t index; /* An index of this node */
/* IMPORTANT!
* SGW-S5C-F-TEID is same with an index */
* SGW-S5C-TEID = INDEX | 0x80000000
* INDEX = SGW-S5C-TEID & ~0x80000000
*/
#define SGW_S5C_TEID(__tEID) (__tEID & 0x80000000)
#define SGW_S5C_TEID_TO_INDEX(__iNDEX) (__iNDEX & ~0x80000000)
#define SGW_S5C_INDEX_TO_TEID(__iNDEX) (__iNDEX | 0x80000000)
c_uint32_t sgw_s5c_teid;
c_uint32_t sgw_s5c_addr;
c_uint32_t pgw_s5c_teid; /* PGW-S5C-F-TEID */
@@ -97,7 +103,7 @@ typedef struct _sgw_sess_t {
d_assert((__gNODE), return, "Null param"); \
(__sESS)->pgw = __gNODE; \
} while(0)
sgw_mme_t *pgw;
sgw_pgw_t *pgw;
sgw_ue_t *sgw_ue;
} sgw_sess_t;
@@ -157,12 +163,11 @@ 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 *pgw);
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(sgw_ue_t*) sgw_ue_add(gtp_f_teid_t *mme_s11_teid,
c_uint8_t *imsi, int imsi_len, c_int8_t *apn, c_uint8_t ebi);
CORE_DECLARE(status_t) sgw_ue_remove(sgw_ue_t *sgw_ue);
CORE_DECLARE(status_t) sgw_ue_remove_all();
CORE_DECLARE(sgw_ue_t*) sgw_ue_find(index_t index);
CORE_DECLARE(sgw_ue_t*) sgw_ue_find_by_imsi(c_uint8_t *imsi, int imsi_len);
CORE_DECLARE(sgw_ue_t*) sgw_ue_find_by_imsi_bcd(c_int8_t *imsi_bcd);
CORE_DECLARE(sgw_ue_t*) sgw_ue_find_by_teid(c_uint32_t teid);
@@ -177,7 +182,6 @@ CORE_DECLARE(sgw_sess_t*) sgw_sess_add(sgw_ue_t *sgw_ue,
c_int8_t *apn, c_uint8_t ebi);
CORE_DECLARE(status_t ) sgw_sess_remove(sgw_sess_t *sess);
CORE_DECLARE(status_t ) sgw_sess_remove_all(sgw_ue_t *sgw_ue);
CORE_DECLARE(sgw_sess_t*) sgw_sess_find(index_t index);
CORE_DECLARE(sgw_sess_t*) sgw_sess_find_by_apn(
sgw_ue_t *sgw_ue, c_int8_t *apn);
CORE_DECLARE(sgw_sess_t*) sgw_sess_find_by_ebi(

View File

@@ -16,10 +16,8 @@ static int _gtpv2_c_recv_cb(net_sock_t *sock, void *data)
event_t e;
status_t rv;
gtp_header_t *gtp_h = NULL;
c_uint32_t teid = 0;
pkbuf_t *pkbuf = NULL;
c_uint32_t addr = 0;
c_uint16_t port = 0;
sgw_mme_t *mme = NULL;
d_assert(sock, return -1, "Null param");
@@ -34,39 +32,20 @@ static int _gtpv2_c_recv_cb(net_sock_t *sock, void *data)
gtp_h = (gtp_header_t *)pkbuf->payload;
d_assert(gtp_h, return -1, "Null param");
d_assert(gtp_h->teid_presence, return -1,);
teid = ntohl(gtp_h->teid);
addr = sock->remote.sin_addr.s_addr;
port = ntohs(sock->remote.sin_port);
mme = sgw_mme_find(addr, port);
if (!mme && gtp_h->teid == 0)
if (SGW_S5C_TEID(teid))
{
mme = sgw_mme_add();
d_assert(mme, return -1, "Can't add MME-GTP node");
mme->addr = addr;
mme->port = port;
mme->sock = sock;
}
if (mme)
{
d_trace(10, "S11 PDU received from MME\n");
event_set(&e, SGW_EVT_S11_MESSAGE);
event_set_param1(&e, (c_uintptr_t)mme);
event_set_param2(&e, (c_uintptr_t)pkbuf);
d_trace(10, "S5C PDU received from PGW\n");
event_set(&e, SGW_EVT_S5C_MESSAGE);
}
else
{
d_trace(10, "S5C PDU received from PGW\n");
event_set(&e, SGW_EVT_S5C_MESSAGE);
event_set_param1(&e, (c_uintptr_t)addr);
event_set_param2(&e, (c_uintptr_t)port);
event_set_param3(&e, (c_uintptr_t)pkbuf);
d_trace(10, "S11 PDU received from MME\n");
event_set(&e, SGW_EVT_S11_MESSAGE);
}
event_set_param1(&e, (c_uintptr_t)pkbuf);
d_trace_hex(10, pkbuf->payload, pkbuf->len);
@@ -241,222 +220,6 @@ static int _gtpv1_u_recv_cb(net_sock_t *sock, void *data)
return 0;
}
#if 0
static int _gtpv1_s5u_recv_cb(net_sock_t *sock, void *data)
{
pkbuf_t *pkbuf = NULL;
gtp_node_t gnode;
gtp_header_t *gtp_h = NULL;
sgw_bearer_t *bearer = NULL;
c_uint32_t teid;
d_assert(sock, return -1, "Null param");
pkbuf = gtp_read(sock);
if (pkbuf == NULL)
{
if (sock->sndrcv_errno == EAGAIN)
return 0;
return -1;
}
d_trace(50, "S5-U PDU received from PGW\n");
d_trace_hex(50, pkbuf->payload, pkbuf->len);
gtp_h = (gtp_header_t *)pkbuf->payload;
if (gtp_h->type == GTPU_MSGTYPE_ECHO_REQ)
{
pkbuf_t *echo_rsp;
d_trace(3, "Received echo-req");
echo_rsp = gtp_handle_echo_req(pkbuf);
if (echo_rsp)
{
/* Echo reply */
d_trace(3, "Send echo-rsp to peer(PGW) ");
gnode.addr = sock->remote.sin_addr.s_addr;
gnode.port = GTPV1_U_UDP_PORT;
gnode.sock = sgw_self()->s5u_sock;
gtp_send(&gnode, echo_rsp);
pkbuf_free(echo_rsp);
}
}
else if (gtp_h->type == GTPU_MSGTYPE_GPDU)
{
teid = ntohl(gtp_h->teid);
d_trace(50, "Recv GPDU (teid = 0x%x)",teid);
bearer = sgw_bearer_find_by_sgw_s5u_teid(teid);
if (bearer)
{
if (bearer->enb_s1u_teid)
{
/* Convert Teid and send to enodeB via s1u */
gtp_h->teid = htonl(bearer->enb_s1u_teid);
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)
{
int i;
for (i = 0; i < bearer->num_buffered_pkt; i++)
{
gtp_h =
(gtp_header_t *)bearer->buffered_pkts[i]->payload;
gtp_h->teid = htonl(bearer->enb_s1u_teid);
gtp_send(&gnode, bearer->buffered_pkts[i]);
pkbuf_free(bearer->buffered_pkts[i]);
}
bearer->num_buffered_pkt = 0;
}
gtp_send(&gnode, pkbuf);
}
else
{
/* S1U path is deactivated.
* Send downlink_data_notification to MME.
*
*/
sgw_ue_t *sgw_ue = NULL;
d_assert(bearer->sess, pkbuf_free(pkbuf); return 0,
"Session is NULL");
d_assert(bearer->sess->sgw_ue, pkbuf_free(pkbuf); return 0,
"SGW_UE is NULL");
sgw_ue = bearer->sess->sgw_ue;
if ((SGW_GET_UE_STATE(sgw_ue) & SGW_S1U_INACTIVE))
{
if ( !(SGW_GET_UE_STATE(sgw_ue) & SGW_DL_NOTI_SENT))
{
event_t e;
status_t rv;
event_set(&e, SGW_EVT_LO_DLDATA_NOTI);
event_set_param1(&e, (c_uintptr_t)bearer->index);
rv = sgw_event_send(&e);
if (rv != CORE_OK)
{
d_error("sgw_event_send error");
pkbuf_free(pkbuf);
return -1;
}
SGW_SET_UE_STATE(sgw_ue, SGW_DL_NOTI_SENT);
}
/* Buffer the packet */
if (bearer->num_buffered_pkt < MAX_NUM_BUFFER_PKT)
{
bearer->buffered_pkts[bearer->num_buffered_pkt++] =
pkbuf;
return 0;
}
}
else
{
/* UE is S1U_ACTIVE state but there is no s1u teid */
d_warn("UE is ACITVE but there is no matched "
"s1u_teid(tedid = 0x%x)",teid);
/* Just drop it */
}
}
}
}
pkbuf_free(pkbuf);
return 0;
}
static int _gtpv1_s1u_recv_cb(net_sock_t *sock, void *data)
{
pkbuf_t *pkbuf = NULL;
gtp_node_t gnode;
gtp_header_t *gtp_h = NULL;
sgw_tunnel_t *tunnel = NULL;
c_uint32_t teid;
d_assert(sock, return -1, "Null param");
pkbuf = gtp_read(sock);
if (pkbuf == NULL)
{
if (sock->sndrcv_errno == EAGAIN)
return 0;
return -1;
}
d_trace(50, "S1-U PDU received from ENB\n");
d_trace_hex(50, pkbuf->payload, pkbuf->len);
gtp_h = (gtp_header_t *)pkbuf->payload;
if (gtp_h->type == GTPU_MSGTYPE_ECHO_REQ)
{
pkbuf_t *echo_rsp;
d_trace(3, "Received echo-req\n");
echo_rsp = gtp_handle_echo_req(pkbuf);
if (echo_rsp)
{
/* Echo reply */
d_trace(3, "Send echo-rsp to peer(ENB)\n");
gnode.addr = sock->remote.sin_addr.s_addr;
gnode.port = GTPV1_U_UDP_PORT;
gnode.sock = sgw_self()->s1u_sock;
gtp_send(&gnode, echo_rsp);
pkbuf_free(echo_rsp);
}
}
else if (gtp_h->type == GTPU_MSGTYPE_GPDU ||
gtp_h->type == GTPU_MSGTYPE_END_MARKER)
{
teid = ntohl(gtp_h->teid);
d_trace(50, "Recv GPDU (teid = 0x%x) from ENB\n",teid);
tunnel = sgw_tunnel_find_by_teid(teid);
if (tunnel)
{
gtp_h->teid = htonl(tunnel->remote_teid);
gnode.addr = tunnel->remote_addr;
gnode.port = GTPV1_U_UDP_PORT;
if (tunnel->interface_type == GTP_F_TEID_S1_U_SGW_GTP_U)
gnode.sock = sgw_self()->s5u_sock;
else if (tunnel->interface_type ==
GTP_F_TEID_SGW_GTP_U_FOR_DL_DATA_FORWARDING)
gnode.sock = sgw_self()->s1u_sock;
else if (tunnel->interface_type ==
GTP_F_TEID_SGW_GTP_U_FOR_UL_DATA_FORWARDING)
gnode.sock = sgw_self()->s1u_sock;
else
d_assert(0, return -1, "Invalid type(%d)",
tunnel->interface_type);
gtp_send(&gnode, pkbuf);
}
}
pkbuf_free(pkbuf);
return 0;
}
#endif
status_t sgw_gtp_open()
{
status_t rv;

View File

@@ -37,11 +37,6 @@ void sgw_s11_handle_create_session_request(gtp_xact_t *s11_xact,
req = &gtp_message->create_session_request;
if (req->sender_f_teid_for_control_plane.presence == 0)
{
d_error("No TEID");
return;
}
if (req->bearer_contexts_to_be_created.presence == 0)
{
d_error("No Bearer");
@@ -77,6 +72,7 @@ void sgw_s11_handle_create_session_request(gtp_xact_t *s11_xact,
sess = sgw_sess_add(sgw_ue, apn,
req->bearer_contexts_to_be_created.eps_bearer_id.u8);
}
d_assert(sess, return, "Null param");
bearer = sgw_default_bearer_in_sess(sess);
d_assert(bearer, return, "Null param");
@@ -117,7 +113,6 @@ void sgw_s11_handle_create_session_request(gtp_xact_t *s11_xact,
}
/* Setup GTP Node */
CONNECT_MME_GTP_NODE(sgw_ue, s11_xact);
CONNECT_PGW_GTP_NODE(sess, pgw);
req->pgw_s5_s8_address_for_control_plane_or_pmip.presence = 0;

View File

@@ -56,18 +56,14 @@ void sgw_state_operational(fsm_t *s, event_t *e)
case SGW_EVT_S11_MESSAGE:
{
status_t rv;
gtp_node_t *gnode = (gtp_node_t *)event_get_param1(e);
pkbuf_t *pkbuf = (pkbuf_t *)event_get_param2(e);
pkbuf_t *pkbuf = (pkbuf_t *)event_get_param1(e);
gtp_xact_t *xact = NULL;
gtp_message_t message;
sgw_ue_t *sgw_ue = NULL;
d_assert(pkbuf, break, "Null param");
d_assert(gnode, pkbuf_free(pkbuf); break, "Null param");
rv = gtp_xact_receive(gnode, pkbuf, &xact, &message);
if (rv != CORE_OK)
break;
rv = gtp_parse_msg(&message, pkbuf);
d_assert(rv == CORE_OK, pkbuf_free(pkbuf); break, "parse error");
if (message.h.type == GTP_CREATE_SESSION_REQUEST_TYPE)
sgw_ue = sgw_ue_find_or_add_by_message(&message);
@@ -75,6 +71,13 @@ void sgw_state_operational(fsm_t *s, event_t *e)
sgw_ue = sgw_ue_find_by_teid(message.h.teid);
d_assert(sgw_ue, pkbuf_free(pkbuf); break, "No Session Context");
rv = gtp_xact_receive(sgw_ue->mme, &message.h, &xact);
if (rv != CORE_OK)
{
pkbuf_free(pkbuf);
break;
}
switch(message.h.type)
{
case GTP_CREATE_SESSION_REQUEST_TYPE:
@@ -121,25 +124,25 @@ void sgw_state_operational(fsm_t *s, event_t *e)
case SGW_EVT_S5C_MESSAGE:
{
status_t rv;
gtp_node_t *gnode = NULL;
c_uint32_t addr = (c_uint32_t)event_get_param1(e);
c_uint16_t port = (c_uint16_t)event_get_param2(e);
pkbuf_t *pkbuf = (pkbuf_t *)event_get_param3(e);
pkbuf_t *pkbuf = (pkbuf_t *)event_get_param1(e);
gtp_xact_t *xact = NULL;
gtp_message_t message;
sgw_sess_t *sess = NULL;
d_assert(pkbuf, break, "Null param");
gnode = sgw_pgw_find(addr, port);
d_assert(gnode, pkbuf_free(pkbuf); break, "Null param");
rv = gtp_xact_receive(gnode, pkbuf, &xact, &message);
if (rv != CORE_OK)
break;
rv = gtp_parse_msg(&message, pkbuf);
d_assert(rv == CORE_OK, pkbuf_free(pkbuf); break, "parse error");
sess = sgw_sess_find_by_teid(message.h.teid);
d_assert(sess, pkbuf_free(pkbuf); break, "No Session Context");
rv = gtp_xact_receive(sess->pgw, &message.h, &xact);
if (rv != CORE_OK)
{
pkbuf_free(pkbuf);
break;
}
switch(message.h.type)
{
case GTP_CREATE_SESSION_RESPONSE_TYPE: