aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@osmocom.org>2020-11-23 15:14:20 +0100
committerHarald Welte <laforge@osmocom.org>2020-11-24 11:33:12 +0100
commit3375fa4d64b37ee68f105ce51ea61deeeb8f585b (patch)
treeb5ed9ad6cf3744f520fe1c275e407216f7270bc5
parente1ba4239b47d96a98401977b6b2c26375d69bea6 (diff)
gbproxy: Properly implement paging to LAC/RAC
There may very well be many PCUs connected within the same RAC or LAC. This means we'll need to iterate the list of peers and dispatch it to each matching peer. Change-Id: I2c44959661fb53730586f4347cbfbbcece065e13
-rw-r--r--src/gbproxy/gb_proxy.c41
1 files changed, 29 insertions, 12 deletions
diff --git a/src/gbproxy/gb_proxy.c b/src/gbproxy/gb_proxy.c
index fb58284d..6c56233d 100644
--- a/src/gbproxy/gb_proxy.c
+++ b/src/gbproxy/gb_proxy.c
@@ -1098,37 +1098,54 @@ err_mand_ie:
static int gbprox_rx_paging(struct gbproxy_config *cfg, struct msgb *msg, struct tlv_parsed *tp,
uint32_t nsei, uint16_t ns_bvci)
{
- struct gbproxy_peer *peer = NULL;
+ struct gbproxy_peer *peer;
+ unsigned int n_peers = 0;
int errctr = GBPROX_GLOB_CTR_PROTO_ERR_SGSN;
LOGP(DGPRS, LOGL_INFO, "NSEI=%u(SGSN) BSSGP PAGING ",
nsei);
if (TLVP_PRESENT(tp, BSSGP_IE_BVCI)) {
uint16_t bvci = ntohs(tlvp_val16_unal(tp, BSSGP_IE_BVCI));
- peer = gbproxy_peer_by_bvci(cfg, bvci);
- LOGPC(DGPRS, LOGL_INFO, "routing by BVCI to peer BVCI=%u\n",
- bvci);
errctr = GBPROX_GLOB_CTR_OTHER_ERR;
+ peer = gbproxy_peer_by_bvci(cfg, bvci);
+ LOGPC(DGPRS, LOGL_INFO, "routing by BVCI to peer BVCI=%u\n", bvci);
+ if (!peer) {
+ LOGP(DGPRS, LOGL_NOTICE, "NSEI=%u(SGSN) BSSGP PAGING: "
+ "unable to route: BVCI=%u unknown\n", nsei, bvci);
+ rate_ctr_inc(&cfg->ctrg->ctr[errctr]);
+ return -EINVAL;
+ }
+ return gbprox_relay2peer(msg, peer, ns_bvci);
} else if (TLVP_PRESENT(tp, BSSGP_IE_ROUTEING_AREA)) {
- peer = gbproxy_peer_by_rai(cfg, TLVP_VAL(tp, BSSGP_IE_ROUTEING_AREA));
- LOGPC(DGPRS, LOGL_INFO, "routing by RAI to peer BVCI=%u\n",
- peer ? peer->bvci : -1);
errctr = GBPROX_GLOB_CTR_INV_RAI;
+ /* iterate over all peers and dispatch the paging to each matching one */
+ llist_for_each_entry(peer, &cfg->bts_peers, list) {
+ if (!memcmp(peer->ra, TLVP_VAL(tp, BSSGP_IE_ROUTEING_AREA), 6)) {
+ LOGPC(DGPRS, LOGL_INFO, "routing by RAI to peer BVCI=%u\n", peer->bvci);
+ gbprox_relay2peer(msg, peer, ns_bvci);
+ n_peers++;
+ }
+ }
} else if (TLVP_PRESENT(tp, BSSGP_IE_LOCATION_AREA)) {
- peer = gbproxy_peer_by_lai(cfg, TLVP_VAL(tp, BSSGP_IE_LOCATION_AREA));
- LOGPC(DGPRS, LOGL_INFO, "routing by LAI to peer BVCI=%u\n",
- peer ? peer->bvci : -1);
errctr = GBPROX_GLOB_CTR_INV_LAI;
+ /* iterate over all peers and dispatch the paging to each matching one */
+ llist_for_each_entry(peer, &cfg->bts_peers, list) {
+ if (!memcmp(peer->ra, TLVP_VAL(tp, BSSGP_IE_LOCATION_AREA), 5)) {
+ LOGPC(DGPRS, LOGL_INFO, "routing by LAI to peer BVCI=%u\n", peer->bvci);
+ gbprox_relay2peer(msg, peer, ns_bvci);
+ n_peers++;
+ }
+ }
} else
LOGPC(DGPRS, LOGL_INFO, "\n");
- if (!peer) {
+ if (n_peers == 0) {
LOGP(DGPRS, LOGL_ERROR, "NSEI=%u(SGSN) BSSGP PAGING: "
"unable to route, missing IE\n", nsei);
rate_ctr_inc(&cfg->ctrg->ctr[errctr]);
return -EINVAL;
}
- return gbprox_relay2peer(msg, peer, ns_bvci);
+ return 0;
}
/* Receive an incoming BVC-RESET message from the SGSN */