blob: 57f6ea70b78b9109e403cf113a03c10a0c9d140b [file] [log] [blame]
Philipp Maier2ce050b2020-12-14 23:27:47 +01001
2#include <stdio.h>
3
4#include <errno.h>
5#include <stdint.h>
6
7#include <osmocom/core/msgb.h>
8#include <osmocom/gsm/tlv.h>
9#include <osmocom/vty/logging.h>
10#include <osmocom/gprs/gprs_ns.h>
11#include <osmocom/gprs/gprs_bssgp.h>
12#include <osmocom/gprs/gprs_bssgp_rim.h>
13#include <osmocom/sgsn/sgsn_rim.h>
Pau Espin Pedrole5c89982021-05-03 18:16:42 +020014#include <osmocom/sgsn/gtp_mme.h>
Pau Espin Pedrol8ec269a2023-01-05 19:19:32 +010015#include <osmocom/sgsn/gtp.h>
Philipp Maier2ce050b2020-12-14 23:27:47 +010016#include <osmocom/sgsn/debug.h>
Pau Espin Pedrole5c89982021-05-03 18:16:42 +020017#include <osmocom/sgsn/sgsn.h>
Philipp Maier2ce050b2020-12-14 23:27:47 +010018
Pau Espin Pedrole5c89982021-05-03 18:16:42 +020019static int sgsn_bssgp_fwd_rim_to_geran(const struct bssgp_ran_information_pdu *pdu)
Philipp Maier2ce050b2020-12-14 23:27:47 +010020{
21 struct bssgp_bvc_ctx *bvc_ctx;
Pau Espin Pedrole5c89982021-05-03 18:16:42 +020022 OSMO_ASSERT(pdu->routing_info_dest.discr == BSSGP_RIM_ROUTING_INFO_GERAN);
Philipp Maier2ce050b2020-12-14 23:27:47 +010023
Pau Espin Pedrole5c89982021-05-03 18:16:42 +020024 bvc_ctx = btsctx_by_raid_cid(&pdu->routing_info_dest.geran.raid, pdu->routing_info_dest.geran.cid);
Philipp Maier2ce050b2020-12-14 23:27:47 +010025 if (!bvc_ctx) {
Pau Espin Pedrole5c89982021-05-03 18:16:42 +020026 LOGP(DRIM, LOGL_ERROR, "Unable to find NSEI for destination cell %s\n",
27 bssgp_rim_ri_name(&pdu->routing_info_dest));
Philipp Maier2ce050b2020-12-14 23:27:47 +010028 return -EINVAL;
29 }
30
Pau Espin Pedrole5c89982021-05-03 18:16:42 +020031 /* Forward PDU as it is to the correct interface */
32 return bssgp_tx_rim(pdu, bvc_ctx->nsei);
Philipp Maier2ce050b2020-12-14 23:27:47 +010033}
34
Pau Espin Pedrole5c89982021-05-03 18:16:42 +020035static int sgsn_bssgp_fwd_rim_to_eutran(const struct bssgp_ran_information_pdu *pdu)
Philipp Maier2ce050b2020-12-14 23:27:47 +010036{
Pau Espin Pedrole5c89982021-05-03 18:16:42 +020037 struct sgsn_mme_ctx *mme;
38 OSMO_ASSERT(pdu->routing_info_dest.discr == BSSGP_RIM_ROUTING_INFO_EUTRAN);
Philipp Maier2ce050b2020-12-14 23:27:47 +010039
Pau Espin Pedrole5c89982021-05-03 18:16:42 +020040 mme = sgsn_mme_ctx_by_route(sgsn, &pdu->routing_info_dest.eutran.tai);
41 if (!mme) { /* See if we have a default route configured */
42 mme = sgsn_mme_ctx_by_default_route(sgsn);
43 if (!mme) {
44 LOGP(DRIM, LOGL_ERROR, "Unable to find MME for destination cell %s\n",
45 bssgp_rim_ri_name(&pdu->routing_info_dest));
46 return -EINVAL;
47 }
Philipp Maier2ce050b2020-12-14 23:27:47 +010048 }
Pau Espin Pedrole5c89982021-05-03 18:16:42 +020049
50 return sgsn_mme_ran_info_req(mme, pdu);
51}
52
53/* Receive a RIM PDU from BSSGP (GERAN) */
54int sgsn_rim_rx_from_gb(struct osmo_bssgp_prim *bp, struct msgb *msg)
55{
56 uint16_t nsei = msgb_nsei(msg);
57 struct bssgp_ran_information_pdu *pdu = &bp->u.rim_pdu;
58
Philipp Maier2ce050b2020-12-14 23:27:47 +010059 if (pdu->routing_info_src.discr != BSSGP_RIM_ROUTING_INFO_GERAN) {
60 LOGP(DRIM, LOGL_ERROR,
Pau Espin Pedrole5c89982021-05-03 18:16:42 +020061 "Rx BSSGP RIM (NSEI=%u): Expected src %s, got %s\n", nsei,
62 bssgp_rim_routing_info_discr_str(BSSGP_RIM_ROUTING_INFO_GERAN),
63 bssgp_rim_routing_info_discr_str(pdu->routing_info_src.discr));
64 goto err;
Philipp Maier2ce050b2020-12-14 23:27:47 +010065 }
66
Pau Espin Pedrole5c89982021-05-03 18:16:42 +020067 switch (pdu->routing_info_dest.discr) {
68 case BSSGP_RIM_ROUTING_INFO_GERAN:
69 return sgsn_bssgp_fwd_rim_to_geran(pdu);
70 case BSSGP_RIM_ROUTING_INFO_EUTRAN:
71 return sgsn_bssgp_fwd_rim_to_eutran(pdu);
72 default:
73 /* At the moment we can only handle GERAN/EUTRAN addresses, any
74 * other type of address will be considered as an invalid
75 * address. see also: 3GPP TS 48.018, section 8c.3.1.3
76 */
77 LOGP(DRIM, LOGL_ERROR,
78 "Rx BSSGP RIM (NSEI=%u): Unsupported dst %s\n", nsei,
79 bssgp_rim_routing_info_discr_str(pdu->routing_info_dest.discr));
Philipp Maier2ce050b2020-12-14 23:27:47 +010080 }
81
Pau Espin Pedrole5c89982021-05-03 18:16:42 +020082 LOGP(DRIM, LOGL_INFO, "Rx BSSGP RIM (NSEI=%u): for dest cell %s\n", nsei,
83 bssgp_rim_ri_name(&pdu->routing_info_dest));
84
85err:
86 /* In case of an invalid destination address we respond with
87 * a BSSGP STATUS PDU, see also: 3GPP TS 48.018, section 8c.3.1.3 */
88 bssgp_tx_status(BSSGP_CAUSE_UNKN_RIM_AI, NULL, msg);
89 return -1;
90}
91
92/* Receive a RIM PDU from GTPvC1 (EUTRAN) */
93int sgsn_rim_rx_from_gtp(struct bssgp_ran_information_pdu *pdu, struct sgsn_mme_ctx *mme)
94{
95 struct sgsn_mme_ctx *mme_tmp;
96 if (pdu->routing_info_src.discr != BSSGP_RIM_ROUTING_INFO_EUTRAN) {
97 LOGMME(mme, DRIM, LOGL_ERROR, "Rx GTP RAN Information Relay: Expected src %s, got %s\n",
98 bssgp_rim_routing_info_discr_str(BSSGP_RIM_ROUTING_INFO_EUTRAN),
99 bssgp_rim_routing_info_discr_str(pdu->routing_info_src.discr));
100 return -EINVAL;
101 }
102
103 if (pdu->routing_info_dest.discr != BSSGP_RIM_ROUTING_INFO_GERAN) {
104 LOGMME(mme, DRIM, LOGL_ERROR, "Rx GTP RAN Information Relay: Expected dst %s, got %s\n",
105 bssgp_rim_routing_info_discr_str(BSSGP_RIM_ROUTING_INFO_GERAN),
106 bssgp_rim_routing_info_discr_str(pdu->routing_info_dest.discr));
107 return -EINVAL;
108 }
109
110 mme_tmp = sgsn_mme_ctx_by_route(sgsn, &pdu->routing_info_src.eutran.tai);
111 if (!mme_tmp)/* See if we have a default route configured */
112 mme_tmp = sgsn_mme_ctx_by_default_route(sgsn);
113 if (mme != mme_tmp) {
114 LOGP(DRIM, LOGL_ERROR, "Rx GTP RAN Information Relay: "
115 "Source MME doesn't have RIM routing configured for TAI: %s\n",
116 bssgp_rim_ri_name(&pdu->routing_info_src));
117 return -EINVAL;
118 }
119
120 LOGMME(mme, DRIM, LOGL_INFO, "Rx GTP RAN Information Relay for dest cell %s\n",
121 bssgp_rim_ri_name(&pdu->routing_info_dest));
122
123 return sgsn_bssgp_fwd_rim_to_geran(pdu);
Philipp Maier2ce050b2020-12-14 23:27:47 +0100124}