laforge has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/osmo-hnbgw/+/36081?usp=email )


Change subject: Introduce concept of per-HNB persistent data structure
......................................................................

Introduce concept of per-HNB persistent data structure

This allows us to add a new "hnb-policy closed", which means we do not
accept any random HNB connection anymore, but only those whose identity
is pre-configured explicitly using administrative means.

Furthermore, this new data structure will allow us (in future patches)
to keep persistent data like uptime / downtime of each HNB.

Related: SYS#6773
Change-Id: Ife89a7a206836bd89334d19d3cf8c92969dd74de
---
M include/osmocom/hnbgw/hnbgw.h
M include/osmocom/hnbgw/vty.h
M src/osmo-hnbgw/hnbgw.c
M src/osmo-hnbgw/hnbgw_hnbap.c
M src/osmo-hnbgw/hnbgw_rua.c
M src/osmo-hnbgw/hnbgw_vty.c
6 files changed, 167 insertions(+), 3 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-hnbgw refs/changes/81/36081/1

diff --git a/include/osmocom/hnbgw/hnbgw.h b/include/osmocom/hnbgw/hnbgw.h
index f4f7dc1..59bb96b 100644
--- a/include/osmocom/hnbgw/hnbgw.h
+++ b/include/osmocom/hnbgw/hnbgw.h
@@ -233,6 +233,18 @@

        /* linked list of hnbgw_context_map */
        struct llist_head map_list;
+
+       /*! pointer to the associated hnb persistent state */
+       struct hnb_persistent *persistent;
+};
+
+/* persistent data for one HNB.  This continues to exist even as conn / 
hnb_context is deleted on disconnect */
+struct hnb_persistent {
+       /*! Entry in HNBGW-global list of hnb_persistent */
+       struct llist_head list;
+
+       /*! copied from HNB-Identity-Info IE */
+       char identity_info[256];
 };

 struct ue_context {
@@ -259,6 +271,7 @@
                bool hnbap_allow_tmsi;
                /*! print hnb-id (true) or MCC-MNC-LAC-RAC-SAC (false) in logs 
*/
                bool log_prefix_hnb_id;
+               bool accept_all_hnb;
                struct mgcp_client_conf *mgcp_client;
                struct {
                        char *local_addr;
@@ -275,6 +288,8 @@
        struct osmo_stream_srv_link *iuh;
        /* list of struct hnb_context */
        struct llist_head hnb_list;
+       /* list of struct hnb_persistent */
+       struct llist_head hnb_persistent_list;
        /* list of struct ue_context */
        struct llist_head ue_list;
        /* next availble UE Context ID */
@@ -323,6 +338,10 @@
 void hnb_context_release(struct hnb_context *ctx);
 void hnb_context_release_ue_state(struct hnb_context *ctx);

+struct hnb_persistent *hnb_persistent_alloc(const char *identity);
+struct hnb_persistent *hnb_persistent_find_by_identity(const char *identity);
+void hnb_persistent_free(struct hnb_persistent *hnbp);
+
 void hnbgw_vty_init(void);
 int hnbgw_vty_go_parent(struct vty *vty);

diff --git a/include/osmocom/hnbgw/vty.h b/include/osmocom/hnbgw/vty.h
index da0c469..9134521 100644
--- a/include/osmocom/hnbgw/vty.h
+++ b/include/osmocom/hnbgw/vty.h
@@ -4,6 +4,7 @@

 enum osmo_iuh_vty_node {
        HNBGW_NODE = _LAST_OSMOVTY_NODE + 1,
+       HNB_NODE,
        IUH_NODE,
        IUCS_NODE,
        IUPS_NODE,
diff --git a/src/osmo-hnbgw/hnbgw.c b/src/osmo-hnbgw/hnbgw.c
index 695822e..8a7626f 100644
--- a/src/osmo-hnbgw/hnbgw.c
+++ b/src/osmo-hnbgw/hnbgw.c
@@ -1,6 +1,6 @@
 /* kitchen sink for OsmoHNBGW implementation */

-/* (C) 2015 by Harald Welte <[email protected]>
+/* (C) 2015,2024 by Harald Welte <[email protected]>
  * (C) 2016-2023 by sysmocom s.f.m.c. GmbH <[email protected]>
  * All Rights Reserved
  *
@@ -266,7 +266,40 @@
        talloc_free(ctx);
 }

+/***********************************************************************
+ * HNB Persistent Data
+ ***********************************************************************/

+struct hnb_persistent *hnb_persistent_alloc(const char *identity)
+{
+       struct hnb_persistent *hnbp = talloc_zero(g_hnbgw, struct 
hnb_persistent);
+       if (!hnbp)
+               return NULL;
+
+       llist_add(&g_hnbgw->hnb_persistent_list, &hnbp->list);
+       OSMO_STRLCPY_ARRAY(hnbp->identity_info, identity);
+
+       return hnbp;
+}
+
+struct hnb_persistent *hnb_persistent_find_by_identity(const char *identity)
+{
+       struct hnb_persistent *hnbp;
+
+       llist_for_each_entry(hnbp, &g_hnbgw->hnb_persistent_list, list) {
+               if (!strcmp(hnbp->identity_info, identity))
+                       return hnbp;
+       }
+
+       return NULL;
+}
+
+void hnb_persistent_free(struct hnb_persistent *hnbp)
+{
+       /* FIXME: check if in use? */
+       llist_del(&hnbp->list);
+       talloc_free(hnbp);
+}

 /***********************************************************************
  * SCTP Socket / stream handling
@@ -585,6 +618,7 @@

        g_hnbgw->next_ue_ctx_id = 23;
        INIT_LLIST_HEAD(&g_hnbgw->hnb_list);
+       INIT_LLIST_HEAD(&g_hnbgw->hnb_persistent_list);
        INIT_LLIST_HEAD(&g_hnbgw->ue_list);
        INIT_LLIST_HEAD(&g_hnbgw->sccp.users);

diff --git a/src/osmo-hnbgw/hnbgw_hnbap.c b/src/osmo-hnbgw/hnbgw_hnbap.c
index 06d1a9d..f8c6bd6 100644
--- a/src/osmo-hnbgw/hnbgw_hnbap.c
+++ b/src/osmo-hnbgw/hnbgw_hnbap.c
@@ -404,21 +404,34 @@

 static int hnbgw_rx_hnb_register_req(struct hnb_context *ctx, ANY_t *in)
 {
+       struct hnb_persistent *hnbp;
        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];

        rc = hnbap_decode_hnbregisterrequesties(&ies, in);
        if (rc < 0) {
                LOGHNB(ctx, DHNBAP, LOGL_ERROR, "Failure to decode 
HNB-REGISTER-REQ: rc=%d\n", rc);
                return rc;
        }
+       asn1_strncpy(identity_str, &ies.hnB_Identity.hNB_Identity_Info, 
sizeof(identity_str));
+
+       hnbp = hnb_persistent_find_by_identity(identity_str);
+       if (!hnbp && g_hnbgw->config.accept_all_hnb)
+               hnbp = hnb_persistent_alloc(identity_str);
+
+       if (!hnbp) {
+               LOGHNB(ctx, DHNBAP, LOGL_NOTICE, "Rejecting unknonwn HNB with 
identity %s\n", identity_str);
+               hnbap_free_hnbregisterrequesties(&ies);
+               return hnbgw_tx_hnb_register_rej(ctx);
+       }
+       ctx->persistent = hnbp;

        /* copy all identity parameters from the message to ctx */
-       asn1_strncpy(ctx->identity_info, &ies.hnB_Identity.hNB_Identity_Info,
-                       sizeof(ctx->identity_info));
+       OSMO_STRLCPY_ARRAY(ctx->identity_info, identity_str);
        ctx->id.lac = asn1str_to_u16(&ies.lac);
        ctx->id.sac = asn1str_to_u16(&ies.sac);
        ctx->id.rac = asn1str_to_u8(&ies.rac);
diff --git a/src/osmo-hnbgw/hnbgw_rua.c b/src/osmo-hnbgw/hnbgw_rua.c
index d73f22d..76e3231 100644
--- a/src/osmo-hnbgw/hnbgw_rua.c
+++ b/src/osmo-hnbgw/hnbgw_rua.c
@@ -579,6 +579,10 @@
        asn_dec_rval_t dec_ret;
        int rc;

+       /* RUA is only processed after HNB registration, and as soon as the HNB 
is registered,
+        * it should have a persistent config associated with it */
+       OSMO_ASSERT(hnb->persistent);
+
        /* decode and handle to _hnbgw_hnbap_rx() */

        memset(pdu, 0, sizeof(*pdu));
diff --git a/src/osmo-hnbgw/hnbgw_vty.c b/src/osmo-hnbgw/hnbgw_vty.c
index cb34d7f..59afd6c 100644
--- a/src/osmo-hnbgw/hnbgw_vty.c
+++ b/src/osmo-hnbgw/hnbgw_vty.c
@@ -1,6 +1,7 @@
 /* HNB-GW interface to quagga VTY */

 /* (C) 2016 by sysmocom s.f.m.c. GmbH <[email protected]>
+ * (C) 2024 by Harald Welte <[email protected]>
  * All Rights Reserved
  *
  * This program is free software; you can redistribute it and/or modify
@@ -53,6 +54,12 @@
        return CMD_SUCCESS;
 }

+static struct cmd_node hnb_node = {
+       HNB_NODE,
+       "%s(config-hnbgw-hnb)# ",
+       1,
+};
+
 static struct cmd_node iuh_node = {
        IUH_NODE,
        "%s(config-hnbgw-iuh)# ",
@@ -355,6 +362,19 @@
        return CMD_SUCCESS;
 }

+DEFUN(cfg_hnbgw_hnb_policy, cfg_hnbgw_hnb_policy_cmd,
+       "hnb-policy (accept-all|closed)",
+       "Configure the policy of which HNB connections to accept\n"
+       "Accept HNB of any identity\n"
+       "Accept only HNB whose identity is explicitly configured via VTY\n")
+{
+       if (!strcmp(argv[0], "accept-all"))
+               g_hnbgw->config.accept_all_hnb = true;
+       else
+               g_hnbgw->config.accept_all_hnb = false;
+       return CMD_SUCCESS;
+}
+
 DEFUN_DEPRECATED(cfg_hnbgw_max_sccp_cr_payload_len, 
cfg_hnbgw_max_sccp_cr_payload_len_cmd,
       "sccp cr max-payload-len <0-999999>",
       "Configure SCCP behavior\n"
@@ -799,6 +819,43 @@
        return CMD_SUCCESS;
 }

+#define HNB_STR "hNodeB specific configuration\n"
+
+DEFUN(cfg_hnbgw_hnb, cfg_hnbgw_hnb_cmd,
+      "hnb IDENTITY_INFO",
+      HNB_STR
+      "Identity of hNodeB\n")
+{
+       struct hnb_persistent *hnbp = hnb_persistent_find_by_identity(argv[0]);
+       if (!hnbp)
+               hnbp = hnb_persistent_alloc(argv[0]);
+       if (!hnbp) {
+               vty_out(vty, "%% Could not create HNB '%s'%s", argv[0], 
VTY_NEWLINE);
+               return CMD_WARNING;
+       }
+
+       vty->index = hnbp;
+       vty->node = HNB_NODE;
+
+       return CMD_SUCCESS;
+}
+
+DEFUN(cfg_hnbgw_no_hnb, cfg_hnbgw_no_hnb_cmd,
+       "no hnb IDENTITY_INFO",
+       NO_STR "Remve configuration for specified hNodeB\n"
+       "Identity of hNodeB\n")
+{
+       struct hnb_persistent *hnbp = hnb_persistent_find_by_identity(argv[0]);
+
+       if (!hnbp) {
+               vty_out(vty, "%% Could not find any HNB for identity '%s'%s", 
argv[0], VTY_NEWLINE);
+               return CMD_WARNING;
+       }
+
+       hnb_persistent_free(hnbp);
+       return CMD_SUCCESS;
+}
+
 #if ENABLE_PFCP

 static struct cmd_node pfcp_node = {
@@ -889,8 +946,15 @@
        cnpool_write_nri(vty, cnpool, false);
 }

+static void write_one_hnbp(struct vty *vty, const struct hnb_persistent *hnbp)
+{
+       vty_out(vty, " hnb %s%s", hnbp->identity_info, VTY_NEWLINE);
+}
+
 static int config_write_hnbgw(struct vty *vty)
 {
+       const struct hnb_persistent *hnbp;
+
        vty_out(vty, "hnbgw%s", VTY_NEWLINE);

        if (g_hnbgw->config.plmn.mcc)
@@ -903,8 +967,15 @@

        vty_out(vty, " log-prefix %s%s", g_hnbgw->config.log_prefix_hnb_id ? 
"hnb-id" : "umts-cell-id",
                VTY_NEWLINE);
+
+       if (!g_hnbgw->config.accept_all_hnb)
+               vty_out(vty, " hnb-policy closed%s", VTY_NEWLINE);
+
        osmo_tdef_vty_groups_write(vty, " ");

+       llist_for_each_entry(hnbp, &g_hnbgw->hnb_persistent_list, list)
+               write_one_hnbp(vty, hnbp);
+
        _config_write_cnpool(vty, &g_hnbgw->sccp.cnpool_iucs);
        _config_write_cnpool(vty, &g_hnbgw->sccp.cnpool_iups);

@@ -1003,6 +1074,7 @@
        install_element(HNBGW_NODE, &cfg_hnbgw_rnc_id_cmd);
        install_element(HNBGW_NODE, &cfg_hnbgw_log_prefix_cmd);
        install_element(HNBGW_NODE, &cfg_hnbgw_max_sccp_cr_payload_len_cmd);
+       install_element(HNBGW_NODE, &cfg_hnbgw_hnb_policy_cmd);

        install_element(HNBGW_NODE, &cfg_hnbgw_iuh_cmd);
        install_node(&iuh_node, config_write_hnbgw_iuh);
@@ -1027,6 +1099,10 @@
        install_element(IUCS_NODE, &cfg_hnbgw_cnpool_remote_addr_cmd);
        install_element(IUPS_NODE, &cfg_hnbgw_cnpool_remote_addr_cmd);

+       install_element(HNBGW_NODE, &cfg_hnbgw_hnb_cmd);
+       install_element(HNBGW_NODE, &cfg_hnbgw_no_hnb_cmd);
+       install_node(&hnb_node, NULL);
+
        install_element_ve(&show_cnlink_cmd);
        install_element_ve(&show_hnb_cmd);
        install_element_ve(&show_one_hnb_cmd);

--
To view, visit https://gerrit.osmocom.org/c/osmo-hnbgw/+/36081?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: Ife89a7a206836bd89334d19d3cf8c92969dd74de
Gerrit-Change-Number: 36081
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <[email protected]>
Gerrit-MessageType: newchange

Reply via email to