mirror of
				https://github.com/open5gs/open5gs.git
				synced 2025-11-04 05:53:18 +00:00 
			
		
		
		
	[#306] Refine static IP addresses
This commit is contained 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
 | 
			
		||||
 
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 15 KiB  | 
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								webui/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								webui/package-lock.json
									
									
									
										generated
									
									
									
								
							@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "open5gs",
 | 
			
		||||
  "version": "1.0.0",
 | 
			
		||||
  "version": "1.1.0",
 | 
			
		||||
  "lockfileVersion": 1,
 | 
			
		||||
  "requires": true,
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
 
 | 
			
		||||
@@ -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",
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -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"
 | 
			
		||||
 
 | 
			
		||||
@@ -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}>
 | 
			
		||||
 
 | 
			
		||||
@@ -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"
 | 
			
		||||
 
 | 
			
		||||
@@ -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  | 
		Reference in New Issue
	
	Block a user