Session-AMBR changes required field in WebUI

This commit is contained in:
Sukchan Lee 2020-06-17 21:43:16 -04:00
parent dbee687a75
commit c54e85c5c0
55 changed files with 703 additions and 1011 deletions

View File

@ -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));

View File

@ -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;

View File

@ -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

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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
}

View File

@ -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 {

View File

@ -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;

View File

@ -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('.')

View File

@ -34,6 +34,7 @@
#include "gtp/build.h"
#include "gtp/path.h"
#include "gtp/xact.h"
#include "gtp/util.h"
#ifdef __cplusplus
extern "C" {

47
lib/gtp/util.c Normal file
View File

@ -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;
}

37
lib/gtp/util.h Normal file
View File

@ -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 */

View File

@ -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);
}

View File

@ -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;

View File

@ -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) {

View File

@ -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);

View File

@ -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;

View File

@ -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
}

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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));
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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];

View File

@ -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);
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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 */

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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");

View File

@ -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\" : { "

View File

@ -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
},
}
},

View File

@ -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}

View File

@ -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
},
}
},

View File

@ -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}

View File

@ -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

View File

@ -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