forked from acouzens/open5gs
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:
parent
5d6e63c20e
commit
4672ee559f
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue