gtp node is added

This commit is contained in:
Sukchan Lee 2017-12-02 14:17:32 +09:00
parent 3ae058dc63
commit ce5b65b4df
12 changed files with 267 additions and 59 deletions

View File

@ -122,7 +122,7 @@ CORE_DECLARE(c_sockaddr_t *) sock_remote_addr(sock_id id);
* Socket Address
*/
CORE_DECLARE(sock_node_t *) sock_add_node(list_t *list,
int family, const char *hostname, c_uint16_t port, int flags);
int family, const char *hostname, c_uint16_t port);
CORE_DECLARE(status_t) sock_remove_node(list_t *list, sock_node_t *node);
CORE_DECLARE(status_t) sock_remove_all_nodes(list_t *list);

View File

@ -7,14 +7,14 @@
#include "core_arch_network.h"
#define MAX_SOCK_POOL_SIZE 512
#define MAX_SOCKNODE_POOL_SIZE 512
#define MAX_SOCK_NODE_POOL_SIZE 512
static int max_fd;
static list_t fd_list;
static fd_set read_fds;
pool_declare(sock_pool, sock_t, MAX_SOCK_POOL_SIZE);
pool_declare(sock_node_pool, sock_node_t, MAX_SOCKNODE_POOL_SIZE);
pool_declare(sock_node_pool, sock_node_t, MAX_SOCK_NODE_POOL_SIZE);
static status_t sononblock(int sd);
static status_t soblock(int sd);
@ -27,7 +27,7 @@ static void fd_dispatch(fd_set *fds);
status_t network_init(void)
{
pool_init(&sock_pool, MAX_SOCK_POOL_SIZE);
pool_init(&sock_node_pool, MAX_SOCKNODE_POOL_SIZE);
pool_init(&sock_node_pool, MAX_SOCK_NODE_POOL_SIZE);
max_fd = 0;
list_init(&fd_list);
@ -310,10 +310,14 @@ static sock_node_t *sock_add_node_internal(list_t *list, c_sockaddr_t *sa_list)
}
sock_node_t *sock_add_node(list_t *list,
int family, const char *hostname, c_uint16_t port, int flags)
int family, const char *hostname, c_uint16_t port)
{
status_t rv;
c_sockaddr_t *sa_list = NULL;
int flags = 0;
if (hostname == NULL)
flags = AI_PASSIVE;
rv = core_getaddrinfo(&sa_list, family, hostname, port, flags);
if (rv != CORE_OK)

View File

@ -342,7 +342,7 @@ static void sock_test7(abts_case *tc, void *data)
list_init(&list);
node = sock_add_node(&list, AF_INET6, NULL, PORT, 0);
node = sock_add_node(&list, AF_INET6, "localhost", PORT);
ABTS_PTR_NOTNULL(tc, node);
rv = sock_filter_node(&list, AF_INET6);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
@ -353,7 +353,7 @@ static void sock_test7(abts_case *tc, void *data)
node = list_first(&list);
ABTS_PTR_NULL(tc, node);
node = sock_add_node(&list, AF_INET, NULL, PORT, AI_PASSIVE);
node = sock_add_node(&list, AF_INET, NULL, PORT);
ABTS_PTR_NOTNULL(tc, node);
rv = sock_filter_node(&list, AF_INET);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
@ -364,7 +364,7 @@ static void sock_test7(abts_case *tc, void *data)
node = list_first(&list);
ABTS_PTR_NULL(tc, node);
node = sock_add_node(&list, AF_UNSPEC, NULL, PORT, 0);
node = sock_add_node(&list, AF_UNSPEC, "localhost", PORT);
ABTS_PTR_NOTNULL(tc, node);
rv = sock_filter_node(&list, AF_INET6);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
@ -375,11 +375,11 @@ static void sock_test7(abts_case *tc, void *data)
node = list_first(&list);
ABTS_PTR_NULL(tc, node);
node = sock_add_node(&list, AF_INET6, NULL, PORT, 0);
node = sock_add_node(&list, AF_INET6, "localhost", PORT);
ABTS_PTR_NOTNULL(tc, node);
node = sock_add_node(&list, AF_INET, NULL, PORT, AI_PASSIVE);
node = sock_add_node(&list, AF_INET, NULL, PORT);
ABTS_PTR_NOTNULL(tc, node);
node = sock_add_node(&list, AF_UNSPEC, NULL, PORT, AI_PASSIVE);
node = sock_add_node(&list, AF_UNSPEC, NULL, PORT);
ABTS_PTR_NOTNULL(tc, node);
node = list_first(&list);

View File

@ -4,25 +4,31 @@ pkglib_LTLIBRARIES = libgtp.la
libgtp_la_SOURCES = \
gtp_message.h gtp_types.h gtp_conv.h gtp_node.h gtp_path.h gtp_xact.h \
gtp_message.c gtp_types.c gtp_conv.c gtp_node.c gtp_path.c gtp_xact.c
gtp_message.c gtp_types.c gtp_conv.c gtp_node.c gtp_path.c gtp_xact.c \
$(NULL)
libgtp_la_DEPENDENCIES = \
$(top_srcdir)/lib/core/src/libcore.la \
$(top_srcdir)/lib/3gpp/lib3gpp.la
$(top_srcdir)/lib/3gpp/lib3gpp.la \
$(NULL)
libgtp_la_LIBADD = \
$(top_srcdir)/lib/core/src/libcore.la \
$(top_srcdir)/lib/3gpp/lib3gpp.la
$(top_srcdir)/lib/3gpp/lib3gpp.la \
$(NULL)
AM_LDFLAGS = \
-version-info @LIBVERSION@
-version-info @LIBVERSION@ \
$(NULL)
AM_CPPFLAGS = \
-I$(top_srcdir)/lib/core/include \
-I$(top_srcdir)/lib/3gpp
-I$(top_srcdir)/lib/3gpp \
$(NULL)
AM_CFLAGS = \
-Wall -Werror
-Wall -Werror \
$(NULL)
MAINTAINERCLEANFILES = Makefile.in
MOSTLYCLEANFILES = *.stackdump

View File

@ -3,3 +3,106 @@
#include "core_debug.h"
#include "gtp_node.h"
pool_declare(gtp_node_pool, gtp_node_t, MAX_NUM_OF_GTP_CLIENT);
status_t gtp_node_init(void)
{
pool_init(&gtp_node_pool, MAX_NUM_OF_GTP_CLIENT);
return CORE_OK;
}
status_t gtp_node_final(void)
{
if (pool_size(&gtp_node_pool) != pool_avail(&gtp_node_pool))
d_error("%d not freed in gtp_node_pool[%d]",
pool_size(&gtp_node_pool) - pool_avail(&gtp_node_pool),
pool_size(&gtp_node_pool));
d_trace(3, "%d not freed in gtp_node_pool[%d]\n",
pool_size(&gtp_node_pool) - pool_avail(&gtp_node_pool),
pool_size(&gtp_node_pool));
pool_final(&gtp_node_pool);
return CORE_OK;
}
gtp_node_t *gtp_add_node(list_t *list,
int family, const char *hostname, c_uint16_t port)
{
status_t rv;
gtp_node_t *node = NULL;
c_sockaddr_t *sa_list = NULL;
d_assert(list, return NULL,);
rv = core_getaddrinfo(&sa_list, family, hostname, port, 0);
if (rv != CORE_OK)
{
d_error("core_getaddrinfo(%d:%s:%d)", family, hostname, port);
return NULL;
}
d_assert(sa_list, return NULL,);
pool_alloc_node(&gtp_node_pool, &node);
d_assert(node, return NULL,);
memset(node, 0, sizeof(gtp_node_t));
node->sa_list = sa_list;
list_append(list, node);
return node;
}
status_t gtp_remove_node(list_t *list, gtp_node_t *node)
{
d_assert(node, return CORE_ERROR,);
list_remove(list, node);
core_freeaddrinfo(node->sa_list);
pool_free_node(&gtp_node_pool, node);
return CORE_OK;
}
status_t gtp_remove_all_nodes(list_t *list)
{
gtp_node_t *node = NULL, *next_node = NULL;
node = list_first(list);
while(node)
{
next_node = list_next(node);
gtp_remove_node(list, node);
node = next_node;
}
return CORE_OK;
}
status_t gtp_filter_node(list_t *list, int family)
{
gtp_node_t *node = NULL, *next_node = NULL;
d_assert(list, return CORE_ERROR,);
node = list_first(list);
while(node)
{
next_node = list_next(node);
core_filteraddrinfo(&node->sa_list, family);
if (node->sa_list == NULL)
gtp_remove_node(list, node);
node = next_node;
}
return CORE_OK;
}

View File

@ -10,14 +10,12 @@
extern "C" {
#endif /* __cplusplus */
typedef list_t gnode_list_t;
/**
* This structure represents the commonalities of GTP node such as MME, SGW,
* PGW gateway. Some of members may not be used by the specific type of node */
typedef struct _gtp_node_t {
lnode_t node; /**< A node of list_t */
c_sockaddr_t *addr; /**< Socket Address */
c_sockaddr_t *sa_list; /**< Socket Address List */
c_sockaddr_t old_addr; /**< Will be removed */
sock_id sock; /**< Socket Descriptor */
@ -26,6 +24,15 @@ typedef struct _gtp_node_t {
list_t remote_list;
} gtp_node_t;
CORE_DECLARE(status_t) gtp_node_init(void);
CORE_DECLARE(status_t) gtp_node_final(void);
CORE_DECLARE(gtp_node_t *) gtp_add_node(list_t *list,
int family, const char *hostname, c_uint16_t port);
CORE_DECLARE(status_t) gtp_remove_node(list_t *list, gtp_node_t *node);
CORE_DECLARE(status_t) gtp_remove_all_nodes(list_t *list);
CORE_DECLARE(status_t) gtp_filter_node(list_t *list, int family);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -9,19 +9,37 @@
#include "gtp_path.h"
status_t gtp_server(sock_id *new, c_sockaddr_t *sa_list, sock_handler handler)
status_t gtp_server(sock_node_t *snode, sock_handler handler)
{
status_t rv;
char buf[CORE_ADDRSTRLEN];
rv = udp_server(new, sa_list);
d_assert(snode, return CORE_ERROR,);
rv = udp_server(&snode->sock, snode->sa_list);
d_assert(rv == CORE_OK, return CORE_ERROR,);
rv = sock_register(*new, handler, NULL);
rv = sock_register(snode->sock, handler, NULL);
d_assert(rv == CORE_OK, return CORE_ERROR,);
d_trace(1, "gtp_server() [%s]:%d\n",
CORE_ADDR(sa_list, buf), CORE_PORT(sa_list));
CORE_ADDR(snode->sa_list, buf), CORE_PORT(snode->sa_list));
return CORE_OK;
}
status_t gtp_client(gtp_node_t *gnode)
{
status_t rv;
char buf[CORE_ADDRSTRLEN];
d_assert(gnode, return CORE_ERROR,);
rv = udp_client(&gnode->sock, gnode->sa_list);
d_assert(rv == CORE_OK, return CORE_ERROR,);
d_trace(1, "gtp_client() [%s]:%d\n",
CORE_ADDR(gnode->sa_list, buf), CORE_PORT(gnode->sa_list));
return CORE_OK;
}
@ -151,7 +169,7 @@ status_t gtp_send(gtp_node_t *gnode, pkbuf_t *pkbuf)
sock = gnode->sock;
d_assert(sock, return CORE_ERROR, "Null param");
if (gnode->addr)
if (gnode->sa_list)
{
/* New interface */
d_assert(0, return CORE_ERROR,);

View File

@ -10,8 +10,8 @@ typedef struct _gtp_node_t gtp_node_t;
extern "C" {
#endif /* __cplusplus */
CORE_DECLARE(status_t) gtp_server(sock_id *new,
c_sockaddr_t *sa_list, sock_handler handler);
CORE_DECLARE(status_t) gtp_server(sock_node_t *snode, sock_handler handler);
CORE_DECLARE(status_t) gtp_client(gtp_node_t *gnode);
CORE_DECLARE(status_t) gtp_listen(sock_id *sock,
sock_handler handler, c_uint32_t addr, c_uint16_t port, void *data);

View File

@ -51,9 +51,12 @@ status_t mme_context_init()
list_init(&self.gtpc4_list);
list_init(&self.gtpc6_list);
pool_init(&mme_sgw_pool, MAX_NUM_OF_GTP_CLIENT);
gtp_node_init();
list_init(&self.sgw_list);
pool_init(&mme_sgw_pool, MAX_NUM_OF_GTP_CLIENT);
list_init(&self.old_sgw_list);
index_init(&mme_enb_pool, MAX_NUM_OF_ENB);
index_init(&mme_ue_pool, MAX_POOL_OF_UE);
index_init(&enb_ue_pool, MAX_POOL_OF_UE);
@ -109,6 +112,9 @@ status_t mme_context_final()
index_final(&mme_enb_pool);
pool_final(&mme_sgw_pool);
gtp_remove_all_nodes(&self.sgw_list);
gtp_node_final();
sock_remove_all_nodes(&self.gtpc4_list);
sock_remove_all_nodes(&self.gtpc6_list);
@ -157,6 +163,13 @@ static status_t mme_context_validation()
return CORE_ERROR;
}
if (list_first(&self.sgw_list) == NULL)
{
d_error("No sgw.gtpc.hostname in '%s'",
context_self()->config.path);
return CORE_ERROR;
}
mme_sgw_t *sgw = mme_sgw_first();
if (sgw == NULL)
{
@ -401,7 +414,7 @@ status_t mme_context_parse_config()
if (context_self()->parameter.no_ipv4 == 0)
{
node = sock_add_node(&self.gtpc4_list,
family, hostname, port, AI_PASSIVE);
family, hostname, port);
d_assert(node, return CORE_ERROR,);
rv = sock_filter_node(
&self.gtpc4_list, AF_INET);
@ -411,7 +424,7 @@ status_t mme_context_parse_config()
if (context_self()->parameter.no_ipv6 == 0)
{
node = sock_add_node(&self.gtpc6_list,
family, hostname, port, AI_PASSIVE);
family, hostname, port);
d_assert(node, return CORE_ERROR,);
rv = sock_filter_node(
&self.gtpc6_list, AF_INET6);
@ -934,7 +947,22 @@ status_t mme_context_parse_config()
sgw->old_addr.c_sa_port = htons(port);
#endif
sgw = gtp_add_node(&self.sgw_list,
family, hostname, port);
d_assert(sgw, return CORE_ERROR,);
} while(yaml_iter_type(&gtpc_array) == YAML_SEQUENCE_NODE);
if (context_self()->parameter.no_ipv4 == 1)
{
rv = gtp_filter_node(&self.sgw_list, AF_INET6);
d_assert(rv == CORE_OK, return CORE_ERROR,);
}
if (context_self()->parameter.no_ipv6 == 1)
{
rv = gtp_filter_node(&self.sgw_list, AF_INET);
d_assert(rv == CORE_OK, return CORE_ERROR,);
}
}
}
}
@ -1204,7 +1232,7 @@ mme_sgw_t* mme_sgw_add()
list_init(&sgw->local_list);
list_init(&sgw->remote_list);
list_append(&self.sgw_list, sgw);
list_append(&self.old_sgw_list, sgw);
return sgw;
}
@ -1213,7 +1241,7 @@ status_t mme_sgw_remove(mme_sgw_t *sgw)
{
d_assert(sgw, return CORE_ERROR, "Null param");
list_remove(&self.sgw_list, sgw);
list_remove(&self.old_sgw_list, sgw);
gtp_xact_delete_all(sgw);
pool_free_node(&mme_sgw_pool, sgw);
@ -1240,7 +1268,7 @@ status_t mme_sgw_remove_all()
mme_sgw_t* mme_sgw_first()
{
return list_first(&self.sgw_list);
return list_first(&self.old_sgw_list);
}
mme_sgw_t* mme_sgw_next(mme_sgw_t *sgw)

View File

@ -57,15 +57,17 @@ typedef struct _mme_context_t {
const char *fd_conf_path; /* MME freeDiameter conf path */
list_t s1ap_list; /* MME S1AP Server List */
list_t sgw_list; /* SGW GTPC Client List */
list_t old_sgw_list; /* SGW GTPC Client List */
c_uint16_t gtpc_port; /* Default GTPC Port */
list_t gtpc4_list; /* MME GTPC IPv4 Server List */
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 */
list_t gtpc6_list; /* MME GTPC IPv6 Server List */
c_sockaddr_t *gtpc6_addr; /* MME GTPC IPv6 Address */
list_t sgw_list; /* SGW GTPC Client List */
c_uint32_t s5c_addr; /* PGW S5C remote address */
c_uint16_t s5c_port; /* PGW S5C remote port */

View File

@ -42,39 +42,39 @@ static int _gtpv2_c_recv_cb(sock_id sock, void *data)
return 0;
}
status_t mme_gtp_open()
static status_t mme_gtp_server()
{
status_t rv;
mme_sgw_t *sgw = mme_sgw_first();
sock_node_t *node;
sock_node_t *snode;
sock_id temp; /* FIXME ADDR */
for (node = list_first(&mme_self()->gtpc4_list);
node; node = list_next(node))
for (snode = list_first(&mme_self()->gtpc4_list);
snode; snode = list_next(snode))
{
rv = gtp_server(&node->sock, node->sa_list, _gtpv2_c_recv_cb);
rv = gtp_server(snode, _gtpv2_c_recv_cb);
if (rv != CORE_OK)
{
d_error("Can't establish GTP-C Path for SGW");
return rv;
}
temp = node->sock; /* FIXME ADDR : Shoud be removed */
temp = snode->sock; /* FIXME ADDR : Shoud be removed */
}
for (node = list_first(&mme_self()->gtpc4_list);
node; node = list_next(node))
for (snode = list_first(&mme_self()->gtpc4_list);
snode; snode = list_next(snode))
{
mme_self()->gtpc4_addr = sock_local_addr(node->sock);
mme_self()->gtpc4_addr = sock_local_addr(snode->sock);
if (mme_self()->gtpc4_addr)
{
break;
}
}
for (node = list_first(&mme_self()->gtpc6_list);
node; node = list_next(node))
for (snode = list_first(&mme_self()->gtpc6_list);
snode; snode = list_next(snode))
{
rv = gtp_server(&node->sock, node->sa_list, _gtpv2_c_recv_cb);
rv = gtp_server(snode, _gtpv2_c_recv_cb);
if (rv != CORE_OK)
{
d_error("Can't establish GTP-C Path for SGW");
@ -82,10 +82,10 @@ status_t mme_gtp_open()
}
}
for (node = list_first(&mme_self()->gtpc6_list);
node; node = list_next(node))
for (snode = list_first(&mme_self()->gtpc6_list);
snode; snode = list_next(snode))
{
mme_self()->gtpc6_addr = sock_local_addr(node->sock);
mme_self()->gtpc6_addr = sock_local_addr(snode->sock);
if (mme_self()->gtpc6_addr)
{
break;
@ -105,20 +105,59 @@ status_t mme_gtp_open()
return CORE_OK;
}
status_t mme_gtp_close()
static status_t mme_gtp_client()
{
sock_node_t *node;
status_t rv;
gtp_node_t *gnode = NULL;
for (node = list_first(&mme_self()->gtpc4_list);
node; node = list_next(node))
for (gnode = list_first(&mme_self()->sgw_list);
gnode; gnode = list_next(gnode))
{
sock_delete(node->sock);
rv = gtp_client(gnode);
if (rv != CORE_OK)
{
d_error("Can't connect GTP-C Path to SGW");
return rv;
}
}
for (node = list_first(&mme_self()->gtpc6_list);
node; node = list_next(node))
return CORE_OK;
}
status_t mme_gtp_open()
{
status_t rv;
rv = mme_gtp_server();
if (rv != CORE_OK) return CORE_ERROR;
rv = mme_gtp_client();
if (rv != CORE_OK) return CORE_ERROR;
return CORE_OK;
}
status_t mme_gtp_close()
{
sock_node_t *snode;
gtp_node_t *gnode;
for (snode = list_first(&mme_self()->gtpc4_list);
snode; snode = list_next(snode))
{
sock_delete(node->sock);
sock_delete(snode->sock);
}
for (snode = list_first(&mme_self()->gtpc6_list);
snode; snode = list_next(snode))
{
sock_delete(snode->sock);
}
for (gnode = list_first(&mme_self()->sgw_list);
gnode; gnode = list_next(gnode))
{
sock_delete(gnode->sock);
}
return CORE_OK;

View File

@ -176,6 +176,7 @@ status_t testgtpu_enb_send(sock_id sock, c_uint32_t src_ip, c_uint32_t dst_ip)
icmp_h->checksum = in_cksum(
(unsigned short *)icmp_h, sizeof(struct icmp_header_t));
memset(&gnode, 0, sizeof(gtp_node_t));
gnode.old_addr.sin.sin_addr.s_addr = bearer->sgw_s1u_addr;
gnode.old_addr.c_sa_port = htons(GTPV1_U_UDP_PORT);
gnode.old_addr.c_sa_family = AF_INET;