[PATCH] osmo-iuh[master]: ensure unique CellIDs in HNB-GW

2018-02-22 Thread Stefan Sperling
Hello Jenkins Builder,

I'd like you to reexamine a change.  Please visit

https://gerrit.osmocom.org/6602

to look at the new patch set (#2).

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)

This change depends on a new API in libosmo-netif, which is added in
https://gerrit.osmocom.org/#/c/6844/

Change-Id: Iffd441eb2b6b75dfbe001b49b01bea015ca6e11c
Depends: I8ed78fe39c463e9018756700d13ee5ebe003b57f
Related: OS#2789
---
M include/osmocom/iuh/hnbgw.h
M src/hnbgw.c
M src/hnbgw_hnbap.c
3 files changed, 73 insertions(+), 6 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/osmo-iuh refs/changes/02/6602/2

diff --git a/include/osmocom/iuh/hnbgw.h b/include/osmocom/iuh/hnbgw.h
index 094f31f..b79bcc1 100644
--- a/include/osmocom/iuh/hnbgw.h
+++ b/include/osmocom/iuh/hnbgw.h
@@ -97,6 +97,10 @@
/*! 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;
 };
@@ -157,7 +161,7 @@
 void ue_context_free(struct ue_context *ue);
 
 struct hnb_context *hnb_context_alloc(struct hnb_gw *gw, struct 
osmo_stream_srv_link *link, int new_fd);
-void hnb_context_release(struct hnb_context *ctx);
+void hnb_context_release(struct hnb_context *ctx, bool destroy_conn);
 
 void hnbgw_vty_init(struct hnb_gw *gw, void *tall_ctx);
 int hnbgw_vty_go_parent(struct vty *vty);
diff --git a/src/hnbgw.c b/src/hnbgw.c
index cd492bb..94d8fb9 100644
--- a/src/hnbgw.c
+++ b/src/hnbgw.c
@@ -204,6 +204,12 @@
 }
 static int hnb_close_cb(struct osmo_stream_srv *conn)
 {
+   struct hnb_context *hnb = osmo_stream_srv_get_data(conn);
+
+   /* This connection is about to be closed. Destroy the HNB context now. 
*/
+   if (hnb)
+   hnb_context_release(hnb, false);
+
return 0;
 }
 
@@ -228,10 +234,10 @@
} else if (rc < 0) {
LOGP(DMAIN, LOGL_ERROR, "Error during sctp_recvmsg()\n");
/* FIXME: clean up after disappeared HNB */
-   hnb_context_release(hnb);
+   hnb_context_release(hnb, true);
goto out;
} else if (rc == 0) {
-   hnb_context_release(hnb);
+   hnb_context_release(hnb, true);
rc = -1;
 
goto out;
@@ -288,7 +294,7 @@
return ctx;
 }
 
-void hnb_context_release(struct hnb_context *ctx)
+void hnb_context_release(struct hnb_context *ctx, bool destroy_conn)
 {
struct hnbgw_context_map *map, *map2;
 
@@ -305,7 +311,9 @@
context_map_deactivate(map);
}
ue_context_free_by_hnb(ctx->gw, ctx);
-   osmo_stream_srv_destroy(ctx->conn);
+
+   if (destroy_conn)
+   osmo_stream_srv_destroy(ctx->conn);
 
talloc_free(ctx);
 }
diff --git a/src/hnbgw_hnbap.c b/src/hnbgw_hnbap.c
index 8fba13c..acc5aff 100644
--- a/src/hnbgw_hnbap.c
+++ b/src/hnbgw_hnbap.c
@@ -20,6 +20,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -46,6 +47,45 @@
osmo_stream_srv_send(ctx->conn, 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,
+   

[PATCH] osmo-iuh[master]: ensure unique CellIDs in HNB-GW

2018-02-19 Thread Stefan Sperling

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

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
---
M include/osmocom/iuh/hnbgw.h
M src/hnbgw_hnbap.c
2 files changed, 51 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/osmo-iuh refs/changes/02/6602/1

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 @@
/*! 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 
 #include 
+#include 
 #include 
 #include 
 
@@ -46,6 +47,37 @@
osmo_stream_srv_send(ctx->conn, 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)
@@ -368,6 +400,7 @@
 
 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 @@
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 */

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: Iffd441eb2b6b75dfbe001b49b01bea015ca6e11c
Gerrit-PatchSet: 1
Gerrit-Project: osmo-iuh
Gerrit-Branch: master
Gerrit-Owner: Stefan Sperling