mirror of https://github.com/PentHertz/srsLTE.git
gtpu bugfix - avoid erasing indirect tunnel and causing iterator invalidation while iterating list of tunnels
This commit is contained in:
parent
977c194cbc
commit
a540c56552
|
@ -134,6 +134,8 @@ private:
|
||||||
void error_indication(in_addr_t addr, in_port_t port, uint32_t err_teid);
|
void error_indication(in_addr_t addr, in_port_t port, uint32_t err_teid);
|
||||||
bool end_marker(uint32_t teidin);
|
bool end_marker(uint32_t teidin);
|
||||||
|
|
||||||
|
void handle_end_marker(tunnel& rx_tunnel);
|
||||||
|
|
||||||
int create_dl_fwd_tunnel(uint32_t rx_teid_in, uint32_t tx_teid_in);
|
int create_dl_fwd_tunnel(uint32_t rx_teid_in, uint32_t tx_teid_in);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
|
|
@ -289,16 +289,11 @@ void gtpu::rem_tunnel(uint32_t teidin)
|
||||||
logger.warning("Removing GTPU tunnel TEID In=0x%x", teidin);
|
logger.warning("Removing GTPU tunnel TEID In=0x%x", teidin);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (it->second.fwd_teid_in_present) {
|
|
||||||
// Forward End Marker to forwarding tunnel, before deleting tunnel
|
|
||||||
end_marker(it->second.fwd_teid_in);
|
|
||||||
it->second.fwd_teid_in_present = false;
|
|
||||||
}
|
|
||||||
auto ue_it = ue_teidin_db.find(it->second.rnti);
|
auto ue_it = ue_teidin_db.find(it->second.rnti);
|
||||||
std::vector<uint32_t>& lcid_tunnels = ue_it->second[it->second.lcid];
|
std::vector<uint32_t>& lcid_tunnels = ue_it->second[it->second.lcid];
|
||||||
lcid_tunnels.erase(std::remove(lcid_tunnels.begin(), lcid_tunnels.end(), teidin), lcid_tunnels.end());
|
lcid_tunnels.erase(std::remove(lcid_tunnels.begin(), lcid_tunnels.end(), teidin), lcid_tunnels.end());
|
||||||
|
logger.debug("TEID In=%d for rnti=0x%x erased", teidin, it->second.rnti);
|
||||||
tunnels.erase(it);
|
tunnels.erase(it);
|
||||||
logger.debug("TEID In=%d erased", teidin);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void gtpu::rem_user(uint16_t rnti)
|
void gtpu::rem_user(uint16_t rnti)
|
||||||
|
@ -314,6 +309,39 @@ void gtpu::rem_user(uint16_t rnti)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gtpu::handle_end_marker(tunnel& rx_tunnel)
|
||||||
|
{
|
||||||
|
uint16_t rnti = rx_tunnel.rnti;
|
||||||
|
logger.info("Received GTPU End Marker for rnti=0x%x.", rnti);
|
||||||
|
|
||||||
|
// TS 36.300, Sec 10.1.2.2.1 - Path Switch upon handover
|
||||||
|
if (rx_tunnel.fwd_teid_in_present) {
|
||||||
|
// END MARKER should be forwarded to TeNB if forwarding is activated
|
||||||
|
end_marker(rx_tunnel.fwd_teid_in);
|
||||||
|
rx_tunnel.fwd_teid_in_present = false;
|
||||||
|
|
||||||
|
rem_tunnel(rx_tunnel.teid_in);
|
||||||
|
} else {
|
||||||
|
// TeNB switches paths, and flush PDUs that have been buffered
|
||||||
|
auto rnti_it = ue_teidin_db.find(rnti);
|
||||||
|
if (rnti_it == ue_teidin_db.end()) {
|
||||||
|
logger.error("No rnti=0x%x entry for associated TEID=%d", rnti, rx_tunnel.teid_in);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::vector<uint32_t>& bearer_tunnels = rnti_it->second[rx_tunnel.lcid];
|
||||||
|
for (uint32_t new_teidin : bearer_tunnels) {
|
||||||
|
tunnel& new_tun = tunnels.at(new_teidin);
|
||||||
|
if (new_teidin != rx_tunnel.teid_in and new_tun.prior_teid_in_present and
|
||||||
|
new_tun.prior_teid_in == rx_tunnel.teid_in) {
|
||||||
|
rem_tunnel(new_tun.prior_teid_in);
|
||||||
|
new_tun.prior_teid_in_present = false;
|
||||||
|
set_tunnel_status(new_tun.teid_in, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void gtpu::handle_gtpu_s1u_rx_packet(srslte::unique_byte_buffer_t pdu, const sockaddr_in& addr)
|
void gtpu::handle_gtpu_s1u_rx_packet(srslte::unique_byte_buffer_t pdu, const sockaddr_in& addr)
|
||||||
{
|
{
|
||||||
logger.debug("Received %d bytes from S1-U interface", pdu->N_bytes);
|
logger.debug("Received %d bytes from S1-U interface", pdu->N_bytes);
|
||||||
|
@ -376,35 +404,9 @@ void gtpu::handle_gtpu_s1u_rx_packet(srslte::unique_byte_buffer_t pdu, const soc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case GTPU_MSG_END_MARKER: {
|
case GTPU_MSG_END_MARKER:
|
||||||
uint16_t rnti = rx_tunnel->rnti;
|
handle_end_marker(*rx_tunnel);
|
||||||
logger.info("Received GTPU End Marker for rnti=0x%x.", rnti);
|
|
||||||
|
|
||||||
// TS 36.300, Sec 10.1.2.2.1 - Path Switch upon handover
|
|
||||||
if (rx_tunnel->fwd_teid_in_present) {
|
|
||||||
// END MARKER should be forwarded to TeNB if forwarding is activated
|
|
||||||
end_marker(rx_tunnel->fwd_teid_in);
|
|
||||||
rx_tunnel->fwd_teid_in_present = false;
|
|
||||||
} else {
|
|
||||||
// TeNB switches paths, and flush PDUs that have been buffered
|
|
||||||
auto rnti_it = ue_teidin_db.find(rnti);
|
|
||||||
if (rnti_it == ue_teidin_db.end()) {
|
|
||||||
logger.error("No rnti=0x%x entry for associated TEID=%d", rnti, header.teid);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
std::vector<uint32_t>& bearer_tunnels = rnti_it->second[rx_tunnel->lcid];
|
|
||||||
for (uint32_t new_teidin : bearer_tunnels) {
|
|
||||||
tunnel& new_tun = tunnels.at(new_teidin);
|
|
||||||
if (new_teidin != rx_tunnel->teid_in and new_tun.prior_teid_in_present and
|
|
||||||
new_tun.prior_teid_in == rx_tunnel->teid_in) {
|
|
||||||
rem_tunnel(new_tun.prior_teid_in);
|
|
||||||
new_tun.prior_teid_in_present = false;
|
|
||||||
set_tunnel_status(new_tun.teid_in, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
logger.warning("Unhandled GTPU message type=%d", header.message_type);
|
logger.warning("Unhandled GTPU message type=%d", header.message_type);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue