blob: d9fb4e6fedf583b0a1b0151d76a4b0108b8f5ed6 [file] [log] [blame]
Pau Espin Pedrol421f22e2019-08-20 12:52:13 +02001/*
2 * OsmoGGSN - Gateway GPRS Support Node
3 * Copyright (C) 2002, 2003, 2004 Mondru AB.
4 * Copyright (C) 2017-2019 by Harald Welte <laforge@gnumonks.org>
5 * Copyright (C) 2019 sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
6 *
7 * The contents of this file may be used under the terms of the GNU
8 * General Public License Version 2, provided that the above copyright
9 * notice and this permission notice is included in all copies or
10 * substantial portions of the software.
11 *
12 */
13
14#include "../config.h"
15
16#ifdef HAVE_STDINT_H
17#include <stdint.h>
18#endif
19
20#include <getopt.h>
21#include <ctype.h>
22#include <signal.h>
23#include <stdio.h>
24#include <string.h>
25#include <stdlib.h>
26#include <unistd.h>
27#include <inttypes.h>
28#include <errno.h>
29#include <sys/types.h>
30#include <sys/ioctl.h>
31
32#include <osmocom/core/application.h>
33#include <osmocom/core/select.h>
34#include <osmocom/core/stats.h>
35#include <osmocom/core/rate_ctr.h>
36#include <osmocom/core/timer.h>
37#include <osmocom/core/utils.h>
38#include <osmocom/ctrl/control_if.h>
39#include <osmocom/ctrl/control_cmd.h>
40#include <osmocom/ctrl/control_vty.h>
41#include <osmocom/ctrl/ports.h>
42#include <osmocom/vty/telnet_interface.h>
43#include <osmocom/vty/logging.h>
44#include <osmocom/vty/stats.h>
45#include <osmocom/vty/ports.h>
46#include <osmocom/vty/command.h>
47#include <osmocom/vty/misc.h>
Pau Espin Pedrolaedae4c2020-08-18 12:44:54 +020048#include <osmocom/vty/cpu_sched_vty.h>
Pau Espin Pedrol421f22e2019-08-20 12:52:13 +020049
50#include "ggsn.h"
51
52void *tall_ggsn_ctx;
53
54static int end = 0;
55static int daemonize = 0;
56struct ctrl_handle *g_ctrlh;
57
58struct ul255_t qos;
59struct ul255_t apn;
60
61static char *config_file = "osmo-ggsn.cfg";
62
63/* To exit gracefully. Used with GCC compilation flag -pg and gprof */
64static void signal_handler(int s)
65{
66 LOGP(DGGSN, LOGL_NOTICE, "signal %d received\n", s);
67 switch (s) {
68 case SIGINT:
69 case SIGTERM:
70 LOGP(DGGSN, LOGL_NOTICE, "SIGINT received, shutting down\n");
71 end = 1;
72 break;
73 case SIGABRT:
74 case SIGUSR1:
75 talloc_report(tall_vty_ctx, stderr);
76 talloc_report_full(tall_ggsn_ctx, stderr);
77 break;
78 case SIGUSR2:
79 talloc_report_full(tall_vty_ctx, stderr);
80 break;
81 default:
82 break;
83 }
84}
85
86static void print_usage()
87{
88 printf("Usage: osmo-ggsn [-h] [-D] [-c configfile] [-V]\n");
89}
90
91static void print_help()
92{
93 printf( " Some useful help...\n"
94 " -h --help This help text\n"
95 " -D --daemonize Fork the process into a background daemon\n"
96 " -c --config-file filename The config file to use\n"
97 " -V --version Print the version of OsmoGGSN\n"
98 );
99}
100
101static void handle_options(int argc, char **argv)
102{
103 while (1) {
104 int option_index = 0, c;
105 static struct option long_options[] = {
106 { "help", 0, 0, 'h' },
107 { "daemonize", 0, 0, 'D' },
108 { "config-file", 1, 0, 'c' },
109 { "version", 0, 0, 'V' },
110 { 0, 0, 0, 0 }
111 };
112
113 c = getopt_long(argc, argv, "hdc:V", long_options, &option_index);
114 if (c == -1)
115 break;
116
117 switch (c) {
118 case 'h':
119 print_usage();
120 print_help();
121 exit(0);
122 case 'D':
123 daemonize = 1;
124 break;
125 case 'c':
126 config_file = optarg;
127 break;
128 case 'V':
129 print_version(1);
130 exit(0);
131 break;
132 }
133 }
134}
135
136int main(int argc, char **argv)
137{
138 struct ggsn_ctx *ggsn;
139 int rc;
140
141 tall_ggsn_ctx = talloc_named_const(NULL, 0, "OsmoGGSN");
142 msgb_talloc_ctx_init(tall_ggsn_ctx, 0);
143 g_vty_info.tall_ctx = tall_ggsn_ctx;
144
145 /* Handle keyboard interrupt SIGINT */
146 signal(SIGINT, &signal_handler);
147 signal(SIGTERM, &signal_handler);
148 signal(SIGABRT, &signal_handler);
149 signal(SIGUSR1, &signal_handler);
150 signal(SIGUSR2, &signal_handler);
151
152 osmo_init_ignore_signals();
153 osmo_init_logging2(tall_ggsn_ctx, &log_info);
154 osmo_stats_init(tall_ggsn_ctx);
155
156 vty_init(&g_vty_info);
157 logging_vty_add_cmds();
158 osmo_talloc_vty_add_cmds();
159 osmo_stats_vty_add_cmds();
160 ggsn_vty_init();
161 ctrl_vty_init(tall_ggsn_ctx);
Pau Espin Pedrolaedae4c2020-08-18 12:44:54 +0200162 osmo_cpu_sched_vty_init(tall_ggsn_ctx);
Pau Espin Pedrol421f22e2019-08-20 12:52:13 +0200163
164 handle_options(argc, argv);
165
166 rate_ctr_init(tall_ggsn_ctx);
167
168 rc = vty_read_config_file(config_file, NULL);
169 if (rc < 0) {
170 fprintf(stderr, "Failed to open config file: '%s'\n", config_file);
171 exit(2);
172 }
173
174 rc = telnet_init_dynif(tall_ggsn_ctx, NULL, vty_get_bind_addr(), OSMO_VTY_PORT_GGSN);
175 if (rc < 0)
176 exit(1);
177
178 g_ctrlh = ctrl_interface_setup_dynip(NULL, ctrl_vty_get_bind_addr(),
179 OSMO_CTRL_PORT_GGSN, NULL);
180 if (!g_ctrlh) {
181 LOGP(DGGSN, LOGL_ERROR, "Failed to create CTRL interface.\n");
182 exit(1);
183 }
184
185 if (daemonize) {
186 rc = osmo_daemonize();
187 if (rc < 0) {
188 perror("Error during daemonize");
189 exit(1);
190 }
191 }
192
193#if 0
194 /* qos */
195 qos.l = 3;
196 qos.v[2] = (args_info.qos_arg) & 0xff;
197 qos.v[1] = ((args_info.qos_arg) >> 8) & 0xff;
198 qos.v[0] = ((args_info.qos_arg) >> 16) & 0xff;
199#endif
200
201 /* Main select loop */
202 while (!end) {
203 osmo_select_main(0);
204 }
205
206 llist_for_each_entry(ggsn, &g_ggsn_list, list)
207 ggsn_stop(ggsn);
208
209 return 0;
210}