diff options
Diffstat (limited to 'src/sgsn/sgsn_main.c')
-rw-r--r-- | src/sgsn/sgsn_main.c | 265 |
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; |