Check if RLC is suspended before transmiting PDCP SDU.

This was done to avoid integrity issues, when the UE's RRC erroneously sent
measurement reports while the re-establishment was already in progress.

As errously sending PDCP PDUs on DRBs can cause issues as well, this was
disabled too.
master
Pedro Alvarez 3 years ago
parent 9daa32e591
commit fbcffb84bd

@ -41,6 +41,7 @@ public:
virtual void discard_sdu(uint16_t rnti, uint32_t lcid, uint32_t sn) = 0; virtual void discard_sdu(uint16_t rnti, uint32_t lcid, uint32_t sn) = 0;
virtual bool rb_is_um(uint16_t rnti, uint32_t lcid) = 0; virtual bool rb_is_um(uint16_t rnti, uint32_t lcid) = 0;
virtual bool sdu_queue_is_full(uint16_t rnti, uint32_t lcid) = 0; virtual bool sdu_queue_is_full(uint16_t rnti, uint32_t lcid) = 0;
virtual bool is_suspended(uint16_t rnti, uint32_t lcid) = 0;
}; };
// RLC interface for RRC // RLC interface for RRC
@ -56,6 +57,7 @@ public:
virtual void write_sdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t sdu) = 0; virtual void write_sdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t sdu) = 0;
virtual bool has_bearer(uint16_t rnti, uint32_t lcid) = 0; virtual bool has_bearer(uint16_t rnti, uint32_t lcid) = 0;
virtual bool suspend_bearer(uint16_t rnti, uint32_t lcid) = 0; virtual bool suspend_bearer(uint16_t rnti, uint32_t lcid) = 0;
virtual bool is_suspended(uint16_t rnti, uint32_t lcid) = 0;
virtual bool resume_bearer(uint16_t rnti, uint32_t lcid) = 0; virtual bool resume_bearer(uint16_t rnti, uint32_t lcid) = 0;
virtual void reestablish(uint16_t rnti) = 0; virtual void reestablish(uint16_t rnti) = 0;
}; };

@ -51,6 +51,8 @@ public:
///< Allow PDCP to query SDU queue status ///< Allow PDCP to query SDU queue status
virtual bool sdu_queue_is_full(uint32_t lcid) = 0; virtual bool sdu_queue_is_full(uint32_t lcid) = 0;
virtual bool is_suspended(const uint32_t lcid) = 0;
}; };
class rlc_interface_mac : public srsran::read_pdu_interface class rlc_interface_mac : public srsran::read_pdu_interface

@ -139,6 +139,11 @@ void pdcp_entity_lte::write_sdu(unique_byte_buffer_t sdu, int upper_sn)
return; return;
} }
if (rlc->is_suspended(lcid)) {
logger.warning("Trying to send SDU while re-establishment is in progress. Dropping SDU. LCID=%d", lcid);
return;
}
if (rlc->sdu_queue_is_full(lcid)) { if (rlc->sdu_queue_is_full(lcid)) {
logger.info(sdu->msg, sdu->N_bytes, "Dropping %s SDU due to full queue", rrc->get_rb_name(lcid)); logger.info(sdu->msg, sdu->N_bytes, "Dropping %s SDU due to full queue", rrc->get_rb_name(lcid));
return; return;
@ -166,7 +171,6 @@ void pdcp_entity_lte::write_sdu(unique_byte_buffer_t sdu, int upper_sn)
return; return;
} }
} }
// check for pending security config in transmit direction // check for pending security config in transmit direction
if (enable_security_tx_sn != -1 && enable_security_tx_sn == static_cast<int32_t>(tx_count)) { if (enable_security_tx_sn != -1 && enable_security_tx_sn == static_cast<int32_t>(tx_count)) {
enable_integrity(DIRECTION_TX); enable_integrity(DIRECTION_TX);

@ -55,6 +55,8 @@ public:
logger.info("Discard_count=%" PRIu64 "", discard_count); logger.info("Discard_count=%" PRIu64 "", discard_count);
} }
bool is_suspended(uint32_t lcid) { return false; }
uint64_t rx_count = 0; uint64_t rx_count = 0;
uint64_t discard_count = 0; uint64_t discard_count = 0;

@ -77,6 +77,7 @@ private:
void discard_sdu(uint32_t lcid, uint32_t discard_sn); void discard_sdu(uint32_t lcid, uint32_t discard_sn);
bool rb_is_um(uint32_t lcid); bool rb_is_um(uint32_t lcid);
bool sdu_queue_is_full(uint32_t lcid); bool sdu_queue_is_full(uint32_t lcid);
bool is_suspended(uint32_t lcid);
}; };
class user_interface_gtpu : public srsue::gw_interface_pdcp class user_interface_gtpu : public srsue::gw_interface_pdcp

@ -53,6 +53,7 @@ public:
bool has_bearer(uint16_t rnti, uint32_t lcid); bool has_bearer(uint16_t rnti, uint32_t lcid);
bool suspend_bearer(uint16_t rnti, uint32_t lcid); bool suspend_bearer(uint16_t rnti, uint32_t lcid);
bool resume_bearer(uint16_t rnti, uint32_t lcid); bool resume_bearer(uint16_t rnti, uint32_t lcid);
bool is_suspended(uint16_t rnti, uint32_t lcid);
void reestablish(uint16_t rnti) final; void reestablish(uint16_t rnti) final;
// rlc_interface_pdcp // rlc_interface_pdcp

@ -217,6 +217,11 @@ bool pdcp::user_interface_rlc::rb_is_um(uint32_t lcid)
return rlc->rb_is_um(rnti, lcid); return rlc->rb_is_um(rnti, lcid);
} }
bool pdcp::user_interface_rlc::is_suspended(uint32_t lcid)
{
return rlc->is_suspended(rnti, lcid);
}
bool pdcp::user_interface_rlc::sdu_queue_is_full(uint32_t lcid) bool pdcp::user_interface_rlc::sdu_queue_is_full(uint32_t lcid)
{ {
return rlc->sdu_queue_is_full(rnti, lcid); return rlc->sdu_queue_is_full(rnti, lcid);

@ -150,6 +150,17 @@ bool rlc::suspend_bearer(uint16_t rnti, uint32_t lcid)
return result; return result;
} }
bool rlc::is_suspended(uint16_t rnti, uint32_t lcid)
{
pthread_rwlock_rdlock(&rwlock);
bool result = false;
if (users.count(rnti)) {
result = users[rnti].rlc->is_suspended(lcid);
}
pthread_rwlock_unlock(&rwlock);
return result;
}
bool rlc::resume_bearer(uint16_t rnti, uint32_t lcid) bool rlc::resume_bearer(uint16_t rnti, uint32_t lcid)
{ {
pthread_rwlock_rdlock(&rwlock); pthread_rwlock_rdlock(&rwlock);

@ -30,6 +30,7 @@ public:
void write_sdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t sdu) override { last_sdu = std::move(sdu); } void write_sdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t sdu) override { last_sdu = std::move(sdu); }
bool has_bearer(uint16_t rnti, uint32_t lcid) override { return false; } bool has_bearer(uint16_t rnti, uint32_t lcid) override { return false; }
bool suspend_bearer(uint16_t rnti, uint32_t lcid) override { return true; } bool suspend_bearer(uint16_t rnti, uint32_t lcid) override { return true; }
bool is_suspended(uint16_t rnti, uint32_t lcid) override { return false; }
bool resume_bearer(uint16_t rnti, uint32_t lcid) override { return true; } bool resume_bearer(uint16_t rnti, uint32_t lcid) override { return true; }
void reestablish(uint16_t rnti) override {} void reestablish(uint16_t rnti) override {}

@ -170,6 +170,8 @@ public:
bool sdu_queue_is_full(uint32_t lcid); bool sdu_queue_is_full(uint32_t lcid);
bool is_suspended(uint32_t lcid);
void set_as_security(const ttcn3_helpers::timing_info_t timing, void set_as_security(const ttcn3_helpers::timing_info_t timing,
const std::string cell_name, const std::string cell_name,
std::array<uint8_t, 32> k_rrc_enc_, std::array<uint8_t, 32> k_rrc_enc_,

@ -1191,6 +1191,11 @@ bool ttcn3_syssim::sdu_queue_is_full(uint32_t lcid)
return false; return false;
} }
bool ttcn3_syssim::is_suspended(uint32_t lcid)
{
return false;
}
void ttcn3_syssim::set_as_security(const ttcn3_helpers::timing_info_t timing, void ttcn3_syssim::set_as_security(const ttcn3_helpers::timing_info_t timing,
const std::string cell_name, const std::string cell_name,
std::array<uint8_t, 32> k_rrc_enc_, std::array<uint8_t, 32> k_rrc_enc_,

Loading…
Cancel
Save