nas/gw/rrc: make LCID for DRB dynamic

- add interface to RRC to allow NAS to query the DRB for a given
  EPS bearer id
- extend interface for NAS to setup GW to also pass LCID of bearer
- in NAS, use this new interface to pass actual LCID of the default
  DRB when creating the TUN device
This commit is contained in:
Andre Puschmann 2019-06-05 14:56:30 +02:00
parent ded01a00fd
commit 3f613d7183
7 changed files with 48 additions and 15 deletions

View File

@ -102,7 +102,8 @@ public:
class gw_interface_nas class gw_interface_nas
{ {
public: public:
virtual srslte::error_t setup_if_addr(uint8_t pdn_type, uint32_t ip_addr, uint8_t *ipv6_if_id, char *err_str) = 0; virtual srslte::error_t
setup_if_addr(uint32_t lcid, uint8_t pdn_type, uint32_t ip_addr, uint8_t* ipv6_if_id, char* err_str) = 0;
}; };
// GW interface for RRC // GW interface for RRC
@ -202,6 +203,7 @@ public:
virtual void set_ue_idenity(asn1::rrc::s_tmsi_s s_tmsi) = 0; virtual void set_ue_idenity(asn1::rrc::s_tmsi_s s_tmsi) = 0;
virtual bool is_connected() = 0; virtual bool is_connected() = 0;
virtual std::string get_rb_name(uint32_t lcid) = 0; virtual std::string get_rb_name(uint32_t lcid) = 0;
virtual uint32_t get_lcid_for_eps_bearer(const uint32_t& eps_bearer_id) = 0;
}; };
// RRC interface for PDCP // RRC interface for PDCP

View File

@ -675,6 +675,7 @@ private:
void add_srb(asn1::rrc::srb_to_add_mod_s* srb_cnfg); void add_srb(asn1::rrc::srb_to_add_mod_s* srb_cnfg);
void add_drb(asn1::rrc::drb_to_add_mod_s* drb_cnfg); void add_drb(asn1::rrc::drb_to_add_mod_s* drb_cnfg);
void release_drb(uint32_t drb_id); void release_drb(uint32_t drb_id);
uint32_t get_lcid_for_eps_bearer(const uint32_t& eps_bearer_id);
void add_mrb(uint32_t lcid, uint32_t port); void add_mrb(uint32_t lcid, uint32_t port);
// Helpers for setting default values // Helpers for setting default values

View File

@ -58,7 +58,8 @@ public:
void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t pdu); void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t pdu);
// NAS interface // NAS interface
srslte::error_t setup_if_addr(uint8_t pdn_type, uint32_t ip_addr, uint8_t* ipv6_if_addr, char *err_str); srslte::error_t
setup_if_addr(uint32_t lcid, uint8_t pdn_type, uint32_t ip_addr, uint8_t* ipv6_if_addr, char* err_str);
// RRC interface // RRC interface
void add_mch_port(uint32_t lcid, uint32_t port); void add_mch_port(uint32_t lcid, uint32_t port);
@ -80,6 +81,7 @@ private:
struct ifreq ifr; struct ifreq ifr;
int32_t sock; int32_t sock;
bool if_up; bool if_up;
uint32_t default_lcid = 0;
uint32_t current_ip_addr; uint32_t current_ip_addr;
uint8_t current_if_id[8]; uint8_t current_if_id[8];

View File

@ -3049,6 +3049,17 @@ void rrc::release_drb(uint32_t drb_id)
} }
} }
uint32_t rrc::get_lcid_for_eps_bearer(const uint32_t& eps_bearer_id)
{
// check if this bearer id exists and return it's LCID
for (auto& drb : drbs) {
if (drb.second.eps_bearer_id == eps_bearer_id) {
return drb.first;
}
}
return 0;
}
void rrc::add_mrb(uint32_t lcid, uint32_t port) void rrc::add_mrb(uint32_t lcid, uint32_t port)
{ {
gw->add_mch_port(lcid, port); gw->add_mch_port(lcid, port);

View File

@ -67,9 +67,7 @@ struct in6_ifreq {
namespace srsue { namespace srsue {
#define DRB1_LCID 3 gw::gw() : if_up(false), default_lcid(0), thread("GW")
gw::gw() : if_up(false), thread("GW")
{ {
current_ip_addr = 0; current_ip_addr = 0;
} }
@ -198,7 +196,8 @@ void gw::write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t pdu)
/******************************************************************************* /*******************************************************************************
NAS interface NAS interface
*******************************************************************************/ *******************************************************************************/
srslte::error_t gw::setup_if_addr(uint8_t pdn_type, uint32_t ip_addr, uint8_t *ipv6_if_addr, char *err_str) srslte::error_t
gw::setup_if_addr(uint32_t lcid, uint8_t pdn_type, uint32_t ip_addr, uint8_t* ipv6_if_addr, char* err_str)
{ {
srslte::error_t err; srslte::error_t err;
if(pdn_type == LIBLTE_MME_PDN_TYPE_IPV4 || pdn_type == LIBLTE_MME_PDN_TYPE_IPV4V6 ){ if(pdn_type == LIBLTE_MME_PDN_TYPE_IPV4 || pdn_type == LIBLTE_MME_PDN_TYPE_IPV4V6 ){
@ -214,6 +213,8 @@ srslte::error_t gw::setup_if_addr(uint8_t pdn_type, uint32_t ip_addr, uint8_t *i
} }
} }
default_lcid = lcid;
// Setup a thread to receive packets from the TUN device // Setup a thread to receive packets from the TUN device
start(GW_THREAD_PRIO); start(GW_THREAD_PRIO);
return srslte::ERROR_NONE; return srslte::ERROR_NONE;
@ -280,10 +281,10 @@ void gw::run_thread()
if (pkt_len == pdu->N_bytes) { if (pkt_len == pdu->N_bytes) {
gw_log->info_hex(pdu->msg, pdu->N_bytes, "TX PDU"); gw_log->info_hex(pdu->msg, pdu->N_bytes, "TX PDU");
while (run_enable && !pdcp->is_lcid_enabled(DRB1_LCID) && attach_wait < ATTACH_WAIT_TOUT) { while (run_enable && !pdcp->is_lcid_enabled(default_lcid) && attach_wait < ATTACH_WAIT_TOUT) {
if (!attach_wait) { if (!attach_wait) {
gw_log->info( gw_log->info(
"LCID=%d not active, requesting NAS attach (%d/%d)\n", DRB1_LCID, attach_wait, ATTACH_WAIT_TOUT); "LCID=%d not active, requesting NAS attach (%d/%d)\n", default_lcid, attach_wait, ATTACH_WAIT_TOUT);
if (!nas->attach_request()) { if (!nas->attach_request()) {
gw_log->warning("Could not re-establish the connection\n"); gw_log->warning("Could not re-establish the connection\n");
} }
@ -299,10 +300,10 @@ void gw::run_thread()
} }
// Send PDU directly to PDCP // Send PDU directly to PDCP
if (pdcp->is_lcid_enabled(DRB1_LCID)) { if (pdcp->is_lcid_enabled(default_lcid)) {
pdu->set_timestamp(); pdu->set_timestamp();
ul_tput_bytes += pdu->N_bytes; ul_tput_bytes += pdu->N_bytes;
pdcp->write_sdu(DRB1_LCID, std::move(pdu), false); pdcp->write_sdu(default_lcid, std::move(pdu), false);
do { do {
pdu = srslte::allocate_unique_buffer(*pool); pdu = srslte::allocate_unique_buffer(*pool);
if (!pdu) { if (!pdu) {

View File

@ -722,7 +722,11 @@ void nas::parse_attach_accept(uint32_t lcid, unique_byte_buffer_t pdu)
// Setup GW // Setup GW
char *err_str = NULL; char *err_str = NULL;
if (gw->setup_if_addr(LIBLTE_MME_PDN_TYPE_IPV4, ip_addr, NULL, err_str)) { if (gw->setup_if_addr(rrc->get_lcid_for_eps_bearer(act_def_eps_bearer_context_req.eps_bearer_id),
LIBLTE_MME_PDN_TYPE_IPV4,
ip_addr,
NULL,
err_str)) {
nas_log->error("Failed to set gateway address - %s\n", err_str); nas_log->error("Failed to set gateway address - %s\n", err_str);
} }
} else if (LIBLTE_MME_PDN_TYPE_IPV6 == act_def_eps_bearer_context_req.pdn_addr.pdn_type){ } else if (LIBLTE_MME_PDN_TYPE_IPV6 == act_def_eps_bearer_context_req.pdn_addr.pdn_type){
@ -749,7 +753,11 @@ void nas::parse_attach_accept(uint32_t lcid, unique_byte_buffer_t pdu)
act_def_eps_bearer_context_req.pdn_addr.addr[7]); act_def_eps_bearer_context_req.pdn_addr.addr[7]);
// Setup GW // Setup GW
char *err_str = NULL; char *err_str = NULL;
if (gw->setup_if_addr(LIBLTE_MME_PDN_TYPE_IPV6, 0, ipv6_if_id, err_str)) { if (gw->setup_if_addr(rrc->get_lcid_for_eps_bearer(act_def_eps_bearer_context_req.eps_bearer_id),
LIBLTE_MME_PDN_TYPE_IPV6,
0,
ipv6_if_id,
err_str)) {
nas_log->error("Failed to set gateway address - %s\n", err_str); nas_log->error("Failed to set gateway address - %s\n", err_str);
} }
} else if (LIBLTE_MME_PDN_TYPE_IPV4V6 == act_def_eps_bearer_context_req.pdn_addr.pdn_type){ } else if (LIBLTE_MME_PDN_TYPE_IPV4V6 == act_def_eps_bearer_context_req.pdn_addr.pdn_type){
@ -794,7 +802,11 @@ void nas::parse_attach_accept(uint32_t lcid, unique_byte_buffer_t pdu)
act_def_eps_bearer_context_req.pdn_addr.addr[11]); act_def_eps_bearer_context_req.pdn_addr.addr[11]);
char *err_str = NULL; char *err_str = NULL;
if (gw->setup_if_addr(LIBLTE_MME_PDN_TYPE_IPV4V6, ip_addr, ipv6_if_id, err_str)) { if (gw->setup_if_addr(rrc->get_lcid_for_eps_bearer(act_def_eps_bearer_context_req.eps_bearer_id),
LIBLTE_MME_PDN_TYPE_IPV4V6,
ip_addr,
ipv6_if_id,
err_str)) {
nas_log->error("Failed to set gateway address - %s\n", err_str); nas_log->error("Failed to set gateway address - %s\n", err_str);
} }
} else { } else {

View File

@ -130,6 +130,7 @@ public:
uint16_t get_mcc() { return mcc; } uint16_t get_mcc() { return mcc; }
uint16_t get_mnc() { return mnc; } uint16_t get_mnc() { return mnc; }
void enable_capabilities() {} void enable_capabilities() {}
uint32_t get_lcid_for_eps_bearer(const uint32_t& eps_bearer_id) { return 0; }
private: private:
uint32_t last_sdu_len; uint32_t last_sdu_len;
@ -138,7 +139,10 @@ private:
class gw_dummy : public gw_interface_nas, public gw_interface_pdcp class gw_dummy : public gw_interface_nas, public gw_interface_pdcp
{ {
error_t setup_if_addr(uint8_t pdn_type, uint32_t ip_addr, uint8_t *ipv6_if_id, char *err_str) { return ERROR_NONE; } error_t setup_if_addr(uint32_t lcid, uint8_t pdn_type, uint32_t ip_addr, uint8_t* ipv6_if_id, char* err_str)
{
return ERROR_NONE;
}
void write_pdu(uint32_t lcid, unique_byte_buffer_t pdu) {} void write_pdu(uint32_t lcid, unique_byte_buffer_t pdu) {}
void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t sdu) {} void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t sdu) {}
}; };