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 }) => ( - Next.EPC + Open5GS @@ -65,4 +65,4 @@ const Header = ({ onSidebarToggle, onLogoutRequest }) => ( Header.propTypes = propTypes; -export default Header; \ No newline at end of file +export default Header; diff --git a/webui/src/components/Base/Layout.js b/webui/src/components/Base/Layout.js index 79b706938..9c801053a 100644 --- a/webui/src/components/Base/Layout.js +++ b/webui/src/components/Base/Layout.js @@ -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; \ No newline at end of file +export default Layout; diff --git a/webui/src/components/Profile/Edit.js b/webui/src/components/Profile/Edit.js index 723c92732..9c43c39fb 100644 --- a/webui/src/components/Profile/Edit.js +++ b/webui/src/components/Profile/Edit.js @@ -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" diff --git a/webui/src/components/Profile/View.js b/webui/src/components/Profile/View.js index 2a46cca49..eb244fa42 100644 --- a/webui/src/components/Profile/View.js +++ b/webui/src/components/Profile/View.js @@ -258,7 +258,6 @@ const View = ({ visible, disableOnClickOutside, profile, onEdit, onDelete, onHid
Vulnerablility
MBR DL/UL(Kbps)
GBR DL/UL(Kbps)
-
PGW IP
{pdns.map(pdn =>
@@ -279,9 +278,25 @@ const View = ({ visible, disableOnClickOutside, profile, onEdit, onDelete, onHid
}
-
{(pdn.pgw || {}).addr}
-
{(pdn.pgw || {}).addr6}
+ {pdn['ue'] !== undefined && +
+
+
{"UE IPv4"}
+
{(pdn.ue || {}).addr}
+
{"UE IPv6"}
+
{(pdn.ue || {}).addr6}
+
+ } + {pdn['pgw'] !== undefined && +
+
+
{"PGW IPv4"}
+
{(pdn.pgw || {}).addr}
+
{"PGW IPv6"}
+
{(pdn.pgw || {}).addr6}
+
+ } {pdn['pcc_rule'] !== undefined && pdn.pcc_rule.map((pcc_rule, index) =>
diff --git a/webui/src/components/Subscriber/Edit.js b/webui/src/components/Subscriber/Edit.js index ca56df429..21a77fc95 100644 --- a/webui/src/components/Subscriber/Edit.js +++ b/webui/src/components/Subscriber/Edit.js @@ -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" diff --git a/webui/src/components/Subscriber/View.js b/webui/src/components/Subscriber/View.js index 356d829af..e48751c84 100644 --- a/webui/src/components/Subscriber/View.js +++ b/webui/src/components/Subscriber/View.js @@ -257,7 +257,6 @@ const View = ({ visible, disableOnClickOutside, subscriber, onEdit, onDelete, on
Vulnerablility
MBR DL/UL(Kbps)
GBR DL/UL(Kbps)
-
PGW IP
{pdns.map(pdn =>
@@ -278,9 +277,25 @@ const View = ({ visible, disableOnClickOutside, subscriber, onEdit, onDelete, on
}
-
{(pdn.pgw || {}).addr}
-
{(pdn.pgw || {}).addr6}
+ {pdn['ue'] !== undefined && +
+
+
{"UE IPv4"}
+
{(pdn.ue || {}).addr}
+
{"UE IPv6"}
+
{(pdn.ue || {}).addr6}
+
+ } + {pdn['pgw'] !== undefined && +
+
+
{"PGW IPv4"}
+
{(pdn.pgw || {}).addr}
+
{"PGW IPv6"}
+
{(pdn.pgw || {}).addr6}
+
+ } {pdn['pcc_rule'] !== undefined && pdn.pcc_rule.map((pcc_rule, index) =>
diff --git a/webui/static/favicon.ico b/webui/static/favicon.ico index 764e0c353..c2a6b52b4 100644 Binary files a/webui/static/favicon.ico and b/webui/static/favicon.ico differ