<p>pespin <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/osmo-pcu/+/25404">View Change</a></p><div style="white-space:pre-wrap">Approvals:
Jenkins Builder: Verified
osmith: Looks good to me, but someone else must approve
pespin: Looks good to me, approved
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Support Neighbor Address Resolution over PCUIF IPA multiplex<br><br>While NACC was initially developed, it became clear there was need for<br>a way to interact PCU<->BSC in order resolve ARFCN+BSIC into CGI-PS<br>for later RIM usage.<br>Hence, this resolution was first (until today) implemented using an out<br>of bands RPC system using the CTRL interface, which required specific<br>config to be written and matches in osmo-pcu and osmo-bsc VTY (ip+port<br>of the CTRL interface to use).<br>However, this has several shortcomings:<br>* As explained above, specific configuration is required<br>* Since recently, we do support BSC redundancy in osmo-bts. Hence the BTS<br> may switch to a BSC other than first one. If that happened, that'd mean<br> the CTRL interface would still point to the initially configured one,<br> which may not be the same currently serving the PCU.<br><br>During recent development of ANR related features, a similar need for<br>PCU<->BSC was required, but this time it was decided to extend the IPA<br>multiplex of the Abis OML connection to pass PCUIF messages,<br>transparently forwarded to each side by the BTS.<br>This has the advantage that connection PCU<->BTS is handled by BTS and<br>both sides send messages transparently.<br><br>Let's switch by default to using this new interface, while still<br>maintaing the old way for a while (announcing them as deprecated) to<br>avoid breaking existing deployments until they are upgraded to new<br>versions of osmo-pcu and osmo-bsc.<br><br>Related: SYS#4971<br>Change-Id: I6ad33c7ab10202840cf804dea9ba595978d0e920<br>---<br>M doc/manuals/chapters/configuration.adoc<br>M include/osmocom/pcu/pcuif_proto.h<br>M src/gprs_pcu.c<br>M src/nacc_fsm.c<br>M src/nacc_fsm.h<br>M src/pcu_l1_if.cpp<br>M src/pcu_l1_if.h<br>M src/pcu_vty.c<br>8 files changed, 266 insertions(+), 73 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/doc/manuals/chapters/configuration.adoc b/doc/manuals/chapters/configuration.adoc</span><br><span>index d031ce6..d778929 100644</span><br><span>--- a/doc/manuals/chapters/configuration.adoc</span><br><span>+++ b/doc/manuals/chapters/configuration.adoc</span><br><span>@@ -252,8 +252,40 @@</span><br><span> CGI-PS, since it actually equals to the Circuit Switch CGI + RAC.</span><br><span> </span><br><span> In order to apply this target cell identity translation, OsmoPCU uses the</span><br><span style="color: hsl(0, 100%, 40%);">-OsmoBSC Neighbor Resolution CTRL interface (see OsmoBSC User Manual), since the</span><br><span style="color: hsl(0, 100%, 40%);">-BSC is the node holding all the neighbor related information.</span><br><span style="color: hsl(120, 100%, 40%);">+OsmoBSC Neighbor Resolution Service. This service is nowadays provided by means</span><br><span style="color: hsl(120, 100%, 40%);">+of PCUIF container messages, which are transparently forwarded in both directions</span><br><span style="color: hsl(120, 100%, 40%);">+by the BTS using the IPA multiplex of the OML connection against the BSC. No</span><br><span style="color: hsl(120, 100%, 40%);">+specific configuration is required in any of the involved nodes, they should</span><br><span style="color: hsl(120, 100%, 40%);">+behave properly out of the box.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+These neighbor address resolutions (<ARFCN + BSIC> => <RAI + CI>) are by default</span><br><span style="color: hsl(120, 100%, 40%);">+cached for a while, in order to avoid querying the BSC frequently. As a result,</span><br><span style="color: hsl(120, 100%, 40%);">+the resolution time is also optimized.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+.Example: Configure Neighbor Resolution cache and timeouts</span><br><span style="color: hsl(120, 100%, 40%);">+----</span><br><span style="color: hsl(120, 100%, 40%);">+pcu</span><br><span style="color: hsl(120, 100%, 40%);">+ timer X1 500 <1></span><br><span style="color: hsl(120, 100%, 40%);">+ timer X0 60 <2></span><br><span style="color: hsl(120, 100%, 40%);">+----</span><br><span style="color: hsl(120, 100%, 40%);">+<1> Time out if the BSC doesn't answer our resolution request after 500 ms</span><br><span style="color: hsl(120, 100%, 40%);">+<2> Keep resolved neighbor addresses cached for 60 seconds</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+===== OsmoBSC CTRL interface (deprecated)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+CAUTION: This interface is nowadays considered deprecated and should not be used</span><br><span style="color: hsl(120, 100%, 40%);">+anymore. Any related VTY options should be dropped from configuration files, to</span><br><span style="color: hsl(120, 100%, 40%);">+let OsmoPCU use the new interface instead. This section is kept here for a while</span><br><span style="color: hsl(120, 100%, 40%);">+as a reference for old deployments using old versions of the programs.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+This Neighbor Address Resolution Service was initially implemented by means of a</span><br><span style="color: hsl(120, 100%, 40%);">+separate CTRL interface (see OsmoBSC User Manual), where OsmoPCU would create a</span><br><span style="color: hsl(120, 100%, 40%);">+CTRL connection to the BSC each time an address resolution was required.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+Older versions of OsmoBSC may not support the current Neighbor Address</span><br><span style="color: hsl(120, 100%, 40%);">+Resolution Service over the IPA multiplex (see above). For those cases, OsmoPCU</span><br><span style="color: hsl(120, 100%, 40%);">+can be configured to use the old deprecated CTRL interface.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> By default, the use of this interface is not configured and hence disabled in</span><br><span> OsmoPCU. As a result, until configured, the network won't be able to provide the</span><br><span> System Information to the MS prior to allowing the change during NACC against</span><br><span>@@ -261,20 +293,12 @@</span><br><span> to configure the interface, the OsmoBSC IP address and port to connect to must</span><br><span> be configured in OsmoPCU VTY.</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-These neighbor address resolutions (<ARFCN + BSIC> => <RAI + CI>) are by default</span><br><span style="color: hsl(0, 100%, 40%);">-cached for a while in order to avoid querying the BSC frequently and, as a</span><br><span style="color: hsl(0, 100%, 40%);">-result, optimizing the resolution time too.</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> .Example: Configure Neighbor Resolution CTRL interface against OsmoBSC</span><br><span> ----</span><br><span> pcu</span><br><span> neighbor resolution 172.18.13.10 4248 <1></span><br><span style="color: hsl(0, 100%, 40%);">- timer X1 500 <2></span><br><span style="color: hsl(0, 100%, 40%);">- timer X0 60 <3></span><br><span> ----</span><br><span> <1> Port 4248 is the default and hence could be omitted in this case</span><br><span style="color: hsl(0, 100%, 40%);">-<2> Time out if the BSC doesn't answer our CTRL resolution request after 500 ms</span><br><span style="color: hsl(0, 100%, 40%);">-<3> Keep resolved neighbor addresses cached for 60 seconds</span><br><span> </span><br><span> ==== System Information Resolution</span><br><span> </span><br><span>diff --git a/include/osmocom/pcu/pcuif_proto.h b/include/osmocom/pcu/pcuif_proto.h</span><br><span>index 23b7a2c..8e40a27 100644</span><br><span>--- a/include/osmocom/pcu/pcuif_proto.h</span><br><span>+++ b/include/osmocom/pcu/pcuif_proto.h</span><br><span>@@ -26,6 +26,10 @@</span><br><span> #define PCU_IF_MSG_TXT_IND 0x70 /* Text indication for BTS */</span><br><span> #define PCU_IF_MSG_CONTAINER 0x80 /* Transparent container message */</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* msg_type coming from BSC (inside PCU_IF_MSG_CONTAINER) */</span><br><span style="color: hsl(120, 100%, 40%);">+#define PCU_IF_MSG_NEIGH_ADDR_REQ 0x81 /* Neighbor Address Resolution Request */</span><br><span style="color: hsl(120, 100%, 40%);">+#define PCU_IF_MSG_NEIGH_ADDR_CNF 0x82 /* Neighbor Address Resolution Confirmation */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* sapi */</span><br><span> #define PCU_IF_SAPI_RACH 0x01 /* channel request on CCCH */</span><br><span> #define PCU_IF_SAPI_AGCH 0x02 /* assignment on AGCH */</span><br><span>@@ -228,6 +232,30 @@</span><br><span> uint8_t data[0];</span><br><span> } __attribute__ ((packed));</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*** Used inside container: NOTE: values must be network byte order here! ***/</span><br><span style="color: hsl(120, 100%, 40%);">+/* Neighbor Address Resolution Request */</span><br><span style="color: hsl(120, 100%, 40%);">+struct gsm_pcu_if_neigh_addr_req {</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t local_lac;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t local_ci;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t tgt_arfcn;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t tgt_bsic;</span><br><span style="color: hsl(120, 100%, 40%);">+} __attribute__ ((packed));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Neighbor Address Resolution Confirmation */</span><br><span style="color: hsl(120, 100%, 40%);">+struct gsm_pcu_if_neigh_addr_cnf {</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm_pcu_if_neigh_addr_req orig_req;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t err_code; /* 0 success, !0 failed & below unset */</span><br><span style="color: hsl(120, 100%, 40%);">+ /* RAI + CI (CGI-PS): */</span><br><span style="color: hsl(120, 100%, 40%);">+ struct __attribute__ ((packed)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t mcc;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t mnc;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t mnc_3_digits;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t lac;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t rac;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t cell_identity;</span><br><span style="color: hsl(120, 100%, 40%);">+ } cgi_ps;</span><br><span style="color: hsl(120, 100%, 40%);">+} __attribute__ ((packed));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> struct gsm_pcu_if {</span><br><span> /* context based information */</span><br><span> uint8_t msg_type; /* message type */</span><br><span>diff --git a/src/gprs_pcu.c b/src/gprs_pcu.c</span><br><span>index a7bab8d..5ed9d7d 100644</span><br><span>--- a/src/gprs_pcu.c</span><br><span>+++ b/src/gprs_pcu.c</span><br><span>@@ -114,7 +114,7 @@</span><br><span> pcu->vty.ws_pdch = 0;</span><br><span> pcu->vty.llc_codel_interval_msec = LLC_CODEL_USE_DEFAULT;</span><br><span> pcu->vty.llc_idle_ack_csec = 10;</span><br><span style="color: hsl(0, 100%, 40%);">- pcu->vty.neigh_ctrl_addr = talloc_strdup(pcu, "127.0.0.1");</span><br><span style="color: hsl(120, 100%, 40%);">+ pcu->vty.neigh_ctrl_addr = NULL; /* don't use CTRL iface for Neigh Addr Resolution */</span><br><span> pcu->vty.neigh_ctrl_port = OSMO_CTRL_PORT_BSC_NEIGH;</span><br><span> </span><br><span> pcu->T_defs = T_defs_pcu;</span><br><span>diff --git a/src/nacc_fsm.c b/src/nacc_fsm.c</span><br><span>index 738b2c5..ca226ac 100644</span><br><span>--- a/src/nacc_fsm.c</span><br><span>+++ b/src/nacc_fsm.c</span><br><span>@@ -361,14 +361,72 @@</span><br><span> }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static int send_neigh_addr_req_ctrl_iface(struct nacc_fsm_ctx *ctx)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gprs_rlcmac_bts *bts = ctx->ms->bts;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gprs_pcu *pcu = bts->pcu;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ctrl_cmd *cmd = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* We may have changed to this state previously (eg: we are handling</span><br><span style="color: hsl(120, 100%, 40%);">+ * another Pkt cell Change Notify with different target). Avoid</span><br><span style="color: hsl(120, 100%, 40%);">+ * re-creating the socket in that case. */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ctx->neigh_ctrl_conn->write_queue.bfd.fd == -1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = osmo_sock_init2_ofd(&ctx->neigh_ctrl_conn->write_queue.bfd,</span><br><span style="color: hsl(120, 100%, 40%);">+ AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP,</span><br><span style="color: hsl(120, 100%, 40%);">+ NULL, 0, pcu->vty.neigh_ctrl_addr, pcu->vty.neigh_ctrl_port,</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_SOCK_F_CONNECT);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPFSML(ctx->fi, LOGL_ERROR,</span><br><span style="color: hsl(120, 100%, 40%);">+ "Failed to establish CTRL (neighbor resolution) connection to BSC r=%s:%u\n\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ pcu->vty.neigh_ctrl_addr, pcu->vty.neigh_ctrl_port);</span><br><span style="color: hsl(120, 100%, 40%);">+ goto err_term;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ cmd = ctrl_cmd_create(ctx, CTRL_TYPE_GET);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!cmd) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPFSML(ctx->fi, LOGL_ERROR, "CTRL msg creation failed\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ goto err_term;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ cmd->id = talloc_asprintf(cmd, "%u", arfcn_bsic_2_ctrl_id(ctx->neigh_key.tgt_arfcn,</span><br><span style="color: hsl(120, 100%, 40%);">+ ctx->neigh_key.tgt_bsic));</span><br><span style="color: hsl(120, 100%, 40%);">+ cmd->variable = talloc_asprintf(cmd, "neighbor_resolve_cgi_ps_from_lac_ci.%d.%d.%d.%d",</span><br><span style="color: hsl(120, 100%, 40%);">+ ctx->neigh_key.local_lac, ctx->neigh_key.local_ci,</span><br><span style="color: hsl(120, 100%, 40%);">+ ctx->neigh_key.tgt_arfcn, ctx->neigh_key.tgt_bsic);</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = ctrl_cmd_send(&ctx->neigh_ctrl_conn->write_queue, cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPFSML(ctx->fi, LOGL_ERROR, "CTRL msg sent failed: %d\n", rc);</span><br><span style="color: hsl(120, 100%, 40%);">+ goto err_term;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ talloc_free(cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+err_term:</span><br><span style="color: hsl(120, 100%, 40%);">+ talloc_free(cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int send_neigh_addr_req(struct nacc_fsm_ctx *ctx)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gprs_rlcmac_bts *bts = ctx->ms->bts;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* If PCU was configured to use the old CTRL interface, use it: */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ctx->neigh_ctrl_conn)</span><br><span style="color: hsl(120, 100%, 40%);">+ return send_neigh_addr_req_ctrl_iface(ctx);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Otherwise, by default the new PCUIF over IPA Abis multiplex proto should be used: */</span><br><span style="color: hsl(120, 100%, 40%);">+ return pcu_tx_neigh_addr_res_req(bts, &ctx->neigh_key);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static void st_wait_resolve_rac_ci_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)</span><br><span> {</span><br><span> struct nacc_fsm_ctx *ctx = (struct nacc_fsm_ctx *)fi->priv;</span><br><span> struct gprs_rlcmac_bts *bts = ctx->ms->bts;</span><br><span> struct gprs_pcu *pcu = bts->pcu;</span><br><span> const struct osmo_cell_global_id_ps *cgi_ps;</span><br><span style="color: hsl(0, 100%, 40%);">- struct ctrl_cmd *cmd = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- int rc;</span><br><span> </span><br><span> /* First try to find the value in the cache */</span><br><span> cgi_ps = neigh_cache_lookup_value(pcu->neigh_cache, &ctx->neigh_key);</span><br><span>@@ -383,45 +441,8 @@</span><br><span> LOGPFSML(fi, LOGL_DEBUG, "No CGI-PS found in cache, resolving " NEIGH_CACHE_ENTRY_KEY_FMT "...\n",</span><br><span> NEIGH_CACHE_ENTRY_KEY_ARGS(&ctx->neigh_key));</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- /* We may have changed to this state previously (eg: we are handling</span><br><span style="color: hsl(0, 100%, 40%);">- * another Pkt cell Change Notify with different target). Avoid</span><br><span style="color: hsl(0, 100%, 40%);">- * re-creating the socket in that case. */</span><br><span style="color: hsl(0, 100%, 40%);">- if (ctx->neigh_ctrl_conn->write_queue.bfd.fd == -1) {</span><br><span style="color: hsl(0, 100%, 40%);">- rc = osmo_sock_init2_ofd(&ctx->neigh_ctrl_conn->write_queue.bfd,</span><br><span style="color: hsl(0, 100%, 40%);">- AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP,</span><br><span style="color: hsl(0, 100%, 40%);">- NULL, 0, pcu->vty.neigh_ctrl_addr, pcu->vty.neigh_ctrl_port,</span><br><span style="color: hsl(0, 100%, 40%);">- OSMO_SOCK_F_CONNECT);</span><br><span style="color: hsl(0, 100%, 40%);">- if (rc < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPFSML(fi, LOGL_ERROR,</span><br><span style="color: hsl(0, 100%, 40%);">- "Failed to establish CTRL (neighbor resolution) connection to BSC r=%s:%u\n\n",</span><br><span style="color: hsl(0, 100%, 40%);">- pcu->vty.neigh_ctrl_addr, pcu->vty.neigh_ctrl_port);</span><br><span style="color: hsl(0, 100%, 40%);">- goto err_term;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- cmd = ctrl_cmd_create(ctx, CTRL_TYPE_GET);</span><br><span style="color: hsl(0, 100%, 40%);">- if (!cmd) {</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPFSML(fi, LOGL_ERROR, "CTRL msg creation failed\n");</span><br><span style="color: hsl(0, 100%, 40%);">- goto err_term;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- cmd->id = talloc_asprintf(cmd, "%u", arfcn_bsic_2_ctrl_id(ctx->neigh_key.tgt_arfcn,</span><br><span style="color: hsl(0, 100%, 40%);">- ctx->neigh_key.tgt_bsic));</span><br><span style="color: hsl(0, 100%, 40%);">- cmd->variable = talloc_asprintf(cmd, "neighbor_resolve_cgi_ps_from_lac_ci.%d.%d.%d.%d",</span><br><span style="color: hsl(0, 100%, 40%);">- ctx->neigh_key.local_lac, ctx->neigh_key.local_ci,</span><br><span style="color: hsl(0, 100%, 40%);">- ctx->neigh_key.tgt_arfcn, ctx->neigh_key.tgt_bsic);</span><br><span style="color: hsl(0, 100%, 40%);">- rc = ctrl_cmd_send(&ctx->neigh_ctrl_conn->write_queue, cmd);</span><br><span style="color: hsl(0, 100%, 40%);">- if (rc) {</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPFSML(fi, LOGL_ERROR, "CTRL msg sent failed: %d\n", rc);</span><br><span style="color: hsl(0, 100%, 40%);">- goto err_term;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- talloc_free(cmd);</span><br><span style="color: hsl(0, 100%, 40%);">- return;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-err_term:</span><br><span style="color: hsl(0, 100%, 40%);">- talloc_free(cmd);</span><br><span style="color: hsl(0, 100%, 40%);">- nacc_fsm_state_chg(fi, NACC_ST_TX_CELL_CHG_CONTINUE);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (send_neigh_addr_req(ctx) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ nacc_fsm_state_chg(fi, NACC_ST_TX_CELL_CHG_CONTINUE);</span><br><span> }</span><br><span> </span><br><span> static void st_wait_resolve_rac_ci(struct osmo_fsm_inst *fi, uint32_t event, void *data)</span><br><span>@@ -435,8 +456,13 @@</span><br><span> handle_retrans_pkt_cell_chg_notif(ctx, notif);</span><br><span> break;</span><br><span> case NACC_EV_RX_RAC_CI:</span><br><span style="color: hsl(0, 100%, 40%);">- /* Assumption: ctx->cgi_ps has been filled by caller of the event */</span><br><span style="color: hsl(0, 100%, 40%);">- nacc_fsm_state_chg(fi, NACC_ST_WAIT_REQUEST_SI);</span><br><span style="color: hsl(120, 100%, 40%);">+ /* data is NULL upon failure */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (data) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ctx->cgi_ps = *(struct osmo_cell_global_id_ps *)data;</span><br><span style="color: hsl(120, 100%, 40%);">+ nacc_fsm_state_chg(fi, NACC_ST_WAIT_REQUEST_SI);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ nacc_fsm_state_chg(fi, NACC_ST_TX_CELL_CHG_CONTINUE);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> break;</span><br><span> default:</span><br><span> OSMO_ASSERT(0);</span><br><span>@@ -740,12 +766,13 @@</span><br><span> struct nacc_fsm_ctx *ctx = (struct nacc_fsm_ctx *)data;</span><br><span> char *tmp = NULL, *tok, *saveptr;</span><br><span> unsigned int exp_id;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_cell_global_id_ps cgi_ps;</span><br><span> </span><br><span> LOGPFSML(ctx->fi, LOGL_NOTICE, "Received CTRL message: type=%d %s %s: %s\n",</span><br><span> cmd->type, cmd->variable, cmd->id, osmo_escape_str(cmd->reply, -1));</span><br><span> </span><br><span> if (cmd->type != CTRL_TYPE_GET_REPLY || !cmd->reply) {</span><br><span style="color: hsl(0, 100%, 40%);">- nacc_fsm_state_chg(ctx->fi, NACC_ST_TX_CELL_CHG_CONTINUE);</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_fsm_inst_dispatch(ctx->fi, NACC_EV_RX_RAC_CI, NULL);</span><br><span> return;</span><br><span> }</span><br><span> </span><br><span>@@ -771,33 +798,33 @@</span><br><span> </span><br><span> if (!(tok = strtok_r(tmp, "-", &saveptr)))</span><br><span> goto free_ret;</span><br><span style="color: hsl(0, 100%, 40%);">- ctx->cgi_ps.rai.lac.plmn.mcc = atoi(tok);</span><br><span style="color: hsl(120, 100%, 40%);">+ cgi_ps.rai.lac.plmn.mcc = atoi(tok);</span><br><span> </span><br><span> if (!(tok = strtok_r(NULL, "-", &saveptr)))</span><br><span> goto free_ret;</span><br><span style="color: hsl(0, 100%, 40%);">- ctx->cgi_ps.rai.lac.plmn.mnc = atoi(tok);</span><br><span style="color: hsl(120, 100%, 40%);">+ cgi_ps.rai.lac.plmn.mnc = atoi(tok);</span><br><span> </span><br><span> if (!(tok = strtok_r(NULL, "-", &saveptr)))</span><br><span> goto free_ret;</span><br><span style="color: hsl(0, 100%, 40%);">- ctx->cgi_ps.rai.lac.lac = atoi(tok);</span><br><span style="color: hsl(120, 100%, 40%);">+ cgi_ps.rai.lac.lac = atoi(tok);</span><br><span> </span><br><span> if (!(tok = strtok_r(NULL, "-", &saveptr)))</span><br><span> goto free_ret;</span><br><span style="color: hsl(0, 100%, 40%);">- ctx->cgi_ps.rai.rac = atoi(tok);</span><br><span style="color: hsl(120, 100%, 40%);">+ cgi_ps.rai.rac = atoi(tok);</span><br><span> </span><br><span> if (!(tok = strtok_r(NULL, "\0", &saveptr)))</span><br><span> goto free_ret;</span><br><span style="color: hsl(0, 100%, 40%);">- ctx->cgi_ps.cell_identity = atoi(tok);</span><br><span style="color: hsl(120, 100%, 40%);">+ cgi_ps.cell_identity = atoi(tok);</span><br><span> </span><br><span> /* Cache the cgi_ps so we can avoid requesting again same resolution for a while */</span><br><span style="color: hsl(0, 100%, 40%);">- neigh_cache_add(ctx->ms->bts->pcu->neigh_cache, &ctx->neigh_key, &ctx->cgi_ps);</span><br><span style="color: hsl(120, 100%, 40%);">+ neigh_cache_add(ctx->ms->bts->pcu->neigh_cache, &ctx->neigh_key, &cgi_ps);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- osmo_fsm_inst_dispatch(ctx->fi, NACC_EV_RX_RAC_CI, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_fsm_inst_dispatch(ctx->fi, NACC_EV_RX_RAC_CI, &cgi_ps);</span><br><span> return;</span><br><span> </span><br><span> free_ret:</span><br><span> talloc_free(tmp);</span><br><span style="color: hsl(0, 100%, 40%);">- nacc_fsm_state_chg(ctx->fi, NACC_ST_TX_CELL_CHG_CONTINUE);</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_fsm_inst_dispatch(ctx->fi, NACC_EV_RX_RAC_CI, NULL);</span><br><span> return;</span><br><span> }</span><br><span> </span><br><span>@@ -834,18 +861,29 @@</span><br><span> if (!ctx->fi)</span><br><span> goto free_ret;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- ctx->neigh_ctrl = ctrl_handle_alloc(ctx, ctx, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">- ctx->neigh_ctrl->reply_cb = nacc_fsm_ctrl_reply_cb;</span><br><span style="color: hsl(0, 100%, 40%);">- ctx->neigh_ctrl_conn = osmo_ctrl_conn_alloc(ctx, ctx->neigh_ctrl);</span><br><span style="color: hsl(0, 100%, 40%);">- if (!ctx->neigh_ctrl_conn)</span><br><span style="color: hsl(0, 100%, 40%);">- goto free_ret;</span><br><span style="color: hsl(0, 100%, 40%);">- /* Older versions of osmo_ctrl_conn_alloc didn't properly initialize fd to -1,</span><br><span style="color: hsl(0, 100%, 40%);">- * so make sure to do it here otherwise fd may be valid fd 0 and cause trouble */</span><br><span style="color: hsl(0, 100%, 40%);">- ctx->neigh_ctrl_conn->write_queue.bfd.fd = -1;</span><br><span style="color: hsl(0, 100%, 40%);">- llist_add(&ctx->neigh_ctrl_conn->list_entry, &ctx->neigh_ctrl->ccon_list);</span><br><span style="color: hsl(120, 100%, 40%);">+ /* If CTRL ip present, use the old CTRL interface for neighbor resolution */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ms->bts->pcu->vty.neigh_ctrl_addr) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ctx->neigh_ctrl = ctrl_handle_alloc(ctx, ctx, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+ ctx->neigh_ctrl->reply_cb = nacc_fsm_ctrl_reply_cb;</span><br><span style="color: hsl(120, 100%, 40%);">+ ctx->neigh_ctrl_conn = osmo_ctrl_conn_alloc(ctx, ctx->neigh_ctrl);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!ctx->neigh_ctrl_conn)</span><br><span style="color: hsl(120, 100%, 40%);">+ goto free_ret;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Older versions of osmo_ctrl_conn_alloc didn't properly initialize fd to -1,</span><br><span style="color: hsl(120, 100%, 40%);">+ * so make sure to do it here otherwise fd may be valid fd 0 and cause trouble */</span><br><span style="color: hsl(120, 100%, 40%);">+ ctx->neigh_ctrl_conn->write_queue.bfd.fd = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ llist_add(&ctx->neigh_ctrl_conn->list_entry, &ctx->neigh_ctrl->ccon_list);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> </span><br><span> return ctx;</span><br><span> free_ret:</span><br><span> talloc_free(ctx);</span><br><span> return NULL;</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+bool nacc_fsm_is_waiting_addr_resolution(const struct nacc_fsm_ctx *ctx,</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct neigh_cache_entry_key *neigh_key)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ctx->fi->state != NACC_ST_WAIT_RESOLVE_RAC_CI)</span><br><span style="color: hsl(120, 100%, 40%);">+ return false;</span><br><span style="color: hsl(120, 100%, 40%);">+ return neigh_cache_entry_key_eq(&ctx->neigh_key, neigh_key);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/src/nacc_fsm.h b/src/nacc_fsm.h</span><br><span>index 7b0adfd..04c9ba4 100644</span><br><span>--- a/src/nacc_fsm.h</span><br><span>+++ b/src/nacc_fsm.h</span><br><span>@@ -29,7 +29,7 @@</span><br><span> </span><br><span> enum nacc_fsm_event {</span><br><span> NACC_EV_RX_CELL_CHG_NOTIFICATION, /* data: Packet_Cell_Change_Notification_t* */</span><br><span style="color: hsl(0, 100%, 40%);">- NACC_EV_RX_RAC_CI, /* no data passed, RAC_CI became available in neigh_cache */</span><br><span style="color: hsl(120, 100%, 40%);">+ NACC_EV_RX_RAC_CI, /* RAC_CI became available in neigh_cache. NULL on failure, pointer to ctx->cgi_ps on success */</span><br><span> NACC_EV_RX_SI, /* data: struct si_cache_entry* */</span><br><span> NACC_EV_CREATE_RLCMAC_MSG, /* data: struct nacc_ev_create_rlcmac_msg_ctx* */</span><br><span> NACC_EV_RX_CELL_CHG_CONTINUE_ACK,</span><br><span>@@ -69,3 +69,6 @@</span><br><span> };</span><br><span> </span><br><span> struct nacc_fsm_ctx *nacc_fsm_alloc(struct GprsMs* ms);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+bool nacc_fsm_is_waiting_addr_resolution(const struct nacc_fsm_ctx *ctx,</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct neigh_cache_entry_key *neigh_key);</span><br><span>diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp</span><br><span>index 4530e1a..25c1933 100644</span><br><span>--- a/src/pcu_l1_if.cpp</span><br><span>+++ b/src/pcu_l1_if.cpp</span><br><span>@@ -44,6 +44,8 @@</span><br><span> #include <osmocom/gsm/protocol/gsm_04_08.h></span><br><span> #include <osmocom/gsm/gsm48_rest_octets.h></span><br><span> #include <osmocom/gsm/sysinfo.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <nacc_fsm.h></span><br><span> }</span><br><span> </span><br><span> #include <gprs_rlcmac.h></span><br><span>@@ -95,6 +97,7 @@</span><br><span> * PCU messages</span><br><span> */</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* Can be used to allocate message with non-variable size */</span><br><span> struct msgb *pcu_msgb_alloc(uint8_t msg_type, uint8_t bts_nr)</span><br><span> {</span><br><span> struct msgb *msg;</span><br><span>@@ -111,6 +114,21 @@</span><br><span> return msg;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* Allocate message with extra size, only reserve pcuif msg hdr */</span><br><span style="color: hsl(120, 100%, 40%);">+static struct msgb *pcu_msgb_alloc_ext_size(uint8_t msg_type, uint8_t bts_nr, size_t extra_size)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct msgb *msg;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm_pcu_if *pcu_prim;</span><br><span style="color: hsl(120, 100%, 40%);">+ msg = msgb_alloc(sizeof(struct gsm_pcu_if) + extra_size, "pcu_sock_tx");</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Only header is filled, caller is responible for reserving + filling</span><br><span style="color: hsl(120, 100%, 40%);">+ * message type specific contents: */</span><br><span style="color: hsl(120, 100%, 40%);">+ msgb_put(msg, PCUIF_HDR_SIZE);</span><br><span style="color: hsl(120, 100%, 40%);">+ pcu_prim = (struct gsm_pcu_if *) msgb_data(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+ pcu_prim->msg_type = msg_type;</span><br><span style="color: hsl(120, 100%, 40%);">+ pcu_prim->bts_nr = bts_nr;</span><br><span style="color: hsl(120, 100%, 40%);">+ return msg;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> const struct value_string gsm_pcu_if_text_type_names[] = {</span><br><span> OSMO_VALUE_STRING(PCU_VERSION),</span><br><span> OSMO_VALUE_STRING(PCU_OML_ALERT),</span><br><span>@@ -271,6 +289,33 @@</span><br><span> pcu_tx_data_req(bts, 0, 0, PCU_IF_SAPI_PCH, 0, 0, 0, data, PAGING_GROUP_LEN + GSM_MACBLOCK_LEN);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+int pcu_tx_neigh_addr_res_req(struct gprs_rlcmac_bts *bts, const struct neigh_cache_entry_key *neigh_key)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct msgb *msg;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm_pcu_if *pcu_prim;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm_pcu_if_neigh_addr_req *naddr_req;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DL1IF, LOGL_DEBUG, "(bts=%u) Tx Neighbor Address Resolution Request: " NEIGH_CACHE_ENTRY_KEY_FMT "\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ bts->nr, NEIGH_CACHE_ENTRY_KEY_ARGS(neigh_key));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ msg = pcu_msgb_alloc_ext_size(PCU_IF_MSG_CONTAINER, bts->nr, sizeof(struct gsm_pcu_if_neigh_addr_req));</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!msg)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -ENOMEM;</span><br><span style="color: hsl(120, 100%, 40%);">+ pcu_prim = (struct gsm_pcu_if *) msgb_data(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+ naddr_req = (struct gsm_pcu_if_neigh_addr_req *)&pcu_prim->u.container.data[0];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ msgb_put(msg, sizeof(pcu_prim->u.container) + sizeof(struct gsm_pcu_if_neigh_addr_req));</span><br><span style="color: hsl(120, 100%, 40%);">+ pcu_prim->u.container.msg_type = PCU_IF_MSG_NEIGH_ADDR_REQ;</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_store16be(sizeof(struct gsm_pcu_if_neigh_addr_req), &pcu_prim->u.container.length);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_store16be(neigh_key->local_lac, &naddr_req->local_lac);</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_store16be(neigh_key->local_ci, &naddr_req->local_ci);</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_store16be(neigh_key->tgt_arfcn, &naddr_req->tgt_arfcn);</span><br><span style="color: hsl(120, 100%, 40%);">+ naddr_req->tgt_bsic = neigh_key->tgt_bsic;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return pcu_sock_send(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> void pcu_rx_block_time(struct gprs_rlcmac_bts *bts, uint16_t arfcn, uint32_t fn, uint8_t ts_no)</span><br><span> {</span><br><span> bts_set_current_block_frame_number(bts, fn);</span><br><span>@@ -955,11 +1000,60 @@</span><br><span> return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static int pcu_rx_neigh_addr_cnf(struct gprs_rlcmac_bts *bts, struct gsm_pcu_if_neigh_addr_cnf *naddr_cnf)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct llist_head *tmp;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_cell_global_id_ps cgi_ps;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_cell_global_id_ps *cgi_ps_ptr = &cgi_ps;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ struct neigh_cache_entry_key neigh_key = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .local_lac = osmo_load16be(&naddr_cnf->orig_req.local_lac),</span><br><span style="color: hsl(120, 100%, 40%);">+ .local_ci = osmo_load16be(&naddr_cnf->orig_req.local_ci),</span><br><span style="color: hsl(120, 100%, 40%);">+ .tgt_arfcn = osmo_load16be(&naddr_cnf->orig_req.tgt_arfcn),</span><br><span style="color: hsl(120, 100%, 40%);">+ .tgt_bsic = naddr_cnf->orig_req.tgt_bsic,</span><br><span style="color: hsl(120, 100%, 40%);">+ };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (naddr_cnf->err_code == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ cgi_ps.rai.lac.plmn.mcc = osmo_load16be(&naddr_cnf->cgi_ps.mcc);</span><br><span style="color: hsl(120, 100%, 40%);">+ cgi_ps.rai.lac.plmn.mnc = osmo_load16be(&naddr_cnf->cgi_ps.mnc);</span><br><span style="color: hsl(120, 100%, 40%);">+ cgi_ps.rai.lac.plmn.mnc_3_digits = naddr_cnf->cgi_ps.mnc_3_digits;</span><br><span style="color: hsl(120, 100%, 40%);">+ cgi_ps.rai.lac.lac = osmo_load16be(&naddr_cnf->cgi_ps.lac);</span><br><span style="color: hsl(120, 100%, 40%);">+ cgi_ps.rai.rac = naddr_cnf->cgi_ps.rac;</span><br><span style="color: hsl(120, 100%, 40%);">+ cgi_ps.cell_identity = osmo_load16be(&naddr_cnf->cgi_ps.cell_identity);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DL1IF, LOGL_INFO, "Rx Neighbor Address Resolution Confirmation for " NEIGH_CACHE_ENTRY_KEY_FMT ": %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ NEIGH_CACHE_ENTRY_KEY_ARGS(&neigh_key), osmo_cgi_ps_name(&cgi_ps));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Cache the cgi_ps so we can avoid requesting again same resolution for a while */</span><br><span style="color: hsl(120, 100%, 40%);">+ neigh_cache_add(bts->pcu->neigh_cache, &neigh_key, &cgi_ps);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ cgi_ps_ptr = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DL1IF, LOGL_INFO, "Rx Neighbor Address Resolution Confirmation for " NEIGH_CACHE_ENTRY_KEY_FMT ": failed with err_code=%u\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ NEIGH_CACHE_ENTRY_KEY_ARGS(&neigh_key), naddr_cnf->err_code);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ llist_for_each(tmp, bts_ms_store(bts)->ms_list()) {</span><br><span style="color: hsl(120, 100%, 40%);">+ GprsMs *ms = llist_entry(tmp, typeof(*ms), list);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ms->nacc && nacc_fsm_is_waiting_addr_resolution(ms->nacc, &neigh_key))</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_fsm_inst_dispatch(ms->nacc->fi, NACC_EV_RX_RAC_CI, cgi_ps_ptr);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static int pcu_rx_container(struct gprs_rlcmac_bts *bts, struct gsm_pcu_if_container *container)</span><br><span> {</span><br><span> int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t data_length = osmo_load16be(&container->length);</span><br><span> </span><br><span> switch (container->msg_type) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case PCU_IF_MSG_NEIGH_ADDR_CNF:</span><br><span style="color: hsl(120, 100%, 40%);">+ if (data_length < sizeof(struct gsm_pcu_if_neigh_addr_cnf)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DL1IF, LOGL_ERROR, "Rx container(NEIGH_ADDR_CNF) message too short: %u vs exp %zu\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ data_length, sizeof(struct gsm_pcu_if_neigh_addr_cnf));</span><br><span style="color: hsl(120, 100%, 40%);">+ return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = pcu_rx_neigh_addr_cnf(bts, (struct gsm_pcu_if_neigh_addr_cnf*)&container->data);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span> default:</span><br><span> LOGP(DL1IF, LOGL_NOTICE, "(bts=%d) Rx unexpected msg type (%u) inside container!\n",</span><br><span> bts->nr, container->msg_type);</span><br><span>diff --git a/src/pcu_l1_if.h b/src/pcu_l1_if.h</span><br><span>index 2a4f0ea..7d48feb 100644</span><br><span>--- a/src/pcu_l1_if.h</span><br><span>+++ b/src/pcu_l1_if.h</span><br><span>@@ -160,6 +160,8 @@</span><br><span> #endif</span><br><span> struct gprs_rlcmac_bts;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+int pcu_tx_neigh_addr_res_req(struct gprs_rlcmac_bts *bts, const struct neigh_cache_entry_key *neigh_key);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> int pcu_rx(struct gsm_pcu_if *pcu_prim, size_t pcu_prim_length);</span><br><span> int pcu_l1if_open(void);</span><br><span> void pcu_l1if_close(void);</span><br><span>diff --git a/src/pcu_vty.c b/src/pcu_vty.c</span><br><span>index 1ca6376..c85e324 100644</span><br><span>--- a/src/pcu_vty.c</span><br><span>+++ b/src/pcu_vty.c</span><br><span>@@ -1067,6 +1067,10 @@</span><br><span> "IPv4 address to connect to\n" "IPv6 address to connect to\n"</span><br><span> "Port to connect to (default 4248)\n")</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+ vty_out(vty, "%% Warning: The CTRL interface for Neighbor Address Resolution is now deprecated."</span><br><span style="color: hsl(120, 100%, 40%);">+ "Upgrade osmo-bsc and drop the 'neighbor resolution " VTY_IPV46_CMD " [<0-65535>]' VTY "</span><br><span style="color: hsl(120, 100%, 40%);">+ "option in order to let osmo-pcu use the new resoluton method using the PCUIF over IPA "</span><br><span style="color: hsl(120, 100%, 40%);">+ "multiplex, which will work out of the box without required configuration.%s", VTY_NEWLINE);</span><br><span> osmo_talloc_replace_string(the_pcu, &the_pcu->vty.neigh_ctrl_addr, argv[0]);</span><br><span> if (argc > 1)</span><br><span> the_pcu->vty.neigh_ctrl_port = atoi(argv[1]);</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-pcu/+/25404">change 25404</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/osmo-pcu/+/25404"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: osmo-pcu </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I6ad33c7ab10202840cf804dea9ba595978d0e920 </div>
<div style="display:none"> Gerrit-Change-Number: 25404 </div>
<div style="display:none"> Gerrit-PatchSet: 4 </div>
<div style="display:none"> Gerrit-Owner: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-Reviewer: osmith <osmith@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>