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 <laforge(a)gnumonks.org>
+/* (C) 2015,2024 by Harald Welte <laforge(a)gnumonks.org>
* (C) 2016-2023 by sysmocom s.f.m.c. GmbH <info(a)sysmocom.de>
* 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 <info(a)sysmocom.de>
+ * (C) 2024 by Harald Welte <laforge(a)gnumonks.org>
* 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 <laforge(a)osmocom.org>
Gerrit-MessageType: newchange