aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <holger@moiji-mobile.com>2014-12-17 15:44:32 +0100
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2014-12-17 15:50:11 +0100
commitf7e23c5ff7d28c985d6c1e6d1dc0b9e8f5895a30 (patch)
tree2fb7a5fed1315f299ed37eb919d238a51c611246
parentc22930e24b8d61cecb1fa7c46fd5dc96355d4978 (diff)
bts: When one link drops.. check what needs to be dropped
In case a BTS is dropped, iterate over the list of BTS and check if a dependency is now missing and then drop the BTS. This check could lead to check of 256*256 checks (e.g. all BTS on each other in the chain and the master is being dropped). The performance aspect of it doesn't matter for our usecase. We expect to have pairs of BTS right now.
-rw-r--r--openbsc/include/openbsc/gsm_data.h1
-rw-r--r--openbsc/src/libbsc/bts_ipaccess_nanobts.c16
-rw-r--r--openbsc/src/libcommon/gsm_data.c2
3 files changed, 18 insertions, 1 deletions
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index 89db48b05..ae6757d7d 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -440,5 +440,6 @@ int msc_ctrl_cmds_install(void);
void bts_depend_mark(struct gsm_bts *bts, int dep);
void bts_depend_clear(struct gsm_bts *bts, int dep);
int bts_depend_check(struct gsm_bts *bts);
+int bts_depend_is_depedency(struct gsm_bts *base, struct gsm_bts *other);
#endif /* _GSM_DATA_H */
diff --git a/openbsc/src/libbsc/bts_ipaccess_nanobts.c b/openbsc/src/libbsc/bts_ipaccess_nanobts.c
index 825a22e2a..9e1b3c2cb 100644
--- a/openbsc/src/libbsc/bts_ipaccess_nanobts.c
+++ b/openbsc/src/libbsc/bts_ipaccess_nanobts.c
@@ -551,6 +551,7 @@ void ipaccess_drop_rsl(struct gsm_bts_trx *trx)
void ipaccess_drop_oml(struct gsm_bts *bts)
{
+ struct gsm_bts *rdep_bts;
struct gsm_bts_trx *trx;
if (!bts->oml_link)
@@ -564,6 +565,21 @@ void ipaccess_drop_oml(struct gsm_bts *bts)
ipaccess_drop_rsl(trx);
bts->ip_access.flags = 0;
+
+ /*
+ * Go through the list and see if we are the depndency of a BTS
+ * and then drop the BTS. This can lead to some recursion but it
+ * should be fine in userspace.
+ * The oml_link is serving as recursion anchor for us and
+ * it is set to NULL some lines above.
+ */
+ llist_for_each_entry(rdep_bts, &bts->network->bts_list, list) {
+ if (!bts_depend_is_depedency(rdep_bts, bts))
+ continue;
+ LOGP(DLINP, LOGL_NOTICE, "Dropping BTS(%u) due BTS(%u).\n",
+ rdep_bts->nr, bts->nr);
+ ipaccess_drop_oml(rdep_bts);
+ }
}
/* This function is called once the OML/RSL link becomes up. */
diff --git a/openbsc/src/libcommon/gsm_data.c b/openbsc/src/libcommon/gsm_data.c
index 73041fcec..7cb1d3814 100644
--- a/openbsc/src/libcommon/gsm_data.c
+++ b/openbsc/src/libcommon/gsm_data.c
@@ -388,7 +388,7 @@ void bts_depend_clear(struct gsm_bts *bts, int dep)
bts->depends_on[idx] &= ~(1 << bit);
}
-static int bts_depend_is_depedency(struct gsm_bts *base, struct gsm_bts *other)
+int bts_depend_is_depedency(struct gsm_bts *base, struct gsm_bts *other)
{
int idx, bit;
depends_calc_index_bit(other->nr, &idx, &bit);