aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/osmocom/bsc/gsm_data.h11
-rw-r--r--src/osmo-bsc/bsc_init.c1
-rw-r--r--src/osmo-bsc/bsc_vty.c28
-rw-r--r--src/osmo-bsc/bts_ipaccess_nanobts.c56
4 files changed, 92 insertions, 4 deletions
diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h
index 7c91e5982..7897fea86 100644
--- a/include/osmocom/bsc/gsm_data.h
+++ b/include/osmocom/bsc/gsm_data.h
@@ -1129,6 +1129,16 @@ struct gsm_bts {
uint8_t chan_load_avg; /* current channel load average in percent (0 - 100). */
};
+/* One rejected BTS */
+struct gsm_bts_rejected {
+ /* list header in net->bts_rejected */
+ struct llist_head list;
+
+ uint16_t site_id;
+ uint16_t bts_id;
+ char ip[INET6_ADDRSTRLEN];
+ time_t time;
+};
struct gsm_network *gsm_network_init(void *ctx);
@@ -1404,6 +1414,7 @@ struct gsm_network {
unsigned int num_bts;
struct llist_head bts_list;
+ struct llist_head bts_rejected;
/* shall reference gsm_network_T[] */
struct T_def *T_defs;
diff --git a/src/osmo-bsc/bsc_init.c b/src/osmo-bsc/bsc_init.c
index b1388b8cf..2f44b200a 100644
--- a/src/osmo-bsc/bsc_init.c
+++ b/src/osmo-bsc/bsc_init.c
@@ -257,6 +257,7 @@ static struct gsm_network *bsc_network_init(void *ctx)
return NULL;
}
+ INIT_LLIST_HEAD(&net->bts_rejected);
gsm_net_update_ctype(net);
/*
diff --git a/src/osmo-bsc/bsc_vty.c b/src/osmo-bsc/bsc_vty.c
index dd540c12f..410cdac15 100644
--- a/src/osmo-bsc/bsc_vty.c
+++ b/src/osmo-bsc/bsc_vty.c
@@ -541,6 +541,33 @@ DEFUN(show_bts, show_bts_cmd, "show bts [<0-255>]",
return CMD_SUCCESS;
}
+DEFUN(show_rejected_bts, show_rejected_bts_cmd, "show rejected-bts",
+ SHOW_STR "Display recently rejected BTS devices\n")
+{
+ struct gsm_bts_rejected *pos;
+
+ /* empty list */
+ struct llist_head *rejected = &gsmnet_from_vty(vty)->bts_rejected;
+ if (llist_empty(rejected)) {
+ vty_out(vty, "No BTS has been rejected.%s", VTY_NEWLINE);
+ return CMD_SUCCESS;
+ }
+
+ /* table head */
+ vty_out(vty, "Date Site ID BTS ID IP%s", VTY_NEWLINE);
+ vty_out(vty, "------------------- ------- ------ ---------------%s", VTY_NEWLINE);
+
+ /* table body */
+ llist_for_each_entry(pos, rejected, list) {
+ /* timestamp formatted like: "2018-10-24 15:04:52" */
+ char buf[20];
+ strftime(buf, sizeof(buf), "%F %T", localtime(&pos->time));
+
+ vty_out(vty, "%s %7u %6u %15s%s", buf, pos->site_id, pos->bts_id, pos->ip, VTY_NEWLINE);
+ }
+ return CMD_SUCCESS;
+}
+
/* utility functions */
static void parse_e1_link(struct gsm_e1_subslot *e1_link, const char *line,
const char *ts, const char *ss)
@@ -4867,6 +4894,7 @@ int bsc_vty_init(struct gsm_network *network)
install_element_ve(&bsc_show_net_cmd);
install_element_ve(&show_bts_cmd);
+ install_element_ve(&show_rejected_bts_cmd);
install_element_ve(&show_trx_cmd);
install_element_ve(&show_ts_cmd);
install_element_ve(&show_lchan_cmd);
diff --git a/src/osmo-bsc/bts_ipaccess_nanobts.c b/src/osmo-bsc/bts_ipaccess_nanobts.c
index fec4147e0..40cabb8a5 100644
--- a/src/osmo-bsc/bts_ipaccess_nanobts.c
+++ b/src/osmo-bsc/bts_ipaccess_nanobts.c
@@ -30,6 +30,7 @@
#include <osmocom/abis/e1_input.h>
#include <osmocom/gsm/tlv.h>
#include <osmocom/core/msgb.h>
+#include <osmocom/core/socket.h>
#include <osmocom/core/talloc.h>
#include <osmocom/bsc/gsm_data.h>
#include <osmocom/bsc/abis_nm.h>
@@ -458,6 +459,56 @@ void ipaccess_drop_oml_deferred(struct gsm_bts *bts)
}
}
+/* Reject BTS because of an unknown unit ID */
+static void ipaccess_sign_link_reject(const struct ipaccess_unit *dev, const struct e1inp_ts* ts)
+{
+ uint16_t site_id = dev->site_id;
+ uint16_t bts_id = dev->bts_id;
+ uint16_t trx_id = dev->trx_id;
+ char ip[INET6_ADDRSTRLEN];
+ struct gsm_bts_rejected *entry = NULL;
+ struct gsm_bts_rejected *pos;
+
+ /* Write to log and increase counter */
+ LOGP(DLINP, LOGL_ERROR, "Unable to find BTS configuration for %u/%u/%u, disconnecting\n", site_id, bts_id,
+ trx_id);
+ rate_ctr_inc(&bsc_gsmnet->bsc_ctrs->ctr[BSC_CTR_UNKNOWN_UNIT_ID]);
+
+ /* Get remote IP */
+ if (osmo_sock_get_remote_ip(ts->driver.ipaccess.fd.fd, ip, sizeof(ip)))
+ return;
+
+ /* Rejected list: unlink existing entry */
+ llist_for_each_entry(pos, &bsc_gsmnet->bts_rejected, list) {
+ if (pos->site_id == site_id && pos->bts_id == bts_id && !strcmp(pos->ip, ip)) {
+ entry = pos;
+ llist_del(&entry->list);
+ break;
+ }
+ }
+
+ /* Allocate new entry */
+ if (!entry) {
+ entry = talloc_zero(tall_bsc_ctx, struct gsm_bts_rejected);
+ if (!entry)
+ return;
+ entry->site_id = site_id;
+ entry->bts_id = bts_id;
+ strncpy(entry->ip, ip, sizeof(entry->ip));
+ }
+
+ /* Add to beginning with current timestamp */
+ llist_add(&entry->list, &bsc_gsmnet->bts_rejected);
+ entry->time = time(NULL);
+
+ /* Cut off last (oldest) element if we have too many */
+ if (llist_count(&bsc_gsmnet->bts_rejected) > 25) {
+ pos = llist_last_entry(&bsc_gsmnet->bts_rejected, struct gsm_bts_rejected, list);
+ llist_del(&pos->list);
+ talloc_free(pos);
+ }
+}
+
/* This function is called once the OML/RSL link becomes up. */
static struct e1inp_sign_link *
ipaccess_sign_link_up(void *unit_data, struct e1inp_line *line,
@@ -471,10 +522,7 @@ ipaccess_sign_link_up(void *unit_data, struct e1inp_line *line,
bts = find_bts_by_unitid(bsc_gsmnet, dev->site_id, dev->bts_id);
if (!bts) {
- LOGP(DLINP, LOGL_ERROR, "Unable to find BTS configuration for "
- " %u/%u/%u, disconnecting\n", dev->site_id,
- dev->bts_id, dev->trx_id);
- rate_ctr_inc(&bsc_gsmnet->bsc_ctrs->ctr[BSC_CTR_UNKNOWN_UNIT_ID]);
+ ipaccess_sign_link_reject(dev, &line->ts[E1INP_SIGN_OML - 1]);
return NULL;
}
DEBUGP(DLINP, "Identified BTS %u/%u/%u\n",