Commit 0dba68d6 authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

Merge branch 'support-phone' into 'develop'

Support phone

See merge request oai/cn5g/oai-cn5g-smf!52
parents 678b126f 8b872ed6
...@@ -133,6 +133,7 @@ bool conv::plmnFromString( ...@@ -133,6 +133,7 @@ bool conv::plmnFromString(
p.mcc_digit3 = mcc[2] - '0'; p.mcc_digit3 = mcc[2] - '0';
else else
return false; return false;
// MNC // MNC
if (isdigit(mnc[0])) if (isdigit(mnc[0]))
p.mnc_digit1 = mnc[0] - '0'; p.mnc_digit1 = mnc[0] - '0';
...@@ -147,6 +148,8 @@ bool conv::plmnFromString( ...@@ -147,6 +148,8 @@ bool conv::plmnFromString(
p.mnc_digit3 = mnc[2] - '0'; p.mnc_digit3 = mnc[2] - '0';
else else
return false; return false;
} else {
p.mnc_digit3 = 0x0;
} }
return true; return true;
} }
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <iostream> #include <iostream>
#include "epc.h" #include "epc.h"
#include "conversions.h"
using namespace EPC; using namespace EPC;
...@@ -49,6 +50,29 @@ std::string Utility::home_network_gprs(const char* mnc, const char* mcc) { ...@@ -49,6 +50,29 @@ std::string Utility::home_network_gprs(const char* mnc, const char* mcc) {
return s; return s;
} }
std::string Utility::home_network_gprs(const plmn_t& plmn) {
// '.mnc(\d{3})\.mcc(\d{3})\.gprs'
std::string s;
uint16_t mcc = 0;
uint16_t mnc = 0;
uint16_t mnc_len = 0;
mcc = plmn.mcc_digit1 * 100 + plmn.mcc_digit2 * 10 + plmn.mcc_digit3;
mnc_len = (plmn.mnc_digit3 == 0x0 ? 2 : 3);
mnc = plmn.mnc_digit1 * 10 + plmn.mnc_digit2;
mnc = (mnc_len == 2 ? mnc : mnc * 10 + plmn.mnc_digit3);
s.append(".mnc");
if (mnc_len == 2) s.append("0");
s.append(std::to_string(mnc));
s.append(".mcc");
s.append(std::to_string(mcc));
s.append(".gprs");
return s;
}
std::string Utility::home_network_gprs(const unsigned char* plmnid) { std::string Utility::home_network_gprs(const unsigned char* plmnid) {
PARSE_PLMNID(plmnid); PARSE_PLMNID(plmnid);
return home_network_gprs(mnc, mcc); return home_network_gprs(mnc, mcc);
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <sstream> #include <sstream>
#include <list> #include <list>
#include <vector> #include <vector>
#include "3gpp_23.003.h"
/* /*
MCC digit 1 - low order nibble octet 1 MCC digit 1 - low order nibble octet 1
...@@ -82,6 +83,7 @@ class Utility { ...@@ -82,6 +83,7 @@ class Utility {
static std::string home_network(const char* mnc, const char* mcc); static std::string home_network(const char* mnc, const char* mcc);
static std::string home_network(const unsigned char* plmnid); static std::string home_network(const unsigned char* plmnid);
static std::string home_network_gprs(const char* mnc, const char* mcc); static std::string home_network_gprs(const char* mnc, const char* mcc);
static std::string home_network_gprs(const plmn_t& plmn);
static std::string home_network_gprs(const unsigned char* plmnid); static std::string home_network_gprs(const unsigned char* plmnid);
static std::string tai_fqdn( static std::string tai_fqdn(
const char* lb, const char* hb, const char* mnc, const char* mcc); const char* lb, const char* hb, const char* mnc, const char* mcc);
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
* contact@openairinterface.org * contact@openairinterface.org
*/ */
#include "string.hpp" #include "string.hpp"
#include "logger.hpp"
#include <stdarg.h> #include <stdarg.h>
#include <algorithm> #include <algorithm>
...@@ -94,13 +95,85 @@ void util::ipv4_to_bstring(struct in_addr ipv4_address, bstring str) { ...@@ -94,13 +95,85 @@ void util::ipv4_to_bstring(struct in_addr ipv4_address, bstring str) {
bitstream_addr[2] = (uint8_t)(((ipv4_address.s_addr) & 0x00ff0000) >> 16); bitstream_addr[2] = (uint8_t)(((ipv4_address.s_addr) & 0x00ff0000) >> 16);
bitstream_addr[3] = (uint8_t)(((ipv4_address.s_addr) & 0xff000000) >> 24); bitstream_addr[3] = (uint8_t)(((ipv4_address.s_addr) & 0xff000000) >> 24);
// str = bfromcstralloc(4, "\0"); // str = bfromcstralloc(4, "\0");
str->slen = 4; str->slen = 4;
memcpy(str->data, bitstream_addr, sizeof(bitstream_addr)); memcpy(str->data, bitstream_addr, sizeof(bitstream_addr));
} }
void util::ipv6_to_bstring(struct in6_addr ipv6_address, bstring str) {
char str_addr6[INET6_ADDRSTRLEN];
if (inet_ntop(AF_INET6, &ipv6_address, str_addr6, sizeof(str_addr6))) {
std::string ipv6_addr_str((char*) str_addr6, INET6_ADDRSTRLEN);
// Logger::smf_app().info(" Ipv6 address....: %s", ipv6_addr_str.c_str());
unsigned char buf_in6_addr[sizeof(struct in6_addr)];
if (inet_pton(AF_INET6, util::trim(ipv6_addr_str).c_str(), buf_in6_addr) ==
1) {
str->slen = 16;
memcpy(str->data, buf_in6_addr, sizeof(buf_in6_addr));
}
}
}
void util::ipv4v6_to_pdu_address_information(
struct in_addr ipv4_address, struct in6_addr ipv6_address, bstring str) {
unsigned char bitstream_addr[12];
char str_addr6[INET6_ADDRSTRLEN];
if (inet_ntop(AF_INET6, &ipv6_address, str_addr6, sizeof(str_addr6))) {
std::string ipv6_addr_str((char*) str_addr6, INET6_ADDRSTRLEN);
// Logger::smf_app().info(" Ipv6 address....: %s", ipv6_addr_str.c_str());
unsigned char buf_in6_addr[sizeof(struct in6_addr)];
if (inet_pton(AF_INET6, util::trim(ipv6_addr_str).c_str(), buf_in6_addr) ==
1) {
for (int i = 0; i <= 7; i++)
bitstream_addr[i] = (uint8_t)(buf_in6_addr[i]);
}
}
bitstream_addr[8] = (uint8_t)((ipv4_address.s_addr) & 0x000000ff);
bitstream_addr[9] = (uint8_t)(((ipv4_address.s_addr) & 0x0000ff00) >> 8);
bitstream_addr[10] = (uint8_t)(((ipv4_address.s_addr) & 0x00ff0000) >> 16);
bitstream_addr[11] = (uint8_t)(((ipv4_address.s_addr) & 0xff000000) >> 24);
str->slen = 12;
memcpy(str->data, bitstream_addr, sizeof(bitstream_addr));
}
void util::string_to_bstring(const std::string& str, bstring bstr) { void util::string_to_bstring(const std::string& str, bstring bstr) {
// bstr = bfromcstralloc(str.length(), "\0"); // bstr = bfromcstralloc(str.length(), "\0");
bstr->slen = str.length();
memcpy((void*) bstr->data, (void*) str.c_str(), str.length());
}
bool util::string_to_dotted(const std::string& str, std::string& dotted) {
uint8_t offset = 0;
uint8_t* last_size;
uint8_t word_length = 0;
uint8_t value[str.length() + 1];
dotted = {};
last_size = &value[0];
while (str[offset]) {
// We replace the . by the length of the word
if (str[offset] == '.') {
*last_size = word_length;
word_length = 0;
last_size = &value[offset + 1];
} else {
word_length++;
value[offset + 1] = str[offset];
}
offset++;
}
*last_size = word_length;
dotted.assign((const char*) value, str.length() + 1);
return true;
};
void util::string_to_dnn(const std::string& str, bstring bstr) {
bstr->slen = str.length(); bstr->slen = str.length();
memcpy((void*) bstr->data, (void*) str.c_str(), str.length()); memcpy((void*) bstr->data, (void*) str.c_str(), str.length());
} }
...@@ -47,6 +47,21 @@ std::string& trim(std::string& s); ...@@ -47,6 +47,21 @@ std::string& trim(std::string& s);
void ipv4_to_bstring(struct in_addr ipv4_address, bstring str); void ipv4_to_bstring(struct in_addr ipv4_address, bstring str);
void ipv6_to_bstring(struct in6_addr ipv6_address, bstring str);
/*
* Create a PDU Address Information in form of a bstring (byte 0-7: IPv6 prefix,
* 8-11: Ipv4 Address)
* @param [struct in_addr] ipv4_address: IPv4 address
* @param [struct in6_addr ] ipv6_address: IPv6 address
* @param [bstring] str: store the PDU Address Information
* @return void
*/
void ipv4v6_to_pdu_address_information(
struct in_addr ipv4_address, struct in6_addr ipv6_address, bstring str);
void string_to_bstring(const std::string& str, bstring bstr); void string_to_bstring(const std::string& str, bstring bstr);
bool string_to_dotted(const std::string& str, std::string& dotted);
void string_to_dnn(const std::string& str, bstring bstr);
} // namespace util } // namespace util
#endif #endif
...@@ -44,6 +44,7 @@ int encode_snssai(SNSSAI snssai, uint8_t iei, uint8_t* buffer, uint32_t len) { ...@@ -44,6 +44,7 @@ int encode_snssai(SNSSAI snssai, uint8_t iei, uint8_t* buffer, uint32_t len) {
} }
ielen = snssai.len; ielen = snssai.len;
ielen = 1;
*(buffer + encoded) = ielen; *(buffer + encoded) = ielen;
encoded++; encoded++;
......
...@@ -36,10 +36,10 @@ int encode__pdu_session_type( ...@@ -36,10 +36,10 @@ int encode__pdu_session_type(
buffer, _PDU_SESSION_TYPE_MINIMUM_LENGTH, len); buffer, _PDU_SESSION_TYPE_MINIMUM_LENGTH, len);
if (iei > 0) { if (iei > 0) {
bitStream |= (iei & 0xf0); bitStream |= (iei & 0xf0) ;
} }
bitStream |= (_pdusessiontype.pdu_session_type_value & 0x07); bitStream |= ((_pdusessiontype.pdu_session_type_value & 0x07) | 0x10);
ENCODE_U8(buffer + encoded, bitStream, encoded); ENCODE_U8(buffer + encoded, bitStream, encoded);
return encoded; return encoded;
......
...@@ -215,6 +215,7 @@ int encode_pdu_session_establishment_accept( ...@@ -215,6 +215,7 @@ int encode_pdu_session_establishment_accept(
CHECK_PDU_POINTER_AND_LENGTH_ENCODER( CHECK_PDU_POINTER_AND_LENGTH_ENCODER(
buffer, PDU_SESSION_ESTABLISHMENT_ACCEPT_MINIMUM_LENGTH, len); buffer, PDU_SESSION_ESTABLISHMENT_ACCEPT_MINIMUM_LENGTH, len);
if ((encoded_result = encode__pdu_session_type( if ((encoded_result = encode__pdu_session_type(
pdu_session_establishment_accept->_pdusessiontype, 0, pdu_session_establishment_accept->_pdusessiontype, 0,
buffer + encoded, len - encoded)) < 0) buffer + encoded, len - encoded)) < 0)
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include "smf_app.hpp" #include "smf_app.hpp"
#include <boost/uuid/random_generator.hpp> #include <boost/uuid/random_generator.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/uuid/uuid_io.hpp> #include <boost/uuid/uuid_io.hpp>
#include <cstdlib> #include <cstdlib>
#include <iostream> #include <iostream>
...@@ -81,6 +82,7 @@ void smf_app_task(void*); ...@@ -81,6 +82,7 @@ void smf_app_task(void*);
int smf_app::apply_config(const smf_config& cfg) { int smf_app::apply_config(const smf_config& cfg) {
Logger::smf_app().info("Apply config..."); Logger::smf_app().info("Apply config...");
paa_t paa = {};
for (int ia = 0; ia < cfg.num_dnn; ia++) { for (int ia = 0; ia < cfg.num_dnn; ia++) {
if (cfg.dnn[ia].pool_id_iv4 >= 0) { if (cfg.dnn[ia].pool_id_iv4 >= 0) {
int pool_id = cfg.dnn[ia].pool_id_iv4; int pool_id = cfg.dnn[ia].pool_id_iv4;
...@@ -90,13 +92,18 @@ int smf_app::apply_config(const smf_config& cfg) { ...@@ -90,13 +92,18 @@ int smf_app::apply_config(const smf_config& cfg) {
cfg.dnn[ia].dnn, pool_id, cfg.ue_pool_range_low[pool_id], range); cfg.dnn[ia].dnn, pool_id, cfg.ue_pool_range_low[pool_id], range);
// TODO: check with dnn_label // TODO: check with dnn_label
Logger::smf_app().info("Applied config %s", cfg.dnn[ia].dnn.c_str()); Logger::smf_app().info("Applied config %s", cfg.dnn[ia].dnn.c_str());
paa.ipv4_address = cfg.ue_pool_range_low[pool_id];
} }
if (cfg.dnn[ia].pool_id_iv6 >= 0) { if (cfg.dnn[ia].pool_id_iv6 >= 0) {
int pool_id = cfg.dnn[ia].pool_id_iv6; int pool_id = cfg.dnn[ia].pool_id_iv6;
paa_dynamic::get_instance().add_pool( paa_dynamic::get_instance().add_pool(
cfg.dnn[ia].dnn, pool_id, cfg.paa_pool6_prefix[pool_id], cfg.dnn[ia].dnn, pool_id, cfg.paa_pool6_prefix[pool_id],
cfg.paa_pool6_prefix_len[pool_id]); cfg.paa_pool6_prefix_len[pool_id]);
paa.ipv6_address = cfg.paa_pool6_prefix[pool_id];
// TODO: check with dnn_label // TODO: check with dnn_label
Logger::smf_app().info(
"Applied config for IPv6 %s", cfg.dnn[ia].dnn.c_str());
} }
} }
...@@ -506,7 +513,7 @@ void smf_app::handle_itti_msg(std::shared_ptr<itti_n4_node_failure> snf) { ...@@ -506,7 +513,7 @@ void smf_app::handle_itti_msg(std::shared_ptr<itti_n4_node_failure> snf) {
"Remove the associated PDU session (SUPI " SUPI_64_FMT "Remove the associated PDU session (SUPI " SUPI_64_FMT
", PDU Sessin Id %d)", ", PDU Sessin Id %d)",
supi64, it.second->pdu_session_id); supi64, it.second->pdu_session_id);
//TODO: remove the session // TODO: remove the session
} }
} }
} }
...@@ -729,6 +736,7 @@ void smf_app::handle_pdu_session_create_sm_context_request( ...@@ -729,6 +736,7 @@ void smf_app::handle_pdu_session_create_sm_context_request(
// Get necessary info from NAS // Get necessary info from NAS
xgpp_conv::sm_context_request_from_nas(decoded_nas_msg, smreq->req); xgpp_conv::sm_context_request_from_nas(decoded_nas_msg, smreq->req);
pdu_session_type.pdu_session_type = smreq->req.get_pdu_session_type();
// TODO: Support IPv4 only for now // TODO: Support IPv4 only for now
if (pdu_session_type.pdu_session_type == PDU_SESSION_TYPE_E_IPV6) { if (pdu_session_type.pdu_session_type == PDU_SESSION_TYPE_E_IPV6) {
cause_n1 = cause_value_5gsm_e::CAUSE_50_PDU_SESSION_TYPE_IPV4_ONLY_ALLOWED; cause_n1 = cause_value_5gsm_e::CAUSE_50_PDU_SESSION_TYPE_IPV4_ONLY_ALLOWED;
...@@ -737,7 +745,9 @@ void smf_app::handle_pdu_session_create_sm_context_request( ...@@ -737,7 +745,9 @@ void smf_app::handle_pdu_session_create_sm_context_request(
(pdu_session_type.pdu_session_type == PDU_SESSION_TYPE_E_UNSTRUCTURED)) { (pdu_session_type.pdu_session_type == PDU_SESSION_TYPE_E_UNSTRUCTURED)) {
cause_n1 = cause_value_5gsm_e::CAUSE_28_UNKNOWN_PDU_SESSION_TYPE; cause_n1 = cause_value_5gsm_e::CAUSE_28_UNKNOWN_PDU_SESSION_TYPE;
} }
if (pdu_session_type.pdu_session_type != PDU_SESSION_TYPE_E_IPV4) {
if ((pdu_session_type.pdu_session_type != PDU_SESSION_TYPE_E_IPV4) and
(pdu_session_type.pdu_session_type != PDU_SESSION_TYPE_E_IPV4V6)) {
// PDU Session Establishment Reject // PDU Session Establishment Reject
if (smf_n1::get_instance().create_n1_pdu_session_establishment_reject( if (smf_n1::get_instance().create_n1_pdu_session_establishment_reject(
smreq->req, n1_sm_message, cause_n1)) { smreq->req, n1_sm_message, cause_n1)) {
...@@ -947,7 +957,7 @@ void smf_app::handle_pdu_session_create_sm_context_request( ...@@ -947,7 +957,7 @@ void smf_app::handle_pdu_session_create_sm_context_request(
"Retrieve Session Management Subscription data from the UDM"); "Retrieve Session Management Subscription data from the UDM");
if (smf_sbi_inst->get_sm_data(supi64, dnn, snssai, subscription)) { if (smf_sbi_inst->get_sm_data(supi64, dnn, snssai, subscription)) {
// update dnn_context with subscription info // update dnn_context with subscription info
sc.get()->insert_dnn_subscription(snssai, subscription); sc.get()->insert_dnn_subscription(snssai, dnn, subscription);
} else { } else {
// Cannot retrieve information from UDM, reject PDU session // Cannot retrieve information from UDM, reject PDU session
// establishment // establishment
...@@ -982,11 +992,14 @@ void smf_app::handle_pdu_session_create_sm_context_request( ...@@ -982,11 +992,14 @@ void smf_app::handle_pdu_session_create_sm_context_request(
if (get_session_management_subscription_data( if (get_session_management_subscription_data(
supi64, dnn, snssai, subscription)) { supi64, dnn, snssai, subscription)) {
// update dnn_context with subscription info // update dnn_context with subscription info
sc.get()->insert_dnn_subscription(snssai, subscription); sc.get()->insert_dnn_subscription(snssai, dnn, subscription);
} }
} }
} }
// store PLMN
sc.get()->set_plmn(smreq->req.get_plmn());
// Step 8. generate a SMF context Id and store the corresponding information // Step 8. generate a SMF context Id and store the corresponding information
// in a map (SM_Context_ID, (supi, dnn, nssai, pdu_session_id)) // in a map (SM_Context_ID, (supi, dnn, nssai, pdu_session_id))
scid_t scid = generate_smf_context_ref(); scid_t scid = generate_smf_context_ref();
...@@ -1000,7 +1013,6 @@ void smf_app::handle_pdu_session_create_sm_context_request( ...@@ -1000,7 +1013,6 @@ void smf_app::handle_pdu_session_create_sm_context_request(
smreq->set_scid(scid); smreq->set_scid(scid);
// store scid in the context itself // store scid in the context itself
sc.get()->set_scid(scid); sc.get()->set_scid(scid);
Logger::smf_app().debug("Generated a SMF Context ID " SCID_FMT " ", scid); Logger::smf_app().debug("Generated a SMF Context ID " SCID_FMT " ", scid);
// Step 9. Let the context handle the message // Step 9. Let the context handle the message
...@@ -1639,21 +1651,20 @@ bool smf_app::get_session_management_subscription_data( ...@@ -1639,21 +1651,20 @@ bool smf_app::get_session_management_subscription_data(
Logger::smf_app().debug( Logger::smf_app().debug(
"Default session type %s", "Default session type %s",
smf_cfg.session_management_subscription[i].session_type.c_str()); smf_cfg.session_management_subscription[i].session_type.c_str());
if (smf_cfg.session_management_subscription[i].session_type.compare(
"IPV4") == 0) { std::string session_type =
smf_cfg.session_management_subscription[i].session_type;
if (boost::iequals(session_type, "IPv4")) {
pdu_session_type.pdu_session_type = pdu_session_type.pdu_session_type =
pdu_session_type_e::PDU_SESSION_TYPE_E_IPV4; pdu_session_type_e::PDU_SESSION_TYPE_E_IPV4;
} else if ( } else if (boost::iequals(session_type, "IPv6")) {
smf_cfg.session_management_subscription[i].session_type.compare(
"IPV6") == 0) {
pdu_session_type.pdu_session_type = pdu_session_type.pdu_session_type =
pdu_session_type_e::PDU_SESSION_TYPE_E_IPV6; pdu_session_type_e::PDU_SESSION_TYPE_E_IPV6;
} else if ( } else if (boost::iequals(session_type, "IPv4v6")) {
smf_cfg.session_management_subscription[i].session_type.compare(
"IPV4V6") == 0) {
pdu_session_type.pdu_session_type = pdu_session_type.pdu_session_type =
pdu_session_type_e::PDU_SESSION_TYPE_E_IPV4V6; pdu_session_type_e::PDU_SESSION_TYPE_E_IPV4V6;
} }
dnn_configuration->pdu_session_types.default_session_type = dnn_configuration->pdu_session_types.default_session_type =
pdu_session_type; pdu_session_type;
......
...@@ -186,6 +186,16 @@ class smf_app { ...@@ -186,6 +186,16 @@ class smf_app {
protocol_configuration_options_t& pco_resp, protocol_configuration_options_t& pco_resp,
const pco_protocol_or_container_id_t* const poc_id); const pco_protocol_or_container_id_t* const poc_id);
/*
* process_pco_dns_server_v6_request
* @param [protocol_configuration_options_t &] pco_resp
* @param [pco_protocol_or_container_id_t *const] proc_id
* @return
*/
int process_pco_dns_server_v6_request(
protocol_configuration_options_t& pco_resp,
const pco_protocol_or_container_id_t* const poc_id);
/* /*
* process_pco_link_mtu_request * process_pco_link_mtu_request
* @param [protocol_configuration_options_t &] pco_resp * @param [protocol_configuration_options_t &] pco_resp
......
...@@ -437,19 +437,19 @@ int smf_config::load(const string& config_file) { ...@@ -437,19 +437,19 @@ int smf_config::load(const string& config_file) {
if (boost::iequals(astring, "IPv4")) { if (boost::iequals(astring, "IPv4")) {
dnn[dnn_idx].pdu_session_type.pdu_session_type = dnn[dnn_idx].pdu_session_type.pdu_session_type =
PDU_SESSION_TYPE_E_IPV4; PDU_SESSION_TYPE_E_IPV4;
} else if (boost::iequals(astring, "IPv6") == 0) { } else if (boost::iequals(astring, "IPv6")) {
dnn[dnn_idx].pdu_session_type.pdu_session_type = dnn[dnn_idx].pdu_session_type.pdu_session_type =
PDU_SESSION_TYPE_E_IPV6; PDU_SESSION_TYPE_E_IPV6;
} else if (boost::iequals(astring, "IPv4IPv6") == 0) { } else if (boost::iequals(astring, "IPv4v6")) {
dnn[dnn_idx].pdu_session_type.pdu_session_type = dnn[dnn_idx].pdu_session_type.pdu_session_type =
PDU_SESSION_TYPE_E_IPV4V6; PDU_SESSION_TYPE_E_IPV4V6;
} else if (boost::iequals(astring, "Unstructured") == 0) { } else if (boost::iequals(astring, "Unstructured")) {
dnn[dnn_idx].pdu_session_type.pdu_session_type = dnn[dnn_idx].pdu_session_type.pdu_session_type =
PDU_SESSION_TYPE_E_UNSTRUCTURED; PDU_SESSION_TYPE_E_UNSTRUCTURED;
} else if (boost::iequals(astring, "Ethernet") == 0) { } else if (boost::iequals(astring, "Ethernet")) {
dnn[dnn_idx].pdu_session_type.pdu_session_type = dnn[dnn_idx].pdu_session_type.pdu_session_type =
PDU_SESSION_TYPE_E_ETHERNET; PDU_SESSION_TYPE_E_ETHERNET;
} else if (boost::iequals(astring, "Reserved") == 0) { } else if (boost::iequals(astring, "Reserved")) {
dnn[dnn_idx].pdu_session_type.pdu_session_type = dnn[dnn_idx].pdu_session_type.pdu_session_type =
PDU_SESSION_TYPE_E_RESERVED; PDU_SESSION_TYPE_E_RESERVED;
} else { } else {
...@@ -873,8 +873,14 @@ void smf_config::display() { ...@@ -873,8 +873,14 @@ void smf_config::display() {
dnn[i].pool_id_iv4, range_low.c_str(), range_high.c_str()); dnn[i].pool_id_iv4, range_low.c_str(), range_high.c_str());
} }
if (dnn[i].pool_id_iv6 >= 0) { if (dnn[i].pool_id_iv6 >= 0) {
if (inet_ntop(
AF_INET6, &paa_pool6_prefix[dnn[i].pool_id_iv6], str_addr6,
sizeof(str_addr6))) {
Logger::smf_app().info( Logger::smf_app().info(
" " SMF_CONFIG_STRING_IPV6_POOL ": %d", dnn[i].pool_id_iv6); " " SMF_CONFIG_STRING_IPV6_POOL ": %d (%s / %d)",
dnn[i].pool_id_iv6, str_addr6,
paa_pool6_prefix_len[dnn[i].pool_id_iv6]);
}
} }
} }
......
...@@ -1128,8 +1128,8 @@ void smf_context::get_session_ambr( ...@@ -1128,8 +1128,8 @@ void smf_context::get_session_ambr(
std::shared_ptr<dnn_configuration_t> sdc = {}; std::shared_ptr<dnn_configuration_t> sdc = {};
find_dnn_subscription(snssai, ss); find_dnn_subscription(snssai, ss);
uint32_t bit_rate_dl = {1}; uint32_t bit_rate_dl = {110000000}; // TODO: to be updated
uint32_t bit_rate_ul = {1}; uint32_t bit_rate_ul = {110000000}; // TODO: to be updated
session_ambr.pDUSessionAggregateMaximumBitRateDL.size = 4; session_ambr.pDUSessionAggregateMaximumBitRateDL.size = 4;
session_ambr.pDUSessionAggregateMaximumBitRateDL.buf = session_ambr.pDUSessionAggregateMaximumBitRateDL.buf =
...@@ -1328,7 +1328,8 @@ void smf_context::handle_pdu_session_create_sm_context_request( ...@@ -1328,7 +1328,8 @@ void smf_context::handle_pdu_session_create_sm_context_request(
.ci_dns_server_ipv4_address_request = 0, .ci_dns_server_ipv4_address_request = 0,
.ci_ip_address_allocation_via_nas_signalling = 0, .ci_ip_address_allocation_via_nas_signalling = 0,
.ci_ipv4_address_allocation_via_dhcpv4 = 0, .ci_ipv4_address_allocation_via_dhcpv4 = 0,
.ci_ipv4_link_mtu_request = 0}; .ci_ipv4_link_mtu_request = 0,
.ci_dns_server_ipv6_address_request = 0};
smf_app_inst->process_pco_request(pco_req, pco_resp, pco_ids); smf_app_inst->process_pco_request(pco_req, pco_resp, pco_ids);
sm_context_resp_pending->res.set_epco(pco_resp); sm_context_resp_pending->res.set_epco(pco_resp);
...@@ -1338,8 +1339,55 @@ void smf_context::handle_pdu_session_create_sm_context_request( ...@@ -1338,8 +1339,55 @@ void smf_context::handle_pdu_session_create_sm_context_request(
bool set_paa = false; bool set_paa = false;
paa_t paa = {}; paa_t paa = {};
Logger::smf_app().debug("UE Address Allocation"); Logger::smf_app().debug("UE Address Allocation");
switch (sp->pdu_session_type.pdu_session_type) { 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: Verified 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())) {
bool success =
paa_dynamic::get_instance().get_free_paa(sd->dnn_in_use, paa);
if (success) {
set_paa = true;
} else {
// ALL_DYNAMIC_ADDRESSES_ARE_OCCUPIED;
set_paa = false;
request_accepted = false;
sm_context_resp->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())) {
set_paa = true;
}
Logger::smf_app().info(
"PAA, Ipv4 Address: %s",
inet_ntoa(*((struct in_addr*) &paa.ipv4_address)));
char str_addr6[INET6_ADDRSTRLEN];
if (inet_ntop(
AF_INET6, &paa.ipv6_address, str_addr6, sizeof(str_addr6))) {
Logger::smf_app().info("PAA, IPv6 Address: %s", str_addr6);
}
}; break;
case PDU_SESSION_TYPE_E_IPV4: { case PDU_SESSION_TYPE_E_IPV4: {
Logger::smf_app().debug("PDU Session Type IPv4");
if (!pco_ids.ci_ipv4_address_allocation_via_dhcpv4) { if (!pco_ids.ci_ipv4_address_allocation_via_dhcpv4) {
// use SM NAS signalling // use SM NAS signalling
// static or dynamic address allocation // static or dynamic address allocation
...@@ -1357,7 +1405,10 @@ void smf_context::handle_pdu_session_create_sm_context_request( ...@@ -1357,7 +1405,10 @@ void smf_context::handle_pdu_session_create_sm_context_request(
if (nullptr != sdc.get()) { if (nullptr != sdc.get()) {
paa.pdu_session_type.pdu_session_type = paa.pdu_session_type.pdu_session_type =
sdc.get() sdc.get()
->pdu_session_types.default_session_type.pdu_session_type; ->pdu_session_types.default_session_type
.pdu_session_type; // TODO: Verified if use default session
// type or requested session type
// TODO: static ip address // TODO: static ip address
} }
} }
...@@ -1395,11 +1446,6 @@ void smf_context::handle_pdu_session_create_sm_context_request( ...@@ -1395,11 +1446,6 @@ void smf_context::handle_pdu_session_create_sm_context_request(
Logger::smf_app().debug("IPv6 has not been supported yet!"); Logger::smf_app().debug("IPv6 has not been supported yet!");
} break; } break;
case PDU_SESSION_TYPE_E_IPV4V6: {
// TODO:
Logger::smf_app().debug("IPv4/v6 has not been supported yet!");
} break;
default: { default: {
Logger::smf_app().error( Logger::smf_app().error(
"Unknown PDN type %d", sp->pdu_session_type.pdu_session_type); "Unknown PDN type %d", sp->pdu_session_type.pdu_session_type);
...@@ -1535,7 +1581,7 @@ void smf_context::handle_pdu_session_create_sm_context_request( ...@@ -1535,7 +1581,7 @@ void smf_context::handle_pdu_session_create_sm_context_request(
if (sm_context_resp->res.get_cause() != if (sm_context_resp->res.get_cause() !=
static_cast<uint8_t>(cause_value_5gsm_e::CAUSE_255_REQUEST_ACCEPTED)) { static_cast<uint8_t>(cause_value_5gsm_e::CAUSE_255_REQUEST_ACCEPTED)) {
// clear pco, ambr // clear pco, ambr
// TODO:
// free paa // free paa
paa_t free_paa = {}; paa_t free_paa = {};
free_paa = sm_context_resp->res.get_paa(); free_paa = sm_context_resp->res.get_paa();
...@@ -1543,11 +1589,12 @@ void smf_context::handle_pdu_session_create_sm_context_request( ...@@ -1543,11 +1589,12 @@ void smf_context::handle_pdu_session_create_sm_context_request(
switch (sp->pdu_session_type.pdu_session_type) { switch (sp->pdu_session_type.pdu_session_type) {
case PDU_SESSION_TYPE_E_IPV4: case PDU_SESSION_TYPE_E_IPV4:
case PDU_SESSION_TYPE_E_IPV4V6: case PDU_SESSION_TYPE_E_IPV4V6:
paa_dynamic::get_instance().release_paa( // paa_dynamic::get_instance().release_paa(
sd->dnn_in_use, free_paa.ipv4_address); // sd->dnn_in_use, free_paa.ipv4_address);
break; // break;
case PDU_SESSION_TYPE_E_IPV6: case PDU_SESSION_TYPE_E_IPV6:
paa_dynamic::get_instance().release_paa(sd->dnn_in_use, free_paa);
break;
case PDU_SESSION_TYPE_E_UNSTRUCTURED: case PDU_SESSION_TYPE_E_UNSTRUCTURED:
case PDU_SESSION_TYPE_E_ETHERNET: case PDU_SESSION_TYPE_E_ETHERNET:
case PDU_SESSION_TYPE_E_RESERVED: case PDU_SESSION_TYPE_E_RESERVED:
...@@ -2826,11 +2873,35 @@ void smf_context::insert_dnn_subscription( ...@@ -2826,11 +2873,35 @@ void smf_context::insert_dnn_subscription(
const snssai_t& snssai, const snssai_t& snssai,
std::shared_ptr<session_management_subscription>& ss) { std::shared_ptr<session_management_subscription>& ss) {
std::unique_lock<std::recursive_mutex> lock(m_context); std::unique_lock<std::recursive_mutex> lock(m_context);
dnn_subscriptions[(uint8_t) snssai.sST] = ss; dnn_subscriptions[(uint8_t) snssai.sST] = ss;
Logger::smf_app().info( Logger::smf_app().info(
"Inserted DNN Subscription, key: %d", (uint8_t) snssai.sST); "Inserted DNN Subscription, key: %d", (uint8_t) snssai.sST);
} }
//------------------------------------------------------------------------------
void smf_context::insert_dnn_subscription(
const snssai_t& snssai, const std::string& dnn,
std::shared_ptr<session_management_subscription>& ss) {
std::unique_lock<std::recursive_mutex> lock(m_context);
if (dnn_subscriptions.count((uint8_t) snssai.sST) > 0) {
std::shared_ptr<session_management_subscription> old_ss =
dnn_subscriptions.at((uint8_t) snssai.sST);
std::shared_ptr<dnn_configuration_t> dnn_configuration = {};
ss.get()->find_dnn_configuration(dnn, dnn_configuration);
if (dnn_configuration != nullptr) {
old_ss.get()->insert_dnn_configuration(dnn, dnn_configuration);
}
} else {
dnn_subscriptions[(uint8_t) snssai.sST] = ss;
}
Logger::smf_app().info(
"Inserted DNN Subscription, key: %d, dnn %s", (uint8_t) snssai.sST,
dnn.c_str());
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool smf_context::is_dnn_snssai_subscription_data( bool smf_context::is_dnn_snssai_subscription_data(
const std::string& dnn, const snssai_t& snssai) { const std::string& dnn, const snssai_t& snssai) {
...@@ -3187,6 +3258,16 @@ void smf_context::get_amf_addr(std::string& addr) const { ...@@ -3187,6 +3258,16 @@ void smf_context::get_amf_addr(std::string& addr) const {
addr = amf_addr; addr = amf_addr;
} }
//------------------------------------------------------------------------------
void smf_context::set_plmn(const plmn_t& plmn) {
this->plmn = plmn;
}
//------------------------------------------------------------------------------
void smf_context::get_plmn(plmn_t& plmn) const {
plmn = this->plmn;
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool dnn_context::find_pdu_session( bool dnn_context::find_pdu_session(
const uint32_t pdu_session_id, const uint32_t pdu_session_id,
......
...@@ -562,7 +562,8 @@ class smf_context : public std::enable_shared_from_this<smf_context> { ...@@ -562,7 +562,8 @@ class smf_context : public std::enable_shared_from_this<smf_context> {
pending_procedures(), pending_procedures(),
dnn_subscriptions(), dnn_subscriptions(),
scid(0), scid(0),
event_sub() { event_sub(),
plmn() {
supi_prefix = {}; supi_prefix = {};
// Subscribe to sm context status change // Subscribe to sm context status change
sm_context_status_connection = sm_context_status_connection =
...@@ -853,6 +854,18 @@ class smf_context : public std::enable_shared_from_this<smf_context> { ...@@ -853,6 +854,18 @@ class smf_context : public std::enable_shared_from_this<smf_context> {
const snssai_t& snssai, const snssai_t& snssai,
std::shared_ptr<session_management_subscription>& ss); std::shared_ptr<session_management_subscription>& ss);
/*
* Insert a session management subscription into the SMF context
* @param [const snssai_t&] snssai
* @param [const dnn&] dnn
* @param [std::shared_ptr<session_management_subscription>&] ss: pointer to
* the subscription
* @return void
*/
void insert_dnn_subscription(
const snssai_t& snssai, const std::string& dnn,
std::shared_ptr<session_management_subscription>& ss);
/* /*
* Verify whether a subscription data exist with a given dnn and snssai * Verify whether a subscription data exist with a given dnn and snssai
* @param [const std::string &] dnn: DNN * @param [const std::string &] dnn: DNN
...@@ -1043,6 +1056,9 @@ class smf_context : public std::enable_shared_from_this<smf_context> { ...@@ -1043,6 +1056,9 @@ class smf_context : public std::enable_shared_from_this<smf_context> {
*/ */
void get_amf_addr(std::string& addr) const; void get_amf_addr(std::string& addr) const;
void set_plmn(const plmn_t& plmn);
void get_plmn(plmn_t& plmn) const;
private: private:
std::vector<std::shared_ptr<dnn_context>> dnns; std::vector<std::shared_ptr<dnn_context>> dnns;
std::vector<std::shared_ptr<smf_procedure>> pending_procedures; std::vector<std::shared_ptr<smf_procedure>> pending_procedures;
...@@ -1052,6 +1068,7 @@ class smf_context : public std::enable_shared_from_this<smf_context> { ...@@ -1052,6 +1068,7 @@ class smf_context : public std::enable_shared_from_this<smf_context> {
supi_t supi; supi_t supi;
std::string supi_prefix; std::string supi_prefix;
scid_t scid; // SM Context ID scid_t scid; // SM Context ID
plmn_t plmn;
// AMF IP addr // AMF IP addr
string amf_addr; string amf_addr;
......
...@@ -362,6 +362,11 @@ void pdu_session_create_sm_context_request::get_plmn(plmn_t& p) const { ...@@ -362,6 +362,11 @@ void pdu_session_create_sm_context_request::get_plmn(plmn_t& p) const {
p = m_serving_network; p = m_serving_network;
} }
//-----------------------------------------------------------------------------
plmn_t pdu_session_create_sm_context_request::get_plmn() const {
return m_serving_network;
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void pdu_session_create_sm_context_request::set_an_type( void pdu_session_create_sm_context_request::set_an_type(
const std::string& an_type) { const std::string& an_type) {
......
...@@ -269,6 +269,7 @@ class pdu_session_create_sm_context_request ...@@ -269,6 +269,7 @@ class pdu_session_create_sm_context_request
void get_epco(protocol_configuration_options_t& p) const; void get_epco(protocol_configuration_options_t& p) const;
void set_plmn(const plmn_t p); void set_plmn(const plmn_t p);
void get_plmn(plmn_t& p) const; void get_plmn(plmn_t& p) const;
plmn_t get_plmn() const;
void set_an_type(const std::string& an_type); void set_an_type(const std::string& an_type);
void get_an_type(std::string& an_type) const; void get_an_type(std::string& an_type) const;
void set_guami(const guami_5g_t& guami); void set_guami(const guami_5g_t& guami);
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include "smf.h" #include "smf.h"
#include "smf_app.hpp" #include "smf_app.hpp"
#include "3gpp_conversions.hpp" #include "3gpp_conversions.hpp"
#include "epc.h"
extern "C" { extern "C" {
#include "dynamic_memory_check.h" #include "dynamic_memory_check.h"
...@@ -102,11 +103,11 @@ bool smf_n1::create_n1_pdu_session_establishment_accept( ...@@ -102,11 +103,11 @@ bool smf_n1::create_n1_pdu_session_establishment_accept(
"PDU Session Type: %d", sm_msg->pdu_session_establishment_accept "PDU Session Type: %d", sm_msg->pdu_session_establishment_accept
._pdusessiontype.pdu_session_type_value); ._pdusessiontype.pdu_session_type_value);
sm_msg->pdu_session_establishment_accept.sscmode.ssc_mode_value = // sm_msg->pdu_session_establishment_accept.sscmode.ssc_mode_value =
SSC_MODE_1; // TODO: get from sm_context_res // SSC_MODE_1; // TODO: get from sm_context_res
Logger::smf_n1().debug( // Logger::smf_n1().debug(
"SSC Mode: %d", // "SSC Mode: %d",
sm_msg->pdu_session_establishment_accept.sscmode.ssc_mode_value); // sm_msg->pdu_session_establishment_accept.sscmode.ssc_mode_value);
// authorized QoS rules of the PDU session: QOSRules (Section 6.2.5@3GPP // authorized QoS rules of the PDU session: QOSRules (Section 6.2.5@3GPP
// TS 24.501) (Section 6.4.1.3@3GPP TS 24.501 V16.1.0) Make sure that the // TS 24.501) (Section 6.4.1.3@3GPP TS 24.501 V16.1.0) Make sure that the
...@@ -152,23 +153,47 @@ bool smf_n1::create_n1_pdu_session_establishment_accept( ...@@ -152,23 +153,47 @@ bool smf_n1::create_n1_pdu_session_establishment_accept(
return false; return false;
} }
sm_msg->pdu_session_establishment_accept.presence = 0x03df; sm_msg->pdu_session_establishment_accept.presence = 0x038a;
if (static_cast<uint8_t>(sm_cause) > 0) {
sm_msg->pdu_session_establishment_accept.presence = 0x039b;
sm_msg->pdu_session_establishment_accept._5gsmcause = sm_msg->pdu_session_establishment_accept._5gsmcause =
static_cast<uint8_t>(sm_cause); static_cast<uint8_t>(sm_cause);
Logger::smf_n1().debug( Logger::smf_n1().debug(
"5GSM Cause: %d", sm_msg->pdu_session_establishment_accept._5gsmcause); "5GSM Cause: %d", sm_msg->pdu_session_establishment_accept._5gsmcause);
}
// PDUAddress // PDUAddress
paa_t paa = sm_context_res.get_paa(); paa_t paa = sm_context_res.get_paa();
sm_msg->pdu_session_establishment_accept.pduaddress.pdu_address_information = Logger::smf_n1().debug(
bfromcstralloc(4, "\0"); "PDU Session Type %s", paa.pdu_session_type.toString().c_str());
sm_msg->pdu_session_establishment_accept.pduaddress.pdu_session_type_value =
static_cast<uint8_t>(paa.pdu_session_type.pdu_session_type);
if (paa.pdu_session_type.pdu_session_type == PDU_SESSION_TYPE_E_IPV4) {
sm_msg->pdu_session_establishment_accept.pduaddress
.pdu_address_information = bfromcstralloc(4, "\0");
util::ipv4_to_bstring( util::ipv4_to_bstring(
paa.ipv4_address, sm_msg->pdu_session_establishment_accept.pduaddress paa.ipv4_address, sm_msg->pdu_session_establishment_accept.pduaddress
.pdu_address_information); .pdu_address_information);
sm_msg->pdu_session_establishment_accept.pduaddress.pdu_session_type_value =
static_cast<uint8_t>(PDU_SESSION_TYPE_E_IPV4);
Logger::smf_n1().debug( Logger::smf_n1().debug(
"UE Address %s", conv::toString(paa.ipv4_address).c_str()); "UE IPv4 Address %s", conv::toString(paa.ipv4_address).c_str());
} else if (
paa.pdu_session_type.pdu_session_type == PDU_SESSION_TYPE_E_IPV4V6) {
sm_msg->pdu_session_establishment_accept.pduaddress
.pdu_address_information = bfromcstralloc(12, "\0");
util::ipv4v6_to_pdu_address_information(
paa.ipv4_address, paa.ipv6_address,
sm_msg->pdu_session_establishment_accept.pduaddress
.pdu_address_information);
Logger::smf_n1().debug(
"UE IPv4 Address %s", conv::toString(paa.ipv4_address).c_str());
char str_addr6[INET6_ADDRSTRLEN];
if (inet_ntop(AF_INET6, &paa.ipv6_address, str_addr6, sizeof(str_addr6))) {
Logger::smf_n1().debug("UE IPv6 Address: %s", str_addr6);
}
} else if (paa.pdu_session_type.pdu_session_type == PDU_SESSION_TYPE_E_IPV6) {
// TODO:
Logger::smf_n1().debug("IPv6 is not fully supported yet!");
}
// TODO: GPRSTimer // TODO: GPRSTimer
// sm_msg->pdu_session_establishment_accept.gprstimer.unit = // sm_msg->pdu_session_establishment_accept.gprstimer.unit =
...@@ -228,11 +253,18 @@ bool smf_n1::create_n1_pdu_session_establishment_accept( ...@@ -228,11 +253,18 @@ bool smf_n1::create_n1_pdu_session_establishment_accept(
.extendedprotocolconfigurationoptions); .extendedprotocolconfigurationoptions);
// DNN // DNN
plmn_t plmn = {};
sc.get()->get_plmn(plmn);
std::string gprs = EPC::Utility::home_network_gprs(plmn);
std::string full_dnn =
sm_context_res.get_dnn() + gprs; //".mnc011.mcc110.gprs";
std::string dotted;
util::string_to_dotted(full_dnn, dotted);
Logger::smf_n1().debug(
"Full DNN %s, dotted DNN %s", full_dnn.c_str(), dotted.c_str());
sm_msg->pdu_session_establishment_accept.dnn = sm_msg->pdu_session_establishment_accept.dnn =
bfromcstralloc(sm_context_res.get_dnn().length(), "\0"); bfromcstralloc(dotted.length() + 1, "\0");
util::string_to_bstring( util::string_to_dnn(dotted, sm_msg->pdu_session_establishment_accept.dnn);
sm_context_res.get_dnn(), sm_msg->pdu_session_establishment_accept.dnn);
Logger::smf_n1().debug("DNN %s", sm_context_res.get_dnn().c_str());
Logger::smf_n1().info("Encode PDU Session Establishment Accept"); Logger::smf_n1().info("Encode PDU Session Establishment Accept");
// Encode NAS message // Encode NAS message
......
...@@ -33,6 +33,8 @@ ...@@ -33,6 +33,8 @@
#include <map> #include <map>
#include "logger.hpp" #include "logger.hpp"
#include "string.hpp"
#include <boost/algorithm/string.hpp>
class ipv6_pool { class ipv6_pool {
public: public:
...@@ -180,13 +182,15 @@ class paa_dynamic { ...@@ -180,13 +182,15 @@ class paa_dynamic {
ipv4_pool pool(first, range); ipv4_pool pool(first, range);
ipv4_pools[uint32pool_id] = pool; ipv4_pools[uint32pool_id] = pool;
} }
if (!dnns.count(dnn_label)) {
dnn_dynamic_pools adp = {}; dnn_dynamic_pools adp = {};
if (dnns.count(dnn_label)) {
adp = dnns[dnn_label];
}
adp.add_ipv4_pool_id(uint32pool_id); adp.add_ipv4_pool_id(uint32pool_id);
dnns[dnn_label] = adp; dnns[dnn_label] = adp;
} }
} }
}
void add_pool( void add_pool(
const std::string& dnn_label, const int pool_id, const std::string& dnn_label, const int pool_id,
...@@ -197,13 +201,15 @@ class paa_dynamic { ...@@ -197,13 +201,15 @@ class paa_dynamic {
ipv6_pool pool(prefix, prefix_len); ipv6_pool pool(prefix, prefix_len);
ipv6_pools[uint32pool_id] = pool; ipv6_pools[uint32pool_id] = pool;
} }
if (!dnns.count(dnn_label)) {
dnn_dynamic_pools adp = {}; dnn_dynamic_pools adp = {};
if (dnns.count(dnn_label)) {
adp = dnns[dnn_label];
}
adp.add_ipv6_pool_id(uint32pool_id); adp.add_ipv6_pool_id(uint32pool_id);
dnns[dnn_label] = adp; dnns[dnn_label] = adp;
} }
} }
}
bool get_free_paa(const std::string& dnn_label, paa_t& paa) { bool get_free_paa(const std::string& dnn_label, paa_t& paa) {
if (dnns.count(dnn_label)) { if (dnns.count(dnn_label)) {
...@@ -225,10 +231,13 @@ class paa_dynamic { ...@@ -225,10 +231,13 @@ class paa_dynamic {
paa.pdu_session_type.pdu_session_type == PDU_SESSION_TYPE_E_IPV4V6) { paa.pdu_session_type.pdu_session_type == PDU_SESSION_TYPE_E_IPV4V6) {
bool success = false; bool success = false;
std::vector<uint32_t>::const_iterator it4 = {}; std::vector<uint32_t>::const_iterator it4 = {};
uint32_t ipv4_pool_id = 0;
for (it4 = dnn_pool.ipv4_pool_ids.begin(); for (it4 = dnn_pool.ipv4_pool_ids.begin();
it4 != dnn_pool.ipv4_pool_ids.end(); ++it4) { it4 != dnn_pool.ipv4_pool_ids.end(); ++it4) {
if (ipv4_pools[*it4].alloc_address(paa.ipv4_address)) { if (ipv4_pools[*it4].alloc_address(paa.ipv4_address)) {
success = true; success = true;
ipv4_pool_id = *it4;
break;
} }
} }
if (success) { if (success) {
...@@ -239,7 +248,7 @@ class paa_dynamic { ...@@ -239,7 +248,7 @@ class paa_dynamic {
return true; return true;
} }
} }
ipv4_pools[*it4].free_address(paa.ipv4_address); ipv4_pools[ipv4_pool_id].free_address(paa.ipv4_address);
} }
Logger::smf_app().warn( Logger::smf_app().warn(
"Could not get PAA PDU_SESSION_TYPE_E_IPV4V6 for DNN %s", "Could not get PAA PDU_SESSION_TYPE_E_IPV4V6 for DNN %s",
...@@ -290,6 +299,7 @@ class paa_dynamic { ...@@ -290,6 +299,7 @@ class paa_dynamic {
return false; return false;
} else if ( } else if (
paa.pdu_session_type.pdu_session_type == PDU_SESSION_TYPE_E_IPV6) { paa.pdu_session_type.pdu_session_type == PDU_SESSION_TYPE_E_IPV6) {
Logger::smf_app().debug("IPv6 is not fully supported yet!");
return true; return true;
} }
} }
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include "rfc_1877.h" #include "rfc_1877.h"
#include "smf_app.hpp" #include "smf_app.hpp"
#include "smf_config.hpp" #include "smf_config.hpp"
#include "string.hpp"
using namespace smf; using namespace smf;
...@@ -283,6 +284,38 @@ int smf_app::process_pco_dns_server_request( ...@@ -283,6 +284,38 @@ int smf_app::process_pco_dns_server_request(
return pco_push_protocol_or_container_id(pco_resp, &poc_id_resp); return pco_push_protocol_or_container_id(pco_resp, &poc_id_resp);
} }
//------------------------------------------------------------------------------
int smf_app::process_pco_dns_server_v6_request(
protocol_configuration_options_t& pco_resp,
const pco_protocol_or_container_id_t* const poc_id) {
in6_addr ipcp_out_dns_prim_ipv6_addr = smf_cfg.default_dnsv6;
pco_protocol_or_container_id_t poc_id_resp = {0};
uint8_t dnsv6_array[16];
Logger::smf_app().debug(
"PCO: Protocol identifier IPCP option DNS Server v6 Request");
poc_id_resp.protocol_id = PCO_CONTAINER_IDENTIFIER_DNS_SERVER_IPV6_ADDRESS;
poc_id_resp.length_of_protocol_id_contents = 16;
char str_addr6[INET6_ADDRSTRLEN];
if (inet_ntop(
AF_INET6, &ipcp_out_dns_prim_ipv6_addr, str_addr6,
sizeof(str_addr6))) {
std::string ipv6_addr_str((char*) str_addr6, INET6_ADDRSTRLEN);
// Logger::smf_app().info(" Ipv6 address....: %s", ipv6_addr_str.c_str());
unsigned char buf_in6_addr[sizeof(struct in6_addr)];
if (inet_pton(AF_INET6, util::trim(ipv6_addr_str).c_str(), buf_in6_addr) ==
1) {
for (int i = 0; i <= 15; i++) dnsv6_array[i] = (uint8_t)(buf_in6_addr[i]);
}
}
std::string tmp_s((const char*) &dnsv6_array[0], sizeof(dnsv6_array));
poc_id_resp.protocol_id_contents = tmp_s;
return pco_push_protocol_or_container_id(pco_resp, &poc_id_resp);
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
int smf_app::process_pco_link_mtu_request( int smf_app::process_pco_link_mtu_request(
protocol_configuration_options_t& pco_resp, protocol_configuration_options_t& pco_resp,
...@@ -335,7 +368,11 @@ int smf_app::process_pco_request( ...@@ -335,7 +368,11 @@ int smf_app::process_pco_request(
pco_resp, &pco_req.protocol_or_container_ids[id]); pco_resp, &pco_req.protocol_or_container_ids[id]);
pco_ids.ci_dns_server_ipv4_address_request = true; pco_ids.ci_dns_server_ipv4_address_request = true;
break; break;
case PCO_CONTAINER_IDENTIFIER_DNS_SERVER_IPV6_ADDRESS:
process_pco_dns_server_v6_request(
pco_resp, &pco_req.protocol_or_container_ids[id]);
pco_ids.ci_dns_server_ipv6_address_request = true;
break;
case PCO_CONTAINER_IDENTIFIER_IP_ADDRESS_ALLOCATION_VIA_NAS_SIGNALLING: case PCO_CONTAINER_IDENTIFIER_IP_ADDRESS_ALLOCATION_VIA_NAS_SIGNALLING:
Logger::smf_app().debug("PCO: Allocation via NAS signaling requested"); Logger::smf_app().debug("PCO: Allocation via NAS signaling requested");
pco_ids.ci_ip_address_allocation_via_nas_signalling = true; pco_ids.ci_ip_address_allocation_via_nas_signalling = true;
......
...@@ -47,6 +47,7 @@ typedef struct protocol_configuration_options_ids_s { ...@@ -47,6 +47,7 @@ typedef struct protocol_configuration_options_ids_s {
uint8_t ci_ip_address_allocation_via_nas_signalling : 1; uint8_t ci_ip_address_allocation_via_nas_signalling : 1;
uint8_t ci_ipv4_address_allocation_via_dhcpv4 : 1; uint8_t ci_ipv4_address_allocation_via_dhcpv4 : 1;
uint8_t ci_ipv4_link_mtu_request : 1; uint8_t ci_ipv4_link_mtu_request : 1;
uint8_t ci_dns_server_ipv6_address_request : 1;
} protocol_configuration_options_ids_t; } protocol_configuration_options_ids_t;
#endif #endif
...@@ -414,7 +414,7 @@ void session_create_sm_context_procedure::handle_itti_msg( ...@@ -414,7 +414,7 @@ void session_create_sm_context_procedure::handle_itti_msg(
// TODO: Support IPv4 only for now // TODO: Support IPv4 only for now
if (n11_triggered_pending->res.get_pdu_session_type() == if (n11_triggered_pending->res.get_pdu_session_type() ==
PDU_SESSION_TYPE_E_IPV4V6) { PDU_SESSION_TYPE_E_IPV6) {
n11_triggered_pending->res.set_pdu_session_type(PDU_SESSION_TYPE_E_IPV4); n11_triggered_pending->res.set_pdu_session_type(PDU_SESSION_TYPE_E_IPV4);
cause_n1 = cause_n1 =
cause_value_5gsm_e::CAUSE_50_PDU_SESSION_TYPE_IPV4_ONLY_ALLOWED; cause_value_5gsm_e::CAUSE_50_PDU_SESSION_TYPE_IPV4_ONLY_ALLOWED;
......
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