From ce5b65b4df8c951710bb3d1251f10f105f6318de Mon Sep 17 00:00:00 2001 From: Sukchan Lee Date: Sat, 2 Dec 2017 14:17:32 +0900 Subject: [PATCH] gtp node is added --- lib/core/include/core_network.h | 2 +- lib/core/src/unix/socket.c | 12 ++-- lib/core/test/testsock.c | 12 ++-- lib/gtp/Makefile.am | 18 ++++-- lib/gtp/gtp_node.c | 103 ++++++++++++++++++++++++++++++++ lib/gtp/gtp_node.h | 13 +++- lib/gtp/gtp_path.c | 28 +++++++-- lib/gtp/gtp_path.h | 4 +- src/mme/mme_context.c | 40 +++++++++++-- src/mme/mme_context.h | 8 ++- src/mme/mme_gtp_path.c | 85 +++++++++++++++++++------- test/testpacket.c | 1 + 12 files changed, 267 insertions(+), 59 deletions(-) diff --git a/lib/core/include/core_network.h b/lib/core/include/core_network.h index a27a17858..a57be177e 100644 --- a/lib/core/include/core_network.h +++ b/lib/core/include/core_network.h @@ -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); diff --git a/lib/core/src/unix/socket.c b/lib/core/src/unix/socket.c index b5f18aa09..0e7175dce 100644 --- a/lib/core/src/unix/socket.c +++ b/lib/core/src/unix/socket.c @@ -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) diff --git a/lib/core/test/testsock.c b/lib/core/test/testsock.c index e9c59b106..dcde81112 100644 --- a/lib/core/test/testsock.c +++ b/lib/core/test/testsock.c @@ -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); diff --git a/lib/gtp/Makefile.am b/lib/gtp/Makefile.am index d6830c045..065ddac6c 100644 --- a/lib/gtp/Makefile.am +++ b/lib/gtp/Makefile.am @@ -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 diff --git a/lib/gtp/gtp_node.c b/lib/gtp/gtp_node.c index e24c1bfae..d4f84441b 100644 --- a/lib/gtp/gtp_node.c +++ b/lib/gtp/gtp_node.c @@ -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(>p_node_pool, MAX_NUM_OF_GTP_CLIENT); + + return CORE_OK; +} +status_t gtp_node_final(void) +{ + if (pool_size(>p_node_pool) != pool_avail(>p_node_pool)) + d_error("%d not freed in gtp_node_pool[%d]", + pool_size(>p_node_pool) - pool_avail(>p_node_pool), + pool_size(>p_node_pool)); + d_trace(3, "%d not freed in gtp_node_pool[%d]\n", + pool_size(>p_node_pool) - pool_avail(>p_node_pool), + pool_size(>p_node_pool)); + pool_final(>p_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(>p_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(>p_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; +} + diff --git a/lib/gtp/gtp_node.h b/lib/gtp/gtp_node.h index 01fd38f57..1f2600098 100644 --- a/lib/gtp/gtp_node.h +++ b/lib/gtp/gtp_node.h @@ -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 */ diff --git a/lib/gtp/gtp_path.c b/lib/gtp/gtp_path.c index eb3192582..de7114201 100644 --- a/lib/gtp/gtp_path.c +++ b/lib/gtp/gtp_path.c @@ -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,); diff --git a/lib/gtp/gtp_path.h b/lib/gtp/gtp_path.h index 1c93f6077..3e2549a0f 100644 --- a/lib/gtp/gtp_path.h +++ b/lib/gtp/gtp_path.h @@ -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); diff --git a/src/mme/mme_context.c b/src/mme/mme_context.c index 426e505d9..4374775a3 100644 --- a/src/mme/mme_context.c +++ b/src/mme/mme_context.c @@ -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(>pc_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) diff --git a/src/mme/mme_context.h b/src/mme/mme_context.h index b451e6a46..ef42f360b 100644 --- a/src/mme/mme_context.h +++ b/src/mme/mme_context.h @@ -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 */ diff --git a/src/mme/mme_gtp_path.c b/src/mme/mme_gtp_path.c index 1086cc211..b1bb8054b 100644 --- a/src/mme/mme_gtp_path.c +++ b/src/mme/mme_gtp_path.c @@ -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; diff --git a/test/testpacket.c b/test/testpacket.c index 1f53b2db3..8f8a3e636 100644 --- a/test/testpacket.c +++ b/test/testpacket.c @@ -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;