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
{
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
@ -202,6 +203,7 @@ public:
virtual void set_ue_idenity(asn1::rrc::s_tmsi_s s_tmsi) = 0;
virtual bool is_connected() = 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

View File

@ -675,6 +675,7 @@ private:
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 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);
// 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);
// 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
void add_mch_port(uint32_t lcid, uint32_t port);
@ -80,6 +81,7 @@ private:
struct ifreq ifr;
int32_t sock;
bool if_up;
uint32_t default_lcid = 0;
uint32_t current_ip_addr;
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)
{
gw->add_mch_port(lcid, port);

View File

@ -67,9 +67,7 @@ struct in6_ifreq {
namespace srsue {
#define DRB1_LCID 3
gw::gw() : if_up(false), thread("GW")
gw::gw() : if_up(false), default_lcid(0), thread("GW")
{
current_ip_addr = 0;
}
@ -198,7 +196,8 @@ void gw::write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t pdu)
/*******************************************************************************
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;
if(pdn_type == LIBLTE_MME_PDN_TYPE_IPV4 || pdn_type == LIBLTE_MME_PDN_TYPE_IPV4V6 ){
@ -213,7 +212,9 @@ srslte::error_t gw::setup_if_addr(uint8_t pdn_type, uint32_t ip_addr, uint8_t *i
return err;
}
}
default_lcid = lcid;
// Setup a thread to receive packets from the TUN device
start(GW_THREAD_PRIO);
return srslte::ERROR_NONE;
@ -280,10 +281,10 @@ void gw::run_thread()
if (pkt_len == pdu->N_bytes) {
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) {
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()) {
gw_log->warning("Could not re-establish the connection\n");
}
@ -299,10 +300,10 @@ void gw::run_thread()
}
// Send PDU directly to PDCP
if (pdcp->is_lcid_enabled(DRB1_LCID)) {
if (pdcp->is_lcid_enabled(default_lcid)) {
pdu->set_timestamp();
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 {
pdu = srslte::allocate_unique_buffer(*pool);
if (!pdu) {

View File

@ -722,7 +722,11 @@ void nas::parse_attach_accept(uint32_t lcid, unique_byte_buffer_t pdu)
// Setup GW
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);
}
} 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]);
// Setup GW
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);
}
} 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]);
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);
}
} else {

View File

@ -130,6 +130,7 @@ public:
uint16_t get_mcc() { return mcc; }
uint16_t get_mnc() { return mnc; }
void enable_capabilities() {}
uint32_t get_lcid_for_eps_bearer(const uint32_t& eps_bearer_id) { return 0; }
private:
uint32_t last_sdu_len;
@ -138,7 +139,10 @@ private:
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_mch(uint32_t lcid, srslte::unique_byte_buffer_t sdu) {}
};