aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Sperling <ssperling@sysmocom.de>2018-02-19 17:02:12 +0100
committerStefan Sperling <ssperling@sysmocom.de>2018-02-22 11:43:45 +0100
commitcc6ed397a63df49316dde1fd5e2385ca83f51aaf (patch)
treedc524f200ef5bd117db0a106495d2305404f5a56
parente1c01a02624b12a5c6396d47902482fa97217b23 (diff)
ensure unique CellIDs in HNB-GW
If we receive a HNB-REGISTER-REQ with a cell ID which is already used by another registered NNB, log an error and send HNB-REGISTER-REJECT. Tested manually by running two 'hnb-test' programs concurrently (they need to listen on different telnet ports; this port is hard-coded so I compiled two different hnb-test binaries). Then I issued the 'hnbap hnb register' command on the telnet interface of each, and verified that the correct action is logged by osmo-hnbgw. Both hnb-test programs can connect, but only one of them can register at a time. Killing a registered 'hnb-test' program terminates its connection and allows the previously rejected one to register. The new rejection log message looks like this: hnbgw_hnbap.c:429 rejecting HNB-REGISTER-REQ with duplicate cell identity MCC=901,MNC=99,LAC=49406,RAC=66,SAC=43947,CID=182250155 from (r=127.0.0.1:42828<->l=127.0.0.1:29169) Change-Id: Iffd441eb2b6b75dfbe001b49b01bea015ca6e11c Related: OS#2789
-rw-r--r--include/osmocom/iuh/hnbgw.h4
-rw-r--r--src/hnbgw_hnbap.c47
2 files changed, 51 insertions, 0 deletions
diff --git a/include/osmocom/iuh/hnbgw.h b/include/osmocom/iuh/hnbgw.h
index 094f31f..db49dc1 100644
--- a/include/osmocom/iuh/hnbgw.h
+++ b/include/osmocom/iuh/hnbgw.h
@@ -97,6 +97,10 @@ struct hnb_context {
/*! SCTP stream ID for RUA */
uint16_t rua_stream;
+ /*! True if a HNB-REGISTER-REQ from this HNB has been accepted. Note that
+ * this entire data structure is freed if the HNB sends HNB-DE-REGISTER-REQ. */
+ bool hnb_registered;
+
/* linked list of hnbgw_context_map */
struct llist_head map_list;
};
diff --git a/src/hnbgw_hnbap.c b/src/hnbgw_hnbap.c
index 8fba13c..c9a8807 100644
--- a/src/hnbgw_hnbap.c
+++ b/src/hnbgw_hnbap.c
@@ -20,6 +20,7 @@
#include <osmocom/core/msgb.h>
#include <osmocom/core/utils.h>
+#include <osmocom/core/socket.h>
#include <osmocom/gsm/gsm48.h>
#include <osmocom/netif/stream.h>
@@ -48,6 +49,37 @@ static int hnbgw_hnbap_tx(struct hnb_context *ctx, struct msgb *msg)
return 0;
}
+static int hnbgw_tx_hnb_register_rej(struct hnb_context *ctx)
+{
+ HNBRegisterReject_t reject_out;
+ HNBRegisterRejectIEs_t reject;
+ struct msgb *msg;
+ int rc;
+
+ reject.presenceMask = 0,
+ reject.cause.present = Cause_PR_radioNetwork;
+ reject.cause.choice.radioNetwork = CauseRadioNetwork_unspecified;
+
+ /* encode the Information Elements */
+ memset(&reject_out, 0, sizeof(reject_out));
+ rc = hnbap_encode_hnbregisterrejecties(&reject_out, &reject);
+ if (rc < 0) {
+ LOGP(DHNBAP, LOGL_ERROR, "Failure to encode HNB-REGISTER-REJECT to %s: rc=%d\n",
+ ctx->identity_info, rc);
+ return rc;
+ }
+
+ /* generate a successfull outcome PDU */
+ msg = hnbap_generate_unsuccessful_outcome(ProcedureCode_id_HNBRegister,
+ Criticality_reject,
+ &asn_DEF_HNBRegisterReject,
+ &reject_out);
+
+ ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_HNBRegisterReject, &reject_out);
+
+ return hnbgw_hnbap_tx(ctx, msg);
+}
+
static int hnbgw_tx_hnb_register_acc(struct hnb_context *ctx)
{
HNBRegisterAccept_t accept_out;
@@ -368,6 +400,7 @@ static int hnbgw_rx_hnb_deregister(struct hnb_context *ctx, ANY_t *in)
static int hnbgw_rx_hnb_register_req(struct hnb_context *ctx, ANY_t *in)
{
+ struct hnb_context *hnb;
HNBRegisterRequestIEs_t ies;
int rc;
@@ -387,6 +420,20 @@ static int hnbgw_rx_hnb_register_req(struct hnb_context *ctx, ANY_t *in)
ctx->id.cid = asn1bitstr_to_u28(&ies.cellIdentity);
gsm48_mcc_mnc_from_bcd(ies.plmNidentity.buf, &ctx->id.mcc, &ctx->id.mnc);
+ llist_for_each_entry(hnb, &ctx->gw->hnb_list, list) {
+ if (hnb->hnb_registered && ctx != hnb && memcmp(&ctx->id, &hnb->id, sizeof(ctx->id)) == 0) {
+ struct osmo_fd *ofd = osmo_stream_srv_get_ofd(ctx->conn);
+ char *name = osmo_sock_get_name(ctx, ofd->fd);
+ LOGP(DHNBAP, LOGL_ERROR, "rejecting HNB-REGISTER-REQ with duplicate cell identity "
+ "MCC=%u,MNC=%u,LAC=%u,RAC=%u,SAC=%u,CID=%u from %s\n",
+ ctx->id.mcc, ctx->id.mnc, ctx->id.lac, ctx->id.rac, ctx->id.sac, ctx->id.cid, name);
+ talloc_free(name);
+ return hnbgw_tx_hnb_register_rej(ctx);
+ }
+ }
+
+ ctx->hnb_registered = true;
+
DEBUGP(DHNBAP, "HNB-REGISTER-REQ from %s\n", ctx->identity_info);
/* Send HNBRegisterAccept */