Getting all information necessary at the SP-GW to setup the user tunnels from the modify bearer response.

master
Pedro Alvarez 7 years ago
parent d972549124
commit 04d67509cf

@ -75,7 +75,7 @@ typedef union gtpc_msg_choice
struct gtpc_create_session_request create_session_request; struct gtpc_create_session_request create_session_request;
struct gtpc_create_session_response create_session_response; struct gtpc_create_session_response create_session_response;
struct gtpc_modify_bearer_request modify_bearer_request; struct gtpc_modify_bearer_request modify_bearer_request;
//struct gtpc_modify_bearer_response modify_bearer_response; struct gtpc_modify_bearer_response modify_bearer_response;
} gtpc_msg_choice_t; } gtpc_msg_choice_t;
/**************************************************************************** /****************************************************************************

@ -334,5 +334,48 @@ struct gtpc_modify_bearer_request
//SGW LDN //SGW LDN
}; };
}; //namespace /****************************************************************************
*
* GTP-C v2 Modify Bearer Response
* Ref: 3GPP TS 29.274 v10.14.0 Table 7.2.8-1
*
***************************************************************************/
struct gtpc_modify_bearer_response
{
struct gtpc_cause_ie cause;
//MSISDN
//Linked EPS Bearer ID
//APN-AMBR
//APN Restriction
//Protocol Configuration Options
struct gtpc_bearer_context_modified_ie
{
uint8_t ebi;
struct gtpc_cause_ie cause;
bool s1_u_sgw_f_teid_present;
struct gtpc_f_teid_ie s1_u_sgw_f_teid;
bool s12_sgw_f_teid_present;
struct gtpc_f_teid_ie s12_sgw_f_teid;
bool s4_u_sgw_f_teid_present;
struct gtpc_f_teid_ie s4_u_sgw_f_teid;
//charging id
//bearer flags
} eps_bearer_context_modified;
//Bearer Contexts marked for removal
//Change Reporting action
//CSG information reporting action
//Charging gateway name
//charging gateway address
//P-GW FQ-CSID
//S-GW FQ-CSID
//Recovery
//S-GW LDN
//P-GW LDN
//indication Flags
//ext
};
} //namespace
#endif //GTPC_V2_MSG_H #endif //GTPC_V2_MSG_H

@ -22,5 +22,5 @@ mnc = 01
mme_bind_addr = 127.0.0.0/24 mme_bind_addr = 127.0.0.0/24
[spgw] [spgw]
gtpu_bind_addr=127.0.0.1 gtpu_bind_addr=127.0.0.2
sgi_if_addr=172.0.0.1 sgi_if_addr=172.0.0.1

@ -102,6 +102,8 @@ private:
uint64_t m_next_ctrl_teid; uint64_t m_next_ctrl_teid;
uint64_t m_next_user_teid; uint64_t m_next_user_teid;
sockaddr_in m_s1u_addr;
std::map<uint32_t,spgw_tunnel_ctx*> m_teid_to_tunnel_ctx; //Map control TEID to tunnel ctx. Usefull to get reply ctrl TEID, UE IP, etc. std::map<uint32_t,spgw_tunnel_ctx*> m_teid_to_tunnel_ctx; //Map control TEID to tunnel ctx. Usefull to get reply ctrl TEID, UE IP, etc.
std::map<in_addr_t,srslte::gtpc_f_teid_ie> m_ip_to_teid; //Map IP to User-plane TEID for downlink traffic std::map<in_addr_t,srslte::gtpc_f_teid_ie> m_ip_to_teid; //Map IP to User-plane TEID for downlink traffic

@ -108,6 +108,7 @@ mme_gtpc::send_create_session_request(uint64_t imsi, uint32_t mme_ue_s1ap_id)
cs_req_pdu.header.type = srslte::GTPC_MSG_TYPE_CREATE_SESSION_REQUEST; cs_req_pdu.header.type = srslte::GTPC_MSG_TYPE_CREATE_SESSION_REQUEST;
//Setup GTP-C Create Session Request IEs //Setup GTP-C Create Session Request IEs
cs_req->imsi = imsi;
// Control TEID allocated // Control TEID allocated
cs_req->sender_f_teid.teid = get_new_ctrl_teid(); cs_req->sender_f_teid.teid = get_new_ctrl_teid();
cs_req->sender_f_teid.ipv4 = m_mme_gtpc_ip; cs_req->sender_f_teid.ipv4 = m_mme_gtpc_ip;
@ -171,7 +172,7 @@ mme_gtpc::send_modify_bearer_request(erab_ctx_t *erab_ctx)
srslte::gtpc_f_teid_ie *enb_fteid = &erab_ctx->enb_fteid; srslte::gtpc_f_teid_ie *enb_fteid = &erab_ctx->enb_fteid;
srslte::gtpc_f_teid_ie *sgw_ctrl_fteid = &erab_ctx->sgw_ctrl_fteid; srslte::gtpc_f_teid_ie *sgw_ctrl_fteid = &erab_ctx->sgw_ctrl_fteid;
srslte::gtpc_header *header = &pdu.header; srslte::gtpc_header *header = &mb_req_pdu.header;
header->teid_present = true; header->teid_present = true;
header->teid = sgw_ctrl_fteid->teid; header->teid = sgw_ctrl_fteid->teid;
header->type = srslte::GTPC_MSG_TYPE_MODIFY_BEARER_REQUEST; header->type = srslte::GTPC_MSG_TYPE_MODIFY_BEARER_REQUEST;
@ -182,7 +183,9 @@ mme_gtpc::send_modify_bearer_request(erab_ctx_t *erab_ctx)
mb_req->eps_bearer_context_to_modify.s1_u_enb_f_teid.teid = enb_fteid->teid; mb_req->eps_bearer_context_to_modify.s1_u_enb_f_teid.teid = enb_fteid->teid;
m_mme_gtpc_log->info("GTP-C Modify bearer request -- S-GW Control TEID %d\n", sgw_ctrl_fteid->teid ); m_mme_gtpc_log->info("GTP-C Modify bearer request -- S-GW Control TEID %d\n", sgw_ctrl_fteid->teid );
m_mme_gtpc_log->info("GTP-C Modify bearer request -- S1-U TEID 0x%x\n", enb_fteid->teid ); struct in_addr addr;
addr.s_addr = enb_fteid->ipv4;
m_mme_gtpc_log->info("GTP-C Modify bearer request -- S1-U TEID 0x%x, IP %s\n", enb_fteid->teid, inet_ntoa(addr) );
// //
srslte::gtpc_pdu mb_resp_pdu; srslte::gtpc_pdu mb_resp_pdu;

@ -674,8 +674,12 @@ s1ap::send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, struct srslte:
ue_ctx->erabs_ctx[erab_ctxt->e_RAB_ID.E_RAB_ID].sgw_ctrl_fteid.teid = sgw_ctrl_fteid.teid; ue_ctx->erabs_ctx[erab_ctxt->e_RAB_ID.E_RAB_ID].sgw_ctrl_fteid.teid = sgw_ctrl_fteid.teid;
ue_ctx->erabs_ctx[erab_ctxt->e_RAB_ID.E_RAB_ID].sgw_ctrl_fteid.ipv4 = sgw_ctrl_fteid.ipv4; ue_ctx->erabs_ctx[erab_ctxt->e_RAB_ID.E_RAB_ID].sgw_ctrl_fteid.ipv4 = sgw_ctrl_fteid.ipv4;
struct in_addr addr;
addr.s_addr = sgw_s1u_ip;
m_s1ap_log->info("Sent Intial Context Setup Request. E-RAB id %d \n",erab_ctxt->e_RAB_ID.E_RAB_ID); m_s1ap_log->info("Sent Intial Context Setup Request. E-RAB id %d \n",erab_ctxt->e_RAB_ID.E_RAB_ID);
m_s1ap_log->info("Initial Context -- S1-U TEID 0x%x. IP %s \n", tmp_teid,inet_ntoa(addr));
m_s1ap_log->console("Sent Intial Context Setup Request, E-RAB id %d\n",erab_ctxt->e_RAB_ID.E_RAB_ID); m_s1ap_log->console("Sent Intial Context Setup Request, E-RAB id %d\n",erab_ctxt->e_RAB_ID.E_RAB_ID);
m_s1ap_log->console("Initial Context -- S1-U TEID 0x%x. IP %s \n", tmp_teid,inet_ntoa(addr));
m_pool->deallocate(reply_buffer); m_pool->deallocate(reply_buffer);
m_pool->deallocate(nas_buffer); m_pool->deallocate(nas_buffer);

@ -220,16 +220,17 @@ spgw::init_s1u(spgw_args_t *args)
m_s1u_up = true; m_s1u_up = true;
//Bind the socket //Bind the socket
struct sockaddr_in servaddr; m_s1u_addr.sin_family = AF_INET;
servaddr.sin_family = AF_INET; m_s1u_addr.sin_addr.s_addr=inet_addr(args->gtpu_bind_addr.c_str());
servaddr.sin_addr.s_addr=inet_addr(args->gtpu_bind_addr.c_str()); m_s1u_addr.sin_port=htons(GTPU_RX_PORT);
servaddr.sin_port=htons(GTPU_RX_PORT);
if (bind(m_s1u,(struct sockaddr *)&servaddr,sizeof(struct sockaddr_in))) { if (bind(m_s1u,(struct sockaddr *)&m_s1u_addr,sizeof(struct sockaddr_in))) {
m_spgw_log->error("Failed to bind socket: %s\n", strerror(errno)); m_spgw_log->error("Failed to bind socket: %s\n", strerror(errno));
return srslte::ERROR_CANT_START; return srslte::ERROR_CANT_START;
} }
m_spgw_log->info("S1-U socket = %d\n", m_s1u); m_spgw_log->info("S1-U socket = %d\n", m_s1u);
m_spgw_log->info("S1-U IP = %s, Port = %d \n", inet_ntoa(m_s1u_addr.sin_addr),ntohs(m_s1u_addr.sin_port));
return srslte::ERROR_NONE; return srslte::ERROR_NONE;
} }
@ -326,9 +327,13 @@ spgw::handle_create_session_request(struct srslte::gtpc_create_session_request *
spgw_tunnel_ctx_t *tunnel_ctx = new spgw_tunnel_ctx_t; spgw_tunnel_ctx_t *tunnel_ctx = new spgw_tunnel_ctx_t;
tunnel_ctx->imsi = cs_req->imsi; tunnel_ctx->imsi = cs_req->imsi;
tunnel_ctx->up_user_fteid.teid = spgw_uplink_user_teid; tunnel_ctx->up_user_fteid.teid = spgw_uplink_user_teid;
tunnel_ctx->up_user_fteid.ipv4 = m_s1u_addr.sin_addr.s_addr;
tunnel_ctx->dw_ctrl_fteid.teid = cs_req->sender_f_teid.teid;
tunnel_ctx->dw_ctrl_fteid.ipv4 = cs_req->sender_f_teid.ipv4;
tunnel_ctx->up_ctrl_fteid.teid = spgw_uplink_ctrl_teid; tunnel_ctx->up_ctrl_fteid.teid = spgw_uplink_ctrl_teid;
tunnel_ctx->ue_ipv4 = ue_ip; tunnel_ctx->ue_ipv4 = ue_ip;
m_teid_to_tunnel_ctx.insert(std::pair<uint32_t,spgw_tunnel_ctx_t*>(spgw_uplink_ctrl_teid,tunnel_ctx));
//Create session response message //Create session response message
//Setup GTP-C header //Setup GTP-C header
header->piggyback = false; header->piggyback = false;
@ -348,6 +353,7 @@ spgw::handle_create_session_request(struct srslte::gtpc_create_session_request *
cs_resp->eps_bearer_context_created.cause.cause_value = srslte::GTPC_CAUSE_VALUE_REQUEST_ACCEPTED; cs_resp->eps_bearer_context_created.cause.cause_value = srslte::GTPC_CAUSE_VALUE_REQUEST_ACCEPTED;
cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid_present=true; cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid_present=true;
cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid.teid = spgw_uplink_user_teid; cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid.teid = spgw_uplink_user_teid;
cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid.ipv4 = m_s1u_addr.sin_addr.s_addr;
//Fill in the PAA //Fill in the PAA
cs_resp->paa_present = true; cs_resp->paa_present = true;
cs_resp->paa.pdn_type = srslte::GTPC_PDN_TYPE_IPV4; cs_resp->paa.pdn_type = srslte::GTPC_PDN_TYPE_IPV4;
@ -368,15 +374,30 @@ spgw::handle_modify_bearer_request(struct srslte::gtpc_pdu *mb_req_pdu, struct s
std::map<uint32_t,spgw_tunnel_ctx_t*>::iterator tunnel_it = m_teid_to_tunnel_ctx.find(ctrl_teid); std::map<uint32_t,spgw_tunnel_ctx_t*>::iterator tunnel_it = m_teid_to_tunnel_ctx.find(ctrl_teid);
if(tunnel_it == m_teid_to_tunnel_ctx.end()) if(tunnel_it == m_teid_to_tunnel_ctx.end())
{ {
m_spgw_log->warning("Could not find TEID %d to modify",ctrl_teid); m_spgw_log->warning("Could not find TEID %d to modify\n",ctrl_teid);
return; return;
} }
spgw_tunnel_ctx_t *tunnel_ctx = tunnel_it->second; spgw_tunnel_ctx_t *tunnel_ctx = tunnel_it->second;
//Store user DW link TEID //Store user DW link TEID
srslte::gtpc_modify_bearer_request *mb_req = &mb_req_pdu->choice.modify_bearer_request; srslte::gtpc_modify_bearer_request *mb_req = &mb_req_pdu->choice.modify_bearer_request;
tunnel_ctx->dw_user_fteid = mb_req->eps_bearer_context_to_modify.s1_u_enb_f_teid; tunnel_ctx->dw_user_fteid.teid = mb_req->eps_bearer_context_to_modify.s1_u_enb_f_teid.teid;
tunnel_ctx->dw_user_fteid.ipv4 = mb_req->eps_bearer_context_to_modify.s1_u_enb_f_teid.ipv4;
//Set up actual tunnel //Set up actual tunnel
m_spgw_log->info("Setting Up GTP-U tunnel. Tunnel info: \n");
struct in_addr addr;
addr.s_addr = tunnel_ctx->ue_ipv4;
m_spgw_log->info("IMSI: %lu, UE IP, %s \n",tunnel_ctx->imsi, inet_ntoa(addr));
m_spgw_log->info("S-GW Rx Ctrl TEID 0x%x, MME Rx Ctrl TEID 0x%x\n", tunnel_ctx->up_ctrl_fteid.teid, tunnel_ctx->dw_ctrl_fteid.teid);
m_spgw_log->info("S-GW Rx Ctrl IP (NA), MME Rx Ctrl IP (NA)\n");
struct in_addr addr2;
addr2.s_addr = tunnel_ctx->up_user_fteid.ipv4;
m_spgw_log->info("S-GW Rx User TEID 0x%x, S-GW Rx User IP %s\n", tunnel_ctx->up_user_fteid.teid, inet_ntoa(addr2));
struct in_addr addr3;
addr3.s_addr = tunnel_ctx->dw_user_fteid.ipv4;
m_spgw_log->info("eNB Rx User TEID 0x%x, eNB Rx User IP %s\n", tunnel_ctx->dw_user_fteid.teid, inet_ntoa(addr3));
//TODO!!! //TODO!!!
//Setting up Modify bearer response PDU //Setting up Modify bearer response PDU
@ -388,6 +409,6 @@ spgw::handle_modify_bearer_request(struct srslte::gtpc_pdu *mb_req_pdu, struct s
header->type = srslte::GTPC_MSG_TYPE_MODIFY_BEARER_RESPONSE; header->type = srslte::GTPC_MSG_TYPE_MODIFY_BEARER_RESPONSE;
//PDU //PDU
srslte::gtpc_modify_bearer_response *mb_resp = mb_req_pdu.choice.modify_bearer_response; srslte::gtpc_modify_bearer_response *mb_resp = &mb_req_pdu->choice.modify_bearer_response;
} }
} //namespace srsepc } //namespace srsepc

Loading…
Cancel
Save