One IP assign for SGW

Configuration is changed
Remove S11_XXXX, S1U_XXXX, S5C_XXXX, S5U_XXXX

Introduce GTPC_IPV4, GTPU_IPV4
This commit is contained in:
Sukchan Lee 2017-10-13 21:13:39 +09:00
parent 5d6e63c20e
commit 4672ee559f
5 changed files with 268 additions and 156 deletions

View File

@ -80,37 +80,23 @@ sgw_context_t* sgw_self()
static status_t sgw_context_prepare()
{
self.s11_port = GTPV2_C_UDP_PORT;
self.s5c_port = GTPV2_C_UDP_PORT;
self.s1u_port = GTPV1_U_UDP_PORT;
self.s5u_port = GTPV1_U_UDP_PORT;
self.gtpc_port = GTPV2_C_UDP_PORT;
self.gtpu_port = GTPV1_U_UDP_PORT;
return CORE_OK;
}
static status_t sgw_context_validation()
{
if (self.s11_addr == 0)
if (self.gtpc_addr == 0)
{
d_error("No SGW.NEWORK.S11_IPV4 in '%s'",
d_error("No SGW.NEWORK.GTPC_IPV4 in '%s'",
context_self()->config.path);
return CORE_ERROR;
}
if (self.s5c_addr == 0)
if (self.gtpu_addr == 0)
{
d_error("No SGW.NEWORK.S5C_IPV4 in '%s'",
context_self()->config.path);
return CORE_ERROR;
}
if (self.s1u_addr == 0)
{
d_error("No SGW.NEWORK.S1U_IPV4 in '%s'",
context_self()->config.path);
return CORE_ERROR;
}
if (self.s5u_addr == 0)
{
d_error("No SGW.NEWORK.S5U_IPV4 in '%s'",
d_error("No SGW.NEWORK.GTPU_IPV4 in '%s'",
context_self()->config.path);
return CORE_ERROR;
}
@ -199,45 +185,25 @@ status_t sgw_context_parse_config()
{
n += (t+m)->size;
if (jsmntok_equal(json, t+m, "S11_IPV4") == 0)
if (jsmntok_equal(json, t+m, "GTPC_IPV4") == 0)
{
char *v = jsmntok_to_string(json, t+m+1);
if (v) self.s11_addr = inet_addr(v);
if (v) self.gtpc_addr = inet_addr(v);
}
else if (jsmntok_equal(json, t+m, "S11_PORT") == 0)
else if (jsmntok_equal(json, t+m, "GTPC_PORT") == 0)
{
char *v = jsmntok_to_string(json, t+m+1);
if (v) self.s11_port = atoi(v);
if (v) self.gtpc_port = atoi(v);
}
else if (jsmntok_equal(json, t+m, "S5C_IPV4") == 0)
else if (jsmntok_equal(json, t+m, "GTPU_IPV4") == 0)
{
char *v = jsmntok_to_string(json, t+m+1);
if (v) self.s5c_addr = inet_addr(v);
if (v) self.gtpu_addr = inet_addr(v);
}
else if (jsmntok_equal(json, t+m, "S5C_PORT") == 0)
else if (jsmntok_equal(json, t+m, "GTPU_PORT") == 0)
{
char *v = jsmntok_to_string(json, t+m+1);
if (v) self.s5c_port = atoi(v);
}
else if (jsmntok_equal(json, t+m, "S1U_IPV4") == 0)
{
char *v = jsmntok_to_string(json, t+m+1);
if (v) self.s1u_addr = inet_addr(v);
}
else if (jsmntok_equal(json, t+m, "S1U_PORT") == 0)
{
char *v = jsmntok_to_string(json, t+m+1);
if (v) self.s1u_port = atoi(v);
}
else if (jsmntok_equal(json, t+m, "S5U_IPV4") == 0)
{
char *v = jsmntok_to_string(json, t+m+1);
if (v) self.s5u_addr = inet_addr(v);
}
else if (jsmntok_equal(json, t+m, "S5U_PORT") == 0)
{
char *v = jsmntok_to_string(json, t+m+1);
if (v) self.s5u_port = atoi(v);
if (v) self.gtpu_port = atoi(v);
}
}
}
@ -472,7 +438,7 @@ sgw_ue_t* sgw_ue_add(
d_assert(sgw_ue, return NULL, "Null param");
sgw_ue->sgw_s11_teid = sgw_ue->index;
sgw_ue->sgw_s11_addr = sgw_self()->s11_addr;
sgw_ue->sgw_s11_addr = sgw_self()->gtpc_addr;
/* Set IMSI */
sgw_ue->imsi_len = imsi_len;
@ -609,7 +575,7 @@ sgw_sess_t *sgw_sess_add(
d_assert(sess, return NULL, "Null param");
sess->sgw_s5c_teid = sess->index;
sess->sgw_s5c_addr = sgw_self()->s5c_addr;
sess->sgw_s5c_addr = sgw_self()->gtpc_addr;
/* Set APN */
core_cpystrn(sess->pdn.apn, apn, MAX_APN_LEN+1);
@ -719,9 +685,6 @@ sgw_bearer_t* sgw_bearer_add(sgw_sess_t *sess)
index_alloc(&sgw_bearer_pool, &bearer);
d_assert(bearer, return NULL, "Bearer context allocation failed");
bearer->sgw_s5u_teid = bearer->index;
bearer->sgw_s5u_addr = sgw_self()->s5u_addr;
list_append(&sess->bearer_list, bearer);
bearer->sgw_ue = sgw_ue;
@ -732,6 +695,9 @@ sgw_bearer_t* sgw_bearer_add(sgw_sess_t *sess)
tunnel = sgw_tunnel_add(bearer, GTP_F_TEID_S1_U_SGW_GTP_U);
d_assert(tunnel, return NULL, "Tunnel context allocation failed");
tunnel = sgw_tunnel_add(bearer, GTP_F_TEID_S5_S8_SGW_GTP_U);
d_assert(tunnel, return NULL, "Tunnel context allocation failed");
return bearer;
}
@ -849,7 +815,7 @@ sgw_tunnel_t* sgw_tunnel_add(sgw_bearer_t *bearer, c_uint8_t interface_type)
tunnel->interface_type = interface_type;
tunnel->local_teid = tunnel->index;
tunnel->local_addr = sgw_self()->s1u_addr;
tunnel->local_addr = sgw_self()->gtpu_addr;
tunnel->bearer = bearer;
@ -901,7 +867,8 @@ sgw_tunnel_t* sgw_tunnel_find_by_teid(c_uint32_t teid)
return sgw_tunnel_find(teid);
}
sgw_tunnel_t* sgw_direct_tunnel_in_bearer(sgw_bearer_t *bearer)
sgw_tunnel_t* sgw_tunnel_find_by_interface_type(
sgw_bearer_t *bearer, c_uint8_t interface_type)
{
sgw_tunnel_t *tunnel = NULL;
@ -910,7 +877,7 @@ sgw_tunnel_t* sgw_direct_tunnel_in_bearer(sgw_bearer_t *bearer)
tunnel = sgw_tunnel_first(bearer);
while(tunnel)
{
if (tunnel->interface_type == GTP_F_TEID_S1_U_SGW_GTP_U)
if (tunnel->interface_type == interface_type)
{
return tunnel;
}
@ -921,6 +888,17 @@ sgw_tunnel_t* sgw_direct_tunnel_in_bearer(sgw_bearer_t *bearer)
return NULL;
}
sgw_tunnel_t* sgw_s1u_tunnel_in_bearer(sgw_bearer_t *bearer)
{
return sgw_tunnel_find_by_interface_type(
bearer, GTP_F_TEID_S1_U_SGW_GTP_U);
}
sgw_tunnel_t* sgw_s5u_tunnel_in_bearer(sgw_bearer_t *bearer)
{
return sgw_tunnel_find_by_interface_type(
bearer, GTP_F_TEID_S5_S8_SGW_GTP_U);
}
sgw_tunnel_t* sgw_tunnel_first(sgw_bearer_t *bearer)
{
d_assert(bearer, return NULL, "Null param");

View File

@ -21,26 +21,16 @@ 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 */
c_uint32_t gtpc_addr; /* GTP-U local address */
c_uint32_t gtpc_port; /* GTP-U local port */
net_sock_t* gtpc_sock; /* GTP-U local listen socket */
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 */
c_uint32_t gtpu_addr; /* GTP-U local address */
c_uint32_t gtpu_port; /* GTP-U local port */
net_sock_t* gtpu_sock; /* GTP-U local listen socket */
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 */
c_uint32_t s1u_addr; /* SGW S1-U local address */
c_uint32_t s1u_port; /* SGW S1-U local port */
net_sock_t* s1u_sock; /* SGW S1-U local listen socket */
c_uint32_t s5u_addr; /* SGW S5-U local address */
c_uint32_t s5u_port; /* SGW S5-U local port */
net_sock_t* s5u_sock; /* SGW S5-U local listen socket */
msgq_id queue_id; /* Queue for processing SGW control plane */
tm_service_t tm_service; /* Timer Service */
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 */
@ -117,13 +107,6 @@ typedef struct _sgw_bearer_t {
c_uint8_t ebi;
/* IMPORTANT!
* SGW-S5U-TEID is same with an index */
c_uint32_t sgw_s5u_teid;
c_uint32_t sgw_s5u_addr;
c_uint32_t enb_s1u_teid;
c_uint32_t enb_s1u_addr;
/* User-Lication-Info */
tai_t tai;
e_cgi_t e_cgi;
@ -224,7 +207,10 @@ CORE_DECLARE(status_t) sgw_tunnel_remove(sgw_tunnel_t *tunnel);
CORE_DECLARE(status_t) sgw_tunnel_remove_all(sgw_bearer_t *bearer);
CORE_DECLARE(sgw_tunnel_t*) sgw_tunnel_find(index_t index);
CORE_DECLARE(sgw_tunnel_t*) sgw_tunnel_find_by_teid(c_uint32_t teid);
CORE_DECLARE(sgw_tunnel_t*) sgw_direct_tunnel_in_bearer(sgw_bearer_t *bearer);
CORE_DECLARE(sgw_tunnel_t*) sgw_tunnel_find_by_interface_type(
sgw_bearer_t *bearer, c_uint8_t interface_type);
CORE_DECLARE(sgw_tunnel_t*) sgw_s1u_tunnel_in_bearer(sgw_bearer_t *bearer);
CORE_DECLARE(sgw_tunnel_t*) sgw_s5u_tunnel_in_bearer(sgw_bearer_t *bearer);
CORE_DECLARE(sgw_tunnel_t*) sgw_tunnel_first(sgw_bearer_t *bearer);
CORE_DECLARE(sgw_tunnel_t*) sgw_tunnel_next(sgw_tunnel_t *tunnel);

View File

@ -11,7 +11,7 @@
#include "sgw_event.h"
#include "sgw_gtp_path.h"
static int _gtpv2_c_recv_cb(net_sock_t *sock, void *data)
static int _gtpc_recv_cb(net_sock_t *sock, void *data)
{
event_t e;
status_t rv;
@ -22,7 +22,6 @@ static int _gtpv2_c_recv_cb(net_sock_t *sock, void *data)
sgw_mme_t *mme = NULL;
d_assert(sock, return -1, "Null param");
d_assert(data, return -1, "Null param");
pkbuf = gtp_read(sock);
if (pkbuf == NULL)
@ -82,6 +81,160 @@ static int _gtpv2_c_recv_cb(net_sock_t *sock, void *data)
return 0;
}
static int _gtpu_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;
sgw_tunnel_t *tunnel = NULL;
c_uint32_t teid;
int i;
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\n");
gnode.addr = sock->remote.sin_addr.s_addr;
gnode.port = ntohs(sock->remote.sin_port);
gnode.sock = 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)\n", teid);
tunnel = sgw_tunnel_find_by_teid(teid);
d_assert(tunnel, return -1, "No TEID(0x%x)", teid);
/* Convert TEID */
gtp_h->teid = htonl(tunnel->remote_teid);
gnode.addr = tunnel->remote_addr;
gnode.port = GTPV1_U_UDP_PORT;
gnode.sock = sgw_self()->gtpu_sock;
if (tunnel->interface_type ==
GTP_F_TEID_S1_U_SGW_GTP_U ||
tunnel->interface_type ==
GTP_F_TEID_SGW_GTP_U_FOR_DL_DATA_FORWARDING ||
tunnel->interface_type ==
GTP_F_TEID_SGW_GTP_U_FOR_UL_DATA_FORWARDING)
{
d_trace(50, "Recv GPDU (teid = 0x%x) from eNB\n", teid);
gtp_send(&gnode, pkbuf);
}
else if (tunnel->interface_type == GTP_F_TEID_S5_S8_SGW_GTP_U)
{
d_trace(50, "Recv GPDU (teid = 0x%x) from PGW\n", teid);
bearer = tunnel->bearer;
d_assert(bearer, return -1, "Null param");
if (tunnel->remote_teid)
{
/* If there is buffered packet, send it first */
for (i = 0; i < bearer->num_buffered_pkt; i++)
{
gtp_h = (gtp_header_t *)bearer->buffered_pkts[i]->payload;
gtp_h->teid = htonl(tunnel->remote_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;
}
#if 0
static int _gtpv1_s5u_recv_cb(net_sock_t *sock, void *data)
{
pkbuf_t *pkbuf = NULL;
@ -294,42 +447,25 @@ static int _gtpv1_s1u_recv_cb(net_sock_t *sock, void *data)
pkbuf_free(pkbuf);
return 0;
}
#endif
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,
(void*)SGW_EVT_S11_MESSAGE);
rv = gtp_listen(&sgw_self()->gtpc_sock, _gtpc_recv_cb,
sgw_self()->gtpc_addr, sgw_self()->gtpc_port, NULL);
if (rv != CORE_OK)
{
d_error("Can't establish S11 Path for SGW");
d_error("Can't establish GTP-C Path for MME/PGW");
return rv;
}
rv = gtp_listen(&sgw_self()->s5c_sock, _gtpv2_c_recv_cb,
sgw_self()->s5c_addr, sgw_self()->s5c_port,
(void*)SGW_EVT_S5C_MESSAGE);
rv = gtp_listen(&sgw_self()->gtpu_sock, _gtpu_recv_cb,
sgw_self()->gtpu_addr, sgw_self()->gtpu_port, NULL);
if (rv != CORE_OK)
{
d_error("Can't establish S5-C Path for SGW");
return rv;
}
rv = gtp_listen(&sgw_self()->s5u_sock, _gtpv1_s5u_recv_cb,
sgw_self()->s5u_addr, sgw_self()->s5u_port, NULL);
if (rv != CORE_OK)
{
d_error("Can't establish S5-U Path for SGW");
return rv;
}
rv = gtp_listen(&sgw_self()->s1u_sock, _gtpv1_s1u_recv_cb,
sgw_self()->s1u_addr, sgw_self()->s1u_port, NULL);
if (rv != CORE_OK)
{
d_error("Can't establish S1-U Path for SGW");
d_error("Can't establish GTP-U Path for eNB/SGW");
return rv;
}
@ -340,24 +476,17 @@ status_t sgw_gtp_close()
{
status_t rv;
rv = gtp_close(sgw_self()->s11_sock);
rv = gtp_close(sgw_self()->gtpc_sock);
if (rv != CORE_OK)
{
d_error("Can't close S11 Path for MME");
d_error("Can't close GTP-C Path for MME/PGW");
return rv;
}
rv = gtp_close(sgw_self()->s5c_sock);
rv = gtp_close(sgw_self()->gtpu_sock);
if (rv != CORE_OK)
{
d_error("Can't close S5-C Path for MME");
return rv;
}
rv = gtp_close(sgw_self()->s5u_sock);
if (rv != CORE_OK)
{
d_error("Can't close S5-U Path for MME");
d_error("Can't close GTP-U Path for eNB/PGW");
return rv;
}
@ -370,8 +499,11 @@ status_t sgw_gtp_send_end_marker(sgw_bearer_t *bearer)
pkbuf_t *pkbuf = NULL;
gtp_header_t *h = NULL;
gtp_node_t gnode;
sgw_tunnel_t *s1u_tunnel = NULL;
d_assert(bearer, return CORE_ERROR,);
s1u_tunnel = sgw_s1u_tunnel_in_bearer(bearer);
d_assert(s1u_tunnel, return CORE_ERROR,);
pkbuf = pkbuf_alloc(0, 100 /* enough for END_MARKER; use smaller buffer */);
d_assert(pkbuf, return CORE_ERROR,);
@ -386,11 +518,11 @@ status_t sgw_gtp_send_end_marker(sgw_bearer_t *bearer)
*/
h->flags = 0x30;
h->type = GTPU_MSGTYPE_END_MARKER;
h->teid = htonl(bearer->enb_s1u_teid);
h->teid = htonl(s1u_tunnel->remote_teid);
gnode.addr = bearer->enb_s1u_addr;
gnode.addr = s1u_tunnel->remote_addr;
gnode.port = GTPV1_U_UDP_PORT;
gnode.sock = sgw_self()->s1u_sock;
gnode.sock = sgw_self()->gtpu_sock;
rv = gtp_send(&gnode, pkbuf);
d_assert(rv == CORE_OK, , "gtp send failed");

View File

@ -29,6 +29,7 @@ void sgw_s11_handle_create_session_request(gtp_xact_t *s11_xact,
gtp_xact_t *s5c_xact = NULL;
sgw_sess_t *sess = NULL;
sgw_bearer_t *bearer = NULL;
sgw_tunnel_t *s5u_tunnel = NULL;
d_assert(s11_xact, return, "Null param");
d_assert(sgw_ue, return, "Null param");
@ -79,6 +80,8 @@ void sgw_s11_handle_create_session_request(gtp_xact_t *s11_xact,
d_assert(sess, return, "Null param");
bearer = sgw_default_bearer_in_sess(sess);
d_assert(bearer, return, "Null param");
s5u_tunnel = sgw_s5u_tunnel_in_bearer(bearer);
d_assert(s5u_tunnel, return, "Null param");
/* Receive Control Plane(DL) : MME-S11 */
mme_s11_teid = req->sender_f_teid_for_control_plane.data;
@ -110,7 +113,7 @@ void sgw_s11_handle_create_session_request(gtp_xact_t *s11_xact,
pgw->addr = addr;
pgw->port = port;
pgw->sock = sgw_self()->s5c_sock;
pgw->sock = sgw_self()->gtpc_sock;
}
/* Setup GTP Node */
@ -121,8 +124,8 @@ void sgw_s11_handle_create_session_request(gtp_xact_t *s11_xact,
/* Data Plane(DL) : SGW-S5U */
memset(&sgw_s5u_teid, 0, sizeof(gtp_f_teid_t));
sgw_s5u_teid.teid = htonl(bearer->sgw_s5u_teid);
sgw_s5u_teid.ipv4_addr = bearer->sgw_s5u_addr;
sgw_s5u_teid.teid = htonl(s5u_tunnel->local_teid);
sgw_s5u_teid.ipv4_addr = s5u_tunnel->local_addr;
sgw_s5u_teid.interface_type = GTP_F_TEID_S5_S8_SGW_GTP_U;
req->bearer_contexts_to_be_created.s5_s8_u_sgw_f_teid.presence = 1;
req->bearer_contexts_to_be_created.s5_s8_u_sgw_f_teid.data = &sgw_s5u_teid;
@ -161,6 +164,7 @@ CORE_DECLARE(void) sgw_s11_handle_modify_bearer_request(gtp_xact_t *s11_xact,
status_t rv;
c_uint16_t decoded;
sgw_bearer_t *bearer = NULL;
sgw_tunnel_t *s1u_tunnel = NULL;
gtp_modify_bearer_response_t *rsp = NULL;
pkbuf_t *pkbuf = NULL;
gtp_message_t gtp_message;
@ -192,6 +196,8 @@ CORE_DECLARE(void) sgw_s11_handle_modify_bearer_request(gtp_xact_t *s11_xact,
bearer = sgw_bearer_find_by_ue_ebi(sgw_ue,
req->bearer_contexts_to_be_modified.eps_bearer_id.u8);
d_assert(bearer, return, "No Bearer Context");
s1u_tunnel = sgw_s1u_tunnel_in_bearer(bearer);
d_assert(s1u_tunnel, return, "No S1U Tunnel Context");
/* Set User Location Information */
if (req->user_location_information.presence == 1)
@ -212,8 +218,8 @@ CORE_DECLARE(void) sgw_s11_handle_modify_bearer_request(gtp_xact_t *s11_xact,
/* Data Plane(DL) : eNB-S1U */
enb_s1u_teid = req->bearer_contexts_to_be_modified.s1_u_enodeb_f_teid.data;
bearer->enb_s1u_teid = ntohl(enb_s1u_teid->teid);
bearer->enb_s1u_addr = enb_s1u_teid->ipv4_addr;
s1u_tunnel->remote_teid = ntohl(enb_s1u_teid->teid);
s1u_tunnel->remote_addr = enb_s1u_teid->ipv4_addr;
/* Reset UE state */
SGW_RESET_UE_STATE(sgw_ue, SGW_S1U_INACTIVE);
@ -296,7 +302,7 @@ void sgw_s11_handle_create_bearer_response(gtp_xact_t *s11_xact,
gtp_xact_t *s5c_xact = NULL;
sgw_sess_t *sess = NULL;
sgw_bearer_t *bearer = NULL;
sgw_tunnel_t *tunnel = NULL;
sgw_tunnel_t *s1u_tunnel = NULL, *s5u_tunnel = NULL;
gtp_create_bearer_response_t *req = NULL;
gtp_f_teid_t *sgw_s1u_teid = NULL, *enb_s1u_teid = NULL;
@ -344,10 +350,12 @@ void sgw_s11_handle_create_bearer_response(gtp_xact_t *s11_xact,
req->bearer_contexts.s4_u_sgsn_f_teid.presence = 0;
/* Find the Tunnel by SGW-S1U-TEID */
tunnel = sgw_tunnel_find_by_teid(ntohl(sgw_s1u_teid->teid));
d_assert(tunnel, return, "Null param");
bearer = tunnel->bearer;
s1u_tunnel = sgw_tunnel_find_by_teid(ntohl(sgw_s1u_teid->teid));
d_assert(s1u_tunnel, return, "Null param");
bearer = s1u_tunnel->bearer;
d_assert(bearer, return, "Null param");
s5u_tunnel = sgw_s5u_tunnel_in_bearer(bearer);
d_assert(s5u_tunnel, return, "Null param");
sess = bearer->sess;
d_assert(sess, return, "Null param");
@ -356,8 +364,8 @@ void sgw_s11_handle_create_bearer_response(gtp_xact_t *s11_xact,
/* Data Plane(DL) : eNB-S1U */
enb_s1u_teid = req->bearer_contexts.s1_u_enodeb_f_teid.data;
bearer->enb_s1u_teid = ntohl(enb_s1u_teid->teid);
bearer->enb_s1u_addr = enb_s1u_teid->ipv4_addr;
s1u_tunnel->remote_teid = ntohl(enb_s1u_teid->teid);
s1u_tunnel->remote_addr = enb_s1u_teid->ipv4_addr;
req->bearer_contexts.s1_u_enodeb_f_teid.presence = 0;
decoded = gtp_parse_uli(&uli, &req->user_location_information);
@ -372,8 +380,8 @@ void sgw_s11_handle_create_bearer_response(gtp_xact_t *s11_xact,
/* Data Plane(DL) : SGW-S5U */
memset(&sgw_s5u_teid, 0, sizeof(gtp_f_teid_t));
sgw_s5u_teid.teid = htonl(bearer->sgw_s5u_teid);
sgw_s5u_teid.ipv4_addr = bearer->sgw_s5u_addr;
sgw_s5u_teid.teid = htonl(s5u_tunnel->local_teid);
sgw_s5u_teid.ipv4_addr = s5u_tunnel->local_addr;
sgw_s5u_teid.interface_type = GTP_F_TEID_S5_S8_SGW_GTP_U;
req->bearer_contexts.s5_s8_u_sgw_f_teid.presence = 1;
req->bearer_contexts.s5_s8_u_sgw_f_teid.data = &sgw_s5u_teid;
@ -381,8 +389,8 @@ void sgw_s11_handle_create_bearer_response(gtp_xact_t *s11_xact,
/* Data Plane(DL) : PGW-S5U */
memset(&pgw_s5u_teid, 0, sizeof(gtp_f_teid_t));
pgw_s5u_teid.teid = htonl(tunnel->remote_teid);
pgw_s5u_teid.ipv4_addr = tunnel->remote_addr;
pgw_s5u_teid.teid = htonl(s5u_tunnel->remote_teid);
pgw_s5u_teid.ipv4_addr = s5u_tunnel->remote_addr;
pgw_s5u_teid.interface_type = GTP_F_TEID_S5_S8_PGW_GTP_U;
req->bearer_contexts.s5_s8_u_pgw_f_teid.presence = 1;
req->bearer_contexts.s5_s8_u_pgw_f_teid.data = &pgw_s5u_teid;
@ -412,6 +420,7 @@ void sgw_s11_handle_release_access_bearers_request(gtp_xact_t *s11_xact,
pkbuf_t *pkbuf = NULL;
gtp_message_t gtp_message;
sgw_bearer_t *bearer = NULL, *next_bearer = NULL;
sgw_tunnel_t *s1u_tunnel = NULL;
sgw_sess_t *sess = NULL;
gtp_cause_t cause;
@ -434,8 +443,11 @@ void sgw_s11_handle_release_access_bearers_request(gtp_xact_t *s11_xact,
{
next_bearer = list_next(bearer);
bearer->enb_s1u_teid = 0;
bearer->enb_s1u_addr = 0;
s1u_tunnel = sgw_s1u_tunnel_in_bearer(bearer);
d_assert(s1u_tunnel, return, "Null param");
s1u_tunnel->remote_teid = 0;
s1u_tunnel->remote_addr = 0;
bearer = next_bearer;
}

View File

@ -16,7 +16,7 @@ void sgw_s5c_handle_create_session_response(gtp_xact_t *s5c_xact,
status_t rv;
gtp_xact_t *s11_xact = NULL;
sgw_bearer_t *bearer = NULL;
sgw_tunnel_t *tunnel = NULL;
sgw_tunnel_t *s1u_tunnel = NULL, *s5u_tunnel = NULL;
gtp_create_session_response_t *rsp = NULL;
pkbuf_t *pkbuf = NULL;
sgw_ue_t *sgw_ue = NULL;
@ -61,8 +61,10 @@ void sgw_s5c_handle_create_session_response(gtp_xact_t *s5c_xact,
bearer = sgw_bearer_find_by_sess_ebi(sess,
rsp->bearer_contexts_created.eps_bearer_id.u8);
d_assert(bearer, return, "No Bearer Context");
tunnel = sgw_direct_tunnel_in_bearer(bearer);
d_assert(tunnel, return, "No Tunnel Context");
s1u_tunnel = sgw_s1u_tunnel_in_bearer(bearer);
d_assert(s1u_tunnel, return, "No Tunnel Context");
s5u_tunnel = sgw_s5u_tunnel_in_bearer(bearer);
d_assert(s5u_tunnel, return, "No Tunnel Context");
/* Receive Control Plane(UL) : PGW-S5C */
pgw_s5c_teid = rsp->pgw_s5_s8__s2a_s2b_f_teid_for_pmip_based_interface_or_for_gtp_based_control_plane_interface.
@ -76,8 +78,8 @@ void sgw_s5c_handle_create_session_response(gtp_xact_t *s5c_xact,
/* Receive Data Plane(UL) : PGW-S5U */
pgw_s5u_teid = rsp->bearer_contexts_created.s5_s8_u_sgw_f_teid.data;
d_assert(pgw_s5u_teid, return, "Null param");
tunnel->remote_teid = ntohl(pgw_s5u_teid->teid);
tunnel->remote_addr = pgw_s5u_teid->ipv4_addr;
s5u_tunnel->remote_teid = ntohl(pgw_s5u_teid->teid);
s5u_tunnel->remote_addr = pgw_s5u_teid->ipv4_addr;
rsp->bearer_contexts_created.s5_s8_u_sgw_f_teid.presence = 0;
/* Send Control Plane(UL) : SGW-S11 */
@ -93,9 +95,9 @@ void sgw_s5c_handle_create_session_response(gtp_xact_t *s5c_xact,
/* Send Data Plane(UL) : SGW-S1U */
memset(&sgw_s1u_teid, 0, sizeof(gtp_f_teid_t));
sgw_s1u_teid.ipv4 = 1;
sgw_s1u_teid.interface_type = tunnel->interface_type;
sgw_s1u_teid.ipv4_addr = tunnel->local_addr;
sgw_s1u_teid.teid = htonl(tunnel->local_teid);
sgw_s1u_teid.interface_type = s1u_tunnel->interface_type;
sgw_s1u_teid.ipv4_addr = s1u_tunnel->local_addr;
sgw_s1u_teid.teid = htonl(s1u_tunnel->local_teid);
rsp->bearer_contexts_created.s1_u_enodeb_f_teid.presence = 1;
rsp->bearer_contexts_created.s1_u_enodeb_f_teid.data = &sgw_s1u_teid;
rsp->bearer_contexts_created.s1_u_enodeb_f_teid.len = GTP_F_TEID_IPV4_LEN;
@ -190,7 +192,7 @@ void sgw_s5c_handle_create_bearer_request(gtp_xact_t *s5c_xact,
status_t rv;
gtp_xact_t *s11_xact = NULL;
sgw_bearer_t *bearer = NULL;
sgw_tunnel_t *tunnel = NULL;
sgw_tunnel_t *s1u_tunnel = NULL, *s5u_tunnel = NULL;
gtp_create_bearer_request_t *req = NULL;
pkbuf_t *pkbuf = NULL;
sgw_ue_t *sgw_ue = NULL;
@ -229,22 +231,24 @@ void sgw_s5c_handle_create_bearer_request(gtp_xact_t *s5c_xact,
bearer = sgw_bearer_add(sess);
d_assert(bearer, return, "No Bearer Context");
tunnel = sgw_direct_tunnel_in_bearer(bearer);
d_assert(tunnel, return, "No Tunnel Context");
s1u_tunnel = sgw_s1u_tunnel_in_bearer(bearer);
d_assert(s1u_tunnel, return, "No Tunnel Context");
s5u_tunnel = sgw_s5u_tunnel_in_bearer(bearer);
d_assert(s5u_tunnel, return, "No Tunnel Context");
/* Receive Data Plane(UL) : PGW-S5U */
pgw_s5u_teid = req->bearer_contexts.s5_s8_u_sgw_f_teid.data;
d_assert(pgw_s5u_teid, return, "Null param");
tunnel->remote_teid = ntohl(pgw_s5u_teid->teid);
tunnel->remote_addr = pgw_s5u_teid->ipv4_addr;
s5u_tunnel->remote_teid = ntohl(pgw_s5u_teid->teid);
s5u_tunnel->remote_addr = pgw_s5u_teid->ipv4_addr;
req->bearer_contexts.s5_s8_u_sgw_f_teid.presence = 0;
/* Send Data Plane(UL) : SGW-S1U */
memset(&sgw_s1u_teid, 0, sizeof(gtp_f_teid_t));
sgw_s1u_teid.ipv4 = 1;
sgw_s1u_teid.interface_type = tunnel->interface_type;
sgw_s1u_teid.ipv4_addr = tunnel->local_addr;
sgw_s1u_teid.teid = htonl(tunnel->local_teid);
sgw_s1u_teid.interface_type = s1u_tunnel->interface_type;
sgw_s1u_teid.ipv4_addr = s1u_tunnel->local_addr;
sgw_s1u_teid.teid = htonl(s1u_tunnel->local_teid);
req->bearer_contexts.s1_u_enodeb_f_teid.presence = 1;
req->bearer_contexts.s1_u_enodeb_f_teid.data = &sgw_s1u_teid;
req->bearer_contexts.s1_u_enodeb_f_teid.len = GTP_F_TEID_IPV4_LEN;
@ -264,6 +268,6 @@ void sgw_s5c_handle_create_bearer_request(gtp_xact_t *s5c_xact,
d_assert(rv == CORE_OK, return, "xact_commit error");
d_trace(3, "[GTP] Create Bearer Request : SGW[%d] <-- PGW[%d]\n",
tunnel->local_teid, tunnel->remote_teid);
s5u_tunnel->local_teid, s5u_tunnel->remote_teid);
}