Review at  https://gerrit.osmocom.org/6672

implement support for 3-digit MNC with leading zeros

Add 3-digit flags and use the new RAI and LAI API from libosmocore throughout
the code base to be able to handle an MNC < 100 that has three digits (leading
zeros).

Note that in gbproxy_test.ok, 0-0 changes to 000-000 instead of 000-00, because
the parsed ra buffer is 000000 which results in 000-000, while 00f000 would
result in 000-00. IOW this is expected.

Change-Id: I7437dfaa586689e2bef0d4be6537e5577a8f6c26
---
M include/osmocom/sgsn/gb_proxy.h
M src/gprs/gb_proxy.c
M src/gprs/gb_proxy_patch.c
M src/gprs/gb_proxy_vty.c
M src/gprs/gprs_gb_parse.c
M src/gprs/gprs_gmm.c
M src/gprs/gprs_utils.c
M src/gprs/sgsn_auth.c
M src/gprs/sgsn_vty.c
M tests/gbproxy/gbproxy_test.c
M tests/gbproxy/gbproxy_test.ok
11 files changed, 70 insertions(+), 56 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/osmo-sgsn refs/changes/72/6672/1

diff --git a/include/osmocom/sgsn/gb_proxy.h b/include/osmocom/sgsn/gb_proxy.h
index e10894f..f4d82a0 100644
--- a/include/osmocom/sgsn/gb_proxy.h
+++ b/include/osmocom/sgsn/gb_proxy.h
@@ -102,6 +102,7 @@
 
        /* force mcc/mnc */
        int core_mnc;
+       bool core_mnc_3_digits;
        int core_mcc;
        uint8_t* core_apn;
        size_t core_apn_size;
@@ -121,6 +122,7 @@
 
 struct gbproxy_patch_state {
        int local_mnc;
+       bool local_mnc_3_digits;
        int local_mcc;
 
        /* List of TLLIs for which patching is enabled */
diff --git a/src/gprs/gb_proxy.c b/src/gprs/gb_proxy.c
index 63c3a61..68d9b15 100644
--- a/src/gprs/gb_proxy.c
+++ b/src/gprs/gb_proxy.c
@@ -194,6 +194,7 @@
        struct gbproxy_patch_state *state = &peer->patch_state;
        const int old_local_mcc = state->local_mcc;
        const int old_local_mnc = state->local_mnc;
+       const bool old_local_mnc_3_digits = state->local_mnc_3_digits;
        struct gprs_ra_id raid;
 
        if (!raid_enc)
@@ -208,22 +209,28 @@
                state->local_mcc = raid.mcc;
        }
 
-       if (!peer->cfg->core_mnc || raid.mnc == peer->cfg->core_mnc) {
+       if (!peer->cfg->core_mnc
+           || !gsm48_mnc_cmp(raid.mnc, raid.mnc_3_digits,
+                             peer->cfg->core_mnc, 
peer->cfg->core_mnc_3_digits)) {
                state->local_mnc = 0;
+               state->local_mnc_3_digits = false;
        } else {
                state->local_mnc = raid.mnc;
+               state->local_mnc_3_digits = raid.mnc_3_digits;
        }
 
-       if (old_local_mcc != state->local_mcc ||
-           old_local_mnc != state->local_mnc)
+       if (old_local_mcc != state->local_mcc
+           || gsm48_mnc_cmp(old_local_mnc, old_local_mnc_3_digits,
+                            state->local_mnc, state->local_mnc_3_digits))
                LOGP(DGPRS, LOGL_NOTICE,
                     "Patching RAID %sactivated, msg: %s, "
-                    "local: %d-%d, core: %d-%d\n",
+                    "local: %s, core: %s\n",
                     state->local_mcc || state->local_mnc ?
                     "" : "de",
                     log_text,
-                    state->local_mcc, state->local_mnc,
-                    peer->cfg->core_mcc, peer->cfg->core_mnc);
+                    osmo_mcc_mnc_name(state->local_mcc, state->local_mnc, 
state->local_mnc_3_digits),
+                    osmo_mcc_mnc_name2(peer->cfg->core_mcc, 
peer->cfg->core_mnc,
+                                       peer->cfg->core_mnc_3_digits));
 }
 
 uint32_t gbproxy_make_bss_ptmsi(struct gbproxy_peer *peer,
@@ -994,9 +1001,8 @@
                        sizeof(from_peer->ra));
                gsm48_parse_ra(&raid, from_peer->ra);
                LOGP(DGPRS, LOGL_INFO, "NSEI=%u BSSGP SUSPEND/RESUME "
-                       "RAI snooping: RAI %u-%u-%u-%u behind BVCI=%u\n",
-                       nsei, raid.mcc, raid.mnc, raid.lac,
-                       raid.rac , from_peer->bvci);
+                       "RAI snooping: RAI %s behind BVCI=%u\n",
+                       nsei, osmo_rai_name(&raid), from_peer->bvci);
                /* FIXME: This only supports one BSS per RA */
                break;
        case BSSGP_PDUT_BVC_RESET:
@@ -1037,10 +1043,8 @@
                                        TLVP_VAL(&tp, BSSGP_IE_CELL_ID),
                                        sizeof(from_peer->ra));
                                gsm48_parse_ra(&raid, from_peer->ra);
-                               LOGP(DGPRS, LOGL_INFO, "NSEI=%u/BVCI=%u "
-                                    "Cell ID %u-%u-%u-%u\n", nsei,
-                                    bvci, raid.mcc, raid.mnc, raid.lac,
-                                    raid.rac);
+                               LOGP(DGPRS, LOGL_INFO, "NSEI=%u/BVCI=%u Cell ID 
%s\n",
+                                    nsei, bvci, osmo_rai_name(&raid));
                        }
                        if (cfg->route_to_sgsn2)
                                copy_to_sgsn2 = 1;
diff --git a/src/gprs/gb_proxy_patch.c b/src/gprs/gb_proxy_patch.c
index 1be9c24..9121505 100644
--- a/src/gprs/gb_proxy_patch.c
+++ b/src/gprs/gb_proxy_patch.c
@@ -38,6 +38,7 @@
        struct gbproxy_patch_state *state = &peer->patch_state;
        int old_mcc;
        int old_mnc;
+       bool old_mnc_3_digits;
        struct gprs_ra_id raid;
        enum gbproxy_peer_ctr counter =
                to_bss ?
@@ -51,30 +52,35 @@
 
        old_mcc = raid.mcc;
        old_mnc = raid.mnc;
+       old_mnc_3_digits = raid.mnc_3_digits;
 
        if (!to_bss) {
                /* BSS -> SGSN */
                if (state->local_mcc)
                        raid.mcc = peer->cfg->core_mcc;
 
-               if (state->local_mnc)
+               if (state->local_mnc) {
                        raid.mnc = peer->cfg->core_mnc;
+                       raid.mnc_3_digits = peer->cfg->core_mnc_3_digits;
+               }
        } else {
                /* SGSN -> BSS */
                if (state->local_mcc)
                        raid.mcc = state->local_mcc;
 
-               if (state->local_mnc)
+               if (state->local_mnc) {
                        raid.mnc = state->local_mnc;
+                       raid.mnc_3_digits = state->local_mnc_3_digits;
+               }
        }
 
        LOGP(DGPRS, LOGL_DEBUG,
             "Patching %s to %s: "
-            "%d-%d-%d-%d -> %d-%d-%d-%d\n",
+            "%s-%d-%d -> %s\n",
             log_text,
             to_bss ? "BSS" : "SGSN",
-            old_mcc, old_mnc, raid.lac, raid.rac,
-            raid.mcc, raid.mnc, raid.lac, raid.rac);
+            osmo_mcc_mnc_name(old_mcc, old_mnc, old_mnc_3_digits), raid.lac, 
raid.rac,
+            osmo_rai_name(&raid));
 
        gsm48_encode_ra(raid_enc, &raid);
        rate_ctr_inc(&peer->ctrg->ctr[counter]);
diff --git a/src/gprs/gb_proxy_vty.c b/src/gprs/gb_proxy_vty.c
index 25ef756..d4076db 100644
--- a/src/gprs/gb_proxy_vty.c
+++ b/src/gprs/gb_proxy_vty.c
@@ -71,9 +71,7 @@
        gsm48_parse_ra(&raid, peer->ra);
 
        vty_out(vty, "NSEI %5u, PTP-BVCI %5u, "
-               "RAI %u-%u-%u-%u",
-               peer->nsei, peer->bvci,
-               raid.mcc, raid.mnc, raid.lac, raid.rac);
+               "RAI %s", peer->nsei, peer->bvci, osmo_rai_name(&raid));
        if (peer->blocked)
                vty_out(vty, " [BVC-BLOCKED]");
 
@@ -90,11 +88,11 @@
                VTY_NEWLINE);
 
        if (g_cfg->core_mcc > 0)
-               vty_out(vty, " core-mobile-country-code %d%s",
-                       g_cfg->core_mcc, VTY_NEWLINE);
+               vty_out(vty, " core-mobile-country-code %s%s",
+                       osmo_mcc_name(g_cfg->core_mcc), VTY_NEWLINE);
        if (g_cfg->core_mnc > 0)
-               vty_out(vty, " core-mobile-network-code %d%s",
-                       g_cfg->core_mnc, VTY_NEWLINE);
+               vty_out(vty, " core-mobile-network-code %s%s",
+                       osmo_mnc_name(g_cfg->core_mnc, 
g_cfg->core_mnc_3_digits), VTY_NEWLINE);
 
        for (match_id = 0; match_id < ARRAY_SIZE(g_cfg->matches); ++match_id) {
                struct gbproxy_match *match = &g_cfg->matches[match_id];
@@ -170,7 +168,14 @@
       "core-mobile-network-code <1-999>",
       GBPROXY_CORE_MNC_STR "NCC value\n")
 {
-       g_cfg->core_mnc = atoi(argv[0]);
+       uint16_t mnc;
+       bool mnc_3_digits;
+       if (gsm48_mnc_from_str(argv[0], &mnc, &mnc_3_digits)) {
+               vty_out(vty, "%% Invalid MNC: %s%s", argv[0], VTY_NEWLINE);
+               return CMD_WARNING;
+       }
+       g_cfg->core_mnc = mnc;
+       g_cfg->core_mnc_3_digits = mnc_3_digits;
        return CMD_SUCCESS;
 }
 
@@ -180,6 +185,7 @@
       NO_STR GBPROXY_CORE_MNC_STR)
 {
        g_cfg->core_mnc = 0;
+       g_cfg->core_mnc_3_digits = false;
        return CMD_SUCCESS;
 }
 
diff --git a/src/gprs/gprs_gb_parse.c b/src/gprs/gprs_gb_parse.c
index ba78e89..18565ae 100644
--- a/src/gprs/gprs_gb_parse.c
+++ b/src/gprs/gprs_gb_parse.c
@@ -551,24 +551,21 @@
        if (parse_ctx->bssgp_raid_enc) {
                struct gprs_ra_id raid;
                gsm48_parse_ra(&raid, parse_ctx->bssgp_raid_enc);
-               LOGPC(DGPRS, log_level, "%s BSSGP RAID %u-%u-%u-%u", sep,
-                    raid.mcc, raid.mnc, raid.lac, raid.rac);
+               LOGPC(DGPRS, log_level, "%s BSSGP RAID %s", sep, 
osmo_rai_name(&raid));
                sep = ",";
        }
 
        if (parse_ctx->raid_enc) {
                struct gprs_ra_id raid;
                gsm48_parse_ra(&raid, parse_ctx->raid_enc);
-               LOGPC(DGPRS, log_level, "%s RAID %u-%u-%u-%u", sep,
-                    raid.mcc, raid.mnc, raid.lac, raid.rac);
+               LOGPC(DGPRS, log_level, "%s RAID %s", sep, 
osmo_rai_name(&raid));
                sep = ",";
        }
 
        if (parse_ctx->old_raid_enc) {
                struct gprs_ra_id raid;
                gsm48_parse_ra(&raid, parse_ctx->old_raid_enc);
-               LOGPC(DGPRS, log_level, "%s old RAID %u-%u-%u-%u", sep,
-                    raid.mcc, raid.mnc, raid.lac, raid.rac);
+               LOGPC(DGPRS, log_level, "%s old RAID %s", sep, 
osmo_rai_name(&raid));
                sep = ",";
        }
 
diff --git a/src/gprs/gprs_gmm.c b/src/gprs/gprs_gmm.c
index 9313e98..c9fb8da 100644
--- a/src/gprs/gprs_gmm.c
+++ b/src/gprs/gprs_gmm.c
@@ -1673,12 +1673,11 @@
                        LOGMMCTXP(LOGL_INFO, mmctx,
                                "Looked up by matching TLLI and P_TMSI. "
                                "BSSGP TLLI: %08x, P-TMSI: %08x (%08x), "
-                               "TLLI: %08x (%08x), RA: %d-%d-%d-%d\n",
+                               "TLLI: %08x (%08x), RA: %s\n",
                                msgb_tlli(msg),
                                mmctx->p_tmsi, mmctx->p_tmsi_old,
                                mmctx->gb.tlli, mmctx->gb.tlli_new,
-                               mmctx->ra.mcc, mmctx->ra.mnc,
-                               mmctx->ra.lac, mmctx->ra.rac);
+                               osmo_rai_name(&mmctx->ra));
 
                        mmctx->gmm_state = GMM_COMMON_PROC_INIT;
                }
@@ -1687,8 +1686,8 @@
        {
                /* We cannot use the mmctx */
                LOGMMCTXP(LOGL_INFO, mmctx,
-                       "The MM context cannot be used, RA: %d-%d-%d-%d\n",
-                       mmctx->ra.mcc, mmctx->ra.mnc,
+                       "The MM context cannot be used, RA: %03d-%0*d-%d-%d\n",
+                       mmctx->ra.mcc, mmctx->ra.mnc_3_digits, mmctx->ra.mnc,
                        mmctx->ra.lac, mmctx->ra.rac);
                mmctx = NULL;
        }
diff --git a/src/gprs/gprs_utils.c b/src/gprs/gprs_utils.c
index 307699b..38e5451 100644
--- a/src/gprs/gprs_utils.c
+++ b/src/gprs/gprs_utils.c
@@ -241,6 +241,8 @@
 int gprs_ra_id_equals(const struct gprs_ra_id *id1,
                        const struct gprs_ra_id *id2)
 {
-       return (id1->mcc == id2->mcc && id1->mnc == id2->mnc &&
-               id1->lac == id2->lac && id1->rac == id2->rac);
+       return (id1->mcc == id2->mcc
+               && !gsm48_mnc_cmp(id1->mnc, id1->mnc_3_digits,
+                                 id2->mnc, id2->mnc_3_digits)
+               && id1->lac == id2->lac && id1->rac == id2->rac);
 }
diff --git a/src/gprs/sgsn_auth.c b/src/gprs/sgsn_auth.c
index 92712ef..6fb32b7 100644
--- a/src/gprs/sgsn_auth.c
+++ b/src/gprs/sgsn_auth.c
@@ -133,9 +133,10 @@
        if (check_net) {
                /* We simply assume that the IMSI exists, as long as it is part
                 * of 'our' network */
-               snprintf(mccmnc, sizeof(mccmnc), "%03d%02d",
-                        mmctx->ra.mcc, mmctx->ra.mnc);
-               if (strncmp(mccmnc, mmctx->imsi, 5) == 0)
+               snprintf(mccmnc, sizeof(mccmnc), "%s%s",
+                        osmo_mcc_name(mmctx->ra.mcc),
+                        osmo_mnc_name(mmctx->ra.mnc, mmctx->ra.mnc_3_digits));
+               if (strncmp(mccmnc, mmctx->imsi, mmctx->ra.mnc_3_digits ? 6 : 
5) == 0)
                        return SGSN_AUTH_ACCEPTED;
        }
 
diff --git a/src/gprs/sgsn_vty.c b/src/gprs/sgsn_vty.c
index c2c03b5..f963022 100644
--- a/src/gprs/sgsn_vty.c
+++ b/src/gprs/sgsn_vty.c
@@ -473,11 +473,9 @@
                pfx, mm->imsi, mm->imei, mm->p_tmsi, VTY_NEWLINE);
        vty_out(vty, "%s  MSISDN: %s, TLLI: %08x%s HLR: %s",
                pfx, mm->msisdn, mm->gb.tlli, mm->hlr, VTY_NEWLINE);
-       vty_out(vty, "%s  MM State: %s, Routeing Area: %u-%u-%u-%u, "
-               "Cell ID: %u%s", pfx,
-               get_value_string(gprs_mm_st_strs, mm->gmm_state),
-               mm->ra.mcc, mm->ra.mnc, mm->ra.lac, mm->ra.rac,
-               mm->gb.cell_id, VTY_NEWLINE);
+       vty_out(vty, "%s  MM State: %s, Routeing Area: %s, Cell ID: %u%s",
+               pfx, get_value_string(gprs_mm_st_strs, mm->gmm_state),
+               osmo_rai_name(&mm->ra), mm->gb.cell_id, VTY_NEWLINE);
 
        vty_out_rate_ctr_group(vty, " ", mm->ctrg);
 
diff --git a/tests/gbproxy/gbproxy_test.c b/tests/gbproxy/gbproxy_test.c
index 080c96b..c239236 100644
--- a/tests/gbproxy/gbproxy_test.c
+++ b/tests/gbproxy/gbproxy_test.c
@@ -131,12 +131,11 @@
                struct gbproxy_patch_state *state = &peer->patch_state;
                gsm48_parse_ra(&raid, peer->ra);
 
-               rc = fprintf(stream, "%*s  NSEI %u, BVCI %u, %sblocked, "
-                            "RAI %u-%u-%u-%u\n",
+               rc = fprintf(stream, "%*s  NSEI %u, BVCI %u, %sblocked, RAI 
%s\n",
                             indent, "",
                             peer->nsei, peer->bvci,
                             peer->blocked ? "" : "not ",
-                            raid.mcc, raid.mnc, raid.lac, raid.rac);
+                            osmo_rai_name(&raid));
 
                if (rc < 0)
                        return rc;
diff --git a/tests/gbproxy/gbproxy_test.ok b/tests/gbproxy/gbproxy_test.ok
index ff86b67..5d77dc9 100644
--- a/tests/gbproxy/gbproxy_test.ok
+++ b/tests/gbproxy/gbproxy_test.ok
@@ -7249,7 +7249,7 @@
   Add TLLI 1, IMSI 1
   Add TLLI 2, IMSI 1 (should replace TLLI 1)
   Peers:
-    NSEI 0, BVCI 20, not blocked, RAI 0-0-0-0
+    NSEI 0, BVCI 20, not blocked, RAI 000-000-0-0
       TLLI cache size                 : 1
       TLLI-Cache: 1
         TLLI c000162e, IMSI 03242526, AGE 0, IMSI matches
@@ -7258,7 +7258,7 @@
   Add TLLI 1, IMSI 1
   Add TLLI 1, IMSI 2 (should replace IMSI 1)
   Peers:
-    NSEI 0, BVCI 20, not blocked, RAI 0-0-0-0
+    NSEI 0, BVCI 20, not blocked, RAI 000-000-0-0
       TLLI cache size                 : 1
       TLLI-Cache: 1
         TLLI c00004d2, IMSI 06272829, AGE 0, IMSI matches
@@ -7267,7 +7267,7 @@
   Add TLLI 1, IMSI 1
   Add TLLI 2, IMSI 2 (should replace IMSI 1)
   Peers:
-    NSEI 0, BVCI 20, not blocked, RAI 0-0-0-0
+    NSEI 0, BVCI 20, not blocked, RAI 000-000-0-0
       TLLI cache size                 : 1
       TLLI-Cache: 1
         TLLI c000162e, IMSI 06272829, AGE 0, IMSI matches
@@ -7276,7 +7276,7 @@
   Add TLLI 1, IMSI 1 (should expire after timeout)
   Add TLLI 2, IMSI 2 (should not expire after timeout)
   Peers:
-    NSEI 0, BVCI 20, not blocked, RAI 0-0-0-0
+    NSEI 0, BVCI 20, not blocked, RAI 000-000-0-0
       TLLI cache size                 : 1
       TLLI-Cache: 1
         TLLI c000162e, IMSI 06272829, AGE 1, IMSI matches
@@ -7286,7 +7286,7 @@
   Add TLLI 2, IMSI 2 (should expire after timeout)
   Add TLLI 3, IMSI 3 (should not expire after timeout)
   Peers:
-    NSEI 0, BVCI 20, not blocked, RAI 0-0-0-0
+    NSEI 0, BVCI 20, not blocked, RAI 000-000-0-0
       TLLI cache size                 : 3
       TLLI-Cache: 3
         TLLI c0000d80, IMSI 12345678, AGE 0, IMSI matches
@@ -7294,7 +7294,7 @@
         TLLI c00004d2, IMSI 03242526, AGE 2, IMSI matches
   Remove stale TLLIs
   Peers:
-    NSEI 0, BVCI 20, not blocked, RAI 0-0-0-0
+    NSEI 0, BVCI 20, not blocked, RAI 000-000-0-0
       TLLI cache size                 : 1
       TLLI-Cache: 1
         TLLI c0000d80, IMSI 12345678, AGE 0, IMSI matches

-- 
To view, visit https://gerrit.osmocom.org/6672
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I7437dfaa586689e2bef0d4be6537e5577a8f6c26
Gerrit-PatchSet: 1
Gerrit-Project: osmo-sgsn
Gerrit-Branch: master
Gerrit-Owner: Neels Hofmeyr <[email protected]>

Reply via email to