Fix several issues in GW class:

- Avoid triggering an assertion when the  gw thread is pending termination.
- Re-order gw::stop method to avoid a race condition when closing the TUN device while the gw thread is still running.
master
faluco 3 years ago committed by faluco
parent 229b1eef21
commit 3b2f0d2f65

@ -44,6 +44,7 @@ class gw : public gw_interface_stack, public srsran::thread
{
public:
gw(srslog::basic_logger& logger_);
~gw();
int init(const gw_args_t& args_, stack_interface_gw* stack);
void stop();
@ -76,7 +77,7 @@ private:
int32_t tun_fd = 0;
struct ifreq ifr = {};
int32_t sock = 0;
bool if_up = false;
std::atomic<bool> if_up = {false};
static const int NOT_ASSIGNED = -1;
int32_t default_eps_bearer_id = NOT_ASSIGNED;

@ -62,12 +62,22 @@ int gw::init(const gw_args_t& args_, stack_interface_gw* stack_)
return SRSRAN_SUCCESS;
}
gw::~gw()
{
if (tun_fd > 0) {
close(tun_fd);
}
}
void gw::stop()
{
if (run_enable) {
run_enable = false;
if (if_up) {
close(tun_fd);
if_up = false;
if (running) {
thread_cancel();
}
// Wait thread to exit gracefully otherwise might leave a mutex locked
int cnt = 0;
@ -75,9 +85,6 @@ void gw::stop()
usleep(10000);
cnt++;
}
if (running) {
thread_cancel();
}
wait_thread_finish();
current_ip_addr = 0;
@ -125,7 +132,9 @@ void gw::write_pdu(uint32_t lcid, srsran::unique_byte_buffer_t pdu)
dl_tput_bytes += pdu->N_bytes;
}
if (!if_up) {
logger.warning("TUN/TAP not up - dropping gw RX message");
if (run_enable) {
logger.warning("TUN/TAP not up - dropping gw RX message");
}
} else if (pdu->N_bytes < 20) {
// Packet not large enough to hold IPv4 Header
logger.warning("Packet to small to hold IPv4 header. Dropping packet with %d B", pdu->N_bytes);
@ -163,7 +172,9 @@ void gw::write_pdu_mch(uint32_t lcid, srsran::unique_byte_buffer_t pdu)
memcpy(&dst_addr.s_addr, &pdu->msg[16], 4);
if (!if_up) {
logger.warning("TUN/TAP not up - dropping gw RX message");
if (run_enable) {
logger.warning("TUN/TAP not up - dropping gw RX message");
}
} else {
int n = write(tun_fd, pdu->msg, pdu->N_bytes);
if (n > 0 && (pdu->N_bytes != (uint32_t)n)) {
@ -324,6 +335,10 @@ void gw::run_thread()
continue;
}
if (!run_enable) {
break;
}
// Beyond this point we should have a activated default EPS bearer
srsran_assert(default_eps_bearer_id != NOT_ASSIGNED, "Default EPS bearer not activated");

Loading…
Cancel
Save