Adding S11 initialization in MME and SPGW as unix sockets.

This commit is contained in:
Pedro Alvarez 2019-03-22 11:43:27 +00:00 committed by Andre Puschmann
parent 8a0ae614c2
commit 3e9f10e20d
4 changed files with 111 additions and 2 deletions

View File

@ -31,6 +31,8 @@
#include "srslte/common/buffer_pool.h" #include "srslte/common/buffer_pool.h"
#include "srslte/common/log.h" #include "srslte/common/log.h"
#include "srslte/common/log_filter.h" #include "srslte/common/log_filter.h"
#include <sys/socket.h>
#include <sys/un.h>
namespace srsepc { namespace srsepc {
@ -44,13 +46,13 @@ public:
srslte::gtp_fteid_t mme_ctr_fteid; srslte::gtp_fteid_t mme_ctr_fteid;
srslte::gtp_fteid_t sgw_ctr_fteid; srslte::gtp_fteid_t sgw_ctr_fteid;
} gtpc_ctx_t; } gtpc_ctx_t;
static mme_gtpc* get_instance(void); static mme_gtpc* get_instance(void);
static void cleanup(void); static void cleanup(void);
bool init(srslte::log_filter* mme_gtpc_log); bool init(srslte::log_filter* mme_gtpc_log);
void handle_s11_pdu(srslte::gtpc_pdu* msg); void handle_s11_pdu(srslte::gtpc_pdu* msg);
uint32_t get_new_ctrl_teid();
virtual bool send_create_session_request(uint64_t imsi); virtual bool send_create_session_request(uint64_t imsi);
bool handle_create_session_response(srslte::gtpc_pdu* cs_resp_pdu); bool handle_create_session_response(srslte::gtpc_pdu* cs_resp_pdu);
virtual bool send_modify_bearer_request(uint64_t imsi, uint16_t erab_to_modify, srslte::gtp_fteid_t* enb_fteid); virtual bool send_modify_bearer_request(uint64_t imsi, uint16_t erab_to_modify, srslte::gtp_fteid_t* enb_fteid);
@ -73,6 +75,12 @@ private:
uint32_t m_next_ctrl_teid; uint32_t m_next_ctrl_teid;
std::map<uint32_t, uint64_t> m_mme_ctr_teid_to_imsi; std::map<uint32_t, uint64_t> m_mme_ctr_teid_to_imsi;
std::map<uint64_t, struct gtpc_ctx> m_imsi_to_gtpc_ctx; std::map<uint64_t, struct gtpc_ctx> m_imsi_to_gtpc_ctx;
int m_s11;
struct sockaddr_un m_mme_addr, m_spgw_addr;
bool init_s11();
uint32_t get_new_ctrl_teid();
}; };
inline uint32_t mme_gtpc::get_new_ctrl_teid() inline uint32_t mme_gtpc::get_new_ctrl_teid()

View File

@ -29,6 +29,8 @@
#include "srsepc/hdr/spgw/spgw.h" #include "srsepc/hdr/spgw/spgw.h"
#include "srslte/asn1/gtpc.h" #include "srslte/asn1/gtpc.h"
#include "srslte/interfaces/epc_interfaces.h" #include "srslte/interfaces/epc_interfaces.h"
#include <sys/socket.h>
#include <sys/un.h>
namespace srsepc { namespace srsepc {
@ -40,13 +42,16 @@ public:
int init(spgw_args_t* args, spgw* spgw, gtpu_interface_gtpc* gtpu, srslte::log_filter* gtpc_log); int init(spgw_args_t* args, spgw* spgw, gtpu_interface_gtpc* gtpu, srslte::log_filter* gtpc_log);
void stop(); void stop();
srslte::error_t init_s11(spgw_args_t *args);
srslte::error_t init_ue_ip(spgw_args_t* args); srslte::error_t init_ue_ip(spgw_args_t* args);
int get_s11();
uint64_t get_new_ctrl_teid(); uint64_t get_new_ctrl_teid();
uint64_t get_new_user_teid(); uint64_t get_new_user_teid();
in_addr_t get_new_ue_ipv4(); in_addr_t get_new_ue_ipv4();
void handle_s11_pdu(srslte::gtpc_pdu* msg, srslte::gtpc_pdu* reply_msg); void handle_s11_pdu(srslte::gtpc_pdu* msg, srslte::gtpc_pdu* reply_msg);
void handle_create_session_request(const srslte::gtpc_create_session_request& cs_req, srslte::gtpc_pdu* gtpc_pdu); void handle_create_session_request(const srslte::gtpc_create_session_request& cs_req, srslte::gtpc_pdu* gtpc_pdu);
void handle_modify_bearer_request(const srslte::gtpc_header& mb_req_hdr, void handle_modify_bearer_request(const srslte::gtpc_header& mb_req_hdr,
const srslte::gtpc_modify_bearer_request& mb_req, const srslte::gtpc_modify_bearer_request& mb_req,
@ -64,6 +69,9 @@ public:
spgw* m_spgw; spgw* m_spgw;
gtpu_interface_gtpc* m_gtpu; gtpu_interface_gtpc* m_gtpu;
int m_s11;
struct sockaddr_un m_spgw_addr, m_mme_addr;
uint32_t m_h_next_ue_ip; uint32_t m_h_next_ue_ip;
uint64_t m_next_ctrl_teid; uint64_t m_next_ctrl_teid;
uint64_t m_next_user_teid; uint64_t m_next_user_teid;
@ -77,6 +85,11 @@ public:
srslte::byte_buffer_pool* m_pool; srslte::byte_buffer_pool* m_pool;
}; };
inline int spgw::gtpc::get_s11()
{
return m_s11;
}
inline uint64_t spgw::gtpc::get_new_ctrl_teid() inline uint64_t spgw::gtpc::get_new_ctrl_teid()
{ {
return m_next_ctrl_teid++; return m_next_ctrl_teid++;

View File

@ -76,11 +76,56 @@ bool mme_gtpc::init(srslte::log_filter* mme_gtpc_log)
m_s1ap = s1ap::get_instance(); m_s1ap = s1ap::get_instance();
m_spgw = spgw::get_instance(); m_spgw = spgw::get_instance();
if (!init_s11()) {
m_mme_gtpc_log->error("Error Initializing MME S11 Interface\n");
return false;
}
m_mme_gtpc_log->info("MME GTP-C Initialized\n"); m_mme_gtpc_log->info("MME GTP-C Initialized\n");
m_mme_gtpc_log->console("MME GTP-C Initialized\n"); m_mme_gtpc_log->console("MME GTP-C Initialized\n");
return true; return true;
} }
bool mme_gtpc::init_s11()
{
socklen_t sock_len;
char mme_addr_name[] = "@mme_s11";
char spgw_addr_name[] = "@spgw_s11";
// Logs
m_mme_gtpc_log->info("Initializing MME S11 interface.\n");
// Open Socket
m_s11 = socket(AF_UNIX, SOCK_DGRAM, 0);
if (m_s11 < 0) {
m_mme_gtpc_log->error("Error opening UNIX socket. Error %s\n", strerror(errno));
return false;
}
// Set MME Address
memset(&m_mme_addr, 0, sizeof(struct sockaddr_un));
m_mme_addr.sun_family = AF_UNIX;
strncpy(m_mme_addr.sun_path, mme_addr_name, strlen(mme_addr_name));
m_mme_addr.sun_path[0] = '\0';
// Bind socket to address
if (bind(m_s11, (const struct sockaddr*)&m_mme_addr, sizeof(m_mme_addr)) == -1) {
m_mme_gtpc_log->error("Error binding UNIX socket. Error %s\n", strerror(errno));
return false;
}
// Set SPGW Address for later use
memset(&m_spgw_addr, 0, sizeof(struct sockaddr_un));
m_spgw_addr.sun_family = AF_UNIX;
strncpy(m_spgw_addr.sun_path, spgw_addr_name, strlen(spgw_addr_name));
m_spgw_addr.sun_path[0] = '\0';
m_mme_gtpc_log->info("MME S11 Initialized\n");
m_mme_gtpc_log->console("MME S11 Initialized\n");
return true;
}
void mme_gtpc::handle_s11_pdu(srslte::gtpc_pdu *pdu) void mme_gtpc::handle_s11_pdu(srslte::gtpc_pdu *pdu)
{ {
m_mme_gtpc_log->debug("MME Received GTP-C PDU. Message type %s\n",srslte::gtpc_msg_type_to_str(pdu->header.type)); m_mme_gtpc_log->debug("MME Received GTP-C PDU. Message type %s\n",srslte::gtpc_msg_type_to_str(pdu->header.type));

View File

@ -66,6 +66,13 @@ int spgw::gtpc::init(spgw_args_t* args, spgw* spgw, gtpu_interface_gtpc* gtpu, s
m_spgw = spgw; m_spgw = spgw;
m_gtpu = gtpu; m_gtpu = gtpu;
// Init S11 interface
err = init_s11(args);
if (err != srslte::ERROR_NONE) {
m_gtpc_log->console("Could not initialize the S11 interface.\n");
return -1;
}
// Init IP pool // Init IP pool
err = init_ue_ip(args); err = init_ue_ip(args);
if (err != srslte::ERROR_NONE) { if (err != srslte::ERROR_NONE) {
@ -90,6 +97,42 @@ void spgw::gtpc::stop()
return; return;
} }
srslte::error_t spgw::gtpc::init_s11(spgw_args_t* args)
{
socklen_t sock_len;
char spgw_addr_name[] = "@spgw_s11";
char mme_addr_name[] = "@mme_s11";
// Logs
m_gtpc_log->info("Initializing SPGW S11 interface.\n");
// Open Socket
m_s11 = socket(AF_UNIX, SOCK_DGRAM, 0);
if (m_s11 < 0) {
m_gtpc_log->error("Error opening UNIX socket. Error %s\n", strerror(errno));
return srslte::ERROR_CANT_START;
}
// Set MME Address
memset(&m_mme_addr, 0, sizeof(struct sockaddr_un));
m_mme_addr.sun_family = AF_UNIX;
strncpy(m_mme_addr.sun_path, mme_addr_name, strlen(mme_addr_name));
m_mme_addr.sun_path[0] = '\0';
// Set SPGW Address
memset(&m_spgw_addr, 0, sizeof(struct sockaddr_un));
m_spgw_addr.sun_family = AF_UNIX;
strncpy(m_spgw_addr.sun_path, spgw_addr_name, strlen(spgw_addr_name));
m_spgw_addr.sun_path[0] = '\0';
// Bind socket to address
if (bind(m_s11, (const struct sockaddr*)&m_spgw_addr, sizeof(m_spgw_addr)) == -1) {
m_gtpc_log->error("Error binding UNIX socket. Error %s\n", strerror(errno));
return srslte::ERROR_CANT_START;
}
return srslte::ERROR_NONE;
}
void spgw::gtpc::handle_s11_pdu(srslte::gtpc_pdu* pdu, srslte::gtpc_pdu* reply_pdu) void spgw::gtpc::handle_s11_pdu(srslte::gtpc_pdu* pdu, srslte::gtpc_pdu* reply_pdu)
{ {
m_gtpc_log->console("Received GTP-C PDU. Message type: %s\n", srslte::gtpc_msg_type_to_str(pdu->header.type)); m_gtpc_log->console("Received GTP-C PDU. Message type: %s\n", srslte::gtpc_msg_type_to_str(pdu->header.type));