diff --git a/configs/installed.yaml.in b/configs/installed.yaml.in
index f32f85420..a54d7d801 100644
--- a/configs/installed.yaml.in
+++ b/configs/installed.yaml.in
@@ -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
diff --git a/docs/assets/favicon.ico b/docs/assets/favicon.ico
index f92925820..c2a6b52b4 100644
Binary files a/docs/assets/favicon.ico and b/docs/assets/favicon.ico differ
diff --git a/lib/core/ogs-3gpp-types.h b/lib/core/ogs-3gpp-types.h
index 4b8008e23..45220e2e5 100644
--- a/lib/core/ogs-3gpp-types.h
+++ b/lib/core/ogs-3gpp-types.h
@@ -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;
diff --git a/misc/dbconf.sh b/misc/dbconf.sh
index cb9253f4a..8c0c445c8 100755
--- a/misc/dbconf.sh
+++ b/misc/dbconf.sh
@@ -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
diff --git a/src/hss/hss-context.c b/src/hss/hss-context.c
index 7212f84ad..95d3c3d7f 100644
--- a/src/hss/hss-context.c
+++ b/src/hss/hss-context.c
@@ -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);
}
}
}
diff --git a/src/hss/hss-fd-path.c b/src/hss/hss-fd-path.c
index 58c2d7a64..df2de868f 100644
--- a/src/hss/hss-fd-path.c
+++ b/src/hss/hss-fd-path.c
@@ -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);
}
diff --git a/src/mme/mme-fd-path.c b/src/mme/mme-fd-path.c
index c7b950f23..2a5ff9ddb 100644
--- a/src/mme/mme-fd-path.c
+++ b/src/mme/mme-fd-path.c
@@ -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);
diff --git a/src/mme/mme-s11-build.c b/src/mme/mme-s11-build.c
index fa0011d2d..75483bcaf 100644
--- a/src/mme/mme-s11-build.c
+++ b/src/mme/mme-s11-build.c
@@ -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);
diff --git a/src/pgw/pgw-context.c b/src/pgw/pgw-context.c
index e66ea1945..6ea3c07a2 100644
--- a/src/pgw/pgw-context.c
+++ b/src/pgw/pgw-context.c
@@ -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;
diff --git a/src/pgw/pgw-context.h b/src/pgw/pgw-context.h
index 3ca4c8064..b340d17d6 100644
--- a/src/pgw/pgw-context.h
+++ b/src/pgw/pgw-context.h
@@ -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);
diff --git a/webui/package-lock.json b/webui/package-lock.json
index c11ef13a1..0b851e6ab 100644
--- a/webui/package-lock.json
+++ b/webui/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "open5gs",
- "version": "1.0.0",
+ "version": "1.1.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/webui/package.json b/webui/package.json
index c32a56905..0f389cc9c 100644
--- a/webui/package.json
+++ b/webui/package.json
@@ -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",
diff --git a/webui/server/models/profile.js b/webui/server/models/profile.js
index 919b69013..70726867e 100644
--- a/webui/server/models/profile.js
+++ b/webui/server/models/profile.js
@@ -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
diff --git a/webui/server/models/subscriber.js b/webui/server/models/subscriber.js
index ca4b5d94f..da74c7b8b 100644
--- a/webui/server/models/subscriber.js
+++ b/webui/server/models/subscriber.js
@@ -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
diff --git a/webui/src/components/Base/Header.js b/webui/src/components/Base/Header.js
index 21276d861..e6ddf3b8a 100644
--- a/webui/src/components/Base/Header.js
+++ b/webui/src/components/Base/Header.js
@@ -51,7 +51,7 @@ const Header = ({ onSidebarToggle, onLogoutRequest }) => (