aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--openbsc/src/gprs/gb_proxy.c42
-rw-r--r--openbsc/tests/gbproxy/gbproxy_test.ok20
2 files changed, 51 insertions, 11 deletions
diff --git a/openbsc/src/gprs/gb_proxy.c b/openbsc/src/gprs/gb_proxy.c
index 6e93e1493..2026d1a03 100644
--- a/openbsc/src/gprs/gb_proxy.c
+++ b/openbsc/src/gprs/gb_proxy.c
@@ -614,6 +614,8 @@ static int gbprox_rx_ptp_from_bss(struct gbproxy_config *cfg,
uint16_t nsvci, uint16_t ns_bvci)
{
struct gbproxy_peer *peer;
+ struct bssgp_normal_hdr *bgph = (struct bssgp_normal_hdr *) msgb_bssgph(msg);
+ uint8_t pdu_type = bgph->pdu_type;
int rc;
peer = gbproxy_peer_by_bvci(cfg, ns_bvci);
@@ -625,6 +627,19 @@ static int gbprox_rx_ptp_from_bss(struct gbproxy_config *cfg,
if (!rc)
return 0;
+ switch (pdu_type) {
+ case BSSGP_PDUT_FLOW_CONTROL_BVC:
+ if (!cfg->route_to_sgsn2)
+ break;
+
+ /* Send a copy to the secondary SGSN */
+ gbprox_relay2sgsn(cfg, msg, ns_bvci, cfg->nsip_sgsn2_nsei);
+ break;
+ default:
+ break;
+ }
+
+
return gbprox_relay2sgsn(cfg, msg, ns_bvci, cfg->nsip_sgsn_nsei);
}
@@ -634,6 +649,8 @@ static int gbprox_rx_ptp_from_sgsn(struct gbproxy_config *cfg,
uint16_t nsvci, uint16_t ns_bvci)
{
struct gbproxy_peer *peer;
+ struct bssgp_normal_hdr *bgph = (struct bssgp_normal_hdr *) msgb_bssgph(msg);
+ uint8_t pdu_type = bgph->pdu_type;
peer = gbproxy_peer_by_bvci(cfg, ns_bvci);
@@ -657,6 +674,19 @@ static int gbprox_rx_ptp_from_sgsn(struct gbproxy_config *cfg,
return bssgp_tx_status(BSSGP_CAUSE_BVCI_BLOCKED, NULL, msg);
}
+ switch (pdu_type) {
+ case BSSGP_PDUT_FLOW_CONTROL_BVC_ACK:
+ case BSSGP_PDUT_BVC_BLOCK_ACK:
+ case BSSGP_PDUT_BVC_UNBLOCK_ACK:
+ if (cfg->route_to_sgsn2 && nsei == cfg->nsip_sgsn2_nsei)
+ /* Hide ACKs from the secondary SGSN, the primary SGSN
+ * is responsible to send them. */
+ return 0;
+ break;
+ default:
+ break;
+ }
+
/* Optionally patch the message */
gbprox_process_bssgp_dl(cfg, msg, peer);
@@ -674,6 +704,7 @@ static int gbprox_rx_sig_from_bss(struct gbproxy_config *cfg,
int data_len = msgb_bssgp_len(msg) - sizeof(*bgph);
struct gbproxy_peer *from_peer = NULL;
struct gprs_ra_id raid;
+ int copy_to_sgsn2 = 0;
int rc;
if (ns_bvci != 0 && ns_bvci != 1) {
@@ -758,6 +789,8 @@ static int gbprox_rx_sig_from_bss(struct gbproxy_config *cfg,
bvci, raid.mcc, raid.mnc, raid.lac,
raid.rac);
}
+ if (cfg->route_to_sgsn2)
+ copy_to_sgsn2 = 1;
}
break;
}
@@ -767,6 +800,10 @@ static int gbprox_rx_sig_from_bss(struct gbproxy_config *cfg,
rc = gbprox_process_bssgp_ul(cfg, msg, from_peer);
if (!rc)
return 0;
+
+ if (copy_to_sgsn2)
+ gbprox_relay2sgsn(cfg, msg, ns_bvci, cfg->nsip_sgsn2_nsei);
+
return gbprox_relay2sgsn(cfg, msg, ns_bvci, cfg->nsip_sgsn_nsei);
err_no_peer:
LOGP(DGPRS, LOGL_ERROR, "NSEI=%u(BSS) cannot find peer based on NSEI\n",
@@ -900,8 +937,11 @@ static int gbprox_rx_sig_from_sgsn(struct gbproxy_config *cfg,
case BSSGP_PDUT_BVC_RESET:
rc = rx_reset_from_sgsn(cfg, msg, orig_msg, &tp, nsei, ns_bvci);
break;
- case BSSGP_PDUT_FLUSH_LL:
case BSSGP_PDUT_BVC_RESET_ACK:
+ if (cfg->route_to_sgsn2 && nsei == cfg->nsip_sgsn2_nsei)
+ break;
+ /* fall through */
+ case BSSGP_PDUT_FLUSH_LL:
/* simple case: BVCI IE is mandatory */
if (!TLVP_PRESENT(&tp, BSSGP_IE_BVCI))
goto err_mand_ie;
diff --git a/openbsc/tests/gbproxy/gbproxy_test.ok b/openbsc/tests/gbproxy/gbproxy_test.ok
index 90900eb17..c554f42af 100644
--- a/openbsc/tests/gbproxy/gbproxy_test.ok
+++ b/openbsc/tests/gbproxy/gbproxy_test.ok
@@ -3001,6 +3001,10 @@ PROCESSING BVC_RESET from 0x01020304:1111
CALLBACK, event 0, msg length 18, bvci 0x0000
00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00
+NS UNITDATA MESSAGE to SGSN 2, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg)
+MESSAGE to SGSN 2 at 0x15161718:32001, msg length 22
+00 00 00 00 22 04 82 10 02 07 81 08 08 88 21 63 54 40 50 60 10 00
+
NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 22
00 00 00 00 22 04 82 10 02 07 81 08 08 88 21 63 54 40 50 60 10 00
@@ -3025,11 +3029,7 @@ PROCESSING BVC_RESET_ACK from 0x15161718:32001
CALLBACK, event 0, msg length 5, bvci 0x0000
00 00 00 00 23 04 82 10 02
-NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg)
-MESSAGE to BSS at 0x01020304:1111, msg length 9
-00 00 00 00 23 04 82 10 02
-
-result (BVC_RESET_ACK) = 9
+result (BVC_RESET_ACK) = 1
Current NS-VCIs:
VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111
@@ -3053,6 +3053,10 @@ PROCESSING FLOW_CONTROL_BVC from 0x01020304:1111
CALLBACK, event 0, msg length 24, bvci 0x1002
00 00 10 02 26 1e 81 01 05 82 01 dc 03 82 02 76 01 82 00 50 1c 82 02 58 06 82 00 03
+NS UNITDATA MESSAGE to SGSN 2, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg)
+MESSAGE to SGSN 2 at 0x15161718:32001, msg length 28
+00 00 10 02 26 1e 81 01 05 82 01 dc 03 82 02 76 01 82 00 50 1c 82 02 58 06 82 00 03
+
NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 28
00 00 10 02 26 1e 81 01 05 82 01 dc 03 82 02 76 01 82 00 50 1c 82 02 58 06 82 00 03
@@ -3077,11 +3081,7 @@ PROCESSING FLOW_CONTROL_BVC_ACK from 0x15161718:32001
CALLBACK, event 0, msg length 4, bvci 0x1002
00 00 10 02 27 1e 81 01
-NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 4 (gprs_ns_sendmsg)
-MESSAGE to BSS at 0x01020304:1111, msg length 8
-00 00 10 02 27 1e 81 01
-
-result (FLOW_CONTROL_BVC_ACK) = 8
+result (FLOW_CONTROL_BVC_ACK) = 0
--- Establish GPRS connection (SGSN 1) ---