summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJacob Erlbeck <jerlbeck@sysmocom.de>2013-10-24 01:33:24 +0200
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2013-10-24 10:01:18 +0200
commitab852ee23439725360f28c63d20ab61b0d774b2b (patch)
tree85aed91a7366e8f5a2f0dd452d1bf11ec823af16
parent5405a104bbe7d3711fe6f19ea7d0fce50ef91147 (diff)
gb: Fix RESET handling with changing NSEI
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
-rw-r--r--src/gb/gprs_ns.c68
-rw-r--r--tests/gb/gprs_ns_test.ok49
2 files changed, 67 insertions, 50 deletions
diff --git a/src/gb/gprs_ns.c b/src/gb/gprs_ns.c
index a597c2c0..043a66c0 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 a882488a..5f90d03f 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: