diff options
Diffstat (limited to 'openbsc/src/osmo-bsc')
-rw-r--r-- | openbsc/src/osmo-bsc/Makefile.am | 4 | ||||
-rw-r--r-- | openbsc/src/osmo-bsc/osmo_bsc_api.c | 91 | ||||
-rw-r--r-- | openbsc/src/osmo-bsc/osmo_bsc_main.c | 9 | ||||
-rw-r--r-- | openbsc/src/osmo-bsc/osmo_bsc_vty.c | 66 |
4 files changed, 166 insertions, 4 deletions
diff --git a/openbsc/src/osmo-bsc/Makefile.am b/openbsc/src/osmo-bsc/Makefile.am index 6248fcd6f..b4a2cba64 100644 --- a/openbsc/src/osmo-bsc/Makefile.am +++ b/openbsc/src/osmo-bsc/Makefile.am @@ -9,7 +9,9 @@ osmo_bsc_SOURCES = osmo_bsc_main.c osmo_bsc_vty.c osmo_bsc_api.c \ osmo_bsc_grace.c osmo_bsc_msc.c osmo_bsc_sccp.c \ osmo_bsc_filter.c osmo_bsc_bssap.c osmo_bsc_audio.c osmo_bsc_ctrl.c # once again since TRAU uses CC symbol :( -osmo_bsc_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ +osmo_bsc_LDADD = \ + $(top_builddir)/src/libfilter/libfilter.a \ + $(top_builddir)/src/libbsc/libbsc.a \ $(top_builddir)/src/libmsc/libmsc.a \ $(top_builddir)/src/libbsc/libbsc.a \ $(top_builddir)/src/libtrau/libtrau.a \ diff --git a/openbsc/src/osmo-bsc/osmo_bsc_api.c b/openbsc/src/osmo-bsc/osmo_bsc_api.c index 18b9607a0..5a01d6b82 100644 --- a/openbsc/src/osmo-bsc/osmo_bsc_api.c +++ b/openbsc/src/osmo-bsc/osmo_bsc_api.c @@ -1,4 +1,4 @@ -/* (C) 2009-2011 by Holger Hans Peter Freyther <zecke@selfish.org> +/* (C) 2009-2015 by Holger Hans Peter Freyther <zecke@selfish.org> * (C) 2009-2011 by On-Waves * All Rights Reserved * @@ -79,6 +79,69 @@ static uint16_t get_ci_for_msc(struct osmo_msc_data *msc, struct gsm_bts *bts) return bts->cell_identity; } +static void bsc_maybe_lu_reject(struct gsm_subscriber_connection *conn, int con_type, int cause) +{ + struct msgb *msg; + + /* ignore cm service request or such */ + if (con_type != FLT_CON_TYPE_LU) + return; + + msg = gsm48_create_loc_upd_rej(cause); + if (!msg) { + LOGP(DMM, LOGL_ERROR, "Failed to create msg for LOCATION UPDATING REJECT.\n"); + return; + } + + msg->lchan = conn->lchan; + gsm0808_submit_dtap(conn, msg, 0, 0); +} + +static int bsc_filter_initial(struct osmo_bsc_data *bsc, + struct osmo_msc_data *msc, + struct gsm_subscriber_connection *conn, + struct msgb *msg, char **imsi, int *con_type, + int *lu_cause) +{ + struct bsc_filter_request req; + struct bsc_filter_reject_cause cause; + struct gsm48_hdr *gh = msgb_l3(msg); + int rc; + + req.ctx = conn; + req.black_list = NULL; + req.access_lists = bsc_access_lists(); + req.local_lst_name = msc->acc_lst_name; + req.global_lst_name = conn->bts->network->bsc_data->acc_lst_name; + req.bsc_nr = 0; + + rc = bsc_msg_filter_initial(gh, msgb_l3len(msg), &req, + con_type, imsi, &cause); + *lu_cause = cause.lu_reject_cause; + return rc; +} + +static int bsc_filter_data(struct gsm_subscriber_connection *conn, + struct msgb *msg, int *lu_cause) +{ + struct bsc_filter_request req; + struct gsm48_hdr *gh = msgb_l3(msg); + struct bsc_filter_reject_cause cause; + int rc; + + req.ctx = conn; + req.black_list = NULL; + req.access_lists = bsc_access_lists(); + req.local_lst_name = conn->sccp_con->msc->acc_lst_name; + req.global_lst_name = conn->bts->network->bsc_data->acc_lst_name; + req.bsc_nr = 0; + + rc = bsc_msg_filter_data(gh, msgb_l3len(msg), &req, + &conn->sccp_con->filter_state, + &cause); + *lu_cause = cause.lu_reject_cause; + return rc; +} static void bsc_sapi_n_reject(struct gsm_subscriber_connection *conn, int dlci) { @@ -172,6 +235,8 @@ static int bsc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg static int complete_layer3(struct gsm_subscriber_connection *conn, struct msgb *msg, struct osmo_msc_data *msc) { + int con_type, rc, lu_cause; + char *imsi = NULL; struct timeval tv; struct msgb *resp; uint16_t network_code; @@ -189,6 +254,14 @@ static int complete_layer3(struct gsm_subscriber_connection *conn, if (send_ping && osmo_timer_remaining(&msc->ping_timer, NULL, &tv) == -1) send_ping = 0; + /* Check the filter */ + rc = bsc_filter_initial(msc->network->bsc_data, msc, conn, msg, + &imsi, &con_type, &lu_cause); + if (rc < 0) { + bsc_maybe_lu_reject(conn, con_type, lu_cause); + return BSC_API_CONN_POL_REJECT; + } + /* allocate resource for a new connection */ ret = bsc_create_new_connection(conn, msc, send_ping); @@ -202,6 +275,10 @@ static int complete_layer3(struct gsm_subscriber_connection *conn, return BSC_API_CONN_POL_REJECT; } + if (imsi) + conn->sccp_con->filter_state.imsi = talloc_steal(conn, imsi); + conn->sccp_con->filter_state.con_type = con_type; + /* check return value, if failed check msg for and send USSD */ network_code = get_network_code_for_msc(conn->sccp_con->msc); @@ -210,6 +287,7 @@ static int complete_layer3(struct gsm_subscriber_connection *conn, ci = get_ci_for_msc(conn->sccp_con->msc, conn->bts); bsc_scan_bts_msg(conn, msg); + resp = gsm0808_create_layer3(msg, network_code, country_code, lac, ci); if (!resp) { LOGP(DMSC, LOGL_DEBUG, "Failed to create layer3 message.\n"); @@ -320,6 +398,7 @@ static int handle_cc_setup(struct gsm_subscriber_connection *conn, static void bsc_dtap(struct gsm_subscriber_connection *conn, uint8_t link_id, struct msgb *msg) { + int lu_cause; struct msgb *resp; return_when_not_connected(conn); @@ -332,8 +411,16 @@ static void bsc_dtap(struct gsm_subscriber_connection *conn, uint8_t link_id, st if (handle_cc_setup(conn, msg) >= 1) return; - bsc_scan_bts_msg(conn, msg); + /* Check the filter */ + if (bsc_filter_data(conn, msg, &lu_cause) < 0) { + bsc_maybe_lu_reject(conn, + conn->sccp_con->filter_state.con_type, + lu_cause); + bsc_clear_request(conn, 0); + return; + } + bsc_scan_bts_msg(conn, msg); resp = gsm0808_create_dtap(msg, link_id); queue_msg_or_return(resp); diff --git a/openbsc/src/osmo-bsc/osmo_bsc_main.c b/openbsc/src/osmo-bsc/osmo_bsc_main.c index 5c3885575..ee86cb647 100644 --- a/openbsc/src/osmo-bsc/osmo_bsc_main.c +++ b/openbsc/src/osmo-bsc/osmo_bsc_main.c @@ -59,6 +59,12 @@ static const char *config_file = "openbsc.cfg"; static const char *rf_ctrl = NULL; extern const char *openbsc_copyright; static int daemonize = 0; +static struct llist_head access_lists; + +struct llist_head *bsc_access_lists(void) +{ + return &access_lists; +} static void print_usage() { @@ -196,6 +202,9 @@ int main(int argc, char **argv) vty_info.copyright = openbsc_copyright; vty_init(&vty_info); bsc_vty_init(&log_info); + bsc_msg_lst_vty_init(tall_bsc_ctx, &access_lists, BSC_NODE); + + INIT_LLIST_HEAD(&access_lists); /* parse options */ handle_options(argc, argv); diff --git a/openbsc/src/osmo-bsc/osmo_bsc_vty.c b/openbsc/src/osmo-bsc/osmo_bsc_vty.c index bbbba1cd2..06ad77d59 100644 --- a/openbsc/src/osmo-bsc/osmo_bsc_vty.c +++ b/openbsc/src/osmo-bsc/osmo_bsc_vty.c @@ -1,5 +1,5 @@ /* Osmo BSC VTY Configuration */ -/* (C) 2009-2014 by Holger Hans Peter Freyther +/* (C) 2009-2015 by Holger Hans Peter Freyther * (C) 2009-2014 by On-Waves * All Rights Reserved * @@ -24,6 +24,7 @@ #include <openbsc/vty.h> #include <openbsc/gsm_subscriber.h> #include <openbsc/debug.h> +#include <openbsc/bsc_msg_filter.h> #include <osmocom/core/talloc.h> #include <osmocom/vty/logging.h> @@ -175,6 +176,9 @@ static void write_msc(struct vty *vty, struct osmo_msc_data *msc) if (msc->local_pref) vty_out(vty, " local-prefix %s%s", msc->local_pref, VTY_NEWLINE); + if (msc->acc_lst_name) + vty_out(vty, " access-list-name %s%s", msc->acc_lst_name, VTY_NEWLINE); + /* write amr options */ write_msc_amr_options(vty, msc); } @@ -210,6 +214,8 @@ static int config_write_bsc(struct vty *vty) vty_out(vty, " missing-msc-text %s%s", bsc->ussd_no_msc_txt, VTY_NEWLINE); else vty_out(vty, " no missing-msc-text%s", VTY_NEWLINE); + if (bsc->acc_lst_name) + vty_out(vty, " access-list-name %s%s", bsc->acc_lst_name, VTY_NEWLINE); return CMD_SUCCESS; } @@ -625,6 +631,33 @@ AMR_COMMAND(5_90) AMR_COMMAND(5_15) AMR_COMMAND(4_75) +DEFUN(cfg_msc_acc_lst_name, + cfg_msc_acc_lst_name_cmd, + "access-list-name NAME", + "Set the name of the access list to use.\n" + "The name of the to be used access list.") +{ + struct osmo_msc_data *msc = osmo_msc_data(vty); + + bsc_replace_string(msc, &msc->acc_lst_name, argv[0]); + return CMD_SUCCESS; +} + +DEFUN(cfg_msc_no_acc_lst_name, + cfg_msc_no_acc_lst_name_cmd, + "no access-list-name", + NO_STR "Remove the access list from the NAT.\n") +{ + struct osmo_msc_data *msc = osmo_msc_data(vty); + + if (msc->acc_lst_name) { + talloc_free(msc->acc_lst_name); + msc->acc_lst_name = NULL; + } + + return CMD_SUCCESS; +} + DEFUN(cfg_net_bsc_mid_call_text, cfg_net_bsc_mid_call_text_cmd, "mid-call-text .TEXT", @@ -681,6 +714,33 @@ DEFUN(cfg_net_no_rf_off_time, return CMD_SUCCESS; } +DEFUN(cfg_bsc_acc_lst_name, + cfg_bsc_acc_lst_name_cmd, + "access-list-name NAME", + "Set the name of the access list to use.\n" + "The name of the to be used access list.") +{ + struct osmo_bsc_data *bsc = osmo_bsc_data(vty); + + bsc_replace_string(bsc, &bsc->acc_lst_name, argv[0]); + return CMD_SUCCESS; +} + +DEFUN(cfg_bsc_no_acc_lst_name, + cfg_bsc_no_acc_lst_name_cmd, + "no access-list-name", + NO_STR "Remove the access list from the BSC\n") +{ + struct osmo_bsc_data *bsc = osmo_bsc_data(vty); + + if (bsc->acc_lst_name) { + talloc_free(bsc->acc_lst_name); + bsc->acc_lst_name = NULL; + } + + return CMD_SUCCESS; +} + DEFUN(show_statistics, show_statistics_cmd, "show statistics", @@ -805,6 +865,8 @@ int bsc_vty_init_extra(void) install_element(BSC_NODE, &cfg_net_no_rf_off_time_cmd); install_element(BSC_NODE, &cfg_net_bsc_missing_msc_ussd_cmd); install_element(BSC_NODE, &cfg_net_bsc_no_missing_msc_text_cmd); + install_element(BSC_NODE, &cfg_bsc_acc_lst_name_cmd); + install_element(BSC_NODE, &cfg_bsc_no_acc_lst_name_cmd); install_node(&msc_node, config_write_msc); vty_install_default(MSC_NODE); @@ -839,6 +901,8 @@ int bsc_vty_init_extra(void) install_element(MSC_NODE, &cfg_net_msc_amr_5_90_cmd); install_element(MSC_NODE, &cfg_net_msc_amr_5_15_cmd); install_element(MSC_NODE, &cfg_net_msc_amr_4_75_cmd); + install_element(MSC_NODE, &cfg_msc_acc_lst_name_cmd); + install_element(MSC_NODE, &cfg_msc_no_acc_lst_name_cmd); install_element_ve(&show_statistics_cmd); install_element_ve(&show_mscs_cmd); |