[PATCH 6/7] gb: Fix RESET handling with changing NSEI

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/OpenBSC@lists.osmocom.org/.

Jacob Erlbeck jerlbeck at sysmocom.de
Wed Oct 23 23:33:24 UTC 2013


This modifies the NS stack's behavior to accept RESET and RESET_ACK
NSEI changes for NS-VC dynamically created by RESET messages from
BSSes. This feature is not used for NS-VC configured via VTY or NS-VC
to a SGSN.

Sponsored-by: On-Waves ehf
---
 src/gb/gprs_ns.c         |   68 +++++++++++++++++++++++++++-------------------
 tests/gb/gprs_ns_test.ok |   49 ++++++++++++++++++---------------
 2 files changed, 67 insertions(+), 50 deletions(-)

diff --git a/src/gb/gprs_ns.c b/src/gb/gprs_ns.c
index a597c2c..043a66c 100644
--- a/src/gb/gprs_ns.c
+++ b/src/gb/gprs_ns.c
@@ -114,7 +114,7 @@ static const struct rate_ctr_desc nsvc_ctr_description[] = {
 	{ "blocked",	"NS-VC Block count         " },
 	{ "dead",	"NS-VC gone dead count     " },
 	{ "replaced",	"NS-VC replaced other count" },
-	{ "nsei-chg",	"NS-VC changed NSEI        " },
+	{ "nsei-chg",	"NS-VC changed NSEI count  " },
 	{ "inv-nsvci",	"NS-VCI was invalid count  " },
 	{ "inv-nsei",	"NSEI was invalid count    " },
 };
@@ -769,10 +769,8 @@ static int gprs_ns_rx_reset(struct gprs_nsvc **nsvc, struct msgb *msg)
 	     (*nsvc)->nsvci, (*nsvc)->nsvci_is_valid ? "" : "(invalid)",
 	     nsei, nsvci, gprs_ns_cause_str(cause));
 
-	if (!(*nsvc)->nsvci_is_valid) {
-		/* It's a new uninitialised NS-VC, nothing to check here */
-	} else if ((*nsvc)->nsvci != nsvci) {
-		if ((*nsvc)->remote_end_is_sgsn) {
+	if ((*nsvc)->nsvci_is_valid && (*nsvc)->nsvci != nsvci) {
+		if ((*nsvc)->persistent || (*nsvc)->remote_end_is_sgsn) {
 			/* The incoming RESET doesn't match the NSVCI. Send an
 			 * appropriate RESET_ACK and ignore the RESET.
 			 * See 3GPP TS 08.16, 7.3.1, 2nd paragraph.
@@ -787,18 +785,25 @@ static int gprs_ns_rx_reset(struct gprs_nsvc **nsvc, struct msgb *msg)
 
 		/* NS-VCI has changed */
 		gprs_nsvc_replace_if_found(nsvci, nsvc, &orig_nsvc);
+	}
 
-	} else if ((*nsvc)->nsei != nsei) {
-		/* The incoming RESET doesn't match the NSEI. Send an
-		 * appropriate RESET_ACK and ignore the RESET.
-		 * See 3GPP TS 08.16, 7.3.1, 3rd paragraph.
-		 */
-		ns_osmo_signal_dispatch_mismatch(*nsvc, msg,
-						 NS_PDUT_RESET,
-						 NS_IE_NSEI);
-		rate_ctr_inc(&(*nsvc)->ctrg->ctr[NS_CTR_INV_NSEI]);
-		gprs_ns_tx_reset_ack(*nsvc);
-		return 0;
+	if ((*nsvc)->nsvci_is_valid && (*nsvc)->nsei != nsei) {
+		if ((*nsvc)->persistent || (*nsvc)->remote_end_is_sgsn) {
+			/* The incoming RESET doesn't match the NSEI. Send an
+			 * appropriate RESET_ACK and ignore the RESET.
+			 * See 3GPP TS 08.16, 7.3.1, 3rd paragraph.
+			 */
+			ns_osmo_signal_dispatch_mismatch(*nsvc, msg,
+							 NS_PDUT_RESET,
+							 NS_IE_NSEI);
+			rate_ctr_inc(&(*nsvc)->ctrg->ctr[NS_CTR_INV_NSEI]);
+			gprs_ns_tx_reset_ack(*nsvc);
+			return 0;
+		}
+
+		/* NSEI has changed */
+		rate_ctr_inc(&(*nsvc)->ctrg->ctr[NS_CTR_NSEI_CHG]);
+		(*nsvc)->nsei = nsei;
 	}
 
 	/* Mark NS-VC as blocked and alive */
@@ -885,7 +890,8 @@ static int gprs_ns_rx_reset_ack(struct gprs_nsvc **nsvc, struct msgb *msg)
 		int use_other_nsvc;
 
 		/* Only do this with BSS peers */
-		use_other_nsvc = !(*nsvc)->remote_end_is_sgsn;
+		use_other_nsvc = !(*nsvc)->remote_end_is_sgsn &&
+			!(*nsvc)->persistent;
 
 		if (use_other_nsvc)
 			/* Update *nsvc to point to the right NSVC object */
@@ -916,17 +922,23 @@ static int gprs_ns_rx_reset_ack(struct gprs_nsvc **nsvc, struct msgb *msg)
 		gprs_ns_ll_copy(*nsvc, orig_nsvc);
 		gprs_ns_ll_clear(orig_nsvc);
 	} else if ((*nsvc)->nsei != nsei) {
-		/* The incoming RESET_ACK doesn't match the NSEI.
-		 * See 3GPP TS 08.16, 7.3.1, 4th paragraph.
-		 */
-		ns_osmo_signal_dispatch_mismatch(*nsvc, msg,
-						 NS_PDUT_RESET_ACK,
-						 NS_IE_NSEI);
-		rate_ctr_inc(&(*nsvc)->ctrg->ctr[NS_CTR_INV_NSEI]);
-		LOGP(DNS, LOGL_ERROR,
-		     "NS RESET ACK Unknown NSEI %d (NS-VCI=%u) from %s\n",
-		     nsei, nsvci, gprs_ns_ll_str(*nsvc));
-		return -EINVAL;
+		if ((*nsvc)->persistent || (*nsvc)->remote_end_is_sgsn) {
+			/* The incoming RESET_ACK doesn't match the NSEI.
+			 * See 3GPP TS 08.16, 7.3.1, 4th paragraph.
+			 */
+			ns_osmo_signal_dispatch_mismatch(*nsvc, msg,
+							 NS_PDUT_RESET_ACK,
+							 NS_IE_NSEI);
+			rate_ctr_inc(&(*nsvc)->ctrg->ctr[NS_CTR_INV_NSEI]);
+			LOGP(DNS, LOGL_ERROR,
+			     "NS RESET ACK Unknown NSEI %d (NS-VCI=%u) from %s\n",
+			     nsei, nsvci, gprs_ns_ll_str(*nsvc));
+			return -EINVAL;
+		}
+
+		/* NSEI has changed */
+		rate_ctr_inc(&(*nsvc)->ctrg->ctr[NS_CTR_NSEI_CHG]);
+		(*nsvc)->nsei = nsei;
 	}
 
 	/* Mark NS-VC as blocked and alive */
diff --git a/tests/gb/gprs_ns_test.ok b/tests/gb/gprs_ns_test.ok
index a882488..5f90d03 100644
--- a/tests/gb/gprs_ns_test.ok
+++ b/tests/gb/gprs_ns_test.ok
@@ -186,7 +186,7 @@ result (RESET) = 9
 Current NS-VCIs:
     VCI 0x3344, NSEI 0x1122, peer 0x01020304:3333, blocked
     VCI 0x1122, NSEI 0x3344, peer 0x01020304:4444, blocked
-         NS-VC changed NSEI        : 1
+         NS-VC changed NSEI count  : 1
 
 --- Peer port 3333, RESET, VCI is changed back ---
 
@@ -196,7 +196,7 @@ PROCESSING RESET from 0x01020304:3333
 ==> got signal NS_REPLACED: 0x1122/1.2.3.4:4444 -> 0x3344/1.2.3.4:3333
 ==> got signal NS_RESET, NS-VC 0x1122/1.2.3.4:3333
 MESSAGE to BSS, msg length 9
-03 01 82 11 22 04 82 33 44 
+03 01 82 11 22 04 82 11 22 
 
 MESSAGE to BSS, msg length 1
 0a 
@@ -205,9 +205,9 @@ result (RESET) = 9
 
 Current NS-VCIs:
     VCI 0x3344, NSEI 0x1122, peer 0x00000000:0, blocked
-    VCI 0x1122, NSEI 0x3344, peer 0x01020304:3333, blocked
+    VCI 0x1122, NSEI 0x1122, peer 0x01020304:3333, blocked
          NS-VC replaced other count: 1
-         NS-VC changed NSEI        : 1
+         NS-VC changed NSEI count  : 2
 
 --- Peer port 4444, RESET, NSEI is changed back ---
 
@@ -227,7 +227,7 @@ Current NS-VCIs:
     VCI 0x3344, NSEI 0x1122, peer 0x00000000:0, blocked
     VCI 0x1122, NSEI 0x1122, peer 0x01020304:4444, blocked
          NS-VC replaced other count: 1
-         NS-VC changed NSEI        : 2
+         NS-VC changed NSEI count  : 2
 
 --- Setup VC 1 BSS -> SGSN ---
 
@@ -424,18 +424,21 @@ Current NS-VCIs:
 PROCESSING RESET from 0x01020304:2222
 02 00 81 01 01 82 10 01 04 82 f0 00 
 
-==> got signal NS_MISMATCH: 0x1001/1.2.3.4:2222 pdu=2, ie=4
+==> got signal NS_RESET, NS-VC 0x1001/1.2.3.4:2222
 MESSAGE to BSS, msg length 9
-03 01 82 10 01 04 82 10 00 
+03 01 82 10 01 04 82 f0 00 
 
-result (RESET) = 0
+MESSAGE to BSS, msg length 1
+0a 
+
+result (RESET) = 9
 
 Current NS-VCIs:
     VCI 0x2001, NSEI 0x2000, peer 0x01020304:1111
-    VCI 0x1001, NSEI 0x1000, peer 0x01020304:2222, blocked
+    VCI 0x1001, NSEI 0xf000, peer 0x01020304:2222, blocked
          NS-VC Block count         : 3
          NS-VC replaced other count: 1
-         NSEI was invalid count    : 1
+         NS-VC changed NSEI count  : 1
 
 --- RESET with invalid NSVCI, BSS -> SGSN ---
 
@@ -456,7 +459,7 @@ Current NS-VCIs:
     VCI 0xf001, NSEI 0x1000, peer 0x01020304:2222, blocked
          NS-VC Block count         : 3
          NS-VC replaced other count: 1
-         NSEI was invalid count    : 1
+         NS-VC changed NSEI count  : 2
 
 --- RESET with old NSEI, NSVCI, BSS -> SGSN ---
 
@@ -477,7 +480,7 @@ Current NS-VCIs:
     VCI 0x1001, NSEI 0x1000, peer 0x01020304:2222, blocked
          NS-VC Block count         : 3
          NS-VC replaced other count: 1
-         NSEI was invalid count    : 1
+         NS-VC changed NSEI count  : 2
 
 --- Unexpected RESET_ACK VC 1, BSS -> SGSN ---
 
@@ -491,7 +494,7 @@ Current NS-VCIs:
     VCI 0x1001, NSEI 0x1000, peer 0x01020304:2222, blocked
          NS-VC Block count         : 3
          NS-VC replaced other count: 1
-         NSEI was invalid count    : 1
+         NS-VC changed NSEI count  : 2
 
 ---  RESET_ACK with invalid NSEI, BSS -> SGSN ---
 
@@ -501,20 +504,22 @@ MESSAGE to BSS, msg length 12
 PROCESSING RESET_ACK from 0x01020304:2222
 03 01 82 10 01 04 82 f0 00 
 
-==> got signal NS_MISMATCH: 0x1001/1.2.3.4:2222 pdu=3, ie=4
-result (RESET_ACK) = -22
+MESSAGE to BSS, msg length 1
+0a 
+
+result (RESET_ACK) = 1
 
 Current NS-VCIs:
     VCI 0x2001, NSEI 0x2000, peer 0x01020304:1111
-    VCI 0x1001, NSEI 0x1000, peer 0x01020304:2222, blocked
-         NS-VC Block count         : 3
+    VCI 0x1001, NSEI 0xf000, peer 0x01020304:2222, blocked
+         NS-VC Block count         : 4
          NS-VC replaced other count: 1
-         NSEI was invalid count    : 2
+         NS-VC changed NSEI count  : 3
 
 ---  RESET_ACK with invalid NSVCI, BSS -> SGSN ---
 
 MESSAGE to BSS, msg length 12
-02 00 81 01 01 82 10 01 04 82 10 00 
+02 00 81 01 01 82 10 01 04 82 f0 00 
 
 PROCESSING RESET_ACK from 0x01020304:2222
 03 01 82 f0 01 04 82 10 00 
@@ -524,11 +529,11 @@ result (RESET_ACK) = -22
 
 Current NS-VCIs:
     VCI 0x2001, NSEI 0x2000, peer 0x01020304:1111
-    VCI 0x1001, NSEI 0x1000, peer 0x01020304:2222, blocked
-         NS-VC Block count         : 3
+    VCI 0x1001, NSEI 0xf000, peer 0x01020304:2222, blocked
+         NS-VC Block count         : 4
          NS-VC replaced other count: 1
+         NS-VC changed NSEI count  : 3
          NS-VCI was invalid count  : 1
-         NSEI was invalid count    : 2
 
 Current NS-VCIs:
 
-- 
1.7.9.5





More information about the OpenBSC mailing list