[#306] Refine static IP addresses

This commit is contained in:
Sukchan Lee 2019-11-17 17:43:36 +09:00
parent c8bcfffe2e
commit 835b3c9851
21 changed files with 406 additions and 195 deletions

View File

@ -507,6 +507,34 @@ pgw:
# - addr: cafe:2::1/64
# apn: volte
# dev: ogstun3
#
# o Pool Range Sample
# ue_pool:
# - addr: 45.45.0.1/24
# range: 45.45.0.100-45.45.0.200
#
# ue_pool:
# - addr: 45.45.0.1/24
# range:
# - 45.45.0.5-45.45.0.50
# - 45.45.0.100-
#
# ue_pool:
# - addr: 45.45.0.1/24
# range:
# - -45.45.0.200
# - 45.45.0.210-45.45.0.220
#
# ue_pool:
# - addr: 45.45.0.1/16
# range:
# - 45.45.0.100-45.45.0.200
# - 45.45.1.100-45.45.1.200
# - addr: cafe::1/64
# range:
# - cafe::a0-cafe:b0
# - cafe::c0-cafe:d0
#
#
ue_pool:
- addr: 45.45.0.1/16

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -255,10 +255,10 @@ typedef struct ogs_pcc_rule_s {
typedef struct ogs_pdn_s {
uint32_t context_identifier;
char apn[OGS_MAX_APN_LEN+1];
#define OGS_HSS_PDN_TYPE_IPV4 0
#define OGS_HSS_PDN_TYPE_IPV6 1
#define OGS_HSS_PDN_TYPE_IPV4V6 2
#define OGS_HSS_PDN_TYPE_IPV4_OR_IPV6 3
#define OGS_DIAM_PDN_TYPE_IPV4 0
#define OGS_DIAM_PDN_TYPE_IPV6 1
#define OGS_DIAM_PDN_TYPE_IPV4V6 2
#define OGS_DIAM_PDN_TYPE_IPV4_OR_IPV6 3
int pdn_type;
ogs_qos_t qos;

View File

@ -32,7 +32,7 @@ if [ "$1" = "add" ]; then
KI=$3
OPC=$4
mongo --eval "db.subscribers.update({\"imsi\" : \"$IMSI\"}, { \$setOnInsert: { \"imsi\" : \"$IMSI\", \"pdn\" : [ { \"apn\" : \"internet\", \"_id\" : new ObjectId(), \"pcc_rule\" : [ ], \"pgw\" : { \"addr\" : \"127.0.0.3\" }, \"ambr\" : { \"downlink\" : NumberLong(1024000), \"uplink\" : NumberLong(1024000) }, \"qos\" : { \"qci\" : NumberInt(9), \"arp\" : { \"priority_level\" : NumberInt(8), \"pre_emption_vulnerability\" : NumberInt(1), \"pre_emption_capability\" : NumberInt(0) } }, \"type\" : NumberInt(0) } ], \"ambr\" : { \"downlink\" : NumberLong(1024000), \"uplink\" : NumberLong(1024000) }, \"subscribed_rau_tau_timer\" : NumberInt(12), \"network_access_mode\" : NumberInt(2), \"subscriber_status\" : NumberInt(0), \"access_restriction_data\" : NumberInt(32), \"security\" : { \"k\" : \"$KI\", \"amf\" : \"8000\", \"op\" : null, \"opc\" : \"$OPC\" }, \"__v\" : 0 } }, upsert=true);" open5gs
mongo --eval "db.subscribers.update({\"imsi\" : \"$IMSI\"}, { \$setOnInsert: { \"imsi\" : \"$IMSI\", \"pdn\" : [ { \"apn\" : \"internet\", \"_id\" : new ObjectId(), \"pcc_rule\" : [ ], \"ambr\" : { \"downlink\" : NumberLong(1024000), \"uplink\" : NumberLong(1024000) }, \"qos\" : { \"qci\" : NumberInt(9), \"arp\" : { \"priority_level\" : NumberInt(8), \"pre_emption_vulnerability\" : NumberInt(1), \"pre_emption_capability\" : NumberInt(0) } }, \"type\" : NumberInt(0) } ], \"ambr\" : { \"downlink\" : NumberLong(1024000), \"uplink\" : NumberLong(1024000) }, \"subscribed_rau_tau_timer\" : NumberInt(12), \"network_access_mode\" : NumberInt(2), \"subscriber_status\" : NumberInt(0), \"access_restriction_data\" : NumberInt(32), \"security\" : { \"k\" : \"$KI\", \"amf\" : \"8000\", \"op\" : null, \"opc\" : \"$OPC\" }, \"__v\" : 0 } }, upsert=true);" open5gs
exit 0
fi
@ -42,7 +42,7 @@ if [ "$1" = "add" ]; then
KI=$4
OPC=$5
mongo --eval "db.subscribers.update({\"imsi\" : \"$IMSI\"}, { \$setOnInsert: { \"imsi\" : \"$IMSI\", \"pdn\" : [ { \"apn\" : \"internet\", \"_id\" : new ObjectId(), \"pcc_rule\" : [ ], \"pgw\" : { \"addr\" : \"127.0.0.3\" }, \"ambr\" : { \"downlink\" : NumberLong(1024000), \"uplink\" : NumberLong(1024000) }, \"qos\" : { \"qci\" : NumberInt(9), \"arp\" : { \"priority_level\" : NumberInt(8), \"pre_emption_vulnerability\" : NumberInt(1), \"pre_emption_capability\" : NumberInt(0) } }, \"type\" : NumberInt(0), \"addr\" : \"$IP\" } ], \"ambr\" : { \"downlink\" : NumberLong(1024000), \"uplink\" : NumberLong(1024000) }, \"subscribed_rau_tau_timer\" : NumberInt(12), \"network_access_mode\" : NumberInt(2), \"subscriber_status\" : NumberInt(0), \"access_restriction_data\" : NumberInt(32), \"security\" : { \"k\" : \"$KI\", \"amf\" : \"8000\", \"op\" : null, \"opc\" : \"$OPC\" }, \"__v\" : 0 } }, upsert=true);" open5gs
mongo --eval "db.subscribers.update({\"imsi\" : \"$IMSI\"}, { \$setOnInsert: { \"imsi\" : \"$IMSI\", \"pdn\" : [ { \"apn\" : \"internet\", \"_id\" : new ObjectId(), \"pcc_rule\" : [ ], \"ambr\" : { \"downlink\" : NumberLong(1024000), \"uplink\" : NumberLong(1024000) }, \"qos\" : { \"qci\" : NumberInt(9), \"arp\" : { \"priority_level\" : NumberInt(8), \"pre_emption_vulnerability\" : NumberInt(1), \"pre_emption_capability\" : NumberInt(0) } }, \"type\" : NumberInt(0), \"ue\" : { \"addr\" : \"$IP\" } } ], \"ambr\" : { \"downlink\" : NumberLong(1024000), \"uplink\" : NumberLong(1024000) }, \"subscribed_rau_tau_timer\" : NumberInt(12), \"network_access_mode\" : NumberInt(2), \"subscriber_status\" : NumberInt(0), \"access_restriction_data\" : NumberInt(32), \"security\" : { \"k\" : \"$KI\", \"amf\" : \"8000\", \"op\" : null, \"opc\" : \"$OPC\" }, \"__v\" : 0 } }, upsert=true);" open5gs
exit 0
fi
@ -79,7 +79,7 @@ if [ "$1" = "static_ip" ]; then
IMSI=$2
IP=$3
mongo --eval "db.subscribers.update({\"imsi\": \"$IMSI\"},{\$set: { \"pdn.0.addr\": \"$IP\" }});" open5gs
mongo --eval "db.subscribers.update({\"imsi\": \"$IMSI\"},{\$set: { \"pdn.0.ue.addr\": \"$IP\" }});" open5gs
exit 0
fi
@ -91,7 +91,7 @@ if [ "$1" = "static_ip6" ]; then
IMSI=$2
IP=$3
mongo --eval "db.subscribers.update({\"imsi\": \"$IMSI\"},{\$set: { \"pdn.0.addr6\": \"$IP\" }});" open5gs
mongo --eval "db.subscribers.update({\"imsi\": \"$IMSI\"},{\$set: { \"pdn.0.ue.addr6\": \"$IP\" }});" open5gs
exit 0
fi

View File

@ -630,29 +630,49 @@ int hss_db_subscription_data(
}
}
}
} else if (!strcmp(child2_key, "addr") && BSON_ITER_HOLDS_UTF8(&child2_iter)) {
ogs_ipsubnet_t ipsub;
const char *v = bson_iter_utf8(&child2_iter, &length);
rv = ogs_ipsubnet(&ipsub, v, NULL);
if (rv == OGS_OK) {
if (pdn->paa.pdn_type == OGS_HSS_PDN_TYPE_IPV6) {
pdn->paa.pdn_type = OGS_HSS_PDN_TYPE_IPV4V6;
} else {
pdn->paa.pdn_type = OGS_HSS_PDN_TYPE_IPV4;
} else if (!strcmp(child2_key, "ue") &&
BSON_ITER_HOLDS_DOCUMENT(&child2_iter)) {
bson_iter_recurse(&child2_iter, &child3_iter);
while (bson_iter_next(&child3_iter)) {
const char *child3_key =
bson_iter_key(&child3_iter);
if (!strcmp(child3_key, "addr") &&
BSON_ITER_HOLDS_UTF8(&child3_iter)) {
ogs_ipsubnet_t ipsub;
const char *v =
bson_iter_utf8(&child3_iter, &length);
rv = ogs_ipsubnet(&ipsub, v, NULL);
if (rv == OGS_OK) {
if (pdn->paa.pdn_type ==
OGS_GTP_PDN_TYPE_IPV6) {
pdn->paa.pdn_type =
OGS_GTP_PDN_TYPE_IPV4V6;
} else {
pdn->paa.pdn_type =
OGS_GTP_PDN_TYPE_IPV4;
}
pdn->paa.both.addr = ipsub.sub[0];
}
} else if (!strcmp(child3_key, "addr6") &&
BSON_ITER_HOLDS_UTF8(&child3_iter)) {
ogs_ipsubnet_t ipsub;
const char *v =
bson_iter_utf8(&child3_iter, &length);
rv = ogs_ipsubnet(&ipsub, v, NULL);
if (rv == OGS_OK) {
if (pdn->paa.pdn_type ==
OGS_GTP_PDN_TYPE_IPV4) {
pdn->paa.pdn_type =
OGS_GTP_PDN_TYPE_IPV4V6;
} else {
pdn->paa.pdn_type =
OGS_GTP_PDN_TYPE_IPV6;
}
memcpy(&(pdn->paa.both.addr6),
ipsub.sub, OGS_IPV6_LEN);
}
}
pdn->paa.both.addr = ipsub.sub[0];
}
} else if (!strcmp(child2_key, "addr6") && BSON_ITER_HOLDS_UTF8(&child2_iter)) {
ogs_ipsubnet_t ipsub;
const char *v = bson_iter_utf8(&child2_iter, &length);
rv = ogs_ipsubnet(&ipsub, v, NULL);
if (rv == OGS_OK) {
if (pdn->paa.pdn_type == OGS_HSS_PDN_TYPE_IPV4) {
pdn->paa.pdn_type = OGS_HSS_PDN_TYPE_IPV4V6;
} else {
pdn->paa.pdn_type = OGS_HSS_PDN_TYPE_IPV6;
}
memcpy(&(pdn->paa.both.addr6), ipsub.sub, OGS_IPV6_LEN);
}
}
}

View File

@ -445,8 +445,8 @@ static int hss_ogs_diam_s6a_ulr_cb( struct msg **msg, struct avp *avp,
for (i = 0; i < subscription_data.num_of_pdn; i++) {
/* Set the APN Configuration */
struct avp *apn_configuration, *context_identifier;
struct avp *pdn_type, *served_party_ip_address, *service_selection;
struct avp *apn_configuration, *context_identifier, *pdn_type;
struct avp *served_party_ip_address, *service_selection;
struct avp *eps_subscribed_qos_profile, *qos_class_identifier;
struct avp *allocation_retention_priority, *priority_level;
struct avp *pre_emption_capability, *pre_emption_vulnerability;
@ -482,27 +482,38 @@ static int hss_ogs_diam_s6a_ulr_cb( struct msg **msg, struct avp *avp,
ogs_assert(ret == 0);
/* Set Served-Party-IP-Address */
if ((pdn->pdn_type == OGS_HSS_PDN_TYPE_IPV4 || pdn->pdn_type == OGS_HSS_PDN_TYPE_IPV4V6) &&
(pdn->paa.pdn_type == OGS_HSS_PDN_TYPE_IPV4 || pdn->paa.pdn_type == OGS_HSS_PDN_TYPE_IPV4V6)) {
ret = fd_msg_avp_new(ogs_diam_s6a_served_party_ip_address, 0, &served_party_ip_address);
if ((pdn->pdn_type == OGS_DIAM_PDN_TYPE_IPV4 ||
pdn->pdn_type == OGS_DIAM_PDN_TYPE_IPV4V6) &&
(pdn->paa.pdn_type == OGS_GTP_PDN_TYPE_IPV4 ||
pdn->paa.pdn_type == OGS_GTP_PDN_TYPE_IPV4V6)) {
ret = fd_msg_avp_new(ogs_diam_s6a_served_party_ip_address,
0, &served_party_ip_address);
ogs_assert(ret == 0);
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = pdn->paa.both.addr;
ret = fd_msg_avp_value_encode (&sin, served_party_ip_address);
ret = fd_msg_avp_value_encode(
&sin, served_party_ip_address);
ogs_assert(ret == 0);
ret = fd_msg_avp_add(apn_configuration, MSG_BRW_LAST_CHILD, served_party_ip_address);
ret = fd_msg_avp_add(apn_configuration, MSG_BRW_LAST_CHILD,
served_party_ip_address);
ogs_assert(ret == 0);
}
if ((pdn->pdn_type == OGS_HSS_PDN_TYPE_IPV6 || pdn->pdn_type == OGS_HSS_PDN_TYPE_IPV4V6) &&
(pdn->paa.pdn_type == OGS_HSS_PDN_TYPE_IPV6 || pdn->paa.pdn_type == OGS_HSS_PDN_TYPE_IPV4V6)) {
ret = fd_msg_avp_new(ogs_diam_s6a_served_party_ip_address, 0, &served_party_ip_address);
if ((pdn->pdn_type == OGS_DIAM_PDN_TYPE_IPV6 ||
pdn->pdn_type == OGS_DIAM_PDN_TYPE_IPV4V6) &&
(pdn->paa.pdn_type == OGS_GTP_PDN_TYPE_IPV6 ||
pdn->paa.pdn_type == OGS_GTP_PDN_TYPE_IPV4V6)) {
ret = fd_msg_avp_new(ogs_diam_s6a_served_party_ip_address,
0, &served_party_ip_address);
ogs_assert(ret == 0);
sin6.sin6_family = AF_INET6;
memcpy(sin6.sin6_addr.s6_addr, pdn->paa.both.addr6, OGS_IPV6_LEN);
ret = fd_msg_avp_value_encode (&sin6, served_party_ip_address);
memcpy(sin6.sin6_addr.s6_addr,
pdn->paa.both.addr6, OGS_IPV6_LEN);
ret = fd_msg_avp_value_encode(
&sin6, served_party_ip_address);
ogs_assert(ret == 0);
ret = fd_msg_avp_add(apn_configuration, MSG_BRW_LAST_CHILD, served_party_ip_address);
ret = fd_msg_avp_add(apn_configuration, MSG_BRW_LAST_CHILD,
served_party_ip_address);
ogs_assert(ret == 0);
}

View File

@ -528,7 +528,8 @@ void mme_s6a_send_ulr(mme_ue_t *mme_ue)
ogs_assert(ret == 0);
/* Set Vendor-Specific-Application-Id AVP */
ret = ogs_diam_message_vendor_specific_appid_set( req, OGS_DIAM_S6A_APPLICATION_ID);
ret = ogs_diam_message_vendor_specific_appid_set(
req, OGS_DIAM_S6A_APPLICATION_ID);
ogs_assert(ret == 0);
ret = clock_gettime(CLOCK_REALTIME, &sess_data->ts);
@ -622,7 +623,8 @@ static void mme_s6a_ula_cb(void *data, struct msg **msg)
ret = fd_msg_search_avp(*msg, ogs_diam_experimental_result, &avp);
ogs_assert(ret == 0);
if (avp) {
ret = fd_avp_search_avp(avp, ogs_diam_experimental_result_code, &avpch);
ret = fd_avp_search_avp(avp,
ogs_diam_experimental_result_code, &avpch);
ogs_assert(ret == 0);
if (avpch) {
ret = fd_msg_avp_hdr(avpch, &hdr);
@ -681,7 +683,8 @@ static void mme_s6a_ula_cb(void *data, struct msg **msg)
ret = fd_avp_search_avp(avp, ogs_diam_s6a_ambr, &avpch1);
ogs_assert(ret == 0);
if (avpch1) {
ret = fd_avp_search_avp( avpch1, ogs_diam_s6a_max_bandwidth_ul, &avpch2);
ret = fd_avp_search_avp( avpch1,
ogs_diam_s6a_max_bandwidth_ul, &avpch2);
ogs_assert(ret == 0);
if (avpch2) {
ret = fd_msg_avp_hdr(avpch2, &hdr);
@ -692,7 +695,8 @@ static void mme_s6a_ula_cb(void *data, struct msg **msg)
error++;
}
ret = fd_avp_search_avp(avpch1, ogs_diam_s6a_max_bandwidth_dl, &avpch2);
ret = fd_avp_search_avp(avpch1,
ogs_diam_s6a_max_bandwidth_dl, &avpch2);
ogs_assert(ret == 0);
if (avpch2) {
ret = fd_msg_avp_hdr(avpch2, &hdr);
@ -708,7 +712,8 @@ static void mme_s6a_ula_cb(void *data, struct msg **msg)
error++;
}
ret = fd_avp_search_avp(avp, ogs_diam_s6a_subscribed_rau_tau_timer, &avpch1);
ret = fd_avp_search_avp(avp,
ogs_diam_s6a_subscribed_rau_tau_timer, &avpch1);
ogs_assert(ret == 0);
if (avpch1) {
ret = fd_msg_avp_hdr(avpch1, &hdr);
@ -719,7 +724,8 @@ static void mme_s6a_ula_cb(void *data, struct msg **msg)
OGS_DIAM_S6A_RAU_TAU_DEFAULT_TIME;
}
ret = fd_avp_search_avp(avp, ogs_diam_s6a_apn_configuration_profile, &avpch1);
ret = fd_avp_search_avp(avp,
ogs_diam_s6a_apn_configuration_profile, &avpch1);
ogs_assert(ret == 0);
if (avpch1) {
ret = fd_msg_browse(avpch1, MSG_BRW_FIRST_CHILD, &avpch2, NULL);
@ -763,19 +769,20 @@ static void mme_s6a_ula_cb(void *data, struct msg **msg)
error++;
}
ret = fd_avp_search_avp(avpch2, ogs_diam_s6a_pdn_type, &avpch3);
ret = fd_avp_search_avp(avpch2, ogs_diam_s6a_pdn_type,
&avpch3);
ogs_assert(ret == 0);
if (avpch3) {
ret = fd_msg_avp_hdr(avpch3, &hdr);
pdn->pdn_type = hdr->avp_value->i32;
pdn->paa.pdn_type = pdn->pdn_type;
} else {
ogs_error("no_PDN-Type");
error++;
}
/* Served-Party-IP-Address parsing for any static IPs */
ret = fd_msg_browse(avpch2, MSG_BRW_FIRST_CHILD, &avpch3, NULL);
ret = fd_msg_browse(avpch2, MSG_BRW_FIRST_CHILD,
&avpch3, NULL);
ogs_assert(ret == 0);
while (avpch3) {
ret = fd_msg_avp_hdr(avpch3, &hdr);
@ -786,21 +793,35 @@ static void mme_s6a_ula_cb(void *data, struct msg **msg)
ogs_assert(ret == 0);
if (addr.ogs_sa_family == AF_INET) {
if (pdn->paa.pdn_type == OGS_HSS_PDN_TYPE_IPV4) {
if (pdn->pdn_type == OGS_DIAM_PDN_TYPE_IPV4) {
pdn->paa.addr = addr.sin.sin_addr.s_addr;
} else if (pdn->paa.pdn_type == OGS_HSS_PDN_TYPE_IPV4V6) {
pdn->paa.both.addr = addr.sin.sin_addr.s_addr;
} else if (pdn->pdn_type ==
OGS_DIAM_PDN_TYPE_IPV4V6) {
pdn->paa.both.addr =
addr.sin.sin_addr.s_addr;
} else {
ogs_error("Warning: Received a static IPv4 address but PDN-Type does not include IPv4. Ignoring...");
ogs_error("Warning: Received a static IPv4 "
"address but PDN-Type does not include "
"IPv4. Ignoring...");
}
} else if (addr.ogs_sa_family == AF_INET6) {
if (pdn->paa.pdn_type == OGS_HSS_PDN_TYPE_IPV6) {
memcpy(pdn->paa.addr6, addr.sin6.sin6_addr.s6_addr, OGS_IPV6_LEN);
} else if (pdn->paa.pdn_type == OGS_HSS_PDN_TYPE_IPV4V6) {
memcpy(pdn->paa.both.addr6, addr.sin6.sin6_addr.s6_addr, OGS_IPV6_LEN);
if (pdn->pdn_type == OGS_DIAM_PDN_TYPE_IPV6) {
memcpy(pdn->paa.addr6,
addr.sin6.sin6_addr.s6_addr,
OGS_IPV6_LEN);
} else if (pdn->pdn_type ==
OGS_DIAM_PDN_TYPE_IPV4V6) {
memcpy(pdn->paa.both.addr6,
addr.sin6.sin6_addr.s6_addr,
OGS_IPV6_LEN);
} else {
ogs_error("Warning: Received a static IPv6 address but PDN-Type does not include IPv6. Ignoring...");
ogs_error("Warning: Received a static IPv6 "
"address but PDN-Type does not include "
"IPv6. Ignoring...");
}
} else {
ogs_error("Invalid family[%d]",
addr.ogs_sa_family);
}
break;
default:
@ -889,9 +910,6 @@ static void mme_s6a_ula_cb(void *data, struct msg **msg)
ret = fd_msg_avp_hdr(avpch4, &hdr);
switch(hdr->avp_code) {
case OGS_DIAM_S6A_AVP_CODE_MIP_HOME_AGENT_ADDRESS:
{
ogs_sockaddr_t addr;
ret = fd_msg_avp_value_interpret(avpch4,
&addr.sa);
ogs_assert(ret == 0);
@ -915,7 +933,6 @@ static void mme_s6a_ula_cb(void *data, struct msg **msg)
error++;
}
break;
}
default:
ogs_error("Unknown AVP-Code:%d",
hdr->avp_code);

View File

@ -151,12 +151,12 @@ int mme_s11_build_create_session_request(
OGS_NAS_PDN_CONNECTIVITY_PDN_TYPE_IPV6 ||
sess->request_type.pdn_type ==
OGS_NAS_PDN_CONNECTIVITY_PDN_TYPE_IPV4V6);
if (pdn->pdn_type == OGS_HSS_PDN_TYPE_IPV4 ||
pdn->pdn_type == OGS_HSS_PDN_TYPE_IPV6 ||
pdn->pdn_type == OGS_HSS_PDN_TYPE_IPV4V6) {
if (pdn->pdn_type == OGS_DIAM_PDN_TYPE_IPV4 ||
pdn->pdn_type == OGS_DIAM_PDN_TYPE_IPV6 ||
pdn->pdn_type == OGS_DIAM_PDN_TYPE_IPV4V6) {
req->pdn_type.u8 = ((pdn->pdn_type + 1) & sess->request_type.pdn_type);
ogs_assert(req->pdn_type.u8 != 0);
} else if (pdn->pdn_type == OGS_HSS_PDN_TYPE_IPV4_OR_IPV6) {
} else if (pdn->pdn_type == OGS_DIAM_PDN_TYPE_IPV4_OR_IPV6) {
req->pdn_type.u8 = sess->request_type.pdn_type;
} else {
ogs_fatal("Invalid PDN_TYPE[%d]\n", pdn->pdn_type);
@ -168,12 +168,12 @@ int mme_s11_build_create_session_request(
* (pdn_type & sess->request_type) truncates us down to just one,
* we need to change position of addresses in struct. */
if (req->pdn_type.u8 == OGS_GTP_PDN_TYPE_IPV4 &&
pdn->paa.pdn_type == OGS_HSS_PDN_TYPE_IPV4V6) {
pdn->pdn_type == OGS_DIAM_PDN_TYPE_IPV4V6) {
uint32_t addr = pdn->paa.both.addr;
pdn->paa.addr = addr;
}
if (req->pdn_type.u8 == OGS_GTP_PDN_TYPE_IPV6 &&
pdn->paa.pdn_type == OGS_HSS_PDN_TYPE_IPV4V6) {
pdn->pdn_type == OGS_DIAM_PDN_TYPE_IPV4V6) {
uint8_t addr[16];
memcpy(&addr, pdn->paa.both.addr6, OGS_IPV6_LEN);
memcpy(pdn->paa.addr6, &addr, OGS_IPV6_LEN);

View File

@ -573,7 +573,9 @@ int pgw_context_parse_config(void)
const char *mask_or_numbits = NULL;
const char *apn = NULL;
const char *dev = self.tun_ifname;
bool static_pool = false;
const char *low[MAX_NUM_OF_SUBNET_RANGE];
const char *high[MAX_NUM_OF_SUBNET_RANGE];
int i, num = 0;
if (ogs_yaml_iter_type(&ue_pool_array) ==
YAML_MAPPING_NODE) {
@ -608,22 +610,59 @@ int pgw_context_parse_config(void)
apn = ogs_yaml_iter_value(&ue_pool_iter);
} else if (!strcmp(ue_pool_key, "dev")) {
dev = ogs_yaml_iter_value(&ue_pool_iter);
} else if (!strcmp(ue_pool_key, "static")) {
char *str = (char *)ogs_yaml_iter_value(&ue_pool_iter);
if (!strcmp(str, "true")) {
static_pool = true;
}
} else if (!strcmp(ue_pool_key, "range")) {
ogs_yaml_iter_t range_iter;
ogs_yaml_iter_recurse(
&ue_pool_iter, &range_iter);
ogs_assert(ogs_yaml_iter_type(&range_iter) !=
YAML_MAPPING_NODE);
do {
char *v = NULL;
if (ogs_yaml_iter_type(&range_iter) ==
YAML_SEQUENCE_NODE) {
if (!ogs_yaml_iter_next(&range_iter))
break;
}
v = (char *)ogs_yaml_iter_value(
&range_iter);
if (v) {
ogs_assert(num <=
MAX_NUM_OF_SUBNET_RANGE);
low[num] =
(const char *)strsep(&v, "-");
if (low[num] && strlen(low[num]) == 0)
low[num] = NULL;
high[num] = (const char *)v;
if (high[num] && strlen(high[num]) == 0)
high[num] = NULL;
}
if (low[num] || high[num]) num++;
} while (
ogs_yaml_iter_type(&range_iter) ==
YAML_SEQUENCE_NODE);
} else
ogs_warn("unknown key `%s`", ue_pool_key);
}
if (ipstr && mask_or_numbits) {
subnet = pgw_subnet_add(ipstr, mask_or_numbits, apn, dev, static_pool);
subnet = pgw_subnet_add(
ipstr, mask_or_numbits, apn, dev);
ogs_assert(subnet);
subnet->num_of_range = num;
for (i = 0; i < subnet->num_of_range; i++) {
subnet->range[i].low = low[i];
subnet->range[i].high = high[i];
}
} else {
ogs_warn("Ignore : addr(%s/%s), apn(%s)",
ipstr, mask_or_numbits, apn);
}
} while (ogs_yaml_iter_type(&ue_pool_array) ==
YAML_SEQUENCE_NODE);
} else if (!strcmp(pgw_key, "dns")) {
@ -737,6 +776,10 @@ pgw_sess_t *pgw_sess_add(
pgw_bearer_t *bearer = NULL;
pgw_subnet_t *subnet6 = NULL;
ogs_assert(imsi);
ogs_assert(apn);
ogs_assert(paa);
ogs_pool_alloc(&pgw_sess_pool, &sess);
ogs_assert(sess);
memset(sess, 0, sizeof *sess);
@ -869,6 +912,7 @@ pgw_sess_t *pgw_sess_find_by_imsi_apn(
pgw_sess_t *pgw_sess_add_by_message(ogs_gtp_message_t *message)
{
pgw_sess_t *sess = NULL;
ogs_paa_t *paa = NULL;
char apn[OGS_MAX_APN_LEN];
ogs_gtp_create_session_request_t *req = &message->create_session_request;
@ -906,7 +950,7 @@ pgw_sess_t *pgw_sess_add_by_message(ogs_gtp_message_t *message)
apn, req->pdn_type.u8,
req->bearer_contexts_to_be_created.eps_bearer_id.u8);
ogs_paa_t *paa = (ogs_paa_t *)req->pdn_address_allocation.data;
paa = (ogs_paa_t *)req->pdn_address_allocation.data;
/*
* 7.2.1 in 3GPP TS 29.274 Release 15
@ -1156,79 +1200,93 @@ pgw_pf_t *pgw_pf_next(pgw_pf_t *pf)
int pgw_ue_pool_generate(void)
{
int j;
int i, rv;
pgw_subnet_t *subnet = NULL;
for (subnet = pgw_subnet_first();
subnet; subnet = pgw_subnet_next(subnet)) {
int index = 0;
uint32_t mask_count;
uint32_t broadcast[4];
int maxbytes = 0;
int lastindex = 0;
uint32_t start[4], end[4], broadcast[4];
int rangeindex, num_of_range;
int poolindex;
int inc;
if (subnet->family == AF_INET) {
if (subnet->prefixlen == 32)
mask_count = 1;
else if (subnet->prefixlen < 32)
mask_count = (0xffffffff >> subnet->prefixlen) + 1;
else
{
ogs_assert_if_reached();
return OGS_ERROR;
}
} else if (subnet->family == AF_INET6) {
if (subnet->prefixlen == 128)
mask_count = 1;
else if (subnet->prefixlen > 96 && subnet->prefixlen < 128)
mask_count = (0xffffffff >> (subnet->prefixlen - 96)) + 1;
else if (subnet->prefixlen <= 96)
mask_count = 0xffffffff;
else {
ogs_assert_if_reached();
return OGS_ERROR;
}
} else {
ogs_assert_if_reached();
return OGS_ERROR;
maxbytes = 4;
lastindex = 0;
}
for (j = 0; j < 4; j++) {
broadcast[j] = subnet->sub.sub[j] + ~subnet->sub.mask[j];
else if (subnet->family == AF_INET6) {
maxbytes = 16;
lastindex = 3;
}
for (j = 0; j < mask_count && index < ogs_config()->pool.sess; j++) {
pgw_ue_ip_t *ue_ip = NULL;
int maxbytes = 0;
int lastindex = 0;
ue_ip = &subnet->pool.array[index];
ogs_assert(ue_ip);
memset(ue_ip, 0, sizeof *ue_ip);
if (subnet->family == AF_INET) {
maxbytes = 4;
lastindex = 0;
}
else if (subnet->family == AF_INET6) {
maxbytes = 16;
lastindex = 3;
}
memcpy(ue_ip->addr, subnet->sub.sub, maxbytes);
ue_ip->addr[lastindex] += htonl(j);
ue_ip->subnet = subnet;
/* Exclude Network Address */
if (memcmp(ue_ip->addr, subnet->sub.sub, maxbytes) == 0) continue;
/* Exclude Broadcast Address */
if (memcmp(ue_ip->addr, broadcast, maxbytes) == 0) continue;
/* Exclude TUN IP Address */
if (memcmp(ue_ip->addr, subnet->gw.sub, maxbytes) == 0) continue;
index++;
for (i = 0; i < 4; i++) {
broadcast[i] = subnet->sub.sub[i] + ~subnet->sub.mask[i];
}
subnet->pool.size = subnet->pool.avail = index;
num_of_range = subnet->num_of_range;
if (!num_of_range) num_of_range = 1;
poolindex = 0;
for (rangeindex = 0; rangeindex < num_of_range; rangeindex++) {
if (subnet->num_of_range &&
subnet->range[rangeindex].low) {
ogs_ipsubnet_t low;
rv = ogs_ipsubnet(
&low, subnet->range[rangeindex].low, NULL);
ogs_assert(rv == OGS_OK);
memcpy(start, low.sub, maxbytes);
} else {
memcpy(start, subnet->sub.sub, maxbytes);
}
if (subnet->num_of_range &&
subnet->range[rangeindex].high) {
ogs_ipsubnet_t high;
rv = ogs_ipsubnet(
&high, subnet->range[rangeindex].high, NULL);
ogs_assert(rv == OGS_OK);
high.sub[lastindex] += htonl(1);
memcpy(end, high.sub, maxbytes);
} else {
memcpy(end, broadcast, maxbytes);
}
inc = 0;
while(poolindex < ogs_config()->pool.sess) {
pgw_ue_ip_t *ue_ip = NULL;
ue_ip = &subnet->pool.array[poolindex];
ogs_assert(ue_ip);
memset(ue_ip, 0, sizeof *ue_ip);
ue_ip->subnet = subnet;
memcpy(ue_ip->addr, start, maxbytes);
ue_ip->addr[lastindex] += htonl(inc);
inc++;
if (memcmp(ue_ip->addr, end, maxbytes) == 0)
break;
/* Exclude Network Address */
if (memcmp(ue_ip->addr, subnet->sub.sub, maxbytes) == 0)
continue;
/* Exclude TUN IP Address */
if (memcmp(ue_ip->addr, subnet->gw.sub, maxbytes) == 0)
continue;
ogs_debug("[%d] - %x:%x:%x:%x",
poolindex,
ue_ip->addr[0], ue_ip->addr[1],
ue_ip->addr[2], ue_ip->addr[3]);
poolindex++;
}
}
subnet->pool.size = subnet->pool.avail = poolindex;
}
return OGS_OK;
@ -1272,47 +1330,30 @@ pgw_ue_ip_t *pgw_ue_ip_alloc(int family, const char *apn, uint8_t *addr)
pgw_subnet_t *subnet = NULL;
pgw_ue_ip_t *ue_ip = NULL;
uint8_t zero[16];
size_t maxbytes = 0;
ogs_assert(apn);
subnet = find_subnet(family, apn);
ogs_assert(subnet);
bool static_ip = 0;
int address_size = 0;
memset(zero, 0, sizeof zero);
if (family == AF_INET) {
address_size = 4;
maxbytes = 4;
} else if (family == AF_INET6) {
address_size = 16;
maxbytes = 16;
} else {
ogs_error("unknown address family!");
ogs_assert(0);
}
// if address is all zeros, we are allocating dynamically
int i = 0;
for(i = 0; i < address_size; i++) {
if (addr[i] != 0) {
static_ip = 1;
break;
}
}
// mismatch error cases
if (!subnet->static_pool && static_ip) {
ogs_warn("HSS assigning static IP but PGW subnet is dynamic (default). Ignoring HSS-assigned IP and proceeding with dynamic allocation...");
}
if (subnet->static_pool && !static_ip) {
ogs_error("PGW subnet is static but HSS did not assign the UE an IP. Cannot proceed with assignment.");
ogs_assert(ue_ip);
return ue_ip;
ogs_fatal("Invalid family[%d]", family);
ogs_assert_if_reached();
}
// if assigning a static IP, do so. If not, assign dynamically!
if (subnet->static_pool) {
ue_ip = calloc(1, sizeof(pgw_ue_ip_t));
if (memcmp(addr, zero, maxbytes) != 0) {
ue_ip = ogs_calloc(1, sizeof(pgw_ue_ip_t));
ue_ip->subnet = subnet;
memcpy(ue_ip->addr, addr, address_size);
ue_ip->static_ip = true;
memcpy(ue_ip->addr, addr, maxbytes);
} else {
ogs_pool_alloc(&subnet->pool, &ue_ip);
}
@ -1330,8 +1371,8 @@ int pgw_ue_ip_free(pgw_ue_ip_t *ue_ip)
ogs_assert(subnet);
if (subnet->static_pool) {
free(ue_ip);
if (ue_ip->static_ip) {
ogs_free(ue_ip);
} else {
ogs_pool_free(&subnet->pool, ue_ip);
}
@ -1407,7 +1448,7 @@ pgw_dev_t *pgw_dev_next(pgw_dev_t *dev)
pgw_subnet_t *pgw_subnet_add(
const char *ipstr, const char *mask_or_numbits,
const char *apn, const char *ifname, bool static_pool)
const char *apn, const char *ifname)
{
int rv;
pgw_dev_t *dev = NULL;
@ -1442,8 +1483,6 @@ pgw_subnet_t *pgw_subnet_add(
ogs_pool_init(&subnet->pool, ogs_config()->pool.sess);
subnet->static_pool = static_pool;
ogs_list_add(&self.subnet_list, subnet);
return subnet;

View File

@ -95,6 +95,7 @@ typedef struct pgw_context_s {
typedef struct pgw_subnet_s pgw_subnet_t;
typedef struct pgw_ue_ip_s {
uint32_t addr[4];
bool static_ip;
/* Related Context */
pgw_subnet_t *subnet;
@ -117,13 +118,22 @@ typedef struct pgw_subnet_s {
ogs_ipsubnet_t gw; /* Gateway : cafe::1 */
char apn[OGS_MAX_APN_LEN]; /* APN : "internet", "volte", .. */
bool static_pool; /* Does the pool assign addresses dynamically or statically via HSS */
int family; /* AF_INET or AF_INET6 */
uint8_t prefixlen; /* prefixlen */
#define MAX_NUM_OF_SUBNET_RANGE 16
struct {
#if 0
ogs_ipsubnet_t low, high;
#else
const char *low;
const char *high;
#endif
} range[MAX_NUM_OF_SUBNET_RANGE];
int num_of_range;
int family; /* AF_INET or AF_INET6 */
uint8_t prefixlen; /* prefixlen */
OGS_POOL(pool, pgw_ue_ip_t);
/* Related Context */
pgw_dev_t *dev;
pgw_dev_t *dev; /* Related Context */
} pgw_subnet_t;
typedef struct pgw_sess_s {
@ -273,7 +283,7 @@ pgw_dev_t *pgw_dev_next(pgw_dev_t *dev);
pgw_subnet_t *pgw_subnet_add(
const char *ipstr, const char *mask_or_numbits,
const char *apn, const char *ifname, bool static_pool);
const char *apn, const char *ifname);
pgw_subnet_t *pgw_subnet_next(pgw_subnet_t *subnet);
int pgw_subnet_remove(pgw_subnet_t *subnet);
void pgw_subnet_remove_all(void);

View File

@ -1,6 +1,6 @@
{
"name": "open5gs",
"version": "1.0.0",
"version": "1.1.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View File

@ -1,6 +1,6 @@
{
"name": "open5gs",
"version": "1.0.0",
"version": "1.1.0",
"description": "Open5gs",
"main": "index.js",
"repository": "https://github.com/open5gs/webui",

View File

@ -38,6 +38,10 @@ const Profile = new Schema({
downlink: Schema.Types.Long,
uplink: Schema.Types.Long
},
ue: {
addr: String,
addr6: String
},
pgw: {
addr: String,
addr6: String

View File

@ -58,6 +58,10 @@ const Subscriber = new Schema({
downlink: Schema.Types.Long,
uplink: Schema.Types.Long
},
ue: {
addr: String,
addr6: String
},
pgw: {
addr: String,
addr6: String

View File

@ -51,7 +51,7 @@ const Header = ({ onSidebarToggle, onLogoutRequest }) => (
<MenuIcon/>
</Menu>
<Title>
Next.EPC
Open5GS
</Title>
<Thumbnail onClick={onLogoutRequest}>
<Tooltip bottom content='Logout' width="60px">
@ -65,4 +65,4 @@ const Header = ({ onSidebarToggle, onLogoutRequest }) => (
Header.propTypes = propTypes;
export default Header;
export default Header;

View File

@ -19,7 +19,7 @@ const propTypes = {
}
const defaultProps = {
title: `Next.EPC ${Package.version}`
title: `Open5GS ${Package.version}`
}
const Layout = ({ title, children }) => (
@ -52,4 +52,4 @@ Layout.Container = ({visible, children}) => visible ? (
Layout.Content = styled.div`
`;
export default Layout;
export default Layout;

View File

@ -141,6 +141,22 @@ const schema = {
},
}
},
"ue": {
"type": "object",
"title": "",
"properties": {
"addr": {
"type": "string",
"title": "UE IPv4 Address",
"format" : "ipv4"
},
"addr6": {
"type": "string",
"title": "UE IPv6 Address",
"format" : "ipv6"
},
}
},
"pgw": {
"type": "object",
"title": "",
@ -332,6 +348,14 @@ const uiSchema = {
classNames: "col-xs-6"
},
},
"ue" : {
"addr" : {
classNames: "col-xs-6"
},
"addr6" : {
classNames: "col-xs-6"
},
},
"pgw" : {
"addr" : {
classNames: "col-xs-6"

View File

@ -258,7 +258,6 @@ const View = ({ visible, disableOnClickOutside, profile, onEdit, onDelete, onHid
<div className="medium_data">Vulnerablility</div>
<div className="large_data">MBR DL/UL(Kbps)</div>
<div className="large_data">GBR DL/UL(Kbps)</div>
<div className="medium_data">PGW IP</div>
</div>
{pdns.map(pdn =>
<div key={pdn.apn}>
@ -279,9 +278,25 @@ const View = ({ visible, disableOnClickOutside, profile, onEdit, onDelete, onHid
</div>
}
<div className="large_data"></div>
<div className="small_data">{(pdn.pgw || {}).addr}</div>
<div className="small_data">{(pdn.pgw || {}).addr6}</div>
</div>
{pdn['ue'] !== undefined &&
<div className="body">
<div className="medium_data"></div>
<div className="medium_data" style={{color:oc.gray[5]}}>{"UE IPv4"} </div>
<div className="large_data">{(pdn.ue || {}).addr}</div>
<div className="medium_data" style={{color:oc.gray[5]}}>{"UE IPv6"} </div>
<div className="large_data">{(pdn.ue || {}).addr6}</div>
</div>
}
{pdn['pgw'] !== undefined &&
<div className="body">
<div className="medium_data"></div>
<div className="medium_data" style={{color:oc.gray[5]}}>{"PGW IPv4"} </div>
<div className="large_data">{(pdn.pgw || {}).addr}</div>
<div className="medium_data" style={{color:oc.gray[5]}}>{"PGW IPv6"} </div>
<div className="large_data">{(pdn.pgw || {}).addr6}</div>
</div>
}
{pdn['pcc_rule'] !== undefined &&
pdn.pcc_rule.map((pcc_rule, index) =>
<div key={index}>

View File

@ -147,6 +147,22 @@ const schema = {
},
}
},
"ue": {
"type": "object",
"title": "",
"properties": {
"addr": {
"type": "string",
"title": "UE IPv4 Address",
"format" : "ipv4"
},
"addr6": {
"type": "string",
"title": "UE IPv6 Address",
"format" : "ipv6"
},
}
},
"pgw": {
"type": "object",
"title": "",
@ -338,6 +354,14 @@ const uiSchema = {
classNames: "col-xs-6"
},
},
"ue" : {
"addr" : {
classNames: "col-xs-6"
},
"addr6" : {
classNames: "col-xs-6"
},
},
"pgw" : {
"addr" : {
classNames: "col-xs-6"

View File

@ -257,7 +257,6 @@ const View = ({ visible, disableOnClickOutside, subscriber, onEdit, onDelete, on
<div className="medium_data">Vulnerablility</div>
<div className="large_data">MBR DL/UL(Kbps)</div>
<div className="large_data">GBR DL/UL(Kbps)</div>
<div className="medium_data">PGW IP</div>
</div>
{pdns.map(pdn =>
<div key={pdn.apn}>
@ -278,9 +277,25 @@ const View = ({ visible, disableOnClickOutside, subscriber, onEdit, onDelete, on
</div>
}
<div className="large_data"></div>
<div className="small_data">{(pdn.pgw || {}).addr}</div>
<div className="small_data">{(pdn.pgw || {}).addr6}</div>
</div>
{pdn['ue'] !== undefined &&
<div className="body">
<div className="medium_data"></div>
<div className="medium_data" style={{color:oc.gray[5]}}>{"UE IPv4"} </div>
<div className="large_data">{(pdn.ue || {}).addr}</div>
<div className="medium_data" style={{color:oc.gray[5]}}>{"UE IPv6"} </div>
<div className="large_data">{(pdn.ue || {}).addr6}</div>
</div>
}
{pdn['pgw'] !== undefined &&
<div className="body">
<div className="medium_data"></div>
<div className="medium_data" style={{color:oc.gray[5]}}>{"PGW IPv4"} </div>
<div className="large_data">{(pdn.pgw || {}).addr}</div>
<div className="medium_data" style={{color:oc.gray[5]}}>{"PGW IPv6"} </div>
<div className="large_data">{(pdn.pgw || {}).addr6}</div>
</div>
}
{pdn['pcc_rule'] !== undefined &&
pdn.pcc_rule.map((pcc_rule, index) =>
<div key={index}>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 15 KiB