From eba0edea4a22264abbc371ab59135411e80f18b0 Mon Sep 17 00:00:00 2001 From: Francisco Date: Wed, 24 Mar 2021 11:21:41 +0000 Subject: [PATCH] creation of static id obj pool class. Application of this class to gtpu tunnels container to avoid allocations --- lib/include/srsran/adt/circular_map.h | 39 +++++++++++++++++++++ srsenb/hdr/stack/upper/gtpu.h | 15 ++++---- srsenb/src/stack/upper/gtpu.cc | 49 ++++++++++++++------------- 3 files changed, 71 insertions(+), 32 deletions(-) diff --git a/lib/include/srsran/adt/circular_map.h b/lib/include/srsran/adt/circular_map.h index 23fc4c252..d3b09ac2a 100644 --- a/lib/include/srsran/adt/circular_map.h +++ b/lib/include/srsran/adt/circular_map.h @@ -214,6 +214,7 @@ public: size_t size() const { return count; } bool empty() const { return count == 0; } bool full() const { return count == N; } + bool has_space(K id) { return not present[id % N]; } size_t capacity() const { return N; } iterator begin() { return iterator(this, 0); } @@ -245,6 +246,44 @@ private: size_t count = 0; }; +template +class static_id_obj_pool : private static_circular_map +{ + using base_t = static_circular_map; + +public: + using iterator = typename base_t::iterator; + using const_iterator = typename base_t::const_iterator; + + using base_t::operator[]; + using base_t::begin; + using base_t::contains; + using base_t::empty; + using base_t::end; + using base_t::erase; + using base_t::find; + using base_t::full; + using base_t::size; + + explicit static_id_obj_pool(K first_id = 0) : next_id(first_id) {} + + template + srsran::expected insert(U&& t) + { + if (full()) { + return srsran::default_error_t{}; + } + while (not base_t::has_space(next_id)) { + ++next_id; + } + base_t::insert(next_id, std::forward(t)); + return next_id++; + } + +private: + K next_id = 0; +}; + } // namespace srsran #endif // SRSRAN_ID_MAP_H diff --git a/srsenb/hdr/stack/upper/gtpu.h b/srsenb/hdr/stack/upper/gtpu.h index 4b7e1f23f..6e710c383 100644 --- a/srsenb/hdr/stack/upper/gtpu.h +++ b/srsenb/hdr/stack/upper/gtpu.h @@ -55,8 +55,9 @@ struct gtpu_tunnel { class gtpu_tunnel_manager { public: - using lcid_teid_list = std::vector; - using ue_lcid_tunnel_list = srsran::static_circular_map; + const static size_t MAX_TUNNELS_PER_UE = 4; + using lcid_teid_list = std::vector; + using ue_lcid_tunnel_list = srsran::static_circular_map; gtpu_tunnel_manager(); @@ -64,7 +65,7 @@ public: ue_lcid_tunnel_list* find_rnti_tunnels(uint16_t rnti); srsran::span find_rnti_lcid_tunnels(uint16_t rnti, uint32_t lcid); - gtpu_tunnel* add_tunnel(uint32_t teid, uint16_t rnti, uint32_t lcid); + gtpu_tunnel* add_tunnel(uint16_t rnti, uint32_t lcid, uint32_t teidout, uint32_t spgw_addr); bool update_rnti(uint16_t old_rnti, uint16_t new_rnti); bool remove_tunnel(uint32_t teid); @@ -74,8 +75,8 @@ public: private: srslog::basic_logger& logger; - std::unordered_map tunnels; - srsran::static_circular_map ue_teidin_db; + srsran::static_id_obj_pool tunnels; + srsran::static_circular_map ue_teidin_db; }; class gtpu final : public gtpu_interface_rrc, public gtpu_interface_pdcp @@ -160,7 +161,7 @@ private: // Socket file descriptor int fd = -1; - void send_pdu_to_tunnel(gtpu_tunnel& tx_tun, srsran::unique_byte_buffer_t pdu, int pdcp_sn = -1); + void send_pdu_to_tunnel(const gtpu_tunnel& tx_tun, srsran::unique_byte_buffer_t pdu, int pdcp_sn = -1); void echo_response(in_addr_t addr, in_port_t port, uint16_t seq); void error_indication(in_addr_t addr, in_port_t port, uint32_t err_teid); @@ -175,8 +176,6 @@ private: /**************************************************************************** * TEID to RNIT/LCID helper functions ***************************************************************************/ - uint32_t next_teid_in = 0; - void log_message(const gtpu_tunnel& tun, bool is_rx, srsran::span pdu, int pdcp_sn = -1); }; diff --git a/srsenb/src/stack/upper/gtpu.cc b/srsenb/src/stack/upper/gtpu.cc index 7cbffc4f6..0a0033d6a 100644 --- a/srsenb/src/stack/upper/gtpu.cc +++ b/srsenb/src/stack/upper/gtpu.cc @@ -58,13 +58,19 @@ srsran::span gtpu_tunnel_manager::find_rnti_lcid_tunnels(uint16_t rnti return (*ue_ptr)[lcid]; } -gtpu_tunnel* gtpu_tunnel_manager::add_tunnel(uint32_t teidin, uint16_t rnti, uint32_t lcid) +gtpu_tunnel* gtpu_tunnel_manager::add_tunnel(uint16_t rnti, uint32_t lcid, uint32_t teidout, uint32_t spgw_addr) { - auto ret_pair = tunnels.emplace(teidin, gtpu_tunnel()); - if (not ret_pair.second) { - logger.warning("Adding GTPU TEID In=0x%x", teidin); + auto ret_pair = tunnels.insert(gtpu_tunnel()); + if (not ret_pair) { + logger.warning("Adding new GTPU TEID In"); return nullptr; } + gtpu_tunnel* tun = &tunnels[ret_pair.value()]; + tun->teid_in = ret_pair.value(); + tun->rnti = rnti; + tun->lcid = lcid; + tun->teid_out = teidout; + tun->spgw_addr = spgw_addr; if (not ue_teidin_db.contains(rnti)) { ue_teidin_db.insert(rnti, ue_lcid_tunnel_list()); @@ -72,9 +78,18 @@ gtpu_tunnel* gtpu_tunnel_manager::add_tunnel(uint32_t teidin, uint16_t rnti, uin if (not ue_teidin_db[rnti].contains(lcid)) { ue_teidin_db[rnti].insert(lcid, std::vector()); } - ue_teidin_db[rnti][lcid].push_back(teidin); + ue_teidin_db[rnti][lcid].push_back(tun->teid_in); - return &ret_pair.first->second; + fmt::memory_buffer str_buffer; + srsran::gtpu_ntoa(str_buffer, htonl(spgw_addr)); + logger.info("New tunnel teid_in=0x%x, teid_out=0x%x, rnti=0x%x, lcid=%d, addr=%s", + tun->teid_in, + teidout, + rnti, + lcid, + srsran::to_c_str(str_buffer)); + + return tun; } bool gtpu_tunnel_manager::update_rnti(uint16_t old_rnti, uint16_t new_rnti) @@ -244,7 +259,7 @@ void gtpu::write_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t send_pdu_to_tunnel(tx_tun, std::move(pdu)); } -void gtpu::send_pdu_to_tunnel(gtpu_tunnel& tx_tun, srsran::unique_byte_buffer_t pdu, int pdcp_sn) +void gtpu::send_pdu_to_tunnel(const gtpu_tunnel& tx_tun, srsran::unique_byte_buffer_t pdu, int pdcp_sn) { // Check valid IP version struct iphdr* ip_pkt = (struct iphdr*)pdu->msg; @@ -286,25 +301,11 @@ void gtpu::send_pdu_to_tunnel(gtpu_tunnel& tx_tun, srsran::unique_byte_buffer_t uint32_t gtpu::add_bearer(uint16_t rnti, uint32_t lcid, uint32_t addr, uint32_t teid_out, const bearer_props* props) { // Allocate a TEID for the incoming tunnel - uint32_t teid_in = ++next_teid_in; - gtpu_tunnel* new_tun = tunnels.add_tunnel(teid_in, rnti, lcid); + gtpu_tunnel* new_tun = tunnels.add_tunnel(rnti, lcid, teid_out, addr); if (new_tun == nullptr) { return -1; } - new_tun->teid_in = teid_in; - new_tun->rnti = rnti; - new_tun->lcid = lcid; - new_tun->spgw_addr = addr; - new_tun->teid_out = teid_out; - - fmt::memory_buffer str_buffer; - srsran::gtpu_ntoa(str_buffer, htonl(addr)); - logger.info("New tunnel teid_in=0x%x, teid_out=0x%x, rnti=0x%x, lcid=%d, addr=%s", - teid_in, - teid_out, - rnti, - lcid, - srsran::to_c_str(str_buffer)); + uint32_t teid_in = new_tun->teid_in; if (props != nullptr) { if (props->flush_before_teidin_present) { @@ -489,7 +490,7 @@ void gtpu::handle_msg_data_pdu(const gtpu_header_t& header, gtpu_tunnel& rx_tunn if (rx_tunnel.fwd_teid_in_present) { // Forward SDU to direct/indirect tunnel during Handover - gtpu_tunnel* tx_tun_ptr = tunnels.find_tunnel(rx_tunnel.fwd_teid_in); + const gtpu_tunnel* tx_tun_ptr = tunnels.find_tunnel(rx_tunnel.fwd_teid_in); if (tx_tun_ptr == nullptr) { logger.error("Forwarding tunnel TEID=%d does not exist", rx_tunnel.fwd_teid_in); return;