diff options
-rw-r--r-- | include/osmocom/sgsn/sgsn_rim.h | 2 | ||||
-rw-r--r-- | src/sgsn/sgsn_libgtp.c | 33 | ||||
-rw-r--r-- | src/sgsn/sgsn_rim.c | 47 |
3 files changed, 51 insertions, 31 deletions
diff --git a/include/osmocom/sgsn/sgsn_rim.h b/include/osmocom/sgsn/sgsn_rim.h index aa5a72664..a19265c54 100644 --- a/include/osmocom/sgsn/sgsn_rim.h +++ b/include/osmocom/sgsn/sgsn_rim.h @@ -3,4 +3,4 @@ struct sgsn_mme_ctx; int sgsn_rim_rx_from_gb(struct osmo_bssgp_prim *bp, struct msgb *msg); -int sgsn_rim_rx_from_gtp(struct bssgp_ran_information_pdu *pdu, struct sgsn_mme_ctx *mme); +int sgsn_rim_rx_from_gtp(struct msgb *msg, struct bssgp_rim_routing_info *ra, struct sgsn_mme_ctx *mme); diff --git a/src/sgsn/sgsn_libgtp.c b/src/sgsn/sgsn_libgtp.c index 7c08e6fce..6d6524ec5 100644 --- a/src/sgsn/sgsn_libgtp.c +++ b/src/sgsn/sgsn_libgtp.c @@ -695,9 +695,31 @@ static int cb_gtp_ran_info_relay_ind(struct sockaddr_in *peer, union gtpie_membe LOGMME(mme, DGTP, LOGL_INFO, "Rx GTP RAN Information Relay\n"); + int rc; unsigned int len = 0; - struct msgb *msg = msgb_alloc(4096, "gtpcv1_ran_info"); - struct bssgp_ran_information_pdu pdu; + struct msgb *msg = bssgp_msgb_alloc(); + + uint8_t rim_ra_encoded[1024]; + unsigned int rim_ra_encoded_len = 0; + struct bssgp_rim_routing_info rim_ra; + + /* Read RIM Routing Address */ + if (gtpie_gettlv(ie, GTPIE_RIM_RA_DISCR, 0, &rim_ra_encoded_len, rim_ra_encoded, + sizeof(rim_ra_encoded)) || rim_ra_encoded_len <= 0) { + LOGMME(mme, DGTP, LOGL_ERROR, "Rx GTP RAN Information Relay: No RIM Routing Address Discriminator IE found!\n"); + goto ret_error; + } + if (gtpie_gettlv(ie, GTPIE_RIM_ROUT_ADDR, 0, &rim_ra_encoded_len, rim_ra_encoded + 1, + sizeof(rim_ra_encoded) - 1) || rim_ra_encoded_len <= 0) { + LOGMME(mme, DGTP, LOGL_ERROR, "Rx GTP RAN Information Relay: No RIM Routing Address IE found!\n"); + goto ret_error; + } + rim_ra_encoded_len += 1; + rc = bssgp_parse_rim_ri(&rim_ra, rim_ra_encoded, rim_ra_encoded_len); + if (rc < 0) { + LOGMME(mme, DGTP, LOGL_ERROR, "Rx GTP RAN Information Relay: Failed parsing RIM Routing Address/RIM Routing Address Discriminator IE!\n"); + goto ret_error; + } if (gtpie_gettlv(ie, GTPIE_RAN_T_CONTAIN, 0, &len, msgb_data(msg), 4096) || len <= 0) { LOGMME(mme, DGTP, LOGL_ERROR, "Rx GTP RAN Information Relay: No Transparent Container IE found!\n"); @@ -706,13 +728,8 @@ static int cb_gtp_ran_info_relay_ind(struct sockaddr_in *peer, union gtpie_membe msgb_put(msg, len); msgb_bssgph(msg) = msg->data; msgb_nsei(msg) = 0; - if (bssgp_parse_rim_pdu(&pdu, msg) < 0) { - LOGMME(mme, DGTP, LOGL_ERROR, "Rx GTP RAN Information Relay: Failed parsing Transparent Container IE!\n"); - goto ret_error; - } - msgb_free(msg); - return sgsn_rim_rx_from_gtp(&pdu, mme); + return sgsn_rim_rx_from_gtp(msg, &rim_ra, mme); ret_error: msgb_free(msg); diff --git a/src/sgsn/sgsn_rim.c b/src/sgsn/sgsn_rim.c index 07eff6b48..2cfdc69b3 100644 --- a/src/sgsn/sgsn_rim.c +++ b/src/sgsn/sgsn_rim.c @@ -32,6 +32,26 @@ static int sgsn_bssgp_fwd_rim_to_geran(const struct bssgp_ran_information_pdu *p return bssgp_tx_rim(pdu, bvc_ctx->nsei); } +static int sgsn_bssgp_fwd_rim_from_eutran_to_geran(struct msgb *msg, struct bssgp_rim_routing_info *ra) +{ + struct bssgp_bvc_ctx *bvc_ctx; + OSMO_ASSERT(ra->discr == BSSGP_RIM_ROUTING_INFO_GERAN); + + /* TODO: use RIM ROUTING ADDRESS */ + bvc_ctx = btsctx_by_raid_cid(&ra->geran.raid, ra->geran.cid); + if (!bvc_ctx) { + LOGP(DRIM, LOGL_ERROR, "Unable to find NSEI for destination cell %s\n", + bssgp_rim_ri_name(ra)); + return -EINVAL; + } + + /* Forward PDU as it is to the correct interface */ + return bssgp_tx_rim_encoded(msg, bvc_ctx->nsei, ra); +} + + + + static int sgsn_bssgp_fwd_rim_to_eutran(const struct bssgp_ran_information_pdu *pdu) { struct sgsn_mme_ctx *mme; @@ -90,35 +110,18 @@ err: } /* Receive a RIM PDU from GTPv1C (EUTRAN) */ -int sgsn_rim_rx_from_gtp(struct bssgp_ran_information_pdu *pdu, struct sgsn_mme_ctx *mme) +int sgsn_rim_rx_from_gtp(struct msgb *msg, struct bssgp_rim_routing_info *ra, struct sgsn_mme_ctx *mme) { - struct sgsn_mme_ctx *mme_tmp; - if (pdu->routing_info_src.discr != BSSGP_RIM_ROUTING_INFO_EUTRAN) { - LOGMME(mme, DRIM, LOGL_ERROR, "Rx GTP RAN Information Relay: Expected src %s, got %s\n", - bssgp_rim_routing_info_discr_str(BSSGP_RIM_ROUTING_INFO_EUTRAN), - bssgp_rim_routing_info_discr_str(pdu->routing_info_src.discr)); - return -EINVAL; - } - if (pdu->routing_info_dest.discr != BSSGP_RIM_ROUTING_INFO_GERAN) { + if (ra->discr != BSSGP_RIM_ROUTING_INFO_GERAN) { LOGMME(mme, DRIM, LOGL_ERROR, "Rx GTP RAN Information Relay: Expected dst %s, got %s\n", bssgp_rim_routing_info_discr_str(BSSGP_RIM_ROUTING_INFO_GERAN), - bssgp_rim_routing_info_discr_str(pdu->routing_info_dest.discr)); - return -EINVAL; - } - - mme_tmp = sgsn_mme_ctx_by_route(sgsn, &pdu->routing_info_src.eutran.tai); - if (!mme_tmp)/* See if we have a default route configured */ - mme_tmp = sgsn_mme_ctx_by_default_route(sgsn); - if (mme != mme_tmp) { - LOGP(DRIM, LOGL_ERROR, "Rx GTP RAN Information Relay: " - "Source MME doesn't have RIM routing configured for TAI: %s\n", - bssgp_rim_ri_name(&pdu->routing_info_src)); + bssgp_rim_routing_info_discr_str(ra->discr)); return -EINVAL; } LOGMME(mme, DRIM, LOGL_INFO, "Rx GTP RAN Information Relay for dest cell %s\n", - bssgp_rim_ri_name(&pdu->routing_info_dest)); + bssgp_rim_ri_name(ra)); - return sgsn_bssgp_fwd_rim_to_geran(pdu); + return sgsn_bssgp_fwd_rim_from_eutran_to_geran(msg, ra); } |