neels has submitted this change. ( 
https://gerrit.osmocom.org/c/osmo-hnbgw/+/36893?usp=email )

Change subject: 3-digit MNC: use osmo_plmn_id in struct umts_cell_id
......................................................................

3-digit MNC: use osmo_plmn_id in struct umts_cell_id

Properly represent the mnc_3_digits flag in umts_cell_id, and preserve
the three digit indicator as received on the wire.

Before this patch, the indicator for a three digit MNC received on the
wire was discarded, and instead g_hnbgw->config.plmn.mnc_3_digits was
used to convert any PLMN to string, whether it had 3 digits or not.

== hnb_persistent_list:

The cell id is used as primary key in the list of hnb_persistent
instances. This patch prevents any collisions between 2-digit and
3-digit MNCs (however unlikely in practice this may be).

== nft_kpi.c:

Just like the cell ids in hnb_persistent, the ids' strings are used as
primary key in nftables rulesets in nft_kpi.c -- also prevent MNC
collisions there:

Properly transport the 3-digit property in conversions:
  struct umts_cell_id <-> string
Uncouple to_str conversion from the PLMN set in the hnbgw VTY cfg.

Related: OS#6457
Change-Id: Id9a91c80cd2745424a916aef4736993bb7cd8ba0
---
M include/osmocom/hnbgw/hnbgw.h
M src/osmo-hnbgw/hnbgw.c
M src/osmo-hnbgw/hnbgw_hnbap.c
M src/osmo-hnbgw/hnbgw_vty.c
M tests/umts_cell_id/umts_cell_id_test.c
M tests/umts_cell_id/umts_cell_id_test.ok
6 files changed, 94 insertions(+), 46 deletions(-)

Approvals:
  osmith: Looks good to me, but someone else must approve
  laforge: Looks good to me, but someone else must approve
  neels: Looks good to me, approved
  Jenkins Builder: Verified




diff --git a/include/osmocom/hnbgw/hnbgw.h b/include/osmocom/hnbgw/hnbgw.h
index 87844f4..9b07584 100644
--- a/include/osmocom/hnbgw/hnbgw.h
+++ b/include/osmocom/hnbgw/hnbgw.h
@@ -166,8 +166,7 @@
 };

 struct umts_cell_id {
-       uint16_t mcc;   /*!< Mobile Country Code (0-999) */
-       uint16_t mnc;   /*!< Mobile Network Code (0-999) */
+       struct osmo_plmn_id plmn;       /*!< Mobile Country Code and Mobile 
Network Code (000-00 to 999-999) */
        uint16_t lac;   /*!< Locaton Area Code (1-65534) */
        uint16_t rac;   /*!< Routing Area Code (0-255) */
        uint16_t sac;   /*!< Service Area Code */
@@ -182,9 +181,7 @@
 /*! are both given umts_cell_id euqal? */
 static inline bool umts_cell_id_equal(const struct umts_cell_id *a, const 
struct umts_cell_id *b)
 {
-       if (a->mcc != b->mcc)
-               return false;
-       if (a->mnc != b->mnc)
+       if (osmo_plmn_cmp(&a->plmn, &b->plmn))
                return false;
        if (a->lac != b->lac)
                return false;
diff --git a/src/osmo-hnbgw/hnbgw.c b/src/osmo-hnbgw/hnbgw.c
index 4f3fafa..20a665e 100644
--- a/src/osmo-hnbgw/hnbgw.c
+++ b/src/osmo-hnbgw/hnbgw.c
@@ -234,12 +234,10 @@

 int umts_cell_id_to_str_buf(char *buf, size_t buflen, const struct 
umts_cell_id *ucid)
 {
-       const char *fmtstr = "%03u-%02u-L%u-R%u-S%u-C%u";
-
-       if (g_hnbgw->config.plmn.mnc_3_digits)
-               fmtstr = "%03u-%03u-L%u-R%u-S%u-C%u";
-       return snprintf(buf, buflen, fmtstr, ucid->mcc, ucid->mnc, ucid->lac, 
ucid->rac,
-                       ucid->sac, ucid->cid);
+       struct osmo_strbuf sb = { .buf = buf, .len = buflen };
+       OSMO_STRBUF_APPEND_NOLEN(sb, osmo_plmn_name_buf, &ucid->plmn);
+       OSMO_STRBUF_PRINTF(sb, "-L%u-R%u-S%u-C%u", ucid->lac, ucid->rac, 
ucid->sac, ucid->cid);
+       return sb.chars_needed;
 }

 char *umts_cell_id_to_str_c(void *ctx, const struct umts_cell_id *ucid)
@@ -262,22 +260,38 @@
 int umts_cell_id_from_str(struct umts_cell_id *ucid, const char *instr)
 {
        int rc;
+       char buf[4];
+       const char *pos = instr;
+       const char *end;

        /* We want to use struct umts_cell_id as hashtable key. If it ever 
happens to contain any padding bytes, make
         * sure everything is deterministically zero. */
        memset(ucid, 0, sizeof(*ucid));

-       rc = sscanf(instr, "%hu-%hu-L%hu-R%hu-S%hu-C%u", &ucid->mcc, 
&ucid->mnc, &ucid->lac, &ucid->rac, &ucid->sac, &ucid->cid);
+       /* read MCC */
+       end = strchr(pos, '-');
+       if (!end || end <= pos || (end - pos) >= sizeof(buf))
+               return -EINVAL;
+       osmo_strlcpy(buf, pos, end - pos + 1);
+       if (osmo_mcc_from_str(buf, &ucid->plmn.mcc))
+               return -EINVAL;
+       pos = end + 1;
+
+       /* read MNC -- here the number of leading zeros matters. */
+       end = strchr(pos, '-');
+       if (!end || end == pos || (end - pos) >= sizeof(buf))
+               return -EINVAL;
+       osmo_strlcpy(buf, pos, end - pos + 1);
+       if (osmo_mnc_from_str(buf, &ucid->plmn.mnc, &ucid->plmn.mnc_3_digits))
+               return -EINVAL;
+       pos = end + 1;
+
+       /* parse the rest, where leading zeros do not matter */
+       rc = sscanf(pos, "L%hu-R%hu-S%hu-C%u", &ucid->lac, &ucid->rac, 
&ucid->sac, &ucid->cid);
        if (rc < 0)
                return -errno;

-       if (rc != 6)
-               return -EINVAL;
-
-       if (ucid->mcc > 999)
-               return -EINVAL;
-
-       if (ucid->mnc > 999)
+       if (rc != 4)
                return -EINVAL;

        if (ucid->lac == 0 || ucid->lac == 0xffff)
diff --git a/src/osmo-hnbgw/hnbgw_hnbap.c b/src/osmo-hnbgw/hnbgw_hnbap.c
index 29851a0..b220918 100644
--- a/src/osmo-hnbgw/hnbgw_hnbap.c
+++ b/src/osmo-hnbgw/hnbgw_hnbap.c
@@ -472,7 +472,6 @@
        struct hnb_context *hnb, *tmp;
        HNBAP_HNBRegisterRequestIEs_t ies;
        int rc;
-       struct osmo_plmn_id plmn;
        struct osmo_fd *ofd = osmo_stream_srv_get_ofd(ctx->conn);
        char identity_str[256];
        const char *cell_id_str;
@@ -500,9 +499,7 @@
        ctx->id.sac = asn1str_to_u16(&ies.sac);
        ctx->id.rac = asn1str_to_u8(&ies.rac);
        ctx->id.cid = asn1bitstr_to_u28(&ies.cellIdentity);
-       osmo_plmn_from_bcd(ies.plmNidentity.buf, &plmn);
-       ctx->id.mcc = plmn.mcc;
-       ctx->id.mnc = plmn.mnc;
+       osmo_plmn_from_bcd(ies.plmNidentity.buf, &ctx->id.plmn);
        cell_id_str = umts_cell_id_to_str(&ctx->id);

        if (getpeername(ofd->fd, &cur_osa.u.sa, &len) < 0) {
@@ -761,8 +758,7 @@
 {
        /* We don't care much about HNBAP */
        LOGHNB(hnb, DHNBAP, LOGL_ERROR, "Received Unsuccessful Outcome, 
procedureCode %ld, criticality %ld,"
-               " cell mcc %u mnc %u lac %u rac %u sac %u cid %u\n", 
msg->procedureCode, msg->criticality,
-               hnb->id.mcc, hnb->id.mnc, hnb->id.lac, hnb->id.rac, 
hnb->id.sac, hnb->id.cid);
+               " cell %s\n", msg->procedureCode, msg->criticality, 
umts_cell_id_to_str(&hnb->id));
        return 0;
 }

diff --git a/src/osmo-hnbgw/hnbgw_vty.c b/src/osmo-hnbgw/hnbgw_vty.c
index 8163197..d719c29 100644
--- a/src/osmo-hnbgw/hnbgw_vty.c
+++ b/src/osmo-hnbgw/hnbgw_vty.c
@@ -210,8 +210,9 @@
        vty_out(vty, "HNB ");
        vty_out_ofd_addr(vty, hnb->conn? osmo_stream_srv_get_ofd(hnb->conn) : 
NULL);
        vty_out(vty, " \"%s\"%s", hnb->identity_info, VTY_NEWLINE);
-       vty_out(vty, "    MCC %u MNC %u LAC %u RAC %u SAC %u CID %u 
SCTP-stream:HNBAP=%u,RUA=%u%s",
-               hnb->id.mcc, hnb->id.mnc, hnb->id.lac, hnb->id.rac, 
hnb->id.sac, hnb->id.cid,
+       vty_out(vty, "    MCC %s MNC %s LAC %u RAC %u SAC %u CID %u 
SCTP-stream:HNBAP=%u,RUA=%u%s",
+               osmo_mcc_name(hnb->id.plmn.mcc), 
osmo_mnc_name(hnb->id.plmn.mnc, hnb->id.plmn.mnc_3_digits),
+               hnb->id.lac, hnb->id.rac, hnb->id.sac, hnb->id.cid,
                hnb->hnbap_stream, hnb->rua_stream, VTY_NEWLINE);

        llist_for_each_entry(map, &hnb->map_list, hnb_list) {
diff --git a/tests/umts_cell_id/umts_cell_id_test.c 
b/tests/umts_cell_id/umts_cell_id_test.c
index e9183c4..a25b3d1 100644
--- a/tests/umts_cell_id/umts_cell_id_test.c
+++ b/tests/umts_cell_id/umts_cell_id_test.c
@@ -12,8 +12,10 @@
        {
                .id_str = "001-01-L1-R1-S1-C1",
                .id = {
-                       .mcc = 1,
-                       .mnc = 1,
+                       .plmn = {
+                               .mcc = 1,
+                               .mnc = 1,
+                       },
                        .lac = 1,
                        .rac = 1,
                        .sac = 1,
@@ -25,8 +27,11 @@
        {
                .id_str = "001-001-L1-R1-S1-C1",
                .id = {
-                       .mcc = 1,
-                       .mnc = 1,
+                       .plmn = {
+                               .mcc = 1,
+                               .mnc = 1,
+                               .mnc_3_digits = true,
+                       },
                        .lac = 1,
                        .rac = 1,
                        .sac = 1,
@@ -36,8 +41,11 @@
        {
                .id_str = "001-099-L1-R1-S1-C1",
                .id = {
-                       .mcc = 1,
-                       .mnc = 99,
+                       .plmn = {
+                               .mcc = 1,
+                               .mnc = 99,
+                               .mnc_3_digits = true,
+                       },
                        .lac = 1,
                        .rac = 1,
                        .sac = 1,
@@ -47,8 +55,11 @@
        {
                .id_str = "001-99-L1-R1-S1-C1",
                .id = {
-                       .mcc = 1,
-                       .mnc = 99,
+                       .plmn = {
+                               .mcc = 1,
+                               .mnc = 99,
+                               .mnc_3_digits = false,
+                       },
                        .lac = 1,
                        .rac = 1,
                        .sac = 1,
@@ -59,8 +70,11 @@
        {
                .id_str = "999-999-L65534-R65535-S65535-C268435455",
                .id = {
-                       .mcc = 999,
-                       .mnc = 999,
+                       .plmn = {
+                               .mcc = 999,
+                               .mnc = 999,
+                               .mnc_3_digits = true,
+                       },
                        .lac = 65534,
                        .rac = 65535,
                        .sac = 65535,
@@ -94,12 +108,7 @@

 int main(void)
 {
-       struct hnbgw hnbgw_dummy = {};
        struct test *t;
-
-       /* umts_cell_id_to_str() accesses g_hnbgw->config.plmn.mnc_3_digits, so 
make sure it is valid mem: */
-       g_hnbgw = &hnbgw_dummy;
-
        for (t = tests; (t - tests) < ARRAY_SIZE(tests); t++) {
                int rc;
                struct umts_cell_id parsed;
diff --git a/tests/umts_cell_id/umts_cell_id_test.ok 
b/tests/umts_cell_id/umts_cell_id_test.ok
index 457f78a..2c1992f 100644
--- a/tests/umts_cell_id/umts_cell_id_test.ok
+++ b/tests/umts_cell_id/umts_cell_id_test.ok
@@ -6,14 +6,12 @@
 "001-001-L1-R1-S1-C1"
   -> umts_cell_id_from_str(): ok
   -> umts_cell_id_to_str_buf(): ok
-  ERROR: conversion to umts_cell_id and back to string doesn't return the 
original string
-  -> "001-01-L1-R1-S1-C1"
+  -> "001-001-L1-R1-S1-C1"
   umts_cell_id_equal(expected, parsed): ok
 "001-099-L1-R1-S1-C1"
   -> umts_cell_id_from_str(): ok
   -> umts_cell_id_to_str_buf(): ok
-  ERROR: conversion to umts_cell_id and back to string doesn't return the 
original string
-  -> "001-99-L1-R1-S1-C1"
+  -> "001-099-L1-R1-S1-C1"
   umts_cell_id_equal(expected, parsed): ok
 "001-99-L1-R1-S1-C1"
   -> umts_cell_id_from_str(): ok

--
To view, visit https://gerrit.osmocom.org/c/osmo-hnbgw/+/36893?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-hnbgw
Gerrit-Branch: master
Gerrit-Change-Id: Id9a91c80cd2745424a916aef4736993bb7cd8ba0
Gerrit-Change-Number: 36893
Gerrit-PatchSet: 4
Gerrit-Owner: neels <nhofm...@sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <lafo...@osmocom.org>
Gerrit-Reviewer: neels <nhofm...@sysmocom.de>
Gerrit-Reviewer: osmith <osm...@sysmocom.de>
Gerrit-MessageType: merged

Reply via email to