update it

This commit is contained in:
Sukchan Lee 2017-04-12 10:05:23 +09:00
parent 17d5856805
commit 258cc29454
14 changed files with 209 additions and 60 deletions

View File

@ -67,6 +67,29 @@ typedef struct _e_cgi_t {
c_uint32_t cell_id; /* 28 bit */
} __attribute__ ((packed)) e_cgi_t;
/**************************************************
* 8.14 PDN Address Allocation (PAA) */
#define PAA_IPV4_LEN 5
#define PAA_IPV6_LEN 18
#define PAA_IPV4V6_LEN 22
typedef struct _paa_t {
/* 8.34 PDN Type */
#define GTP_PDN_TYPE_IPV4 1
#define GTP_PDN_TYPE_IPV6 2
#define GTP_PDN_TYPE_BOTH 3
#define GTP_PDN_TYPE_NON_IP 4
ED2(c_uint8_t spare:6;,
c_uint8_t gtp_type:2;)
union {
c_uint32_t ipv4_addr;;
struct {
c_uint8_t ipv6_len;
c_uint8_t ipv6_addr[IPV6_LEN];
};
};
c_uint32_t ipv4v6_addr;
} __attribute__ ((packed)) paa_t;
/**********************************
* PDN Structure */
typedef c_uint32_t pdn_id_t;
@ -75,11 +98,12 @@ typedef struct _pdn_t {
pdn_id_t id;
c_int8_t apn[MAX_APN_LEN];
#define PDN_TYPE_IPV4 0
#define PDN_TYPE_IPV6 1
#define PDN_TYPE_IPV4_AND_IPV6 2
#define PDN_TYPE_IPV4_OR_IPV6 3
c_int8_t type;
#define S6A_PDN_TYPE_IPV4 0
#define S6A_PDN_TYPE_IPV6 1
#define S6A_PDN_TYPE_IPV4_AND_IPV6 2
#define S6A_PDN_TYPE_IPV4_OR_IPV6 3
c_int8_t s6a_type;
paa_t paa;
c_uint32_t max_bandwidth_ul; /* Kbps */
c_uint32_t max_bandwidth_dl; /* Kbps */

View File

@ -193,21 +193,6 @@ CORE_DECLARE(c_int16_t) gtp_parse_uli(gtp_uli_t *uli, tlv_octet_t *octet);
CORE_DECLARE(c_int16_t) gtp_build_uli(
tlv_octet_t *octet, gtp_uli_t *uli, void *data, int data_len);
/* 8.14 PDN Address Allocation (PAA) */
#define GTP_PAA_IPV4_LEN 5
#define GTP_PAA_IPV6_LEN 18
typedef struct _gtp_paa_t {
ED2(c_uint8_t spare:6;,
c_uint8_t pdn_type:2;)
union {
c_uint32_t ipv4_prefix;;
struct {
c_uint8_t ipv6_prefix_lengh;
c_uint8_t ipv6_prefix[16];
};
};
} gtp_paa_t;
/* 8.22 Fully Qualified TEID (F-TEID) */
#define GTP_F_TEID_S1_U_ENODEB_GTP_U 0
#define GTP_F_TEID_S1_U_SGW_GTP_U 1
@ -263,12 +248,6 @@ ED3(c_uint8_t ipv4:1;,
};
} __attribute__ ((packed)) gtp_f_teid_t;
/* 8.34 PDN Type */
#define GTP_PDN_TYPE_IPV4 1
#define GTP_PDN_TYPE_IPV6 2
#define GTP_PDN_TYPE_BOTH 3
#define GTP_PDN_TYPE_NON_IP 4
/* 8.44 UE Time Zone */
#define GTP_UE_TIME_ZONE_NO_ADJUSTMENT_FOR_DAYLIGHT_SAVING_TIME 0
#define GTP_UE_TIME_ZONE_1_HOUR_FOR_DAYLIGHT_SAVING_TIME 1

View File

@ -68,7 +68,7 @@ status_t hss_context_init(void)
pdn->apn[0] = 0x08;
strcpy(pdn->apn+1, "internet");
pdn->type = PDN_TYPE_IPV4;
pdn->s6a_type = S6A_PDN_TYPE_IPV4;
pdn->qci = PDN_QCI_9;
pdn->priority_level = 8;

View File

@ -327,7 +327,7 @@ static int hss_ulr_cb( struct msg **msg, struct avp *avp,
d_assert(fd_msg_avp_new(s6a_pdn_type, 0,
&pdn_type) == 0, goto out,);
val.i32 = pdn->type;
val.i32 = pdn->s6a_type;
d_assert(fd_msg_avp_setvalue(pdn_type, &val) == 0,
goto out,);
d_assert(fd_msg_avp_add(apn_configuration,

View File

@ -42,13 +42,14 @@ void esm_handle_information_response(mme_esm_t *esm,
{
nas_protocol_configuration_options_t *protocol_configuration_options =
&esm_information_response->protocol_configuration_options;
esm->pco_len = protocol_configuration_options->length;
d_assert(esm->pco_len <= MAX_PCO_LEN, return,
"length(%d) exceeds MAX:%d", esm->pco_len, MAX_PCO_LEN);
memcpy(esm->pco, protocol_configuration_options->buffer, esm->pco_len);
esm->ue_pco_len = protocol_configuration_options->length;
d_assert(esm->ue_pco_len <= MAX_PCO_LEN, return,
"length(%d) exceeds MAX:%d", esm->ue_pco_len, MAX_PCO_LEN);
memcpy(esm->ue_pco, protocol_configuration_options->buffer,
esm->ue_pco_len);
}
rv = mme_s11_build_create_session_req(&pkbuf, esm);
rv = mme_s11_build_create_session_request(&pkbuf, esm);
d_assert(rv == CORE_OK, return, "S11 build error");
rv = mme_s11_send_to_sgw(esm->sgw,

View File

@ -39,16 +39,17 @@ status_t mme_context_init()
memset(&self, 0, sizeof(mme_context_t));
pool_init(&mme_sgw_pool, MAX_NUM_OF_SGW);
list_init(&self.sgw_list);
pool_init(&mme_pdn_pool, MAX_NUM_OF_PDN);
list_init(&self.pdn_list);
index_init(&mme_enb_pool, MAX_NUM_OF_ENB);
list_init(&self.enb_list);
index_init(&mme_ue_pool, MAX_NUM_OF_UE);
index_init(&mme_esm_pool, MAX_NUM_OF_ESM);
list_init(&self.sgw_list);
list_init(&self.enb_list);
list_init(&self.pdn_list);
self.mme_ue_s1ap_id_hash = hash_make();
self.s1ap_addr = inet_addr("127.0.0.1");

View File

@ -71,7 +71,7 @@ typedef struct _mme_context_t {
list_t sgw_list;
list_t enb_list;
list_t pdn_list;;
list_t pdn_list;
hash_t *mme_ue_s1ap_id_hash; /* hash table for MME-UE-S1AP-ID */
} mme_context_t;
@ -168,8 +168,11 @@ typedef struct _mme_esm_t {
c_uint32_t sgw_addr; /* SGW-S11-F-TEID IPv4 Address */
c_uint32_t sgw_teid; /* SGW-S11-F-TEID */
c_uint8_t pco[MAX_PCO_LEN];
int pco_len;
/* Protocol Configuration Options */
c_uint8_t ue_pco[MAX_PCO_LEN];
int ue_pco_len;
c_uint8_t pgw_pco[MAX_PCO_LEN];
int pgw_pco_len;
mme_sgw_t *sgw;
pdn_t *pdn;

View File

@ -8,7 +8,7 @@
#include "3gpp_common.h"
#include "mme_context.h"
status_t mme_s11_build_create_session_req(pkbuf_t **pkbuf, mme_esm_t *esm)
status_t mme_s11_build_create_session_request(pkbuf_t **pkbuf, mme_esm_t *esm)
{
status_t rv;
pdn_t *pdn = NULL;
@ -20,7 +20,6 @@ status_t mme_s11_build_create_session_req(pkbuf_t **pkbuf, mme_esm_t *esm)
gtp_uli_t uli;
char uli_buf[GTP_MAX_ULI_LEN];
gtp_f_teid_t s11, s5;
gtp_paa_t paa;
gtp_ambr_t ambr;
gtp_bearer_qos_t bearer_qos;
char bearer_qos_buf[GTP_BEARER_QOS_LEN];
@ -34,7 +33,7 @@ status_t mme_s11_build_create_session_req(pkbuf_t **pkbuf, mme_esm_t *esm)
ue = esm->ue;
d_assert(ue, return CORE_ERROR, "Null param");
d_assert(esm->pco_len, return CORE_ERROR, "Null param");
d_assert(esm->ue_pco_len, return CORE_ERROR, "Null param");
memset(&gtp_message, 0, sizeof(gtp_message_t));
@ -98,11 +97,11 @@ status_t mme_s11_build_create_session_req(pkbuf_t **pkbuf, mme_esm_t *esm)
req->pdn_type.presence = 1;
req->pdn_type.u8 = GTP_PDN_TYPE_IPV4;
memset(&paa, 0, sizeof(gtp_paa_t));
paa.pdn_type = GTP_PDN_TYPE_IPV4;
memset(&pdn->paa, 0, sizeof(paa_t));
pdn->paa.gtp_type = GTP_PDN_TYPE_IPV4;
req->pdn_address_allocation.presence = 1;
req->pdn_address_allocation.data = &paa;
req->pdn_address_allocation.len = GTP_PAA_IPV4_LEN;
req->pdn_address_allocation.data = &pdn->paa;
req->pdn_address_allocation.len = PAA_IPV4_LEN;
req->maximum_apn_restriction.presence = 1;
req->maximum_apn_restriction.u8 = GTP_APN_NO_RESTRICTION;
@ -115,8 +114,8 @@ status_t mme_s11_build_create_session_req(pkbuf_t **pkbuf, mme_esm_t *esm)
req->aggregate_maximum_bit_rate.len = sizeof(ambr);
req->protocol_configuration_options.presence = 1;
req->protocol_configuration_options.data = esm->pco;
req->protocol_configuration_options.len = esm->pco_len;
req->protocol_configuration_options.data = esm->ue_pco;
req->protocol_configuration_options.len = esm->ue_pco_len;
req->bearer_contexts_to_be_created.presence = 1;
req->bearer_contexts_to_be_created.eps_bearer_id.presence = 1;

View File

@ -7,7 +7,7 @@
extern "C" {
#endif /* __cplusplus */
CORE_DECLARE(status_t) mme_s11_build_create_session_req(
CORE_DECLARE(status_t) mme_s11_build_create_session_request(
pkbuf_t **pkbuf, mme_esm_t *esm);
#ifdef __cplusplus

View File

@ -342,7 +342,7 @@ static void mme_s6a_ula_cb(void *data, struct msg **msg)
&avpch3) == 0 && avpch3, error++; goto out,);
d_assert(fd_msg_avp_hdr(avpch3, &hdr) == 0 && hdr,
error++; goto out,);
pdn->type = hdr->avp_value->i32;
pdn->s6a_type = hdr->avp_value->i32;
d_assert(fd_avp_search_avp(avpch2, s6a_service_selection,
&avpch3) == 0 && avpch3, error++; goto out,);
@ -356,11 +356,13 @@ static void mme_s6a_ula_cb(void *data, struct msg **msg)
if (pdn_added)
d_info("PDN(id:%d, type:%s, APN:%s) Added",
pdn->id,
pdn->type == PDN_TYPE_IPV4 ? "IPv4" :
pdn->type == PDN_TYPE_IPV6 ? "IPv6" :
pdn->type == PDN_TYPE_IPV4_AND_IPV6 ? "IPv4_AND_IPv6" :
pdn->type == PDN_TYPE_IPV4_OR_IPV6 ? "IPv4_OR_IPv6" :
"Unknown Type",
pdn->s6a_type == S6A_PDN_TYPE_IPV4 ? "IPv4" :
pdn->s6a_type == S6A_PDN_TYPE_IPV6 ? "IPv6" :
pdn->s6a_type == S6A_PDN_TYPE_IPV4_AND_IPV6 ?
"IPv4_AND_IPv6" :
pdn->s6a_type == S6A_PDN_TYPE_IPV4_OR_IPV6 ?
"IPv4_OR_IPv6" :
"Unknown Type",
pdn->apn);
d_assert(fd_avp_search_avp(avpch2,

View File

@ -10,17 +10,23 @@
static pgw_context_t self;
pool_declare(pgw_pdn_pool, pdn_t, MAX_NUM_OF_PDN);
index_declare(pgw_sess_pool, pgw_sess_t, MAX_NUM_OF_UE);
static int context_initiaized = 0;
status_t pgw_context_init()
{
pdn_t *pdn = NULL;
d_assert(context_initiaized == 0, return CORE_ERROR,
"MME context already has been initialized");
memset(&self, 0, sizeof(pgw_context_t));
pool_init(&pgw_pdn_pool, MAX_NUM_OF_PDN);
list_init(&self.pdn_list);
index_init(&pgw_sess_pool, MAX_NUM_OF_UE);
list_init(&self.sess_list);
@ -36,6 +42,17 @@ status_t pgw_context_init()
self.s5u_node.addr = inet_addr("127.0.0.1");
self.s5u_node.port = GTPV1_U_UDP_PORT;
/***********************************************
* PDN DB */
pdn = pgw_pdn_add();
d_assert(pdn, return -1, "Profile context add failed");
pdn->apn[0] = 0x08;
strcpy(pdn->apn+1, "internet");
pdn->paa.gtp_type = GTP_PDN_TYPE_IPV4;
pdn->paa.ipv4_addr = inet_addr("45.45.45.113"); /* FIXME */
context_initiaized = 1;
return CORE_OK;
@ -48,11 +65,14 @@ status_t pgw_context_final()
gtp_xact_delete_all(&self.s5c_node);
pgw_sess_remove_all();
pgw_pdn_remove_all();
d_print("%d not freed in pgw_sess_pool[%d] in PGW-Context\n",
index_size(&pgw_sess_pool) - pool_avail(&pgw_sess_pool),
index_size(&pgw_sess_pool));
index_final(&pgw_sess_pool);
pool_final(&pgw_pdn_pool);
context_initiaized = 0;
@ -64,6 +84,91 @@ pgw_context_t* pgw_self()
return &self;
}
pdn_t* pgw_pdn_add()
{
pdn_t *pdn = NULL;
pool_alloc_node(&pgw_pdn_pool, &pdn);
d_assert(pdn, return NULL, "HSS-UE context allocation failed");
memset(pdn, 0, sizeof(pdn_t));
pdn->id = NEXT_ID(self.pdn_id, 1, 0xffffffff);
list_append(&self.pdn_list, pdn);
return pdn;
}
status_t pgw_pdn_remove(pdn_t *pdn)
{
d_assert(pdn, return CORE_ERROR, "Null param");
list_remove(&self.pdn_list, pdn);
pool_free_node(&pgw_pdn_pool, pdn);
return CORE_OK;
}
status_t pgw_pdn_remove_all()
{
pdn_t *pdn = NULL, *next_pdn = NULL;
pdn = list_first(&self.pdn_list);
while (pdn)
{
next_pdn = list_next(pdn);
pgw_pdn_remove(pdn);
pdn = next_pdn;
}
return CORE_OK;
}
pdn_t* pgw_pdn_find_by_id(pdn_id_t id)
{
pdn_t *pdn = NULL;
pdn = list_first(&self.pdn_list);
while (pdn)
{
if (pdn->id == id)
break;
pdn = list_next(pdn);
}
return pdn;
}
pdn_t* pgw_pdn_find_by_apn(c_int8_t *apn)
{
pdn_t *pdn = NULL;
pdn = list_first(&self.pdn_list);
while (pdn)
{
if (strcmp(pdn->apn, apn) == 0)
break;
pdn = list_next(pdn);
}
return pdn;
}
pdn_t* pgw_pdn_first()
{
return list_first(&self.pdn_list);
}
pdn_t* pgw_pdn_next(pdn_t *pdn)
{
return list_next(pdn);
}
pgw_sess_t *pgw_sess_add()
{
pgw_sess_t *sess = NULL;

View File

@ -30,6 +30,9 @@ typedef struct _pgw_context_t {
tm_service_t tm_service; /* Timer Service */
gtp_xact_ctx_t gtp_xact_ctx; /* GTP Transaction Context */
c_uint32_t pdn_id; /* PDN ID Generator */
list_t pdn_list;
list_t sess_list;
} pgw_context_t;
@ -58,6 +61,14 @@ CORE_DECLARE(pgw_sess_t*) pgw_sess_find_by_teid(c_uint32_t teid);
CORE_DECLARE(pgw_sess_t *) pgw_sess_first();
CORE_DECLARE(pgw_sess_t *) pgw_sess_next(pgw_sess_t *sess);
CORE_DECLARE(pdn_t*) pgw_pdn_add();
CORE_DECLARE(status_t) pgw_pdn_remove(pdn_t *pdn);
CORE_DECLARE(status_t) pgw_pdn_remove_all(void);
CORE_DECLARE(pdn_t*) pgw_pdn_find_by_id(pdn_id_t id);
CORE_DECLARE(pdn_t*) pgw_pdn_find_by_apn(c_int8_t *apn);
CORE_DECLARE(pdn_t*) pgw_pdn_first(void);
CORE_DECLARE(pdn_t*) pgw_pdn_next(pdn_t *pdn);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -13,6 +13,8 @@ void pgw_handle_create_session_request(
gtp_xact_t *xact, gtp_create_session_request_t *req)
{
status_t rv;
c_int8_t apn[MAX_APN_LEN];
pdn_t *pdn = NULL;
pkbuf_t *pkbuf;
gtp_message_t gtp_message;
c_uint8_t type = GTP_CREATE_SESSION_RESPONSE_TYPE;
@ -27,12 +29,27 @@ void pgw_handle_create_session_request(
d_assert(xact, return, "Null param");
d_assert(req, return, "Null param");
if (req->access_point_name.presence == 0)
{
d_error("No APN");
return;
}
if (req->sender_f_teid_for_control_plane.presence == 0)
{
d_error("No Sender F-TEID for control plance");
return;
}
memcpy(apn, req->access_point_name.data, req->access_point_name.len);
apn[req->access_point_name.len] = 0;
pdn = pgw_pdn_find_by_apn(apn);
if (!pdn)
{
d_error("No PDN Context-APN[%s]", apn);
return;
}
sgw_f_teid = req->sender_f_teid_for_control_plane.data;
if (!(sgw_f_teid->ipv4 == 1 && sgw_f_teid->ipv6 == 0 &&
sgw_f_teid->interface_type == GTP_F_TEID_S5_S8_SGW_GTP_C))
@ -69,6 +86,13 @@ void pgw_handle_create_session_request(
rsp->pgw_s5_s8__s2a_s2b_f_teid_for_pmip_based_interface_or_for_gtp_based_control_plane_interface.
len = GTP_F_TEID_IPV4_LEN;
rsp->pdn_address_allocation.presence = 1;
rsp->pdn_address_allocation.data = &pdn->paa;
rsp->pdn_address_allocation.len = PAA_IPV4_LEN;
rsp->apn_restriction.presence = 1;
rsp->apn_restriction.u8 = GTP_APN_NO_RESTRICTION;
rv = gtp_build_msg(&pkbuf, type, &gtp_message);
d_assert(rv == CORE_OK, return, "gtp build failed");

View File

@ -31,7 +31,7 @@ static void gtp_message_test1(abts_case *tc, void *data)
plmn_id_t serving_network;
char apnbuf[34];
gtp_f_teid_t s11, s5;
gtp_paa_t paa;
paa_t paa;
gtp_ambr_t ambr;
pco_t pco;
char pcobuf[MAX_PCO_LEN];
@ -103,11 +103,11 @@ static void gtp_message_test1(abts_case *tc, void *data)
req.pdn_type.presence = 1;
req.pdn_type.u8 = GTP_PDN_TYPE_IPV4;
memset(&paa, 0, sizeof(gtp_paa_t));
paa.pdn_type = GTP_PDN_TYPE_IPV4;
memset(&paa, 0, sizeof(paa_t));
paa.gtp_type = GTP_PDN_TYPE_IPV4;
req.pdn_address_allocation.presence = 1;
req.pdn_address_allocation.data = &paa;
req.pdn_address_allocation.len = GTP_PAA_IPV4_LEN;
req.pdn_address_allocation.len = PAA_IPV4_LEN;
req.maximum_apn_restriction.presence = 1;
req.maximum_apn_restriction.u8 = GTP_APN_NO_RESTRICTION;