Commit 71b5eb69 authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

Merge branch 'static_ue_ip_addr' into 'develop'

Static ue ip addr

See merge request oai/cn5g/oai-cn5g-smf!96
parents 52700d25 885f0f3e
......@@ -318,6 +318,18 @@ typedef struct pdu_session_type_s {
pdu_session_type_s(const uint8_t& p) : pdu_session_type(p) {}
pdu_session_type_s(const struct pdu_session_type_s& p)
: pdu_session_type(p.pdu_session_type) {}
pdu_session_type_s(const std::string& s) {
if (s.compare("IPV4") == 0) {
pdu_session_type = pdu_session_type_e::PDU_SESSION_TYPE_E_IPV4;
} else if (s.compare("IPV6") == 0) {
pdu_session_type = pdu_session_type_e::PDU_SESSION_TYPE_E_IPV6;
} else if (s.compare("IPV4V6") == 0) {
pdu_session_type = pdu_session_type_e::PDU_SESSION_TYPE_E_IPV4V6;
} else {
pdu_session_type =
pdu_session_type_e::PDU_SESSION_TYPE_E_IPV4; // Default value
}
}
bool operator==(const struct pdu_session_type_s& p) const {
return (p.pdu_session_type == pdu_session_type);
}
......@@ -329,6 +341,7 @@ typedef struct pdu_session_type_s {
const std::string& toString() const {
return pdu_session_type_e2str.at(pdu_session_type);
}
} pdu_session_type_t;
//-------------------------------------
......
......@@ -142,15 +142,6 @@ struct imsi_s {
};
typedef struct imsi_s imsi_t;
//-------------------------------------
// 8.9 IP Address
typedef struct ip_address_s {
bool is_ipv4; // if not ipv4, then it is ipv6
union {
struct in_addr ipv4_address;
struct in6_addr ipv6_address;
} address;
} ip_address_t;
//-------------------------------------
// 8.10 Mobile Equipment Identity (MEI)
// The ME Identity field contains either the IMEI or the IMEISV as defined in
......
......@@ -38,6 +38,26 @@ typedef struct ssc_mode_s {
ssc_mode_s() : ssc_mode(SSC_MODE_1) {}
ssc_mode_s(ssc_mode_e mode) : ssc_mode(mode) {}
ssc_mode_s(const struct ssc_mode_s& p) : ssc_mode(p.ssc_mode) {}
ssc_mode_s(const std::string& s) {
if (s.compare("SSC_MODE_1") == 0) {
ssc_mode = ssc_mode_e::SSC_MODE_1;
} else if (s.compare("SSC_MODE_2") == 0) {
ssc_mode = ssc_mode_e::SSC_MODE_2;
} else if (s.compare("SSC_MODE_3") == 0) {
ssc_mode = ssc_mode_e::SSC_MODE_3;
} else {
ssc_mode = ssc_mode_e::SSC_MODE_1; // default mode
}
}
ssc_mode_s& operator=(const ssc_mode_s& s) {
ssc_mode = s.ssc_mode;
return *this;
}
virtual ~ssc_mode_s(){};
} ssc_mode_t;
typedef struct pdu_session_types_s {
......@@ -50,12 +70,133 @@ typedef struct ssc_modes_s {
std::vector<ssc_mode_t> allowed_ssc_modes;
} ssc_modes_t;
enum ip_address_type_value_e {
IP_ADDRESS_TYPE_IPV4_ADDRESS = 0,
IP_ADDRESS_TYPE_IPV6_ADDRESS = 1,
IP_ADDRESS_TYPE_IPV6_PREFIX = 2
};
typedef struct ipv6_prefix_s {
struct in6_addr prefix;
uint8_t prefix_len;
std::string to_string() const {
return conv::toString(prefix) + "/" + std::to_string(prefix_len);
}
} ipv6_prefix_t;
typedef struct ip_address_s {
uint8_t ip_address_type;
union {
struct in_addr ipv4_address;
struct in6_addr ipv6_address;
ipv6_prefix_t ipv6_prefix;
} u1;
bool operator==(const struct ip_address_s& i) const {
if ((i.ip_address_type == this->ip_address_type) &&
(i.u1.ipv4_address.s_addr == this->u1.ipv4_address.s_addr) &&
(i.u1.ipv6_address.s6_addr32[0] ==
this->u1.ipv6_address.s6_addr32[0]) &&
(i.u1.ipv6_address.s6_addr32[1] ==
this->u1.ipv6_address.s6_addr32[1]) &&
(i.u1.ipv6_address.s6_addr32[2] ==
this->u1.ipv6_address.s6_addr32[2]) &&
(i.u1.ipv6_address.s6_addr32[3] ==
this->u1.ipv6_address.s6_addr32[3]) &&
(i.u1.ipv6_prefix.prefix_len == this->u1.ipv6_prefix.prefix_len) &&
(i.u1.ipv6_prefix.prefix.s6_addr32[0] ==
this->u1.ipv6_prefix.prefix.s6_addr32[0]) &&
(i.u1.ipv6_prefix.prefix.s6_addr32[1] ==
this->u1.ipv6_prefix.prefix.s6_addr32[1]) &&
(i.u1.ipv6_prefix.prefix.s6_addr32[2] ==
this->u1.ipv6_prefix.prefix.s6_addr32[2]) &&
(i.u1.ipv6_prefix.prefix.s6_addr32[3] ==
this->u1.ipv6_prefix.prefix.s6_addr32[3])) {
return true;
} else {
return false;
}
};
bool operator==(const struct in_addr& a) const {
if ((IP_ADDRESS_TYPE_IPV4_ADDRESS == this->ip_address_type) &&
(a.s_addr == u1.ipv4_address.s_addr)) {
return true;
} else {
return false;
}
};
bool operator==(const struct in6_addr& i) const {
if ((IP_ADDRESS_TYPE_IPV6_ADDRESS == this->ip_address_type) &&
(i.s6_addr32[0] == this->u1.ipv6_address.s6_addr32[0]) &&
(i.s6_addr32[1] == this->u1.ipv6_address.s6_addr32[1]) &&
(i.s6_addr32[2] == this->u1.ipv6_address.s6_addr32[2]) &&
(i.s6_addr32[3] == this->u1.ipv6_address.s6_addr32[3])) {
return true;
} else {
return false;
}
};
bool operator==(const ipv6_prefix_t& i) const {
if ((IP_ADDRESS_TYPE_IPV6_PREFIX == this->ip_address_type) &&
(i.prefix_len == this->u1.ipv6_prefix.prefix_len) &&
(i.prefix.s6_addr32[0] == this->u1.ipv6_prefix.prefix.s6_addr32[0]) &&
(i.prefix.s6_addr32[1] == this->u1.ipv6_prefix.prefix.s6_addr32[1]) &&
(i.prefix.s6_addr32[2] == this->u1.ipv6_prefix.prefix.s6_addr32[2]) &&
(i.prefix.s6_addr32[3] == this->u1.ipv6_prefix.prefix.s6_addr32[3])) {
return true;
} else {
return false;
}
};
ip_address_s& operator=(const struct in_addr& a) {
ip_address_type = IP_ADDRESS_TYPE_IPV4_ADDRESS;
u1.ipv4_address.s_addr = a.s_addr;
return *this;
}
ip_address_s& operator=(const struct in6_addr& a) {
ip_address_type = IP_ADDRESS_TYPE_IPV6_ADDRESS;
u1.ipv6_address.s6_addr32[0] = a.s6_addr32[0];
u1.ipv6_address.s6_addr32[1] = a.s6_addr32[1];
u1.ipv6_address.s6_addr32[2] = a.s6_addr32[2];
u1.ipv6_address.s6_addr32[3] = a.s6_addr32[3];
return *this;
}
ip_address_s& operator=(const ipv6_prefix_t& a) {
ip_address_type = IP_ADDRESS_TYPE_IPV6_PREFIX;
u1.ipv6_prefix.prefix_len = a.prefix_len;
u1.ipv6_prefix.prefix.s6_addr32[0] = a.prefix.s6_addr32[0];
u1.ipv6_prefix.prefix.s6_addr32[1] = a.prefix.s6_addr32[1];
u1.ipv6_prefix.prefix.s6_addr32[2] = a.prefix.s6_addr32[2];
u1.ipv6_prefix.prefix.s6_addr32[3] = a.prefix.s6_addr32[3];
return *this;
}
virtual ~ip_address_s(){};
std::string to_string() const {
if (IP_ADDRESS_TYPE_IPV4_ADDRESS == this->ip_address_type) {
return conv::toString(u1.ipv4_address);
} else if (IP_ADDRESS_TYPE_IPV6_ADDRESS == this->ip_address_type) {
return conv::toString(u1.ipv6_address);
} else if (IP_ADDRESS_TYPE_IPV6_PREFIX == this->ip_address_type) {
return u1.ipv6_prefix.to_string();
}
return std::string("Unknown IP Address Type");
}
} ip_address_t;
typedef struct dnn_configuration_s {
pdu_session_types_t pdu_session_types;
ssc_modes_t ssc_modes;
session_ambr_t session_ambr;
subscribed_default_qos_t _5g_qos_profile;
// staticIpAddresses
std::vector<ip_address_t> static_ip_addresses;
} dnn_configuration_t;
#endif
......@@ -701,8 +701,8 @@ void smf_app::handle_pdu_session_create_sm_context_request(
std::string n1_sm_message, n1_sm_message_hex;
nas_message_t decoded_nas_msg = {};
cause_value_5gsm_e cause_n1 = {cause_value_5gsm_e::CAUSE_0_UNKNOWN};
pdu_session_type_t pdu_session_type = {
.pdu_session_type = PDU_SESSION_TYPE_E_IPV4};
pdu_session_type_t pdu_session_type = {.pdu_session_type =
PDU_SESSION_TYPE_E_IPV4};
// Step 1. Decode NAS and get the necessary information
int decoder_rc = smf_n1::get_instance().decode_n1_sm_container(
......@@ -907,6 +907,7 @@ void smf_app::handle_pdu_session_create_sm_context_request(
sc.get()->set_supi(supi);
sc.get()->set_supi_prefix(supi_prefix);
set_supi_2_smf_context(supi64, sc);
sc.get()->set_plmn(smreq->req.get_plmn()); // PLMN
}
// Step 5. Create/update context with dnn information
......@@ -954,7 +955,9 @@ void smf_app::handle_pdu_session_create_sm_context_request(
if (not use_local_configuration_subscription_data(dnn_selection_mode)) {
Logger::smf_app().debug(
"Retrieve Session Management Subscription data from the UDM");
if (smf_sbi_inst->get_sm_data(supi64, dnn, snssai, subscription)) {
plmn_t plmn = {};
sc.get()->get_plmn(plmn);
if (smf_sbi_inst->get_sm_data(supi64, dnn, snssai, subscription, plmn)) {
// Update dnn_context with subscription info
sc.get()->insert_dnn_subscription(snssai, dnn, subscription);
} else {
......@@ -996,9 +999,6 @@ void smf_app::handle_pdu_session_create_sm_context_request(
}
}
// Store PLMN
sc.get()->set_plmn(smreq->req.get_plmn());
// Step 8. Generate a SMF context Id and store the corresponding information
// in a map (SM_Context_ID, (supi, dnn, nssai, pdu_session_id))
scid_t scid = generate_smf_context_ref();
......
......@@ -1366,27 +1366,63 @@ void smf_context::handle_pdu_session_create_sm_context_request(
bool set_paa = false;
paa_t paa = {};
Logger::smf_app().debug("UE Address Allocation");
bool paa_static_ip = false;
std::shared_ptr<session_management_subscription> ss = {};
std::shared_ptr<dnn_configuration_t> sdc = {};
find_dnn_subscription(snssai, ss);
if (nullptr != ss.get()) {
ss.get()->find_dnn_configuration(sd->dnn_in_use, sdc);
if (nullptr != sdc.get()) {
paa.pdu_session_type.pdu_session_type =
sdc.get()
->pdu_session_types.default_session_type
.pdu_session_type; // TODO: Verified if use default session
// type or requested session type
// Static IP address allocation
for (auto addr : sdc.get()->static_ip_addresses) {
if ((sp->pdu_session_type.pdu_session_type ==
PDU_SESSION_TYPE_E_IPV4V6) or
(sp->pdu_session_type.pdu_session_type ==
PDU_SESSION_TYPE_E_IPV4)) {
if (addr.ip_address_type == IP_ADDRESS_TYPE_IPV4_ADDRESS) {
Logger::smf_app().debug(
"Static IP Address with IPv4 %s",
inet_ntoa(*((struct in_addr*) &addr.u1.ipv4_address)));
paa.ipv4_address.s_addr = addr.u1.ipv4_address.s_addr;
paa.pdu_session_type = pdu_session_type_e::PDU_SESSION_TYPE_E_IPV4;
set_paa = true;
paa_static_ip = true;
}
} else if (
sp->pdu_session_type.pdu_session_type == PDU_SESSION_TYPE_E_IPV6) {
paa.pdu_session_type = pdu_session_type_e::PDU_SESSION_TYPE_E_IPV6;
if (addr.ip_address_type == IP_ADDRESS_TYPE_IPV6_ADDRESS) {
paa.ipv6_address = addr.u1.ipv6_address;
} else if (addr.ip_address_type == IP_ADDRESS_TYPE_IPV6_PREFIX) {
paa.ipv6_address = addr.u1.ipv6_prefix.prefix;
// TODO: prefix length
}
char str_addr6[INET6_ADDRSTRLEN];
if (inet_ntop(
AF_INET6, &paa.ipv6_address, str_addr6, sizeof(str_addr6))) {
Logger::smf_app().debug(
"Static IP Address with IPv6 %s", str_addr6);
}
set_paa = true;
paa_static_ip = true;
}
}
}
}
switch (sp->pdu_session_type.pdu_session_type) {
case PDU_SESSION_TYPE_E_IPV4V6: {
Logger::smf_app().debug(
"PDU Session Type IPv4v6, select PDU Session Type IPv4");
bool paa_res = false;
// TODO: Verify if use default session type or requested session type
std::shared_ptr<session_management_subscription> ss = {};
std::shared_ptr<dnn_configuration_t> sdc = {};
find_dnn_subscription(snssai, ss);
if (nullptr != ss.get()) {
ss.get()->find_dnn_configuration(sd->dnn_in_use, sdc);
if (nullptr != sdc.get()) {
paa.pdu_session_type.pdu_session_type =
sdc.get()
->pdu_session_types.default_session_type.pdu_session_type;
}
}
// TODO: use requested PDU Session Type?
// paa.pdu_session_type.pdu_session_type = PDU_SESSION_TYPE_E_IPV4V6;
if ((not paa_res) || (not paa.is_ip_assigned())) {
if ((not paa_static_ip) || (not paa.is_ip_assigned())) {
bool success =
paa_dynamic::get_instance().get_free_paa(sd->dnn_in_use, paa);
if (success) {
......@@ -1398,8 +1434,7 @@ void smf_context::handle_pdu_session_create_sm_context_request(
sm_context_resp_pending->res.set_cause(static_cast<uint8_t>(
cause_value_5gsm_e::CAUSE_26_INSUFFICIENT_RESOURCES));
}
// TODO: Static IP address allocation
} else if ((paa_res) && (paa.is_ip_assigned())) {
} else if ((paa_static_ip) && (paa.is_ip_assigned())) {
set_paa = true;
}
Logger::smf_app().info(
......@@ -1417,30 +1452,7 @@ void smf_context::handle_pdu_session_create_sm_context_request(
Logger::smf_app().debug("PDU Session Type IPv4");
if (!pco_ids.ci_ipv4_address_allocation_via_dhcpv4) {
// use SM NAS signalling
// static or dynamic address allocation
bool paa_res = false; // how to define static or dynamic
// depend of subscription information: staticIpAddress in DNN
// Configuration
// TODO: check static IP address is available in the subscription
// information (SessionManagementSubscription) or in DHCP/DN-AAA
std::shared_ptr<session_management_subscription> ss = {};
std::shared_ptr<dnn_configuration_t> sdc = {};
find_dnn_subscription(snssai, ss);
if (nullptr != ss.get()) {
ss.get()->find_dnn_configuration(sd->dnn_in_use, sdc);
if (nullptr != sdc.get()) {
paa.pdu_session_type.pdu_session_type =
sdc.get()
->pdu_session_types.default_session_type
.pdu_session_type; // TODO: Verified if use default session
// type or requested session type
// TODO: static ip address
}
}
if ((not paa_res) || (not paa.is_ip_assigned())) {
if ((not paa_static_ip) || (not paa.is_ip_assigned())) {
bool success =
paa_dynamic::get_instance().get_free_paa(sd->dnn_in_use, paa);
if (success) {
......@@ -1452,8 +1464,8 @@ void smf_context::handle_pdu_session_create_sm_context_request(
sm_context_resp_pending->res.set_cause(static_cast<uint8_t>(
cause_value_5gsm_e::CAUSE_26_INSUFFICIENT_RESOURCES));
}
// Static IP address allocation
} else if ((paa_res) && (paa.is_ip_assigned())) {
} else if ((paa_static_ip) && (paa.is_ip_assigned())) {
set_paa = true;
}
Logger::smf_app().info(
......
This diff is collapsed.
......@@ -157,7 +157,8 @@ class smf_sbi {
*/
bool get_sm_data(
const supi64_t& supi, const std::string& dnn, const snssai_t& snssai,
std::shared_ptr<session_management_subscription> subscription);
std::shared_ptr<session_management_subscription>& subscription,
plmn_t plmn = {});
/*
* Subscribe to be notify from UDM
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment