fix the PGW peer configuration bug

This commit is contained in:
Sukchan Lee 2017-12-03 21:34:39 +09:00
parent a6d23971cd
commit 97c7ad63b6
9 changed files with 158 additions and 103 deletions

View File

@ -2,6 +2,8 @@
#include "core_debug.h"
#include "gtp_message.h"
#include "gtp_types.h"
#include "gtp_conv.h"
void gtp_bearers_in_create_indirect_tunnel_request(

View File

@ -1,7 +1,11 @@
#ifndef __GTP_CONV_H__
#define __GTP_CONV_H__
#include "gtp_message.h"
#include "core_errno.h"
typedef struct _tlv_bearer_context_t tlv_bearer_context_t;
typedef struct _gtp_create_indirect_data_forwarding_tunnel_request_t gtp_create_indirect_data_forwarding_tunnel_request_t;
typedef struct _gtp_create_indirect_data_forwarding_tunnel_response_t gtp_create_indirect_data_forwarding_tunnel_response_t;
#ifdef __cplusplus
extern "C" {

View File

@ -27,6 +27,7 @@
#include "core_debug.h"
#include "core_lib.h"
#include "core_network.h"
#include "gtp_types.h"
#include "gtp_message.h"
@ -381,3 +382,54 @@ c_int16_t gtp_build_uli(
return octet->len;
}
c_int16_t gtp_build_f_teid(
tlv_octet_t *octet, gtp_f_teid_t *f_teid, void *data, int data_len)
{
gtp_f_teid_t target;
c_int16_t size = 0;
d_assert(f_teid, return -1, "Null param");
d_assert(octet, return -1, "Null param");
d_assert(data, return -1, "Null param");
d_assert(data_len, return -1, "Null param");
octet->data = data;
memcpy(&target, f_teid, sizeof(gtp_f_teid_t));
target.interface_type = f_teid->interface_type;
target.teid = htonl(f_teid->teid);
if (f_teid->addr && f_teid->addr6)
{
target.ipv4 = 1;
target.both.ipv4_addr = f_teid->addr->sin.sin_addr.s_addr;
target.ipv6 = 1;
memcpy(target.both.ipv6_addr,
f_teid->addr6->sin6.sin6_addr.s6_addr, IPV6_LEN);
size = GTP_F_TEID_IPV4_AND_IPV6_LEN;
}
else if (f_teid->addr)
{
target.ipv4 = 1;
target.ipv4_addr = f_teid->addr->sin.sin_addr.s_addr;
size = GTP_F_TEID_IPV4_LEN;
}
else if (f_teid->addr6)
{
target.ipv6 = 1;
memcpy(target.ipv6_addr,
f_teid->addr6->sin6.sin6_addr.s6_addr, IPV6_LEN);
size = GTP_F_TEID_IPV6_LEN;
}
else
d_assert(0, return -1,);
d_assert(size <= data_len, return -1, "encode error");
memcpy(octet->data, &target, size);
octet->len = size;
return octet->len;
}

View File

@ -4,6 +4,8 @@
#include "core_tlv_msg.h"
#include "types.h"
typedef struct c_sockaddr_t c_sockaddr_t;
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
@ -343,6 +345,7 @@ CORE_DECLARE(c_int16_t) gtp_build_uli(
#define GTP_F_TEID_IPV4_LEN 9
#define GTP_F_TEID_IPV6_LEN 21
#define GTP_F_TEID_IPV4_AND_IPV6_LEN 25
#define GTP_MAX_F_TEID_LEN 25
typedef struct _gtp_f_teid_t {
ED3(c_uint8_t ipv4:1;,
c_uint8_t ipv6:1;,
@ -356,8 +359,13 @@ ED3(c_uint8_t ipv4:1;,
c_uint8_t ipv6_addr[IPV6_LEN];
} both;
};
c_sockaddr_t *addr;
c_sockaddr_t *addr6;
} __attribute__ ((packed)) gtp_f_teid_t;
CORE_DECLARE(c_int16_t) gtp_build_f_teid(
tlv_octet_t *octet, gtp_f_teid_t *f_teid, void *data, int data_len);
/* 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

@ -47,8 +47,8 @@ status_t mme_context_init()
pool_init(&mme_s1ap_pool, MAX_NUM_OF_S1AP_SERVER);
list_init(&self.s1ap_list);
list_init(&self.gtpc4_list);
list_init(&self.gtpc6_list);
list_init(&self.gtpc_list);
list_init(&self.gtpc_list6);
gtp_node_init();
list_init(&self.sgw_list);
@ -110,8 +110,8 @@ status_t mme_context_final()
gtp_remove_all_nodes(&self.pgw_list);
gtp_node_final();
sock_remove_all_nodes(&self.gtpc4_list);
sock_remove_all_nodes(&self.gtpc6_list);
sock_remove_all_nodes(&self.gtpc_list);
sock_remove_all_nodes(&self.gtpc_list6);
pool_final(&mme_s1ap_pool);
@ -149,8 +149,8 @@ static status_t mme_context_validation()
return CORE_ERROR;
}
if (list_first(&self.gtpc4_list) == NULL &&
list_first(&self.gtpc6_list) == NULL)
if (list_first(&self.gtpc_list) == NULL &&
list_first(&self.gtpc_list6) == NULL)
{
d_error("No mme.gtpc in '%s'",
context_self()->config.path);
@ -163,7 +163,6 @@ static status_t mme_context_validation()
context_self()->config.path);
return CORE_ERROR;
}
self.sgw = list_first(&self.sgw_list);
if (list_first(&self.pgw_list) == NULL)
{
@ -171,7 +170,6 @@ static status_t mme_context_validation()
context_self()->config.path);
return CORE_ERROR;
}
self.pgw = list_first(&self.pgw_list);
if (self.max_num_of_served_gummei == 0)
{
@ -397,44 +395,44 @@ status_t mme_context_parse_config()
if (context_self()->parameter.no_ipv4 == 0)
{
node = sock_add_node(&self.gtpc4_list,
node = sock_add_node(&self.gtpc_list,
family, hostname, port);
d_assert(node, return CORE_ERROR,);
rv = sock_filter_node(
&self.gtpc4_list, AF_INET);
&self.gtpc_list, AF_INET);
d_assert(rv == CORE_OK, return CORE_ERROR,);
}
if (context_self()->parameter.no_ipv6 == 0)
{
node = sock_add_node(&self.gtpc6_list,
node = sock_add_node(&self.gtpc_list6,
family, hostname, port);
d_assert(node, return CORE_ERROR,);
rv = sock_filter_node(
&self.gtpc6_list, AF_INET6);
&self.gtpc_list6, AF_INET6);
d_assert(rv == CORE_OK, return CORE_ERROR,);
}
} while(yaml_iter_type(&gtpc_array) == YAML_SEQUENCE_NODE);
if (list_first(&self.gtpc4_list) == NULL &&
list_first(&self.gtpc6_list) == NULL)
if (list_first(&self.gtpc_list) == NULL &&
list_first(&self.gtpc_list6) == NULL)
{
if (context_self()->parameter.no_ipv4 == 0)
{
rv = sock_get_all_nodes(
&self.gtpc4_list, self.gtpc_port);
&self.gtpc_list, self.gtpc_port);
d_assert(rv == CORE_OK, return CORE_ERROR,);
rv = sock_filter_node(
&self.gtpc4_list, AF_INET);
&self.gtpc_list, AF_INET);
d_assert(rv == CORE_OK, return CORE_ERROR,);
}
if (context_self()->parameter.no_ipv6 == 0)
{
rv = sock_get_all_nodes(
&self.gtpc6_list, self.gtpc_port);
&self.gtpc_list6, self.gtpc_port);
d_assert(rv == CORE_OK, return CORE_ERROR,);
rv = sock_filter_node(&self.gtpc6_list,
rv = sock_filter_node(&self.gtpc_list6,
AF_INET6);
d_assert(rv == CORE_OK, return CORE_ERROR,);
}
@ -1037,16 +1035,6 @@ status_t mme_context_parse_config()
rv = gtp_filter_node(&self.pgw_list, AF_INET);
d_assert(rv == CORE_OK, return CORE_ERROR,);
}
if (context_self()->parameter.prefer_ipv4 == 1)
{
rv = gtp_sort_node(&self.pgw_list, AF_INET);
d_assert(rv == CORE_OK, return CORE_ERROR,);
}
else
{
rv = gtp_sort_node(&self.pgw_list, AF_INET6);
d_assert(rv == CORE_OK, return CORE_ERROR,);
}
}
}
}
@ -1486,8 +1474,8 @@ mme_ue_t* mme_ue_add(enb_ue_t *enb_ue)
list_init(&mme_ue->sess_list);
mme_ue->mme_s11_teid = mme_ue->index;
mme_ue->mme_s11_ipv4 = mme_self()->gtpc4_addr;
mme_ue->mme_s11_ipv6 = mme_self()->gtpc6_addr;
mme_ue->mme_s11_ipv4 = mme_self()->gtpc_addr;
mme_ue->mme_s11_ipv6 = mme_self()->gtpc_addr6;
CONNECT_SGW_GTP_NODE(mme_ue);

View File

@ -58,16 +58,17 @@ typedef struct _mme_context_t {
c_uint16_t gtpc_port; /* Default GTPC Port */
list_t gtpc4_list; /* MME GTPC IPv4 Server List */
c_sockaddr_t *gtpc4_addr; /* MME GTPC IPv4 Address */
list_t gtpc6_list; /* MME GTPC IPv6 Server List */
c_sockaddr_t *gtpc6_addr; /* MME GTPC IPv6 Address */
list_t gtpc_list; /* MME GTPC IPv4 Server List */
c_sockaddr_t *gtpc_addr; /* MME GTPC IPv4 Address */
list_t gtpc_list6; /* MME GTPC IPv6 Server List */
c_sockaddr_t *gtpc_addr6; /* MME GTPC IPv6 Address */
list_t sgw_list; /* SGW GTPC Client List */
gtp_node_t *sgw; /* Iterator for SGW round-robin */
list_t pgw_list; /* PGW GTPC Client List */
gtp_node_t *pgw; /* First Node Selected */
c_sockaddr_t *pgw_addr; /* First IPv4 Address Selected */
c_sockaddr_t *pgw_addr6; /* First IPv6 Address Selected */
msgq_id queue_id; /* Queue for processing MME control plane */
tm_service_t tm_service; /* Timer Service */

View File

@ -47,7 +47,7 @@ static status_t mme_gtp_server()
status_t rv;
sock_node_t *snode;
for (snode = list_first(&mme_self()->gtpc4_list);
for (snode = list_first(&mme_self()->gtpc_list);
snode; snode = list_next(snode))
{
rv = gtp_server(snode, _gtpv2_c_recv_cb);
@ -58,17 +58,17 @@ static status_t mme_gtp_server()
}
}
for (snode = list_first(&mme_self()->gtpc4_list);
for (snode = list_first(&mme_self()->gtpc_list);
snode; snode = list_next(snode))
{
mme_self()->gtpc4_addr = sock_local_addr(snode->sock);
if (mme_self()->gtpc4_addr)
mme_self()->gtpc_addr = sock_local_addr(snode->sock);
if (mme_self()->gtpc_addr)
{
break;
}
}
for (snode = list_first(&mme_self()->gtpc6_list);
for (snode = list_first(&mme_self()->gtpc_list6);
snode; snode = list_next(snode))
{
rv = gtp_server(snode, _gtpv2_c_recv_cb);
@ -79,17 +79,17 @@ static status_t mme_gtp_server()
}
}
for (snode = list_first(&mme_self()->gtpc6_list);
for (snode = list_first(&mme_self()->gtpc_list6);
snode; snode = list_next(snode))
{
mme_self()->gtpc6_addr = sock_local_addr(snode->sock);
if (mme_self()->gtpc6_addr)
mme_self()->gtpc_addr6 = sock_local_addr(snode->sock);
if (mme_self()->gtpc_addr6)
{
break;
}
}
d_assert(mme_self()->gtpc4_addr || mme_self()->gtpc6_addr,
d_assert(mme_self()->gtpc_addr || mme_self()->gtpc_addr6,
return CORE_ERROR, "No GTP Server");
return CORE_OK;
@ -111,6 +111,42 @@ static status_t mme_gtp_client()
}
}
mme_self()->sgw = list_first(&mme_self()->sgw_list);
d_assert(mme_self()->sgw, return CORE_ERROR,);
for (gnode = list_first(&mme_self()->pgw_list);
gnode; gnode = list_next(gnode))
{
c_sockaddr_t *addr = gnode->sa_list;
while(addr)
{
if (addr->c_sa_family == AF_INET)
{
mme_self()->pgw_addr = addr;
break;
}
addr = addr->next;
}
}
for (gnode = list_first(&mme_self()->pgw_list);
gnode; gnode = list_next(gnode))
{
c_sockaddr_t *addr = gnode->sa_list;
while(addr)
{
if (addr->c_sa_family == AF_INET6)
{
mme_self()->pgw_addr6 = addr;
break;
}
addr = addr->next;
}
}
d_assert(mme_self()->pgw_addr || mme_self()->pgw_addr6,
return CORE_ERROR,);
return CORE_OK;
}
@ -132,13 +168,13 @@ status_t mme_gtp_close()
sock_node_t *snode;
gtp_node_t *gnode;
for (snode = list_first(&mme_self()->gtpc4_list);
for (snode = list_first(&mme_self()->gtpc_list);
snode; snode = list_next(snode))
{
sock_delete(snode->sock);
}
for (snode = list_first(&mme_self()->gtpc6_list);
for (snode = list_first(&mme_self()->gtpc_list6);
snode; snode = list_next(snode))
{
sock_delete(snode->sock);

View File

@ -25,6 +25,8 @@ status_t mme_s11_build_create_session_request(
gtp_uli_t uli;
char uli_buf[GTP_MAX_ULI_LEN];
gtp_f_teid_t mme_s11_teid, pgw_s5c_teid;
char mme_s11_teid_buf[GTP_MAX_F_TEID_LEN];
char pgw_s5c_teid_buf[GTP_MAX_F_TEID_LEN];
gtp_ambr_t ambr;
gtp_bearer_qos_t bearer_qos;
char bearer_qos_buf[GTP_BEARER_QOS_LEN];
@ -67,72 +69,34 @@ status_t mme_s11_build_create_session_request(
memset(&mme_s11_teid, 0, sizeof(gtp_f_teid_t));
mme_s11_teid.interface_type = GTP_F_TEID_S11_MME_GTP_C;
mme_s11_teid.teid = htonl(mme_ue->mme_s11_teid);
if (mme_ue->mme_s11_ipv4 && mme_ue->mme_s11_ipv6)
{
mme_s11_teid.ipv4 = 1;
mme_s11_teid.both.ipv4_addr = mme_ue->mme_s11_ipv4->sin.sin_addr.s_addr;
mme_s11_teid.ipv6 = 1;
memcpy(mme_s11_teid.both.ipv6_addr,
mme_ue->mme_s11_ipv6->sin6.sin6_addr.s6_addr,
sizeof(mme_s11_teid.ipv6_addr));
req->sender_f_teid_for_control_plane.len =
GTP_F_TEID_IPV4_AND_IPV6_LEN;
}
else if (mme_ue->mme_s11_ipv4)
{
mme_s11_teid.ipv4 = 1;
mme_s11_teid.ipv4_addr = mme_ue->mme_s11_ipv4->sin.sin_addr.s_addr;
req->sender_f_teid_for_control_plane.len = GTP_F_TEID_IPV4_LEN;
}
else if (mme_ue->mme_s11_ipv6)
{
mme_s11_teid.ipv6 = 1;
memcpy(mme_s11_teid.ipv6_addr,
mme_ue->mme_s11_ipv6->sin6.sin6_addr.s6_addr,
sizeof(mme_s11_teid.ipv6_addr));
req->sender_f_teid_for_control_plane.len = GTP_F_TEID_IPV6_LEN;
}
else
d_assert(0, return CORE_ERROR,);
mme_s11_teid.teid = mme_ue->mme_s11_teid;
mme_s11_teid.addr = mme_ue->mme_s11_ipv4;
mme_s11_teid.addr6 = mme_ue->mme_s11_ipv6;
req->sender_f_teid_for_control_plane.presence = 1;
req->sender_f_teid_for_control_plane.data = &mme_s11_teid;
gtp_build_f_teid(&req->sender_f_teid_for_control_plane,
&mme_s11_teid, mme_s11_teid_buf, GTP_MAX_F_TEID_LEN);
memset(&pgw_s5c_teid, 0, sizeof(gtp_f_teid_t));
pgw_s5c_teid.interface_type = GTP_F_TEID_S5_S8_PGW_GTP_C;
if (pdn->pgw.ipv4_addr)
{
/* FIXME */
pgw_s5c_teid.ipv4 = 1;
pgw_s5c_teid.ipv4_addr = pdn->pgw.ipv4_addr;
req->pgw_s5_s8_address_for_control_plane_or_pmip.presence = 1;
req->pgw_s5_s8_address_for_control_plane_or_pmip.len =
GTP_F_TEID_IPV4_LEN;
req->pgw_s5_s8_address_for_control_plane_or_pmip.data =
&pgw_s5c_teid;
}
else
{
c_sockaddr_t *s5c_addr = NULL;
d_assert(mme_self()->pgw, return CORE_ERROR,);
s5c_addr = mme_self()->pgw->sa_list;
d_assert(s5c_addr, return CORE_ERROR,);
if (s5c_addr->c_sa_family == AF_INET)
{
pgw_s5c_teid.ipv4 = 1;
pgw_s5c_teid.ipv4_addr = s5c_addr->sin.sin_addr.s_addr;
req->pgw_s5_s8_address_for_control_plane_or_pmip.len =
GTP_F_TEID_IPV4_LEN;
}
else if (s5c_addr->c_sa_family == AF_INET6)
{
pgw_s5c_teid.ipv6 = 1;
memcpy(pgw_s5c_teid.ipv6_addr, s5c_addr->sin6.sin6_addr.s6_addr,
sizeof(pgw_s5c_teid.ipv6_addr));
req->pgw_s5_s8_address_for_control_plane_or_pmip.len =
GTP_F_TEID_IPV6_LEN;
}
else
d_assert(0, return CORE_ERROR,);
pgw_s5c_teid.addr = mme_self()->pgw_addr;
pgw_s5c_teid.addr6 = mme_self()->pgw_addr6;
req->pgw_s5_s8_address_for_control_plane_or_pmip.presence = 1;
gtp_build_f_teid(&req->pgw_s5_s8_address_for_control_plane_or_pmip,
&pgw_s5c_teid, pgw_s5c_teid_buf, GTP_MAX_F_TEID_LEN);
}
req->pgw_s5_s8_address_for_control_plane_or_pmip.presence = 1;
req->pgw_s5_s8_address_for_control_plane_or_pmip.data = &pgw_s5c_teid;
req->access_point_name.presence = 1;
req->access_point_name.len = apn_build(apn, pdn->apn, strlen(pdn->apn));

View File

@ -51,10 +51,10 @@ status_t testgtpu_enb_connect(sock_id *new)
if (test_only_control_plane) return CORE_OK;
d_assert(mme, return CORE_ERROR,);
d_assert(mme->gtpc4_addr, return CORE_ERROR,);
d_assert(mme->gtpc_addr, return CORE_ERROR,);
if (!mme) return CORE_ERROR;
memcpy(&addr, mme->gtpc4_addr, sizeof(c_sockaddr_t));
memcpy(&addr, mme->gtpc_addr, sizeof(c_sockaddr_t));
addr.c_sa_port = htons(GTPV1_U_UDP_PORT);
rv = udp_socket(new, AF_INET);