PGW GTP-C server is added

This commit is contained in:
Sukchan Lee 2017-12-05 21:34:17 +09:00
parent a747f91b39
commit 4591209759
5 changed files with 143 additions and 116 deletions

View File

@ -36,6 +36,9 @@ status_t pgw_context_init()
memset(&self, 0, sizeof(pgw_context_t));
list_init(&self.gtpc_list);
list_init(&self.gtpc_list6);
gtp_node_init();
list_init(&self.sgw_list);
@ -89,6 +92,9 @@ status_t pgw_context_final()
gtp_remove_all_nodes(&self.sgw_list);
gtp_node_final();
sock_remove_all_nodes(&self.gtpc_list);
sock_remove_all_nodes(&self.gtpc_list6);
context_initiaized = 0;
return CORE_OK;
@ -115,7 +121,8 @@ static status_t pgw_context_validation()
context_self()->config.path);
return CORE_ERROR;
}
if (self.gtpc_addr == 0)
if (list_first(&self.gtpc_list) == NULL &&
list_first(&self.gtpc_list6) == NULL)
{
d_error("No pgw.gtpc in '%s'",
context_self()->config.path);
@ -179,12 +186,13 @@ status_t pgw_context_parse_config()
yaml_iter_recurse(&pgw_iter, &gtpc_array);
do
{
#if 0
pgw_gtpc_t *gtpc = NULL;
#endif
int family = AF_UNSPEC;
const char *hostname = NULL;
c_uint16_t port = GTPV2_C_UDP_PORT;
int i, num = 0;
#define MAX_NUM_OF_HOSTNAME 16
const char *hostname[MAX_NUM_OF_HOSTNAME];
c_uint16_t port = self.gtpc_port;
c_sockaddr_t *list = NULL;
sock_node_t *node = NULL;
if (yaml_iter_type(&gtpc_array) == YAML_MAPPING_NODE)
{
@ -199,7 +207,7 @@ status_t pgw_context_parse_config()
yaml_iter_recurse(&gtpc_array, &gtpc_iter);
}
else if (yaml_iter_type(&gtpc_array) ==
YAML_SCALAR_NODE)
YAML_SCALAR_NODE)
{
break;
}
@ -227,11 +235,27 @@ status_t pgw_context_parse_config()
else if (!strcmp(gtpc_key, "addr") ||
!strcmp(gtpc_key, "name"))
{
hostname = yaml_iter_value(&gtpc_iter);
#if 1
if (hostname)
self.gtpc_addr = inet_addr(hostname);
#endif
yaml_iter_t hostname_iter;
yaml_iter_recurse(&gtpc_iter, &hostname_iter);
d_assert(yaml_iter_type(&hostname_iter) !=
YAML_MAPPING_NODE, return CORE_ERROR,);
do
{
if (yaml_iter_type(&hostname_iter) ==
YAML_SEQUENCE_NODE)
{
if (!yaml_iter_next(&hostname_iter))
break;
}
d_assert(num <= MAX_NUM_OF_HOSTNAME,
return CORE_ERROR,);
hostname[num++] =
yaml_iter_value(&hostname_iter);
} while(
yaml_iter_type(&hostname_iter) ==
YAML_SEQUENCE_NODE);
}
else if (!strcmp(gtpc_key, "port"))
{
@ -246,12 +270,43 @@ status_t pgw_context_parse_config()
d_warn("unknown key `%s`", gtpc_key);
}
#if 0
gtpc = pgw_gtpc_add(family, hostname, port);
d_assert(gtpc, return CORE_ERROR,);
#endif
list = NULL;
for (i = 0; i < num; i++)
{
rv = core_addaddrinfo(&list,
family, hostname[i], port, AI_PASSIVE);
d_assert(rv == CORE_OK, return CORE_ERROR,);
}
if (context_self()->parameter.no_ipv4 == 0)
{
rv = sock_add_node(&self.gtpc_list,
&node, list, AF_INET);
d_assert(rv == CORE_OK, return CORE_ERROR,);
}
if (context_self()->parameter.no_ipv6 == 0)
{
rv = sock_add_node(&self.gtpc_list,
&node, list, AF_INET6);
d_assert(rv == CORE_OK, return CORE_ERROR,);
}
core_freeaddrinfo(list);
} while(yaml_iter_type(&gtpc_array) == YAML_SEQUENCE_NODE);
if (list_first(&self.gtpc_list) == NULL &&
list_first(&self.gtpc_list6) == NULL)
{
rv = sock_probe_node(
context_self()->parameter.no_ipv4 ?
NULL : &self.gtpc_list,
context_self()->parameter.no_ipv6 ?
NULL : &self.gtpc_list6,
self.gtpc_port);
d_assert(rv == CORE_OK, return CORE_ERROR,);
}
}
else if (!strcmp(pgw_key, "gtpu"))
{
@ -609,7 +664,8 @@ pgw_sess_t *pgw_sess_add(
d_assert(sess, return NULL, "Null param");
sess->pgw_s5c_teid = sess->index; /* derived from an index */
sess->pgw_s5c_addr = pgw_self()->gtpc_addr;
sess->pgw_s5c_ipv4 = pgw_self()->gtpc_addr;
sess->pgw_s5c_ipv6 = pgw_self()->gtpc_addr6;
/* Set IMSI */
sess->imsi_len = imsi_len;

View File

@ -23,9 +23,12 @@ typedef struct _gtp_node_t gtp_node_t;
typedef struct _pgw_context_t {
c_uint32_t pgw_addr; /* PGW local address */
c_uint32_t gtpc_addr; /* PGW GTP-C local address */
c_uint32_t gtpc_port; /* PGW GTP-C local port */
sock_id gtpc_sock; /* PGW GTP-C local listen socket */
c_uint32_t gtpc_port; /* PGW GTP-C local port */
list_t gtpc_list; /* PGW GTPC IPv4 Server List */
c_sockaddr_t *gtpc_addr; /* PGW GTPC IPv4 Address */
list_t gtpc_list6; /* PGW GTPC IPv6 Server List */
c_sockaddr_t *gtpc_addr6; /* PGW GTPC IPv6 Address */
c_uint32_t gtpu_addr; /* PGW GTP-U local address */
c_uint32_t gtpu_port; /* PGW GTP-U local port */
@ -70,7 +73,8 @@ typedef struct _pgw_sess_t {
/* IMPORTANT!
* PGW-S5C-F-TEID is same with an index */
c_uint32_t pgw_s5c_teid;
c_uint32_t pgw_s5c_addr;
c_sockaddr_t *pgw_s5c_ipv4; /* PGW S5C IPv4 Address */
c_sockaddr_t *pgw_s5c_ipv6; /* PGW S5C IPv6 Address */
c_uint32_t sgw_s5c_teid;
c_uint32_t sgw_s5c_addr;

View File

@ -160,20 +160,55 @@ static int _gtpv1_u_recv_cb(sock_id sock, void *data)
status_t pgw_gtp_open()
{
status_t rv;
sock_node_t *snode;
int i;
int rc;
#if 0 /* ADDR */
char buf[INET_ADDRSTRLEN];
#endif
rv = gtp_listen(&pgw_self()->gtpc_sock, _gtpv2_c_recv_cb,
pgw_self()->gtpc_addr, pgw_self()->gtpc_port, NULL);
if (rv != CORE_OK)
for (snode = list_first(&pgw_self()->gtpc_list);
snode; snode = list_next(snode))
{
d_error("Can't establish GTP-C Path for PGW");
return rv;
rv = gtp_server(snode, _gtpv2_c_recv_cb);
if (rv != CORE_OK)
{
d_error("Can't establish GTP-C Path for SGW");
return rv;
}
}
for (snode = list_first(&pgw_self()->gtpc_list);
snode; snode = list_next(snode))
{
pgw_self()->gtpc_addr = sock_local_addr(snode->sock);
if (pgw_self()->gtpc_addr)
{
break;
}
}
for (snode = list_first(&pgw_self()->gtpc_list6);
snode; snode = list_next(snode))
{
rv = gtp_server(snode, _gtpv2_c_recv_cb);
if (rv != CORE_OK)
{
d_error("Can't establish GTP-C Path for SGW");
return rv;
}
}
for (snode = list_first(&pgw_self()->gtpc_list6);
snode; snode = list_next(snode))
{
pgw_self()->gtpc_addr6 = sock_local_addr(snode->sock);
if (pgw_self()->gtpc_addr6)
{
break;
}
}
d_assert(pgw_self()->gtpc_addr || pgw_self()->gtpc_addr6,
return CORE_ERROR, "No GTP Server");
rv = gtp_listen(&pgw_self()->gtpu_sock, _gtpv1_u_recv_cb,
pgw_self()->gtpu_addr, pgw_self()->gtpu_port, NULL);
if (rv != CORE_OK)
@ -251,8 +286,20 @@ status_t pgw_gtp_open()
status_t pgw_gtp_close()
{
int i;
sock_node_t *snode;
for (snode = list_first(&pgw_self()->gtpc_list);
snode; snode = list_next(snode))
{
sock_delete(snode->sock);
}
for (snode = list_first(&pgw_self()->gtpc_list6);
snode; snode = list_next(snode))
{
sock_delete(snode->sock);
}
sock_delete(pgw_self()->gtpc_sock);
sock_delete(pgw_self()->gtpu_sock);
for (i = 0; i < pgw_self()->num_of_ue_network; i++)
{

View File

@ -3,6 +3,7 @@
#include "core_debug.h"
#include "gtp_types.h"
#include "gtp_conv.h"
#include "gtp_message.h"
#include "gx_message.h"
@ -23,6 +24,7 @@ status_t pgw_s5c_build_create_session_response(
gtp_cause_t cause;
gtp_f_teid_t pgw_s5c_teid, pgw_s5u_teid;
int len;
c_uint8_t pco_buf[MAX_PCO_LEN];
c_int16_t pco_len;
@ -44,10 +46,11 @@ status_t pgw_s5c_build_create_session_response(
/* Control Plane(UL) : PGW-S5C */
memset(&pgw_s5c_teid, 0, sizeof(gtp_f_teid_t));
pgw_s5c_teid.ipv4 = 1;
pgw_s5c_teid.interface_type = GTP_F_TEID_S5_S8_PGW_GTP_C;
pgw_s5c_teid.ip.addr = sess->pgw_s5c_addr;
pgw_s5c_teid.teid = htonl(sess->pgw_s5c_teid);
rv = gtp_sockaddr_to_f_teid(
sess->pgw_s5c_ipv4, sess->pgw_s5c_ipv6, &pgw_s5c_teid, &len);
d_assert(rv == CORE_OK, return CORE_ERROR, );
rsp->pgw_s5_s8__s2a_s2b_f_teid_for_pmip_based_interface_or_for_gtp_based_control_plane_interface.
presence = 1;
rsp->pgw_s5_s8__s2a_s2b_f_teid_for_pmip_based_interface_or_for_gtp_based_control_plane_interface.

View File

@ -99,7 +99,7 @@ static status_t sgw_context_validation()
if (list_first(&self.gtpc_list) == NULL &&
list_first(&self.gtpc_list6) == NULL)
{
d_error("No mme.gtpc in '%s'",
d_error("No sgw.gtpc in '%s'",
context_self()->config.path);
return CORE_ERROR;
}
@ -139,88 +139,6 @@ status_t sgw_context_parse_config()
{
const char *sgw_key = yaml_iter_key(&sgw_iter);
d_assert(sgw_key, return CORE_ERROR,);
#if 0
if (!strcmp(sgw_key, "gtpc"))
{
yaml_iter_t gtpc_array, gtpc_iter;
yaml_iter_recurse(&sgw_iter, &gtpc_array);
do
{
#if 0
sgw_gtpc_t *gtpc = NULL;
#endif
int family = AF_UNSPEC;
const char *hostname = NULL;
c_uint16_t port = GTPV2_C_UDP_PORT;
if (yaml_iter_type(&gtpc_array) == YAML_MAPPING_NODE)
{
memcpy(&gtpc_iter, &gtpc_array,
sizeof(yaml_iter_t));
}
else if (yaml_iter_type(&gtpc_array) ==
YAML_SEQUENCE_NODE)
{
if (!yaml_iter_next(&gtpc_array))
break;
yaml_iter_recurse(&gtpc_array, &gtpc_iter);
}
else if (yaml_iter_type(&gtpc_array) ==
YAML_SCALAR_NODE)
{
break;
}
else
d_assert(0, return CORE_ERROR,);
while(yaml_iter_next(&gtpc_iter))
{
const char *gtpc_key =
yaml_iter_key(&gtpc_iter);
d_assert(gtpc_key,
return CORE_ERROR,);
if (!strcmp(gtpc_key, "family"))
{
const char *v = yaml_iter_value(&gtpc_iter);
if (v) family = atoi(v);
if (family != AF_UNSPEC &&
family != AF_INET && family != AF_INET6)
{
d_warn("Ignore family(%d) : AF_UNSPEC(0), "
"AF_INET(2), AF_INET6(30) ", family);
family = AF_UNSPEC;
}
}
else if (!strcmp(gtpc_key, "addr") ||
!strcmp(gtpc_key, "name"))
{
hostname = yaml_iter_value(&gtpc_iter);
#if 1
if (hostname)
self.old_gtpc_addr = inet_addr(hostname);
#endif
}
else if (!strcmp(gtpc_key, "port"))
{
const char *v = yaml_iter_value(&gtpc_iter);
if (v)
{
port = atoi(v);
self.gtpc_port = port;
}
}
else
d_warn("unknown key `%s`", gtpc_key);
}
#if 0
gtpc = sgw_gtpc_add(family, hostname, port);
d_assert(gtpc, return CORE_ERROR,);
#endif
} while(yaml_iter_type(&gtpc_array) == YAML_SEQUENCE_NODE);
}
#else
if (!strcmp(sgw_key, "gtpc"))
{
yaml_iter_t gtpc_array, gtpc_iter;
@ -349,7 +267,6 @@ status_t sgw_context_parse_config()
d_assert(rv == CORE_OK, return CORE_ERROR,);
}
}
#endif
else if (!strcmp(sgw_key, "gtpu"))
{
yaml_iter_t gtpu_array, gtpu_iter;