Commit 6a68aff2 authored by gauthier's avatar gauthier

GTPU_ERROR_INDICATION (no ext UDP port)

parent ac9ae9ac
......@@ -158,9 +158,9 @@ void paa_to_pfcp_ue_ip_address(const oai::cn::core::paa_t& paa, oai::cn::core::p
}
}
//------------------------------------------------------------------------------
void pdn_ip_to_pfcp_ue_ip_address(const oai::cn::core::pdn_type_t& pdn_type,
void pdn_ip_to_pfcp_ue_ip_address(const oai::cn::core::pdn_type_t& pdn_type,
const struct in_addr& ipv4_address,
const struct in6_addr ipv6_address,
const struct in6_addr ipv6_address,
oai::cn::core::pfcp::ue_ip_address_t& ue_ip_address)
{
switch (pdn_type.pdn_type) {
......@@ -184,3 +184,24 @@ void pdn_ip_to_pfcp_ue_ip_address(const oai::cn::core::pdn_type_t& pdn_type,
}
}
bool sockaddr_storage_to_gtp_u_peer_address(const struct sockaddr_storage& peer_sockaddr, oai::cn::core::gtp_u_peer_address_t& peer_address)
{
switch (peer_sockaddr.ss_family) {
case AF_INET: {
const struct sockaddr_in * const sin = reinterpret_cast<const sockaddr_in* const>(&peer_sockaddr);
peer_address.ipv4_address.s_addr = sin->sin_addr.s_addr;
peer_address.is_v4 = true;
return true;
}
break;
case AF_INET6: {
const struct sockaddr_in6 * const sin6 = reinterpret_cast<const sockaddr_in6* const>(&peer_sockaddr);
peer_address.ipv6_address = sin6->sin6_addr;
peer_address.is_v4 = false;
return true;
}
break;
default:
return false;
}
}
......@@ -31,6 +31,7 @@
#include "3gpp_23.003.h"
#include "3gpp_24.008.h"
#include "3gpp_29.274.h"
#include "3gpp_29.281.h"
#include "3gpp_29.244.h"
#ifdef __cplusplus
......@@ -421,8 +422,10 @@ do { \
#endif
void paa_to_pfcp_ue_ip_address(const oai::cn::core::paa_t& paa, oai::cn::core::pfcp::ue_ip_address_t& ue_ip_address);
void pdn_ip_to_pfcp_ue_ip_address(const oai::cn::core::pdn_type_t& pdn_type,
void pdn_ip_to_pfcp_ue_ip_address(const oai::cn::core::pdn_type_t& pdn_type,
const struct in_addr& ipv4_address,
const struct in6_addr ipv6_address,
const struct in6_addr ipv6_address,
oai::cn::core::pfcp::ue_ip_address_t& ue_ip_address);
bool sockaddr_storage_to_gtp_u_peer_address(const struct sockaddr_storage& peer_sockaddr, oai::cn::core::gtp_u_peer_address_t& peer_address);
#endif /* FILE_CONVERSIONS_HPP_SEEN */
......@@ -88,3 +88,11 @@ gtpv1u_msg::gtpv1u_msg(const gtpv1u_echo_response& gtp_ies) : gtpv1u_msg_header(
if (gtp_ies.recovery.first) {std::shared_ptr<gtpv1u_recovery_ie> sie(new gtpv1u_recovery_ie(gtp_ies.recovery.second)); add_ie(sie);}
if (gtp_ies.private_extension.first) {std::shared_ptr<gtpv1u_private_extension_ie> sie(new gtpv1u_private_extension_ie(gtp_ies.private_extension.second)); add_ie(sie);}
}
//------------------------------------------------------------------------------
gtpv1u_msg::gtpv1u_msg(const gtpv1u_error_indication& gtp_ies) : gtpv1u_msg_header() {
ies = {};
set_message_type(GTPU_ERROR_INDICATION);
if (gtp_ies.tunnel_endpoint_identifier_data_i.first) {std::shared_ptr<gtpv1u_tunnel_endpoint_identifier_data_i_ie> sie(new gtpv1u_tunnel_endpoint_identifier_data_i_ie(gtp_ies.tunnel_endpoint_identifier_data_i.second)); add_ie(sie);}
if (gtp_ies.gtp_u_peer_address.first) {std::shared_ptr<gtpv1u_gtp_u_peer_address_ie> sie(new gtpv1u_gtp_u_peer_address_ie(gtp_ies.gtp_u_peer_address.second)); add_ie(sie);}
if (gtp_ies.private_extension.first) {std::shared_ptr<gtpv1u_private_extension_ie> sie(new gtpv1u_private_extension_ie(gtp_ies.private_extension.second)); add_ie(sie);}
}
......@@ -340,3 +340,33 @@ void gtpu_l4_stack::send_response(const gtpv1u_echo_response& gtp_ies)
Logger::gtpv1_u().debug( "gtpu_l4_stack::send_response %s, no known peer addr", gtp_ies.get_msg_name());
}
}
//------------------------------------------------------------------------------
void gtpu_l4_stack::send_indication(const gtpv1u_error_indication& gtp_ies)
{
std::ostringstream oss(std::ostringstream::binary);
gtpv1u_msg msg(gtp_ies);
uint32_t teid = UNASSIGNED_TEID;
if (gtp_ies.get_teid(teid)) {
msg.set_teid(teid);
}
uint16_t sn = 0;
if (gtp_ies.get_sequence_number(sn)) {
msg.set_sequence_number(sn);
}
msg.dump_to(oss);
std::string bstream = oss.str();
switch (gtp_ies.r_endpoint.ss_family) {
case AF_INET: {
const struct sockaddr_in * const sin = reinterpret_cast<const sockaddr_in* const>(&gtp_ies.r_endpoint);
udp_s.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), *sin);
}
break;
case AF_INET6: {
const struct sockaddr_in6 * const sin6 = reinterpret_cast<const sockaddr_in6* const>(&gtp_ies.r_endpoint);
udp_s.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), *sin6);
}
break;
default:
Logger::gtpv1_u().debug( "gtpu_l4_stack::send_indication %s, no known peer addr", gtp_ies.get_msg_name());
}
}
......@@ -171,6 +171,7 @@ public:
void send_g_pdu(const struct sockaddr_in6& peer_addr, const teid_t teid, const char* payload, const ssize_t payload_len);
void send_response(const gtpv1u_echo_response& gtp_ies);
void send_indication(const gtpv1u_error_indication& gtp_ies);
};
} // namespace gtpv1u
......
......@@ -27,6 +27,7 @@
*/
#include "common_defs.h"
#include "conversions.hpp"
#include "gtpu.h"
#include "itti.hpp"
#include "logger.hpp"
......@@ -65,6 +66,10 @@ void spgwu_s1u_task (void *args_p)
spgwu_s1u_inst->handle_itti_msg(std::static_pointer_cast<itti_s1u_echo_response>(shared_msg));
break;
case S1U_ERROR_INDICATION:
spgwu_s1u_inst->handle_itti_msg(std::static_pointer_cast<itti_s1u_error_indication>(shared_msg));
break;
case TIME_OUT:
if (itti_msg_timeout* to = dynamic_cast<itti_msg_timeout*>(msg)) {
Logger::spgwu_s1u().info( "TIME-OUT event timer id %d", to->timer_id);
......@@ -211,4 +216,36 @@ void spgwu_s1u::handle_itti_msg (std::shared_ptr<core::itti::itti_s1u_echo_respo
{
send_response(m->gtp_ies);
}
//------------------------------------------------------------------------------
void spgwu_s1u::handle_itti_msg (std::shared_ptr<core::itti::itti_s1u_error_indication> m)
{
send_indication(m->gtp_ies);
}
//------------------------------------------------------------------------------
void spgwu_s1u::report_error_indication(const struct sockaddr_storage& r_endpoint, const socklen_t& r_endpoint_addr_len, const uint32_t tunnel_id)
{
itti_s1u_error_indication *error_ind = new itti_s1u_error_indication(TASK_SPGWU_S1U, TASK_SPGWU_S1U);
error_ind->gtp_ies.r_endpoint = r_endpoint;
error_ind->gtp_ies.r_endpoint_addr_len = r_endpoint_addr_len;
error_ind->gtp_ies.set_teid(0);
core::tunnel_endpoint_identifier_data_i_t tun_data = {};
tun_data.tunnel_endpoint_identifier_data_i = tunnel_id;
error_ind->gtp_ies.set(tun_data);
core::gtp_u_peer_address_t peer_address = {};
if (sockaddr_storage_to_gtp_u_peer_address(r_endpoint, peer_address)) {
error_ind->gtp_ies.set(peer_address);
} else {
// mandatory ie
free(error_ind);
return;
}
std::shared_ptr<itti_s1u_error_indication> serror_ind = std::shared_ptr<itti_s1u_error_indication>(error_ind);
int ret = itti_inst->send_msg(serror_ind);
if (RETURNok != ret) {
Logger::spgwu_s1u().error( "Could not send ITTI message %s to task TASK_SPGWU_S1U", error_ind->get_msg_name());
}
}
......@@ -54,7 +54,7 @@ public:
//void handle_itti_msg (oai::cn::core::itti::itti_s1u_echo_request& s) {};
void handle_itti_msg (std::shared_ptr<oai::cn::core::itti::itti_s1u_echo_response> m);
//void handle_itti_msg (oai::cn::core::itti::itti_s1u_error_indication& s) {};
void handle_itti_msg (std::shared_ptr<oai::cn::core::itti::itti_s1u_error_indication> m);
//void handle_itti_msg (oai::cn::core::itti::itti_s1u_supported_extension_headers_notification& s) {};
//void handle_itti_msg (oai::cn::core::itti::itti_s1u_end_marker& s) {};
......@@ -71,6 +71,7 @@ public:
void send_g_pdu(const struct in6_addr& peer_addr, const uint16_t peer_udp_port, const uint32_t tunnel_id, const char* send_buffer, const ssize_t num_bytes);
void time_out_itti_event(const uint32_t timer_id);
void report_error_indication(const struct sockaddr_storage& r_endpoint, const socklen_t& r_endpoint_addr_len, const uint32_t tunnel_id);
};
}
#endif /* FILE_SGWU_S1U_HPP_SEEN */
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