From 271ba5442329ce5303981b19ad50d9070eaad664 Mon Sep 17 00:00:00 2001 From: Sukchan Lee Date: Wed, 13 Sep 2017 20:35:19 +0900 Subject: [PATCH] add create indirect data forwarding tunnel response --- src/mme/mme_s11_build.c | 2 - src/mme/mme_s11_handler.c | 6 ++ src/mme/mme_s11_handler.h | 3 + src/mme/mme_sm.c | 5 ++ src/sgw/sgw_context.c | 42 +------------- src/sgw/sgw_context.h | 4 -- src/sgw/sgw_gtp_path.c | 6 +- src/sgw/sgw_s11_handler.c | 118 ++++++++++++++++++++++++++++++++++++++ src/sgw/sgw_s11_handler.h | 4 ++ src/sgw/sgw_s5c_handler.c | 4 +- src/sgw/sgw_sm.c | 6 ++ 11 files changed, 149 insertions(+), 51 deletions(-) diff --git a/src/mme/mme_s11_build.c b/src/mme/mme_s11_build.c index de7ef7bb3..a1b7a8e4c 100644 --- a/src/mme/mme_s11_build.c +++ b/src/mme/mme_s11_build.c @@ -441,7 +441,6 @@ status_t mme_s11_build_create_indirect_data_forwarding_tunnel_request( bearers[i]->s1_u_enodeb_f_teid.data = &tunnel_teid[i]; bearers[i]->s1_u_enodeb_f_teid.len = GTP_F_TEID_IPV4_LEN; i++; - printf("DL\n"); } if (MME_HAVE_UL_INDIRECT_TUNNEL(bearer)) @@ -460,7 +459,6 @@ status_t mme_s11_build_create_indirect_data_forwarding_tunnel_request( bearers[i]->s12_rnc_f_teid.presence = 1; bearers[i]->s12_rnc_f_teid.data = &tunnel_teid[i]; bearers[i]->s12_rnc_f_teid.len = GTP_F_TEID_IPV4_LEN; - printf("UL\n"); i++; } diff --git a/src/mme/mme_s11_handler.c b/src/mme/mme_s11_handler.c index 7a23c0bbb..4dbb9301b 100644 --- a/src/mme/mme_s11_handler.c +++ b/src/mme/mme_s11_handler.c @@ -332,3 +332,9 @@ void mme_s11_handle_downlink_data_notification( rv = gtp_xact_commit(xact); d_assert(rv == CORE_OK, return, "xact_commit error"); } + +void mme_s11_handle_create_indirect_data_forwarding_tunnel_response( + gtp_xact_t *xact, mme_ue_t *mme_ue, + gtp_create_indirect_data_forwarding_tunnel_response_t *rsp) +{ +} diff --git a/src/mme/mme_s11_handler.h b/src/mme/mme_s11_handler.h index 9ba8d495f..e08d0bf21 100644 --- a/src/mme/mme_s11_handler.h +++ b/src/mme/mme_s11_handler.h @@ -24,6 +24,9 @@ CORE_DECLARE(void) mme_s11_handle_release_access_bearers_response( CORE_DECLARE(void) mme_s11_handle_downlink_data_notification( gtp_xact_t *xact, mme_ue_t *mme_ue, gtp_downlink_data_notification_t *noti); +CORE_DECLARE(void) mme_s11_handle_create_indirect_data_forwarding_tunnel_response( + gtp_xact_t *xact, mme_ue_t *mme_ue, + gtp_create_indirect_data_forwarding_tunnel_response_t *rsp); #ifdef __cplusplus } diff --git a/src/mme/mme_sm.c b/src/mme/mme_sm.c index aec2b0081..6a675bcae 100644 --- a/src/mme/mme_sm.c +++ b/src/mme/mme_sm.c @@ -355,6 +355,11 @@ void mme_state_operational(fsm_t *s, event_t *e) /* Start T3413 */ tm_start(mme_ue->t3413); break; + case GTP_CREATE_INDIRECT_DATA_FORWARDING_TUNNEL_RESPONSE_TYPE: + mme_s11_handle_create_indirect_data_forwarding_tunnel_response( + xact, mme_ue, + &message.create_indirect_data_forwarding_tunnel_response); + break; default: d_warn("Not implmeneted(type:%d)", message.h.type); break; diff --git a/src/sgw/sgw_context.c b/src/sgw/sgw_context.c index 2e44036bd..8a7b99f02 100644 --- a/src/sgw/sgw_context.c +++ b/src/sgw/sgw_context.c @@ -724,7 +724,7 @@ sgw_bearer_t* sgw_bearer_add(sgw_sess_t *sess) list_init(&bearer->tunnel_list); - tunnel = sgw_tunnel_add(bearer, GTP_F_TEID_S1_U_ENODEB_GTP_U); + tunnel = sgw_tunnel_add(bearer, GTP_F_TEID_S1_U_SGW_GTP_U); d_assert(tunnel, return NULL, "Tunnel context allocation failed"); return bearer; @@ -905,7 +905,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_ENODEB_GTP_U) + if (tunnel->interface_type == GTP_F_TEID_S1_U_SGW_GTP_U) { return tunnel; } @@ -916,44 +916,6 @@ sgw_tunnel_t* sgw_direct_tunnel_in_bearer(sgw_bearer_t *bearer) 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"); diff --git a/src/sgw/sgw_context.h b/src/sgw/sgw_context.h index 912364809..33fcdd56d 100644 --- a/src/sgw/sgw_context.h +++ b/src/sgw/sgw_context.h @@ -223,10 +223,6 @@ 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); diff --git a/src/sgw/sgw_gtp_path.c b/src/sgw/sgw_gtp_path.c index b758eab73..44406f235 100644 --- a/src/sgw/sgw_gtp_path.c +++ b/src/sgw/sgw_gtp_path.c @@ -271,13 +271,13 @@ static int _gtpv1_s1u_recv_cb(net_sock_t *sock, void *data) gnode.addr = tunnel->remote_addr; gnode.port = GTPV1_U_UDP_PORT; - if (tunnel->interface_type == GTP_F_TEID_S1_U_ENODEB_GTP_U) + if (tunnel->interface_type == GTP_F_TEID_S1_U_SGW_GTP_U) gnode.sock = sgw_self()->s5u_sock; else if (tunnel->interface_type == - GTP_F_TEID_ENODEB_GTP_U_FOR_DL_DATA_FORWARDING) + GTP_F_TEID_SGW_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) + GTP_F_TEID_SGW_GTP_U_FOR_UL_DATA_FORWARDING) gnode.sock = sgw_self()->s1u_sock; else d_assert(0, return -1, "Invalid type(%d)", diff --git a/src/sgw/sgw_s11_handler.c b/src/sgw/sgw_s11_handler.c index 31b7e9e81..c7ae2a8f9 100644 --- a/src/sgw/sgw_s11_handler.c +++ b/src/sgw/sgw_s11_handler.c @@ -4,6 +4,7 @@ #include "core_lib.h" #include "gtp_types.h" +#include "gtp_conv.h" #include "sgw_event.h" #include "sgw_context.h" @@ -521,3 +522,120 @@ void sgw_s11_handle_downlink_data_notification_ack(sgw_ue_t *sgw_ue, d_trace(3, "[GTP] Downlink Data Notification Ack: " "MME[%d] --> SGW[%d]\n", sgw_ue->mme_s11_teid, sgw_ue->sgw_s11_teid); } + +void sgw_s11_handle_create_indirect_data_forwarding_tunnel_request( + gtp_xact_t *s11_xact, sgw_ue_t *sgw_ue, + gtp_create_indirect_data_forwarding_tunnel_request_t *req) +{ + status_t rv; + gtp_create_indirect_data_forwarding_tunnel_response_t *rsp = NULL; + pkbuf_t *pkbuf = NULL; + gtp_message_t gtp_message; + int i; + + sgw_bearer_t *bearer = NULL; + sgw_tunnel_t *tunnel = NULL; + + gtp_cause_t cause; + tlv_bearer_context_t *req_bearers[GTP_MAX_NUM_OF_INDIRECT_TUNNEL]; + tlv_bearer_context_t *rsp_bearers[GTP_MAX_NUM_OF_INDIRECT_TUNNEL]; + gtp_f_teid_t *req_teid = NULL; + gtp_f_teid_t rsp_teid[GTP_MAX_NUM_OF_INDIRECT_TUNNEL]; + + + d_assert(sgw_ue, return, "Null param"); + d_assert(s11_xact, return, "Null param"); + d_assert(req, return, "Null param"); + + rsp = >p_message.create_indirect_data_forwarding_tunnel_response; + memset(>p_message, 0, sizeof(gtp_message_t)); + + gtp_bearers_in_create_indirect_tunnel_request(&req_bearers, req); + gtp_bearers_in_create_indirect_tunnel_response(&rsp_bearers, rsp); + + memset(&cause, 0, sizeof(cause)); + cause.value = GTP_CAUSE_REQUEST_ACCEPTED; + + rsp->cause.presence = 1; + rsp->cause.data = &cause; + rsp->cause.len = sizeof(cause); + + for (i = 0; req_bearers[i]->presence; i++) + { + if (req_bearers[i]->eps_bearer_id.presence == 0) + { + d_error("No EBI"); + } + + bearer = sgw_bearer_find_by_ue_ebi(sgw_ue, + req_bearers[i]->eps_bearer_id.u8); + d_assert(bearer, return, "No Bearer Context"); + + if (req_bearers[i]->s1_u_enodeb_f_teid.presence) + { + req_teid = req_bearers[i]->s1_u_enodeb_f_teid.data; + d_assert(req_teid, return,); + + tunnel = sgw_tunnel_add(bearer, + GTP_F_TEID_SGW_GTP_U_FOR_DL_DATA_FORWARDING); + d_assert(tunnel, return, "No Tunnel Context"); + + } + else if (req_bearers[i]->s12_rnc_f_teid.presence) + { + req_teid = req_bearers[i]->s12_rnc_f_teid.data; + d_assert(req_teid, return,); + + tunnel = sgw_tunnel_add(bearer, + GTP_F_TEID_SGW_GTP_U_FOR_UL_DATA_FORWARDING); + d_assert(tunnel, return, "No Tunnel Context"); + } + else + d_assert(0, return, "Not Supported"); + + tunnel->remote_teid = ntohl(req_teid->teid); + tunnel->remote_addr = req_teid->ipv4_addr; + + d_assert(rsp_bearers[i], return,); + rsp_bearers[i]->presence = 1; + rsp_bearers[i]->eps_bearer_id.presence = 1; + rsp_bearers[i]->eps_bearer_id.u8 = bearer->ebi; + + memset(&rsp_teid[i], 0, sizeof(gtp_f_teid_t)); + rsp_teid[i].ipv4 = 1; + rsp_teid[i].ipv4_addr = tunnel->local_addr; + rsp_teid[i].teid = htonl(tunnel->local_teid); + rsp_teid[i].interface_type = tunnel->interface_type; + + if (tunnel->interface_type == + GTP_F_TEID_SGW_GTP_U_FOR_DL_DATA_FORWARDING) + { + rsp_bearers[i]->s4_u_sgsn_f_teid.presence = 1; + rsp_bearers[i]->s4_u_sgsn_f_teid.data = &rsp_teid[i]; + rsp_bearers[i]->s4_u_sgsn_f_teid.len = GTP_F_TEID_IPV4_LEN; + } + else if (tunnel->interface_type == + GTP_F_TEID_SGW_GTP_U_FOR_UL_DATA_FORWARDING) + { + rsp_bearers[i]->s2b_u_epdg_f_teid_5.presence = 1; + rsp_bearers[i]->s2b_u_epdg_f_teid_5.data = &rsp_teid[i]; + rsp_bearers[i]->s2b_u_epdg_f_teid_5.len = GTP_F_TEID_IPV4_LEN; + } + } + + gtp_message.h.type = + GTP_CREATE_INDIRECT_DATA_FORWARDING_TUNNEL_RESPONSE_TYPE; + gtp_message.h.teid = sgw_ue->mme_s11_teid; + + rv = gtp_build_msg(&pkbuf, >p_message); + d_assert(rv == CORE_OK, return, "gtp build failed"); + + rv = gtp_xact_update_tx(s11_xact, >p_message.h, pkbuf); + d_assert(rv == CORE_OK, return, "gtp_xact_update_tx error"); + + rv = gtp_xact_commit(s11_xact); + d_assert(rv == CORE_OK, return, "xact_commit error"); + + d_trace(3, "[GTP] Create Indirect Data Forwarding Tunnel Response : " + "MME[%d] --> SGW[%d]\n", sgw_ue->mme_s11_teid, sgw_ue->sgw_s11_teid); +} diff --git a/src/sgw/sgw_s11_handler.h b/src/sgw/sgw_s11_handler.h index b315871f9..da0ce55f4 100644 --- a/src/sgw/sgw_s11_handler.h +++ b/src/sgw/sgw_s11_handler.h @@ -24,6 +24,10 @@ CORE_DECLARE(void) sgw_s11_handle_release_access_bearers_request( CORE_DECLARE(void) sgw_s11_handle_lo_dldata_notification(sgw_bearer_t *bearer); CORE_DECLARE(void) sgw_s11_handle_downlink_data_notification_ack( sgw_ue_t *sgw_ue, gtp_downlink_data_notification_acknowledge_t *ack); + +CORE_DECLARE(void) sgw_s11_handle_create_indirect_data_forwarding_tunnel_request( + gtp_xact_t *s11_xact, sgw_ue_t *sgw_ue, + gtp_create_indirect_data_forwarding_tunnel_request_t *req); #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/src/sgw/sgw_s5c_handler.c b/src/sgw/sgw_s5c_handler.c index b0fa0a7b4..a4e1fcabf 100644 --- a/src/sgw/sgw_s5c_handler.c +++ b/src/sgw/sgw_s5c_handler.c @@ -93,7 +93,7 @@ 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 = GTP_F_TEID_S1_U_SGW_GTP_U; + sgw_s1u_teid.interface_type = tunnel->interface_type; 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; @@ -242,7 +242,7 @@ void sgw_s5c_handle_create_bearer_request(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 = GTP_F_TEID_S1_U_SGW_GTP_U; + sgw_s1u_teid.interface_type = tunnel->interface_type; 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; diff --git a/src/sgw/sgw_sm.c b/src/sgw/sgw_sm.c index 3a3dcd542..3d14d22ea 100644 --- a/src/sgw/sgw_sm.c +++ b/src/sgw/sgw_sm.c @@ -101,6 +101,12 @@ void sgw_state_operational(fsm_t *s, event_t *e) sgw_s11_handle_downlink_data_notification_ack(sgw_ue, &message.downlink_data_notification_acknowledge); break; + case GTP_CREATE_INDIRECT_DATA_FORWARDING_TUNNEL_REQUEST_TYPE: + sgw_s11_handle_create_indirect_data_forwarding_tunnel_request( + xact, sgw_ue, + &message. + create_indirect_data_forwarding_tunnel_request); + break; default: d_warn("Not implmeneted(type:%d)", message.h.type); break;