pespin submitted this change.

View Change

Approvals: fixeria: Looks good to me, but someone else must approve Jenkins Builder: Verified pespin: Looks good to me, approved
peek_l3_ul_nas: Split parsing logic based on PS/CS ctx

It makes no sense to receive an MM message over PS context or a GMM
message over a CS context, hence better clearly split the parsing code
paths to avoid unintended logic execution.

Related: OS#6717
Change-Id: I198f2fd14952362c4d189663d067c7f9dae2ed05
---
M src/osmo-hnbgw/hnbgw_l3.c
1 file changed, 52 insertions(+), 54 deletions(-)

diff --git a/src/osmo-hnbgw/hnbgw_l3.c b/src/osmo-hnbgw/hnbgw_l3.c
index 1fd3398..0ed628f 100644
--- a/src/osmo-hnbgw/hnbgw_l3.c
+++ b/src/osmo-hnbgw/hnbgw_l3.c
@@ -156,60 +156,34 @@
return 0;
}

-static int peek_l3_ul_nas(struct hnbgw_context_map *map, const uint8_t *nas_pdu, size_t len,
- const struct osmo_plmn_id *local_plmn)
+/* CS MM: Determine mobile identity, from_other_plmn, is_emerg. */
+static int peek_l3_ul_nas_cs(struct hnbgw_context_map *map, const uint8_t *nas_pdu, size_t len,
+ const struct osmo_plmn_id *local_plmn)
{
- const struct gsm48_hdr *gh;
- int8_t pdisc;
- uint8_t mtype;
+ const struct gsm48_hdr *gh = (const struct gsm48_hdr *)nas_pdu;
+ struct osmo_location_area_id old_lai;
const struct gsm48_loc_upd_req *lu;
struct gsm48_service_request *cm;
- struct osmo_location_area_id old_lai;
- struct osmo_routing_area_id old_ra = {};
- int nri = -1;

- map->l3 = (struct hnbgw_l3_peek){
- .gmm_nri_container = -1,
- };
+ osmo_mobile_identity_decode_from_l3_buf(&map->l3.mi, nas_pdu, len, false);

- /* Get the mobile identity from CS MM -- the PS GMM happens further down.
- * This will return an error for GMM messages, ignore that. */
- if (!map->is_ps)
- osmo_mobile_identity_decode_from_l3_buf(&map->l3.mi, nas_pdu, len, false);
-
- /* Get is_emerg and from_other_plmn */
- if (len < sizeof(*gh)) {
- LOGP(DCN, LOGL_ERROR, "Layer 3 message too short for header\n");
- return -EINVAL;
- }
-
- gh = (void *)nas_pdu;
- pdisc = gsm48_hdr_pdisc(gh);
- mtype = gsm48_hdr_msg_type(gh);
-
- map->l3.gsm48_pdisc = pdisc;
- map->l3.gsm48_msg_type = mtype;
-
- /* Determine from_other_plmn and is_emerg */
- switch (pdisc) {
+ switch (map->l3.gsm48_pdisc) {
case GSM48_PDISC_MM:
-
- switch (mtype) {
+ /* Get is_emerg and from_other_plmn */
+ switch (map->l3.gsm48_msg_type) {
case GSM48_MT_MM_LOC_UPD_REQUEST:
if (len < sizeof(*gh) + sizeof(*lu)) {
LOGP(DCN, LOGL_ERROR, "LU Req message too short\n");
break;
}
-
lu = (struct gsm48_loc_upd_req *)gh->data;
gsm48_decode_lai2(&lu->lai, &old_lai);
-
map->l3.from_other_plmn = (osmo_plmn_cmp(&old_lai.plmn, local_plmn) != 0);
if (map->l3.from_other_plmn)
LOGP(DRUA, LOGL_INFO, "LU from other PLMN: old LAI=%s my PLMN=%s\n",
osmo_plmn_name_c(OTC_SELECT, &old_lai.plmn),
osmo_plmn_name_c(OTC_SELECT, local_plmn));
- break;
+ return 0;

case GSM48_MT_MM_CM_SERV_REQ:
if (len < sizeof(*gh) + sizeof(*cm)) {
@@ -219,64 +193,88 @@
cm = (struct gsm48_service_request *)&gh->data[0];
map->l3.is_emerg = (cm->cm_service_type == GSM48_CMSERV_EMERGENCY);
LOGP(DRUA, LOGL_DEBUG, "CM Service is_emerg=%d\n", map->l3.is_emerg);
- break;
-
- default:
- break;
+ return 0;
}
break;
+ }

+ return 0;
+}
+
+/* PS GMM: Determine mobile identity, gmm_nri_container, from_other_plmn and is_emerg */
+static int peek_l3_ul_nas_ps(struct hnbgw_context_map *map, const uint8_t *nas_pdu, size_t len,
+ const struct osmo_plmn_id *local_plmn)
+{
+ struct osmo_routing_area_id old_ra = {};
+ int nri = -1;
+
+ switch (map->l3.gsm48_pdisc) {
case GSM48_PDISC_MM_GPRS:
- switch (mtype) {
+ switch (map->l3.gsm48_msg_type) {
case GSM48_MT_GMM_ATTACH_REQ:
mobile_identity_decode_from_gmm_att_req(&map->l3.mi, &old_ra, &nri, nas_pdu, len, false);
-
LOGP(DRUA, LOGL_DEBUG, "GMM Attach Req mi=%s old_ra=%s nri:%d=0x%x\n",
osmo_mobile_identity_to_str_c(OTC_SELECT, &map->l3.mi),
osmo_rai_name2_c(OTC_SELECT, &old_ra),
nri, nri);
-
if (old_ra.lac.plmn.mcc && osmo_plmn_cmp(&old_ra.lac.plmn, local_plmn)) {
map->l3.from_other_plmn = true;
LOGP(DRUA, LOGL_INFO, "GMM Attach Req from other PLMN: old RAI=%s my PLMN=%s\n",
osmo_rai_name2_c(OTC_SELECT, &old_ra),
osmo_plmn_name_c(OTC_SELECT, local_plmn));
}
-
if (nri >= 0)
map->l3.gmm_nri_container = nri;
-
- break;
+ return 0;

case GSM48_MT_GMM_RA_UPD_REQ:
mobile_identity_decode_from_gmm_rau_req(&map->l3.mi, &old_ra, &nri, nas_pdu, len, false);
-
LOGP(DRUA, LOGL_DEBUG, "GMM Routing Area Upd Req mi=%s old_ra=%s nri:%d=0x%x\n",
osmo_mobile_identity_to_str_c(OTC_SELECT, &map->l3.mi),
osmo_rai_name2_c(OTC_SELECT, &old_ra),
nri, nri);
-
if (old_ra.lac.plmn.mcc && osmo_plmn_cmp(&old_ra.lac.plmn, local_plmn)) {
map->l3.from_other_plmn = true;
LOGP(DRUA, LOGL_INFO, "GMM Routing Area Upd Req from other PLMN: old RAI=%s my PLMN=%s\n",
osmo_rai_name2_c(OTC_SELECT, &old_ra),
osmo_plmn_name_c(OTC_SELECT, local_plmn));
}
-
if (nri >= 0)
map->l3.gmm_nri_container = nri;
-
- break;
+ return 0;
}
break;
-
- default:
- break;
}

return 0;
}

+static int peek_l3_ul_nas(struct hnbgw_context_map *map, const uint8_t *nas_pdu, size_t len,
+ const struct osmo_plmn_id *local_plmn)
+{
+ const struct gsm48_hdr *gh = (const struct gsm48_hdr *)nas_pdu;
+
+ map->l3 = (struct hnbgw_l3_peek){
+ .gmm_nri_container = -1,
+ .mi = {
+ .type = GSM_MI_TYPE_NONE,
+ .tmsi = GSM_RESERVED_TMSI,
+ },
+ };
+
+ if (len < sizeof(*gh)) {
+ LOGP(DCN, LOGL_ERROR, "Layer 3 message too short for header\n");
+ return -EINVAL;
+ }
+
+ map->l3.gsm48_pdisc = gsm48_hdr_pdisc(gh);
+ map->l3.gsm48_msg_type = gsm48_hdr_msg_type(gh);
+
+ if (map->is_ps)
+ return peek_l3_ul_nas_ps(map, nas_pdu, len, local_plmn);
+ return peek_l3_ul_nas_cs(map, nas_pdu, len, local_plmn);
+}
+
static int peek_l3_ul_initial_ue(struct hnbgw_context_map *map, const RANAP_InitialUE_MessageIEs_t *ies)
{
struct osmo_plmn_id local_plmn;

To view, visit change 39479. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-MessageType: merged
Gerrit-Project: osmo-hnbgw
Gerrit-Branch: master
Gerrit-Change-Id: I198f2fd14952362c4d189663d067c7f9dae2ed05
Gerrit-Change-Number: 39479
Gerrit-PatchSet: 2
Gerrit-Owner: pespin <pespin@sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <vyanitskiy@sysmocom.de>
Gerrit-Reviewer: laforge <laforge@osmocom.org>
Gerrit-Reviewer: lynxis lazus <lynxis@fe80.eu>
Gerrit-Reviewer: neels <nhofmeyr@sysmocom.de>
Gerrit-Reviewer: pespin <pespin@sysmocom.de>