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.
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index 89db48b..ae6757d 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -440,5 +440,6 @@
 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 825a22e..9e1b3c2 100644
--- a/openbsc/src/libbsc/bts_ipaccess_nanobts.c
+++ b/openbsc/src/libbsc/bts_ipaccess_nanobts.c
@@ -551,6 +551,7 @@
 
 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 @@
 		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 73041fc..7cb1d38 100644
--- a/openbsc/src/libcommon/gsm_data.c
+++ b/openbsc/src/libcommon/gsm_data.c
@@ -388,7 +388,7 @@
 	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);