From c0434e486c4263273cb43475b65bc2361552f1b7 Mon Sep 17 00:00:00 2001 From: Philipp Maier Date: Mon, 14 Dec 2020 23:27:47 +0100 Subject: 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 --- include/osmocom/sgsn/Makefile.am | 1 + include/osmocom/sgsn/debug.h | 1 + include/osmocom/sgsn/sgsn_rim.h | 3 ++ src/sgsn/Makefile.am | 1 + src/sgsn/sgsn_main.c | 8 +++++ src/sgsn/sgsn_rim.c | 67 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 81 insertions(+) create mode 100644 include/osmocom/sgsn/sgsn_rim.h create mode 100644 src/sgsn/sgsn_rim.c 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 19039f694..173df0bf1 100644 --- a/src/sgsn/sgsn_main.c +++ b/src/sgsn/sgsn_main.c @@ -67,6 +67,7 @@ #include #include +#include #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 + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/* 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); +} -- cgit v1.2.3