@@ -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 = >pu_tx_notifier;
121+ msg.gtpu_pcap = >pu_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
67167drb_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 = >pu_tx_notifier;
298- msg.gtpu_pcap = >pu_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-
344345pdu_session_modification_result
345346pdu_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- }
0 commit comments