2017-03-24 09:47:05 +00:00
|
|
|
#define TRACE_MODULE _mme_s11_path
|
2017-03-23 14:05:40 +00:00
|
|
|
#include "core_debug.h"
|
|
|
|
#include "core_pkbuf.h"
|
|
|
|
|
2017-11-30 11:13:15 +00:00
|
|
|
#include "gtp_node.h"
|
|
|
|
#include "gtp_path.h"
|
|
|
|
#include "gtp_xact.h"
|
|
|
|
|
2017-04-04 01:49:19 +00:00
|
|
|
#include "mme_event.h"
|
2017-08-31 02:05:00 +00:00
|
|
|
#include "mme_gtp_path.h"
|
2017-09-07 06:56:31 +00:00
|
|
|
#include "mme_s11_build.h"
|
2017-03-23 14:05:40 +00:00
|
|
|
|
2017-11-22 15:19:28 +00:00
|
|
|
static int _gtpv2_c_recv_cb(sock_id sock, void *data)
|
2017-03-24 04:19:36 +00:00
|
|
|
{
|
2017-03-26 16:50:01 +00:00
|
|
|
status_t rv;
|
2017-03-24 04:19:36 +00:00
|
|
|
event_t e;
|
|
|
|
pkbuf_t *pkbuf = NULL;
|
2017-03-26 15:48:33 +00:00
|
|
|
|
2017-04-03 06:27:00 +00:00
|
|
|
d_assert(sock, return -1, "Null param");
|
2017-03-24 04:19:36 +00:00
|
|
|
|
2017-11-22 12:50:08 +00:00
|
|
|
rv = gtp_recv(sock, &pkbuf);
|
|
|
|
if (rv != CORE_OK)
|
2017-03-24 04:19:36 +00:00
|
|
|
{
|
2017-11-22 12:50:08 +00:00
|
|
|
if (errno == EAGAIN)
|
2017-03-24 04:19:36 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2017-11-22 12:50:08 +00:00
|
|
|
d_trace(10, "S11_PDU is received from SGW\n");
|
2017-07-31 13:35:25 +00:00
|
|
|
d_trace_hex(10, pkbuf->payload, pkbuf->len);
|
2017-03-24 04:19:36 +00:00
|
|
|
|
2017-08-25 15:25:55 +00:00
|
|
|
event_set(&e, MME_EVT_S11_MESSAGE);
|
2017-11-21 05:52:07 +00:00
|
|
|
event_set_param1(&e, (c_uintptr_t)pkbuf);
|
2017-03-26 16:50:01 +00:00
|
|
|
rv = mme_event_send(&e);
|
|
|
|
if (rv != CORE_OK)
|
2017-03-26 15:48:33 +00:00
|
|
|
{
|
2017-03-26 16:50:01 +00:00
|
|
|
d_error("mme_event_send error");
|
2017-03-26 15:48:33 +00:00
|
|
|
pkbuf_free(pkbuf);
|
2017-03-26 16:50:01 +00:00
|
|
|
return -1;
|
2017-03-26 15:48:33 +00:00
|
|
|
}
|
2017-03-24 04:19:36 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-08-31 02:05:00 +00:00
|
|
|
status_t mme_gtp_open()
|
2017-03-23 14:05:40 +00:00
|
|
|
{
|
2017-03-26 15:48:33 +00:00
|
|
|
status_t rv;
|
2017-09-01 15:11:49 +00:00
|
|
|
mme_sgw_t *sgw = mme_sgw_first();
|
2017-12-02 01:50:24 +00:00
|
|
|
sock_node_t *node;
|
2017-12-01 13:04:51 +00:00
|
|
|
sock_id temp; /* FIXME ADDR */
|
2017-03-26 15:48:33 +00:00
|
|
|
|
2017-12-01 13:04:51 +00:00
|
|
|
for (node = list_first(&mme_self()->gtpc4_list);
|
|
|
|
node; node = list_next(node))
|
2017-03-26 15:48:33 +00:00
|
|
|
{
|
2017-12-01 13:04:51 +00:00
|
|
|
rv = gtp_server(&node->sock, node->sa_list, _gtpv2_c_recv_cb);
|
|
|
|
if (rv != CORE_OK)
|
|
|
|
{
|
|
|
|
d_error("Can't establish GTP-C Path for SGW");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
temp = node->sock; /* FIXME ADDR : Shoud be removed */
|
2017-03-26 15:48:33 +00:00
|
|
|
}
|
|
|
|
|
2017-12-01 15:44:07 +00:00
|
|
|
for (node = list_first(&mme_self()->gtpc4_list);
|
|
|
|
node; node = list_next(node))
|
|
|
|
{
|
|
|
|
mme_self()->gtpc4_addr = sock_local_addr(node->sock);
|
|
|
|
if (mme_self()->gtpc4_addr)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-01 13:04:51 +00:00
|
|
|
for (node = list_first(&mme_self()->gtpc6_list);
|
|
|
|
node; node = list_next(node))
|
|
|
|
{
|
|
|
|
rv = gtp_server(&node->sock, node->sa_list, _gtpv2_c_recv_cb);
|
|
|
|
if (rv != CORE_OK)
|
|
|
|
{
|
|
|
|
d_error("Can't establish GTP-C Path for SGW");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
}
|
2017-12-01 15:44:07 +00:00
|
|
|
|
|
|
|
for (node = list_first(&mme_self()->gtpc6_list);
|
|
|
|
node; node = list_next(node))
|
|
|
|
{
|
|
|
|
mme_self()->gtpc6_addr = sock_local_addr(node->sock);
|
|
|
|
if (mme_self()->gtpc6_addr)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
d_assert(mme_self()->gtpc4_addr || mme_self()->gtpc6_addr,
|
|
|
|
return CORE_ERROR, "No GTP Server");
|
2017-12-01 13:04:51 +00:00
|
|
|
|
|
|
|
/* FIXME : socket descriptor needs in gnode when packet is sending initilly */
|
2017-09-01 15:11:49 +00:00
|
|
|
while(sgw)
|
|
|
|
{
|
2017-12-01 13:04:51 +00:00
|
|
|
sgw->sock = temp;
|
2017-09-01 15:11:49 +00:00
|
|
|
sgw = mme_sgw_next(sgw);
|
|
|
|
}
|
|
|
|
|
2017-03-26 15:48:33 +00:00
|
|
|
return CORE_OK;
|
2017-03-23 14:05:40 +00:00
|
|
|
}
|
|
|
|
|
2017-08-31 02:05:00 +00:00
|
|
|
status_t mme_gtp_close()
|
2017-03-23 14:05:40 +00:00
|
|
|
{
|
2017-12-02 01:50:24 +00:00
|
|
|
sock_node_t *node;
|
2017-03-26 15:48:33 +00:00
|
|
|
|
2017-12-01 13:04:51 +00:00
|
|
|
for (node = list_first(&mme_self()->gtpc4_list);
|
|
|
|
node; node = list_next(node))
|
|
|
|
{
|
|
|
|
sock_delete(node->sock);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (node = list_first(&mme_self()->gtpc6_list);
|
|
|
|
node; node = list_next(node))
|
2017-03-26 15:48:33 +00:00
|
|
|
{
|
2017-12-01 13:04:51 +00:00
|
|
|
sock_delete(node->sock);
|
2017-03-26 15:48:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return CORE_OK;
|
2017-03-23 14:05:40 +00:00
|
|
|
}
|
2017-09-07 06:56:31 +00:00
|
|
|
|
2017-09-08 07:46:37 +00:00
|
|
|
status_t mme_gtp_send_create_session_request(mme_sess_t *sess)
|
|
|
|
{
|
|
|
|
status_t rv;
|
|
|
|
gtp_header_t h;
|
|
|
|
pkbuf_t *pkbuf = NULL;
|
|
|
|
gtp_xact_t *xact = NULL;
|
|
|
|
mme_ue_t *mme_ue = NULL;
|
|
|
|
|
|
|
|
mme_ue = sess->mme_ue;
|
|
|
|
d_assert(mme_ue, return CORE_ERROR, "Null param");
|
|
|
|
|
|
|
|
memset(&h, 0, sizeof(gtp_header_t));
|
|
|
|
h.type = GTP_CREATE_SESSION_REQUEST_TYPE;
|
|
|
|
h.teid = mme_ue->sgw_s11_teid;
|
|
|
|
|
|
|
|
rv = mme_s11_build_create_session_request(&pkbuf, h.type, sess);
|
|
|
|
d_assert(rv == CORE_OK, return CORE_ERROR,
|
|
|
|
"S11 build error");
|
|
|
|
|
2017-09-14 10:55:21 +00:00
|
|
|
xact = gtp_xact_local_create(mme_ue->sgw, &h, pkbuf);
|
2017-09-08 07:46:37 +00:00
|
|
|
d_assert(xact, return CORE_ERROR, "Null param");
|
|
|
|
|
|
|
|
rv = gtp_xact_commit(xact);
|
|
|
|
d_assert(rv == CORE_OK, return CORE_ERROR, "xact_commit error");
|
|
|
|
|
|
|
|
return CORE_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-09-13 02:18:17 +00:00
|
|
|
status_t mme_gtp_send_modify_bearer_request(
|
2017-09-14 08:29:34 +00:00
|
|
|
mme_bearer_t *bearer, int uli_presence)
|
2017-09-07 06:56:31 +00:00
|
|
|
{
|
|
|
|
status_t rv;
|
|
|
|
|
|
|
|
gtp_xact_t *xact = NULL;
|
|
|
|
mme_ue_t *mme_ue = NULL;
|
|
|
|
|
|
|
|
gtp_header_t h;
|
|
|
|
pkbuf_t *pkbuf = NULL;
|
|
|
|
|
|
|
|
d_assert(bearer, return CORE_ERROR, "Null param");
|
2017-09-14 10:55:21 +00:00
|
|
|
mme_ue = bearer->mme_ue;
|
2017-09-07 06:56:31 +00:00
|
|
|
d_assert(mme_ue, return CORE_ERROR, "Null param");
|
|
|
|
|
|
|
|
memset(&h, 0, sizeof(gtp_header_t));
|
|
|
|
h.type = GTP_MODIFY_BEARER_REQUEST_TYPE;
|
|
|
|
h.teid = mme_ue->sgw_s11_teid;
|
|
|
|
|
2017-09-14 08:29:34 +00:00
|
|
|
rv = mme_s11_build_modify_bearer_request(
|
|
|
|
&pkbuf, h.type, bearer, uli_presence);
|
2017-09-07 06:56:31 +00:00
|
|
|
d_assert(rv == CORE_OK, return CORE_ERROR, "S11 build error");
|
|
|
|
|
2017-09-14 10:55:21 +00:00
|
|
|
xact = gtp_xact_local_create(mme_ue->sgw, &h, pkbuf);
|
2017-09-07 06:56:31 +00:00
|
|
|
d_assert(xact, return CORE_ERROR, "Null param");
|
|
|
|
|
|
|
|
rv = gtp_xact_commit(xact);
|
|
|
|
d_assert(rv == CORE_OK, return CORE_ERROR, "xact_commit error");
|
|
|
|
|
|
|
|
return CORE_OK;
|
|
|
|
}
|
|
|
|
|
2017-09-07 13:22:42 +00:00
|
|
|
status_t mme_gtp_send_delete_session_request(mme_sess_t *sess)
|
|
|
|
{
|
|
|
|
status_t rv;
|
|
|
|
pkbuf_t *s11buf = NULL;
|
|
|
|
gtp_header_t h;
|
|
|
|
gtp_xact_t *xact = NULL;
|
|
|
|
mme_ue_t *mme_ue = NULL;
|
|
|
|
|
|
|
|
d_assert(sess, return CORE_ERROR, "Null param");
|
|
|
|
mme_ue = sess->mme_ue;
|
|
|
|
d_assert(mme_ue, return CORE_ERROR, "Null param");
|
|
|
|
|
|
|
|
memset(&h, 0, sizeof(gtp_header_t));
|
|
|
|
h.type = GTP_DELETE_SESSION_REQUEST_TYPE;
|
|
|
|
h.teid = mme_ue->sgw_s11_teid;
|
|
|
|
|
2017-09-14 08:29:34 +00:00
|
|
|
rv = mme_s11_build_delete_session_request(&s11buf, h.type, sess);
|
2017-09-07 13:22:42 +00:00
|
|
|
d_assert(rv == CORE_OK, return CORE_ERROR, "S11 build error");
|
|
|
|
|
2017-09-14 10:55:21 +00:00
|
|
|
xact = gtp_xact_local_create(mme_ue->sgw, &h, s11buf);
|
2017-09-07 13:22:42 +00:00
|
|
|
d_assert(xact, return CORE_ERROR, "Null param");
|
|
|
|
|
|
|
|
GTP_XACT_STORE_SESSION(xact, sess);
|
|
|
|
|
|
|
|
rv = gtp_xact_commit(xact);
|
|
|
|
d_assert(rv == CORE_OK, return CORE_ERROR, "xact_commit error");
|
|
|
|
|
2017-09-13 02:57:17 +00:00
|
|
|
GTP_COUNTER_INCREMENT(mme_ue, GTP_COUNTER_DELETE_SESSION);
|
|
|
|
|
2017-09-07 13:22:42 +00:00
|
|
|
return CORE_OK;
|
|
|
|
}
|
|
|
|
|
2017-09-07 14:51:06 +00:00
|
|
|
status_t mme_gtp_send_delete_all_sessions(mme_ue_t *mme_ue)
|
|
|
|
{
|
|
|
|
status_t rv;
|
|
|
|
mme_sess_t *sess = NULL, *next_sess = NULL;
|
|
|
|
|
|
|
|
d_assert(mme_ue, return CORE_ERROR, "Null param");
|
|
|
|
sess = mme_sess_first(mme_ue);
|
|
|
|
while (sess != NULL)
|
|
|
|
{
|
|
|
|
next_sess = mme_sess_next(sess);
|
|
|
|
|
|
|
|
if (MME_HAVE_SGW_S1U_PATH(sess))
|
|
|
|
{
|
|
|
|
rv = mme_gtp_send_delete_session_request(sess);
|
|
|
|
d_assert(rv == CORE_OK, return CORE_ERROR,
|
|
|
|
"mme_gtp_send_delete_session_request error");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mme_sess_remove(sess);
|
|
|
|
}
|
|
|
|
|
|
|
|
sess = next_sess;
|
|
|
|
}
|
|
|
|
|
|
|
|
return CORE_OK;
|
|
|
|
}
|
|
|
|
|
2017-09-07 06:56:31 +00:00
|
|
|
status_t mme_gtp_send_create_bearer_response(mme_bearer_t *bearer)
|
|
|
|
{
|
|
|
|
status_t rv;
|
|
|
|
|
|
|
|
gtp_xact_t *xact = NULL;
|
|
|
|
mme_ue_t *mme_ue = NULL;
|
|
|
|
|
|
|
|
gtp_header_t h;
|
|
|
|
pkbuf_t *pkbuf = NULL;
|
|
|
|
|
|
|
|
d_assert(bearer, return CORE_ERROR, "Null param");
|
|
|
|
mme_ue = bearer->mme_ue;
|
|
|
|
d_assert(mme_ue, return CORE_ERROR, "Null param");
|
|
|
|
xact = bearer->xact;
|
|
|
|
d_assert(xact, return CORE_ERROR, "Null param");
|
|
|
|
|
|
|
|
memset(&h, 0, sizeof(gtp_header_t));
|
|
|
|
h.type = GTP_CREATE_BEARER_RESPONSE_TYPE;
|
|
|
|
h.teid = mme_ue->sgw_s11_teid;
|
|
|
|
|
2017-09-14 08:29:34 +00:00
|
|
|
rv = mme_s11_build_create_bearer_response(&pkbuf, h.type, bearer);
|
2017-09-07 06:56:31 +00:00
|
|
|
d_assert(rv == CORE_OK, return CORE_ERROR, "S11 build error");
|
|
|
|
|
|
|
|
rv = gtp_xact_update_tx(xact, &h, pkbuf);
|
|
|
|
d_assert(xact, return CORE_ERROR, "Null param");
|
|
|
|
|
|
|
|
rv = gtp_xact_commit(xact);
|
|
|
|
d_assert(rv == CORE_OK, return CORE_ERROR, "xact_commit error");
|
|
|
|
|
|
|
|
return CORE_OK;
|
|
|
|
}
|
2017-09-07 10:44:08 +00:00
|
|
|
|
2017-09-13 07:22:39 +00:00
|
|
|
status_t mme_gtp_send_release_access_bearers_request(mme_ue_t *mme_ue)
|
2017-09-07 10:44:08 +00:00
|
|
|
{
|
|
|
|
status_t rv;
|
|
|
|
gtp_header_t h;
|
|
|
|
pkbuf_t *pkbuf = NULL;
|
|
|
|
gtp_xact_t *xact = NULL;
|
|
|
|
|
|
|
|
d_assert(mme_ue, return CORE_ERROR, "Null param");
|
|
|
|
|
|
|
|
memset(&h, 0, sizeof(gtp_header_t));
|
|
|
|
h.type = GTP_RELEASE_ACCESS_BEARERS_REQUEST_TYPE;
|
|
|
|
h.teid = mme_ue->sgw_s11_teid;
|
|
|
|
|
|
|
|
rv = mme_s11_build_release_access_bearers_request(&pkbuf, h.type);
|
|
|
|
d_assert(rv == CORE_OK, return CORE_ERROR, "S11 build error");
|
|
|
|
|
2017-09-14 10:55:21 +00:00
|
|
|
xact = gtp_xact_local_create(mme_ue->sgw, &h, pkbuf);
|
2017-09-07 10:44:08 +00:00
|
|
|
d_assert(xact, return CORE_ERROR, "Null param");
|
|
|
|
|
|
|
|
rv = gtp_xact_commit(xact);
|
|
|
|
d_assert(rv == CORE_OK, return CORE_ERROR, "xact_commit error");
|
|
|
|
|
|
|
|
return CORE_OK;
|
|
|
|
}
|
2017-09-13 07:22:39 +00:00
|
|
|
|
|
|
|
status_t mme_gtp_send_create_indirect_data_forwarding_tunnel_request(
|
|
|
|
mme_ue_t *mme_ue)
|
|
|
|
{
|
|
|
|
status_t rv;
|
|
|
|
gtp_header_t h;
|
|
|
|
pkbuf_t *pkbuf = NULL;
|
|
|
|
gtp_xact_t *xact = NULL;
|
|
|
|
|
|
|
|
d_assert(mme_ue, return CORE_ERROR, "Null param");
|
|
|
|
|
|
|
|
memset(&h, 0, sizeof(gtp_header_t));
|
|
|
|
h.type = GTP_CREATE_INDIRECT_DATA_FORWARDING_TUNNEL_REQUEST_TYPE;
|
|
|
|
h.teid = mme_ue->sgw_s11_teid;
|
|
|
|
|
|
|
|
rv = mme_s11_build_create_indirect_data_forwarding_tunnel_request(
|
|
|
|
&pkbuf, h.type, mme_ue);
|
|
|
|
d_assert(rv == CORE_OK, return CORE_ERROR, "S11 build error");
|
|
|
|
|
2017-09-14 10:55:21 +00:00
|
|
|
xact = gtp_xact_local_create(mme_ue->sgw, &h, pkbuf);
|
2017-09-13 07:22:39 +00:00
|
|
|
d_assert(xact, return CORE_ERROR, "Null param");
|
|
|
|
|
|
|
|
rv = gtp_xact_commit(xact);
|
|
|
|
d_assert(rv == CORE_OK, return CORE_ERROR, "xact_commit error");
|
|
|
|
|
|
|
|
return CORE_OK;
|
|
|
|
}
|
2017-09-14 05:18:47 +00:00
|
|
|
|
|
|
|
status_t mme_gtp_send_delete_indirect_data_forwarding_tunnel_request(
|
|
|
|
mme_ue_t *mme_ue)
|
|
|
|
{
|
|
|
|
status_t rv;
|
|
|
|
gtp_header_t h;
|
|
|
|
pkbuf_t *pkbuf = NULL;
|
|
|
|
gtp_xact_t *xact = NULL;
|
|
|
|
|
|
|
|
d_assert(mme_ue, return CORE_ERROR, "Null param");
|
|
|
|
|
|
|
|
memset(&h, 0, sizeof(gtp_header_t));
|
|
|
|
h.type = GTP_DELETE_INDIRECT_DATA_FORWARDING_TUNNEL_REQUEST_TYPE;
|
|
|
|
h.teid = mme_ue->sgw_s11_teid;
|
|
|
|
|
|
|
|
pkbuf = pkbuf_alloc(TLV_MAX_HEADROOM, 0);
|
|
|
|
d_assert(pkbuf, return CORE_ERROR, "S11 build error");
|
|
|
|
|
2017-09-14 10:55:21 +00:00
|
|
|
xact = gtp_xact_local_create(mme_ue->sgw, &h, pkbuf);
|
2017-09-14 05:18:47 +00:00
|
|
|
d_assert(xact, return CORE_ERROR, "Null param");
|
|
|
|
|
|
|
|
rv = gtp_xact_commit(xact);
|
|
|
|
d_assert(rv == CORE_OK, return CORE_ERROR, "xact_commit error");
|
|
|
|
|
|
|
|
return CORE_OK;
|
|
|
|
}
|