diff --git a/src/sgw/sgw_context.c b/src/sgw/sgw_context.c index 86a864641..18506a3fd 100644 --- a/src/sgw/sgw_context.c +++ b/src/sgw/sgw_context.c @@ -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"); diff --git a/src/sgw/sgw_context.h b/src/sgw/sgw_context.h index 7c953b989..57a4fe38a 100644 --- a/src/sgw/sgw_context.h +++ b/src/sgw/sgw_context.h @@ -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); diff --git a/src/sgw/sgw_gtp_path.c b/src/sgw/sgw_gtp_path.c index 6802f3cc7..0a82eef4d 100644 --- a/src/sgw/sgw_gtp_path.c +++ b/src/sgw/sgw_gtp_path.c @@ -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"); diff --git a/src/sgw/sgw_s11_handler.c b/src/sgw/sgw_s11_handler.c index 5e0ccb2b8..7ab66059a 100644 --- a/src/sgw/sgw_s11_handler.c +++ b/src/sgw/sgw_s11_handler.c @@ -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; } diff --git a/src/sgw/sgw_s5c_handler.c b/src/sgw/sgw_s5c_handler.c index 93837fdd8..a68a03c5b 100644 --- a/src/sgw/sgw_s5c_handler.c +++ b/src/sgw/sgw_s5c_handler.c @@ -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); }