diff --git a/ggsn/Makefile.am b/ggsn/Makefile.am index 022cdef..a8ddf1e 100644 --- a/ggsn/Makefile.am +++ b/ggsn/Makefile.am @@ -12,4 +12,4 @@ osmo_ggsn_LDADD += $(LIBGTPNL_LIBS) endif osmo_ggsn_DEPENDENCIES = ../gtp/libgtp.la ../lib/libmisc.a -osmo_ggsn_SOURCES = ggsn_vty.c ggsn.c ggsn.h icmpv6.c icmpv6.h checksum.c checksum.h pco.c pco.h +osmo_ggsn_SOURCES = ggsn_main.c ggsn_vty.c ggsn.c ggsn.h icmpv6.c icmpv6.h checksum.c checksum.h pco.c pco.h diff --git a/ggsn/ggsn.c b/ggsn/ggsn.c index 3c702c2..c7756d9 100644 --- a/ggsn/ggsn.c +++ b/ggsn/ggsn.c @@ -42,22 +42,8 @@ #include #include -#include -#include -#include -#include #include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include #include "../lib/tun.h" @@ -71,19 +57,9 @@ #include "pco.h" #include "ggsn.h" -void *tall_ggsn_ctx; - -static int end = 0; -static int daemonize = 0; -static struct ctrl_handle *g_ctrlh; - -struct ul255_t qos; -struct ul255_t apn; - static int ggsn_tun_fd_cb(struct osmo_fd *fd, unsigned int what); static int cb_tun_ind(struct tun_t *tun, void *pack, unsigned len); - static void pool_close_all_pdp(struct ippool_t *pool) { unsigned int i; @@ -690,8 +666,6 @@ static int encaps_tun(struct pdp_t *pdp, void *pack, unsigned len) return tun_encaps((struct tun_t *)pdp->ipif, pack, len); } -static char *config_file = "osmo-ggsn.cfg"; - /* callback for tun device osmocom select loop integration */ static int ggsn_tun_fd_cb(struct osmo_fd *fd, unsigned int what) { @@ -749,29 +723,6 @@ static void ggsn_gtp_tmr_cb(void *data) ggsn_gtp_tmr_start(ggsn); } -/* To exit gracefully. Used with GCC compilation flag -pg and gprof */ -static void signal_handler(int s) -{ - LOGP(DGGSN, LOGL_NOTICE, "signal %d received\n", s); - switch (s) { - case SIGINT: - case SIGTERM: - LOGP(DGGSN, LOGL_NOTICE, "SIGINT received, shutting down\n"); - end = 1; - break; - case SIGABRT: - case SIGUSR1: - talloc_report(tall_vty_ctx, stderr); - talloc_report_full(tall_ggsn_ctx, stderr); - break; - case SIGUSR2: - talloc_report_full(tall_vty_ctx, stderr); - break; - default: - break; - } -} - /* libgtp callback for confirmations */ static int cb_conf(int type, int cause, struct pdp_t *pdp, void *cbp) { @@ -882,128 +833,3 @@ int ggsn_stop(struct ggsn_ctx *ggsn) ggsn->started = false; return 0; } - -static void print_usage() -{ - printf("Usage: osmo-ggsn [-h] [-D] [-c configfile] [-V]\n"); -} - -static void print_help() -{ - printf( " Some useful help...\n" - " -h --help This help text\n" - " -D --daemonize Fork the process into a background daemon\n" - " -c --config-file filename The config file to use\n" - " -V --version Print the version of OsmoGGSN\n" - ); -} - -static void handle_options(int argc, char **argv) -{ - while (1) { - int option_index = 0, c; - static struct option long_options[] = { - { "help", 0, 0, 'h' }, - { "daemonize", 0, 0, 'D' }, - { "config-file", 1, 0, 'c' }, - { "version", 0, 0, 'V' }, - { 0, 0, 0, 0 } - }; - - c = getopt_long(argc, argv, "hdc:V", long_options, &option_index); - if (c == -1) - break; - - switch (c) { - case 'h': - print_usage(); - print_help(); - exit(0); - case 'D': - daemonize = 1; - break; - case 'c': - config_file = optarg; - break; - case 'V': - print_version(1); - exit(0); - break; - } - } -} - -int main(int argc, char **argv) -{ - struct ggsn_ctx *ggsn; - int rc; - - tall_ggsn_ctx = talloc_named_const(NULL, 0, "OsmoGGSN"); - msgb_talloc_ctx_init(tall_ggsn_ctx, 0); - g_vty_info.tall_ctx = tall_ggsn_ctx; - - /* Handle keyboard interrupt SIGINT */ - signal(SIGINT, &signal_handler); - signal(SIGTERM, &signal_handler); - signal(SIGABRT, &signal_handler); - signal(SIGUSR1, &signal_handler); - signal(SIGUSR2, &signal_handler); - - osmo_init_ignore_signals(); - osmo_init_logging2(tall_ggsn_ctx, &log_info); - osmo_stats_init(tall_ggsn_ctx); - - vty_init(&g_vty_info); - logging_vty_add_cmds(); - osmo_talloc_vty_add_cmds(); - osmo_stats_vty_add_cmds(); - ggsn_vty_init(); - ctrl_vty_init(tall_ggsn_ctx); - - handle_options(argc, argv); - - rate_ctr_init(tall_ggsn_ctx); - - rc = vty_read_config_file(config_file, NULL); - if (rc < 0) { - fprintf(stderr, "Failed to open config file: '%s'\n", config_file); - exit(2); - } - - rc = telnet_init_dynif(tall_ggsn_ctx, NULL, vty_get_bind_addr(), OSMO_VTY_PORT_GGSN); - if (rc < 0) - exit(1); - - g_ctrlh = ctrl_interface_setup_dynip(NULL, ctrl_vty_get_bind_addr(), - OSMO_CTRL_PORT_GGSN, NULL); - if (!g_ctrlh) { - LOGP(DGGSN, LOGL_ERROR, "Failed to create CTRL interface.\n"); - exit(1); - } - - if (daemonize) { - rc = osmo_daemonize(); - if (rc < 0) { - perror("Error during daemonize"); - exit(1); - } - } - -#if 0 - /* qos */ - qos.l = 3; - qos.v[2] = (args_info.qos_arg) & 0xff; - qos.v[1] = ((args_info.qos_arg) >> 8) & 0xff; - qos.v[0] = ((args_info.qos_arg) >> 16) & 0xff; -#endif - - /* Main select loop */ - while (!end) { - osmo_select_main(0); - } - - llist_for_each_entry(ggsn, &g_ggsn_list, list) - ggsn_stop(ggsn); - - return 0; -} diff --git a/ggsn/ggsn.h b/ggsn/ggsn.h index a37381f..1bd067e 100644 --- a/ggsn/ggsn.h +++ b/ggsn/ggsn.h @@ -6,6 +6,7 @@ #include #include #include +#include #include "../lib/tun.h" #include "../lib/ippool.h" @@ -135,8 +136,11 @@ struct ggsn_ctx *ggsn_find_or_create(void *ctx, const char *name); struct apn_ctx *ggsn_find_apn(struct ggsn_ctx *ggsn, const char *name); struct apn_ctx *ggsn_find_or_create_apn(struct ggsn_ctx *ggsn, const char *name); -/* ggsn.c */ +/* ggsn_main.c */ +extern struct ctrl_handle *g_ctrlh; extern void *tall_ggsn_ctx; + +/* ggsn.c */ extern int ggsn_start(struct ggsn_ctx *ggsn); extern int ggsn_stop(struct ggsn_ctx *ggsn); extern int apn_start(struct apn_ctx *apn); diff --git a/ggsn/ggsn_main.c b/ggsn/ggsn_main.c new file mode 100644 index 0000000..81a8ab1 --- /dev/null +++ b/ggsn/ggsn_main.c @@ -0,0 +1,208 @@ +/* + * OsmoGGSN - Gateway GPRS Support Node + * Copyright (C) 2002, 2003, 2004 Mondru AB. + * Copyright (C) 2017-2019 by Harald Welte + * Copyright (C) 2019 sysmocom - s.f.m.c. GmbH + * + * The contents of this file may be used under the terms of the GNU + * General Public License Version 2, provided that the above copyright + * notice and this permission notice is included in all copies or + * substantial portions of the software. + * + */ + +#include "../config.h" + +#ifdef HAVE_STDINT_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ggsn.h" + +void *tall_ggsn_ctx; + +static int end = 0; +static int daemonize = 0; +struct ctrl_handle *g_ctrlh; + +struct ul255_t qos; +struct ul255_t apn; + +static char *config_file = "osmo-ggsn.cfg"; + +/* To exit gracefully. Used with GCC compilation flag -pg and gprof */ +static void signal_handler(int s) +{ + LOGP(DGGSN, LOGL_NOTICE, "signal %d received\n", s); + switch (s) { + case SIGINT: + case SIGTERM: + LOGP(DGGSN, LOGL_NOTICE, "SIGINT received, shutting down\n"); + end = 1; + break; + case SIGABRT: + case SIGUSR1: + talloc_report(tall_vty_ctx, stderr); + talloc_report_full(tall_ggsn_ctx, stderr); + break; + case SIGUSR2: + talloc_report_full(tall_vty_ctx, stderr); + break; + default: + break; + } +} + +static void print_usage() +{ + printf("Usage: osmo-ggsn [-h] [-D] [-c configfile] [-V]\n"); +} + +static void print_help() +{ + printf( " Some useful help...\n" + " -h --help This help text\n" + " -D --daemonize Fork the process into a background daemon\n" + " -c --config-file filename The config file to use\n" + " -V --version Print the version of OsmoGGSN\n" + ); +} + +static void handle_options(int argc, char **argv) +{ + while (1) { + int option_index = 0, c; + static struct option long_options[] = { + { "help", 0, 0, 'h' }, + { "daemonize", 0, 0, 'D' }, + { "config-file", 1, 0, 'c' }, + { "version", 0, 0, 'V' }, + { 0, 0, 0, 0 } + }; + + c = getopt_long(argc, argv, "hdc:V", long_options, &option_index); + if (c == -1) + break; + + switch (c) { + case 'h': + print_usage(); + print_help(); + exit(0); + case 'D': + daemonize = 1; + break; + case 'c': + config_file = optarg; + break; + case 'V': + print_version(1); + exit(0); + break; + } + } +} + +int main(int argc, char **argv) +{ + struct ggsn_ctx *ggsn; + int rc; + + tall_ggsn_ctx = talloc_named_const(NULL, 0, "OsmoGGSN"); + msgb_talloc_ctx_init(tall_ggsn_ctx, 0); + g_vty_info.tall_ctx = tall_ggsn_ctx; + + /* Handle keyboard interrupt SIGINT */ + signal(SIGINT, &signal_handler); + signal(SIGTERM, &signal_handler); + signal(SIGABRT, &signal_handler); + signal(SIGUSR1, &signal_handler); + signal(SIGUSR2, &signal_handler); + + osmo_init_ignore_signals(); + osmo_init_logging2(tall_ggsn_ctx, &log_info); + osmo_stats_init(tall_ggsn_ctx); + + vty_init(&g_vty_info); + logging_vty_add_cmds(); + osmo_talloc_vty_add_cmds(); + osmo_stats_vty_add_cmds(); + ggsn_vty_init(); + ctrl_vty_init(tall_ggsn_ctx); + + handle_options(argc, argv); + + rate_ctr_init(tall_ggsn_ctx); + + rc = vty_read_config_file(config_file, NULL); + if (rc < 0) { + fprintf(stderr, "Failed to open config file: '%s'\n", config_file); + exit(2); + } + + rc = telnet_init_dynif(tall_ggsn_ctx, NULL, vty_get_bind_addr(), OSMO_VTY_PORT_GGSN); + if (rc < 0) + exit(1); + + g_ctrlh = ctrl_interface_setup_dynip(NULL, ctrl_vty_get_bind_addr(), + OSMO_CTRL_PORT_GGSN, NULL); + if (!g_ctrlh) { + LOGP(DGGSN, LOGL_ERROR, "Failed to create CTRL interface.\n"); + exit(1); + } + + if (daemonize) { + rc = osmo_daemonize(); + if (rc < 0) { + perror("Error during daemonize"); + exit(1); + } + } + +#if 0 + /* qos */ + qos.l = 3; + qos.v[2] = (args_info.qos_arg) & 0xff; + qos.v[1] = ((args_info.qos_arg) >> 8) & 0xff; + qos.v[0] = ((args_info.qos_arg) >> 16) & 0xff; +#endif + + /* Main select loop */ + while (!end) { + osmo_select_main(0); + } + + llist_for_each_entry(ggsn, &g_ggsn_list, list) + ggsn_stop(ggsn); + + return 0; +}