enb,s1ap: adding SCTP configuration to enb.conf

master
Pedro Alvarez 3 years ago
parent 08d03ee6e2
commit 2a60562a2e

@ -80,8 +80,8 @@ public:
bool start_listen(); bool start_listen();
bool reuse_addr(); bool reuse_addr();
bool sctp_subscribe_to_events(); bool sctp_subscribe_to_events();
bool sctp_set_rto_opts(); bool sctp_set_rto_opts(int rto_max);
bool sctp_set_init_msg_opts(); bool sctp_set_init_msg_opts(int max_init_attempts, int max_init_timeo);
int get_socket() const { return sockfd; }; int get_socket() const { return sockfd; };
protected: protected:

@ -29,11 +29,14 @@ struct s1ap_args_t {
std::string gtp_advertise_addr; std::string gtp_advertise_addr;
std::string s1c_bind_addr; std::string s1c_bind_addr;
uint16_t s1c_bind_port; uint16_t s1c_bind_port;
bool s1c_reuse_addr;
std::string enb_name; std::string enb_name;
uint32_t ts1_reloc_prep_timeout; uint32_t ts1_reloc_prep_timeout;
uint32_t ts1_reloc_overall_timeout; uint32_t ts1_reloc_overall_timeout;
int32_t max_s1_setup_retries; int32_t max_s1_setup_retries;
bool sctp_reuse_addr;
int32_t sctp_rto_max;
int32_t sctp_init_max_attempts;
int32_t sctp_max_init_timeo;
}; };
// S1AP interface for RRC // S1AP interface for RRC

@ -111,9 +111,6 @@ int open_socket(net_utils::addr_family ip_type, net_utils::socket_type socket_ty
} }
srslog::fetch_basic_logger(LOGSERVICE).debug("Opened %s socket=%d", net_utils::protocol_to_string(protocol), fd); srslog::fetch_basic_logger(LOGSERVICE).debug("Opened %s socket=%d", net_utils::protocol_to_string(protocol), fd);
if (protocol == protocol_type::SCTP) {
}
return fd; return fd;
} }
@ -237,13 +234,12 @@ bool sctp_subscribe_to_events(int fd)
return true; return true;
} }
bool sctp_set_rto_opts(int fd) /*
* Modify SCTP default parameters for quicker detection of broken links.
* Changes to the maximum re-transmission timeout (rto_max).
*/
bool sctp_set_rto_opts(int fd, int rto_max)
{ {
/*
* Modify SCTP default parameters for quicker detection of broken links.
* This includes changes to the SCTP_INITMSG parameters (to control the timeout of the connect() syscall)
* And changes to the maximum re-transmission timeout (rto_max), for quicker detection of broken links.
*/
// Set RTO_MAX to quickly detect broken links. // Set RTO_MAX to quickly detect broken links.
sctp_rtoinfo rto_opts; sctp_rtoinfo rto_opts;
socklen_t rto_sz = sizeof(sctp_rtoinfo); socklen_t rto_sz = sizeof(sctp_rtoinfo);
@ -254,7 +250,7 @@ bool sctp_set_rto_opts(int fd)
return false; return false;
} }
rto_opts.srto_max = 6000; // 6 seconds rto_opts.srto_max = rto_max;
srslog::fetch_basic_logger(LOGSERVICE) srslog::fetch_basic_logger(LOGSERVICE)
.debug("Setting RTO_INFO options on SCTP socket. Association %d, Initial RTO %d, Minimum RTO %d, Maximum RTO %d", .debug("Setting RTO_INFO options on SCTP socket. Association %d, Initial RTO %d, Minimum RTO %d, Maximum RTO %d",
@ -271,7 +267,11 @@ bool sctp_set_rto_opts(int fd)
return true; return true;
} }
bool sctp_set_init_msg_opts(int fd) /*
* Modify SCTP default parameters for quicker detection of broken links.
* Changes to the SCTP_INITMSG parameters (to control the timeout of the connect() syscall)
*/
bool sctp_set_init_msg_opts(int fd, int init_max_attempts, int max_init_timeo)
{ {
// Set SCTP INITMSG options to reduce blocking timeout of connect() // Set SCTP INITMSG options to reduce blocking timeout of connect()
sctp_initmsg init_opts; sctp_initmsg init_opts;
@ -282,8 +282,8 @@ bool sctp_set_init_msg_opts(int fd)
return false; return false;
} }
init_opts.sinit_max_attempts = 3; init_opts.sinit_max_attempts = init_max_attempts;
init_opts.sinit_max_init_timeo = 5000; // 5 seconds init_opts.sinit_max_init_timeo = max_init_timeo;
srslog::fetch_basic_logger(LOGSERVICE) srslog::fetch_basic_logger(LOGSERVICE)
.debug("Setting SCTP_INITMSG options on SCTP socket. Max attempts %d, Max init attempts timeout %d", .debug("Setting SCTP_INITMSG options on SCTP socket. Max attempts %d, Max init attempts timeout %d",
@ -372,14 +372,14 @@ bool unique_socket::sctp_subscribe_to_events()
return net_utils::sctp_subscribe_to_events(sockfd); return net_utils::sctp_subscribe_to_events(sockfd);
} }
bool unique_socket::sctp_set_rto_opts() bool unique_socket::sctp_set_rto_opts(int rto_max)
{ {
return net_utils::sctp_set_rto_opts(sockfd); return net_utils::sctp_set_rto_opts(sockfd, rto_max);
} }
bool unique_socket::sctp_set_init_msg_opts() bool unique_socket::sctp_set_init_msg_opts(int max_init_attempts, int max_init_timeo)
{ {
return net_utils::sctp_set_init_msg_opts(sockfd); return net_utils::sctp_set_init_msg_opts(sockfd, max_init_attempts, max_init_timeo);
} }
/*************************************************************** /***************************************************************

@ -127,8 +127,8 @@ int test_sctp_bind_error()
TESTASSERT(sock.open_socket(srsran::net_utils::addr_family::ipv4, TESTASSERT(sock.open_socket(srsran::net_utils::addr_family::ipv4,
srsran::net_utils::socket_type::seqpacket, srsran::net_utils::socket_type::seqpacket,
srsran::net_utils::protocol_type::SCTP)); srsran::net_utils::protocol_type::SCTP));
TESTASSERT(sock.bind_addr("1.1.1.1", 8000)); // Bogus IP address TESTASSERT(not sock.bind_addr("1.1.1.1", 8000)); // Bogus IP address
// should not be able to bind // should not be able to bind
srsran::unique_socket sock2; srsran::unique_socket sock2;
TESTASSERT(sock2.open_socket(srsran::net_utils::addr_family::ipv4, TESTASSERT(sock2.open_socket(srsran::net_utils::addr_family::ipv4,

@ -79,7 +79,6 @@ void parse_args(all_args_t* args, int argc, char* argv[])
("enb.gtp_advertise_addr", bpo::value<string>(&args->stack.s1ap.gtp_advertise_addr)->default_value(""), "IP address of eNB to advertise for DL GTP-U Traffic") ("enb.gtp_advertise_addr", bpo::value<string>(&args->stack.s1ap.gtp_advertise_addr)->default_value(""), "IP address of eNB to advertise for DL GTP-U Traffic")
("enb.s1c_bind_addr", bpo::value<string>(&args->stack.s1ap.s1c_bind_addr)->default_value("192.168.3.1"), "Local IP address to bind for S1AP connection") ("enb.s1c_bind_addr", bpo::value<string>(&args->stack.s1ap.s1c_bind_addr)->default_value("192.168.3.1"), "Local IP address to bind for S1AP connection")
("enb.s1c_bind_port", bpo::value<uint16_t>(&args->stack.s1ap.s1c_bind_port)->default_value(0), "Source port for S1AP connection (0 means any)") ("enb.s1c_bind_port", bpo::value<uint16_t>(&args->stack.s1ap.s1c_bind_port)->default_value(0), "Source port for S1AP connection (0 means any)")
("enb.s1c_reuse_addr", bpo::value<bool>(&args->stack.s1ap.s1c_reuse_addr)->default_value(false), "Use SO_REUSE_ADDR on S1-C interface.")
("enb.n_prb", bpo::value<uint32_t>(&args->enb.n_prb)->default_value(25), "Number of PRB") ("enb.n_prb", bpo::value<uint32_t>(&args->enb.n_prb)->default_value(25), "Number of PRB")
("enb.nof_ports", bpo::value<uint32_t>(&args->enb.nof_ports)->default_value(1), "Number of ports") ("enb.nof_ports", bpo::value<uint32_t>(&args->enb.nof_ports)->default_value(1), "Number of ports")
("enb.tm", bpo::value<uint32_t>(&args->enb.transmission_mode)->default_value(1), "Transmission mode (1-8)") ("enb.tm", bpo::value<uint32_t>(&args->enb.transmission_mode)->default_value(1), "Transmission mode (1-8)")
@ -259,7 +258,12 @@ void parse_args(all_args_t* args, int argc, char* argv[])
("expert.ts1_reloc_prep_timeout", bpo::value<uint32_t>(&args->stack.s1ap.ts1_reloc_prep_timeout)->default_value(10000), "S1AP TS 36.413 TS1RelocPrep Expiry Timeout value in milliseconds.") ("expert.ts1_reloc_prep_timeout", bpo::value<uint32_t>(&args->stack.s1ap.ts1_reloc_prep_timeout)->default_value(10000), "S1AP TS 36.413 TS1RelocPrep Expiry Timeout value in milliseconds.")
("expert.ts1_reloc_overall_timeout", bpo::value<uint32_t>(&args->stack.s1ap.ts1_reloc_overall_timeout)->default_value(10000), "S1AP TS 36.413 TS1RelocOverall Expiry Timeout value in milliseconds.") ("expert.ts1_reloc_overall_timeout", bpo::value<uint32_t>(&args->stack.s1ap.ts1_reloc_overall_timeout)->default_value(10000), "S1AP TS 36.413 TS1RelocOverall Expiry Timeout value in milliseconds.")
("expert.rlf_min_ul_snr_estim", bpo::value<int>(&args->stack.mac.rlf_min_ul_snr_estim)->default_value(-2), "SNR threshold in dB below which the eNB is notified with rlf ko.") ("expert.rlf_min_ul_snr_estim", bpo::value<int>(&args->stack.mac.rlf_min_ul_snr_estim)->default_value(-2), "SNR threshold in dB below which the eNB is notified with rlf ko.")
("expert.sctp_reuse_addr", bpo::value<bool>(&args->stack.s1ap.sctp_reuse_addr)->default_value(false), "Use SO_REUSE_ADDR on S1-C interface.")
("expert.max_s1_setup_retries", bpo::value<int32_t>(&args->stack.s1ap.max_s1_setup_retries)->default_value(-1), "Max S1 setup retries") ("expert.max_s1_setup_retries", bpo::value<int32_t>(&args->stack.s1ap.max_s1_setup_retries)->default_value(-1), "Max S1 setup retries")
("expert.sctp_rto_max", bpo::value<int32_t>(&args->stack.s1ap.sctp_rto_max)->default_value(6000), "SCTP maximum RTO.")
("expert.sctp_init_max_attempts", bpo::value<int32_t>(&args->stack.s1ap.sctp_init_max_attempts)->default_value(3), "Maximum SCTP init attempts.")
("expert.sctp_max_init_timeo)", bpo::value<int32_t>(&args->stack.s1ap.sctp_max_init_timeo)->default_value(5000), "Maximum SCTP init timeout.")
("expert.rx_gain_offset", bpo::value<float>(&args->phy.rx_gain_offset)->default_value(62), "RX Gain offset to add to rx_gain to calibrate RSRP readings") ("expert.rx_gain_offset", bpo::value<float>(&args->phy.rx_gain_offset)->default_value(62), "RX Gain offset to add to rx_gain to calibrate RSRP readings")
("expert.mac_prach_bi", bpo::value<uint32_t>(&args->stack.mac.prach_bi)->default_value(0), "Backoff Indicator to reduce contention in the PRACH channel") ("expert.mac_prach_bi", bpo::value<uint32_t>(&args->stack.mac.prach_bi)->default_value(0), "Backoff Indicator to reduce contention in the PRACH channel")

@ -498,16 +498,28 @@ bool s1ap::connect_mme()
} }
// Set SO_REUSE_ADDR if necessary // Set SO_REUSE_ADDR if necessary
if (args.s1c_reuse_addr) { if (args.sctp_reuse_addr) {
if (not mme_socket.reuse_addr()) { if (not mme_socket.reuse_addr()) {
mme_socket.close(); mme_socket.close();
return false; return false;
} }
} }
mme_socket.sctp_subscribe_to_events(); // Subscribe to shutdown events
mme_socket.sctp_set_rto_opts(); if (not mme_socket.sctp_subscribe_to_events()) {
mme_socket.sctp_set_init_msg_opts(); mme_socket.close();
return false;
}
// Set SRTO_MAX
if (not mme_socket.sctp_set_rto_opts(args.sctp_rto_max)) {
return false;
}
// Set SCTP init options
if (not mme_socket.sctp_set_init_msg_opts(args.sctp_init_max_attempts, args.sctp_max_init_timeo)) {
return false;
}
// Bind socket // Bind socket
if (not mme_socket.bind_addr(args.s1c_bind_addr.c_str(), args.s1c_bind_port)) { if (not mme_socket.bind_addr(args.s1c_bind_addr.c_str(), args.s1c_bind_port)) {

@ -640,9 +640,20 @@ bool ngap::connect_amf()
} }
logger.info("SCTP socket opened. fd=%d", amf_socket.fd()); logger.info("SCTP socket opened. fd=%d", amf_socket.fd());
amf_socket.sctp_subscribe_to_events(); if (not amf_socket.sctp_subscribe_to_events()) {
amf_socket.sctp_set_rto_opts(); amf_socket.close();
amf_socket.sctp_set_init_msg_opts(); return false;
}
if (not amf_socket.sctp_set_rto_opts(5000)) {
amf_socket.close();
return false;
}
if (not amf_socket.sctp_set_init_msg_opts(3, 6000)) {
amf_socket.close();
return false;
}
// Bind socket // Bind socket
if (not amf_socket.bind_addr(args.ngc_bind_addr.c_str(), 0)) { if (not amf_socket.bind_addr(args.ngc_bind_addr.c_str(), 0)) {

Loading…
Cancel
Save