add tunnel context in SGW context

This commit is contained in:
Sukchan Lee 2017-09-13 18:52:05 +09:00
parent 142a988064
commit ff7ef740c0
5 changed files with 125 additions and 41 deletions

View File

@ -8,7 +8,6 @@
#include "types.h"
#include "gtp_types.h"
#include "gtp_path.h"
#include "context.h"
#include "sgw_context.h"
@ -615,11 +614,12 @@ sgw_sess_t *sgw_sess_add(
/* Set APN */
core_cpystrn(sess->pdn.apn, apn, MAX_APN_LEN+1);
list_init(&sess->bearer_list);
list_append(&sgw_ue->sess_list, sess);
sess->sgw_ue = sgw_ue;
list_init(&sess->bearer_list);
bearer = sgw_bearer_add(sess);
d_assert(bearer, sgw_sess_remove(sess); return NULL,
"Can't add default bearer context");
@ -716,17 +716,17 @@ 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");
tunnel = sgw_tunnel_add(bearer, GTP_F_TEID_S1_U_ENODEB_GTP_U);
d_assert(tunnel, return NULL, "Tunnel context allocation failed");
bearer->sgw_s1u_teid = bearer->index;
bearer->sgw_s1u_addr = sgw_self()->s1u_addr;
bearer->sgw_s5u_teid = bearer->index;
bearer->sgw_s5u_addr = sgw_self()->s5u_addr;
bearer->sess = sess;
list_append(&sess->bearer_list, bearer);
list_init(&bearer->tunnel_list);
tunnel = sgw_tunnel_add(bearer, GTP_F_TEID_S1_U_ENODEB_GTP_U);
d_assert(tunnel, return NULL, "Tunnel context allocation failed");
return bearer;
}
@ -781,11 +781,6 @@ sgw_bearer_t* sgw_bearer_find_by_sgw_s5u_teid(c_uint32_t sgw_s5u_teid)
return sgw_bearer_find(sgw_s5u_teid);
}
sgw_bearer_t* sgw_bearer_find_by_sgw_s1u_teid(c_uint32_t sgw_s1u_teid)
{
return sgw_bearer_find(sgw_s1u_teid);
}
sgw_bearer_t* sgw_bearer_find_by_sess_ebi(sgw_sess_t *sess, c_uint8_t ebi)
{
sgw_bearer_t *bearer = NULL;
@ -850,8 +845,9 @@ 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->bearer = bearer;
list_append(&bearer->tunnel_list, tunnel);
return tunnel;
@ -874,10 +870,10 @@ status_t sgw_tunnel_remove_all(sgw_bearer_t *bearer)
d_assert(bearer, return CORE_ERROR, "Null param");
tunnel = list_first(&bearer->tunnel_list);
tunnel = sgw_tunnel_first(bearer);
while (tunnel)
{
next_tunnel = list_next(tunnel);
next_tunnel = sgw_tunnel_next(tunnel);
sgw_tunnel_remove(tunnel);
@ -889,7 +885,7 @@ status_t sgw_tunnel_remove_all(sgw_bearer_t *bearer)
sgw_tunnel_t* sgw_tunnel_find(index_t index)
{
d_assert(index && index < MAX_POOL_OF_BEARER, return NULL,
d_assert(index && index < MAX_POOL_OF_TUNNEL, return NULL,
"Invalid Index(%d)",index);
return index_find(&sgw_tunnel_pool, index);
@ -900,6 +896,64 @@ 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 *tunnel = NULL;
d_assert(bearer, return NULL,);
tunnel = sgw_tunnel_first(bearer);
while(tunnel)
{
if (tunnel->interface_type == GTP_F_TEID_S1_U_ENODEB_GTP_U)
{
return tunnel;
}
tunnel = sgw_tunnel_next(tunnel);
}
return NULL;
}
sgw_tunnel_t* sgw_dl_indirect_tunnel_in_bearer(sgw_bearer_t *bearer)
{
sgw_tunnel_t *tunnel = NULL;
d_assert(bearer, return NULL, "Null param");
tunnel = sgw_tunnel_first(bearer);
while (tunnel)
{
if (tunnel->interface_type ==
GTP_F_TEID_ENODEB_GTP_U_FOR_DL_DATA_FORWARDING)
return tunnel;
tunnel = sgw_tunnel_next(tunnel);
}
return NULL;
}
sgw_tunnel_t* sgw_ul_indirect_tunnel_in_bearer(sgw_bearer_t *bearer)
{
sgw_tunnel_t *tunnel = NULL;
d_assert(bearer, return NULL, "Null param");
tunnel = sgw_tunnel_first(bearer);
while (tunnel)
{
if (tunnel->interface_type ==
GTP_F_TEID_ENODEB_GTP_U_FOR_UL_DATA_FORWARDING)
return tunnel;
tunnel = sgw_tunnel_next(tunnel);
}
return NULL;
}
sgw_tunnel_t* sgw_tunnel_first(sgw_bearer_t *bearer)
{
d_assert(bearer, return NULL, "Null param");

View File

@ -116,19 +116,12 @@ typedef struct _sgw_bearer_t {
c_uint8_t ebi;
/* IMPORTANT!
* SGW-S1U-TEID is same with an index */
c_uint32_t sgw_s1u_teid;
c_uint32_t sgw_s1u_addr;
c_uint32_t enb_s1u_teid;
c_uint32_t enb_s1u_addr;
/* IMPORTANT!
* SGW-S5U-TEID is same with an index */
c_uint32_t sgw_s5u_teid;
c_uint32_t sgw_s5u_addr;
c_uint32_t pgw_s5u_teid;
c_uint32_t pgw_s5u_addr;
c_uint32_t enb_s1u_teid;
c_uint32_t enb_s1u_addr;
/* User-Lication-Info */
tai_t tai;
@ -144,6 +137,7 @@ typedef struct _sgw_bearer_t {
} sgw_bearer_t;
typedef struct _sgw_tunnel_t {
lnode_t node; /**< A node of list_t */
index_t index;
c_uint8_t interface_type;
@ -213,8 +207,6 @@ CORE_DECLARE(status_t) sgw_bearer_remove_all(sgw_sess_t *sess);
CORE_DECLARE(sgw_bearer_t*) sgw_bearer_find(index_t index);
CORE_DECLARE(sgw_bearer_t*) sgw_bearer_find_by_sgw_s5u_teid(
c_uint32_t sgw_s5u_teid);
CORE_DECLARE(sgw_bearer_t*) sgw_bearer_find_by_sgw_s1u_teid(
c_uint32_t sgw_s1u_teid);
CORE_DECLARE(sgw_bearer_t*) sgw_bearer_find_by_sess_ebi(
sgw_sess_t *sess, c_uint8_t ebi);
CORE_DECLARE(sgw_bearer_t*) sgw_bearer_find_by_ue_ebi(
@ -230,6 +222,11 @@ 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_dl_indirect_tunnel_in_bearer(
sgw_bearer_t *bearer);
CORE_DECLARE(sgw_tunnel_t*) sgw_ul_indirect_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

@ -4,6 +4,7 @@
#include "core_net.h"
#include "types.h"
#include "gtp_types.h"
#include "gtp_path.h"
#include "sgw_context.h"
@ -221,7 +222,7 @@ 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_bearer_t *bearer = NULL;
sgw_tunnel_t *tunnel = NULL;
c_uint32_t teid;
d_assert(sock, return -1, "Null param");
@ -263,6 +264,28 @@ static int _gtpv1_s1u_recv_cb(net_sock_t *sock, void *data)
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_ENODEB_GTP_U)
gnode.sock = sgw_self()->s5u_sock;
else if (tunnel->interface_type ==
GTP_F_TEID_ENODEB_GTP_U_FOR_DL_DATA_FORWARDING)
gnode.sock = sgw_self()->s1u_sock;
else if (tunnel->interface_type ==
GTP_F_TEID_ENODEB_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);
}
#if 0
bearer = sgw_bearer_find_by_sgw_s1u_teid(teid);
if (bearer)
{
@ -275,6 +298,7 @@ static int _gtpv1_s1u_recv_cb(net_sock_t *sock, void *data)
gtp_send(&gnode, pkbuf);
}
#endif
}
pkbuf_free(pkbuf);

View File

@ -295,6 +295,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;
gtp_create_bearer_response_t *req = NULL;
gtp_f_teid_t *sgw_s1u_teid = NULL, *enb_s1u_teid = NULL;
@ -341,8 +342,10 @@ void sgw_s11_handle_create_bearer_response(gtp_xact_t *s11_xact,
d_assert(sgw_s1u_teid, return, "Null param");
req->bearer_contexts.s4_u_sgsn_f_teid.presence = 0;
/* Find the Bearer by SGW-S1U-TEID */
bearer = sgw_bearer_find_by_sgw_s1u_teid(ntohl(sgw_s1u_teid->teid));
/* 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;
d_assert(bearer, return, "Null param");
sess = bearer->sess;
d_assert(sess, return, "Null param");
@ -377,8 +380,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(bearer->pgw_s5u_teid);
pgw_s5u_teid.ipv4_addr = bearer->pgw_s5u_addr;
pgw_s5u_teid.teid = htonl(tunnel->remote_teid);
pgw_s5u_teid.ipv4_addr = 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;

View File

@ -16,6 +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;
gtp_create_session_response_t *rsp = NULL;
pkbuf_t *pkbuf = NULL;
sgw_ue_t *sgw_ue = NULL;
@ -60,6 +61,8 @@ 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");
/* 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.
@ -73,8 +76,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");
bearer->pgw_s5u_teid = ntohl(pgw_s5u_teid->teid);
bearer->pgw_s5u_addr = pgw_s5u_teid->ipv4_addr;
tunnel->remote_teid = ntohl(pgw_s5u_teid->teid);
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 */
@ -91,8 +94,8 @@ void sgw_s5c_handle_create_session_response(gtp_xact_t *s5c_xact,
memset(&sgw_s1u_teid, 0, sizeof(gtp_f_teid_t));
sgw_s1u_teid.ipv4 = 1;
sgw_s1u_teid.interface_type = GTP_F_TEID_S1_U_SGW_GTP_U;
sgw_s1u_teid.ipv4_addr = bearer->sgw_s1u_addr;
sgw_s1u_teid.teid = htonl(bearer->sgw_s1u_teid);
sgw_s1u_teid.ipv4_addr = tunnel->local_addr;
sgw_s1u_teid.teid = htonl(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;
@ -187,6 +190,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;
gtp_create_bearer_request_t *req = NULL;
pkbuf_t *pkbuf = NULL;
sgw_ue_t *sgw_ue = NULL;
@ -225,20 +229,22 @@ 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");
/* 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");
bearer->pgw_s5u_teid = ntohl(pgw_s5u_teid->teid);
bearer->pgw_s5u_addr = pgw_s5u_teid->ipv4_addr;
tunnel->remote_teid = ntohl(pgw_s5u_teid->teid);
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 = GTP_F_TEID_S1_U_SGW_GTP_U;
sgw_s1u_teid.ipv4_addr = bearer->sgw_s1u_addr;
sgw_s1u_teid.teid = htonl(bearer->sgw_s1u_teid);
sgw_s1u_teid.ipv4_addr = tunnel->local_addr;
sgw_s1u_teid.teid = htonl(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;
@ -258,6 +264,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",
bearer->sgw_s1u_teid, bearer->pgw_s5u_teid);
tunnel->local_teid, tunnel->remote_teid);
}