forked from acouzens/open5gs
add tunnel context in SGW context
This commit is contained in:
parent
142a988064
commit
ff7ef740c0
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue