Commit 016c4873 authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

Merge branch 'pfcp_v16.0.0' into 'develop'

Pfcp v16.0.0

See merge request oai/cn5g/oai-cn5g-smf!31
parents feab55c2 69f90fb1
This diff is collapsed.
......@@ -204,5 +204,8 @@ constexpr auto CURL_MIME_BOUNDARY = "----Boundary";
//for PFCP
constexpr uint64_t SECONDS_SINCE_FIRST_EPOCH = 2208988800;
//8.22 Fully Qualified TEID (F-TEID) - 3GPP TS 29.274 V16.0.0
#define TEID_GRE_KEY_LENGTH 4
#endif
......@@ -969,6 +969,13 @@ pfcp_ie * pfcp_ie::new_pfcp_ie_from_stream(std::istream& is) {
// return ie;
// }
// break;
case PFCP_IE_3GPP_INTERFACE_TYPE: {
pfcp_3gpp_interface_type_ie *ie = new pfcp_3gpp_interface_type_ie(tlv);
ie->load_from(is);
return ie;
}
break;
default:
Logger::pfcp().error("Unknown PFCP IE type %d (length %d)", tlv.get_type(), tlv.get_length());
return nullptr;
......
......@@ -7782,6 +7782,60 @@ public:
// }
//};
// IE 3gpp_interface_type
class pfcp_3gpp_interface_type_ie : public pfcp_ie {
public:
struct {
uint8_t spare :2;
uint8_t _3gpp_interface_type :6;
} interface_type;
union {
struct {
uint8_t spare :2;
uint8_t _3gpp_interface_type :6;
} bf;
uint8_t b;
} u1;
//--------
explicit pfcp_3gpp_interface_type_ie(const pfcp::_3gpp_interface_type_t& b) : pfcp_ie(PFCP_IE_3GPP_INTERFACE_TYPE){
u1.b = b.interface_type_value;
tlv.set_length(1);
}
//--------
pfcp_3gpp_interface_type_ie() : pfcp_ie(PFCP_IE_3GPP_INTERFACE_TYPE){
}
//--------
pfcp_3gpp_interface_type_ie(const pfcp_tlv& t) : pfcp_ie(t) {
};
//--------
void to_core_type(pfcp::_3gpp_interface_type_t& b) {
b.interface_type_value = u1.bf._3gpp_interface_type;
}
//--------
void dump_to(std::ostream& os) {
tlv.dump_to(os);
os.write(reinterpret_cast<const char*>(&u1.b), sizeof(u1.b));
}
//--------
void load_from(std::istream& is) {
if (tlv.get_length() != sizeof(interface_type)) {
throw pfcp_tlv_bad_length_exception(tlv.type, tlv.get_length(), __FILE__, __LINE__);
}
is.read(reinterpret_cast<char*>(&u1.b), sizeof(u1.b));
}
//--------
void to_core_type(pfcp_ies_container& s) {
pfcp::_3gpp_interface_type_t v = {};
to_core_type(v);
s.set(v);
}
};
//-------------------------------------
// IE PDI
class pfcp_pdi_ie : public pfcp_grouped_ie {
......
This diff is collapsed.
......@@ -229,8 +229,7 @@ uint32_t pfcp_l4_stack::send_request(const endpoint& dest, const pfcp_heartbeat_
pending_procedures.insert(std::pair<uint32_t, pfcp_procedure>(msg.get_sequence_number(), proc));
trxn_id2seq_num.insert(std::pair<uint64_t, uint32_t>(proc.trxn_id, msg.get_sequence_number()));
//udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
udp_s_8805.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
return msg.get_sequence_number();
}
//------------------------------------------------------------------------------
......@@ -255,11 +254,7 @@ uint32_t pfcp_l4_stack::send_request(const endpoint& dest, const pfcp_associatio
pending_procedures.insert(std::pair<uint32_t, pfcp_procedure>(msg.get_sequence_number(), proc));
trxn_id2seq_num.insert(std::pair<uint64_t, uint32_t>(proc.trxn_id, msg.get_sequence_number()));
//TTN: temporary fix to be able to work with UPF from dsTester (should be removed later)
//TTN: temporary fix to be able to work with UPF from dsTester (should be removed later)
//udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
udp_s_8805.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
return msg.get_sequence_number();
}
//------------------------------------------------------------------------------
......@@ -284,10 +279,7 @@ uint32_t pfcp_l4_stack::send_request(const endpoint& dest, const pfcp_associatio
pending_procedures.insert(std::pair<uint32_t, pfcp_procedure>(msg.get_sequence_number(), proc));
trxn_id2seq_num.insert(std::pair<uint64_t, uint32_t>(proc.trxn_id, msg.get_sequence_number()));
//TTN: temporary fix to be able to work with UPF from dsTester (should be removed later)
//udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
udp_s_8805.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
return msg.get_sequence_number();
}
////------------------------------------------------------------------------------
......@@ -364,9 +356,7 @@ uint32_t pfcp_l4_stack::send_request(const endpoint& dest, const uint64_t seid,
pending_procedures.insert(std::pair<uint32_t, pfcp_procedure>(msg.get_sequence_number(), proc));
trxn_id2seq_num.insert(std::pair<uint64_t, uint32_t>(proc.trxn_id, msg.get_sequence_number()));
//TTN: temporary fix to be able to work with UPF from dsTester (should be removed later)
//udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
udp_s_8805.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
return msg.get_sequence_number();
}
//------------------------------------------------------------------------------
......@@ -392,9 +382,7 @@ uint32_t pfcp_l4_stack::send_request(const endpoint& dest, const uint64_t seid,
pending_procedures.insert(std::pair<uint32_t, pfcp_procedure>(msg.get_sequence_number(), proc));
trxn_id2seq_num.insert(std::pair<uint64_t, uint32_t>(proc.trxn_id, msg.get_sequence_number()));
//TTN: temporary fix to be able to work with UPF from dsTester (should be removed later)
//udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
udp_s_8805.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
return msg.get_sequence_number();
}
//------------------------------------------------------------------------------
......@@ -420,9 +408,7 @@ uint32_t pfcp_l4_stack::send_request(const endpoint& dest, const uint64_t seid,
pending_procedures.insert(std::pair<uint32_t, pfcp_procedure>(msg.get_sequence_number(), proc));
trxn_id2seq_num.insert(std::pair<uint64_t, uint32_t>(proc.trxn_id, msg.get_sequence_number()));
//TTN: temporary fix to be able to work with UPF from dsTester (should be removed later)
//udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
udp_s_8805.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
return msg.get_sequence_number();
}
////------------------------------------------------------------------------------
......@@ -474,9 +460,7 @@ uint32_t pfcp_l4_stack::send_request(const endpoint& dest, const uint64_t seid,
pending_procedures.insert(std::pair<uint32_t, pfcp_procedure>(msg.get_sequence_number(), proc));
trxn_id2seq_num.insert(std::pair<uint64_t, uint32_t>(proc.trxn_id, msg.get_sequence_number()));
//TTN: temporary fix to be able to work with UPF from dsTester (should be removed later)
//udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
udp_s_8805.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
return msg.get_sequence_number();
}
//------------------------------------------------------------------------------
......@@ -502,9 +486,7 @@ uint32_t pfcp_l4_stack::send_request(const endpoint& dest, const uint64_t seid,
pending_procedures.insert(std::pair<uint32_t, pfcp_procedure>(msg.get_sequence_number(), proc));
trxn_id2seq_num.insert(std::pair<uint64_t, uint32_t>(proc.trxn_id, msg.get_sequence_number()));
//TTN: temporary fix to be able to work with UPF from dsTester (should be removed later)
//udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
udp_s_8805.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
return msg.get_sequence_number();
}
//------------------------------------------------------------------------------
......
This diff is collapsed.
......@@ -104,8 +104,8 @@ class smf_qos_flow {
std::string toString() const;
pfcp::qfi_t qfi; //QoS Flow Identifier
fteid_t ul_fteid; //fteid of UPF
fteid_t dl_fteid; //fteid of AN
pfcp::fteid_t ul_fteid; //fteid of UPF
pfcp::fteid_t dl_fteid; //fteid of AN
pfcp::pdr_id_t pdr_id_ul; // Packet Detection Rule ID, UL
pfcp::pdr_id_t pdr_id_dl; // Packet Detection Rule ID, DL
pfcp::precedence_t precedence;
......@@ -429,7 +429,7 @@ class smf_pdu_session : public std::enable_shared_from_this<smf_pdu_session> {
util::uint_generator<uint32_t> qos_rule_id_generator;
// Recursive lock
mutable std::recursive_mutex m_pdu_session_mutex;
mutable std::shared_mutex m_pdu_session_mutex;
};
......@@ -438,7 +438,8 @@ class session_management_subscription {
session_management_subscription(snssai_t snssai)
:
single_nssai(snssai),
dnn_configurations() {
dnn_configurations(),
m_dnn_configuration_mutex() {
}
/*
......@@ -471,6 +472,8 @@ class session_management_subscription {
private:
snssai_t single_nssai;
std::map<std::string, std::shared_ptr<dnn_configuration_t>> dnn_configurations; //dnn <->dnn_configuration
// Recursive lock
mutable std::shared_mutex m_dnn_configuration_mutex;
};
/*
......@@ -531,7 +534,7 @@ class dnn_context {
std::string dnn_in_use; // The DNN currently used, as received from the AMF
snssai_t nssai;
std::vector<std::shared_ptr<smf_pdu_session>> pdu_sessions; //Store all PDU Sessions associated with this DNN context
mutable std::recursive_mutex m_context;
mutable std::shared_mutex m_context;
};
class smf_context;
......
......@@ -44,12 +44,12 @@ void qos_flow_context_updated::set_qfi(const pfcp::qfi_t &q) {
}
//-----------------------------------------------------------------------------
void qos_flow_context_updated::set_ul_fteid(const fteid_t &teid) {
void qos_flow_context_updated::set_ul_fteid(const pfcp::fteid_t &teid) {
ul_fteid = teid;
}
//-----------------------------------------------------------------------------
void qos_flow_context_updated::set_dl_fteid(const fteid_t &teid) {
void qos_flow_context_updated::set_dl_fteid(const pfcp::fteid_t &teid) {
dl_fteid = teid;
}
......@@ -385,12 +385,12 @@ void pdu_session_update_sm_context_request::get_qfis(
}
//-----------------------------------------------------------------------------
void pdu_session_update_sm_context_request::set_dl_fteid(const fteid_t &t) {
void pdu_session_update_sm_context_request::set_dl_fteid(const pfcp::fteid_t &t) {
dl_fteid = t;
}
//-----------------------------------------------------------------------------
void pdu_session_update_sm_context_request::get_dl_fteid(fteid_t &t) {
void pdu_session_update_sm_context_request::get_dl_fteid(pfcp::fteid_t &t) {
t = dl_fteid;
}
......
......@@ -76,16 +76,16 @@ class qos_flow_context_updated {
void set_cause(const uint8_t cause);
void set_qfi(const pfcp::qfi_t &q);
void set_ul_fteid(const fteid_t &teid);
void set_dl_fteid(const fteid_t &teid);
void set_ul_fteid(const pfcp::fteid_t &teid);
void set_dl_fteid(const pfcp::fteid_t &teid);
void add_qos_rule(const QOSRulesIE &rule);
void set_qos_profile(const qos_profile_t &profile);
void set_priority_level(uint8_t p);
uint8_t cause_value;
pfcp::qfi_t qfi;
fteid_t ul_fteid;
fteid_t dl_fteid;
pfcp::fteid_t ul_fteid;
pfcp::fteid_t dl_fteid;
std::map<uint8_t, QOSRulesIE> qos_rules;
qos_profile_t qos_profile;
bool to_be_removed;
......@@ -342,8 +342,8 @@ class pdu_session_update_sm_context_request :
void add_qfi(const pfcp::qfi_t &qfi);
void add_qfi(const uint8_t &qfi);
void get_qfis(std::vector<pfcp::qfi_t> &q);
void set_dl_fteid(const fteid_t &t);
void get_dl_fteid(fteid_t &t);
void set_dl_fteid(const pfcp::fteid_t &t);
void get_dl_fteid(pfcp::fteid_t &t);
void set_upCnx_state(const std::string &value);
bool upCnx_state_is_set() const;
void set_rat_type(const std::string &value);
......@@ -355,7 +355,7 @@ class pdu_session_update_sm_context_request :
private:
std::vector<pfcp::qfi_t> qfis;
fteid_t dl_fteid; //AN Tunnel Info
pfcp::fteid_t dl_fteid; //AN Tunnel Info
std::string m_nf_instanceId;
std::string m_an_type;
bool m_an_type_is_set;
......
This diff is collapsed.
This diff is collapsed.
......@@ -37,10 +37,10 @@
namespace smf {
#define TASK_SMF_N4_TRIGGER_HEARTBEAT_REQUEST (0)
#define TASK_SMF_N4_TIMEOUT_HEARTBEAT_REQUEST (1)
#define TASK_SMF_N4_TIMEOUT_ASSOCIATION_REQUEST (2)
#define TASK_SMF_N4_TRIGGER_HEARTBEAT_REQUEST (0)
#define TASK_SMF_N4_TIMEOUT_HEARTBEAT_REQUEST (1)
#define TASK_SMF_N4_TIMEOUT_ASSOCIATION_REQUEST (2)
#define TASK_SMF_N4_TIMEOUT_GRACEFUL_RELEASE_PERIOD (3)
class smf_n4 : public pfcp::pfcp_l4_stack {
private:
std::thread::id thread_id;
......@@ -142,6 +142,8 @@ class smf_n4 : public pfcp::pfcp_l4_stack {
void send_heartbeat_response(const endpoint &r_endpoint,
const uint64_t trxn_id);
void send_release_request(std::shared_ptr<pfcp_association> &a);
void handle_receive_pfcp_msg(pfcp::pfcp_msg &msg, const endpoint &r_endpoint);
void handle_receive(char *recv_buffer, const std::size_t bytes_transferred,
const endpoint &r_endpoint);
......@@ -154,7 +156,10 @@ class smf_n4 : public pfcp::pfcp_l4_stack {
const endpoint &r_endpoint);
void handle_receive_association_setup_response(
pfcp::pfcp_msg &msg, const endpoint &remote_endpoint);
void handle_receive_association_update_request(
pfcp::pfcp_msg &msg, const endpoint &remote_endpoint);
void handle_receive_association_release_response(
pfcp::pfcp_msg &msg, const endpoint &remote_endpoint);
void handle_receive_session_establishment_response(
pfcp::pfcp_msg &msg, const endpoint &r_endpoint);
void handle_receive_session_modification_response(pfcp::pfcp_msg &msg,
......
......@@ -58,16 +58,15 @@ void pfcp_association::notify_del_session(const pfcp::fseid_t &cp_fseid) {
std::unique_lock<std::mutex> l(m_sessions);
sessions.erase(cp_fseid);
}
// //------------------------------------------------------------------------------
// void pfcp_association::del_sessions()
// {
// std::unique_lock<std::mutex> l(m_sessions);
// for (std::set<pfcp::fseid_t>::iterator it=sessions.begin(); it!=sessions.end();) {
// ???->remove_pfcp_session(*it);
// sessions.erase(it++);
// }
// }
//------------------------------------------------------------------------------
void pfcp_association::del_sessions()
{
std::unique_lock<std::mutex> l(m_sessions);
sessions.clear();
}
//------------------------------------------------------------------------------
void pfcp_association::restore_n4_sessions() {
std::unique_lock<std::mutex> l(m_sessions);
if (sessions.size()) {
......@@ -136,6 +135,22 @@ bool pfcp_associations::add_association(
}
return true;
}
//------------------------------------------------------------------------------
bool pfcp_associations::update_association(
pfcp::node_id_t &node_id, pfcp::up_function_features_s &function_features) {
std::shared_ptr<pfcp_association> sa = std::shared_ptr<pfcp_association>(
nullptr);
if (get_association(node_id, sa)) {
sa->function_features.first = true;
sa->function_features.second = function_features;
} else {
return false;
}
return true;
}
//------------------------------------------------------------------------------
bool pfcp_associations::get_association(
const pfcp::node_id_t &node_id,
......@@ -193,6 +208,7 @@ void pfcp_associations::initiate_heartbeat_request(timer_id_t timer_id,
smf_n4_inst->send_heartbeat_request(pit->second);
}
}
//------------------------------------------------------------------------------
void pfcp_associations::timeout_heartbeat_request(timer_id_t timer_id,
uint64_t arg2_user) {
......@@ -215,6 +231,20 @@ void pfcp_associations::timeout_heartbeat_request(timer_id_t timer_id,
}
}
}
//------------------------------------------------------------------------------
void pfcp_associations::timeout_release_request(timer_id_t timer_id,
uint64_t arg2_user) {
size_t hash_node_id = (size_t) arg2_user;
auto pit = associations.find((int32_t) hash_node_id);
if (pit == associations.end())
return;
else {
Logger::smf_n4().info("PFCP RELEASE REQUEST hash %u", hash_node_id);
smf_n4_inst->send_release_request(pit->second);
}
}
//------------------------------------------------------------------------------
void pfcp_associations::handle_receive_heartbeat_response(
const uint64_t trxn_id) {
......
......@@ -40,6 +40,8 @@ namespace smf {
#define PFCP_ASSOCIATION_HEARTBEAT_INTERVAL_SEC 10
#define PFCP_ASSOCIATION_HEARTBEAT_MAX_RETRIES 2
#define PFCP_ASSOCIATION_GRACEFUL_RELEASE_PERIOD 5
class pfcp_association {
public:
pfcp::node_id_t node_id;
......@@ -57,6 +59,7 @@ class pfcp_association {
bool is_restore_sessions_pending;
timer_id_t timer_association;
timer_id_t timer_graceful_release;
explicit pfcp_association(const pfcp::node_id_t &node_id)
:
......@@ -71,6 +74,7 @@ class pfcp_association {
trxn_id_heartbeat = 0;
is_restore_sessions_pending = false;
timer_association = ITTI_INVALID_TIMER_ID;
timer_graceful_release = ITTI_INVALID_TIMER_ID;
}
pfcp_association(const pfcp::node_id_t &node_id,
pfcp::recovery_time_stamp_t &recovery_time_stamp)
......@@ -86,6 +90,7 @@ class pfcp_association {
trxn_id_heartbeat = 0;
timer_association = ITTI_INVALID_TIMER_ID;
is_restore_sessions_pending = false;
timer_graceful_release = ITTI_INVALID_TIMER_ID;
}
pfcp_association(const pfcp::node_id_t &ni, pfcp::recovery_time_stamp_t &rts,
pfcp::up_function_features_s &uff)
......@@ -102,6 +107,7 @@ class pfcp_association {
trxn_id_heartbeat = 0;
is_restore_sessions_pending = false;
timer_association = ITTI_INVALID_TIMER_ID;
timer_graceful_release = ITTI_INVALID_TIMER_ID;
}
pfcp_association(pfcp_association const &p)
:
......@@ -113,13 +119,14 @@ class pfcp_association {
num_retries_timer_heartbeat(p.num_retries_timer_heartbeat),
trxn_id_heartbeat(p.trxn_id_heartbeat),
is_restore_sessions_pending(p.is_restore_sessions_pending),
timer_association(0) {
timer_association(0),
timer_graceful_release(0) {
}
void notify_add_session(const pfcp::fseid_t &cp_fseid);
bool has_session(const pfcp::fseid_t &cp_fseid);
void notify_del_session(const pfcp::fseid_t &cp_fseid);
//void del_sessions();
void del_sessions();
void restore_n4_sessions();
void set(const pfcp::up_function_features_s &ff) {
function_features.first = true;
......@@ -168,6 +175,8 @@ class pfcp_associations {
pfcp::recovery_time_stamp_t &recovery_time_stamp,
pfcp::up_function_features_s &function_features,
bool &restore_n4_sessions);
bool update_association(
pfcp::node_id_t &node_id, pfcp::up_function_features_s &function_features);
bool get_association(const pfcp::node_id_t &node_id,
std::shared_ptr<pfcp_association> &sa) const;
bool get_association(const pfcp::fseid_t &cp_fseid,
......@@ -181,6 +190,7 @@ class pfcp_associations {
void initiate_heartbeat_request(timer_id_t timer_id, uint64_t arg2_user);
void timeout_heartbeat_request(timer_id_t timer_id, uint64_t arg2_user);
void timeout_release_request(timer_id_t timer_id, uint64_t arg2_user);
void handle_receive_heartbeat_response(const uint64_t trxn_id);
bool select_up_node(pfcp::node_id_t &node_id,
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment