Change in osmo-pcu[master]: Support Neighbor Address Resolution over PCUIF IPA multiplex

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

pespin gerrit-no-reply at lists.osmocom.org
Wed Sep 8 14:10:49 UTC 2021


pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-pcu/+/25404 )


Change subject: Support Neighbor Address Resolution over PCUIF IPA multiplex
......................................................................

Support Neighbor Address Resolution over PCUIF IPA multiplex

While NACC was initiall developed, it became clear there was need for a
way to interact PCU<->BSC in order resolve ARFCN+BSIC into CGI-PS for
later RIM usage.
Hence, this resolution was first (until today) implemented using an out
of bands RPC system using the CTRL interface, which required specific
config to be written and matches in osmo-pcu and osmo-bsc VTY (ip+port
of the CTRL interface to use).
However, this has several shortcomings:
* As explained above, specific configuration is required
* Since recently, we do support BSC redundancy in osmo-bts. Hence the BTS
  may switch to a BSC other than first one. If that happened, that'd mean
  the CTRL interface would still point to the initially configured one,
  which may not be the same currently serving the PCU.

During recent development of ANR related features, a similar need for
PCU<->BSC was required, but this time it was decided to extend the IPA
multiplex of the Abis OML connection to pass PCUIF messages,
transparently forwarded to each side by the BTS.
This has the advantage that connection PCU<->BTS is handled by BTS and
both sides send messages transparently.

Let's switch by default to using this new interface, while still
maintaing the old way for a while (announcing them as deprecated) to
avoid rbeaking existing deployments until they are upgraded to new
versions of osmo-pcu and osmo-bsc.

TODO: value inside container must be encoded in network order!!!

Related: SYS#4971
Change-Id: I6ad33c7ab10202840cf804dea9ba595978d0e920
---
M include/osmocom/pcu/pcuif_proto.h
M src/gprs_pcu.c
M src/nacc_fsm.c
M src/nacc_fsm.h
M src/pcu_l1_if.cpp
M src/pcu_l1_if.h
M src/pcu_vty.c
7 files changed, 233 insertions(+), 63 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/04/25404/1

diff --git a/include/osmocom/pcu/pcuif_proto.h b/include/osmocom/pcu/pcuif_proto.h
index 23b7a2c..8e40a27 100644
--- a/include/osmocom/pcu/pcuif_proto.h
+++ b/include/osmocom/pcu/pcuif_proto.h
@@ -26,6 +26,10 @@
 #define PCU_IF_MSG_TXT_IND	0x70	/* Text indication for BTS */
 #define PCU_IF_MSG_CONTAINER	0x80	/* Transparent container message */
 
+/* msg_type coming from BSC (inside PCU_IF_MSG_CONTAINER) */
+#define PCU_IF_MSG_NEIGH_ADDR_REQ	0x81	/* Neighbor Address Resolution Request */
+#define PCU_IF_MSG_NEIGH_ADDR_CNF	0x82	/* Neighbor Address Resolution Confirmation */
+
 /* sapi */
 #define PCU_IF_SAPI_RACH	0x01	/* channel request on CCCH */
 #define PCU_IF_SAPI_AGCH	0x02	/* assignment on AGCH */
@@ -228,6 +232,30 @@
 	uint8_t		data[0];
 } __attribute__ ((packed));
 
+/*** Used inside container: NOTE: values must be network byte order here! ***/
+/* Neighbor Address Resolution Request */
+struct gsm_pcu_if_neigh_addr_req {
+	uint16_t	local_lac;
+	uint16_t	local_ci;
+	uint16_t	tgt_arfcn;
+	uint8_t		tgt_bsic;
+} __attribute__ ((packed));
+
+/* Neighbor Address Resolution Confirmation */
+struct gsm_pcu_if_neigh_addr_cnf {
+	struct gsm_pcu_if_neigh_addr_req orig_req;
+	uint8_t		err_code; /* 0 success, !0 failed & below unset */
+	/* RAI + CI (CGI-PS): */
+	struct __attribute__ ((packed)) {
+		uint16_t	mcc;
+		uint16_t	mnc;
+		uint8_t		mnc_3_digits;
+		uint16_t	lac;
+		uint8_t		rac;
+		uint16_t	cell_identity;
+	} cgi_ps;
+} __attribute__ ((packed));
+
 struct gsm_pcu_if {
 	/* context based information */
 	uint8_t		msg_type;	/* message type */
diff --git a/src/gprs_pcu.c b/src/gprs_pcu.c
index a7bab8d..5ed9d7d 100644
--- a/src/gprs_pcu.c
+++ b/src/gprs_pcu.c
@@ -114,7 +114,7 @@
 	pcu->vty.ws_pdch = 0;
 	pcu->vty.llc_codel_interval_msec = LLC_CODEL_USE_DEFAULT;
 	pcu->vty.llc_idle_ack_csec = 10;
-	pcu->vty.neigh_ctrl_addr = talloc_strdup(pcu, "127.0.0.1");
+	pcu->vty.neigh_ctrl_addr = NULL; /* don't use CTRL iface for Neigh Addr Resolution */
 	pcu->vty.neigh_ctrl_port = OSMO_CTRL_PORT_BSC_NEIGH;
 
 	pcu->T_defs = T_defs_pcu;
diff --git a/src/nacc_fsm.c b/src/nacc_fsm.c
index 738b2c5..19f63e4 100644
--- a/src/nacc_fsm.c
+++ b/src/nacc_fsm.c
@@ -361,14 +361,72 @@
 	}
 }
 
+static int send_neigh_addr_req_ctrl_iface(struct nacc_fsm_ctx *ctx)
+{
+	struct gprs_rlcmac_bts *bts = ctx->ms->bts;
+	struct gprs_pcu *pcu = bts->pcu;
+	struct ctrl_cmd *cmd = NULL;
+	int rc;
+
+	/* We may have changed to this state previously (eg: we are handling
+	 * another Pkt cell Change Notify with different target). Avoid
+	 * re-creating the socket in that case. */
+	if (ctx->neigh_ctrl_conn->write_queue.bfd.fd == -1) {
+		rc = osmo_sock_init2_ofd(&ctx->neigh_ctrl_conn->write_queue.bfd,
+					 AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP,
+					 NULL, 0, pcu->vty.neigh_ctrl_addr, pcu->vty.neigh_ctrl_port,
+					 OSMO_SOCK_F_CONNECT);
+		if (rc < 0) {
+			LOGPFSML(ctx->fi, LOGL_ERROR,
+				"Failed to establish CTRL (neighbor resolution) connection to BSC r=%s:%u\n\n",
+				pcu->vty.neigh_ctrl_addr, pcu->vty.neigh_ctrl_port);
+			goto err_term;
+		}
+	}
+
+	cmd = ctrl_cmd_create(ctx, CTRL_TYPE_GET);
+	if (!cmd) {
+		LOGPFSML(ctx->fi, LOGL_ERROR, "CTRL msg creation failed\n");
+		goto err_term;
+	}
+
+	cmd->id = talloc_asprintf(cmd, "%u", arfcn_bsic_2_ctrl_id(ctx->neigh_key.tgt_arfcn,
+								  ctx->neigh_key.tgt_bsic));
+	cmd->variable = talloc_asprintf(cmd, "neighbor_resolve_cgi_ps_from_lac_ci.%d.%d.%d.%d",
+					ctx->neigh_key.local_lac, ctx->neigh_key.local_ci,
+					ctx->neigh_key.tgt_arfcn, ctx->neigh_key.tgt_bsic);
+	rc = ctrl_cmd_send(&ctx->neigh_ctrl_conn->write_queue, cmd);
+	if (rc) {
+		LOGPFSML(ctx->fi, LOGL_ERROR, "CTRL msg sent failed: %d\n", rc);
+		goto err_term;
+	}
+
+	talloc_free(cmd);
+	return 0;
+
+err_term:
+	talloc_free(cmd);
+	return -1;
+}
+
+static int send_neigh_addr_req(struct nacc_fsm_ctx *ctx)
+{
+	struct gprs_rlcmac_bts *bts = ctx->ms->bts;
+
+	/* If PCU was confiured tu se the old CTRL interface, use it: */
+	if (ctx->neigh_ctrl_conn)
+		return send_neigh_addr_req_ctrl_iface(ctx);
+
+	/* Otherwise, by default the new PCUIF over IPA Abis multiplex proto should be used: */
+	return pcu_tx_neigh_addr_res_req(bts, &ctx->neigh_key);
+}
+
 static void st_wait_resolve_rac_ci_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
 {
 	struct nacc_fsm_ctx *ctx = (struct nacc_fsm_ctx *)fi->priv;
 	struct gprs_rlcmac_bts *bts = ctx->ms->bts;
 	struct gprs_pcu *pcu = bts->pcu;
 	const struct osmo_cell_global_id_ps *cgi_ps;
-	struct ctrl_cmd *cmd = NULL;
-	int rc;
 
 	/* First try to find the value in the cache */
 	cgi_ps = neigh_cache_lookup_value(pcu->neigh_cache, &ctx->neigh_key);
@@ -383,45 +441,8 @@
 	LOGPFSML(fi, LOGL_DEBUG, "No CGI-PS found in cache, resolving " NEIGH_CACHE_ENTRY_KEY_FMT "...\n",
 		 NEIGH_CACHE_ENTRY_KEY_ARGS(&ctx->neigh_key));
 
-	/* We may have changed to this state previously (eg: we are handling
-	 * another Pkt cell Change Notify with different target). Avoid
-	 * re-creating the socket in that case. */
-	if (ctx->neigh_ctrl_conn->write_queue.bfd.fd == -1) {
-		rc = osmo_sock_init2_ofd(&ctx->neigh_ctrl_conn->write_queue.bfd,
-					 AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP,
-					 NULL, 0, pcu->vty.neigh_ctrl_addr, pcu->vty.neigh_ctrl_port,
-					 OSMO_SOCK_F_CONNECT);
-		if (rc < 0) {
-			LOGPFSML(fi, LOGL_ERROR,
-				"Failed to establish CTRL (neighbor resolution) connection to BSC r=%s:%u\n\n",
-				pcu->vty.neigh_ctrl_addr, pcu->vty.neigh_ctrl_port);
-			goto err_term;
-		}
-	}
-
-	cmd = ctrl_cmd_create(ctx, CTRL_TYPE_GET);
-	if (!cmd) {
-		LOGPFSML(fi, LOGL_ERROR, "CTRL msg creation failed\n");
-		goto err_term;
-	}
-
-	cmd->id = talloc_asprintf(cmd, "%u", arfcn_bsic_2_ctrl_id(ctx->neigh_key.tgt_arfcn,
-								  ctx->neigh_key.tgt_bsic));
-	cmd->variable = talloc_asprintf(cmd, "neighbor_resolve_cgi_ps_from_lac_ci.%d.%d.%d.%d",
-					ctx->neigh_key.local_lac, ctx->neigh_key.local_ci,
-					ctx->neigh_key.tgt_arfcn, ctx->neigh_key.tgt_bsic);
-	rc = ctrl_cmd_send(&ctx->neigh_ctrl_conn->write_queue, cmd);
-	if (rc) {
-		LOGPFSML(fi, LOGL_ERROR, "CTRL msg sent failed: %d\n", rc);
-		goto err_term;
-	}
-
-	talloc_free(cmd);
-	return;
-
-err_term:
-	talloc_free(cmd);
-	nacc_fsm_state_chg(fi, NACC_ST_TX_CELL_CHG_CONTINUE);
+	if (send_neigh_addr_req(ctx) < 0)
+		nacc_fsm_state_chg(fi, NACC_ST_TX_CELL_CHG_CONTINUE);
 }
 
 static void st_wait_resolve_rac_ci(struct osmo_fsm_inst *fi, uint32_t event, void *data)
@@ -435,8 +456,14 @@
 		handle_retrans_pkt_cell_chg_notif(ctx, notif);
 		break;
 	case NACC_EV_RX_RAC_CI:
-		/* Assumption: ctx->cgi_ps has been filled by caller of the event */
-		nacc_fsm_state_chg(fi, NACC_ST_WAIT_REQUEST_SI);
+		/* data is NULL upon failure */
+		if (data) {
+			ctx->cgi_ps = *(struct osmo_cell_global_id_ps *)data;
+			nacc_fsm_state_chg(fi, NACC_ST_WAIT_REQUEST_SI);
+		}
+		else {
+			nacc_fsm_state_chg(fi, NACC_ST_TX_CELL_CHG_CONTINUE);
+		}
 		break;
 	default:
 		OSMO_ASSERT(0);
@@ -740,12 +767,13 @@
 	struct nacc_fsm_ctx *ctx = (struct nacc_fsm_ctx *)data;
 	char *tmp = NULL, *tok, *saveptr;
 	unsigned int exp_id;
+	struct osmo_cell_global_id_ps cgi_ps;
 
 	LOGPFSML(ctx->fi, LOGL_NOTICE, "Received CTRL message: type=%d %s %s: %s\n",
 		 cmd->type, cmd->variable, cmd->id, osmo_escape_str(cmd->reply, -1));
 
 	if (cmd->type != CTRL_TYPE_GET_REPLY || !cmd->reply) {
-		nacc_fsm_state_chg(ctx->fi, NACC_ST_TX_CELL_CHG_CONTINUE);
+		osmo_fsm_inst_dispatch(ctx->fi, NACC_EV_RX_RAC_CI, NULL);
 		return;
 	}
 
@@ -771,33 +799,33 @@
 
 	if (!(tok = strtok_r(tmp, "-", &saveptr)))
 		goto free_ret;
-	ctx->cgi_ps.rai.lac.plmn.mcc = atoi(tok);
+	cgi_ps.rai.lac.plmn.mcc = atoi(tok);
 
 	if (!(tok = strtok_r(NULL, "-", &saveptr)))
 		goto free_ret;
-	ctx->cgi_ps.rai.lac.plmn.mnc = atoi(tok);
+	cgi_ps.rai.lac.plmn.mnc = atoi(tok);
 
 	if (!(tok = strtok_r(NULL, "-", &saveptr)))
 		goto free_ret;
-	ctx->cgi_ps.rai.lac.lac = atoi(tok);
+	cgi_ps.rai.lac.lac = atoi(tok);
 
 	if (!(tok = strtok_r(NULL, "-", &saveptr)))
 		goto free_ret;
-	ctx->cgi_ps.rai.rac = atoi(tok);
+	cgi_ps.rai.rac = atoi(tok);
 
 	if (!(tok = strtok_r(NULL, "\0", &saveptr)))
 		goto free_ret;
-	ctx->cgi_ps.cell_identity = atoi(tok);
+	cgi_ps.cell_identity = atoi(tok);
 
 	/* Cache the cgi_ps so we can avoid requesting again same resolution for a while */
-	neigh_cache_add(ctx->ms->bts->pcu->neigh_cache, &ctx->neigh_key, &ctx->cgi_ps);
+	neigh_cache_add(ctx->ms->bts->pcu->neigh_cache, &ctx->neigh_key, &cgi_ps);
 
-	osmo_fsm_inst_dispatch(ctx->fi, NACC_EV_RX_RAC_CI, NULL);
+	osmo_fsm_inst_dispatch(ctx->fi, NACC_EV_RX_RAC_CI, &cgi_ps);
 	return;
 
 free_ret:
 	talloc_free(tmp);
-	nacc_fsm_state_chg(ctx->fi, NACC_ST_TX_CELL_CHG_CONTINUE);
+	osmo_fsm_inst_dispatch(ctx->fi, NACC_EV_RX_RAC_CI, NULL);
 	return;
 }
 
@@ -834,18 +862,29 @@
 	if (!ctx->fi)
 		goto free_ret;
 
-	ctx->neigh_ctrl = ctrl_handle_alloc(ctx, ctx, NULL);
-	ctx->neigh_ctrl->reply_cb = nacc_fsm_ctrl_reply_cb;
-	ctx->neigh_ctrl_conn = osmo_ctrl_conn_alloc(ctx, ctx->neigh_ctrl);
-	if (!ctx->neigh_ctrl_conn)
-		goto free_ret;
-	/* Older versions of osmo_ctrl_conn_alloc didn't properly initialize fd to -1,
-	 * so make sure to do it here otherwise fd may be valid fd 0 and cause trouble */
-	ctx->neigh_ctrl_conn->write_queue.bfd.fd = -1;
-	llist_add(&ctx->neigh_ctrl_conn->list_entry, &ctx->neigh_ctrl->ccon_list);
+	/* If CTRL ip present, use the old CTRL interface for neighbor resolution */
+	if (ms->bts->pcu->vty.neigh_ctrl_addr) {
+		ctx->neigh_ctrl = ctrl_handle_alloc(ctx, ctx, NULL);
+		ctx->neigh_ctrl->reply_cb = nacc_fsm_ctrl_reply_cb;
+		ctx->neigh_ctrl_conn = osmo_ctrl_conn_alloc(ctx, ctx->neigh_ctrl);
+		if (!ctx->neigh_ctrl_conn)
+			goto free_ret;
+		/* Older versions of osmo_ctrl_conn_alloc didn't properly initialize fd to -1,
+		 * so make sure to do it here otherwise fd may be valid fd 0 and cause trouble */
+		ctx->neigh_ctrl_conn->write_queue.bfd.fd = -1;
+		llist_add(&ctx->neigh_ctrl_conn->list_entry, &ctx->neigh_ctrl->ccon_list);
+	}
 
 	return ctx;
 free_ret:
 	talloc_free(ctx);
 	return NULL;
 }
+
+bool nacc_fsm_is_waiting_addr_resolution(const struct nacc_fsm_ctx *ctx,
+					 const struct neigh_cache_entry_key *neigh_key)
+{
+	if (ctx->fi->state != NACC_ST_WAIT_RESOLVE_RAC_CI)
+		return false;
+	return neigh_cache_entry_key_eq(&ctx->neigh_key, neigh_key);
+}
diff --git a/src/nacc_fsm.h b/src/nacc_fsm.h
index 7b0adfd..04c9ba4 100644
--- a/src/nacc_fsm.h
+++ b/src/nacc_fsm.h
@@ -29,7 +29,7 @@
 
 enum nacc_fsm_event {
 	NACC_EV_RX_CELL_CHG_NOTIFICATION, /* data: Packet_Cell_Change_Notification_t* */
-	NACC_EV_RX_RAC_CI, /* no data passed, RAC_CI became available in neigh_cache */
+	NACC_EV_RX_RAC_CI, /* RAC_CI became available in neigh_cache. NULL on failure, pointer to ctx->cgi_ps on success */
 	NACC_EV_RX_SI, /* data: struct si_cache_entry* */
 	NACC_EV_CREATE_RLCMAC_MSG, /* data: struct nacc_ev_create_rlcmac_msg_ctx* */
 	NACC_EV_RX_CELL_CHG_CONTINUE_ACK,
@@ -69,3 +69,6 @@
 };
 
 struct nacc_fsm_ctx *nacc_fsm_alloc(struct GprsMs* ms);
+
+bool nacc_fsm_is_waiting_addr_resolution(const struct nacc_fsm_ctx *ctx,
+					 const struct neigh_cache_entry_key *neigh_key);
diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp
index 4530e1a..4fe5627 100644
--- a/src/pcu_l1_if.cpp
+++ b/src/pcu_l1_if.cpp
@@ -44,6 +44,8 @@
 #include <osmocom/gsm/protocol/gsm_04_08.h>
 #include <osmocom/gsm/gsm48_rest_octets.h>
 #include <osmocom/gsm/sysinfo.h>
+
+#include <nacc_fsm.h>
 }
 
 #include <gprs_rlcmac.h>
@@ -95,6 +97,7 @@
  * PCU messages
  */
 
+/* Can be used to allocate message with non-variable size */
 struct msgb *pcu_msgb_alloc(uint8_t msg_type, uint8_t bts_nr)
 {
 	struct msgb *msg;
@@ -111,6 +114,21 @@
 	return msg;
 }
 
+/* Allocate message with extra size, only reserve pcuif msg hdr */
+static struct msgb *pcu_msgb_alloc_ext_size(uint8_t msg_type, uint8_t bts_nr, size_t extra_size)
+{
+	struct msgb *msg;
+	struct gsm_pcu_if *pcu_prim;
+	msg = msgb_alloc(sizeof(struct gsm_pcu_if) + extra_size, "pcu_sock_tx");
+	/* Only header is filled, caller is responible for reserving + filling
+	 * message type specific contents: */
+	msgb_put(msg, PCUIF_HDR_SIZE);
+	pcu_prim = (struct gsm_pcu_if *) msgb_data(msg);
+	pcu_prim->msg_type = msg_type;
+	pcu_prim->bts_nr = bts_nr;
+	return msg;
+}
+
 const struct value_string gsm_pcu_if_text_type_names[] = {
 	OSMO_VALUE_STRING(PCU_VERSION),
 	OSMO_VALUE_STRING(PCU_OML_ALERT),
@@ -271,6 +289,33 @@
 	pcu_tx_data_req(bts, 0, 0, PCU_IF_SAPI_PCH, 0, 0, 0, data, PAGING_GROUP_LEN + GSM_MACBLOCK_LEN);
 }
 
+int pcu_tx_neigh_addr_res_req(struct gprs_rlcmac_bts *bts, const struct neigh_cache_entry_key *neigh_key)
+{
+	struct msgb *msg;
+	struct gsm_pcu_if *pcu_prim;
+	struct gsm_pcu_if_neigh_addr_req *naddr_req;
+
+	LOGP(DL1IF, LOGL_DEBUG, "(bts=%u) Tx Neighbor Address Resolution Request: " NEIGH_CACHE_ENTRY_KEY_FMT "\n",
+	     bts->nr, NEIGH_CACHE_ENTRY_KEY_ARGS(neigh_key));
+
+	msg = pcu_msgb_alloc_ext_size(PCU_IF_MSG_CONTAINER, bts->nr, sizeof(struct gsm_pcu_if_neigh_addr_req));
+	if (!msg)
+		return -ENOMEM;
+	pcu_prim = (struct gsm_pcu_if *) msgb_data(msg);
+	naddr_req = (struct gsm_pcu_if_neigh_addr_req *)&pcu_prim->u.container.data[0];
+
+	msgb_put(msg, sizeof(pcu_prim->u.container) + sizeof(struct gsm_pcu_if_neigh_addr_req));
+	pcu_prim->u.container.msg_type = PCU_IF_MSG_NEIGH_ADDR_REQ;
+	osmo_store16be(sizeof(struct gsm_pcu_if_neigh_addr_req), &pcu_prim->u.container.length);
+
+	osmo_store16be(neigh_key->local_lac, &naddr_req->local_lac);
+	osmo_store16be(neigh_key->local_ci, &naddr_req->local_ci);
+	osmo_store16be(neigh_key->tgt_arfcn, &naddr_req->tgt_arfcn);
+	naddr_req->tgt_bsic = neigh_key->tgt_bsic;
+
+	return pcu_sock_send(msg);
+}
+
 void pcu_rx_block_time(struct gprs_rlcmac_bts *bts, uint16_t arfcn, uint32_t fn, uint8_t ts_no)
 {
 	bts_set_current_block_frame_number(bts, fn);
@@ -955,11 +1000,60 @@
 	return 0;
 }
 
+static int pcu_rx_neigh_addr_cnf(struct gprs_rlcmac_bts *bts, struct gsm_pcu_if_neigh_addr_cnf *naddr_cnf)
+{
+	struct llist_head *tmp;
+	struct osmo_cell_global_id_ps cgi_ps;
+	struct osmo_cell_global_id_ps *cgi_ps_ptr = &cgi_ps;
+
+	struct neigh_cache_entry_key neigh_key = {
+		.local_lac = osmo_load16be(&naddr_cnf->orig_req.local_lac),
+		.local_ci = osmo_load16be(&naddr_cnf->orig_req.local_ci),
+		.tgt_arfcn = osmo_load16be(&naddr_cnf->orig_req.tgt_arfcn),
+		.tgt_bsic = naddr_cnf->orig_req.tgt_bsic,
+	};
+
+	if (naddr_cnf->err_code == 0) {
+		cgi_ps.rai.lac.plmn.mcc = osmo_load16be(&naddr_cnf->cgi_ps.mcc);
+		cgi_ps.rai.lac.plmn.mnc = osmo_load16be(&naddr_cnf->cgi_ps.mnc);
+		cgi_ps.rai.lac.plmn.mnc_3_digits = cgi_ps.rai.lac.plmn.mnc > 99;
+		cgi_ps.rai.lac.lac = osmo_load16be(&naddr_cnf->cgi_ps.lac);
+		cgi_ps.rai.rac = naddr_cnf->cgi_ps.rac;
+		cgi_ps.cell_identity = osmo_load16be(&naddr_cnf->cgi_ps.cell_identity);
+
+		LOGP(DL1IF, LOGL_INFO, "Rx Neighbor Address Resolution Confirmation for " NEIGH_CACHE_ENTRY_KEY_FMT ": %s\n",
+		     NEIGH_CACHE_ENTRY_KEY_ARGS(&neigh_key), osmo_cgi_ps_name(&cgi_ps));
+
+		/* Cache the cgi_ps so we can avoid requesting again same resolution for a while */
+		neigh_cache_add(bts->pcu->neigh_cache, &neigh_key, &cgi_ps);
+	} else {
+		cgi_ps_ptr = NULL;
+		LOGP(DL1IF, LOGL_INFO, "Rx Neighbor Address Resolution Confirmation for " NEIGH_CACHE_ENTRY_KEY_FMT ": failed with err_code=%u\n",
+		     NEIGH_CACHE_ENTRY_KEY_ARGS(&neigh_key), naddr_cnf->err_code);
+	}
+
+	llist_for_each(tmp, bts_ms_store(bts)->ms_list()) {
+		GprsMs *ms = llist_entry(tmp, typeof(*ms), list);
+		if (ms->nacc && nacc_fsm_is_waiting_addr_resolution(ms->nacc, &neigh_key))
+			osmo_fsm_inst_dispatch(ms->nacc->fi, NACC_EV_RX_RAC_CI, cgi_ps_ptr);
+	}
+	return 0;
+}
+
 static int pcu_rx_container(struct gprs_rlcmac_bts *bts, struct gsm_pcu_if_container *container)
 {
 	int rc;
+	uint16_t data_length = osmo_load16be(&container->length);
 
 	switch (container->msg_type) {
+	case PCU_IF_MSG_NEIGH_ADDR_CNF:
+		if (data_length < sizeof(struct gsm_pcu_if_neigh_addr_cnf)) {
+			LOGP(DL1IF, LOGL_ERROR, "Rx container(NEIGH_ADDR_CNF) message too short: %u vs exp %lu\n",
+			     data_length, sizeof(struct gsm_pcu_if_neigh_addr_cnf));
+			return -EINVAL;
+		}
+		rc = pcu_rx_neigh_addr_cnf(bts, (struct gsm_pcu_if_neigh_addr_cnf*)&container->data);
+		break;
 	default:
 		LOGP(DL1IF, LOGL_NOTICE, "(bts=%d) Rx unexpected msg type (%u) inside container!\n",
 		     bts->nr, container->msg_type);
diff --git a/src/pcu_l1_if.h b/src/pcu_l1_if.h
index 2a4f0ea..7d48feb 100644
--- a/src/pcu_l1_if.h
+++ b/src/pcu_l1_if.h
@@ -160,6 +160,8 @@
 #endif
 struct gprs_rlcmac_bts;
 
+int pcu_tx_neigh_addr_res_req(struct gprs_rlcmac_bts *bts, const struct neigh_cache_entry_key *neigh_key);
+
 int pcu_rx(struct gsm_pcu_if *pcu_prim, size_t pcu_prim_length);
 int pcu_l1if_open(void);
 void pcu_l1if_close(void);
diff --git a/src/pcu_vty.c b/src/pcu_vty.c
index 1ca6376..4b4310d 100644
--- a/src/pcu_vty.c
+++ b/src/pcu_vty.c
@@ -1067,6 +1067,10 @@
        "IPv4 address to connect to\n" "IPv6 address to connect to\n"
        "Port to connect to (default 4248)\n")
 {
+	vty_out(vty, "%% Warning: The CTRL interface for Neighbor Address Resolution is now deprecated."
+	 	"Upgrade osmo-bsc and drop the 'neighbor resolution " VTY_IPV46_CMD " [<0-65535>]' VTY "
+		"option in order to let osmo-pcu use the new resoluton method using the PCUIF over IPA "
+		"multiplex, which will work out of the box without required configuration.%s", VTY_NEWLINE);
 	osmo_talloc_replace_string(the_pcu, &the_pcu->vty.neigh_ctrl_addr, argv[0]);
 	if (argc > 1)
 		the_pcu->vty.neigh_ctrl_port = atoi(argv[1]);

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-pcu/+/25404
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-pcu
Gerrit-Branch: master
Gerrit-Change-Id: I6ad33c7ab10202840cf804dea9ba595978d0e920
Gerrit-Change-Number: 25404
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin at sysmocom.de>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210908/dd4bec55/attachment.htm>


More information about the gerrit-log mailing list