This adds a test with a UNITDATA SGSN message that is addressed to an invalid (unknown) BVCI. The test shows, that the message is echoed to the SGSN.
Sponsored-by: On-Waves ehf --- openbsc/include/openbsc/gb_proxy.h | 1 + openbsc/src/gprs/gb_proxy.c | 36 ++++++++++++++++++++++++++++++++- openbsc/tests/gbproxy/gbproxy_test.c | 8 ++++++++ openbsc/tests/gbproxy/gbproxy_test.ok | 18 +++++++++++++++++ 4 files changed, 62 insertions(+), 1 deletion(-)
diff --git a/openbsc/include/openbsc/gb_proxy.h b/openbsc/include/openbsc/gb_proxy.h index 82e47d5..7b14a09 100644 --- a/openbsc/include/openbsc/gb_proxy.h +++ b/openbsc/include/openbsc/gb_proxy.h @@ -35,5 +35,6 @@ int gbprox_signal(unsigned int subsys, unsigned int signal, /* Reset all persistent NS-VC's */ int gbprox_reset_persistent_nsvcs(struct gprs_ns_inst *nsi);
+int gbprox_dump_global(FILE *stream, int indent, int verbose); int gbprox_dump_peers(FILE *stream, int indent, int verbose); #endif diff --git a/openbsc/src/gprs/gb_proxy.c b/openbsc/src/gprs/gb_proxy.c index ddc9e0a..a25a9f5 100644 --- a/openbsc/src/gprs/gb_proxy.c +++ b/openbsc/src/gprs/gb_proxy.c @@ -800,6 +800,37 @@ int gbprox_signal(unsigned int subsys, unsigned int signal, return 0; }
+int gbprox_dump_global(FILE *stream, int indent, int verbose) +{ + unsigned int i; + const struct rate_ctr_group_desc *desc; + int rc; + + rc = fprintf(stream, "%*sGbproxy global:\n", indent, ""); + if (rc < 0) + return rc; + + if (!verbose) + return 0; + + desc = get_global_ctrg()->desc; + + for (i = 0; i < desc->num_ctr; i++) { + struct rate_ctr *ctr = &get_global_ctrg()->ctr[i]; + if (ctr->current) { + rc = fprintf(stream, "%*s %s: %llu\n", + indent, "", + desc->ctr_desc[i].description, + (long long)ctr->current); + + if (rc < 0) + return rc; + } + } + + return 0; +} + int gbprox_dump_peers(FILE *stream, int indent, int verbose) { struct gbprox_peer *peer; @@ -808,7 +839,10 @@ int gbprox_dump_peers(FILE *stream, int indent, int verbose) const struct rate_ctr_group_desc *desc; int rc;
- fprintf(stream, "%*sPeers:\n", indent, ""); + rc = fprintf(stream, "%*sPeers:\n", indent, ""); + if (rc < 0) + return rc; + llist_for_each_entry(peer, &gbprox_bts_peers, list) { gsm48_parse_ra(&raid, peer->ra);
diff --git a/openbsc/tests/gbproxy/gbproxy_test.c b/openbsc/tests/gbproxy/gbproxy_test.c index 21ee723..e1e6587 100644 --- a/openbsc/tests/gbproxy/gbproxy_test.c +++ b/openbsc/tests/gbproxy/gbproxy_test.c @@ -523,6 +523,8 @@ static void test_gbproxy() gprs_dump_nsi(nsi); gbprox_dump_peers(stdout, 0, 1);
+ gbprox_dump_global(stdout, 0, 1); + send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n"); @@ -533,6 +535,12 @@ static void test_gbproxy()
send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
+ printf("--- Send message from SGSN to BSS 1, BVCI 0x10ff (invalid) ---\n\n"); + + send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x10ff, (uint8_t *)"", 0); + + gbprox_dump_global(stdout, 0, 1); + gprs_ns_destroy(nsi); nsi = NULL; } diff --git a/openbsc/tests/gbproxy/gbproxy_test.ok b/openbsc/tests/gbproxy/gbproxy_test.ok index e4b7aba..fcde39f 100644 --- a/openbsc/tests/gbproxy/gbproxy_test.ok +++ b/openbsc/tests/gbproxy/gbproxy_test.ok @@ -749,6 +749,7 @@ Peers: NSEI mismatch : 1 NSEI 4096, BVCI 4098, not blocked, RAC 10-32-16464-96 NSEI mismatch : 1 +Gbproxy global: PROCESSING BVC_RESET_ACK from 0x05060708:32000 00 00 00 00 23 04 82 10 02
@@ -795,5 +796,22 @@ MESSAGE to BSS at 0x01020304:1111, msg length 4
result (UNITDATA) = 4
+--- Send message from SGSN to BSS 1, BVCI 0x10ff (invalid) --- + +PROCESSING UNITDATA from 0x05060708:32000 +00 00 10 ff + +CALLBACK, event 0, msg length 0, bvci 0x10ff + + +NS UNITDATA MESSAGE to SGSN, BVCI 0x10ff, msg length 0 + + +MESSAGE to SGSN at 0x05060708:32000, msg length 4 +00 00 10 ff + +result (UNITDATA) = 4 + +Gbproxy global: ===== NS protocol test END
Currently such messages lead to a creation of a new peer with the SGSN's NSEI, which results in echoing the message back to the SGSN.
This patch modifies this by sending a STATUS response (invalid BVCI) instead back to the SGSN.
Sponsored-by: On-Waves ehf --- openbsc/src/gprs/gb_proxy.c | 12 +++++++----- openbsc/tests/gbproxy/gbproxy_test.ok | 11 ++++++----- 2 files changed, 13 insertions(+), 10 deletions(-)
diff --git a/openbsc/src/gprs/gb_proxy.c b/openbsc/src/gprs/gb_proxy.c index a25a9f5..dea6e3f 100644 --- a/openbsc/src/gprs/gb_proxy.c +++ b/openbsc/src/gprs/gb_proxy.c @@ -693,11 +693,13 @@ int gbprox_rcvmsg(struct msgb *msg, uint16_t nsei, uint16_t ns_bvci, uint16_t ns
/* else: SGSN -> BSS direction */ if (!peer) { - LOGP(DGPRS, LOGL_INFO, "Allocationg new peer for " - "BVCI=%u via NSVC=%u/NSEI=%u\n", ns_bvci, - nsvci, nsei); - peer = peer_alloc(ns_bvci); - peer->nsei = nsei; + LOGP(DGPRS, LOGL_INFO, "Didn't find peer for " + "BVCI=%u for message from NSVC=%u/NSEI=%u (SGSN)\n", + ns_bvci, nsvci, nsei); + rate_ctr_inc(&get_global_ctrg()-> + ctr[GBPROX_GLOB_CTR_INV_BVCI]); + return bssgp_tx_status(BSSGP_CAUSE_UNKNOWN_BVCI, + &ns_bvci, msg); } if (peer->blocked) { LOGP(DGPRS, LOGL_NOTICE, "Dropping PDU for " diff --git a/openbsc/tests/gbproxy/gbproxy_test.ok b/openbsc/tests/gbproxy/gbproxy_test.ok index fcde39f..35d97e7 100644 --- a/openbsc/tests/gbproxy/gbproxy_test.ok +++ b/openbsc/tests/gbproxy/gbproxy_test.ok @@ -804,14 +804,15 @@ PROCESSING UNITDATA from 0x05060708:32000 CALLBACK, event 0, msg length 0, bvci 0x10ff
-NS UNITDATA MESSAGE to SGSN, BVCI 0x10ff, msg length 0 +NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 10 +41 07 81 05 04 82 10 ff 15 80
+MESSAGE to SGSN at 0x05060708:32000, msg length 14 +00 00 00 00 41 07 81 05 04 82 10 ff 15 80
-MESSAGE to SGSN at 0x05060708:32000, msg length 4 -00 00 10 ff - -result (UNITDATA) = 4 +result (UNITDATA) = 14
Gbproxy global: + Invalid BVC Identifier : 1 ===== NS protocol test END