aboutsummaryrefslogtreecommitdiffstats
path: root/src/sgsn/sgsn_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sgsn/sgsn_main.c')
-rw-r--r--src/sgsn/sgsn_main.c265
1 files changed, 117 insertions, 148 deletions
diff --git a/src/sgsn/sgsn_main.c b/src/sgsn/sgsn_main.c
index eef5f8f22..d6afdef52 100644
--- a/src/sgsn/sgsn_main.c
+++ b/src/sgsn/sgsn_main.c
@@ -39,15 +39,18 @@
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/stats.h>
+#include <osmocom/core/sockaddr_str.h>
-#include <osmocom/gprs/gprs_ns.h>
+#include <osmocom/gprs/gprs_ns2.h>
#include <osmocom/gprs/gprs_bssgp.h>
+#include <osmocom/gprs/gprs_bssgp_bss.h>
#include <osmocom/vty/telnet_interface.h>
#include <osmocom/vty/logging.h>
#include <osmocom/vty/stats.h>
#include <osmocom/vty/ports.h>
#include <osmocom/vty/misc.h>
+#include <osmocom/vty/cpu_sched_vty.h>
#include <osmocom/ctrl/control_vty.h>
@@ -56,15 +59,18 @@
#include <osmocom/sgsn/vty.h>
#include <osmocom/sgsn/sgsn.h>
#include <osmocom/sgsn/gprs_llc.h>
+#include <osmocom/sgsn/gprs_sndcp.h>
#include <osmocom/sgsn/gprs_gmm.h>
#include <osmocom/sgsn/gprs_ranap.h>
-
-#include <osmocom/ctrl/control_if.h>
-#include <osmocom/ctrl/ports.h>
+#include <osmocom/sgsn/gprs_ns.h>
+#include <osmocom/sgsn/gprs_bssgp.h>
+#include <osmocom/sgsn/gprs_subscriber.h>
+#include <osmocom/sgsn/gtp.h>
#include <gtp.h>
+#include <osmocom/sgsn/sgsn_rim.h>
-#include "../../bscconfig.h"
+#include "../../config.h"
#if BUILD_IU
#include <osmocom/sigtran/osmo_ss7.h>
@@ -76,9 +82,8 @@
#include <getopt.h>
void *tall_sgsn_ctx;
-struct ctrl_handle *g_ctrlh;
-struct gprs_ns_inst *sgsn_nsi;
+struct gprs_ns2_inst *sgsn_nsi;
static int daemonize = 0;
const char *openbsc_copyright =
"Copyright (C) 2010 Harald Welte and On-Waves\r\n"
@@ -92,60 +97,18 @@ const char *openbsc_copyright =
struct sgsn_instance *sgsn;
-/* call-back function for the NS protocol */
-static int sgsn_ns_cb(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
- struct msgb *msg, uint16_t bvci)
-{
- int rc = 0;
-
- switch (event) {
- case GPRS_NS_EVT_UNIT_DATA:
- /* hand the message into the BSSGP implementation */
- rc = bssgp_rcvmsg(msg);
- break;
- default:
- LOGP(DGPRS, LOGL_ERROR, "SGSN: Unknown event %u from NS\n", event);
- if (msg)
- msgb_free(msg);
- rc = -EIO;
- break;
- }
- return rc;
-}
-
-/* call-back function for the BSSGP protocol */
+/* call-back function for the BSSGP protocol.
+ * Must be left here so that we can add a new one in tests/sgsn_test */
int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
{
- struct osmo_bssgp_prim *bp;
- bp = container_of(oph, struct osmo_bssgp_prim, oph);
-
- switch (oph->sap) {
- case SAP_BSSGP_LL:
- switch (oph->primitive) {
- case PRIM_BSSGP_UL_UD:
- return gprs_llc_rcvmsg(oph->msg, bp->tp);
- }
- break;
- case SAP_BSSGP_GMM:
- switch (oph->primitive) {
- case PRIM_BSSGP_GMM_SUSPEND:
- return gprs_gmm_rx_suspend(bp->ra_id, bp->tlli);
- case PRIM_BSSGP_GMM_RESUME:
- return gprs_gmm_rx_resume(bp->ra_id, bp->tlli,
- bp->u.resume.suspend_ref);
- }
- break;
- case SAP_BSSGP_NM:
- break;
- }
- return 0;
+ return sgsn_bssgp_rx_prim(oph);
}
-static void signal_handler(int signal)
+static void signal_handler(int signum)
{
- fprintf(stdout, "signal %u received\n", signal);
+ fprintf(stdout, "signal %u received\n", signum);
- switch (signal) {
+ switch (signum) {
case SIGINT:
case SIGTERM:
osmo_signal_dispatch(SS_L_GLOBAL, S_L_GLOBAL_SHUTDOWN, NULL);
@@ -153,8 +116,17 @@ static void signal_handler(int signal)
exit(0);
break;
case SIGABRT:
- /* in case of abort, we want to obtain a talloc report
- * and then return to the caller, who will abort the process */
+ /* in case of abort, we want to obtain a talloc report and
+ * then run default SIGABRT handler, who will generate coredump
+ * and abort the process. abort() should do this for us after we
+ * return, but program wouldn't exit if an external SIGABRT is
+ * received.
+ */
+ talloc_report(tall_vty_ctx, stderr);
+ talloc_report_full(tall_sgsn_ctx, stderr);
+ signal(SIGABRT, SIG_DFL);
+ raise(SIGABRT);
+ break;
case SIGUSR1:
talloc_report(tall_vty_ctx, stderr);
talloc_report_full(tall_sgsn_ctx, stderr);
@@ -167,43 +139,36 @@ static void signal_handler(int signal)
}
}
-/* NSI that BSSGP uses when transmitting on NS */
-extern struct gprs_ns_inst *bssgp_nsi;
-
-int sgsn_vty_is_config_node(struct vty *vty, int node)
+static int sgsn_vty_go_parent(struct vty *vty)
{
- /* So far the SGSN has no nested nodes that need parent node
- * declaration, except for the ss7 vty nodes. */
- switch (node) {
+ switch (vty->node) {
case SGSN_NODE:
- return 1;
+ vty->node = CONFIG_NODE;
+ break;
+ case MME_NODE:
+ vty->node = SGSN_NODE;
+ vty->index = NULL;
+ break;
default:
#if BUILD_IU
- return osmo_ss7_is_config_node(vty, node);
+ osmo_ss7_vty_go_parent(vty);
#else
- return 0;
+ vty->node = CONFIG_NODE;
+ vty->index = NULL;
#endif
+ break;
}
-}
-int sgsn_vty_go_parent(struct vty *vty)
-{
- /* So far the SGSN has no nested nodes that need parent node
- * declaration, except for the ss7 vty nodes. */
-#if BUILD_IU
- return osmo_ss7_vty_go_parent(vty);
-#else
- vty->node = CONFIG_NODE;
- vty->index = NULL;
- return 0;
-#endif
+ return vty->node;
}
+/* NSI that BSSGP uses when transmitting on NS */
+extern struct gprs_ns_inst *bssgp_nsi;
+
static struct vty_app_info vty_info = {
.name = "OsmoSGSN",
.version = PACKAGE_VERSION,
.go_parent_cb = sgsn_vty_go_parent,
- .is_config_node = sgsn_vty_is_config_node,
};
static void print_help(void)
@@ -216,12 +181,43 @@ static void print_help(void)
printf(" -s --disable-color\n");
printf(" -c --config-file\tThe config file to use [%s]\n", CONFIG_FILE_DEFAULT);
printf(" -e --log-level number\tSet a global log level\n");
+
+ printf("\nVTY reference generation:\n");
+ printf(" --vty-ref-mode MODE VTY reference generation mode (e.g. 'expert').\n");
+ printf(" --vty-ref-xml Generate the VTY reference XML output and exit.\n");
}
+static void handle_long_options(const char *prog_name, const int long_option)
+{
+ static int vty_ref_mode = VTY_REF_GEN_MODE_DEFAULT;
+
+ switch (long_option) {
+ case 1:
+ vty_ref_mode = get_string_value(vty_ref_gen_mode_names, optarg);
+ if (vty_ref_mode < 0) {
+ fprintf(stderr, "%s: Unknown VTY reference generation "
+ "mode '%s'\n", prog_name, optarg);
+ exit(2);
+ }
+ break;
+ case 2:
+ fprintf(stderr, "Generating the VTY reference in mode '%s' (%s)\n",
+ get_value_string(vty_ref_gen_mode_names, vty_ref_mode),
+ get_value_string(vty_ref_gen_mode_desc, vty_ref_mode));
+ vty_dump_xml_ref_mode(stdout, (enum vty_ref_gen_mode) vty_ref_mode);
+ exit(0);
+ default:
+ fprintf(stderr, "%s: error parsing cmdline options\n", prog_name);
+ exit(2);
+ }
+}
+
+
static void handle_options(int argc, char **argv)
{
while (1) {
int option_index = 0, c;
+ static int long_option = 0;
static struct option long_options[] = {
{"help", 0, 0, 'h'},
{"debug", 1, 0, 'd'},
@@ -231,6 +227,8 @@ static void handle_options(int argc, char **argv)
{"timestamp", 0, 0, 'T'},
{ "version", 0, 0, 'V' },
{"log-level", 1, 0, 'e'},
+ {"vty-ref-mode", 1, &long_option, 1},
+ {"vty-ref-xml", 0, &long_option, 2},
{NULL, 0, 0, 0}
};
@@ -240,6 +238,9 @@ static void handle_options(int argc, char **argv)
break;
switch (c) {
+ case 0:
+ handle_long_options(argv[0], long_option);
+ break;
case 'h':
//print_usage();
print_help();
@@ -271,6 +272,11 @@ static void handle_options(int argc, char **argv)
break;
}
}
+
+ if (argc > optind) {
+ fprintf(stderr, "Unsupported positional arguments on command line\n");
+ exit(2);
+ }
}
/* default categories */
@@ -302,16 +308,6 @@ static struct log_info_cat gprs_categories[] = {
.description = "GPRS Packet Service",
.enabled = 1, .loglevel = LOGL_NOTICE,
},
- [DNS] = {
- .name = "DNS",
- .description = "GPRS Network Service (NS)",
- .enabled = 1, .loglevel = LOGL_NOTICE,
- },
- [DBSSGP] = {
- .name = "DBSSGP",
- .description = "GPRS BSS Gateway Protocol (BSSGP)",
- .enabled = 1, .loglevel = LOGL_NOTICE,
- },
[DLLC] = {
.name = "DLLC",
.description = "GPRS Logical Link Control Protocol (LLC)",
@@ -347,6 +343,11 @@ static struct log_info_cat gprs_categories[] = {
.description = "GPRS Tunnelling Protocol (GTP)",
.enabled = 1, .loglevel = LOGL_NOTICE,
},
+ [DRIM] = {
+ .name = "DRIM",
+ .description = "RAN Information Management (RIM)",
+ .enabled = 1, .loglevel = LOGL_NOTICE,
+ },
};
static const struct log_info gprs_log_info = {
@@ -391,13 +392,32 @@ int main(int argc, char **argv)
osmo_stats_vty_add_cmds();
sgsn_vty_init(&sgsn->cfg);
ctrl_vty_init(tall_sgsn_ctx);
+ osmo_cpu_sched_vty_init(tall_sgsn_ctx);
#if BUILD_IU
- osmo_ss7_init();
+ OSMO_ASSERT(osmo_ss7_init() == 0);
osmo_ss7_vty_init_asp(tall_sgsn_ctx);
osmo_sccp_vty_init();
#endif
+ rate_ctr_init(tall_sgsn_ctx);
+
+ logging_vty_add_deprecated_subsys(tall_sgsn_ctx, "bssgp");
+ logging_vty_add_deprecated_subsys(tall_sgsn_ctx, "ns");
+
+ sgsn_nsi = gprs_ns2_instantiate(tall_sgsn_ctx, &gprs_ns_prim_cb, NULL);
+ if (!sgsn_nsi) {
+ LOGP(DGPRS, LOGL_ERROR, "Unable to instantiate NS\n");
+ exit(1);
+ }
+ sgsn->cfg.nsi = sgsn_nsi;
+ bssgp_set_bssgp_callback(sgsn_bssgp_dispatch_ns_unitdata_req_cb, sgsn_nsi);
+
+ gprs_ns2_vty_init(sgsn_nsi);
+ bssgp_vty_init();
+ gprs_llc_vty_init();
+ gprs_sndcp_vty_init();
+
handle_options(argc, argv);
/* Backwards compatibility: for years, the default config file name was
@@ -415,30 +435,6 @@ int main(int argc, char **argv)
osmo_talloc_replace_string(sgsn, &sgsn->config_file, CONFIG_FILE_DEFAULT);
}
- rate_ctr_init(tall_sgsn_ctx);
-
- gprs_ns_set_log_ss(DNS);
- bssgp_set_log_ss(DBSSGP);
-
- sgsn_nsi = gprs_ns_instantiate(&sgsn_ns_cb, tall_sgsn_ctx);
- if (!sgsn_nsi) {
- LOGP(DGPRS, LOGL_ERROR, "Unable to instantiate NS\n");
- exit(1);
- }
- bssgp_nsi = sgsn->cfg.nsi = sgsn_nsi;
-
- gprs_llc_init("/usr/local/lib/osmocom/crypt/");
- sgsn_rate_ctr_init();
- sgsn_inst_init(sgsn);
-
- gprs_ns_vty_init(bssgp_nsi);
- bssgp_vty_init();
- gprs_llc_vty_init();
- gprs_sndcp_vty_init();
- sgsn_auth_init(sgsn);
- sgsn_cdr_init(sgsn);
- /* FIXME: register signal handler for SS_L_NS */
-
rc = sgsn_parse_config(sgsn->config_file);
if (rc < 0) {
LOGP(DGPRS, LOGL_FATAL, "Error in config file\n");
@@ -446,25 +442,11 @@ int main(int argc, char **argv)
}
/* start telnet after reading config for vty_get_bind_addr() */
- rc = telnet_init_dynif(tall_sgsn_ctx, NULL,
- vty_get_bind_addr(), OSMO_VTY_PORT_SGSN);
+ rc = telnet_init_default(tall_sgsn_ctx, NULL, OSMO_VTY_PORT_SGSN);
if (rc < 0)
exit(1);
- /* start control interface after reading config for
- * ctrl_vty_get_bind_addr() */
- g_ctrlh = ctrl_interface_setup_dynip(NULL, ctrl_vty_get_bind_addr(),
- OSMO_CTRL_PORT_SGSN, NULL);
- if (!g_ctrlh) {
- LOGP(DGPRS, LOGL_ERROR, "Failed to create CTRL interface.\n");
- exit(1);
- }
-
- if (sgsn_ctrl_cmds_install() != 0) {
- LOGP(DGPRS, LOGL_ERROR, "Failed to install CTRL commands.\n");
- exit(1);
- }
-
+ gprs_llc_init(sgsn->cfg.crypt_cipher_plugin_path);
rc = sgsn_gtp_init(sgsn);
if (rc) {
@@ -473,22 +455,9 @@ int main(int argc, char **argv)
} else
LOGP(DGPRS, LOGL_NOTICE, "libGTP v%s initialized\n", gtp_version());
- rc = gprs_subscr_init(sgsn);
- if (rc < 0) {
- LOGP(DGPRS, LOGL_FATAL, "Cannot set up subscriber management\n");
- exit(2);
- }
-
- rc = gprs_ns_nsip_listen(sgsn_nsi);
- if (rc < 0) {
- LOGP(DGPRS, LOGL_FATAL, "Cannot bind/listen on NSIP socket\n");
- exit(2);
- }
-
- rc = gprs_ns_frgre_listen(sgsn_nsi);
+ rc = sgsn_inst_init(sgsn);
if (rc < 0) {
- LOGP(DGPRS, LOGL_FATAL, "Cannot bind/listen GRE "
- "socket. Do you have CAP_NET_RAW?\n");
+ LOGP(DGPRS, LOGL_FATAL, "Cannot set up SGSN\n");
exit(2);
}
@@ -507,8 +476,8 @@ int main(int argc, char **argv)
"OsmoSGSN",
(23 << 3) + 4,
OSMO_SS7_ASP_PROT_M3UA,
- 0, NULL,
- 0, "127.0.0.1");
+ 0, "localhost",
+ 0, "localhost");
if (!sccp) {
printf("Setting up SCCP client failed.\n");
return 8;