Commit 173c9bad authored by Raphael Defosseux's avatar Raphael Defosseux

Merge branch 'assoc_retry' into 'develop'

Added retry for PFCP association request

See merge request oai/cn5g/oai-cn5g-smf!112
parents 553c7e20 a19f3222
......@@ -32,6 +32,7 @@
#include "endpoint.hpp"
#include "itti_msg.hpp"
#include "msg_pfcp.hpp"
#include "smf_profile.hpp"
class itti_n4_msg : public itti_msg {
public:
......@@ -638,4 +639,30 @@ class itti_n4_session_failure_indication : public itti_n4_msg {
pfcp::pfcp_session_modification_request pfcp_ies;
};
//-----------------------------------------------------------------------------
class itti_n4_association_retry : public itti_n4_msg {
public:
itti_n4_association_retry(const task_id_t origin, const task_id_t destination)
: itti_n4_msg(N4_ASSOCIATION_TRIGGER_WITH_RETRY, origin, destination) {}
itti_n4_association_retry(const itti_n4_association_retry& i)
: itti_n4_msg(i) {
node_id = i.node_id;
profile = i.profile;
}
itti_n4_association_retry(
const itti_n4_association_retry& i, const task_id_t orig,
const task_id_t dest)
: itti_n4_msg(i, orig, dest) {
node_id = i.node_id;
profile = i.profile;
}
const char* get_msg_name() {
return typeid(itti_n4_association_retry).name();
};
pfcp::node_id_t node_id;
smf::upf_profile profile;
};
//-----------------------------------------------------------------------------
#endif /* ITTI_MSG_N4_HPP_INCLUDED_ */
......@@ -83,6 +83,7 @@ typedef enum {
N4_HEARTBEAT_RESPONSE,
N4_PFCP_PFD_MANAGEMENT_REQUEST,
N4_PFCP_PFD_MANAGEMENT_RESPONSE,
N4_ASSOCIATION_TRIGGER_WITH_RETRY,
N4_ASSOCIATION_SETUP_REQUEST,
N4_ASSOCIATION_SETUP_RESPONSE,
N4_ASSOCIATION_UPDATE_REQUEST,
......
......@@ -63,6 +63,7 @@
#include "string.hpp"
#include "fqdn.hpp"
#include "smf_config.hpp"
#include "smf_pfcp_association.hpp"
extern "C" {
#include "dynamic_memory_check.h"
......@@ -71,6 +72,9 @@ extern "C" {
using namespace smf;
#define PFCP_ASSOC_RETRY_COUNT 10
#define PFCP_ASSOC_RESP_WAIT 2
extern util::async_shell_cmd* async_shell_cmd_inst;
extern smf_app* smf_app_inst;
extern smf_config smf_cfg;
......@@ -205,6 +209,11 @@ void smf_app_task(void*) {
std::shared_ptr<itti_msg> shared_msg = itti_inst->receive_msg(task_id);
auto* msg = shared_msg.get();
switch (msg->msg_type) {
case N4_ASSOCIATION_TRIGGER_WITH_RETRY:
smf_app_inst->handle_itti_msg(
std::static_pointer_cast<itti_n4_association_retry>(shared_msg));
break;
case N4_SESSION_ESTABLISHMENT_RESPONSE:
if (itti_n4_session_establishment_response* m =
dynamic_cast<itti_n4_session_establishment_response*>(msg)) {
......@@ -367,7 +376,16 @@ void smf_app::start_nf_registration_discovery() {
// verified)
for (std::vector<pfcp::node_id_t>::const_iterator it = smf_cfg.upfs.begin();
it != smf_cfg.upfs.end(); ++it) {
start_upf_association(*it);
for (int i = 0; i < PFCP_ASSOC_RETRY_COUNT; i++) {
start_upf_association(*it);
sleep(PFCP_ASSOC_RESP_WAIT);
std::shared_ptr<pfcp_association> sa = {};
if (not pfcp_associations::get_instance().get_association(*it, sa))
Logger::smf_app().warn(
"Failed to receive PFCP Association Response, Retrying .....!!");
else
break;
}
}
}
......@@ -465,6 +483,24 @@ void smf_app::start_upf_association(
}
}
//------------------------------------------------------------------------------
void smf_app::handle_itti_msg(std::shared_ptr<itti_n4_association_retry> snar) {
pfcp::node_id_t node_id = snar->node_id;
upf_profile profile = snar->profile;
for (int i = 0; i < PFCP_ASSOC_RETRY_COUNT; i++) {
smf_app_inst->start_upf_association(node_id, profile);
sleep(PFCP_ASSOC_RESP_WAIT);
std::shared_ptr<pfcp_association> sa = {};
if (not pfcp_associations::get_instance().get_association(node_id, sa))
Logger::smf_app().warn(
"Failed to receive PFCP Association Response, Retrying "
".....!!");
else
break;
}
}
//------------------------------------------------------------------------------
void smf_app::handle_itti_msg(itti_n4_session_establishment_response& seresp) {
std::shared_ptr<smf_context> pc = {};
......@@ -1412,7 +1448,19 @@ bool smf_app::handle_nf_status_notification(
smf_cfg.upfs.push_back(n);
upf_profile* upf_node_profile =
dynamic_cast<upf_profile*>(profile.get());
start_upf_association(n, std::ref(*upf_node_profile));
// Trigger N4 association request with retry if needed
std::shared_ptr<itti_n4_association_retry> itti_msg =
std::make_shared<itti_n4_association_retry>(
TASK_SMF_N4, TASK_SMF_APP);
itti_msg->node_id = n;
itti_msg->profile = std::ref(*upf_node_profile);
int ret = itti_inst->send_msg(itti_msg);
if (RETURNok != ret) {
Logger::smf_n4().error(
"Could not send ITTI message %s to task TASK_SMF_N4",
itti_msg->get_msg_name());
}
} else {
Logger::smf_app().debug("No IP Addr/FQDN found");
return false;
......@@ -1882,8 +1930,8 @@ bool smf_app::get_session_management_subscription_data(
/*
for (int i = 0; i < smf_cfg.num_session_management_subscription; i++) {
if ((0 == dnn.compare(smf_cfg.session_management_subscription[i].dnn)) and
(snssai.sST ==
if ((0 == dnn.compare(smf_cfg.session_management_subscription[i].dnn))
and (snssai.sST ==
smf_cfg.session_management_subscription[i].single_nssai.sST) and
(0 ==
snssai.sD.compare(
......@@ -2096,7 +2144,8 @@ void smf_app::trigger_session_create_sm_context_response(
pdu_session_create_sm_context_response& sm_context_response,
uint32_t& pid) {
Logger::smf_app().debug(
"Trigger PDU Session Create SM Context Response: Set promise with ID %d "
"Trigger PDU Session Create SM Context Response: Set promise with ID "
"%d "
"to ready",
pid);
std::unique_lock lock(m_sm_context_create_promises);
......@@ -2112,7 +2161,8 @@ void smf_app::trigger_session_update_sm_context_response(
pdu_session_update_sm_context_response& sm_context_response,
uint32_t& pid) {
Logger::smf_app().debug(
"Trigger PDU Session Update SM Context Response: Set promise with ID %d "
"Trigger PDU Session Update SM Context Response: Set promise with ID "
"%d "
"to ready",
pid);
std::unique_lock lock(m_sm_context_update_promises);
......@@ -2128,7 +2178,8 @@ void smf_app::trigger_session_release_sm_context_response(
pdu_session_release_sm_context_response& sm_context_response,
uint32_t& pid) {
Logger::smf_app().debug(
"Trigger PDU Session Release SM Context Response: Set promise with ID %d "
"Trigger PDU Session Release SM Context Response: Set promise with ID "
"%d "
"to ready",
pid);
std::unique_lock lock(m_sm_context_release_promises);
......@@ -2288,7 +2339,8 @@ void smf_app::trigger_nf_registration_request() {
//------------------------------------------------------------------------------
void smf_app::trigger_nf_deregistration() {
Logger::smf_app().debug(
"Send ITTI msg to N11 task to trigger the deregistration request to NRF");
"Send ITTI msg to N11 task to trigger the deregistration request to "
"NRF");
std::shared_ptr<itti_n11_deregister_nf_instance> itti_msg =
std::make_shared<itti_n11_deregister_nf_instance>(
......
......@@ -306,6 +306,12 @@ class smf_app {
* @return void
*/
void handle_itti_msg(std::shared_ptr<itti_n4_session_report_request> snr);
/*
* Handle ITTI message (Trigger N4 Association with Retry)
* @param [itti_n4_association_retry&] snf
* @return void
*/
void handle_itti_msg(std::shared_ptr<itti_n4_association_retry> snar);
/*
* Handle ITTI message (N4 Association Setup Request)
......
......@@ -270,9 +270,29 @@ bool pfcp_associations::get_association(
std::shared_ptr<pfcp_association>& sa) const {
std::size_t hash_node_id = std::hash<pfcp::node_id_t>{}(node_id);
auto pit = associations.find((int32_t) hash_node_id);
if (pit == associations.end())
if (pit == associations.end()) {
// We didn't found association, may be because hash map is made with
// node_id_type FQDN
if (node_id.node_id_type == pfcp::NODE_ID_TYPE_IPV4_ADDRESS) {
struct hostent* hostname = gethostbyaddr(
&node_id.u1.ipv4_address.s_addr,
sizeof(node_id.u1.ipv4_address.s_addr), AF_INET);
pfcp::node_id_t node_id_tmp = {};
node_id_tmp.node_id_type = pfcp::NODE_ID_TYPE_FQDN;
node_id_tmp.fqdn = hostname->h_name;
Logger::smf_app().debug(
"Hash lookup for association retry: Associated Hostname -> %s",
hostname->h_name);
std::size_t hash_node_id = std::hash<pfcp::node_id_t>{}(node_id_tmp);
auto pit = associations.find((int32_t) hash_node_id);
if (get_association(node_id_tmp, sa)) return true;
}
// We didn't found association, may be because hash map is made with
// node_id_type IP ADDR
// ToDo (Might stuck in recursive loop here)
return false;
else {
} else {
sa = pit->second;
return true;
}
......
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