ns2: delay NS_AFF_CAUSE_RECOVERY until NS-VC for data + sig are unblocked
Right now we end up in situations where only a NS-VC for data (BVCI != 0)
becomes unblocked, but the BSSGP and/or user application code is
notified that the NSE has recovered.
In the case of osmo-gbproxy, this will trigger a BVC-RESET on the
BVCI=0, but that obviously only works if the sig_weight > 0...
Closes: OS#4956
Change-Id: I933ee3969c052394d61ec6cf8c7c21d17957d9ab
diff --git a/src/gb/gprs_ns2.c b/src/gb/gprs_ns2.c
index 7c517aa..dc8ad8e 100644
--- a/src/gb/gprs_ns2.c
+++ b/src/gb/gprs_ns2.c
@@ -1121,13 +1121,18 @@
void ns2_nse_data_sum(struct gprs_ns2_nse *nse)
{
struct gprs_ns2_vc *nsvc;
+
nse->nsvc_count = 0;
+ nse->sum_data_weight = 0;
+ nse->sum_sig_weight = 0;
llist_for_each_entry(nsvc, &nse->nsvc, list) {
if (!gprs_ns2_vc_is_unblocked(nsvc))
continue;
nse->nsvc_count++;
+ nse->sum_data_weight += nsvc->data_weight;
+ nse->sum_sig_weight += nsvc->sig_weight;
}
}
@@ -1137,35 +1142,25 @@
void ns2_nse_notify_unblocked(struct gprs_ns2_vc *nsvc, bool unblocked)
{
struct gprs_ns2_nse *nse = nsvc->nse;
- struct gprs_ns2_vc *tmp;
ns2_nse_data_sum(nse);
if (unblocked == nse->alive)
return;
- if (unblocked) {
- /* this is the first unblocked NSVC on an unavailable NSE */
+ /* wait until both data_weight and sig_weight are != 0 before declaring NSE as alive */
+ if (unblocked && nse->sum_data_weight && nse->sum_sig_weight) {
nse->alive = true;
ns2_prim_status_ind(nse, NULL, 0, NS_AFF_CAUSE_RECOVERY);
nse->first = false;
return;
}
- /* check if there are any remaining alive vcs */
- llist_for_each_entry(tmp, &nse->nsvc, list) {
- if (tmp == nsvc)
- continue;
-
- if (gprs_ns2_vc_is_unblocked(tmp)) {
- /* there is at least one remaining alive NSVC */
- return;
- }
+ if (nse->alive && (nse->sum_data_weight == 0 || nse->sum_sig_weight == 0)) {
+ /* nse became unavailable */
+ nse->alive = false;
+ ns2_prim_status_ind(nse, NULL, 0, NS_AFF_CAUSE_FAILURE);
}
-
- /* nse became unavailable */
- nse->alive = false;
- ns2_prim_status_ind(nse, NULL, 0, NS_AFF_CAUSE_FAILURE);
}
/*! Create a new GPRS NS instance
diff --git a/src/gb/gprs_ns2_internal.h b/src/gb/gprs_ns2_internal.h
index 5dbc349..5404ed3 100644
--- a/src/gb/gprs_ns2_internal.h
+++ b/src/gb/gprs_ns2_internal.h
@@ -136,6 +136,12 @@
enum gprs_ns2_dialect dialect;
struct osmo_fsm_inst *bss_sns_fi;
+
+ /*! sum of all the data weight of _active_ NS-VCs */
+ uint32_t sum_data_weight;
+
+ /*! sum of all the signalling weight of _active_ NS-VCs */
+ uint32_t sum_sig_weight;
};
/*! Structure representing a single NS-VC */