From ba332d2af9b4440778edebf997ba87debfa37a22 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 25 Feb 2021 10:05:13 +0000 Subject: [PATCH 1/2] IE Enterprise Specific - decoding function added --- src/common/3gpp_29.244.h | 8 +++++ src/pfcp/3gpp_29.244.cpp | 5 +++ src/pfcp/3gpp_29.244.hpp | 66 +++++++++++++++++++++++++++++++++++++++- src/pfcp/msg_pfcp.hpp | 10 ++++++ 4 files changed, 88 insertions(+), 1 deletion(-) diff --git a/src/common/3gpp_29.244.h b/src/common/3gpp_29.244.h index fe60f8d1..b7c7b4a9 100644 --- a/src/common/3gpp_29.244.h +++ b/src/common/3gpp_29.244.h @@ -39,6 +39,13 @@ #include namespace pfcp { +//------------------------------------- +// 8.1.1 IE with Enterprise Info +typedef struct enterprise_specific_s { + uint16_t enterprise_id; + std::string proprietary_data; +} enterprise_specific_t; +//------------------------------------- struct pfcp_exception : public std::exception { pfcp_exception() throw() { @@ -312,6 +319,7 @@ struct pfcp_ie_value_exception : public pfcp_ie_exception { #define PFCP_IE_PAGING_POLICY_INDICATOR (158) #define PFCP_IE_APN_DNN (159) #define PFCP_IE_3GPP_INTERFACE_TYPE (160) +#define PFCP_IE_ENTERPRISE_SPECIFIC (32770) #define PFCP_IE_PFCPSRREQ_FLAGS_3GPP (161) #define PFCP_IE_PFCPAUREQ_FLAGS (162) diff --git a/src/pfcp/3gpp_29.244.cpp b/src/pfcp/3gpp_29.244.cpp index 2c09d3c9..3eca6afd 100644 --- a/src/pfcp/3gpp_29.244.cpp +++ b/src/pfcp/3gpp_29.244.cpp @@ -38,6 +38,11 @@ pfcp_ie* pfcp_ie::new_pfcp_ie_from_stream(std::istream& is) { tlv.load_from(is); if (tlv.length) { switch (tlv.type) { + case PFCP_IE_ENTERPRISE_SPECIFIC: { + pfcp_enterprise_specific_ie* ie = new pfcp_enterprise_specific_ie(tlv); + ie->load_from(is); + return ie; + } break; case PFCP_IE_CREATE_PDR: { pfcp_create_pdr_ie* ie = new pfcp_create_pdr_ie(tlv); ie->load_from(is); diff --git a/src/pfcp/3gpp_29.244.hpp b/src/pfcp/3gpp_29.244.hpp index f4788b10..ec795e83 100644 --- a/src/pfcp/3gpp_29.244.hpp +++ b/src/pfcp/3gpp_29.244.hpp @@ -107,7 +107,7 @@ class pfcp_ie : public stream_serializable { pfcp_ie() : tlv() {} explicit pfcp_ie(const pfcp_tlv& t) : tlv(t) {} - explicit pfcp_ie(const uint8_t tlv_type) : tlv() { tlv.type = tlv_type; } + explicit pfcp_ie(const uint16_t tlv_type) : tlv() { tlv.type = tlv_type; } virtual ~pfcp_ie(){}; @@ -550,6 +550,70 @@ class pfcp_cause_ie : public pfcp_ie { } }; //------------------------------------- +// IE ENTERPRISE SPECIFIC +class pfcp_enterprise_specific_ie : public pfcp_ie { + public: + uint16_t enterprise_id; + std::string proprietary_data; + + //-------- + explicit pfcp_enterprise_specific_ie(const pfcp::enterprise_specific_t& b) + : pfcp_ie(PFCP_IE_ENTERPRISE_SPECIFIC) { + enterprise_id = b.enterprise_id; + proprietary_data = b.proprietary_data; + tlv.set_length(2 + proprietary_data.size()); + } + //-------- + pfcp_enterprise_specific_ie() : pfcp_ie(PFCP_IE_ENTERPRISE_SPECIFIC) { + enterprise_id = 0; + proprietary_data = {}; + tlv.set_length(2); + } + // -------- + explicit pfcp_enterprise_specific_ie(const pfcp_tlv& t) + : pfcp_ie(t), + enterprise_id(0), + proprietary_data(){}; + + //-------- + void to_core_type(pfcp::enterprise_specific_t& b) { + b.enterprise_id = enterprise_id; + b.proprietary_data = proprietary_data; + } + //-------- + void dump_to(std::ostream& os) { + tlv.dump_to(os); + os.write(reinterpret_cast(&enterprise_id), + sizeof(enterprise_id)); + os << enterprise_id; + } + //-------- + void load_from(std::istream& is) { + // tlv.load_from(is); + if (tlv.get_length() < 2) { + throw pfcp_tlv_bad_length_exception( + tlv.type, tlv.get_length(), __FILE__, __LINE__); + } + is.read(reinterpret_cast(&enterprise_id), + sizeof(enterprise_id)); + + char e[tlv.get_length() - 2]; + is.read(e, tlv.get_length() - 2); + proprietary_data.assign(e, tlv.get_length() - 2); + + if (tlv.get_length() != (2 + proprietary_data.size())) { + throw pfcp_tlv_bad_length_exception( + tlv.type, tlv.get_length(), __FILE__, __LINE__); + } + } + //-------- + void to_core_type(pfcp_ies_container& s) { + pfcp::enterprise_specific_t enterprise_specific = {}; + to_core_type(enterprise_specific); + s.set(enterprise_specific); + } +}; +//------------------------------------- // IE SOURCE_INTERFACE class pfcp_source_interface_ie : public pfcp_ie { public: diff --git a/src/pfcp/msg_pfcp.hpp b/src/pfcp/msg_pfcp.hpp index d3f21b10..270879be 100644 --- a/src/pfcp/msg_pfcp.hpp +++ b/src/pfcp/msg_pfcp.hpp @@ -90,6 +90,16 @@ class pfcp_ies_container { public: static const uint8_t msg_id = 0; + // PFCP_IE_ENTERPRISE_SPECIFIC + virtual bool get(pfcp::enterprise_specific_t& v) const { + throw pfcp_msg_illegal_ie_exception( + 0, PFCP_IE_ENTERPRISE_SPECIFIC, __FILE__, __LINE__); + } + virtual void set(const pfcp::enterprise_specific_t& v) { + throw pfcp_msg_illegal_ie_exception( + 0, PFCP_IE_ENTERPRISE_SPECIFIC, __FILE__, __LINE__); + } + // PFCP_IE_CREATE_PDR virtual bool get(pfcp::create_pdr& v) const { throw pfcp_msg_illegal_ie_exception( -- GitLab From a7c8a089ca9b87231b23c2e9f88f08df11757852 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 25 Feb 2021 11:24:09 +0000 Subject: [PATCH 2/2] IE Enterprise Specific - optional decoding in pfcp asscociation req/resp --- src/pfcp/msg_pfcp.hpp | 32 ++++++++++++++++++++++++++-- src/smf_app/smf_n4.cpp | 12 +++++++++++ src/smf_app/smf_pfcp_association.cpp | 32 ++++++++++++++++++++++++++++ src/smf_app/smf_pfcp_association.hpp | 6 ++++++ 4 files changed, 80 insertions(+), 2 deletions(-) diff --git a/src/pfcp/msg_pfcp.hpp b/src/pfcp/msg_pfcp.hpp index 270879be..003e3c4c 100644 --- a/src/pfcp/msg_pfcp.hpp +++ b/src/pfcp/msg_pfcp.hpp @@ -5566,13 +5566,15 @@ class pfcp_association_setup_request : public pfcp_ies_container { std::pair cp_function_features; std::pair user_plane_ip_resource_information; + std::pair enterprise_specific; pfcp_association_setup_request() : node_id(), recovery_time_stamp(), up_function_features(), cp_function_features(), - user_plane_ip_resource_information() {} + user_plane_ip_resource_information(), + enterprise_specific () {} pfcp_association_setup_request(const pfcp_association_setup_request& i) { node_id = i.node_id; @@ -5580,6 +5582,7 @@ class pfcp_association_setup_request : public pfcp_ies_container { up_function_features = i.up_function_features; cp_function_features = i.cp_function_features; user_plane_ip_resource_information = i.user_plane_ip_resource_information; + enterprise_specific = i.enterprise_specific; } const char* get_msg_name() const { return "PFCP_ASSOCIATION_SETUP_REQUEST"; }; @@ -5618,6 +5621,13 @@ class pfcp_association_setup_request : public pfcp_ies_container { } return false; } + bool get(pfcp::enterprise_specific_t& v) const { + if (enterprise_specific.first) { + v = enterprise_specific.second; + return true; + } + return false; + } void set(const pfcp::node_id_t& v) { node_id.first = true; @@ -5639,6 +5649,10 @@ class pfcp_association_setup_request : public pfcp_ies_container { user_plane_ip_resource_information.first = true; user_plane_ip_resource_information.second = v; } + void set(const pfcp::enterprise_specific_t& v) { + enterprise_specific.first = true; + enterprise_specific.second = v; + } }; //------------------------------------------------------------------------------ @@ -5653,6 +5667,7 @@ class pfcp_association_setup_response : public pfcp_ies_container { std::pair cp_function_features; std::pair user_plane_ip_resource_information; + std::pair enterprise_specific; pfcp_association_setup_response() : node_id(), @@ -5660,7 +5675,8 @@ class pfcp_association_setup_response : public pfcp_ies_container { recovery_time_stamp(), up_function_features(), cp_function_features(), - user_plane_ip_resource_information() {} + user_plane_ip_resource_information(), + enterprise_specific () {} pfcp_association_setup_response(const pfcp_association_setup_response& i) { node_id = i.node_id; @@ -5669,6 +5685,7 @@ class pfcp_association_setup_response : public pfcp_ies_container { up_function_features = i.up_function_features; cp_function_features = i.cp_function_features; user_plane_ip_resource_information = i.user_plane_ip_resource_information; + enterprise_specific = i.enterprise_specific; } const char* get_msg_name() const { return "PFCP_ASSOCIATION_SETUP_RESPONSE"; @@ -5716,6 +5733,13 @@ class pfcp_association_setup_response : public pfcp_ies_container { } return false; } + bool get(pfcp::enterprise_specific_t& v) const { + if (enterprise_specific.first) { + v = enterprise_specific.second; + return true; + } + return false; + } void set(const pfcp::node_id_t& v) { node_id.first = true; @@ -5741,6 +5765,10 @@ class pfcp_association_setup_response : public pfcp_ies_container { user_plane_ip_resource_information.first = true; user_plane_ip_resource_information.second = v; } + void set(const pfcp::enterprise_specific_t& v) { + enterprise_specific.first = true; + enterprise_specific.second = v; + } }; //------------------------------------------------------------------------------ diff --git a/src/smf_app/smf_n4.cpp b/src/smf_app/smf_n4.cpp index 8dc6263f..704f633f 100644 --- a/src/smf_app/smf_n4.cpp +++ b/src/smf_app/smf_n4.cpp @@ -372,6 +372,12 @@ void smf_n4::handle_receive_association_setup_request( msg_ies_container.node_id.second, msg_ies_container.recovery_time_stamp.second, msg_ies_container.up_function_features.second, restore_n4_sessions); + } else if (msg_ies_container.enterprise_specific.first) { + pfcp_associations::get_instance().add_association( + msg_ies_container.node_id.second, + msg_ies_container.recovery_time_stamp.second, + msg_ies_container.up_function_features.second, + msg_ies_container.enterprise_specific.second, restore_n4_sessions); } else { pfcp_associations::get_instance().add_association( msg_ies_container.node_id.second, @@ -446,6 +452,12 @@ void smf_n4::handle_receive_association_setup_response( msg_ies_container.node_id.second, msg_ies_container.recovery_time_stamp.second, msg_ies_container.up_function_features.second, restore_n4_sessions); + } else if (msg_ies_container.enterprise_specific.first) { + pfcp_associations::get_instance().add_association( + msg_ies_container.node_id.second, + msg_ies_container.recovery_time_stamp.second, + msg_ies_container.up_function_features.second, + msg_ies_container.enterprise_specific.second, restore_n4_sessions); } else { pfcp_associations::get_instance().add_association( msg_ies_container.node_id.second, diff --git a/src/smf_app/smf_pfcp_association.cpp b/src/smf_app/smf_pfcp_association.cpp index 34fa7cd9..da21d5cf 100644 --- a/src/smf_app/smf_pfcp_association.cpp +++ b/src/smf_app/smf_pfcp_association.cpp @@ -215,6 +215,38 @@ bool pfcp_associations::add_association( } return true; } +//------------------------------------------------------------------------------ +bool pfcp_associations::add_association( + pfcp::node_id_t& node_id, pfcp::recovery_time_stamp_t& recovery_time_stamp, + pfcp::up_function_features_s& function_features, + pfcp::enterprise_specific_s& enterprise_specific, + bool& restore_n4_sessions) { + std::shared_ptr sa = + std::shared_ptr(nullptr); + if (get_association(node_id, sa)) { + itti_inst->timer_remove(sa->timer_heartbeat); + if (sa->recovery_time_stamp == recovery_time_stamp) { + restore_n4_sessions = false; + } else { + restore_n4_sessions = true; + } + sa->recovery_time_stamp = recovery_time_stamp; + sa->function_features.first = true; + sa->function_features.second = function_features; + } else { + restore_n4_sessions = false; + pfcp_association* association = + new pfcp_association(node_id, recovery_time_stamp, function_features); + sa = std::shared_ptr(association); + sa->recovery_time_stamp = recovery_time_stamp; + sa->function_features.first = true; + sa->function_features.second = function_features; + std::size_t hash_node_id = std::hash{}(node_id); + associations.insert((int32_t) hash_node_id, sa); + trigger_heartbeat_request_procedure(sa); + } + return true; +} //------------------------------------------------------------------------------ bool pfcp_associations::update_association( diff --git a/src/smf_app/smf_pfcp_association.hpp b/src/smf_app/smf_pfcp_association.hpp index d2ddd705..123bc9d2 100644 --- a/src/smf_app/smf_pfcp_association.hpp +++ b/src/smf_app/smf_pfcp_association.hpp @@ -190,6 +190,12 @@ class pfcp_associations { pfcp::recovery_time_stamp_t& recovery_time_stamp, pfcp::up_function_features_s& function_features, bool& restore_n4_sessions); + bool add_association( + pfcp::node_id_t& node_id, + pfcp::recovery_time_stamp_t& recovery_time_stamp, + pfcp::up_function_features_s& function_features, + pfcp::enterprise_specific_s& enterprise_specific, + bool& restore_n4_sessions); bool update_association( pfcp::node_id_t& node_id, pfcp::up_function_features_s& function_features); -- GitLab