Skip to content

Commit c0b2d1f

Browse files
alvasMancodebot
authored andcommitted
cu: pass teid allocator to pdu_session so that pdu_session can de-allocated it's TEID on destruction
1 parent e1e880d commit c0b2d1f

File tree

10 files changed

+56
-37
lines changed

10 files changed

+56
-37
lines changed

include/srsran/gtpu/gtpu_teid_pool.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ class gtpu_teid_pool
2828

2929
SRSRAN_NODISCARD virtual expected<gtpu_teid_t> request_teid() = 0;
3030

31-
SRSRAN_NODISCARD virtual bool release_teid(gtpu_teid_t teid) = 0;
31+
virtual bool release_teid(gtpu_teid_t teid) = 0;
3232

33-
virtual bool full() const = 0;
33+
[[nodiscard]] virtual bool full() const = 0;
3434

3535
virtual uint32_t get_max_nof_teids() = 0;
3636
};

lib/cu_up/cu_up_impl.h

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,12 @@
1717
#include "srsran/cu_up/cu_up.h"
1818
#include "srsran/cu_up/cu_up_configuration.h"
1919
#include "srsran/e1ap/cu_up/e1ap_cu_up.h"
20-
#include "srsran/gateways/udp_network_gateway.h"
2120
#include "srsran/gtpu/gtpu_echo.h"
2221
#include "srsran/gtpu/gtpu_teid_pool.h"
2322
#include "srsran/support/async/fifo_async_task_scheduler.h"
24-
#include "srsran/support/executors/task_executor.h"
2523
#include <memory>
26-
#include <unordered_map>
2724

28-
namespace srsran {
29-
namespace srs_cu_up {
25+
namespace srsran::srs_cu_up {
3026

3127
class cu_up final : public cu_up_interface
3228
{
@@ -96,5 +92,4 @@ class cu_up final : public cu_up_interface
9692
unique_timer statistics_report_timer;
9793
};
9894

99-
} // namespace srs_cu_up
100-
} // namespace srsran
95+
} // namespace srsran::srs_cu_up

lib/cu_up/pdu_session.h

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "adapters/sdap_adapters.h"
1515
#include "drb_context.h"
1616
#include "srsran/gtpu/gtpu_demux.h"
17+
#include "srsran/gtpu/gtpu_teid_pool.h"
1718
#include "srsran/gtpu/gtpu_tunnel_ngu.h"
1819
#include "srsran/ran/up_transport_layer_info.h"
1920

@@ -24,13 +25,16 @@ namespace srs_cu_up {
2425

2526
/// \brief Context for PDU session with session-wide parameters and all contained DRBs.
2627
struct pdu_session {
27-
pdu_session(const e1ap_pdu_session_res_to_setup_item& session, gtpu_demux_ctrl& gtpu_rx_demux_) :
28+
pdu_session(const e1ap_pdu_session_res_to_setup_item& session,
29+
gtpu_demux_ctrl& gtpu_rx_demux_,
30+
gtpu_teid_pool& n3_teid_allocator_) :
2831
pdu_session_id(session.pdu_session_id),
2932
session_type(session.pdu_session_type),
3033
snssai(session.snssai),
3134
security_ind(session.security_ind),
3235
ul_tunnel_info(session.ng_ul_up_tnl_info),
33-
gtpu_rx_demux(gtpu_rx_demux_)
36+
gtpu_rx_demux(gtpu_rx_demux_),
37+
n3_teid_allocator(n3_teid_allocator_)
3438
{
3539
if (session.pdu_session_res_dl_ambr.has_value()) {
3640
pdu_session_res_ambr = session.pdu_session_res_dl_ambr.value();
@@ -41,7 +45,10 @@ struct pdu_session {
4145
void stop()
4246
{
4347
if (not stopped) {
44-
gtpu_rx_demux.remove_tunnel(local_teid);
48+
if (local_teid.has_value()) {
49+
gtpu_rx_demux.remove_tunnel(local_teid.value());
50+
n3_teid_allocator.release_teid(local_teid.value());
51+
}
4552

4653
gtpu->stop();
4754

@@ -70,9 +77,10 @@ struct pdu_session {
7077
uint64_t pdu_session_res_ambr = 0;
7178

7279
// Tunneling info used by all DRBs/QoS flows in this PDU session
73-
up_transport_layer_info ul_tunnel_info; // the peer GTP-U address and TEID
74-
gtpu_teid_t local_teid; // the local teid used by the gNB for this PDU session
75-
gtpu_demux_ctrl& gtpu_rx_demux; // The demux entity to register/remove the tunnel.
80+
up_transport_layer_info ul_tunnel_info; // the peer GTP-U address and TEID
81+
std::optional<gtpu_teid_t> local_teid; // the local teid used by the gNB for this PDU session
82+
gtpu_demux_ctrl& gtpu_rx_demux; // The demux entity to register/remove the tunnel.
83+
gtpu_teid_pool& n3_teid_allocator; // Pool to de-allocate TEID on release
7684

7785
drb_context* default_drb = nullptr; // non-owning pointer to default DRB, if any
7886

lib/cu_up/pdu_session_manager_impl.cpp

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ pdu_session_manager_impl::pdu_session_manager_impl(ue_index_t
5353
ue_ul_timer_factory(ue_ul_timer_factory_),
5454
ue_ctrl_timer_factory(ue_ctrl_timer_factory_),
5555
gtpu_tx_notifier(gtpu_tx_notifier_),
56+
n3_teid_allocator(n3_teid_allocator_),
5657
f1u_teid_allocator(f1u_teid_allocator_),
5758
gtpu_rx_demux(gtpu_rx_demux_),
5859
ue_dl_exec(ue_dl_exec_),
@@ -82,26 +83,31 @@ pdu_session_setup_result pdu_session_manager_impl::setup_pdu_session(const e1ap_
8283
return pdu_session_result;
8384
}
8485

85-
pdu_sessions.emplace(session.pdu_session_id, std::make_unique<pdu_session>(session, gtpu_rx_demux));
86-
std::unique_ptr<pdu_session>& new_session = pdu_sessions.at(session.pdu_session_id);
87-
const auto& ul_tunnel_info = new_session->ul_tunnel_info;
86+
// Allocate local TEID
87+
expected<gtpu_teid_t> ret = n3_teid_allocator.request_teid();
88+
if (ret.is_error()) {
89+
logger.log_warning("Failed to create PDU session. Cause: could not allocate local TEID. {}",
90+
session.pdu_session_id);
91+
return pdu_session_result;
92+
}
93+
94+
std::unique_ptr<pdu_session> new_session = std::make_unique<pdu_session>(session, gtpu_rx_demux, n3_teid_allocator);
95+
const auto& ul_tunnel_info = new_session->ul_tunnel_info;
96+
new_session->local_teid = ret.value();
8897

8998
// Get uplink transport address
90-
logger.log_debug("PDU session uplink tunnel info: {} teid={} addr={}",
99+
logger.log_debug("PDU session uplink tunnel info: {} local_teid={} peer_teid={} peer_addr={}",
91100
session.pdu_session_id,
101+
new_session->local_teid,
92102
ul_tunnel_info.gtp_teid.value(),
93103
ul_tunnel_info.tp_address);
94104

95-
// Allocate local TEID
96-
// TODO
97-
// new_session->local_teid = allocate_local_teid(new_session->pdu_session_id);
98-
99105
// Advertise either local or external IP address of N3 interface
100106
const std::string& n3_addr = net_config.n3_ext_addr.empty() || net_config.n3_ext_addr == "auto"
101107
? net_config.n3_bind_addr
102108
: net_config.n3_ext_addr;
103109
pdu_session_result.gtp_tunnel =
104-
up_transport_layer_info(transport_layer_address::create_from_string(n3_addr), new_session->local_teid);
110+
up_transport_layer_info(transport_layer_address::create_from_string(n3_addr), *new_session->local_teid);
105111

106112
// Create SDAP entity
107113
sdap_entity_creation_message sdap_msg = {ue_index, session.pdu_session_id, &new_session->sdap_to_gtpu_adapter};
@@ -113,7 +119,7 @@ pdu_session_setup_result pdu_session_manager_impl::setup_pdu_session(const e1ap_
113119
msg.cfg.tx.peer_teid = int_to_gtpu_teid(ul_tunnel_info.gtp_teid.value());
114120
msg.cfg.tx.peer_addr = ul_tunnel_info.tp_address.to_string();
115121
msg.cfg.tx.peer_port = net_config.upf_port;
116-
msg.cfg.rx.local_teid = new_session->local_teid;
122+
msg.cfg.rx.local_teid = *new_session->local_teid;
117123
msg.cfg.rx.t_reordering = n3_config.gtpu_reordering_timer;
118124
msg.cfg.rx.warn_expired_t_reordering = n3_config.warn_on_drop;
119125
msg.rx_lower = &new_session->gtpu_to_sdap_adapter;
@@ -128,7 +134,7 @@ pdu_session_setup_result pdu_session_manager_impl::setup_pdu_session(const e1ap_
128134

129135
// Register tunnel at demux
130136
if (!gtpu_rx_demux.add_tunnel(
131-
new_session->local_teid, ue_dl_exec, new_session->gtpu->get_rx_upper_layer_interface())) {
137+
*new_session->local_teid, ue_dl_exec, new_session->gtpu->get_rx_upper_layer_interface())) {
132138
logger.log_error(
133139
"PDU Session {} cannot be created. TEID {} already exists", session.pdu_session_id, new_session->local_teid);
134140
return pdu_session_result;
@@ -160,6 +166,9 @@ pdu_session_setup_result pdu_session_manager_impl::setup_pdu_session(const e1ap_
160166
? confidentiality_protection_result_t::not_performed
161167
: confidentiality_protection_result_t::performed;
162168
}
169+
170+
// PDU session creation was successful, store PDU session.
171+
pdu_sessions.emplace(session.pdu_session_id, std::move(new_session));
163172
pdu_session_result.success = true;
164173
return pdu_session_result;
165174
}

lib/cu_up/pdu_session_manager_impl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ class pdu_session_manager_impl final : public pdu_session_manager_ctrl
8383
timer_factory ue_ul_timer_factory;
8484
timer_factory ue_ctrl_timer_factory;
8585
gtpu_tunnel_common_tx_upper_layer_notifier& gtpu_tx_notifier;
86+
gtpu_teid_pool& n3_teid_allocator;
8687
gtpu_teid_pool& f1u_teid_allocator;
8788
gtpu_demux_ctrl& gtpu_rx_demux;
8889
task_executor& ue_dl_exec;

lib/gtpu/gtpu_teid_pool_impl.h

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010

1111
#pragma once
1212

13-
#include "srsran/adt/expected.h"
14-
#include "srsran/gtpu/gtpu_teid.h"
1513
#include "srsran/gtpu/gtpu_teid_pool.h"
14+
#include "srsran/srslog/logger.h"
15+
#include "srsran/srslog/srslog.h"
1616
#include "srsran/support/compiler.h"
1717
#include <vector>
1818

@@ -21,7 +21,10 @@ namespace srsran {
2121
class gtpu_teid_pool_impl final : public gtpu_teid_pool
2222
{
2323
public:
24-
explicit gtpu_teid_pool_impl(uint32_t max_nof_teids_) : max_nof_teids(max_nof_teids_), teid_pool(max_nof_teids_) {}
24+
explicit gtpu_teid_pool_impl(uint32_t max_nof_teids_) :
25+
max_nof_teids(max_nof_teids_), teid_pool(max_nof_teids_), logger(srslog::fetch_basic_logger("GTPU"))
26+
{
27+
}
2528

2629
SRSRAN_NODISCARD expected<gtpu_teid_t> request_teid() override
2730
{
@@ -53,19 +56,19 @@ class gtpu_teid_pool_impl final : public gtpu_teid_pool
5356
return teid;
5457
}
5558

56-
SRSRAN_NODISCARD bool release_teid(gtpu_teid_t teid) override
59+
bool release_teid(gtpu_teid_t teid) override
5760
{
5861
uint32_t teid_idx = teid.value() - GTPU_TEID_MIN.value();
5962
if (not teid_pool[teid_idx]) {
60-
// trying to free non-allocated TEID
63+
logger.error("Trying to free non-allocated TEID. teid={}", teid);
6164
return false;
6265
}
6366
teid_pool[teid_idx] = false;
6467
nof_teids--;
6568
return true;
6669
}
6770

68-
bool full() const override { return nof_teids >= max_nof_teids; }
71+
[[nodiscard]] bool full() const override { return nof_teids >= max_nof_teids; }
6972

7073
uint32_t get_max_nof_teids() override { return max_nof_teids; }
7174

@@ -75,5 +78,7 @@ class gtpu_teid_pool_impl final : public gtpu_teid_pool
7578
const uint32_t max_nof_teids;
7679

7780
std::vector<bool> teid_pool;
81+
82+
srslog::basic_logger& logger;
7883
};
7984
} // namespace srsran

tests/unittests/cu_up/cu_up_test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ TEST_F(cu_up_test, dl_data_flow)
213213

214214
// teid=2, qfi=1
215215
const uint8_t gtpu_ping_vec[] = {
216-
0x34, 0xff, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x85, 0x01, 0x00, 0x01, 0x00, 0x45,
216+
0x34, 0xff, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x85, 0x01, 0x00, 0x01, 0x00, 0x45,
217217
0x00, 0x00, 0x54, 0x9b, 0xfb, 0x00, 0x00, 0x40, 0x01, 0x56, 0x5a, 0xc0, 0xa8, 0x04, 0x01, 0xc0, 0xa8,
218218
0x03, 0x02, 0x00, 0x00, 0xb8, 0xc0, 0x00, 0x02, 0x00, 0x01, 0x5d, 0x26, 0x77, 0x64, 0x00, 0x00, 0x00,
219219
0x00, 0xb1, 0xde, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,

tests/unittests/cu_up/cu_up_test_helpers.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ class dummy_gtpu_teid_pool final : public gtpu_teid_pool
106106

107107
uint32_t get_max_nof_teids() override { return UINT32_MAX; }
108108

109-
uint32_t next_teid = 0;
109+
uint32_t next_teid = 1;
110110
};
111111

112112
/// Dummy adapter between GTP-U and Network Gateway

tests/unittests/cu_up/pdu_session_manager_test.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ TEST_P(pdu_session_manager_test_set_n3_ext_addr, when_valid_pdu_session_setup_it
3939
? net_config.n3_bind_addr
4040
: net_config.n3_ext_addr;
4141
ASSERT_EQ(setup_result.gtp_tunnel.tp_address.to_string(), tp_address_expect);
42-
ASSERT_EQ(setup_result.drb_setup_results[0].gtp_tunnel.gtp_teid.value(), 0);
42+
ASSERT_EQ(setup_result.drb_setup_results[0].gtp_tunnel.gtp_teid.value(), 1);
4343
ASSERT_EQ(pdu_session_mng->get_nof_pdu_sessions(), 1);
4444

4545
// attempt to remove non-existing session
@@ -378,15 +378,15 @@ TEST_F(pdu_session_manager_test, when_new_ul_info_is_requested_f1u_is_disconnect
378378
pdu_session_setup_result set_result = pdu_session_mng->setup_pdu_session(pdu_session_setup_item);
379379
ASSERT_EQ(pdu_session_mng->get_nof_pdu_sessions(), 1);
380380
drb_setup_result drb_setup_res = set_result.drb_setup_results[0];
381-
ASSERT_EQ(drb_setup_res.gtp_tunnel.gtp_teid, 0x0);
381+
ASSERT_EQ(drb_setup_res.gtp_tunnel.gtp_teid, 0x1);
382382

383383
// prepare modification request (request new UL TNL info)
384384
e1ap_pdu_session_res_to_modify_item pdu_session_modify_item =
385385
generate_pdu_session_res_to_modify_item_to_modify_drb(psi, drb_id);
386386

387387
pdu_session_modification_result mod_result = pdu_session_mng->modify_pdu_session(pdu_session_modify_item, true);
388388
drb_setup_result drb_mod_res = mod_result.drb_modification_results[0];
389-
ASSERT_EQ(drb_mod_res.gtp_tunnel.gtp_teid, 0x1);
389+
ASSERT_EQ(drb_mod_res.gtp_tunnel.gtp_teid, 0x2);
390390

391391
ASSERT_EQ(pdu_session_mng->get_nof_pdu_sessions(), 1);
392392
}

tests/unittests/cu_up/pdu_session_manager_test.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class pdu_session_manager_test_base
3737
gtpu_rx_demux = std::make_unique<dummy_gtpu_demux_ctrl>();
3838
gtpu_tx_notifier = std::make_unique<dummy_gtpu_network_gateway_adapter>();
3939
f1u_gw = std::make_unique<dummy_f1u_gateway>(f1u_bearer);
40+
n3_allocator = std::make_unique<dummy_gtpu_teid_pool>();
4041
f1u_allocator = std::make_unique<dummy_gtpu_teid_pool>();
4142

4243
// create DUT object

0 commit comments

Comments
 (0)