forked from acouzens/open5gs
Session-AMBR changes required field in WebUI
This commit is contained in:
parent
dbee687a75
commit
c54e85c5c0
|
@ -133,11 +133,11 @@ int ogs_asn_BIT_STRING_to_ip(BIT_STRING_t *bit_string, ogs_ip_t *ip)
|
|||
if (bit_string->size == OGS_IPV4V6_LEN) {
|
||||
ip->ipv4 = 1;
|
||||
ip->ipv6 = 1;
|
||||
memcpy(&ip->both.addr, bit_string->buf, OGS_IPV4_LEN);
|
||||
memcpy(&ip->both.addr6, bit_string->buf+OGS_IPV4_LEN, OGS_IPV6_LEN);
|
||||
memcpy(&ip->addr, bit_string->buf, OGS_IPV4_LEN);
|
||||
memcpy(&ip->addr6, bit_string->buf+OGS_IPV4_LEN, OGS_IPV6_LEN);
|
||||
ogs_debug(" IPv4[%s] IPv6[%s]",
|
||||
OGS_INET_NTOP(&ip->both.addr, buf),
|
||||
OGS_INET6_NTOP(&ip->both.addr6, buf2));
|
||||
OGS_INET_NTOP(&ip->addr, buf),
|
||||
OGS_INET6_NTOP(&ip->addr6, buf2));
|
||||
} else if (bit_string->size == OGS_IPV4_LEN) {
|
||||
ip->ipv4 = 1;
|
||||
memcpy(&ip->addr, bit_string->buf, OGS_IPV4_LEN);
|
||||
|
@ -163,11 +163,11 @@ int ogs_asn_ip_to_BIT_STRING(ogs_ip_t *ip, BIT_STRING_t *bit_string)
|
|||
if (ip->ipv4 && ip->ipv6) {
|
||||
bit_string->size = OGS_IPV4V6_LEN;
|
||||
bit_string->buf = CALLOC(bit_string->size, sizeof(uint8_t));
|
||||
memcpy(bit_string->buf, &ip->both.addr, OGS_IPV4_LEN);
|
||||
memcpy(bit_string->buf+OGS_IPV4_LEN, &ip->both.addr6, OGS_IPV6_LEN);
|
||||
memcpy(bit_string->buf, &ip->addr, OGS_IPV4_LEN);
|
||||
memcpy(bit_string->buf+OGS_IPV4_LEN, &ip->addr6, OGS_IPV6_LEN);
|
||||
ogs_debug(" IPv4[%s] IPv6[%s]",
|
||||
OGS_INET_NTOP(&ip->both.addr, buf),
|
||||
OGS_INET6_NTOP(&ip->both.addr6, buf2));
|
||||
OGS_INET_NTOP(&ip->addr, buf),
|
||||
OGS_INET6_NTOP(&ip->addr6, buf2));
|
||||
} else if (ip->ipv4) {
|
||||
bit_string->size = OGS_IPV4_LEN;
|
||||
bit_string->buf = CALLOC(bit_string->size, sizeof(uint8_t));
|
||||
|
|
|
@ -407,8 +407,8 @@ int ogs_ip_to_sockaddr(ogs_ip_t *ip, uint16_t port, ogs_sockaddr_t **list)
|
|||
if (ip->ipv4 && ip->ipv6) {
|
||||
addr->next = addr6;
|
||||
|
||||
addr->sin.sin_addr.s_addr = ip->both.addr;
|
||||
memcpy(addr6->sin6.sin6_addr.s6_addr, ip->both.addr6, OGS_IPV6_LEN);
|
||||
addr->sin.sin_addr.s_addr = ip->addr;
|
||||
memcpy(addr6->sin6.sin6_addr.s6_addr, ip->addr6, OGS_IPV6_LEN);
|
||||
|
||||
*list = addr;
|
||||
} else if (ip->ipv4) {
|
||||
|
@ -442,8 +442,8 @@ void ogs_sockaddr_to_ip(
|
|||
ip->ipv4 = 1;
|
||||
ip->ipv6 = 1;
|
||||
ip->len = OGS_IPV4V6_LEN;
|
||||
ip->both.addr = addr->sin.sin_addr.s_addr;
|
||||
memcpy(ip->both.addr6, addr6->sin6.sin6_addr.s6_addr, OGS_IPV6_LEN);
|
||||
ip->addr = addr->sin.sin_addr.s_addr;
|
||||
memcpy(ip->addr6, addr6->sin6.sin6_addr.s6_addr, OGS_IPV6_LEN);
|
||||
} else if (addr) {
|
||||
ip->ipv4 = 1;
|
||||
ip->len = OGS_IPV4_LEN;
|
||||
|
|
|
@ -48,8 +48,8 @@ extern "C" {
|
|||
OGS_BCD_TO_BUFFER_LEN(OGS_MAX_IMEISV_BCD_LEN)
|
||||
|
||||
#define OGS_MAX_NUM_OF_HOSTNAME 16
|
||||
#define OGS_MAX_APN_LEN 100
|
||||
#define OGS_MAX_DNN_LEN 100
|
||||
#define OGS_MAX_APN_LEN OGS_MAX_DNN_LEN
|
||||
#define OGS_MAX_PCO_LEN 251
|
||||
#define OGS_MAX_FQDN_LEN 256
|
||||
|
||||
|
@ -213,14 +213,8 @@ ogs_uint24_t ogs_s_nssai_sd_from_string(const char *hex);
|
|||
#define OGS_IPV6_LEN 16
|
||||
#define OGS_IPV4V6_LEN 20
|
||||
typedef struct ogs_ip_s {
|
||||
union {
|
||||
uint32_t addr;
|
||||
uint8_t addr6[OGS_IPV6_LEN];
|
||||
struct {
|
||||
uint32_t addr;
|
||||
uint8_t addr6[OGS_IPV6_LEN];
|
||||
} both;
|
||||
};
|
||||
uint32_t addr;
|
||||
uint8_t addr6[OGS_IPV6_LEN];
|
||||
uint32_t len;
|
||||
ED3(uint8_t ipv4:1;,
|
||||
uint8_t ipv6:1;,
|
||||
|
@ -405,7 +399,10 @@ typedef struct ogs_pcc_rule_s {
|
|||
* PDN Structure */
|
||||
typedef struct ogs_pdn_s {
|
||||
uint32_t context_identifier;
|
||||
char apn[OGS_MAX_APN_LEN+1];
|
||||
union {
|
||||
char apn[OGS_MAX_APN_LEN+1];
|
||||
char dnn[OGS_MAX_DNN_LEN+1];
|
||||
};
|
||||
#define OGS_DIAM_PDN_TYPE_IPV4 0
|
||||
#define OGS_DIAM_PDN_TYPE_IPV6 1
|
||||
#define OGS_DIAM_PDN_TYPE_IPV4V6 2
|
||||
|
@ -426,10 +423,7 @@ typedef struct ogs_pdn_s {
|
|||
ogs_bitrate_t ambr; /* APN-AMBR */
|
||||
|
||||
ogs_paa_t paa;
|
||||
struct {
|
||||
uint32_t addr;
|
||||
uint8_t addr6[OGS_IPV6_LEN];
|
||||
} ue_ip;
|
||||
ogs_ip_t ue_ip;
|
||||
ogs_ip_t pgw_ip;
|
||||
} ogs_pdn_t;
|
||||
|
||||
|
@ -486,6 +480,33 @@ ED3(uint8_t ext:1;,
|
|||
int ogs_pco_parse(ogs_pco_t *pco, unsigned char *data, int data_len);
|
||||
int ogs_pco_build(unsigned char *data, int data_len, ogs_pco_t *pco);
|
||||
|
||||
typedef struct ogs_subscription_data_s {
|
||||
#define OGS_ACCESS_RESTRICTION_UTRAN_NOT_ALLOWED (1)
|
||||
#define OGS_ACCESS_RESTRICTION_GERAN_NOT_ALLOWED (1<<1)
|
||||
#define OGS_ACCESS_RESTRICTION_GAN_NOT_ALLOWED (1<<2)
|
||||
#define OGS_ACCESS_RESTRICTION_I_HSPA_EVOLUTION_NOT_ALLOWED (1<<3)
|
||||
#define OGS_ACCESS_RESTRICTION_WB_E_UTRAN_NOT_ALLOWED (1<<4)
|
||||
#define OGS_ACCESS_RESTRICTION_HO_TO_NON_3GPP_ACCESS_NOT_ALLOWED (1<<5)
|
||||
#define OGS_ACCESS_RESTRICTION_NB_IOT_NOT_ALLOWED (1<<6)
|
||||
uint32_t access_restriction_data;
|
||||
#define OGS_SUBSCRIBER_STATUS_SERVICE_GRANTED 0
|
||||
#define OGS_SUBSCRIBER_STATUS_OPERATOR_DETERMINED_BARRING 1
|
||||
uint32_t subscriber_status;
|
||||
#define OGS_NETWORK_ACCESS_MODE_PACKET_AND_CIRCUIT 0
|
||||
#define OGS_NETWORK_ACCESS_MODE_RESERVED 1
|
||||
#define OGS_NETWORK_ACCESS_MODE_ONLY_PACKET 2
|
||||
uint32_t network_access_mode;
|
||||
|
||||
ogs_bitrate_t ambr; /* UE-AMBR */
|
||||
|
||||
#define OGS_RAU_TAU_DEFAULT_TIME (12*60) /* 12 min */
|
||||
uint32_t subscribed_rau_tau_timer; /* unit : seconds */
|
||||
|
||||
uint32_t context_identifier; /* default APN */
|
||||
ogs_pdn_t pdn[OGS_MAX_NUM_OF_SESS];
|
||||
int num_of_pdn;
|
||||
} ogs_subscription_data_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -97,6 +97,8 @@ void ogs_hash_destroy(ogs_hash_t *ht)
|
|||
|
||||
ogs_hash_index_t *ogs_hash_next(ogs_hash_index_t *hi)
|
||||
{
|
||||
ogs_assert(hi);
|
||||
|
||||
hi->this = hi->next;
|
||||
while (!hi->this) {
|
||||
if (hi->index > hi->ht->max)
|
||||
|
@ -112,6 +114,8 @@ ogs_hash_index_t *ogs_hash_first(ogs_hash_t *ht)
|
|||
{
|
||||
ogs_hash_index_t *hi;
|
||||
|
||||
ogs_assert(ht);
|
||||
|
||||
hi = &ht->iterator;
|
||||
|
||||
hi->ht = ht;
|
||||
|
@ -124,6 +128,8 @@ ogs_hash_index_t *ogs_hash_first(ogs_hash_t *ht)
|
|||
void ogs_hash_this(ogs_hash_index_t *hi,
|
||||
const void **key, int *klen, void **val)
|
||||
{
|
||||
ogs_assert(hi);
|
||||
|
||||
if (key) *key = hi->this->key;
|
||||
if (klen) *klen = hi->this->klen;
|
||||
if (val) *val = (void *)hi->this->val;
|
||||
|
@ -276,6 +282,11 @@ static ogs_hash_entry_t **find_entry(ogs_hash_t *ht,
|
|||
void *ogs_hash_get(ogs_hash_t *ht, const void *key, int klen)
|
||||
{
|
||||
ogs_hash_entry_t *he;
|
||||
|
||||
ogs_assert(ht);
|
||||
ogs_assert(key);
|
||||
ogs_assert(klen);
|
||||
|
||||
he = *find_entry(ht, key, klen, NULL);
|
||||
if (he)
|
||||
return (void *)he->val;
|
||||
|
@ -286,6 +297,11 @@ void *ogs_hash_get(ogs_hash_t *ht, const void *key, int klen)
|
|||
void ogs_hash_set(ogs_hash_t *ht, const void *key, int klen, const void *val)
|
||||
{
|
||||
ogs_hash_entry_t **hep;
|
||||
|
||||
ogs_assert(ht);
|
||||
ogs_assert(key);
|
||||
ogs_assert(klen);
|
||||
|
||||
hep = find_entry(ht, key, klen, val);
|
||||
if (*hep) {
|
||||
if (!val) {
|
||||
|
@ -311,6 +327,11 @@ void *ogs_hash_get_or_set(ogs_hash_t *ht,
|
|||
const void *key, int klen, const void *val)
|
||||
{
|
||||
ogs_hash_entry_t **hep;
|
||||
|
||||
ogs_assert(ht);
|
||||
ogs_assert(key);
|
||||
ogs_assert(klen);
|
||||
|
||||
hep = find_entry(ht, key, klen, val);
|
||||
if (*hep) {
|
||||
val = (*hep)->val;
|
||||
|
@ -326,12 +347,16 @@ void *ogs_hash_get_or_set(ogs_hash_t *ht,
|
|||
|
||||
unsigned int ogs_hash_count(ogs_hash_t *ht)
|
||||
{
|
||||
ogs_assert(ht);
|
||||
return ht->count;
|
||||
}
|
||||
|
||||
void ogs_hash_clear(ogs_hash_t *ht)
|
||||
{
|
||||
ogs_hash_index_t *hi;
|
||||
|
||||
ogs_assert(ht);
|
||||
|
||||
for (hi = ogs_hash_first(ht); hi; hi = ogs_hash_next(hi))
|
||||
ogs_hash_set(ht, hi->this->key, hi->this->klen, NULL);
|
||||
}
|
||||
|
|
|
@ -203,7 +203,7 @@ out:
|
|||
}
|
||||
|
||||
int ogs_dbi_subscription_data(char *supi,
|
||||
ogs_dbi_subscription_data_t *subscription_data)
|
||||
ogs_subscription_data_t *subscription_data)
|
||||
{
|
||||
int rv = OGS_OK;
|
||||
mongoc_cursor_t *cursor = NULL;
|
||||
|
@ -256,7 +256,7 @@ int ogs_dbi_subscription_data(char *supi,
|
|||
goto out;
|
||||
}
|
||||
|
||||
memset(subscription_data, 0, sizeof(ogs_dbi_subscription_data_t));
|
||||
memset(subscription_data, 0, sizeof(ogs_subscription_data_t));
|
||||
while (bson_iter_next(&iter)) {
|
||||
const char *key = bson_iter_key(&iter);
|
||||
if (!strcmp(key, "access_restriction_data") &&
|
||||
|
@ -380,7 +380,7 @@ int ogs_dbi_subscription_data(char *supi,
|
|||
rv = ogs_ipsubnet(&ipsub, v, NULL);
|
||||
if (rv == OGS_OK) {
|
||||
pdn->pgw_ip.ipv4 = 1;
|
||||
pdn->pgw_ip.both.addr = ipsub.sub[0];
|
||||
pdn->pgw_ip.addr = ipsub.sub[0];
|
||||
}
|
||||
} else if (!strcmp(child3_key, "addr6") &&
|
||||
BSON_ITER_HOLDS_UTF8(&child3_iter)) {
|
||||
|
@ -390,7 +390,7 @@ int ogs_dbi_subscription_data(char *supi,
|
|||
rv = ogs_ipsubnet(&ipsub, v, NULL);
|
||||
if (rv == OGS_OK) {
|
||||
pdn->pgw_ip.ipv6 = 1;
|
||||
memcpy(pdn->pgw_ip.both.addr6,
|
||||
memcpy(pdn->pgw_ip.addr6,
|
||||
ipsub.sub, sizeof(ipsub.sub));
|
||||
}
|
||||
}
|
||||
|
@ -408,15 +408,7 @@ int ogs_dbi_subscription_data(char *supi,
|
|||
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];
|
||||
pdn->ue_ip.ipv4 = true;
|
||||
pdn->ue_ip.addr = ipsub.sub[0];
|
||||
}
|
||||
} else if (!strcmp(child3_key, "addr6") &&
|
||||
|
@ -426,16 +418,7 @@ int ogs_dbi_subscription_data(char *supi,
|
|||
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->ue_ip.ipv6 = true;
|
||||
memcpy(pdn->ue_ip.addr6,
|
||||
ipsub.sub, OGS_IPV6_LEN);
|
||||
}
|
||||
|
|
|
@ -30,32 +30,6 @@ extern "C" {
|
|||
|
||||
#define OGS_DBI_SUPI_TYPE_IMSI "imsi"
|
||||
|
||||
typedef struct ogs_dbi_subscription_data_s {
|
||||
#define OGS_DBI_ACCESS_RESTRICTION_UTRAN_NOT_ALLOWED (1)
|
||||
#define OGS_DBI_ACCESS_RESTRICTION_GERAN_NOT_ALLOWED (1<<1)
|
||||
#define OGS_DBI_ACCESS_RESTRICTION_GAN_NOT_ALLOWED (1<<2)
|
||||
#define OGS_DBI_ACCESS_RESTRICTION_I_HSPA_EVOLUTION_NOT_ALLOWED (1<<3)
|
||||
#define OGS_DBI_ACCESS_RESTRICTION_WB_E_UTRAN_NOT_ALLOWED (1<<4)
|
||||
#define OGS_DBI_ACCESS_RESTRICTION_HO_TO_NON_3GPP_ACCESS_NOT_ALLOWED (1<<5)
|
||||
#define OGS_DBI_ACCESS_RESTRICTION_NB_IOT_NOT_ALLOWED (1<<6)
|
||||
uint32_t access_restriction_data;
|
||||
#define OGS_DBI_SUBSCRIBER_STATUS_SERVICE_GRANTED 0
|
||||
#define OGS_DBI_SUBSCRIBER_STATUS_OPERATOR_DETERMINED_BARRING 1
|
||||
uint32_t subscriber_status;
|
||||
#define OGS_DBI_NETWORK_ACCESS_MODE_PACKET_AND_CIRCUIT 0
|
||||
#define OGS_DBI_NETWORK_ACCESS_MODE_RESERVED 1
|
||||
#define OGS_DBI_NETWORK_ACCESS_MODE_ONLY_PACKET 2
|
||||
uint32_t network_access_mode;
|
||||
|
||||
ogs_bitrate_t ambr; /* UE-AMBR */
|
||||
|
||||
#define OGS_DBI_RAU_TAU_DEFAULT_TIME (12*60) /* 12 min */
|
||||
uint32_t subscribed_rau_tau_timer; /* unit : seconds */
|
||||
|
||||
ogs_pdn_t pdn[OGS_MAX_NUM_OF_SESS];
|
||||
int num_of_pdn;
|
||||
} ogs_dbi_subscription_data_t;
|
||||
|
||||
typedef struct ogs_dbi_auth_info_s {
|
||||
uint8_t k[OGS_KEY_LEN];
|
||||
uint8_t use_opc;
|
||||
|
@ -71,7 +45,7 @@ int ogs_dbi_update_sqn(char *supi, uint64_t sqn);
|
|||
int ogs_dbi_increment_sqn(char *supi);
|
||||
|
||||
int ogs_dbi_subscription_data(char *supi,
|
||||
ogs_dbi_subscription_data_t *subscription_data);
|
||||
ogs_subscription_data_t *subscription_data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -124,38 +124,11 @@ typedef struct ogs_diam_s6a_aia_message_s {
|
|||
ogs_diam_e_utran_vector_t e_utran_vector;
|
||||
} ogs_diam_s6a_aia_message_t;
|
||||
|
||||
typedef struct ogs_diam_s6a_subscription_data_s {
|
||||
#define OGS_DIAM_S6A_ACCESS_RESTRICTION_UTRAN_NOT_ALLOWED (1)
|
||||
#define OGS_DIAM_S6A_ACCESS_RESTRICTION_GERAN_NOT_ALLOWED (1<<1)
|
||||
#define OGS_DIAM_S6A_ACCESS_RESTRICTION_GAN_NOT_ALLOWED (1<<2)
|
||||
#define OGS_DIAM_S6A_ACCESS_RESTRICTION_I_HSPA_EVOLUTION_NOT_ALLOWED (1<<3)
|
||||
#define OGS_DIAM_S6A_ACCESS_RESTRICTION_WB_E_UTRAN_NOT_ALLOWED (1<<4)
|
||||
#define OGS_DIAM_S6A_ACCESS_RESTRICTION_HO_TO_NON_3GPP_ACCESS_NOT_ALLOWED (1<<5)
|
||||
#define OGS_DIAM_S6A_ACCESS_RESTRICTION_NB_IOT_NOT_ALLOWED (1<<6)
|
||||
uint32_t access_restriction_data;
|
||||
#define OGS_DIAM_S6A_SUBSCRIBER_STATUS_SERVICE_GRANTED 0
|
||||
#define OGS_DIAM_S6A_SUBSCRIBER_STATUS_OPERATOR_DETERMINED_BARRING 1
|
||||
uint32_t subscriber_status;
|
||||
#define OGS_DIAM_S6A_NETWORK_ACCESS_MODE_PACKET_AND_CIRCUIT 0
|
||||
#define OGS_DIAM_S6A_NETWORK_ACCESS_MODE_RESERVED 1
|
||||
#define OGS_DIAM_S6A_NETWORK_ACCESS_MODE_ONLY_PACKET 2
|
||||
uint32_t network_access_mode;
|
||||
|
||||
ogs_bitrate_t ambr; /* UE-AMBR */
|
||||
|
||||
#define OGS_DIAM_S6A_RAU_TAU_DEFAULT_TIME (12*60) /* 12 min */
|
||||
uint32_t subscribed_rau_tau_timer; /* unit : seconds */
|
||||
|
||||
uint32_t context_identifier; /* default APN */
|
||||
ogs_pdn_t pdn[OGS_MAX_NUM_OF_SESS];
|
||||
int num_of_pdn;
|
||||
} ogs_diam_s6a_subscription_data_t;
|
||||
|
||||
typedef struct ogs_diam_s6a_ula_message_s {
|
||||
#define OGS_DIAM_S6A_ULA_FLAGS_SEPARATION_INDICATION (0)
|
||||
#define OGS_DIAM_S6A_ULA_FLAGS_MME_REGISTERED_FOR_SMS (1)
|
||||
uint32_t ula_flags;
|
||||
ogs_diam_s6a_subscription_data_t subscription_data;
|
||||
ogs_subscription_data_t subscription_data;
|
||||
} ogs_diam_s6a_ula_message_t;
|
||||
|
||||
typedef struct ogs_diam_s6a_message_s {
|
||||
|
|
|
@ -136,8 +136,8 @@ int ogs_gtp_f_teid_to_ip(ogs_gtp_f_teid_t *f_teid, ogs_ip_t *ip)
|
|||
ip->ipv6 = f_teid->ipv6;
|
||||
|
||||
if (ip->ipv4 && ip->ipv6) {
|
||||
ip->both.addr = f_teid->both.addr;
|
||||
memcpy(ip->both.addr6, f_teid->both.addr6, OGS_IPV6_LEN);
|
||||
ip->addr = f_teid->both.addr;
|
||||
memcpy(ip->addr6, f_teid->both.addr6, OGS_IPV6_LEN);
|
||||
ip->len = OGS_IPV4V6_LEN;
|
||||
} else if (ip->ipv4) {
|
||||
ip->addr = f_teid->addr;
|
||||
|
@ -160,8 +160,8 @@ int ogs_gtp_ip_to_f_teid(ogs_ip_t *ip, ogs_gtp_f_teid_t *f_teid, int *len)
|
|||
f_teid->ipv6 = ip->ipv6;
|
||||
|
||||
if (f_teid->ipv4 && f_teid->ipv6) {
|
||||
f_teid->both.addr = ip->both.addr;
|
||||
memcpy(f_teid->both.addr6, ip->both.addr6, OGS_IPV6_LEN);
|
||||
f_teid->both.addr = ip->addr;
|
||||
memcpy(f_teid->both.addr6, ip->addr6, OGS_IPV6_LEN);
|
||||
*len = OGS_GTP_F_TEID_IPV4V6_LEN;
|
||||
} else if (f_teid->ipv4) {
|
||||
f_teid->addr = ip->addr;
|
||||
|
|
|
@ -25,6 +25,7 @@ libgtp_sources = files('''
|
|||
build.h
|
||||
path.h
|
||||
xact.h
|
||||
util.h
|
||||
|
||||
message.c
|
||||
types.c
|
||||
|
@ -33,6 +34,7 @@ libgtp_sources = files('''
|
|||
build.c
|
||||
path.c
|
||||
xact.c
|
||||
util.c
|
||||
'''.split())
|
||||
|
||||
libgtp_inc = include_directories('.')
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "gtp/build.h"
|
||||
#include "gtp/path.h"
|
||||
#include "gtp/xact.h"
|
||||
#include "gtp/util.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
||||
*
|
||||
* This file is part of Open5GS.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ogs-gtp.h"
|
||||
|
||||
uint16_t ogs_in_cksum(uint16_t *addr, int len)
|
||||
{
|
||||
int nleft = len;
|
||||
uint32_t sum = 0;
|
||||
uint16_t *w = addr;
|
||||
uint16_t answer = 0;
|
||||
|
||||
// Adding 16 bits sequentially in sum
|
||||
while (nleft > 1) {
|
||||
sum += *w;
|
||||
nleft -= 2;
|
||||
w++;
|
||||
}
|
||||
|
||||
// If an odd byte is left
|
||||
if (nleft == 1) {
|
||||
*(uint8_t *) (&answer) = *(uint8_t *) w;
|
||||
sum += answer;
|
||||
}
|
||||
|
||||
sum = (sum >> 16) + (sum & 0xffff);
|
||||
sum += (sum >> 16);
|
||||
answer = ~sum;
|
||||
|
||||
return answer;
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
||||
*
|
||||
* This file is part of Open5GS.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if !defined(OGS_GTP_INSIDE) && !defined(OGS_GTP_COMPILATION)
|
||||
#error "This header cannot be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef OGS_GTP_UTIL_H
|
||||
#define OGS_GTP_UTIL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
uint16_t ogs_in_cksum(uint16_t *addr, int len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* OGS_GTP_UTIL_H */
|
|
@ -899,12 +899,16 @@ ogs_pfcp_far_t *ogs_pfcp_far_find_or_add(
|
|||
|
||||
void ogs_pfcp_far_remove(ogs_pfcp_far_t *far)
|
||||
{
|
||||
int i;
|
||||
ogs_pfcp_sess_t *sess = NULL;
|
||||
|
||||
ogs_assert(far);
|
||||
sess = far->sess;
|
||||
ogs_assert(sess);
|
||||
|
||||
for (i = 0; i < far->num_of_buffered_packet; i++)
|
||||
ogs_pkbuf_free(far->buffered_packet[i]);
|
||||
|
||||
ogs_list_remove(&sess->far_list, far);
|
||||
ogs_pool_free(&ogs_pfcp_far_pool, far);
|
||||
}
|
||||
|
|
|
@ -136,6 +136,10 @@ typedef struct ogs_pfcp_far_s {
|
|||
ogs_pfcp_outer_header_creation_t outer_header_creation;
|
||||
int outer_header_creation_len;
|
||||
|
||||
#define MAX_NUM_OF_PACKET_BUFFER 512
|
||||
uint32_t num_of_buffered_packet;
|
||||
ogs_pkbuf_t* buffered_packet[MAX_NUM_OF_PACKET_BUFFER];
|
||||
|
||||
/* Related Context */
|
||||
ogs_pfcp_sess_t *sess;
|
||||
void *gnode;
|
||||
|
|
|
@ -159,8 +159,8 @@ int ogs_pfcp_f_seid_to_ip(ogs_pfcp_f_seid_t *f_seid, ogs_ip_t *ip)
|
|||
ip->ipv6 = f_seid->ipv6;
|
||||
|
||||
if (ip->ipv4 && ip->ipv6) {
|
||||
ip->both.addr = f_seid->both.addr;
|
||||
memcpy(ip->both.addr6, f_seid->both.addr6, OGS_IPV6_LEN);
|
||||
ip->addr = f_seid->both.addr;
|
||||
memcpy(ip->addr6, f_seid->both.addr6, OGS_IPV6_LEN);
|
||||
ip->len = OGS_IPV4V6_LEN;
|
||||
} else if (ip->ipv4) {
|
||||
ip->addr = f_seid->addr;
|
||||
|
@ -325,9 +325,9 @@ int ogs_pfcp_ip_to_outer_header_creation(ogs_ip_t *ip,
|
|||
|
||||
if (ip->ipv4 && ip->ipv6) {
|
||||
outer_header_creation->gtpu4 = 1;
|
||||
outer_header_creation->both.addr = ip->both.addr;
|
||||
outer_header_creation->both.addr = ip->addr;
|
||||
outer_header_creation->gtpu6 = 1;
|
||||
memcpy(outer_header_creation->both.addr6, ip->both.addr6, OGS_IPV6_LEN);
|
||||
memcpy(outer_header_creation->both.addr6, ip->addr6, OGS_IPV6_LEN);
|
||||
*len = OGS_IPV4V6_LEN + hdr_len;
|
||||
} else if (ip->ipv4) {
|
||||
outer_header_creation->gtpu4 = 1;
|
||||
|
@ -360,8 +360,8 @@ int ogs_pfcp_outer_header_creation_to_ip(
|
|||
outer_header_creation->udp6)) {
|
||||
ip->ipv4 = 1; ip->ipv6 = 1;
|
||||
ip->len = OGS_IPV4V6_LEN;
|
||||
ip->both.addr = outer_header_creation->both.addr;
|
||||
memcpy(ip->both.addr6, outer_header_creation->both.addr6, OGS_IPV6_LEN);
|
||||
ip->addr = outer_header_creation->both.addr;
|
||||
memcpy(ip->addr6, outer_header_creation->both.addr6, OGS_IPV6_LEN);
|
||||
} else if (outer_header_creation->gtpu4 ||
|
||||
outer_header_creation->ip4 ||
|
||||
outer_header_creation->udp4) {
|
||||
|
|
|
@ -1629,7 +1629,7 @@ amf_sess_t *amf_sess_find_by_dnn(amf_ue_t *amf_ue, char *dnn)
|
|||
|
||||
sess = amf_sess_first(amf_ue);
|
||||
while (sess) {
|
||||
if (sess->pdn && strcmp(sess->pdn->apn, dnn) == 0)
|
||||
if (sess->pdn && strcmp(sess->pdn->dnn, dnn) == 0)
|
||||
return sess;
|
||||
|
||||
sess = amf_sess_next(sess);
|
||||
|
|
|
@ -256,112 +256,21 @@ int hss_context_parse_config(void)
|
|||
return OGS_OK;
|
||||
}
|
||||
|
||||
int hss_db_init()
|
||||
int hss_db_auth_info(char *imsi_bcd, ogs_dbi_auth_info_t *auth_info)
|
||||
{
|
||||
int rv;
|
||||
|
||||
rv = ogs_mongoc_init(ogs_config()->db_uri);
|
||||
if (rv != OGS_OK) return rv;
|
||||
|
||||
if (ogs_mongoc()->client && ogs_mongoc()->name) {
|
||||
self.subscriberCollection = mongoc_client_get_collection(
|
||||
ogs_mongoc()->client, ogs_mongoc()->name, "subscribers");
|
||||
ogs_assert(self.subscriberCollection);
|
||||
}
|
||||
|
||||
return OGS_OK;
|
||||
}
|
||||
|
||||
int hss_db_final()
|
||||
{
|
||||
if (self.subscriberCollection) {
|
||||
mongoc_collection_destroy(self.subscriberCollection);
|
||||
}
|
||||
|
||||
ogs_mongoc_final();
|
||||
|
||||
return OGS_OK;
|
||||
}
|
||||
|
||||
int hss_db_auth_info(
|
||||
char *imsi_bcd, hss_db_auth_info_t *auth_info)
|
||||
{
|
||||
int rv = OGS_OK;
|
||||
mongoc_cursor_t *cursor = NULL;
|
||||
bson_t *query = NULL;
|
||||
bson_error_t error;
|
||||
const bson_t *document;
|
||||
bson_iter_t iter;
|
||||
bson_iter_t inner_iter;
|
||||
char buf[OGS_KEY_LEN];
|
||||
char *utf8 = NULL;
|
||||
uint32_t length = 0;
|
||||
char *supi = NULL;
|
||||
|
||||
ogs_assert(imsi_bcd);
|
||||
ogs_assert(auth_info);
|
||||
|
||||
ogs_thread_mutex_lock(&self.db_lock);
|
||||
supi = ogs_msprintf("%s-%s", OGS_DBI_SUPI_TYPE_IMSI, imsi_bcd);
|
||||
ogs_assert(supi);
|
||||
|
||||
query = BCON_NEW("imsi", BCON_UTF8(imsi_bcd));
|
||||
#if MONGOC_MAJOR_VERSION >= 1 && MONGOC_MINOR_VERSION >= 5
|
||||
cursor = mongoc_collection_find_with_opts(
|
||||
self.subscriberCollection, query, NULL, NULL);
|
||||
#else
|
||||
cursor = mongoc_collection_find(self.subscriberCollection,
|
||||
MONGOC_QUERY_NONE, 0, 0, 0, query, NULL, NULL);
|
||||
#endif
|
||||
|
||||
if (!mongoc_cursor_next(cursor, &document)) {
|
||||
ogs_warn("Cannot find IMSI in DB : %s", imsi_bcd);
|
||||
|
||||
rv = OGS_ERROR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (mongoc_cursor_error(cursor, &error)) {
|
||||
ogs_error("Cursor Failure: %s", error.message);
|
||||
|
||||
rv = OGS_ERROR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!bson_iter_init_find(&iter, document, "security")) {
|
||||
ogs_error("No 'security' field in this document");
|
||||
|
||||
rv = OGS_ERROR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
memset(auth_info, 0, sizeof(hss_db_auth_info_t));
|
||||
bson_iter_recurse(&iter, &inner_iter);
|
||||
while (bson_iter_next(&inner_iter)) {
|
||||
const char *key = bson_iter_key(&inner_iter);
|
||||
|
||||
if (!strcmp(key, "k") && BSON_ITER_HOLDS_UTF8(&inner_iter)) {
|
||||
utf8 = (char *)bson_iter_utf8(&inner_iter, &length);
|
||||
memcpy(auth_info->k, OGS_HEX(utf8, length, buf), OGS_KEY_LEN);
|
||||
} else if (!strcmp(key, "opc") && BSON_ITER_HOLDS_UTF8(&inner_iter)) {
|
||||
utf8 = (char *)bson_iter_utf8(&inner_iter, &length);
|
||||
auth_info->use_opc = 1;
|
||||
memcpy(auth_info->opc, OGS_HEX(utf8, length, buf), OGS_KEY_LEN);
|
||||
} else if (!strcmp(key, "op") && BSON_ITER_HOLDS_UTF8(&inner_iter)) {
|
||||
utf8 = (char *)bson_iter_utf8(&inner_iter, &length);
|
||||
memcpy(auth_info->op, OGS_HEX(utf8, length, buf), OGS_KEY_LEN);
|
||||
} else if (!strcmp(key, "amf") && BSON_ITER_HOLDS_UTF8(&inner_iter)) {
|
||||
utf8 = (char *)bson_iter_utf8(&inner_iter, &length);
|
||||
memcpy(auth_info->amf, OGS_HEX(utf8, length, buf), OGS_AMF_LEN);
|
||||
} else if (!strcmp(key, "rand") && BSON_ITER_HOLDS_UTF8(&inner_iter)) {
|
||||
utf8 = (char *)bson_iter_utf8(&inner_iter, &length);
|
||||
memcpy(auth_info->rand, OGS_HEX(utf8, length, buf), OGS_RAND_LEN);
|
||||
} else if (!strcmp(key, "sqn") && BSON_ITER_HOLDS_INT64(&inner_iter)) {
|
||||
auth_info->sqn = bson_iter_int64(&inner_iter);
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (query) bson_destroy(query);
|
||||
if (cursor) mongoc_cursor_destroy(cursor);
|
||||
rv = ogs_dbi_auth_info(supi, auth_info);
|
||||
|
||||
ogs_free(supi);
|
||||
ogs_thread_mutex_unlock(&self.db_lock);
|
||||
|
||||
return rv;
|
||||
|
@ -370,35 +279,18 @@ out:
|
|||
int hss_db_update_rand_and_sqn(
|
||||
char *imsi_bcd, uint8_t *rand, uint64_t sqn)
|
||||
{
|
||||
int rv = OGS_OK;
|
||||
bson_t *query = NULL;
|
||||
bson_t *update = NULL;
|
||||
bson_error_t error;
|
||||
char printable_rand[128];
|
||||
int rv;
|
||||
char *supi = NULL;
|
||||
|
||||
ogs_assert(rand);
|
||||
ogs_hex_to_ascii(rand, OGS_RAND_LEN,
|
||||
printable_rand, sizeof(printable_rand));
|
||||
ogs_assert(imsi_bcd);
|
||||
|
||||
ogs_thread_mutex_lock(&self.db_lock);
|
||||
supi = ogs_msprintf("%s-%s", OGS_DBI_SUPI_TYPE_IMSI, imsi_bcd);
|
||||
ogs_assert(supi);
|
||||
|
||||
query = BCON_NEW("imsi", BCON_UTF8(imsi_bcd));
|
||||
update = BCON_NEW("$set",
|
||||
"{",
|
||||
"security.rand", printable_rand,
|
||||
"security.sqn", BCON_INT64(sqn),
|
||||
"}");
|
||||
|
||||
if (!mongoc_collection_update(self.subscriberCollection,
|
||||
MONGOC_UPDATE_NONE, query, update, NULL, &error)) {
|
||||
ogs_error("mongoc_collection_update() failure: %s", error.message);
|
||||
|
||||
rv = OGS_ERROR;
|
||||
}
|
||||
|
||||
if (query) bson_destroy(query);
|
||||
if (update) bson_destroy(update);
|
||||
rv = ogs_dbi_update_sqn(supi, sqn);
|
||||
|
||||
ogs_free(supi);
|
||||
ogs_thread_mutex_unlock(&self.db_lock);
|
||||
|
||||
return rv;
|
||||
|
@ -406,292 +298,39 @@ int hss_db_update_rand_and_sqn(
|
|||
|
||||
int hss_db_increment_sqn(char *imsi_bcd)
|
||||
{
|
||||
int rv = OGS_OK;
|
||||
bson_t *query = NULL;
|
||||
bson_t *update = NULL;
|
||||
bson_error_t error;
|
||||
uint64_t max_sqn = OGS_MAX_SQN;
|
||||
int rv;
|
||||
char *supi = NULL;
|
||||
|
||||
ogs_assert(imsi_bcd);
|
||||
|
||||
ogs_thread_mutex_lock(&self.db_lock);
|
||||
supi = ogs_msprintf("%s-%s", OGS_DBI_SUPI_TYPE_IMSI, imsi_bcd);
|
||||
ogs_assert(supi);
|
||||
|
||||
query = BCON_NEW("imsi", BCON_UTF8(imsi_bcd));
|
||||
update = BCON_NEW("$inc",
|
||||
"{",
|
||||
"security.sqn", BCON_INT64(32),
|
||||
"}");
|
||||
if (!mongoc_collection_update(self.subscriberCollection,
|
||||
MONGOC_UPDATE_NONE, query, update, NULL, &error)) {
|
||||
ogs_error("mongoc_collection_update() failure: %s", error.message);
|
||||
|
||||
rv = OGS_ERROR;
|
||||
goto out;
|
||||
}
|
||||
bson_destroy(update);
|
||||
|
||||
update = BCON_NEW("$bit",
|
||||
"{",
|
||||
"security.sqn",
|
||||
"{", "and", BCON_INT64(max_sqn), "}",
|
||||
"}");
|
||||
if (!mongoc_collection_update(self.subscriberCollection,
|
||||
MONGOC_UPDATE_NONE, query, update, NULL, &error)) {
|
||||
ogs_error("mongoc_collection_update() failure: %s", error.message);
|
||||
|
||||
rv = OGS_ERROR;
|
||||
}
|
||||
|
||||
out:
|
||||
if (query) bson_destroy(query);
|
||||
if (update) bson_destroy(update);
|
||||
rv = ogs_dbi_increment_sqn(supi);
|
||||
|
||||
ogs_free(supi);
|
||||
ogs_thread_mutex_unlock(&self.db_lock);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
int hss_db_subscription_data(
|
||||
char *imsi_bcd, ogs_diam_s6a_subscription_data_t *subscription_data)
|
||||
char *imsi_bcd, ogs_subscription_data_t *subscription_data)
|
||||
{
|
||||
int rv = OGS_OK;
|
||||
mongoc_cursor_t *cursor = NULL;
|
||||
bson_t *query = NULL;
|
||||
bson_error_t error;
|
||||
const bson_t *document;
|
||||
bson_iter_t iter;
|
||||
bson_iter_t child1_iter, child2_iter, child3_iter, child4_iter;
|
||||
const char *utf8 = NULL;
|
||||
uint32_t length = 0;
|
||||
int rv;
|
||||
char *supi = NULL;
|
||||
|
||||
ogs_assert(imsi_bcd);
|
||||
ogs_assert(subscription_data);
|
||||
|
||||
ogs_thread_mutex_lock(&self.db_lock);
|
||||
supi = ogs_msprintf("%s-%s", OGS_DBI_SUPI_TYPE_IMSI, imsi_bcd);
|
||||
ogs_assert(supi);
|
||||
|
||||
query = BCON_NEW("imsi", BCON_UTF8(imsi_bcd));
|
||||
#if MONGOC_MAJOR_VERSION >= 1 && MONGOC_MINOR_VERSION >= 5
|
||||
cursor = mongoc_collection_find_with_opts(
|
||||
self.subscriberCollection, query, NULL, NULL);
|
||||
#else
|
||||
cursor = mongoc_collection_find(self.subscriberCollection,
|
||||
MONGOC_QUERY_NONE, 0, 0, 0, query, NULL, NULL);
|
||||
#endif
|
||||
|
||||
if (!mongoc_cursor_next(cursor, &document)) {
|
||||
ogs_error("Cannot find IMSI in DB : %s", imsi_bcd);
|
||||
|
||||
rv = OGS_ERROR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (mongoc_cursor_error(cursor, &error)) {
|
||||
ogs_error("Cursor Failure: %s", error.message);
|
||||
|
||||
rv = OGS_ERROR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!bson_iter_init(&iter, document)) {
|
||||
ogs_error("bson_iter_init failed in this document");
|
||||
|
||||
rv = OGS_ERROR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
memset(subscription_data, 0, sizeof(ogs_diam_s6a_subscription_data_t));
|
||||
while (bson_iter_next(&iter)) {
|
||||
const char *key = bson_iter_key(&iter);
|
||||
if (!strcmp(key, "access_restriction_data") &&
|
||||
BSON_ITER_HOLDS_INT32(&iter)) {
|
||||
subscription_data->access_restriction_data =
|
||||
bson_iter_int32(&iter);
|
||||
|
||||
} else if (!strcmp(key, "subscriber_status") &&
|
||||
BSON_ITER_HOLDS_INT32(&iter)) {
|
||||
subscription_data->subscriber_status =
|
||||
bson_iter_int32(&iter);
|
||||
} else if (!strcmp(key, "network_access_mode") &&
|
||||
BSON_ITER_HOLDS_INT32(&iter)) {
|
||||
subscription_data->network_access_mode =
|
||||
bson_iter_int32(&iter);
|
||||
} else if (!strcmp(key, "subscribed_rau_tau_timer") &&
|
||||
BSON_ITER_HOLDS_INT32(&iter)) {
|
||||
subscription_data->subscribed_rau_tau_timer =
|
||||
bson_iter_int32(&iter);
|
||||
} else if (!strcmp(key, "ambr") &&
|
||||
BSON_ITER_HOLDS_DOCUMENT(&iter)) {
|
||||
bson_iter_recurse(&iter, &child1_iter);
|
||||
while (bson_iter_next(&child1_iter)) {
|
||||
const char *child1_key = bson_iter_key(&child1_iter);
|
||||
if (!strcmp(child1_key, "uplink") &&
|
||||
BSON_ITER_HOLDS_INT64(&child1_iter)) {
|
||||
subscription_data->ambr.uplink =
|
||||
bson_iter_int64(&child1_iter) * 1024;
|
||||
} else if (!strcmp(child1_key, "downlink") &&
|
||||
BSON_ITER_HOLDS_INT64(&child1_iter)) {
|
||||
subscription_data->ambr.downlink =
|
||||
bson_iter_int64(&child1_iter) * 1024;
|
||||
}
|
||||
}
|
||||
} else if (!strcmp(key, "pdn") &&
|
||||
BSON_ITER_HOLDS_ARRAY(&iter)) {
|
||||
int pdn_index = 0;
|
||||
|
||||
bson_iter_recurse(&iter, &child1_iter);
|
||||
while (bson_iter_next(&child1_iter)) {
|
||||
const char *child1_key = bson_iter_key(&child1_iter);
|
||||
ogs_pdn_t *pdn = NULL;
|
||||
|
||||
ogs_assert(child1_key);
|
||||
pdn_index = atoi(child1_key);
|
||||
ogs_assert(pdn_index < OGS_MAX_NUM_OF_SESS);
|
||||
|
||||
pdn = &subscription_data->pdn[pdn_index];
|
||||
|
||||
bson_iter_recurse(&child1_iter, &child2_iter);
|
||||
while (bson_iter_next(&child2_iter)) {
|
||||
const char *child2_key = bson_iter_key(&child2_iter);
|
||||
if (!strcmp(child2_key, "apn") &&
|
||||
BSON_ITER_HOLDS_UTF8(&child2_iter)) {
|
||||
utf8 = bson_iter_utf8(&child2_iter, &length);
|
||||
ogs_cpystrn(pdn->apn, utf8,
|
||||
ogs_min(length, OGS_MAX_APN_LEN)+1);
|
||||
} else if (!strcmp(child2_key, "type") &&
|
||||
BSON_ITER_HOLDS_INT32(&child2_iter)) {
|
||||
pdn->pdn_type = bson_iter_int32(&child2_iter);
|
||||
} else if (!strcmp(child2_key, "qos") &&
|
||||
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, "qci") &&
|
||||
BSON_ITER_HOLDS_INT32(&child3_iter)) {
|
||||
pdn->qos.qci = bson_iter_int32(&child3_iter);
|
||||
} else if (!strcmp(child3_key, "arp") &&
|
||||
BSON_ITER_HOLDS_DOCUMENT(&child3_iter)) {
|
||||
bson_iter_recurse(&child3_iter, &child4_iter);
|
||||
while (bson_iter_next(&child4_iter)) {
|
||||
const char *child4_key =
|
||||
bson_iter_key(&child4_iter);
|
||||
if (!strcmp(child4_key, "priority_level") &&
|
||||
BSON_ITER_HOLDS_INT32(&child4_iter)) {
|
||||
pdn->qos.arp.priority_level =
|
||||
bson_iter_int32(&child4_iter);
|
||||
} else if (!strcmp(child4_key,
|
||||
"pre_emption_capability") &&
|
||||
BSON_ITER_HOLDS_INT32(&child4_iter)) {
|
||||
pdn->qos.arp.pre_emption_capability =
|
||||
bson_iter_int32(&child4_iter);
|
||||
} else if (!strcmp(child4_key,
|
||||
"pre_emption_vulnerability") &&
|
||||
BSON_ITER_HOLDS_INT32(&child4_iter)) {
|
||||
pdn->qos.arp.pre_emption_vulnerability =
|
||||
bson_iter_int32(&child4_iter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (!strcmp(child2_key, "ambr") &&
|
||||
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, "uplink") &&
|
||||
BSON_ITER_HOLDS_INT64(&child3_iter)) {
|
||||
pdn->ambr.uplink =
|
||||
bson_iter_int64(&child3_iter) * 1024;
|
||||
} else if (!strcmp(child3_key, "downlink") &&
|
||||
BSON_ITER_HOLDS_INT64(&child3_iter)) {
|
||||
pdn->ambr.downlink =
|
||||
bson_iter_int64(&child3_iter) * 1024;
|
||||
}
|
||||
}
|
||||
} else if (!strcmp(child2_key, "pgw") &&
|
||||
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) {
|
||||
pdn->pgw_ip.ipv4 = 1;
|
||||
pdn->pgw_ip.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) {
|
||||
pdn->pgw_ip.ipv6 = 1;
|
||||
memcpy(pdn->pgw_ip.both.addr6,
|
||||
ipsub.sub, sizeof(ipsub.sub));
|
||||
}
|
||||
}
|
||||
}
|
||||
} 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_index++;
|
||||
}
|
||||
subscription_data->num_of_pdn = pdn_index;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (query) bson_destroy(query);
|
||||
if (cursor) mongoc_cursor_destroy(cursor);
|
||||
rv = ogs_dbi_subscription_data(supi, subscription_data);
|
||||
|
||||
ogs_free(supi);
|
||||
ogs_thread_mutex_unlock(&self.db_lock);
|
||||
|
||||
return rv;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#define HSS_CONTEXT_H
|
||||
|
||||
#include "ogs-diameter-s6a.h"
|
||||
#include "ogs-dbi.h"
|
||||
#include "ogs-app.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -32,21 +33,10 @@ extern int __hss_log_domain;
|
|||
#undef OGS_LOG_DOMAIN
|
||||
#define OGS_LOG_DOMAIN __hss_log_domain
|
||||
|
||||
typedef struct _hss_db_auth_info_t {
|
||||
uint8_t k[OGS_KEY_LEN];
|
||||
uint8_t use_opc;
|
||||
uint8_t opc[OGS_KEY_LEN];
|
||||
uint8_t op[OGS_KEY_LEN];
|
||||
uint8_t amf[OGS_AMF_LEN];
|
||||
uint8_t rand[OGS_RAND_LEN];
|
||||
uint64_t sqn;
|
||||
} hss_db_auth_info_t;
|
||||
|
||||
typedef struct _hss_context_t {
|
||||
const char *diam_conf_path; /* HSS Diameter conf path */
|
||||
ogs_diam_config_t *diam_config; /* HSS Diameter config */
|
||||
|
||||
void *subscriberCollection;
|
||||
ogs_thread_mutex_t db_lock;
|
||||
} hss_context_t;
|
||||
|
||||
|
@ -56,15 +46,12 @@ hss_context_t *hss_self(void);
|
|||
|
||||
int hss_context_parse_config(void);
|
||||
|
||||
int hss_db_init(void);
|
||||
int hss_db_final(void);
|
||||
|
||||
int hss_db_auth_info(char *imsi_bcd, hss_db_auth_info_t *auth_info);
|
||||
int hss_db_auth_info(char *imsi_bcd, ogs_dbi_auth_info_t *auth_info);
|
||||
int hss_db_update_rand_and_sqn(char *imsi_bcd, uint8_t *rand, uint64_t sqn);
|
||||
int hss_db_increment_sqn(char *imsi_bcd);
|
||||
|
||||
int hss_db_subscription_data(
|
||||
char *imsi_bcd, ogs_diam_s6a_subscription_data_t *subscription_data);
|
||||
char *imsi_bcd, ogs_subscription_data_t *subscription_data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ static int hss_ogs_diam_s6a_air_cb( struct msg **msg, struct avp *avp,
|
|||
#define MAC_S_LEN 8
|
||||
uint8_t mac_s[MAC_S_LEN];
|
||||
|
||||
hss_db_auth_info_t auth_info;
|
||||
ogs_dbi_auth_info_t auth_info;
|
||||
uint8_t zero[OGS_RAND_LEN];
|
||||
int rv;
|
||||
uint32_t result_code = 0;
|
||||
|
@ -279,7 +279,7 @@ static int hss_ogs_diam_s6a_ulr_cb( struct msg **msg, struct avp *avp,
|
|||
|
||||
int rv;
|
||||
uint32_t result_code = 0;
|
||||
ogs_diam_s6a_subscription_data_t subscription_data;
|
||||
ogs_subscription_data_t subscription_data;
|
||||
struct sockaddr_in sin;
|
||||
struct sockaddr_in6 sin6;
|
||||
|
||||
|
@ -490,13 +490,12 @@ static int hss_ogs_diam_s6a_ulr_cb( struct msg **msg, struct avp *avp,
|
|||
/* Set 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)) {
|
||||
pdn->ue_ip.ipv4) {
|
||||
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;
|
||||
sin.sin_addr.s_addr = pdn->ue_ip.addr;
|
||||
ret = fd_msg_avp_value_encode(
|
||||
&sin, served_party_ip_address);
|
||||
ogs_assert(ret == 0);
|
||||
|
@ -507,14 +506,13 @@ static int hss_ogs_diam_s6a_ulr_cb( struct msg **msg, struct avp *avp,
|
|||
|
||||
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)) {
|
||||
pdn->ue_ip.ipv6) {
|
||||
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);
|
||||
pdn->ue_ip.addr6, OGS_IPV6_LEN);
|
||||
ret = fd_msg_avp_value_encode(
|
||||
&sin6, served_party_ip_address);
|
||||
ogs_assert(ret == 0);
|
||||
|
@ -605,7 +603,7 @@ static int hss_ogs_diam_s6a_ulr_cb( struct msg **msg, struct avp *avp,
|
|||
&mip_home_agent_address);
|
||||
ogs_assert(ret == 0);
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_addr.s_addr = pdn->pgw_ip.both.addr;
|
||||
sin.sin_addr.s_addr = pdn->pgw_ip.addr;
|
||||
ret = fd_msg_avp_value_encode (
|
||||
&sin, mip_home_agent_address );
|
||||
ogs_assert(ret == 0);
|
||||
|
@ -619,8 +617,8 @@ static int hss_ogs_diam_s6a_ulr_cb( struct msg **msg, struct avp *avp,
|
|||
&mip_home_agent_address);
|
||||
ogs_assert(ret == 0);
|
||||
sin6.sin6_family = AF_INET6;
|
||||
memcpy(sin6.sin6_addr.s6_addr, pdn->pgw_ip.both.addr6,
|
||||
sizeof pdn->pgw_ip.both.addr6);
|
||||
memcpy(sin6.sin6_addr.s6_addr, pdn->pgw_ip.addr6,
|
||||
sizeof pdn->pgw_ip.addr6);
|
||||
ret = fd_msg_avp_value_encode (
|
||||
&sin6, mip_home_agent_address );
|
||||
ogs_assert(ret == 0);
|
||||
|
|
|
@ -35,7 +35,7 @@ int hss_initialize(void)
|
|||
ogs_config()->logger.domain, ogs_config()->logger.level);
|
||||
if (rv != OGS_OK) return rv;
|
||||
|
||||
rv = hss_db_init();
|
||||
rv = ogs_dbi_init(ogs_config()->db_uri);
|
||||
if (rv != OGS_OK) return rv;
|
||||
|
||||
rv = hss_fd_init();
|
||||
|
@ -52,7 +52,7 @@ void hss_terminate(void)
|
|||
|
||||
hss_fd_final();
|
||||
|
||||
hss_db_final();
|
||||
ogs_dbi_final();
|
||||
hss_context_final();
|
||||
|
||||
return;
|
||||
|
|
|
@ -3032,7 +3032,7 @@ int mme_bearer_set_inactive(mme_ue_t *mme_ue)
|
|||
|
||||
void mme_pdn_remove_all(mme_ue_t *mme_ue)
|
||||
{
|
||||
ogs_diam_s6a_subscription_data_t *subscription_data = NULL;
|
||||
ogs_subscription_data_t *subscription_data = NULL;
|
||||
|
||||
ogs_assert(mme_ue);
|
||||
subscription_data = &mme_ue->subscription_data;
|
||||
|
@ -3043,7 +3043,7 @@ void mme_pdn_remove_all(mme_ue_t *mme_ue)
|
|||
|
||||
ogs_pdn_t *mme_pdn_find_by_apn(mme_ue_t *mme_ue, char *apn)
|
||||
{
|
||||
ogs_diam_s6a_subscription_data_t *subscription_data = NULL;
|
||||
ogs_subscription_data_t *subscription_data = NULL;
|
||||
ogs_pdn_t *pdn = NULL;
|
||||
int i = 0;
|
||||
|
||||
|
@ -3064,7 +3064,7 @@ ogs_pdn_t *mme_pdn_find_by_apn(mme_ue_t *mme_ue, char *apn)
|
|||
|
||||
ogs_pdn_t *mme_default_pdn(mme_ue_t *mme_ue)
|
||||
{
|
||||
ogs_diam_s6a_subscription_data_t *subscription_data = NULL;
|
||||
ogs_subscription_data_t *subscription_data = NULL;
|
||||
ogs_pdn_t *pdn = NULL;
|
||||
int i = 0;
|
||||
|
||||
|
|
|
@ -383,7 +383,7 @@ struct mme_ue_s {
|
|||
uint8_t selected_int_algorithm;
|
||||
|
||||
/* HSS Info */
|
||||
ogs_diam_s6a_subscription_data_t subscription_data;
|
||||
ogs_subscription_data_t subscription_data;
|
||||
|
||||
/* ESM Info */
|
||||
#define MIN_EPS_BEARER_ID 5
|
||||
|
|
|
@ -604,7 +604,7 @@ static void mme_s6a_ula_cb(void *data, struct msg **msg)
|
|||
ogs_pkbuf_t *s6abuf = NULL;
|
||||
ogs_diam_s6a_message_t *s6a_message = NULL;
|
||||
ogs_diam_s6a_ula_message_t *ula_message = NULL;
|
||||
ogs_diam_s6a_subscription_data_t *subscription_data = NULL;
|
||||
ogs_subscription_data_t *subscription_data = NULL;
|
||||
uint16_t s6abuf_len = 0;
|
||||
|
||||
ogs_debug("[MME] Update-Location-Answer");
|
||||
|
@ -752,7 +752,7 @@ static void mme_s6a_ula_cb(void *data, struct msg **msg)
|
|||
subscription_data->subscribed_rau_tau_timer = hdr->avp_value->i32;
|
||||
} else {
|
||||
subscription_data->subscribed_rau_tau_timer =
|
||||
OGS_DIAM_S6A_RAU_TAU_DEFAULT_TIME;
|
||||
OGS_RAU_TAU_DEFAULT_TIME;
|
||||
}
|
||||
|
||||
ret = fd_avp_search_avp(avp,
|
||||
|
@ -947,13 +947,13 @@ static void mme_s6a_ula_cb(void *data, struct msg **msg)
|
|||
if (addr.ogs_sa_family == AF_INET)
|
||||
{
|
||||
pdn->pgw_ip.ipv4 = 1;
|
||||
pdn->pgw_ip.both.addr =
|
||||
pdn->pgw_ip.addr =
|
||||
addr.sin.sin_addr.s_addr;
|
||||
}
|
||||
else if (addr.ogs_sa_family == AF_INET6)
|
||||
{
|
||||
pdn->pgw_ip.ipv6 = 1;
|
||||
memcpy(pdn->pgw_ip.both.addr6,
|
||||
memcpy(pdn->pgw_ip.addr6,
|
||||
addr.sin6.sin6_addr.s6_addr,
|
||||
OGS_IPV6_LEN);
|
||||
}
|
||||
|
|
|
@ -102,20 +102,18 @@ ogs_pkbuf_t *mme_s11_build_create_session_request(
|
|||
pgw_s5c_teid.ipv4 = pdn->pgw_ip.ipv4;
|
||||
pgw_s5c_teid.ipv6 = pdn->pgw_ip.ipv6;
|
||||
if (pgw_s5c_teid.ipv4 && pgw_s5c_teid.ipv6) {
|
||||
pgw_s5c_teid.both.addr = pdn->pgw_ip.both.addr;
|
||||
memcpy(pgw_s5c_teid.both.addr6, pdn->pgw_ip.both.addr6,
|
||||
sizeof pdn->pgw_ip.both.addr6);
|
||||
pgw_s5c_teid.both.addr = pdn->pgw_ip.addr;
|
||||
memcpy(pgw_s5c_teid.both.addr6, pdn->pgw_ip.addr6,
|
||||
sizeof pdn->pgw_ip.addr6);
|
||||
req->pgw_s5_s8_address_for_control_plane_or_pmip.len =
|
||||
OGS_GTP_F_TEID_IPV4V6_LEN;
|
||||
} else if (pgw_s5c_teid.ipv4) {
|
||||
/* pdn->pgw_ip always uses both ip address memory */
|
||||
pgw_s5c_teid.addr = pdn->pgw_ip.both.addr;
|
||||
pgw_s5c_teid.addr = pdn->pgw_ip.addr;
|
||||
req->pgw_s5_s8_address_for_control_plane_or_pmip.len =
|
||||
OGS_GTP_F_TEID_IPV4_LEN;
|
||||
} else if (pgw_s5c_teid.ipv6) {
|
||||
/* pdn->pgw_ip always uses both ip address memory */
|
||||
memcpy(pgw_s5c_teid.addr6, pdn->pgw_ip.both.addr6,
|
||||
sizeof pdn->pgw_ip.both.addr6);
|
||||
memcpy(pgw_s5c_teid.addr6, pdn->pgw_ip.addr6,
|
||||
sizeof pdn->pgw_ip.addr6);
|
||||
req->pgw_s5_s8_address_for_control_plane_or_pmip.len =
|
||||
OGS_GTP_F_TEID_IPV6_LEN;
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ void mme_s6a_handle_aia(mme_ue_t *mme_ue,
|
|||
void mme_s6a_handle_ula(mme_ue_t *mme_ue,
|
||||
ogs_diam_s6a_ula_message_t *ula_message)
|
||||
{
|
||||
ogs_diam_s6a_subscription_data_t *subscription_data = NULL;
|
||||
ogs_subscription_data_t *subscription_data = NULL;
|
||||
|
||||
ogs_assert(mme_ue);
|
||||
ogs_assert(ula_message);
|
||||
|
@ -54,5 +54,5 @@ void mme_s6a_handle_ula(mme_ue_t *mme_ue,
|
|||
ogs_assert(subscription_data);
|
||||
|
||||
memcpy(&mme_ue->subscription_data,
|
||||
subscription_data, sizeof(ogs_diam_s6a_subscription_data_t));
|
||||
subscription_data, sizeof(ogs_subscription_data_t));
|
||||
}
|
||||
|
|
|
@ -278,7 +278,7 @@ ogs_pkbuf_t *s1ap_build_initial_context_setup_request(
|
|||
enb_ue_t *enb_ue = NULL;
|
||||
mme_sess_t *sess = NULL;
|
||||
mme_bearer_t *bearer = NULL;
|
||||
ogs_diam_s6a_subscription_data_t *subscription_data = NULL;
|
||||
ogs_subscription_data_t *subscription_data = NULL;
|
||||
|
||||
ogs_assert(mme_ue);
|
||||
enb_ue = mme_ue->enb_ue;
|
||||
|
@ -1041,7 +1041,7 @@ ogs_pkbuf_t *s1ap_build_e_rab_release_command(
|
|||
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
enb_ue_t *enb_ue = NULL;
|
||||
ogs_diam_s6a_subscription_data_t *subscription_data = NULL;
|
||||
ogs_subscription_data_t *subscription_data = NULL;
|
||||
|
||||
ogs_assert(esmbuf);
|
||||
ogs_assert(bearer);
|
||||
|
@ -1747,7 +1747,7 @@ ogs_pkbuf_t *s1ap_build_handover_request(
|
|||
|
||||
mme_sess_t *sess = NULL;
|
||||
mme_bearer_t *bearer = NULL;
|
||||
ogs_diam_s6a_subscription_data_t *subscription_data = NULL;
|
||||
ogs_subscription_data_t *subscription_data = NULL;
|
||||
|
||||
ogs_assert(handovertype);
|
||||
ogs_assert(cause);
|
||||
|
|
|
@ -41,7 +41,6 @@
|
|||
|
||||
#define PGW_GTP_HANDLED 1
|
||||
|
||||
uint16_t in_cksum(uint16_t *addr, int len);
|
||||
static int pgw_gtp_handle_multicast(ogs_pkbuf_t *recvbuf);
|
||||
static int pgw_gtp_handle_slaac(pgw_sess_t *sess, ogs_pkbuf_t *recvbuf);
|
||||
static int pgw_gtp_send_to_bearer(pgw_bearer_t *bearer, ogs_pkbuf_t *sendbuf);
|
||||
|
@ -510,7 +509,7 @@ static int pgw_gtp_send_router_advertisement(
|
|||
p += OGS_IPV6_LEN;
|
||||
p += 2; memcpy(p, &plen, 2); p += 2;
|
||||
p += 3; *p = nxt; p += 1;
|
||||
advert_h->nd_ra_cksum = in_cksum((uint16_t *)pkbuf->data, pkbuf->len);
|
||||
advert_h->nd_ra_cksum = ogs_in_cksum((uint16_t *)pkbuf->data, pkbuf->len);
|
||||
|
||||
ip6_h->ip6_flow = htobe32(0x60000001);
|
||||
ip6_h->ip6_plen = plen;
|
||||
|
@ -527,30 +526,3 @@ static int pgw_gtp_send_router_advertisement(
|
|||
ogs_pkbuf_free(pkbuf);
|
||||
return rv;
|
||||
}
|
||||
|
||||
uint16_t in_cksum(uint16_t *addr, int len)
|
||||
{
|
||||
int nleft = len;
|
||||
uint32_t sum = 0;
|
||||
uint16_t *w = addr;
|
||||
uint16_t answer = 0;
|
||||
|
||||
// Adding 16 bits sequentially in sum
|
||||
while (nleft > 1) {
|
||||
sum += *w;
|
||||
nleft -= 2;
|
||||
w++;
|
||||
}
|
||||
|
||||
// If an odd byte is left
|
||||
if (nleft == 1) {
|
||||
*(uint8_t *) (&answer) = *(uint8_t *) w;
|
||||
sum += answer;
|
||||
}
|
||||
|
||||
sum = (sum >> 16) + (sum & 0xffff);
|
||||
sum += (sum >> 16);
|
||||
answer = ~sum;
|
||||
|
||||
return answer;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ static ogs_diam_config_t g_diam_conf;
|
|||
int __smf_log_domain;
|
||||
int __gsm_log_domain;
|
||||
|
||||
static OGS_POOL(smf_ue_pool, smf_ue_t);
|
||||
static OGS_POOL(smf_sess_pool, smf_sess_t);
|
||||
static OGS_POOL(smf_bearer_pool, smf_bearer_t);
|
||||
|
||||
|
@ -52,20 +53,21 @@ void smf_context_init(void)
|
|||
|
||||
ogs_gtp_node_init(512);
|
||||
|
||||
ogs_list_init(&self.sess_list);
|
||||
ogs_list_init(&self.smf_ue_list);
|
||||
|
||||
ogs_list_init(&self.gtpc_list);
|
||||
ogs_list_init(&self.gtpc_list6);
|
||||
|
||||
ogs_list_init(&self.sgw_s5c_list);
|
||||
|
||||
ogs_pool_init(&smf_ue_pool, ogs_config()->pool.ue);
|
||||
ogs_pool_init(&smf_sess_pool, ogs_config()->pool.sess);
|
||||
ogs_pool_init(&smf_bearer_pool, ogs_config()->pool.bearer);
|
||||
|
||||
ogs_pool_init(&smf_pf_pool, ogs_config()->pool.pf);
|
||||
|
||||
self.imsi_apn_hash = ogs_hash_make();
|
||||
self.supi_psi_hash = ogs_hash_make();
|
||||
self.supi_hash = ogs_hash_make();
|
||||
self.imsi_hash = ogs_hash_make();
|
||||
self.ipv4_hash = ogs_hash_make();
|
||||
self.ipv6_hash = ogs_hash_make();
|
||||
|
||||
|
@ -76,17 +78,18 @@ void smf_context_final(void)
|
|||
{
|
||||
ogs_assert(context_initialized == 1);
|
||||
|
||||
smf_sess_remove_all();
|
||||
smf_ue_remove_all();
|
||||
|
||||
ogs_assert(self.imsi_apn_hash);
|
||||
ogs_hash_destroy(self.imsi_apn_hash);
|
||||
ogs_assert(self.supi_psi_hash);
|
||||
ogs_hash_destroy(self.supi_psi_hash);
|
||||
ogs_assert(self.supi_hash);
|
||||
ogs_hash_destroy(self.supi_hash);
|
||||
ogs_assert(self.imsi_hash);
|
||||
ogs_hash_destroy(self.imsi_hash);
|
||||
ogs_assert(self.ipv4_hash);
|
||||
ogs_hash_destroy(self.ipv4_hash);
|
||||
ogs_assert(self.ipv6_hash);
|
||||
ogs_hash_destroy(self.ipv6_hash);
|
||||
|
||||
ogs_pool_final(&smf_ue_pool);
|
||||
ogs_pool_final(&smf_bearer_pool);
|
||||
ogs_pool_final(&smf_sess_pool);
|
||||
|
||||
|
@ -510,26 +513,92 @@ int smf_context_parse_config(void)
|
|||
return OGS_OK;
|
||||
}
|
||||
|
||||
static void *imsi_apn_keygen(uint8_t *out, int *out_len,
|
||||
uint8_t *imsi, int imsi_len, char *apn)
|
||||
smf_ue_t *smf_ue_add_by_supi(char *supi)
|
||||
{
|
||||
memcpy(out, imsi, imsi_len);
|
||||
ogs_cpystrn((char*)(out+imsi_len), apn, OGS_MAX_APN_LEN+1);
|
||||
*out_len = imsi_len+strlen((char*)(out+imsi_len));
|
||||
smf_ue_t *smf_ue = NULL;
|
||||
|
||||
return out;
|
||||
ogs_assert(supi);
|
||||
|
||||
ogs_pool_alloc(&smf_ue_pool, &smf_ue);
|
||||
ogs_assert(smf_ue);
|
||||
memset(smf_ue, 0, sizeof *smf_ue);
|
||||
|
||||
ogs_list_init(&smf_ue->sess_list);
|
||||
|
||||
smf_ue->supi = ogs_strdup(supi);
|
||||
ogs_assert(smf_ue->supi);
|
||||
ogs_hash_set(self.supi_hash, smf_ue->supi, strlen(smf_ue->supi), smf_ue);
|
||||
|
||||
ogs_list_add(&self.smf_ue_list, smf_ue);
|
||||
|
||||
return smf_ue;
|
||||
}
|
||||
|
||||
static char *supi_psi_keygen(char *supi, uint8_t psi)
|
||||
smf_ue_t *smf_ue_add_by_imsi(uint8_t *imsi, int imsi_len)
|
||||
{
|
||||
smf_ue_t *smf_ue = NULL;
|
||||
|
||||
ogs_assert(imsi);
|
||||
ogs_assert(imsi_len);
|
||||
|
||||
ogs_pool_alloc(&smf_ue_pool, &smf_ue);
|
||||
ogs_assert(smf_ue);
|
||||
memset(smf_ue, 0, sizeof *smf_ue);
|
||||
|
||||
ogs_list_init(&smf_ue->sess_list);
|
||||
|
||||
smf_ue->imsi_len = imsi_len;
|
||||
memcpy(smf_ue->imsi, imsi, smf_ue->imsi_len);
|
||||
ogs_buffer_to_bcd(smf_ue->imsi, smf_ue->imsi_len, smf_ue->imsi_bcd);
|
||||
ogs_hash_set(self.imsi_hash, smf_ue->imsi, smf_ue->imsi_len, smf_ue);
|
||||
|
||||
ogs_list_add(&self.smf_ue_list, smf_ue);
|
||||
|
||||
return smf_ue;
|
||||
}
|
||||
|
||||
void smf_ue_remove(smf_ue_t *smf_ue)
|
||||
{
|
||||
ogs_assert(smf_ue);
|
||||
|
||||
ogs_list_remove(&self.smf_ue_list, smf_ue);
|
||||
|
||||
if (smf_ue->supi) {
|
||||
ogs_hash_set(self.supi_hash, smf_ue->supi, strlen(smf_ue->supi), NULL);
|
||||
ogs_free(smf_ue->supi);
|
||||
}
|
||||
|
||||
if (smf_ue->imsi && smf_ue->imsi_len) {
|
||||
ogs_hash_set(self.imsi_hash, smf_ue->imsi, smf_ue->imsi_len, NULL);
|
||||
}
|
||||
|
||||
smf_sess_remove_all(smf_ue);
|
||||
|
||||
ogs_pool_free(&smf_ue_pool, smf_ue);
|
||||
}
|
||||
|
||||
void smf_ue_remove_all(void)
|
||||
{
|
||||
smf_ue_t *smf_ue = NULL, *next = NULL;;
|
||||
|
||||
ogs_list_for_each_safe(&self.smf_ue_list, next, smf_ue)
|
||||
smf_ue_remove(smf_ue);
|
||||
}
|
||||
|
||||
smf_ue_t *smf_ue_find_by_supi(char *supi)
|
||||
{
|
||||
ogs_assert(supi);
|
||||
ogs_assert(psi != OGS_NAS_PDU_SESSION_IDENTITY_UNASSIGNED);
|
||||
|
||||
return ogs_mstrcatf(supi, "%03d", psi);
|
||||
return (smf_ue_t *)ogs_hash_get(self.supi_hash, supi, strlen(supi));
|
||||
}
|
||||
|
||||
smf_sess_t *smf_sess_add_by_imsi_apn(
|
||||
uint8_t *imsi, int imsi_len, char *apn,
|
||||
smf_ue_t *smf_ue_find_by_imsi(uint8_t *imsi, int imsi_len)
|
||||
{
|
||||
ogs_assert(imsi);
|
||||
ogs_assert(imsi_len);
|
||||
return (smf_ue_t *)ogs_hash_get(self.imsi_hash, imsi, imsi_len);
|
||||
}
|
||||
|
||||
smf_sess_t *smf_sess_add_by_apn(smf_ue_t *smf_ue, char *apn,
|
||||
uint8_t pdn_type, uint8_t ebi, ogs_paa_t *paa)
|
||||
{
|
||||
smf_event_t e;
|
||||
|
@ -541,7 +610,7 @@ smf_sess_t *smf_sess_add_by_imsi_apn(
|
|||
ogs_pfcp_pdr_t *pdr = NULL;
|
||||
ogs_pfcp_subnet_t *subnet6 = NULL;
|
||||
|
||||
ogs_assert(imsi);
|
||||
ogs_assert(smf_ue);
|
||||
ogs_assert(apn);
|
||||
ogs_assert(paa);
|
||||
|
||||
|
@ -560,11 +629,6 @@ smf_sess_t *smf_sess_add_by_imsi_apn(
|
|||
sess->smf_n4_teid = sess->index;
|
||||
sess->smf_n4_seid = sess->index;
|
||||
|
||||
/* Set IMSI */
|
||||
sess->imsi_len = imsi_len;
|
||||
memcpy(sess->imsi, imsi, sess->imsi_len);
|
||||
ogs_buffer_to_bcd(sess->imsi, sess->imsi_len, sess->imsi_bcd);
|
||||
|
||||
/* Set APN */
|
||||
ogs_cpystrn(sess->pdn.apn, apn, OGS_MAX_APN_LEN+1);
|
||||
|
||||
|
@ -613,12 +677,6 @@ smf_sess_t *smf_sess_add_by_imsi_apn(
|
|||
sess->ipv4 ? OGS_INET_NTOP(&sess->ipv4->addr, buf1) : "",
|
||||
sess->ipv6 ? OGS_INET6_NTOP(&sess->ipv6->addr, buf2) : "");
|
||||
|
||||
/* Generate Hash Key : IMSI + APN */
|
||||
imsi_apn_keygen(sess->imsi_apn_keybuf, &sess->imsi_apn_keylen,
|
||||
imsi, imsi_len, apn);
|
||||
ogs_hash_set(self.imsi_apn_hash,
|
||||
sess->imsi_apn_keybuf, sess->imsi_apn_keylen, sess);
|
||||
|
||||
/* Select UPF with round-robin manner */
|
||||
if (ogs_pfcp_self()->node == NULL)
|
||||
ogs_pfcp_self()->node = ogs_list_first(&ogs_pfcp_self()->n4_list);
|
||||
|
@ -652,13 +710,16 @@ smf_sess_t *smf_sess_add_by_imsi_apn(
|
|||
ogs_fsm_create(&sess->sm, smf_gsm_state_initial, smf_gsm_state_final);
|
||||
ogs_fsm_init(&sess->sm, &e);
|
||||
|
||||
ogs_list_add(&self.sess_list, sess);
|
||||
sess->smf_ue = smf_ue;
|
||||
|
||||
ogs_list_add(&smf_ue->sess_list, sess);
|
||||
|
||||
return sess;
|
||||
}
|
||||
|
||||
smf_sess_t *smf_sess_add_by_gtp_message(ogs_gtp_message_t *message)
|
||||
{
|
||||
smf_ue_t *smf_ue = NULL;
|
||||
smf_sess_t *sess = NULL;
|
||||
ogs_paa_t *paa = NULL;
|
||||
char apn[OGS_MAX_APN_LEN];
|
||||
|
@ -718,14 +779,21 @@ smf_sess_t *smf_sess_add_by_gtp_message(ogs_gtp_message_t *message)
|
|||
* - the existing dedicated bearer context, if the Create Session Request
|
||||
* collides with a dedicated bearer of an existing PDN connection context.
|
||||
*/
|
||||
sess = smf_sess_find_by_imsi_apn(req->imsi.data, req->imsi.len, apn);
|
||||
|
||||
smf_ue = smf_ue_find_by_imsi(req->imsi.data, req->imsi.len);
|
||||
if (!smf_ue) {
|
||||
smf_ue = smf_ue_add_by_imsi(req->imsi.data, req->imsi.len);
|
||||
ogs_assert(smf_ue);
|
||||
}
|
||||
|
||||
sess = smf_sess_find_by_apn(smf_ue, apn);
|
||||
if (sess) {
|
||||
ogs_warn("OLD Session Release [IMSI:%s,APN:%s]",
|
||||
sess->imsi_bcd, sess->pdn.apn);
|
||||
smf_sess_remove(sess);
|
||||
smf_ue->imsi_bcd, sess->pdn.apn);
|
||||
SMF_SESS_CLEAR(sess);
|
||||
}
|
||||
sess = smf_sess_add_by_imsi_apn(req->imsi.data, req->imsi.len, apn,
|
||||
req->pdn_type.u8,
|
||||
|
||||
sess = smf_sess_add_by_apn(smf_ue, apn, req->pdn_type.u8,
|
||||
req->bearer_contexts_to_be_created.eps_bearer_id.u8, paa);
|
||||
return sess;
|
||||
}
|
||||
|
@ -735,8 +803,11 @@ void smf_sess_set_ue_ip(smf_sess_t *sess)
|
|||
char buf1[OGS_ADDRSTRLEN];
|
||||
char buf2[OGS_ADDRSTRLEN];
|
||||
ogs_pfcp_subnet_t *subnet6 = NULL;
|
||||
smf_ue_t *smf_ue = NULL;
|
||||
|
||||
ogs_assert(sess);
|
||||
smf_ue = sess->smf_ue;
|
||||
ogs_assert(smf_ue);
|
||||
|
||||
sess->pdn.paa.pdn_type = sess->pdn.pdn_type;
|
||||
ogs_assert(sess->pdn.pdn_type);
|
||||
|
@ -758,7 +829,7 @@ void smf_sess_set_ue_ip(smf_sess_t *sess)
|
|||
sess->pdn.paa.len = subnet6->prefixlen;
|
||||
memcpy(sess->pdn.paa.addr6, sess->ipv6->addr, OGS_IPV6_LEN);
|
||||
ogs_hash_set(self.ipv6_hash, sess->ipv6->addr, OGS_IPV6_LEN, sess);
|
||||
} else if (sess->pdn.pdn_type == OGS_GTP_PDN_TYPE_IPV4V6) {
|
||||
} else if (sess->pdn.pdn_type == OGS_PDU_SESSION_TYPE_IPV4V6) {
|
||||
sess->ipv4 = ogs_pfcp_ue_ip_alloc(
|
||||
AF_INET, sess->pdn.apn, (uint8_t *)&sess->pdn.ue_ip.addr);
|
||||
ogs_assert(sess->ipv4);
|
||||
|
@ -778,12 +849,12 @@ void smf_sess_set_ue_ip(smf_sess_t *sess)
|
|||
ogs_assert_if_reached();
|
||||
|
||||
ogs_info("UE SUPI:[%s] DNN:[%s] IPv4:[%s] IPv6:[%s]",
|
||||
sess->supi, sess->pdn.apn,
|
||||
smf_ue->supi, sess->pdn.apn,
|
||||
sess->ipv4 ? OGS_INET_NTOP(&sess->ipv4->addr, buf1) : "",
|
||||
sess->ipv6 ? OGS_INET6_NTOP(&sess->ipv6->addr, buf2) : "");
|
||||
}
|
||||
|
||||
smf_sess_t *smf_sess_add_by_supi_psi(char *supi, uint8_t psi)
|
||||
smf_sess_t *smf_sess_add_by_psi(smf_ue_t *smf_ue, uint8_t psi)
|
||||
{
|
||||
smf_event_t e;
|
||||
|
||||
|
@ -791,7 +862,7 @@ smf_sess_t *smf_sess_add_by_supi_psi(char *supi, uint8_t psi)
|
|||
smf_bearer_t *bearer = NULL;
|
||||
ogs_pfcp_pdr_t *pdr = NULL;
|
||||
|
||||
ogs_assert(supi);
|
||||
ogs_assert(smf_ue);
|
||||
ogs_assert(psi != OGS_NAS_PDU_SESSION_IDENTITY_UNASSIGNED);
|
||||
|
||||
ogs_pool_alloc(&smf_sess_pool, &sess);
|
||||
|
@ -809,20 +880,13 @@ smf_sess_t *smf_sess_add_by_supi_psi(char *supi, uint8_t psi)
|
|||
(int)ogs_pool_index(&smf_sess_pool, sess));
|
||||
ogs_assert(sess->sm_context_ref);
|
||||
|
||||
/* Set PSI */
|
||||
sess->psi = psi;
|
||||
|
||||
/* Set TEID & SEID */
|
||||
sess->smf_n4_teid = sess->index;
|
||||
sess->smf_n4_seid = sess->index;
|
||||
|
||||
/* Set SUPI & PSI */
|
||||
sess->supi = ogs_strdup(supi);
|
||||
ogs_assert(sess->supi);
|
||||
sess->psi = psi;
|
||||
|
||||
sess->supi_psi_keybuf = supi_psi_keygen(supi, psi);
|
||||
ogs_assert(sess->supi_psi_keybuf);
|
||||
ogs_hash_set(self.supi_psi_hash,
|
||||
sess->supi_psi_keybuf, strlen(sess->supi_psi_keybuf), sess);
|
||||
|
||||
/* Select UPF with round-robin manner */
|
||||
if (ogs_pfcp_self()->node == NULL)
|
||||
ogs_pfcp_self()->node = ogs_list_first(&ogs_pfcp_self()->n4_list);
|
||||
|
@ -854,13 +918,16 @@ smf_sess_t *smf_sess_add_by_supi_psi(char *supi, uint8_t psi)
|
|||
ogs_fsm_create(&sess->sm, smf_gsm_state_initial, smf_gsm_state_final);
|
||||
ogs_fsm_init(&sess->sm, &e);
|
||||
|
||||
ogs_list_add(&self.sess_list, sess);
|
||||
sess->smf_ue = smf_ue;
|
||||
|
||||
ogs_list_add(&smf_ue->sess_list, sess);
|
||||
|
||||
return sess;
|
||||
}
|
||||
|
||||
smf_sess_t *smf_sess_add_by_sbi_message(ogs_sbi_message_t *message)
|
||||
{
|
||||
smf_ue_t *smf_ue = NULL;
|
||||
smf_sess_t *sess = NULL;
|
||||
|
||||
OpenAPI_sm_context_create_data_t *SmContextCreateData = NULL;
|
||||
|
@ -880,28 +947,35 @@ smf_sess_t *smf_sess_add_by_sbi_message(ogs_sbi_message_t *message)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
sess = smf_sess_find_by_supi_psi(
|
||||
SmContextCreateData->supi, SmContextCreateData->pdu_session_id);
|
||||
smf_ue = smf_ue_find_by_supi(SmContextCreateData->supi);
|
||||
if (!smf_ue) {
|
||||
smf_ue = smf_ue_add_by_supi(SmContextCreateData->supi);
|
||||
ogs_assert(smf_ue);
|
||||
}
|
||||
|
||||
sess = smf_sess_find_by_psi(smf_ue, SmContextCreateData->pdu_session_id);
|
||||
if (sess) {
|
||||
ogs_warn("OLD Session Release [SUPI:%s,PDU Session identity:%d]",
|
||||
SmContextCreateData->supi, SmContextCreateData->pdu_session_id);
|
||||
smf_sess_remove(sess);
|
||||
SMF_SESS_CLEAR(sess);
|
||||
}
|
||||
|
||||
sess = smf_sess_add_by_supi_psi(
|
||||
SmContextCreateData->supi, SmContextCreateData->pdu_session_id);
|
||||
sess = smf_sess_add_by_psi(smf_ue, SmContextCreateData->pdu_session_id);
|
||||
|
||||
return sess;
|
||||
}
|
||||
|
||||
int smf_sess_remove(smf_sess_t *sess)
|
||||
void smf_sess_remove(smf_sess_t *sess)
|
||||
{
|
||||
int i;
|
||||
smf_ue_t *smf_ue = NULL;
|
||||
smf_event_t e;
|
||||
|
||||
ogs_assert(sess);
|
||||
smf_ue = sess->smf_ue;
|
||||
ogs_assert(smf_ue);
|
||||
|
||||
ogs_list_remove(&self.sess_list, sess);
|
||||
ogs_list_remove(&smf_ue->sess_list, sess);
|
||||
|
||||
e.sess = sess;
|
||||
ogs_fsm_fini(&sess->sm, &e);
|
||||
|
@ -915,9 +989,6 @@ int smf_sess_remove(smf_sess_t *sess)
|
|||
OGS_PCC_RULE_FREE(&sess->pcc_rule[i]);
|
||||
sess->num_of_pcc_rule = 0;
|
||||
|
||||
ogs_hash_set(self.imsi_apn_hash,
|
||||
sess->imsi_apn_keybuf, sess->imsi_apn_keylen, NULL);
|
||||
|
||||
if (sess->ipv4) {
|
||||
ogs_hash_set(self.ipv4_hash, sess->ipv4->addr, OGS_IPV4_LEN, NULL);
|
||||
ogs_pfcp_ue_ip_free(sess->ipv4);
|
||||
|
@ -930,10 +1001,6 @@ int smf_sess_remove(smf_sess_t *sess)
|
|||
if (sess->sm_context_ref)
|
||||
ogs_free(sess->sm_context_ref);
|
||||
|
||||
if (sess->supi_psi_keybuf)
|
||||
ogs_free(sess->supi_psi_keybuf);
|
||||
if (sess->supi)
|
||||
ogs_free(sess->supi);
|
||||
if (sess->dnn)
|
||||
ogs_free(sess->dnn);
|
||||
|
||||
|
@ -944,15 +1011,15 @@ int smf_sess_remove(smf_sess_t *sess)
|
|||
smf_bearer_remove_all(sess);
|
||||
|
||||
ogs_pool_free(&smf_sess_pool, sess);
|
||||
|
||||
return OGS_OK;
|
||||
}
|
||||
|
||||
void smf_sess_remove_all(void)
|
||||
void smf_sess_remove_all(smf_ue_t *smf_ue)
|
||||
{
|
||||
smf_sess_t *sess = NULL, *next = NULL;;
|
||||
|
||||
ogs_list_for_each_safe(&self.sess_list, next, sess)
|
||||
ogs_assert(smf_ue);
|
||||
|
||||
ogs_list_for_each_safe(&smf_ue->sess_list, next, sess)
|
||||
smf_sess_remove(sess);
|
||||
}
|
||||
|
||||
|
@ -972,34 +1039,34 @@ smf_sess_t *smf_sess_find_by_seid(uint64_t seid)
|
|||
return smf_sess_find(seid);
|
||||
}
|
||||
|
||||
smf_sess_t *smf_sess_find_by_imsi_apn(
|
||||
uint8_t *imsi, int imsi_len, char *apn)
|
||||
{
|
||||
uint8_t keybuf[OGS_MAX_IMSI_LEN+OGS_MAX_APN_LEN+1];
|
||||
int keylen = 0;
|
||||
|
||||
ogs_assert(self.imsi_apn_hash);
|
||||
|
||||
imsi_apn_keygen(keybuf, &keylen, imsi, imsi_len, apn);
|
||||
return (smf_sess_t *)ogs_hash_get(self.imsi_apn_hash, keybuf, keylen);
|
||||
}
|
||||
|
||||
smf_sess_t *smf_sess_find_by_supi_psi(char *supi, uint8_t psi)
|
||||
smf_sess_t *smf_sess_find_by_apn(smf_ue_t *smf_ue, char *apn)
|
||||
{
|
||||
smf_sess_t *sess = NULL;
|
||||
char *keybuf = NULL;
|
||||
|
||||
ogs_assert(supi);
|
||||
ogs_assert(smf_ue);
|
||||
ogs_assert(apn);
|
||||
|
||||
ogs_list_for_each(&smf_ue->sess_list, sess) {
|
||||
if (!strcmp(sess->pdn.apn, apn))
|
||||
return sess;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
smf_sess_t *smf_sess_find_by_psi(smf_ue_t *smf_ue, uint8_t psi)
|
||||
{
|
||||
smf_sess_t *sess = NULL;
|
||||
|
||||
ogs_assert(smf_ue);
|
||||
ogs_assert(psi != OGS_NAS_PDU_SESSION_IDENTITY_UNASSIGNED);
|
||||
|
||||
keybuf = supi_psi_keygen(supi, psi);
|
||||
ogs_assert(keybuf);
|
||||
ogs_list_for_each(&smf_ue->sess_list, sess) {
|
||||
if (sess->psi == psi)
|
||||
return sess;
|
||||
}
|
||||
|
||||
sess = (smf_sess_t *)ogs_hash_get(self.supi_psi_hash,
|
||||
keybuf, strlen(keybuf));
|
||||
ogs_free(keybuf);
|
||||
|
||||
return sess;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
smf_sess_t *smf_sess_find_by_sm_context_ref(char *sm_context_ref)
|
||||
|
|
|
@ -84,16 +84,59 @@ typedef struct smf_context_s {
|
|||
ogs_list_t sgw_s5c_list; /* SGW GTPC Node List */
|
||||
ogs_list_t ip_pool_list;
|
||||
|
||||
ogs_hash_t *imsi_apn_hash; /* hash table (IMSI+APN) */
|
||||
ogs_hash_t *supi_psi_hash; /* hash table (SUPI+PSI) */
|
||||
ogs_hash_t *supi_hash; /* hash table (SUPI) */
|
||||
ogs_hash_t *imsi_hash; /* hash table (IMSI) */
|
||||
ogs_hash_t *ipv4_hash; /* hash table (IPv4 Address) */
|
||||
ogs_hash_t *ipv6_hash; /* hash table (IPv6 Address) */
|
||||
|
||||
uint16_t mtu; /* MTU to advertise in PCO */
|
||||
|
||||
ogs_list_t sess_list;
|
||||
#define SMF_UE_IS_LAST_SESSION(__sMF) \
|
||||
((__sMF) && (ogs_list_count(&(__sMF)->sess_list)) == 1)
|
||||
ogs_list_t smf_ue_list;
|
||||
} smf_context_t;
|
||||
|
||||
typedef struct smf_ue_s {
|
||||
ogs_lnode_t lnode;
|
||||
|
||||
/* SUPI */
|
||||
char *supi;
|
||||
|
||||
/* IMSI */
|
||||
uint8_t imsi[OGS_MAX_IMSI_LEN];
|
||||
int imsi_len;
|
||||
char imsi_bcd[OGS_MAX_IMSI_BCD_LEN+1];
|
||||
|
||||
ogs_list_t sess_list;
|
||||
} smf_ue_t;
|
||||
|
||||
#define SMF_NF_INSTANCE_CLEAR(_cAUSE, _nFInstance) \
|
||||
do { \
|
||||
ogs_assert(_nFInstance); \
|
||||
if ((_nFInstance)->reference_count == 1) { \
|
||||
ogs_info("[%s] (%s) NF removed", (_nFInstance)->id, (_cAUSE)); \
|
||||
smf_nf_fsm_fini((_nFInstance)); \
|
||||
} else { \
|
||||
/* There is an assocation with other context */ \
|
||||
ogs_info("[%s:%d] (%s) NF suspended", \
|
||||
_nFInstance->id, _nFInstance->reference_count, (_cAUSE)); \
|
||||
OGS_FSM_TRAN(&_nFInstance->sm, smf_nf_state_de_registered); \
|
||||
ogs_fsm_dispatch(&_nFInstance->sm, NULL); \
|
||||
} \
|
||||
ogs_sbi_nf_instance_remove(_nFInstance); \
|
||||
} while(0)
|
||||
#define SMF_SESS_CLEAR(__sESS) \
|
||||
do { \
|
||||
smf_ue_t *smf_ue = NULL; \
|
||||
ogs_assert(__sESS); \
|
||||
smf_ue = __sESS->smf_ue; \
|
||||
ogs_assert(smf_ue); \
|
||||
if (SMF_UE_IS_LAST_SESSION(smf_ue)) \
|
||||
smf_ue_remove(smf_ue); \
|
||||
else \
|
||||
smf_sess_remove(__sESS); \
|
||||
} while(0)
|
||||
|
||||
typedef struct smf_sess_s {
|
||||
ogs_sbi_object_t sbi;
|
||||
uint32_t index; /**< An index of this node */
|
||||
|
@ -119,14 +162,8 @@ typedef struct smf_sess_s {
|
|||
int imsi_len;
|
||||
char imsi_bcd[OGS_MAX_IMSI_BCD_LEN+1];
|
||||
|
||||
uint8_t imsi_apn_keybuf[OGS_MAX_IMSI_LEN+OGS_MAX_APN_LEN+1];
|
||||
int imsi_apn_keylen;
|
||||
|
||||
/* SUPI */
|
||||
char *sm_context_ref;
|
||||
char *supi;
|
||||
uint8_t psi; /* PDU session identity */
|
||||
char *supi_psi_keybuf;
|
||||
char *sm_context_ref; /* smContextRef */
|
||||
uint8_t psi; /* PDU session identity */
|
||||
|
||||
/* Procedure transaction identity */
|
||||
uint8_t pti;
|
||||
|
@ -166,21 +203,8 @@ typedef struct smf_sess_s {
|
|||
ogs_gtp_node_t *gnode;
|
||||
ogs_pfcp_node_t *pfcp_node;
|
||||
|
||||
#define SMF_NF_INSTANCE_CLEAR(_cAUSE, _nFInstance) \
|
||||
do { \
|
||||
ogs_assert(_nFInstance); \
|
||||
if ((_nFInstance)->reference_count == 1) { \
|
||||
ogs_info("[%s] (%s) NF removed", (_nFInstance)->id, (_cAUSE)); \
|
||||
smf_nf_fsm_fini((_nFInstance)); \
|
||||
} else { \
|
||||
/* There is an assocation with other context */ \
|
||||
ogs_info("[%s:%d] (%s) NF suspended", \
|
||||
_nFInstance->id, _nFInstance->reference_count, (_cAUSE)); \
|
||||
OGS_FSM_TRAN(&_nFInstance->sm, smf_nf_state_de_registered); \
|
||||
ogs_fsm_dispatch(&_nFInstance->sm, NULL); \
|
||||
} \
|
||||
ogs_sbi_nf_instance_remove(_nFInstance); \
|
||||
} while(0)
|
||||
/* Related Context */
|
||||
smf_ue_t *smf_ue;
|
||||
} smf_sess_t;
|
||||
|
||||
#define SMF_BEARER(pfcp_sess) ogs_container_of(pfcp_sess, smf_bearer_t, pfcp)
|
||||
|
@ -242,22 +266,29 @@ smf_context_t *smf_self(void);
|
|||
|
||||
int smf_context_parse_config(void);
|
||||
|
||||
smf_ue_t *smf_ue_add_by_supi(char *supi);
|
||||
smf_ue_t *smf_ue_add_by_imsi(uint8_t *imsi, int imsi_len);
|
||||
void smf_ue_remove(smf_ue_t *smf_ue);
|
||||
void smf_ue_remove_all(void);
|
||||
smf_ue_t *smf_ue_find_by_supi(char *supi);
|
||||
smf_ue_t *smf_ue_find_by_imsi(uint8_t *imsi, int imsi_len);
|
||||
|
||||
smf_sess_t *smf_sess_add_by_gtp_message(ogs_gtp_message_t *message);
|
||||
smf_sess_t *smf_sess_add_by_imsi_apn(
|
||||
uint8_t *imsi, int imsi_len, char *apn,
|
||||
smf_sess_t *smf_sess_add_by_apn(smf_ue_t *smf_ue, char *apn,
|
||||
uint8_t pdn_type, uint8_t ebi, ogs_paa_t *addr);
|
||||
|
||||
smf_sess_t *smf_sess_add_by_sbi_message(ogs_sbi_message_t *message);
|
||||
smf_sess_t *smf_sess_add_by_supi_psi(char *supi, uint8_t psi);
|
||||
smf_sess_t *smf_sess_add_by_psi(smf_ue_t *smf_ue, uint8_t psi);
|
||||
void smf_sess_set_ue_ip(smf_sess_t *sess);
|
||||
|
||||
int smf_sess_remove(smf_sess_t *sess);
|
||||
void smf_sess_remove_all(void);
|
||||
void smf_sess_remove(smf_sess_t *sess);
|
||||
void smf_sess_remove_all(smf_ue_t *smf_ue);
|
||||
|
||||
smf_sess_t *smf_sess_find(uint32_t index);
|
||||
smf_sess_t *smf_sess_find_by_teid(uint32_t teid);
|
||||
smf_sess_t *smf_sess_find_by_seid(uint64_t seid);
|
||||
smf_sess_t *smf_sess_find_by_imsi_apn(uint8_t *imsi, int imsi_len, char *apn);
|
||||
smf_sess_t *smf_sess_find_by_supi_psi(char *supi, uint8_t psi);
|
||||
smf_sess_t *smf_sess_find_by_apn(smf_ue_t *smf_ue, char *apn);
|
||||
smf_sess_t *smf_sess_find_by_psi(smf_ue_t *smf_ue, uint8_t psi);
|
||||
smf_sess_t *smf_sess_find_by_sm_context_ref(char *sm_context_ref);
|
||||
smf_sess_t *smf_sess_find_by_ipv4(uint32_t addr);
|
||||
smf_sess_t *smf_sess_find_by_ipv6(uint32_t *addr6);
|
||||
|
|
|
@ -34,6 +34,7 @@ ogs_pkbuf_t *gsm_build_pdu_session_establishment_accept(smf_sess_t *sess)
|
|||
ogs_nas_qos_rules_t *authorized_qos_rules = NULL;
|
||||
ogs_nas_session_ambr_t *session_ambr = NULL;
|
||||
ogs_nas_pdu_address_t *pdu_address = NULL;
|
||||
ogs_nas_5gsm_cause_t *gsm_cause = NULL;
|
||||
|
||||
ogs_nas_qos_rule_t qos_rule[OGS_NAS_MAX_NUM_OF_QOS_RULE];
|
||||
|
||||
|
@ -47,6 +48,8 @@ ogs_pkbuf_t *gsm_build_pdu_session_establishment_accept(smf_sess_t *sess)
|
|||
ogs_assert(session_ambr);
|
||||
pdu_address = &pdu_session_establishment_accept->pdu_address;
|
||||
ogs_assert(pdu_address);
|
||||
gsm_cause = &pdu_session_establishment_accept->gsm_cause;
|
||||
ogs_assert(gsm_cause);
|
||||
|
||||
memset(&message, 0, sizeof(message));
|
||||
message.gsm.h.extended_protocol_discriminator =
|
||||
|
@ -105,6 +108,19 @@ ogs_pkbuf_t *gsm_build_pdu_session_establishment_accept(smf_sess_t *sess)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* GSM cause */
|
||||
if (sess->ue_pdu_session_type == OGS_PDU_SESSION_TYPE_IPV4V6) {
|
||||
if (pdu_address->pdn_type == OGS_PDU_SESSION_TYPE_IPV4) {
|
||||
pdu_session_establishment_accept->presencemask |=
|
||||
OGS_NAS_5GS_PDU_SESSION_ESTABLISHMENT_ACCEPT_5GSM_CAUSE_PRESENT;
|
||||
*gsm_cause = OGS_5GSM_CAUSE_PDU_SESSION_TYPE_IPV4_ONLY_ALLOWED;
|
||||
} else if (pdu_address->pdn_type == OGS_PDU_SESSION_TYPE_IPV6) {
|
||||
pdu_session_establishment_accept->presencemask |=
|
||||
OGS_NAS_5GS_PDU_SESSION_ESTABLISHMENT_ACCEPT_5GSM_CAUSE_PRESENT;
|
||||
*gsm_cause = OGS_5GSM_CAUSE_PDU_SESSION_TYPE_IPV6_ONLY_ALLOWED;
|
||||
}
|
||||
}
|
||||
|
||||
pkbuf = ogs_nas_5gs_plain_encode(&message);
|
||||
ogs_assert(pkbuf);
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ void smf_gsm_state_final(ogs_fsm_t *s, smf_event_t *e)
|
|||
void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
|
||||
{
|
||||
int rv;
|
||||
smf_ue_t *smf_ue = NULL;
|
||||
smf_sess_t *sess = NULL;
|
||||
ogs_pkbuf_t *pkbuf = NULL;
|
||||
|
||||
|
@ -98,6 +99,8 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
|
|||
ogs_assert(sess);
|
||||
session = sess->sbi.session;
|
||||
ogs_assert(session);
|
||||
smf_ue = sess->smf_ue;
|
||||
ogs_assert(smf_ue);
|
||||
|
||||
ogs_timer_stop(sess->sbi.client_wait.timer);
|
||||
|
||||
|
@ -107,17 +110,17 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
|
|||
CASE(OGS_SBI_RESOURCE_NAME_SM_DATA)
|
||||
if (sbi_message->res_status != OGS_SBI_HTTP_STATUS_OK) {
|
||||
ogs_error("[%s] HTTP response error [%d]",
|
||||
sess->supi, sbi_message->res_status);
|
||||
smf_ue->supi, sbi_message->res_status);
|
||||
ogs_sbi_server_send_error(
|
||||
session, sbi_message->res_status,
|
||||
NULL, "HTTP response error", sess->supi);
|
||||
NULL, "HTTP response error", smf_ue->supi);
|
||||
break;
|
||||
}
|
||||
|
||||
if (smf_nudm_sdm_handle_get(sess, sbi_message) != true) {
|
||||
ogs_sbi_server_send_error(session,
|
||||
OGS_SBI_HTTP_STATUS_INTERNAL_SERVER_ERROR,
|
||||
sbi_message, "HTTP response error", sess->supi);
|
||||
sbi_message, "HTTP response error", smf_ue->supi);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -142,7 +145,7 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
|
|||
if (sbi_message->res_status != OGS_SBI_HTTP_STATUS_OK &&
|
||||
sbi_message->res_status != OGS_SBI_HTTP_STATUS_ACCEPTED) {
|
||||
ogs_error("[%s] HTTP response error [%d]",
|
||||
sess->supi, sbi_message->res_status);
|
||||
smf_ue->supi, sbi_message->res_status);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -166,6 +169,8 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
|
|||
ogs_assert(nas_message);
|
||||
sess = e->sess;
|
||||
ogs_assert(sess);
|
||||
smf_ue = sess->smf_ue;
|
||||
ogs_assert(smf_ue);
|
||||
|
||||
switch (nas_message->gsm.h.message_type) {
|
||||
case OGS_NAS_5GS_PDU_SESSION_ESTABLISHMENT_REQUEST:
|
||||
|
@ -173,7 +178,7 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
|
|||
sess, &nas_message->gsm.pdu_session_establishment_request);
|
||||
if (rv != OGS_OK) {
|
||||
ogs_error("[%s:%d] Cannot handle NAS message",
|
||||
sess->supi, sess->psi);
|
||||
smf_ue->supi, sess->psi);
|
||||
OGS_FSM_TRAN(s, smf_gsm_state_exception);
|
||||
break;
|
||||
}
|
||||
|
@ -188,6 +193,8 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
|
|||
case SMF_EVT_NGAP_MESSAGE:
|
||||
sess = e->sess;
|
||||
ogs_assert(sess);
|
||||
smf_ue = sess->smf_ue;
|
||||
ogs_assert(smf_ue);
|
||||
pkbuf = e->pkbuf;
|
||||
ogs_assert(pkbuf);
|
||||
ogs_assert(e->ngap.type);
|
||||
|
@ -198,7 +205,7 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
|
|||
sess, pkbuf);
|
||||
if (rv != OGS_OK) {
|
||||
ogs_error("[%s:%d] Cannot handle NGAP message",
|
||||
sess->supi, sess->psi);
|
||||
smf_ue->supi, sess->psi);
|
||||
OGS_FSM_TRAN(s, smf_gsm_state_exception);
|
||||
}
|
||||
break;
|
||||
|
@ -210,8 +217,7 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
|
|||
break;
|
||||
|
||||
default:
|
||||
ogs_error("[%s:%d] Unknown event %s",
|
||||
sess->supi, sess->psi, smf_event_get_name(e));
|
||||
ogs_error("Unknown event [%s]", smf_event_get_name(e));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,7 +90,7 @@ static struct {
|
|||
ogs_pfcp_ue_ip_addr_t addr;
|
||||
ogs_pfcp_outer_header_removal_t outer_header_removal;
|
||||
ogs_pfcp_f_teid_t f_teid;
|
||||
char apn[OGS_MAX_APN_LEN];
|
||||
char dnn[OGS_MAX_DNN_LEN];
|
||||
char *sdf_filter[OGS_MAX_NUM_OF_RULE];
|
||||
} pdrbuf[OGS_MAX_NUM_OF_PDR];
|
||||
|
||||
|
@ -145,8 +145,8 @@ static void build_create_pdr(
|
|||
|
||||
message->pdi.network_instance.presence = 1;
|
||||
message->pdi.network_instance.len = ogs_fqdn_build(
|
||||
pdrbuf[i].apn, sess->pdn.apn, strlen(sess->pdn.apn));
|
||||
message->pdi.network_instance.data = pdrbuf[i].apn;
|
||||
pdrbuf[i].dnn, sess->pdn.dnn, strlen(sess->pdn.dnn));
|
||||
message->pdi.network_instance.data = pdrbuf[i].dnn;
|
||||
|
||||
for (j = 0; j < pdr->num_of_flow; j++) {
|
||||
ogs_pfcp_sdf_filter_t pfcp_sdf_filter[OGS_MAX_NUM_OF_RULE];
|
||||
|
|
|
@ -204,14 +204,14 @@ void smf_5gc_n4_handle_session_modification_response(
|
|||
ogs_error("Cause[%d] : No Accepted", rsp->cause.u8);
|
||||
smf_sbi_send_sm_context_update_error(session,
|
||||
OGS_SBI_HTTP_STATUS_INTERNAL_SERVER_ERROR,
|
||||
"[PFCP] No Accepted", sess->supi_psi_keybuf, NULL);
|
||||
"[PFCP] No Accepted", NULL, NULL);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
ogs_error("No Cause");
|
||||
smf_sbi_send_sm_context_update_error(session,
|
||||
OGS_SBI_HTTP_STATUS_INTERNAL_SERVER_ERROR,
|
||||
"[PFCP] No Cause", sess->supi_psi_keybuf, NULL);
|
||||
"[PFCP] No Cause", NULL, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -345,5 +345,5 @@ void smf_epc_n4_handle_session_deletion_response(
|
|||
|
||||
smf_gtp_send_delete_session_response(sess, gtp_xact);
|
||||
|
||||
smf_sess_remove(sess);
|
||||
SMF_SESS_CLEAR(sess);
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ ogs_sbi_request_t *smf_namf_comm_build_n1_n2_message_transfer(
|
|||
smf_sess_t *sess, void *data)
|
||||
{
|
||||
int i;
|
||||
smf_ue_t *smf_ue = NULL;
|
||||
|
||||
ogs_sbi_message_t message;
|
||||
ogs_sbi_request_t *request = NULL;
|
||||
|
@ -40,14 +41,16 @@ ogs_sbi_request_t *smf_namf_comm_build_n1_n2_message_transfer(
|
|||
OpenAPI_ref_to_binary_data_t ngapData;
|
||||
|
||||
ogs_assert(sess);
|
||||
ogs_assert(sess->supi);
|
||||
smf_ue = sess->smf_ue;
|
||||
ogs_assert(smf_ue);
|
||||
ogs_assert(smf_ue->supi);
|
||||
|
||||
memset(&message, 0, sizeof(message));
|
||||
message.h.method = (char *)OGS_SBI_HTTP_METHOD_POST;
|
||||
message.h.service.name = (char *)OGS_SBI_SERVICE_NAME_NAMF_COMM;
|
||||
message.h.api.version = (char *)OGS_SBI_API_V1;
|
||||
message.h.resource.component[0] = (char *)OGS_SBI_RESOURCE_NAME_UE_CONTEXTS;
|
||||
message.h.resource.component[1] = sess->supi;
|
||||
message.h.resource.component[1] = smf_ue->supi;
|
||||
message.h.resource.component[2] =
|
||||
(char *)OGS_SBI_RESOURCE_NAME_N1_N2_MESSAGES;
|
||||
message.N1N2MessageTransferReqData = &N1N2MessageTransferReqData;
|
||||
|
|
|
@ -25,6 +25,7 @@ int ngap_handle_pdu_session_resource_setup_response_transfer(
|
|||
smf_sess_t *sess, ogs_pkbuf_t *pkbuf)
|
||||
{
|
||||
ogs_sbi_session_t *session = NULL;
|
||||
smf_ue_t *smf_ue = NULL;
|
||||
smf_bearer_t *bearer = NULL;
|
||||
int rv, i;
|
||||
|
||||
|
@ -43,15 +44,18 @@ int ngap_handle_pdu_session_resource_setup_response_transfer(
|
|||
ogs_assert(session);
|
||||
bearer = smf_default_bearer_in_sess(sess);
|
||||
ogs_assert(bearer);
|
||||
smf_ue = sess->smf_ue;
|
||||
ogs_assert(smf_ue);
|
||||
|
||||
rv = ogs_asn_decode(
|
||||
&asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer,
|
||||
&message, sizeof(message), pkbuf);
|
||||
if (rv != OGS_OK) {
|
||||
ogs_error("[%s:%d] Cannot decode NGAP message", sess->supi, sess->psi);
|
||||
ogs_error("[%s:%d] Cannot decode NGAP message",
|
||||
smf_ue->supi, sess->psi);
|
||||
smf_sbi_send_sm_context_update_error(session,
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||
"No N2 SM Info Type", sess->supi_psi_keybuf, NULL);
|
||||
"No N2 SM Info Type", smf_ue->supi, NULL);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
@ -65,11 +69,11 @@ int ngap_handle_pdu_session_resource_setup_response_transfer(
|
|||
NGAP_UPTransportLayerInformation_PR_gTPTunnel) {
|
||||
ogs_error(
|
||||
"[%s:%d] Unknown NGAP_UPTransportLayerInformation.present [%d]",
|
||||
sess->supi, sess->psi, uPTransportLayerInformation->present);
|
||||
smf_ue->supi, sess->psi, uPTransportLayerInformation->present);
|
||||
smf_sbi_send_sm_context_update_error(session,
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||
"Unknown NGAP_UPTransportLayerInformation.present",
|
||||
sess->supi_psi_keybuf, NULL);
|
||||
smf_ue->supi, NULL);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
@ -85,10 +89,10 @@ int ngap_handle_pdu_session_resource_setup_response_transfer(
|
|||
|
||||
gTPTunnel = uPTransportLayerInformation->choice.gTPTunnel;
|
||||
if (!gTPTunnel) {
|
||||
ogs_error("[%s:%d] No GTPTunnel", sess->supi, sess->psi);
|
||||
ogs_error("[%s:%d] No GTPTunnel", smf_ue->supi, sess->psi);
|
||||
smf_sbi_send_sm_context_update_error(session,
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||
"No GTPTunnel", sess->supi_psi_keybuf, NULL);
|
||||
"No GTPTunnel", smf_ue->supi, NULL);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
bool smf_nsmf_handle_create_sm_context(
|
||||
smf_sess_t *sess, ogs_sbi_message_t *message)
|
||||
{
|
||||
smf_ue_t *smf_ue = NULL;
|
||||
ogs_sbi_session_t *session = NULL;
|
||||
|
||||
OpenAPI_sm_context_create_data_t *SmContextCreateData = NULL;
|
||||
|
@ -37,59 +38,64 @@ bool smf_nsmf_handle_create_sm_context(
|
|||
ogs_assert(sess);
|
||||
session = sess->sbi.session;
|
||||
ogs_assert(session);
|
||||
smf_ue = sess->smf_ue;
|
||||
ogs_assert(smf_ue);
|
||||
|
||||
ogs_assert(message);
|
||||
|
||||
SmContextCreateData = message->SmContextCreateData;
|
||||
if (!SmContextCreateData) {
|
||||
ogs_error("[%s:%d] No SmContextCreateData", sess->supi, sess->psi);
|
||||
ogs_error("[%s:%d] No SmContextCreateData", smf_ue->supi, sess->psi);
|
||||
n1smbuf = gsm_build_pdu_session_establishment_reject(sess,
|
||||
OGS_5GSM_CAUSE_INVALID_MANDATORY_INFORMATION);
|
||||
smf_sbi_send_sm_context_create_error(session,
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||
"No SmContextCreateData", sess->supi_psi_keybuf, n1smbuf);
|
||||
"No SmContextCreateData", smf_ue->supi, n1smbuf);
|
||||
return false;
|
||||
}
|
||||
|
||||
sNssai = SmContextCreateData->s_nssai;
|
||||
if (!sNssai) {
|
||||
ogs_error("[%s:%d] No sNssai", sess->supi, sess->psi);
|
||||
ogs_error("[%s:%d] No sNssai", smf_ue->supi, sess->psi);
|
||||
n1smbuf = gsm_build_pdu_session_establishment_reject(sess,
|
||||
OGS_5GSM_CAUSE_INVALID_MANDATORY_INFORMATION);
|
||||
smf_sbi_send_sm_context_create_error(session,
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||
"No sNssai", sess->supi_psi_keybuf, n1smbuf);
|
||||
"No sNssai", smf_ue->supi, n1smbuf);
|
||||
return false;
|
||||
}
|
||||
|
||||
servingNetwork = SmContextCreateData->serving_network;
|
||||
if (!servingNetwork || !servingNetwork->mnc || !servingNetwork->mcc) {
|
||||
ogs_error("[%s:%d] No servingNetwork", sess->supi, sess->psi);
|
||||
ogs_error("[%s:%d] No servingNetwork", smf_ue->supi, sess->psi);
|
||||
n1smbuf = gsm_build_pdu_session_establishment_reject(sess,
|
||||
OGS_5GSM_CAUSE_INVALID_MANDATORY_INFORMATION);
|
||||
smf_sbi_send_sm_context_create_error(session,
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||
"No servingNetwork", sess->supi_psi_keybuf, n1smbuf);
|
||||
"No servingNetwork", smf_ue->supi, n1smbuf);
|
||||
return false;
|
||||
}
|
||||
|
||||
n1SmMsg = SmContextCreateData->n1_sm_msg;
|
||||
if (!n1SmMsg || !n1SmMsg->content_id) {
|
||||
ogs_error("[%s:%d] No n1SmMsg", smf_ue->supi, sess->psi);
|
||||
n1smbuf = gsm_build_pdu_session_establishment_reject(sess,
|
||||
OGS_5GSM_CAUSE_INVALID_MANDATORY_INFORMATION);
|
||||
smf_sbi_send_sm_context_create_error(session,
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||
"No N1 SM Message", sess->supi_psi_keybuf, n1smbuf);
|
||||
"No n1SmMsg", smf_ue->supi, n1smbuf);
|
||||
return false;
|
||||
}
|
||||
|
||||
n1smbuf = ogs_sbi_find_part_by_content_id(message, n1SmMsg->content_id);
|
||||
if (!n1smbuf) {
|
||||
ogs_error("[%s:%d] No N1 SM Content [%s]",
|
||||
smf_ue->supi, sess->psi, n1SmMsg->content_id);
|
||||
n1smbuf = gsm_build_pdu_session_establishment_reject(sess,
|
||||
OGS_5GSM_CAUSE_INVALID_MANDATORY_INFORMATION);
|
||||
smf_sbi_send_sm_context_create_error(session,
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||
"No N1 SM Content", sess->supi_psi_keybuf, n1smbuf);
|
||||
"No N1 SM Content", smf_ue->supi, n1smbuf);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -114,6 +120,7 @@ bool smf_nsmf_handle_create_sm_context(
|
|||
bool smf_nsmf_handle_update_sm_context(
|
||||
smf_sess_t *sess, ogs_sbi_message_t *message)
|
||||
{
|
||||
smf_ue_t *smf_ue = NULL;
|
||||
ogs_sbi_session_t *session = NULL;
|
||||
|
||||
OpenAPI_sm_context_update_data_t *SmContextUpdateData = NULL;
|
||||
|
@ -124,23 +131,25 @@ bool smf_nsmf_handle_update_sm_context(
|
|||
ogs_assert(sess);
|
||||
session = sess->sbi.session;
|
||||
ogs_assert(session);
|
||||
smf_ue = sess->smf_ue;
|
||||
ogs_assert(smf_ue);
|
||||
|
||||
ogs_assert(message);
|
||||
|
||||
SmContextUpdateData = message->SmContextUpdateData;
|
||||
if (!SmContextUpdateData) {
|
||||
ogs_error("[%s:%d] No SmContextUpdateData", sess->supi, sess->psi);
|
||||
ogs_error("[%s:%d] No SmContextUpdateData", smf_ue->supi, sess->psi);
|
||||
smf_sbi_send_sm_context_update_error(session,
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||
"No SmContextUpdateData", sess->supi_psi_keybuf, NULL);
|
||||
"No SmContextUpdateData", smf_ue->supi, NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!SmContextUpdateData->n2_sm_info_type) {
|
||||
ogs_error("[%s:%d] No n2SmInfoType", sess->supi, sess->psi);
|
||||
ogs_error("[%s:%d] No n2SmInfoType", smf_ue->supi, sess->psi);
|
||||
smf_sbi_send_sm_context_update_error(session,
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||
"No N2 SM Info Type", sess->supi_psi_keybuf, NULL);
|
||||
"No N2 SM Info Type", smf_ue->supi, NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -148,7 +157,7 @@ bool smf_nsmf_handle_update_sm_context(
|
|||
if (!n2SmMsg || !n2SmMsg->content_id) {
|
||||
smf_sbi_send_sm_context_update_error(session,
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||
"No n2SmInfo", sess->supi_psi_keybuf, NULL);
|
||||
"No n2SmInfo", smf_ue->supi, NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -156,7 +165,7 @@ bool smf_nsmf_handle_update_sm_context(
|
|||
if (!n2smbuf) {
|
||||
smf_sbi_send_sm_context_update_error(session,
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||
"No N2 SM Content", sess->supi_psi_keybuf, NULL);
|
||||
"No N2 SM Content", smf_ue->supi, NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -169,90 +178,5 @@ bool smf_nsmf_handle_release_sm_context(
|
|||
smf_sess_t *sess, ogs_sbi_message_t *message)
|
||||
{
|
||||
ogs_fatal("TODO");
|
||||
#if 0
|
||||
ogs_sbi_session_t *session = NULL;
|
||||
|
||||
OpenAPI_sm_context_release_data_t *SmContextReleaseData = NULL;
|
||||
OpenAPI_snssai_t *sNssai = NULL;
|
||||
OpenAPI_plmn_id_nid_t *servingNetwork = NULL;
|
||||
OpenAPI_ref_to_binary_data_t *n1SmMsg = NULL;
|
||||
|
||||
ogs_pkbuf_t *n1smbuf = NULL;
|
||||
|
||||
ogs_assert(sess);
|
||||
session = sess->sbi.session;
|
||||
ogs_assert(session);
|
||||
|
||||
ogs_assert(message);
|
||||
|
||||
SmContextReleaseData = message->SmContextReleaseData;
|
||||
if (!SmContextReleaseData) {
|
||||
ogs_error("[%s:%d] No SmContextReleaseData", sess->supi, sess->psi);
|
||||
n1smbuf = gsm_build_pdu_session_establishment_reject(sess,
|
||||
OGS_5GSM_CAUSE_INVALID_MANDATORY_INFORMATION);
|
||||
smf_sbi_send_sm_context_release_error(session,
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||
"No SmContextReleaseData", sess->supi_psi_keybuf, n1smbuf);
|
||||
return false;
|
||||
}
|
||||
|
||||
sNssai = SmContextReleaseData->s_nssai;
|
||||
if (!sNssai) {
|
||||
ogs_error("[%s:%d] No sNssai", sess->supi, sess->psi);
|
||||
n1smbuf = gsm_build_pdu_session_establishment_reject(sess,
|
||||
OGS_5GSM_CAUSE_INVALID_MANDATORY_INFORMATION);
|
||||
smf_sbi_send_sm_context_release_error(session,
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||
"No sNssai", sess->supi_psi_keybuf, n1smbuf);
|
||||
return false;
|
||||
}
|
||||
|
||||
servingNetwork = SmContextReleaseData->serving_network;
|
||||
if (!servingNetwork || !servingNetwork->mnc || !servingNetwork->mcc) {
|
||||
ogs_error("[%s:%d] No servingNetwork", sess->supi, sess->psi);
|
||||
n1smbuf = gsm_build_pdu_session_establishment_reject(sess,
|
||||
OGS_5GSM_CAUSE_INVALID_MANDATORY_INFORMATION);
|
||||
smf_sbi_send_sm_context_release_error(session,
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||
"No servingNetwork", sess->supi_psi_keybuf, n1smbuf);
|
||||
return false;
|
||||
}
|
||||
|
||||
n1SmMsg = SmContextReleaseData->n1_sm_msg;
|
||||
if (!n1SmMsg || !n1SmMsg->content_id) {
|
||||
n1smbuf = gsm_build_pdu_session_establishment_reject(sess,
|
||||
OGS_5GSM_CAUSE_INVALID_MANDATORY_INFORMATION);
|
||||
smf_sbi_send_sm_context_release_error(session,
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||
"No N1 SM Message", sess->supi_psi_keybuf, n1smbuf);
|
||||
return false;
|
||||
}
|
||||
|
||||
n1smbuf = ogs_sbi_find_part_by_content_id(message, n1SmMsg->content_id);
|
||||
if (!n1smbuf) {
|
||||
n1smbuf = gsm_build_pdu_session_establishment_reject(sess,
|
||||
OGS_5GSM_CAUSE_INVALID_MANDATORY_INFORMATION);
|
||||
smf_sbi_send_sm_context_release_error(session,
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||
"No N1 SM Content", sess->supi_psi_keybuf, n1smbuf);
|
||||
return false;
|
||||
}
|
||||
|
||||
ogs_plmn_id_build(&sess->plmn_id,
|
||||
atoi(servingNetwork->mcc), atoi(servingNetwork->mnc),
|
||||
strlen(servingNetwork->mnc));
|
||||
sess->nid = servingNetwork->nid;
|
||||
|
||||
sess->s_nssai.sst = sNssai->sst;
|
||||
sess->s_nssai.sd = ogs_s_nssai_sd_from_string(sNssai->sd);
|
||||
|
||||
if (SmContextReleaseData->dnn) {
|
||||
if (sess->dnn) ogs_free(sess->dnn);
|
||||
sess->dnn = ogs_strdup(SmContextReleaseData->dnn);
|
||||
}
|
||||
|
||||
nas_5gs_send_to_gsm(sess, n1smbuf);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -21,17 +21,20 @@
|
|||
|
||||
ogs_sbi_request_t *smf_nudm_sdm_build_get(smf_sess_t *sess, void *data)
|
||||
{
|
||||
smf_ue_t *smf_ue = NULL;
|
||||
ogs_sbi_message_t message;
|
||||
ogs_sbi_request_t *request = NULL;
|
||||
|
||||
ogs_assert(sess);
|
||||
ogs_assert(sess->supi);
|
||||
smf_ue = sess->smf_ue;
|
||||
ogs_assert(smf_ue);
|
||||
ogs_assert(smf_ue->supi);
|
||||
|
||||
memset(&message, 0, sizeof(message));
|
||||
message.h.method = (char *)OGS_SBI_HTTP_METHOD_GET;
|
||||
message.h.service.name = (char *)OGS_SBI_SERVICE_NAME_NUDM_SDM;
|
||||
message.h.api.version = (char *)OGS_SBI_API_V2;
|
||||
message.h.resource.component[0] = sess->supi;
|
||||
message.h.resource.component[0] = smf_ue->supi;
|
||||
message.h.resource.component[1] = data;
|
||||
|
||||
message.param.s_nssai_presence = true;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
bool smf_nudm_sdm_handle_get(smf_sess_t *sess, ogs_sbi_message_t *recvmsg)
|
||||
{
|
||||
smf_ue_t *smf_ue = NULL;
|
||||
ogs_sbi_server_t *server = NULL;
|
||||
ogs_sbi_session_t *session = NULL;
|
||||
|
||||
|
@ -45,6 +46,8 @@ bool smf_nudm_sdm_handle_get(smf_sess_t *sess, ogs_sbi_message_t *recvmsg)
|
|||
ogs_assert(sess);
|
||||
session = sess->sbi.session;
|
||||
ogs_assert(session);
|
||||
smf_ue = sess->smf_ue;
|
||||
ogs_assert(smf_ue);
|
||||
server = ogs_sbi_session_get_server(session);
|
||||
ogs_assert(server);
|
||||
|
||||
|
@ -53,14 +56,14 @@ bool smf_nudm_sdm_handle_get(smf_sess_t *sess, ogs_sbi_message_t *recvmsg)
|
|||
SessionManagementSubscriptionData =
|
||||
recvmsg->SessionManagementSubscriptionData;
|
||||
if (!SessionManagementSubscriptionData) {
|
||||
ogs_error("[%s] No SessionManagementSubscriptionData", sess->supi);
|
||||
ogs_error("[%s] No SessionManagementSubscriptionData", smf_ue->supi);
|
||||
return false;
|
||||
}
|
||||
|
||||
dnnConfigurationList =
|
||||
SessionManagementSubscriptionData->dnn_configurations;
|
||||
if (!dnnConfigurationList) {
|
||||
ogs_error("[%s] No dnnConfigurations", sess->supi);
|
||||
ogs_error("[%s] No dnnConfigurations", smf_ue->supi);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -104,15 +107,10 @@ bool smf_nudm_sdm_handle_get(smf_sess_t *sess, ogs_sbi_message_t *recvmsg)
|
|||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sess->pdn.pdn_type =
|
||||
pduSessionTypeList->default_session_type;
|
||||
}
|
||||
|
||||
if (!sess->pdn.pdn_type) {
|
||||
ogs_error("PDU Session Type is not allowed");
|
||||
continue;
|
||||
}
|
||||
if (!sess->pdn.pdn_type)
|
||||
sess->pdn.pdn_type = pduSessionTypeList->default_session_type;
|
||||
|
||||
if (sess->ue_ssc_mode) {
|
||||
OpenAPI_list_for_each(sscModeList->allowed_ssc_modes, node2) {
|
||||
|
@ -204,16 +202,16 @@ bool smf_nudm_sdm_handle_get(smf_sess_t *sess, ogs_sbi_message_t *recvmsg)
|
|||
}
|
||||
|
||||
/* Succeeded to get PDU Session */
|
||||
ogs_cpystrn(sess->pdn.apn, dnnConfigurationMap->key,
|
||||
ogs_cpystrn(sess->pdn.dnn, dnnConfigurationMap->key,
|
||||
ogs_min(strlen(dnnConfigurationMap->key),
|
||||
OGS_MAX_APN_LEN)+1);
|
||||
OGS_MAX_DNN_LEN)+1);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!strlen(sess->pdn.apn)) {
|
||||
ogs_error("[%s] No dnnConfiguration", sess->supi);
|
||||
if (!strlen(sess->pdn.dnn)) {
|
||||
ogs_error("[%s] No dnnConfiguration", smf_ue->supi);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -120,11 +120,16 @@ void smf_sbi_discover_and_send(
|
|||
ogs_sbi_request_t *(*build)(smf_sess_t *sess, void *data))
|
||||
{
|
||||
ogs_sbi_session_t *session = NULL;
|
||||
smf_ue_t *smf_ue = NULL;
|
||||
|
||||
ogs_assert(nf_type);
|
||||
ogs_assert(build);
|
||||
|
||||
ogs_assert(sess);
|
||||
session = sess->sbi.session;
|
||||
ogs_assert(nf_type);
|
||||
ogs_assert(build);
|
||||
ogs_assert(session);
|
||||
smf_ue = sess->smf_ue;
|
||||
ogs_assert(smf_ue);
|
||||
|
||||
sess->sbi.nf_state_registered = smf_nf_state_registered;
|
||||
sess->sbi.client_wait.duration =
|
||||
|
@ -134,7 +139,7 @@ void smf_sbi_discover_and_send(
|
|||
nf_type, &sess->sbi, data, (ogs_sbi_build_f)build) != true) {
|
||||
ogs_sbi_server_send_error(session,
|
||||
OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT, NULL,
|
||||
"Cannot discover", sess->supi);
|
||||
"Cannot discover", smf_ue->supi);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
|
|||
|
||||
ogs_pkbuf_t *recvbuf = NULL;
|
||||
smf_sess_t *sess = NULL;
|
||||
smf_ue_t *smf_ue = NULL;
|
||||
|
||||
ogs_gtp_node_t *gnode = NULL;
|
||||
ogs_gtp_xact_t *gtp_xact = NULL;
|
||||
|
@ -361,6 +362,8 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
|
|||
END
|
||||
|
||||
if (sess) {
|
||||
smf_ue = sess->smf_ue;
|
||||
ogs_assert(smf_ue);
|
||||
ogs_assert(OGS_FSM_STATE(&sess->sm));
|
||||
|
||||
OGS_SETUP_SBI_SESSION(&sess->sbi, session);
|
||||
|
@ -369,8 +372,8 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
|
|||
e->sbi.message = &sbi_message;
|
||||
ogs_fsm_dispatch(&sess->sm, e);
|
||||
if (OGS_FSM_CHECK(&sess->sm, smf_gsm_state_exception)) {
|
||||
ogs_error("[%s] State machine exception", sess->supi);
|
||||
smf_sess_remove(sess);
|
||||
ogs_error("[%s] State machine exception", smf_ue->supi);
|
||||
SMF_SESS_CLEAR(sess);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -516,14 +519,16 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
|
|||
CASE(OGS_SBI_SERVICE_NAME_NAMF_COMM)
|
||||
sess = e->sbi.data;
|
||||
ogs_assert(sess);
|
||||
smf_ue = sess->smf_ue;
|
||||
ogs_assert(smf_ue);
|
||||
ogs_assert(OGS_FSM_STATE(&sess->sm));
|
||||
|
||||
e->sess = sess;
|
||||
e->sbi.message = &sbi_message;;
|
||||
ogs_fsm_dispatch(&sess->sm, e);
|
||||
if (OGS_FSM_CHECK(&sess->sm, smf_gsm_state_exception)) {
|
||||
ogs_error("[%s] State machine exception", sess->supi);
|
||||
smf_sess_remove(sess);
|
||||
ogs_error("[%s] State machine exception", smf_ue->supi);
|
||||
SMF_SESS_CLEAR(sess);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -603,7 +608,7 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
|
|||
ogs_fsm_dispatch(&sess->sm, e);
|
||||
if (OGS_FSM_CHECK(&sess->sm, smf_gsm_state_exception)) {
|
||||
ogs_error("State machine exception");
|
||||
smf_sess_remove(sess);
|
||||
SMF_SESS_CLEAR(sess);
|
||||
}
|
||||
|
||||
ogs_pkbuf_free(pkbuf);
|
||||
|
@ -622,7 +627,7 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
|
|||
ogs_fsm_dispatch(&sess->sm, e);
|
||||
if (OGS_FSM_CHECK(&sess->sm, smf_gsm_state_exception)) {
|
||||
ogs_error("State machine exception");
|
||||
smf_sess_remove(sess);
|
||||
SMF_SESS_CLEAR(sess);
|
||||
}
|
||||
|
||||
ogs_pkbuf_free(pkbuf);
|
||||
|
|
|
@ -254,7 +254,7 @@ bool udr_nudr_dr_handle_subscription_provisioned(
|
|||
|
||||
ogs_sbi_message_t sendmsg;
|
||||
ogs_sbi_response_t *response = NULL;
|
||||
ogs_dbi_subscription_data_t subscription_data;
|
||||
ogs_subscription_data_t subscription_data;
|
||||
|
||||
char *supi = NULL;
|
||||
|
||||
|
@ -470,20 +470,14 @@ bool udr_nudr_dr_handle_subscription_provisioned(
|
|||
staticIpAddress = OpenAPI_list_create();
|
||||
ogs_assert(staticIpAddress);
|
||||
|
||||
if (pdn->paa.pdn_type == OGS_GTP_PDN_TYPE_IPV4 ||
|
||||
pdn->paa.pdn_type == OGS_GTP_PDN_TYPE_IPV6 ||
|
||||
pdn->paa.pdn_type == OGS_GTP_PDN_TYPE_IPV4V6) {
|
||||
if (pdn->ue_ip.ipv4 || pdn->ue_ip.ipv6) {
|
||||
ipAddress = ogs_calloc(1, sizeof(*ipAddress));
|
||||
ogs_assert(ipAddress);
|
||||
|
||||
if (pdn->paa.pdn_type == OGS_GTP_PDN_TYPE_IPV4 ||
|
||||
pdn->paa.pdn_type == OGS_GTP_PDN_TYPE_IPV4V6) {
|
||||
if (pdn->ue_ip.ipv4)
|
||||
ipAddress->ipv4_addr = ogs_ipv4_to_string(pdn->ue_ip.addr);
|
||||
}
|
||||
if (pdn->paa.pdn_type == OGS_GTP_PDN_TYPE_IPV6 ||
|
||||
pdn->paa.pdn_type == OGS_GTP_PDN_TYPE_IPV4V6) {
|
||||
if (pdn->ue_ip.ipv6)
|
||||
ipAddress->ipv6_addr = ogs_ipv6_to_string(pdn->ue_ip.addr6);
|
||||
}
|
||||
|
||||
if (ipAddress->ipv4_addr || ipAddress->ipv6_addr)
|
||||
OpenAPI_list_add(staticIpAddress, ipAddress);
|
||||
|
|
|
@ -41,11 +41,9 @@
|
|||
|
||||
#define UPF_GTP_HANDLED 1
|
||||
|
||||
uint16_t in_cksum(uint16_t *addr, int len);
|
||||
static int upf_gtp_handle_multicast(ogs_pkbuf_t *recvbuf);
|
||||
static int upf_gtp_handle_slaac(upf_sess_t *sess, ogs_pkbuf_t *recvbuf);
|
||||
static void upf_gtp_send_to_far(ogs_pfcp_far_t *far, ogs_pkbuf_t *sendbuf);
|
||||
static void upf_gtp_send_to_pdr(ogs_pfcp_pdr_t *pdr, ogs_pkbuf_t *sendbuf);
|
||||
static int upf_gtp_handle_pdr(ogs_pfcp_pdr_t *pdr, ogs_pkbuf_t *recvbuf);
|
||||
static int upf_gtp_send_router_advertisement(
|
||||
upf_sess_t *sess, uint8_t *ip6_dst);
|
||||
|
||||
|
@ -72,7 +70,7 @@ static void _gtpv1_tun_recv_cb(short when, ogs_socket_t fd, void *data)
|
|||
pdr = upf_pdr_find_by_packet(recvbuf);
|
||||
if (pdr) {
|
||||
/* Unicast */
|
||||
upf_gtp_send_to_pdr(pdr, recvbuf);
|
||||
upf_gtp_handle_pdr(pdr, recvbuf);
|
||||
} else {
|
||||
if (ogs_config()->parameter.multicast) {
|
||||
upf_gtp_handle_multicast(recvbuf);
|
||||
|
@ -252,6 +250,49 @@ void upf_gtp_close(void)
|
|||
}
|
||||
}
|
||||
|
||||
void upf_gtp_send_to_gnb(ogs_pfcp_far_t *far, ogs_pkbuf_t *sendbuf)
|
||||
{
|
||||
char buf[OGS_ADDRSTRLEN];
|
||||
int rv;
|
||||
ogs_gtp_header_t *gtp_h = NULL;
|
||||
ogs_gtp_node_t *gnode = NULL;
|
||||
|
||||
ogs_assert(far);
|
||||
|
||||
if (far->dst_if != OGS_PFCP_INTERFACE_ACCESS) {
|
||||
ogs_error("FAR is NOT Downlink");
|
||||
return;
|
||||
}
|
||||
|
||||
gnode = far->gnode;
|
||||
ogs_assert(gnode);
|
||||
ogs_assert(gnode->sock);
|
||||
ogs_assert(sendbuf);
|
||||
|
||||
/* Add GTP-U header */
|
||||
ogs_assert(ogs_pkbuf_push(sendbuf, OGS_GTPV1U_HEADER_LEN));
|
||||
gtp_h = (ogs_gtp_header_t *)sendbuf->data;
|
||||
/* Bits 8 7 6 5 4 3 2 1
|
||||
* +--+--+--+--+--+--+--+--+
|
||||
* |version |PT| 1| E| S|PN|
|
||||
* +--+--+--+--+--+--+--+--+
|
||||
* 0 0 1 1 0 0 0 0
|
||||
*/
|
||||
gtp_h->flags = 0x30;
|
||||
gtp_h->type = OGS_GTPU_MSGTYPE_GPDU;
|
||||
gtp_h->length = htobe16(sendbuf->len - OGS_GTPV1U_HEADER_LEN);
|
||||
gtp_h->teid = htobe32(far->outer_header_creation.teid);
|
||||
|
||||
/* Send to gNB */
|
||||
ogs_debug("[UPF] SEND GPU-U to gNB[%s] : TEID[0x%x]",
|
||||
OGS_ADDR(&gnode->addr, buf), far->outer_header_creation.teid);
|
||||
rv = ogs_gtp_sendto(gnode, sendbuf);
|
||||
if (rv != OGS_OK)
|
||||
ogs_error("ogs_gtp_sendto() failed");
|
||||
|
||||
ogs_pkbuf_free(sendbuf);
|
||||
}
|
||||
|
||||
static int upf_gtp_handle_multicast(ogs_pkbuf_t *recvbuf)
|
||||
{
|
||||
struct ip *ip_h = NULL;
|
||||
|
@ -279,7 +320,7 @@ static int upf_gtp_handle_multicast(ogs_pkbuf_t *recvbuf)
|
|||
|
||||
pdr = ogs_pfcp_sess_default_pdr(&sess->pfcp);
|
||||
ogs_assert(pdr);
|
||||
upf_gtp_send_to_pdr(pdr, recvbuf);
|
||||
upf_gtp_handle_pdr(pdr, recvbuf);
|
||||
|
||||
return UPF_GTP_HANDLED;
|
||||
}
|
||||
|
@ -319,67 +360,36 @@ static int upf_gtp_handle_slaac(upf_sess_t *sess, ogs_pkbuf_t *recvbuf)
|
|||
return OGS_OK;
|
||||
}
|
||||
|
||||
static void upf_gtp_send_to_far(ogs_pfcp_far_t *far, ogs_pkbuf_t *sendbuf)
|
||||
{
|
||||
char buf[OGS_ADDRSTRLEN];
|
||||
int rv;
|
||||
ogs_gtp_header_t *gtp_h = NULL;
|
||||
ogs_gtp_node_t *gnode = NULL;
|
||||
|
||||
ogs_assert(far);
|
||||
|
||||
if (far->dst_if != OGS_PFCP_INTERFACE_ACCESS) {
|
||||
ogs_error("FAR is NOT Downlink");
|
||||
return;
|
||||
}
|
||||
|
||||
gnode = far->gnode;
|
||||
ogs_assert(gnode);
|
||||
ogs_assert(gnode->sock);
|
||||
ogs_assert(sendbuf);
|
||||
|
||||
/* Add GTP-U header */
|
||||
ogs_assert(ogs_pkbuf_push(sendbuf, OGS_GTPV1U_HEADER_LEN));
|
||||
gtp_h = (ogs_gtp_header_t *)sendbuf->data;
|
||||
/* Bits 8 7 6 5 4 3 2 1
|
||||
* +--+--+--+--+--+--+--+--+
|
||||
* |version |PT| 1| E| S|PN|
|
||||
* +--+--+--+--+--+--+--+--+
|
||||
* 0 0 1 1 0 0 0 0
|
||||
*/
|
||||
gtp_h->flags = 0x30;
|
||||
gtp_h->type = OGS_GTPU_MSGTYPE_GPDU;
|
||||
gtp_h->length = htobe16(sendbuf->len - OGS_GTPV1U_HEADER_LEN);
|
||||
gtp_h->teid = htobe32(far->outer_header_creation.teid);
|
||||
|
||||
/* Send to SGW */
|
||||
ogs_debug("[UPF] SEND GPU-U to gNB[%s] : TEID[0x%x]",
|
||||
OGS_ADDR(&gnode->addr, buf), far->outer_header_creation.teid);
|
||||
rv = ogs_gtp_sendto(gnode, sendbuf);
|
||||
if (rv != OGS_OK)
|
||||
ogs_error("ogs_gtp_sendto() failed");
|
||||
}
|
||||
|
||||
static void upf_gtp_send_to_pdr(ogs_pfcp_pdr_t *pdr, ogs_pkbuf_t *sendbuf)
|
||||
static int upf_gtp_handle_pdr(ogs_pfcp_pdr_t *pdr, ogs_pkbuf_t *recvbuf)
|
||||
{
|
||||
ogs_pfcp_far_t *far = NULL;
|
||||
ogs_pkbuf_t *sendbuf = NULL;
|
||||
|
||||
ogs_assert(sendbuf);
|
||||
ogs_assert(recvbuf);
|
||||
ogs_assert(pdr);
|
||||
|
||||
if (pdr->src_if != OGS_PFCP_INTERFACE_CORE) {
|
||||
ogs_error("PDR is NOT Downlink");
|
||||
return;
|
||||
return OGS_ERROR;
|
||||
}
|
||||
|
||||
far = pdr->far;
|
||||
ogs_assert(far);
|
||||
|
||||
if (far->gnode) {
|
||||
upf_gtp_send_to_far(far, sendbuf);
|
||||
sendbuf = ogs_pkbuf_copy(recvbuf);
|
||||
ogs_assert(sendbuf);
|
||||
if (!far->gnode) {
|
||||
if (far->num_of_buffered_packet < MAX_NUM_OF_PACKET_BUFFER) {
|
||||
far->buffered_packet[far->num_of_buffered_packet++] = sendbuf;
|
||||
return UPF_GTP_HANDLED;
|
||||
}
|
||||
} else {
|
||||
ogs_fatal("TODO Buffering");
|
||||
upf_gtp_send_to_gnb(far, sendbuf);
|
||||
return UPF_GTP_HANDLED;
|
||||
}
|
||||
|
||||
ogs_pkbuf_free(sendbuf);
|
||||
return OGS_OK;
|
||||
}
|
||||
|
||||
static int upf_gtp_send_router_advertisement(
|
||||
|
@ -460,7 +470,7 @@ static int upf_gtp_send_router_advertisement(
|
|||
p += OGS_IPV6_LEN;
|
||||
p += 2; memcpy(p, &plen, 2); p += 2;
|
||||
p += 3; *p = nxt; p += 1;
|
||||
advert_h->nd_ra_cksum = in_cksum((uint16_t *)pkbuf->data, pkbuf->len);
|
||||
advert_h->nd_ra_cksum = ogs_in_cksum((uint16_t *)pkbuf->data, pkbuf->len);
|
||||
|
||||
ip6_h->ip6_flow = htobe32(0x60000001);
|
||||
ip6_h->ip6_plen = plen;
|
||||
|
@ -469,37 +479,10 @@ static int upf_gtp_send_router_advertisement(
|
|||
memcpy(ip6_h->ip6_src.s6_addr, src_ipsub.sub, sizeof src_ipsub.sub);
|
||||
memcpy(ip6_h->ip6_dst.s6_addr, ip6_dst, OGS_IPV6_LEN);
|
||||
|
||||
upf_gtp_send_to_pdr(pdr, pkbuf);
|
||||
upf_gtp_handle_pdr(pdr, pkbuf);
|
||||
|
||||
ogs_debug("[UPF] Router Advertisement");
|
||||
|
||||
ogs_pkbuf_free(pkbuf);
|
||||
return rv;
|
||||
}
|
||||
|
||||
uint16_t in_cksum(uint16_t *addr, int len)
|
||||
{
|
||||
int nleft = len;
|
||||
uint32_t sum = 0;
|
||||
uint16_t *w = addr;
|
||||
uint16_t answer = 0;
|
||||
|
||||
// Adding 16 bits sequentially in sum
|
||||
while (nleft > 1) {
|
||||
sum += *w;
|
||||
nleft -= 2;
|
||||
w++;
|
||||
}
|
||||
|
||||
// If an odd byte is left
|
||||
if (nleft == 1) {
|
||||
*(uint8_t *) (&answer) = *(uint8_t *) w;
|
||||
sum += answer;
|
||||
}
|
||||
|
||||
sum = (sum >> 16) + (sum & 0xffff);
|
||||
sum += (sum >> 16);
|
||||
answer = ~sum;
|
||||
|
||||
return answer;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,8 @@ extern "C" {
|
|||
int upf_gtp_open(void);
|
||||
void upf_gtp_close(void);
|
||||
|
||||
void upf_gtp_send_to_gnb(ogs_pfcp_far_t *far, ogs_pkbuf_t *sendbuf);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
*/
|
||||
|
||||
#include "context.h"
|
||||
#include "timer.h"
|
||||
#include "pfcp-path.h"
|
||||
#include "gtp-path.h"
|
||||
#include "n4-handler.h"
|
||||
|
||||
void upf_n4_handle_association_setup_request(
|
||||
|
@ -264,7 +264,7 @@ static ogs_pfcp_far_t *handle_create_far(ogs_pfcp_sess_t *sess,
|
|||
far->dst_if = message->forwarding_parameters.destination_interface.u8;
|
||||
|
||||
if (far->dst_if == OGS_PFCP_INTERFACE_ACCESS) { /* Downlink */
|
||||
int rv;
|
||||
int rv, i;
|
||||
ogs_ip_t ip;
|
||||
ogs_gtp_node_t *gnode = NULL;
|
||||
|
||||
|
@ -294,6 +294,10 @@ static ogs_pfcp_far_t *handle_create_far(ogs_pfcp_sess_t *sess,
|
|||
ogs_assert(rv == OGS_OK);
|
||||
}
|
||||
OGS_SETUP_GTP_NODE(far, gnode);
|
||||
|
||||
for (i = 0; i < far->num_of_buffered_packet; i++)
|
||||
upf_gtp_send_to_gnb(far, far->buffered_packet[i]);
|
||||
far->num_of_buffered_packet = 0;
|
||||
}
|
||||
} else if (far->dst_if == OGS_PFCP_INTERFACE_CORE) { /* Uplink */
|
||||
|
||||
|
@ -345,7 +349,7 @@ static ogs_pfcp_far_t *handle_update_far(ogs_pfcp_sess_t *sess,
|
|||
destination_interface.u8;
|
||||
|
||||
if (far->dst_if == OGS_PFCP_INTERFACE_ACCESS) { /* Downlink */
|
||||
int rv;
|
||||
int rv, i;
|
||||
ogs_ip_t ip;
|
||||
ogs_gtp_node_t *gnode = NULL;
|
||||
|
||||
|
@ -378,6 +382,10 @@ static ogs_pfcp_far_t *handle_update_far(ogs_pfcp_sess_t *sess,
|
|||
ogs_assert(rv == OGS_OK);
|
||||
}
|
||||
OGS_SETUP_GTP_NODE(far, gnode);
|
||||
|
||||
for (i = 0; i < far->num_of_buffered_packet; i++)
|
||||
upf_gtp_send_to_gnb(far, far->buffered_packet[i]);
|
||||
far->num_of_buffered_packet = 0;
|
||||
}
|
||||
} else if (far->dst_if == OGS_PFCP_INTERFACE_CORE) { /* Uplink */
|
||||
|
||||
|
|
|
@ -76,12 +76,8 @@ int testenb_gtpu_send(ogs_socknode_t *node, ogs_pkbuf_t *sendbuf)
|
|||
|
||||
if (bearer->sgw_s1u_ip.ipv6) {
|
||||
sgw.ogs_sa_family = AF_INET6;
|
||||
if (bearer->sgw_s1u_ip.ipv4)
|
||||
memcpy(sgw.sin6.sin6_addr.s6_addr,
|
||||
bearer->sgw_s1u_ip.both.addr6, OGS_IPV6_LEN);
|
||||
else
|
||||
memcpy(sgw.sin6.sin6_addr.s6_addr,
|
||||
bearer->sgw_s1u_ip.addr6, OGS_IPV6_LEN);
|
||||
memcpy(sgw.sin6.sin6_addr.s6_addr,
|
||||
bearer->sgw_s1u_ip.addr6, OGS_IPV6_LEN);
|
||||
rv = ogs_socknode_fill_scope_id_in_local(&sgw);
|
||||
ogs_assert(rv == OGS_OK);
|
||||
} else {
|
||||
|
@ -3394,8 +3390,6 @@ int tests1ap_build_uplink_nas_transport(ogs_pkbuf_t **pkbuf, int i)
|
|||
return OGS_OK;
|
||||
}
|
||||
|
||||
uint16_t in_cksum(uint16_t *addr, int len); /* from pgw_gtp_path.c */
|
||||
|
||||
int testgtpu_build_ping(ogs_pkbuf_t **sendbuf,
|
||||
const uint32_t teid, const char *src_ip, const char *dst_ip)
|
||||
{
|
||||
|
@ -3440,12 +3434,12 @@ int testgtpu_build_ping(ogs_pkbuf_t **sendbuf,
|
|||
ip_h->ip_len = gtp_h->length;
|
||||
ip_h->ip_src.s_addr = src_ipsub.sub[0];
|
||||
ip_h->ip_dst.s_addr = dst_ipsub.sub[0];
|
||||
ip_h->ip_sum = in_cksum((uint16_t *)ip_h, sizeof *ip_h);
|
||||
ip_h->ip_sum = ogs_in_cksum((uint16_t *)ip_h, sizeof *ip_h);
|
||||
|
||||
icmp_h->icmp_type = 8;
|
||||
icmp_h->icmp_seq = rand();
|
||||
icmp_h->icmp_id = rand();
|
||||
icmp_h->icmp_cksum = in_cksum((uint16_t *)icmp_h, ICMP_MINLEN);
|
||||
icmp_h->icmp_cksum = ogs_in_cksum((uint16_t *)icmp_h, ICMP_MINLEN);
|
||||
} else if (dst_ipsub.family == AF_INET6) {
|
||||
struct ip6_hdr *ip6_h = NULL;
|
||||
struct icmp6_hdr *icmp6_h = NULL;
|
||||
|
@ -3472,7 +3466,7 @@ int testgtpu_build_ping(ogs_pkbuf_t **sendbuf,
|
|||
icmp6_h->icmp6_seq = rand();
|
||||
icmp6_h->icmp6_id = rand();
|
||||
|
||||
icmp6_h->icmp6_cksum = in_cksum(
|
||||
icmp6_h->icmp6_cksum = ogs_in_cksum(
|
||||
(uint16_t *)ip6_h, sizeof *ip6_h + sizeof *icmp6_h);
|
||||
|
||||
ip6_h->ip6_flow = htonl(0x60000001);
|
||||
|
|
|
@ -41,7 +41,7 @@ void testgsm_handle_pdu_session_establishment_accept(test_sess_t *sess,
|
|||
break;
|
||||
case OGS_PDU_SESSION_TYPE_IPV4V6:
|
||||
sess->ue_ip.ipv4 = 1;
|
||||
sess->ue_ip.both.addr = pdu_address->both.addr;
|
||||
sess->ue_ip.addr = pdu_address->both.addr;
|
||||
break;
|
||||
default:
|
||||
ogs_fatal("Invalid PDU Address Type [%d]", pdu_address->pdn_type);
|
||||
|
|
|
@ -109,33 +109,6 @@ void test_gtpu_close(ogs_socknode_t *node)
|
|||
#include <netinet/icmp6.h>
|
||||
#endif
|
||||
|
||||
static uint16_t in_cksum(uint16_t *addr, int len)
|
||||
{
|
||||
int nleft = len;
|
||||
uint32_t sum = 0;
|
||||
uint16_t *w = addr;
|
||||
uint16_t answer = 0;
|
||||
|
||||
// Adding 16 bits sequentially in sum
|
||||
while (nleft > 1) {
|
||||
sum += *w;
|
||||
nleft -= 2;
|
||||
w++;
|
||||
}
|
||||
|
||||
// If an odd byte is left
|
||||
if (nleft == 1) {
|
||||
*(uint8_t *) (&answer) = *(uint8_t *) w;
|
||||
sum += answer;
|
||||
}
|
||||
|
||||
sum = (sum >> 16) + (sum & 0xffff);
|
||||
sum += (sum >> 16);
|
||||
answer = ~sum;
|
||||
|
||||
return answer;
|
||||
}
|
||||
|
||||
int test_gtpu_build_ping(ogs_pkbuf_t **sendbuf,
|
||||
test_sess_t *sess, const char *dst_ip)
|
||||
{
|
||||
|
@ -176,17 +149,14 @@ int test_gtpu_build_ping(ogs_pkbuf_t **sendbuf,
|
|||
ip_h->ip_ttl = 255;
|
||||
ip_h->ip_p = IPPROTO_ICMP;
|
||||
ip_h->ip_len = gtp_h->length;
|
||||
if (sess->ue_ip.ipv4 && sess->ue_ip.ipv6)
|
||||
ip_h->ip_src.s_addr = sess->ue_ip.both.addr;
|
||||
else
|
||||
ip_h->ip_src.s_addr = sess->ue_ip.addr;
|
||||
ip_h->ip_src.s_addr = sess->ue_ip.addr;
|
||||
ip_h->ip_dst.s_addr = dst_ipsub.sub[0];
|
||||
ip_h->ip_sum = in_cksum((uint16_t *)ip_h, sizeof *ip_h);
|
||||
ip_h->ip_sum = ogs_in_cksum((uint16_t *)ip_h, sizeof *ip_h);
|
||||
|
||||
icmp_h->icmp_type = 8;
|
||||
icmp_h->icmp_seq = rand();
|
||||
icmp_h->icmp_id = rand();
|
||||
icmp_h->icmp_cksum = in_cksum((uint16_t *)icmp_h, ICMP_MINLEN);
|
||||
icmp_h->icmp_cksum = ogs_in_cksum((uint16_t *)icmp_h, ICMP_MINLEN);
|
||||
} else if (dst_ipsub.family == AF_INET6) {
|
||||
#if 0
|
||||
struct ip6_hdr *ip6_h = NULL;
|
||||
|
@ -214,7 +184,7 @@ int test_gtpu_build_ping(ogs_pkbuf_t **sendbuf,
|
|||
icmp6_h->icmp6_seq = rand();
|
||||
icmp6_h->icmp6_id = rand();
|
||||
|
||||
icmp6_h->icmp6_cksum = in_cksum(
|
||||
icmp6_h->icmp6_cksum = ogs_in_cksum(
|
||||
(uint16_t *)ip6_h, sizeof *ip6_h + sizeof *icmp6_h);
|
||||
|
||||
ip6_h->ip6_flow = htonl(0x60000001);
|
||||
|
|
|
@ -259,13 +259,24 @@ static void test1_func(abts_case *tc, void *data)
|
|||
ABTS_PTR_NOTNULL(tc, recvbuf);
|
||||
testngap_recv(&test_ue, recvbuf);
|
||||
|
||||
/* Send GTP-U ICMP Packet */
|
||||
rv = test_gtpu_build_ping(&sendbuf, &test_sess, "10.45.0.1");
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
rv = testgnb_gtpu_send(gtpu, sendbuf);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
|
||||
ogs_msleep(50);
|
||||
|
||||
/* Send PDU session resource setup response */
|
||||
sendbuf = testngap_build_pdu_session_resource_setup_response(&test_sess);
|
||||
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||
rv = testgnb_ngap_send(ngap, sendbuf);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
|
||||
ogs_msleep(50);
|
||||
/* Receive GTP-U ICMP Packet */
|
||||
recvbuf = testgnb_gtpu_read(gtpu);
|
||||
ABTS_PTR_NOTNULL(tc, recvbuf);
|
||||
ogs_pkbuf_free(recvbuf);
|
||||
|
||||
/* Send GTP-U ICMP Packet */
|
||||
rv = test_gtpu_build_ping(&sendbuf, &test_sess, "10.45.0.1");
|
||||
|
|
|
@ -73,6 +73,9 @@ static void test1_func(abts_case *tc, void *data)
|
|||
"\"uplink\" : { \"$numberLong\" : \"1000000\" }, "
|
||||
"\"downlink\" : { \"$numberLong\" : \"1000000\" } "
|
||||
"},"
|
||||
#if 0
|
||||
"\"ue\" : { \"addr\" : \"10.45.0.2\", \"addr6\" : \"cafe::2\" },"
|
||||
#endif
|
||||
"\"qos\" : { "
|
||||
"\"qci\" : 9, "
|
||||
"\"arp\" : { "
|
||||
|
|
|
@ -140,11 +140,13 @@ const schema = {
|
|||
"properties": {
|
||||
"downlink": {
|
||||
"type": "number",
|
||||
"title": "APN-AMBR Downlink (Kbps)",
|
||||
"title": "APN-AMBR Downlink (Kbps)*",
|
||||
"required": true
|
||||
},
|
||||
"uplink": {
|
||||
"type": "number",
|
||||
"title": "APN-AMBR Uplink (Kbps)",
|
||||
"title": "APN-AMBR Uplink (Kbps)*",
|
||||
"required": true
|
||||
},
|
||||
}
|
||||
},
|
||||
|
|
|
@ -216,12 +216,6 @@ const View = ({ visible, disableOnClickOutside, profile, onEdit, onDelete, onHid
|
|||
{security.amf}
|
||||
<span style={{color:oc.gray[5]}}><KeyboardControlIcon/>AMF</span>
|
||||
</div>
|
||||
{security.rand &&
|
||||
<div className="data">
|
||||
{security.rand}
|
||||
<span style={{color:oc.gray[5]}}><KeyboardControlIcon/>RAND</span>
|
||||
</div>
|
||||
}
|
||||
{security.sqn &&
|
||||
<div className="data">
|
||||
{security.sqn}
|
||||
|
|
|
@ -146,11 +146,13 @@ const schema = {
|
|||
"properties": {
|
||||
"downlink": {
|
||||
"type": "number",
|
||||
"title": "APN-AMBR Downlink (Kbps)",
|
||||
"title": "APN-AMBR Downlink (Kbps)*",
|
||||
"required": true
|
||||
},
|
||||
"uplink": {
|
||||
"type": "number",
|
||||
"title": "APN-AMBR Uplink (Kbps)",
|
||||
"title": "APN-AMBR Uplink (Kbps)*",
|
||||
"required": true
|
||||
},
|
||||
}
|
||||
},
|
||||
|
|
|
@ -215,12 +215,6 @@ const View = ({ visible, disableOnClickOutside, subscriber, onEdit, onDelete, on
|
|||
{security.amf}
|
||||
<span style={{color:oc.gray[5]}}><KeyboardControlIcon/>AMF</span>
|
||||
</div>
|
||||
{security.rand &&
|
||||
<div className="data">
|
||||
{security.rand}
|
||||
<span style={{color:oc.gray[5]}}><KeyboardControlIcon/>RAND</span>
|
||||
</div>
|
||||
}
|
||||
{security.sqn &&
|
||||
<div className="data">
|
||||
{security.sqn}
|
||||
|
|
|
@ -27,6 +27,10 @@ const formData = {
|
|||
{
|
||||
"apn": "internet",
|
||||
"type": 2,
|
||||
"ambr": {
|
||||
"downlink": 1024000,
|
||||
"uplink": 1024000
|
||||
},
|
||||
"qos": {
|
||||
"qci": 9,
|
||||
// Ch 7.3.40 Allocation-Retenion-Proirty in TS 29.272 V15.9.0
|
||||
|
|
|
@ -28,6 +28,10 @@ const formData = {
|
|||
{
|
||||
"apn": "internet",
|
||||
"type": 2,
|
||||
"ambr": {
|
||||
"downlink": 1024000,
|
||||
"uplink": 1024000
|
||||
},
|
||||
"qos": {
|
||||
"qci": 9,
|
||||
// Ch 7.3.40 Allocation-Retenion-Proirty in TS 29.272 V15.9.0
|
||||
|
|
Loading…
Reference in New Issue