Skip to content

Commit e1e880d

Browse files
alvasMancodebot
authored andcommitted
cu: pass gtpu teid pool to pdu session manager to avoid teid re-use
1 parent 041e762 commit e1e880d

File tree

9 files changed

+122
-110
lines changed

9 files changed

+122
-110
lines changed

lib/cu_up/cu_up_impl.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,12 @@ cu_up::cu_up(const cu_up_configuration& config_) : cfg(config_), main_ctrl_loop(
6767
// Connect GTPU GW adapter to NG-U session in order to send UL PDUs.
6868
gtpu_gw_adapter.connect_network_gateway(*ngu_session);
6969

70-
// Create TEID allocator
70+
// Create N3 TEID allocator
71+
gtpu_allocator_creation_request n3_alloc_msg = {};
72+
n3_alloc_msg.max_nof_teids = MAX_NOF_UES * MAX_NOF_PDU_SESSIONS;
73+
n3_teid_allocator = create_gtpu_allocator(n3_alloc_msg);
74+
75+
// Create F1-U TEID allocator
7176
gtpu_allocator_creation_request f1u_alloc_msg = {};
7277
f1u_alloc_msg.max_nof_teids = MAX_NOF_UES * MAX_NOF_PDU_SESSIONS;
7378
f1u_teid_allocator = create_gtpu_allocator(f1u_alloc_msg);
@@ -86,6 +91,7 @@ cu_up::cu_up(const cu_up_configuration& config_) : cfg(config_), main_ctrl_loop(
8691
*cfg.f1u_gateway,
8792
gtpu_gw_adapter,
8893
*ngu_demux,
94+
*n3_teid_allocator,
8995
*f1u_teid_allocator,
9096
*cfg.ue_exec_pool,
9197
*cfg.gtpu_pcap,

lib/cu_up/cu_up_impl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ class cu_up final : public cu_up_interface
7878
std::unique_ptr<ngu_tnl_pdu_session> ngu_session;
7979
std::unique_ptr<gtpu_demux> ngu_demux;
8080
std::unique_ptr<gtpu_echo> ngu_echo;
81+
std::unique_ptr<gtpu_teid_pool> n3_teid_allocator;
8182
std::unique_ptr<gtpu_teid_pool> f1u_teid_allocator;
8283
std::unique_ptr<ue_manager> ue_mng;
8384

lib/cu_up/pdu_session_manager_impl.cpp

Lines changed: 101 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ pdu_session_manager_impl::pdu_session_manager_impl(ue_index_t
3333
timer_factory ue_ul_timer_factory_,
3434
timer_factory ue_ctrl_timer_factory_,
3535
f1u_cu_up_gateway& f1u_gw_,
36+
gtpu_teid_pool& n3_teid_allocator_,
3637
gtpu_teid_pool& f1u_teid_allocator_,
3738
gtpu_tunnel_common_tx_upper_layer_notifier& gtpu_tx_notifier_,
3839
gtpu_demux_ctrl& gtpu_rx_demux_,
@@ -61,7 +62,106 @@ pdu_session_manager_impl::pdu_session_manager_impl(ue_index_t
6162
gtpu_pcap(gtpu_pcap_),
6263
f1u_gw(f1u_gw_)
6364
{
64-
(void)ue_ctrl_exec;
65+
}
66+
67+
pdu_session_setup_result pdu_session_manager_impl::setup_pdu_session(const e1ap_pdu_session_res_to_setup_item& session)
68+
{
69+
pdu_session_setup_result pdu_session_result = {};
70+
pdu_session_result.success = false;
71+
pdu_session_result.pdu_session_id = session.pdu_session_id;
72+
pdu_session_result.cause = e1ap_cause_radio_network_t::unspecified;
73+
74+
if (pdu_sessions.find(session.pdu_session_id) != pdu_sessions.end()) {
75+
logger.log_error("PDU Session with {} already exists", session.pdu_session_id);
76+
return pdu_session_result;
77+
}
78+
79+
if (pdu_sessions.size() >= MAX_NUM_PDU_SESSIONS_PER_UE) {
80+
logger.log_error("PDU Session for {} cannot be created. Max number of PDU sessions reached",
81+
session.pdu_session_id);
82+
return pdu_session_result;
83+
}
84+
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;
88+
89+
// Get uplink transport address
90+
logger.log_debug("PDU session uplink tunnel info: {} teid={} addr={}",
91+
session.pdu_session_id,
92+
ul_tunnel_info.gtp_teid.value(),
93+
ul_tunnel_info.tp_address);
94+
95+
// Allocate local TEID
96+
// TODO
97+
// new_session->local_teid = allocate_local_teid(new_session->pdu_session_id);
98+
99+
// Advertise either local or external IP address of N3 interface
100+
const std::string& n3_addr = net_config.n3_ext_addr.empty() || net_config.n3_ext_addr == "auto"
101+
? net_config.n3_bind_addr
102+
: net_config.n3_ext_addr;
103+
pdu_session_result.gtp_tunnel =
104+
up_transport_layer_info(transport_layer_address::create_from_string(n3_addr), new_session->local_teid);
105+
106+
// Create SDAP entity
107+
sdap_entity_creation_message sdap_msg = {ue_index, session.pdu_session_id, &new_session->sdap_to_gtpu_adapter};
108+
new_session->sdap = create_sdap(sdap_msg);
109+
110+
// Create GTPU entity
111+
gtpu_tunnel_ngu_creation_message msg = {};
112+
msg.ue_index = ue_index;
113+
msg.cfg.tx.peer_teid = int_to_gtpu_teid(ul_tunnel_info.gtp_teid.value());
114+
msg.cfg.tx.peer_addr = ul_tunnel_info.tp_address.to_string();
115+
msg.cfg.tx.peer_port = net_config.upf_port;
116+
msg.cfg.rx.local_teid = new_session->local_teid;
117+
msg.cfg.rx.t_reordering = n3_config.gtpu_reordering_timer;
118+
msg.cfg.rx.warn_expired_t_reordering = n3_config.warn_on_drop;
119+
msg.rx_lower = &new_session->gtpu_to_sdap_adapter;
120+
msg.tx_upper = &gtpu_tx_notifier;
121+
msg.gtpu_pcap = &gtpu_pcap;
122+
msg.ue_dl_timer_factory = ue_dl_timer_factory;
123+
new_session->gtpu = create_gtpu_tunnel_ngu(msg);
124+
125+
// Connect adapters
126+
new_session->sdap_to_gtpu_adapter.connect_gtpu(*new_session->gtpu->get_tx_lower_layer_interface());
127+
new_session->gtpu_to_sdap_adapter.connect_sdap(new_session->sdap->get_sdap_tx_sdu_handler());
128+
129+
// Register tunnel at demux
130+
if (!gtpu_rx_demux.add_tunnel(
131+
new_session->local_teid, ue_dl_exec, new_session->gtpu->get_rx_upper_layer_interface())) {
132+
logger.log_error(
133+
"PDU Session {} cannot be created. TEID {} already exists", session.pdu_session_id, new_session->local_teid);
134+
return pdu_session_result;
135+
}
136+
137+
// Handle DRB setup
138+
for (const e1ap_drb_to_setup_item_ng_ran& drb_to_setup : session.drb_to_setup_list_ng_ran) {
139+
drb_setup_result drb_result = handle_drb_to_setup_item(*new_session, drb_to_setup);
140+
pdu_session_result.drb_setup_results.push_back(drb_result);
141+
}
142+
143+
// Ref: TS 38.463 Sec. 8.3.1.2:
144+
// For each PDU session for which the Security Indication IE is included in the PDU Session Resource To Setup List
145+
// IE of the BEARER CONTEXT SETUP REQUEST message, and the Integrity Protection Indication IE or Confidentiality
146+
// Protection Indication IE is set to "preferred", then the gNB-CU-UP should, if supported, perform user plane
147+
// integrity protection or ciphering, respectively, for the concerned PDU session and shall notify whether it
148+
// performed the user plane integrity protection or ciphering by including the Integrity Protection Result IE or
149+
// Confidentiality Protection Result IE, respectively, in the PDU Session Resource Setup List IE of the BEARER
150+
// CONTEXT SETUP RESPONSE message.
151+
if (security_result_required(session.security_ind)) {
152+
pdu_session_result.security_result = security_result_t{};
153+
auto& sec_res = pdu_session_result.security_result.value();
154+
sec_res.integrity_protection_result =
155+
session.security_ind.integrity_protection_ind == integrity_protection_indication_t::not_needed
156+
? integrity_protection_result_t::not_performed
157+
: integrity_protection_result_t::performed;
158+
sec_res.confidentiality_protection_result =
159+
session.security_ind.confidentiality_protection_ind == confidentiality_protection_indication_t::not_needed
160+
? confidentiality_protection_result_t::not_performed
161+
: confidentiality_protection_result_t::performed;
162+
}
163+
pdu_session_result.success = true;
164+
return pdu_session_result;
65165
}
66166

67167
drb_setup_result pdu_session_manager_impl::handle_drb_to_setup_item(pdu_session& new_session,
@@ -242,105 +342,6 @@ drb_setup_result pdu_session_manager_impl::handle_drb_to_setup_item(pdu_session&
242342
return drb_result;
243343
}
244344

245-
pdu_session_setup_result pdu_session_manager_impl::setup_pdu_session(const e1ap_pdu_session_res_to_setup_item& session)
246-
{
247-
pdu_session_setup_result pdu_session_result = {};
248-
pdu_session_result.success = false;
249-
pdu_session_result.pdu_session_id = session.pdu_session_id;
250-
pdu_session_result.cause = e1ap_cause_radio_network_t::unspecified;
251-
252-
if (pdu_sessions.find(session.pdu_session_id) != pdu_sessions.end()) {
253-
logger.log_error("PDU Session with {} already exists", session.pdu_session_id);
254-
return pdu_session_result;
255-
}
256-
257-
if (pdu_sessions.size() >= MAX_NUM_PDU_SESSIONS_PER_UE) {
258-
logger.log_error("PDU Session for {} cannot be created. Max number of PDU sessions reached",
259-
session.pdu_session_id);
260-
return pdu_session_result;
261-
}
262-
263-
pdu_sessions.emplace(session.pdu_session_id, std::make_unique<pdu_session>(session, gtpu_rx_demux));
264-
std::unique_ptr<pdu_session>& new_session = pdu_sessions.at(session.pdu_session_id);
265-
const auto& ul_tunnel_info = new_session->ul_tunnel_info;
266-
267-
// Get uplink transport address
268-
logger.log_debug("PDU session uplink tunnel info: {} teid={} addr={}",
269-
session.pdu_session_id,
270-
ul_tunnel_info.gtp_teid.value(),
271-
ul_tunnel_info.tp_address);
272-
273-
// Allocate local TEID
274-
new_session->local_teid = allocate_local_teid(new_session->pdu_session_id);
275-
276-
// Advertise either local or external IP address of N3 interface
277-
const std::string& n3_addr = net_config.n3_ext_addr.empty() || net_config.n3_ext_addr == "auto"
278-
? net_config.n3_bind_addr
279-
: net_config.n3_ext_addr;
280-
pdu_session_result.gtp_tunnel =
281-
up_transport_layer_info(transport_layer_address::create_from_string(n3_addr), new_session->local_teid);
282-
283-
// Create SDAP entity
284-
sdap_entity_creation_message sdap_msg = {ue_index, session.pdu_session_id, &new_session->sdap_to_gtpu_adapter};
285-
new_session->sdap = create_sdap(sdap_msg);
286-
287-
// Create GTPU entity
288-
gtpu_tunnel_ngu_creation_message msg = {};
289-
msg.ue_index = ue_index;
290-
msg.cfg.tx.peer_teid = int_to_gtpu_teid(ul_tunnel_info.gtp_teid.value());
291-
msg.cfg.tx.peer_addr = ul_tunnel_info.tp_address.to_string();
292-
msg.cfg.tx.peer_port = net_config.upf_port;
293-
msg.cfg.rx.local_teid = new_session->local_teid;
294-
msg.cfg.rx.t_reordering = n3_config.gtpu_reordering_timer;
295-
msg.cfg.rx.warn_expired_t_reordering = n3_config.warn_on_drop;
296-
msg.rx_lower = &new_session->gtpu_to_sdap_adapter;
297-
msg.tx_upper = &gtpu_tx_notifier;
298-
msg.gtpu_pcap = &gtpu_pcap;
299-
msg.ue_dl_timer_factory = ue_dl_timer_factory;
300-
new_session->gtpu = create_gtpu_tunnel_ngu(msg);
301-
302-
// Connect adapters
303-
new_session->sdap_to_gtpu_adapter.connect_gtpu(*new_session->gtpu->get_tx_lower_layer_interface());
304-
new_session->gtpu_to_sdap_adapter.connect_sdap(new_session->sdap->get_sdap_tx_sdu_handler());
305-
306-
// Register tunnel at demux
307-
if (!gtpu_rx_demux.add_tunnel(
308-
new_session->local_teid, ue_dl_exec, new_session->gtpu->get_rx_upper_layer_interface())) {
309-
logger.log_error(
310-
"PDU Session {} cannot be created. TEID {} already exists", session.pdu_session_id, new_session->local_teid);
311-
return pdu_session_result;
312-
}
313-
314-
// Handle DRB setup
315-
for (const e1ap_drb_to_setup_item_ng_ran& drb_to_setup : session.drb_to_setup_list_ng_ran) {
316-
drb_setup_result drb_result = handle_drb_to_setup_item(*new_session, drb_to_setup);
317-
pdu_session_result.drb_setup_results.push_back(drb_result);
318-
}
319-
320-
// Ref: TS 38.463 Sec. 8.3.1.2:
321-
// For each PDU session for which the Security Indication IE is included in the PDU Session Resource To Setup List
322-
// IE of the BEARER CONTEXT SETUP REQUEST message, and the Integrity Protection Indication IE or Confidentiality
323-
// Protection Indication IE is set to "preferred", then the gNB-CU-UP should, if supported, perform user plane
324-
// integrity protection or ciphering, respectively, for the concerned PDU session and shall notify whether it
325-
// performed the user plane integrity protection or ciphering by including the Integrity Protection Result IE or
326-
// Confidentiality Protection Result IE, respectively, in the PDU Session Resource Setup List IE of the BEARER
327-
// CONTEXT SETUP RESPONSE message.
328-
if (security_result_required(session.security_ind)) {
329-
pdu_session_result.security_result = security_result_t{};
330-
auto& sec_res = pdu_session_result.security_result.value();
331-
sec_res.integrity_protection_result =
332-
session.security_ind.integrity_protection_ind == integrity_protection_indication_t::not_needed
333-
? integrity_protection_result_t::not_performed
334-
: integrity_protection_result_t::performed;
335-
sec_res.confidentiality_protection_result =
336-
session.security_ind.confidentiality_protection_ind == confidentiality_protection_indication_t::not_needed
337-
? confidentiality_protection_result_t::not_performed
338-
: confidentiality_protection_result_t::performed;
339-
}
340-
pdu_session_result.success = true;
341-
return pdu_session_result;
342-
}
343-
344345
pdu_session_modification_result
345346
pdu_session_manager_impl::modify_pdu_session(const e1ap_pdu_session_res_to_modify_item& session,
346347
bool new_tnl_info_required)
@@ -560,12 +561,3 @@ size_t pdu_session_manager_impl::get_nof_pdu_sessions()
560561
{
561562
return pdu_sessions.size();
562563
}
563-
564-
gtpu_teid_t pdu_session_manager_impl::allocate_local_teid(pdu_session_id_t pdu_session_id)
565-
{
566-
// Local TEID is the concatenation of the unique UE index and the PDU session ID
567-
uint32_t local_teid = ue_index;
568-
local_teid <<= 8U;
569-
local_teid |= pdu_session_id_to_uint(pdu_session_id);
570-
return gtpu_teid_t{local_teid};
571-
}

lib/cu_up/pdu_session_manager_impl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ class pdu_session_manager_impl final : public pdu_session_manager_ctrl
4141
timer_factory ue_ul_timer_factory_,
4242
timer_factory ue_ctrl_timer_factory_,
4343
f1u_cu_up_gateway& f1u_gw_,
44+
gtpu_teid_pool& n3_teid_allocator_,
4445
gtpu_teid_pool& f1u_teid_allocator_,
4546
gtpu_tunnel_common_tx_upper_layer_notifier& gtpu_tx_notifier_,
4647
gtpu_demux_ctrl& gtpu_rx_demux_,

lib/cu_up/ue_context.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ class ue_context : public pdu_session_manager_ctrl
4545
timer_factory ue_ul_timer_factory_,
4646
timer_factory ue_ctrl_timer_factory_,
4747
f1u_cu_up_gateway& f1u_gw_,
48+
gtpu_teid_pool& n3_teid_allocator_,
4849
gtpu_teid_pool& f1u_teid_allocator_,
4950
gtpu_tunnel_common_tx_upper_layer_notifier& gtpu_tx_notifier_,
5051
gtpu_demux_ctrl& gtpu_rx_demux_,
@@ -64,6 +65,7 @@ class ue_context : public pdu_session_manager_ctrl
6465
ue_ul_timer_factory_,
6566
ue_ctrl_timer_factory_,
6667
f1u_gw_,
68+
n3_teid_allocator_,
6769
f1u_teid_allocator_,
6870
gtpu_tx_notifier_,
6971
gtpu_rx_demux_,

lib/cu_up/ue_manager.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ ue_manager::ue_manager(network_interface_config& net_config_,
2020
f1u_cu_up_gateway& f1u_gw_,
2121
gtpu_tunnel_common_tx_upper_layer_notifier& gtpu_tx_notifier_,
2222
gtpu_demux_ctrl& gtpu_rx_demux_,
23+
gtpu_teid_pool& n3_teid_allocator_,
2324
gtpu_teid_pool& f1u_teid_allocator_,
2425
cu_up_executor_pool& exec_pool_,
2526
dlt_pcap& gtpu_pcap_,
@@ -30,6 +31,7 @@ ue_manager::ue_manager(network_interface_config& net_config_,
3031
f1u_gw(f1u_gw_),
3132
gtpu_tx_notifier(gtpu_tx_notifier_),
3233
gtpu_rx_demux(gtpu_rx_demux_),
34+
n3_teid_allocator(n3_teid_allocator_),
3335
f1u_teid_allocator(f1u_teid_allocator_),
3436
exec_pool(exec_pool_),
3537
gtpu_pcap(gtpu_pcap_),
@@ -79,6 +81,7 @@ ue_context* ue_manager::add_ue(const ue_context_cfg& ue_cfg)
7981
ue_ul_timer_factory,
8082
ue_ctrl_timer_factory,
8183
f1u_gw,
84+
n3_teid_allocator,
8285
f1u_teid_allocator,
8386
gtpu_tx_notifier,
8487
gtpu_rx_demux,

lib/cu_up/ue_manager.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class ue_manager : public ue_manager_ctrl
3131
f1u_cu_up_gateway& f1u_gw_,
3232
gtpu_tunnel_common_tx_upper_layer_notifier& gtpu_tx_notifier_,
3333
gtpu_demux_ctrl& gtpu_rx_demux_,
34+
gtpu_teid_pool& n3_teid_allocator_,
3435
gtpu_teid_pool& f1u_teid_allocator_,
3536
cu_up_executor_pool& exec_pool_,
3637
dlt_pcap& gtpu_pcap_,
@@ -55,6 +56,7 @@ class ue_manager : public ue_manager_ctrl
5556
f1u_cu_up_gateway& f1u_gw;
5657
gtpu_tunnel_common_tx_upper_layer_notifier& gtpu_tx_notifier;
5758
gtpu_demux_ctrl& gtpu_rx_demux;
59+
gtpu_teid_pool& n3_teid_allocator;
5860
gtpu_teid_pool& f1u_teid_allocator;
5961
cu_up_executor_pool& exec_pool;
6062
dlt_pcap& gtpu_pcap;

tests/unittests/cu_up/pdu_session_manager_test.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ class pdu_session_manager_test_base
5959
timers_factory,
6060
timers_factory,
6161
*f1u_gw,
62+
*n3_allocator,
6263
*f1u_allocator,
6364
*gtpu_tx_notifier,
6465
*gtpu_rx_demux,
@@ -83,6 +84,7 @@ class pdu_session_manager_test_base
8384
std::unique_ptr<gtpu_tunnel_common_tx_upper_layer_notifier> gtpu_tx_notifier;
8485
dummy_inner_f1u_bearer f1u_bearer;
8586
std::unique_ptr<dummy_f1u_gateway> f1u_gw;
87+
std::unique_ptr<dummy_gtpu_teid_pool> n3_allocator;
8688
std::unique_ptr<dummy_gtpu_teid_pool> f1u_allocator;
8789
std::unique_ptr<pdu_session_manager_ctrl> pdu_session_mng;
8890
null_dlt_pcap gtpu_pcap;

0 commit comments

Comments
 (0)