From bdc5094e17e0f22b9b1c2b1231e50d46dacdb565 Mon Sep 17 00:00:00 2001 From: Francisco Date: Wed, 24 Mar 2021 13:46:25 +0000 Subject: [PATCH] gtpu - added unit test for gtpu_tunnel_manager class --- srsenb/hdr/stack/upper/gtpu.h | 5 ++--- srsenb/src/stack/upper/gtpu.cc | 13 ++++++----- srsenb/test/upper/gtpu_test.cc | 41 ++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 8 deletions(-) diff --git a/srsenb/hdr/stack/upper/gtpu.h b/srsenb/hdr/stack/upper/gtpu.h index 956294e16..a16e4ca51 100644 --- a/srsenb/hdr/stack/upper/gtpu.h +++ b/srsenb/hdr/stack/upper/gtpu.h @@ -12,7 +12,6 @@ #include #include -#include #include "common_enb.h" #include "srsran/adt/bounded_vector.h" @@ -175,9 +174,9 @@ private: 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); - bool end_marker(uint32_t teidin); + bool send_end_marker(uint32_t teidin); - void handle_end_marker(gtpu_tunnel& rx_tunnel); + void handle_end_marker(const gtpu_tunnel& rx_tunnel); void handle_msg_data_pdu(const srsran::gtpu_header_t& header, gtpu_tunnel& rx_tunnel, srsran::unique_byte_buffer_t pdu); diff --git a/srsenb/src/stack/upper/gtpu.cc b/srsenb/src/stack/upper/gtpu.cc index f89645c5e..ed99d0919 100644 --- a/srsenb/src/stack/upper/gtpu.cc +++ b/srsenb/src/stack/upper/gtpu.cc @@ -135,6 +135,11 @@ bool gtpu_tunnel_manager::remove_tunnel(uint32_t teidin) } gtpu_tunnel& tun = it->second; + // Erase any present forwarding tunnel + if (tun.fwd_teid_in_present) { + remove_tunnel(tun.fwd_teid_in); + } + // erase keeping the relative order auto& ue = ue_teidin_db[tun.rnti]; auto lcid_it = std::find(ue.begin(), ue.end(), lcid_tunnel{tun.lcid, tun.teid_in}); @@ -407,7 +412,7 @@ void gtpu::rem_user(uint16_t rnti) tunnels.remove_rnti(rnti); } -void gtpu::handle_end_marker(gtpu_tunnel& rx_tunnel) +void gtpu::handle_end_marker(const gtpu_tunnel& rx_tunnel) { uint16_t rnti = rx_tunnel.rnti; logger.info("Received GTPU End Marker for rnti=0x%x.", rnti); @@ -415,9 +420,7 @@ void gtpu::handle_end_marker(gtpu_tunnel& rx_tunnel) // 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; - + send_end_marker(rx_tunnel.fwd_teid_in); rem_tunnel(rx_tunnel.teid_in); } else { // TeNB switches paths, and flushes PDUs that have been buffered @@ -622,7 +625,7 @@ void gtpu::echo_response(in_addr_t addr, in_port_t port, uint16_t seq) /**************************************************************************** * GTP-U END MARKER ***************************************************************************/ -bool gtpu::end_marker(uint32_t teidin) +bool gtpu::send_end_marker(uint32_t teidin) { logger.info("TX GTPU End Marker."); const gtpu_tunnel* tx_tun = tunnels.find_tunnel(teidin); diff --git a/srsenb/test/upper/gtpu_test.cc b/srsenb/test/upper/gtpu_test.cc index 74d4ccc7f..3588adfe5 100644 --- a/srsenb/test/upper/gtpu_test.cc +++ b/srsenb/test/upper/gtpu_test.cc @@ -127,6 +127,46 @@ srsran::unique_byte_buffer_t read_socket(int fd) return pdu; } +void test_gtpu_tunnel_manager() +{ + const char* sgw_addr_str = "127.0.0.1"; + struct sockaddr_in sgw_sockaddr = {}; + srsran::net_utils::set_sockaddr(&sgw_sockaddr, sgw_addr_str, GTPU_PORT); + uint32_t sgw_addr = ntohl(sgw_sockaddr.sin_addr.s_addr); + const uint32_t drb1_lcid = 3; + + gtpu_tunnel_manager tunnels; + TESTASSERT(tunnels.find_tunnel(0) == nullptr); + TESTASSERT(tunnels.find_rnti_lcid_tunnels(0x46, drb1_lcid).empty()); + TESTASSERT(tunnels.find_rnti_tunnels(0x46) == nullptr); + TESTASSERT(not tunnels.remove_tunnel(0)); + + // Creation of tunnels for different users and lcids + gtpu_tunnel* tun = tunnels.add_tunnel(0x46, drb1_lcid, 5, sgw_addr); + TESTASSERT(tun != nullptr); + TESTASSERT(tunnels.find_tunnel(tun->teid_in) == tun); + gtpu_tunnel* tun2 = tunnels.add_tunnel(0x47, drb1_lcid, 6, sgw_addr); + TESTASSERT(tun2 != nullptr); + TESTASSERT(tunnels.find_tunnel(tun2->teid_in) == tun2); + tun2 = tunnels.add_tunnel(0x47, drb1_lcid + 1, 6, sgw_addr); + TESTASSERT(tun2 != nullptr); + TESTASSERT(tunnels.find_tunnel(tun2->teid_in) == tun2); + TESTASSERT(tunnels.find_rnti_lcid_tunnels(0x46, drb1_lcid).size() == 1); + TESTASSERT(tunnels.find_rnti_lcid_tunnels(0x47, drb1_lcid).size() == 1); + TESTASSERT(tunnels.find_rnti_lcid_tunnels(0x47, drb1_lcid + 1).size() == 1); + + // TEST: Creation/Removal of indirect tunnel + gtpu_tunnel* fwd_tun = tunnels.add_tunnel(0x46, drb1_lcid, 6, sgw_addr); + TESTASSERT(fwd_tun != nullptr); + TESTASSERT(tunnels.find_tunnel(fwd_tun->teid_in) == fwd_tun); + tun->fwd_teid_in_present = true; + tun->fwd_teid_in = fwd_tun->teid_in; + TESTASSERT(tunnels.find_rnti_lcid_tunnels(0x46, drb1_lcid).size() == 2); + // Removing a tunnel also removes any associated forwarding tunnel + TESTASSERT(tunnels.remove_tunnel(tun->teid_in)); + TESTASSERT(tunnels.find_rnti_lcid_tunnels(0x46, drb1_lcid).empty()); +} + enum class tunnel_test_event { success, wait_end_marker_timeout }; int test_gtpu_direct_tunneling(tunnel_test_event event) @@ -269,6 +309,7 @@ int main(int argc, char** argv) // Start the log backend. srsran::test_init(argc, argv); + srsenb::test_gtpu_tunnel_manager(); TESTASSERT(srsenb::test_gtpu_direct_tunneling(srsenb::tunnel_test_event::success) == SRSRAN_SUCCESS); TESTASSERT(srsenb::test_gtpu_direct_tunneling(srsenb::tunnel_test_event::wait_end_marker_timeout) == SRSRAN_SUCCESS);