diff options
author | Philipp Maier <pmaier@sysmocom.de> | 2020-12-14 23:27:47 +0100 |
---|---|---|
committer | Philipp Maier <pmaier@sysmocom.de> | 2021-01-28 23:20:31 +0100 |
commit | 2ce050ba4629059221a3e689845024f474074f9d (patch) | |
tree | de92eb089ccc3dacef288968e5a945f16155bfa6 | |
parent | 43e5f8a2c6c393dfb636783212987c74d7cb9290 (diff) |
sgsn_rim: Add routing for (GERAN) BSSGP RIM messages
The SGSN currently does not forward BSSGP RIM messages.
Related: SYS#5103
Depends: libosmocore Icd667f41d5735de56cd9fb257670337c679dd258
Change-Id: I6fde8ab8955660b48000ca1b650cfc7c7b2e24ba
-rw-r--r-- | include/osmocom/sgsn/Makefile.am | 1 | ||||
-rw-r--r-- | include/osmocom/sgsn/debug.h | 1 | ||||
-rw-r--r-- | include/osmocom/sgsn/sgsn_rim.h | 3 | ||||
-rw-r--r-- | src/sgsn/Makefile.am | 1 | ||||
-rw-r--r-- | src/sgsn/sgsn_main.c | 8 | ||||
-rw-r--r-- | src/sgsn/sgsn_rim.c | 67 |
6 files changed, 81 insertions, 0 deletions
diff --git a/include/osmocom/sgsn/Makefile.am b/include/osmocom/sgsn/Makefile.am index 3fdb6b348..95c811aa5 100644 --- a/include/osmocom/sgsn/Makefile.am +++ b/include/osmocom/sgsn/Makefile.am @@ -24,6 +24,7 @@ noinst_HEADERS = \ gprs_utils.h \ gtphub.h \ sgsn.h \ + sgsn_rim.h \ signal.h \ slhc.h \ v42bis.h \ diff --git a/include/osmocom/sgsn/debug.h b/include/osmocom/sgsn/debug.h index 9a686cb68..37e4a097d 100644 --- a/include/osmocom/sgsn/debug.h +++ b/include/osmocom/sgsn/debug.h @@ -27,6 +27,7 @@ enum { DSIGTRAN, DGTP, DOBJ, + DRIM, Debug_LastEntry, }; diff --git a/include/osmocom/sgsn/sgsn_rim.h b/include/osmocom/sgsn/sgsn_rim.h new file mode 100644 index 000000000..ca3660bd3 --- /dev/null +++ b/include/osmocom/sgsn/sgsn_rim.h @@ -0,0 +1,3 @@ +#pragma once + +int sgsn_rim_rx(struct osmo_bssgp_prim *bp, struct msgb *msg); diff --git a/src/sgsn/Makefile.am b/src/sgsn/Makefile.am index 6a7392baf..873898626 100644 --- a/src/sgsn/Makefile.am +++ b/src/sgsn/Makefile.am @@ -62,6 +62,7 @@ osmo_sgsn_SOURCES = \ sgsn_auth.c \ gprs_subscriber.c \ sgsn_cdr.c \ + sgsn_rim.c \ slhc.c \ gprs_llc_xid.c \ v42bis.c \ diff --git a/src/sgsn/sgsn_main.c b/src/sgsn/sgsn_main.c index 075d59c25..c3a6061f9 100644 --- a/src/sgsn/sgsn_main.c +++ b/src/sgsn/sgsn_main.c @@ -67,6 +67,7 @@ #include <osmocom/ctrl/ports.h> #include <gtp.h> +#include <osmocom/sgsn/sgsn_rim.h> #include "../../bscconfig.h" @@ -120,6 +121,8 @@ int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx) break; case SAP_BSSGP_NM: break; + case SAP_BSSGP_RIM: + return sgsn_rim_rx(bp, oph->msg); } return 0; } @@ -311,6 +314,11 @@ static struct log_info_cat gprs_categories[] = { .description = "GPRS Tunnelling Protocol (GTP)", .enabled = 1, .loglevel = LOGL_NOTICE, }, + [DRIM] = { + .name = "DRIM", + .description = "RAN Information Management (RIM)", + .enabled = 1, .loglevel = LOGL_NOTICE, + }, }; static const struct log_info gprs_log_info = { diff --git a/src/sgsn/sgsn_rim.c b/src/sgsn/sgsn_rim.c new file mode 100644 index 000000000..71e6d9883 --- /dev/null +++ b/src/sgsn/sgsn_rim.c @@ -0,0 +1,67 @@ + +#include <stdio.h> + +#include <errno.h> +#include <stdint.h> + +#include <osmocom/core/msgb.h> +#include <osmocom/gsm/tlv.h> +#include <osmocom/vty/logging.h> +#include <osmocom/gprs/gprs_ns.h> +#include <osmocom/gprs/gprs_bssgp.h> +#include <osmocom/gprs/gprs_bssgp_rim.h> +#include <osmocom/sgsn/sgsn_rim.h> +#include <osmocom/sgsn/debug.h> + +/* Find an NSEI for the destination cell, this function works only for GERAN! */ +static int find_dest_nsei_geran(struct bssgp_rim_routing_info *dest_rim_ri, uint16_t nsei) +{ + struct bssgp_bvc_ctx *bvc_ctx; + + OSMO_ASSERT(dest_rim_ri->discr == BSSGP_RIM_ROUTING_INFO_GERAN); + + bvc_ctx = btsctx_by_raid_cid(&dest_rim_ri->geran.raid, dest_rim_ri->geran.cid); + if (!bvc_ctx) { + LOGP(DRIM, LOGL_ERROR, "BSSGP RIM (NSEI=%u) cannot find NSEI for destination cell\n", nsei); + return -EINVAL; + } + + return bvc_ctx->nsei; +} + +int sgsn_rim_rx(struct osmo_bssgp_prim *bp, struct msgb *msg) +{ + struct bssgp_ran_information_pdu *pdu = &bp->u.rim_pdu; + int d_nsei; + uint16_t nsei = msgb_nsei(msg); + + /* At the moment we only support GERAN, so we block all other network + * types here. */ + if (pdu->routing_info_dest.discr != BSSGP_RIM_ROUTING_INFO_GERAN) { + LOGP(DRIM, LOGL_ERROR, + "BSSGP RIM (NSEI=%u) only GERAN supported, destination cell is not a GERAN cell -- rejected.\n", + nsei); + /* At the moment we can only handle GERAN addresses, any other + * type of address will be consideres as an invalid address. + * see also: 3GPP TS 48.018, section 8c.3.1.3 */ + return bssgp_tx_status(BSSGP_CAUSE_UNKN_RIM_AI, NULL, msg); + } + if (pdu->routing_info_src.discr != BSSGP_RIM_ROUTING_INFO_GERAN) { + LOGP(DRIM, LOGL_ERROR, + "BSSGP RIM (NSEI=%u) only GERAN supported, source cell is not a GERAN cell -- rejected.\n", nsei); + /* See comment above */ + return bssgp_tx_status(BSSGP_CAUSE_UNKN_RIM_AI, NULL, msg); + } + + d_nsei = find_dest_nsei_geran(&pdu->routing_info_dest, nsei); + if (d_nsei < 0) { + LOGP(DRIM, LOGL_NOTICE, "BSSGP RIM (NSEI=%u) Cell %s unknown to this sgsn\n", + nsei, bssgp_rim_ri_name(&pdu->routing_info_dest)); + /* In case of an invalid destination address we respond with + * a BSSGP STATUS PDU, see also: 3GPP TS 48.018, section 8c.3.1.3 */ + return bssgp_tx_status(BSSGP_CAUSE_UNKN_RIM_AI, NULL, msg); + } + + /* Forward PDU as it is to the correct interface */ + return bssgp_tx_rim(pdu, (uint16_t) d_nsei); +} |