<p>laforge <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/osmo-cbc/+/22402">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Jenkins Builder: Verified
  laforge: Looks good to me, approved

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Make ECBE (REST interface) local bind IP + port VTY-configurable<br><br>Change-Id: I656d0d1c7b21db90b62e71109d9844476a2e3215<br>---<br>M doc/manuals/chapters/configuration.adoc<br>M src/cbc_data.h<br>M src/cbc_main.c<br>M src/cbc_vty.c<br>M src/internal.h<br>M src/rest_api.c<br>6 files changed, 110 insertions(+), 13 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 c205d91..095aed5 100644</span><br><span>--- a/doc/manuals/chapters/configuration.adoc</span><br><span>+++ b/doc/manuals/chapters/configuration.adoc</span><br><span>@@ -1,12 +1,14 @@</span><br><span> [[configuration]]</span><br><span style="color: hsl(0, 100%, 40%);">-== CBSP / Peer Configuration</span><br><span style="color: hsl(120, 100%, 40%);">+== Configuration</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+=== CBSP / Peer Configuration</span><br><span> </span><br><span> CBSP is the BSC-CBC interface within the 3GPP architecture.  It serves</span><br><span> to communicate CSB and ETWS messages from the CBC to the BSC, who then</span><br><span> subsequently distributes it among the (matching) cells within the BSC</span><br><span> coverage area.</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-=== Configuring the CBSP connections</span><br><span style="color: hsl(120, 100%, 40%);">+==== Configuring the CBSP connections</span><br><span> </span><br><span> According to 3GPP TS 48.049, a BSC typically operates as a TCP server,</span><br><span> and the CBC connects as TCP client.  This would require the CBC to have</span><br><span>@@ -46,7 +48,7 @@</span><br><span> </span><br><span> For more details on the available configuration commands, please check the OsmoCBC VTY Reference.</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-=== Configuring the IP/Port for CBSP to bind to</span><br><span style="color: hsl(120, 100%, 40%);">+==== Configuring the IP/Port for CBSP to bind to</span><br><span> </span><br><span> It can be configure to which IP and TCP port the CBSP protocol binds to.</span><br><span> </span><br><span>@@ -60,3 +62,20 @@</span><br><span>   local-ip 127.0.0.1</span><br><span>   local-port 48049</span><br><span> ----</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+=== ECBE (REST Interface) Configuration</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+==== Configuring the IP/Port for ECBE to bind to</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+It can be configure to which IP and TCP port the ECBE REST Interface binds to.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+The default is to bind to is the non-standard port number 12349 at the</span><br><span style="color: hsl(120, 100%, 40%);">+loopback IP address 127.0.0.1.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+.Example: Configure ECBE REST interface to bind to 127.0.0.1:8080</span><br><span style="color: hsl(120, 100%, 40%);">+----</span><br><span style="color: hsl(120, 100%, 40%);">+cbc</span><br><span style="color: hsl(120, 100%, 40%);">+ ecbe</span><br><span style="color: hsl(120, 100%, 40%);">+  local-ip 127.0.0.1</span><br><span style="color: hsl(120, 100%, 40%);">+  local-port 8080</span><br><span style="color: hsl(120, 100%, 40%);">+----</span><br><span>diff --git a/src/cbc_data.h b/src/cbc_data.h</span><br><span>index 76fdfad..e88ae45 100644</span><br><span>--- a/src/cbc_data.h</span><br><span>+++ b/src/cbc_data.h</span><br><span>@@ -169,6 +169,10 @@</span><br><span>                    char *local_host;</span><br><span>                    int local_port;</span><br><span>              } cbsp;</span><br><span style="color: hsl(120, 100%, 40%);">+               struct {</span><br><span style="color: hsl(120, 100%, 40%);">+                      char *local_host;</span><br><span style="color: hsl(120, 100%, 40%);">+                     int local_port;</span><br><span style="color: hsl(120, 100%, 40%);">+               } ecbe;</span><br><span>      } config;</span><br><span> </span><br><span>        struct llist_head messages;     /* cbc_message.list */</span><br><span>diff --git a/src/cbc_main.c b/src/cbc_main.c</span><br><span>index 168fd7d..ff696bd 100644</span><br><span>--- a/src/cbc_main.c</span><br><span>+++ b/src/cbc_main.c</span><br><span>@@ -1,6 +1,6 @@</span><br><span> /* Osmocom CBC (Cell Broacast Centre) */</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/* (C) 2019 by Harald Welte <laforge@gnumonks.org></span><br><span style="color: hsl(120, 100%, 40%);">+/* (C) 2019-2021 by Harald Welte <laforge@gnumonks.org></span><br><span>  * All Rights Reserved</span><br><span>  *</span><br><span>  * SPDX-License-Identifier: AGPL-3.0+</span><br><span>@@ -221,6 +221,8 @@</span><br><span>  INIT_LLIST_HEAD(&g_cbc->expired_messages);</span><br><span>    g_cbc->config.cbsp.local_host = talloc_strdup(g_cbc, "127.0.0.1");</span><br><span>      g_cbc->config.cbsp.local_port = CBSP_TCP_PORT;</span><br><span style="color: hsl(120, 100%, 40%);">+     g_cbc->config.ecbe.local_host = talloc_strdup(g_cbc, "127.0.0.1");</span><br><span style="color: hsl(120, 100%, 40%);">+       g_cbc->config.ecbe.local_port = 12345;</span><br><span> </span><br><span>        cbc_vty_init();</span><br><span> </span><br><span>@@ -245,7 +247,7 @@</span><br><span>    cbsp_cbc_create(tall_cbc_ctx, g_cbc->config.cbsp.local_host, g_cbc->config.cbsp.local_port,</span><br><span>                    &cbc_client_rx_cb);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     rest_api_init(tall_rest_ctx, 12345);</span><br><span style="color: hsl(120, 100%, 40%);">+  rest_api_init(tall_rest_ctx, g_cbc->config.ecbe.local_host, g_cbc->config.ecbe.local_port);</span><br><span> </span><br><span>        LOGP(DREST, LOGL_INFO, "Main thread tid: %lu\n", pthread_self());</span><br><span>  g_cbc->it_q.rest2main = osmo_it_q_alloc(g_cbc, "rest2main", 10, rest2main_read_cb, NULL);</span><br><span>diff --git a/src/cbc_vty.c b/src/cbc_vty.c</span><br><span>index b1aa34f..98e2703 100644</span><br><span>--- a/src/cbc_vty.c</span><br><span>+++ b/src/cbc_vty.c</span><br><span>@@ -1,6 +1,6 @@</span><br><span> /* Osmocom CBC (Cell Broacast Centre) */</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/* (C) 2019 by Harald Welte <laforge@gnumonks.org></span><br><span style="color: hsl(120, 100%, 40%);">+/* (C) 2019-2021 by Harald Welte <laforge@gnumonks.org></span><br><span>  * All Rights Reserved</span><br><span>  *</span><br><span>  * SPDX-License-Identifier: AGPL-3.0+</span><br><span>@@ -268,6 +268,7 @@</span><br><span>      CBC_NODE = _LAST_OSMOVTY_NODE + 1,</span><br><span>   PEER_NODE,</span><br><span>   CBSP_NODE,</span><br><span style="color: hsl(120, 100%, 40%);">+    ECBE_NODE,</span><br><span> };</span><br><span> </span><br><span> static struct cmd_node cbc_node = {</span><br><span>@@ -319,6 +320,14 @@</span><br><span>   return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+DEFUN(cfg_ecbe, cfg_ecbe_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+   "ecbe",</span><br><span style="color: hsl(120, 100%, 40%);">+     "External CBS Entity (REST Interface)\n")</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        vty->node = ECBE_NODE;</span><br><span style="color: hsl(120, 100%, 40%);">+     return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> </span><br><span> /* CBSP */</span><br><span> </span><br><span>@@ -356,6 +365,43 @@</span><br><span> }</span><br><span> </span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* ECBE */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static struct cmd_node ecbe_node = {</span><br><span style="color: hsl(120, 100%, 40%);">+        ECBE_NODE,</span><br><span style="color: hsl(120, 100%, 40%);">+    "%s(config-ecbe)# ",</span><br><span style="color: hsl(120, 100%, 40%);">+        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 config_write_ecbe(struct vty *vty)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    vty_out(vty, " ecbe%s", VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+       vty_out(vty, "  local-ip %s%s", g_cbc->config.ecbe.local_host, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+     vty_out(vty, "  local-port %u%s", g_cbc->config.ecbe.local_port, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return CMD_SUCCESS;</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%);">+DEFUN(cfg_ecbe_local_ip, cfg_ecbe_local_ip_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+     "local-ip (A.B.C.D|X:X::X:X)",</span><br><span style="color: hsl(120, 100%, 40%);">+      "Local IP address for CBSP\n"</span><br><span style="color: hsl(120, 100%, 40%);">+       "Local IPv4 address for ECBE REST Interface\n"</span><br><span style="color: hsl(120, 100%, 40%);">+      "Local IPv6 address for ECBE REST Interface\n")</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_talloc_replace_string(g_cbc, &g_cbc->config.ecbe.local_host, argv[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+    return CMD_SUCCESS;</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%);">+DEFUN(cfg_ecbe_local_port, cfg_ecbe_local_port_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+ "local-port <0-65535>",</span><br><span style="color: hsl(120, 100%, 40%);">+       "Local TCP port for ECBE RESET Interface\n"</span><br><span style="color: hsl(120, 100%, 40%);">+ "Local TCP port for ECBE RESET Interface\n")</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     g_cbc->config.ecbe.local_port = atoi(argv[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+     return CMD_SUCCESS;</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> /* PEER */</span><br><span> </span><br><span> DEFUN(cfg_cbc_peer, cfg_cbc_peer_cmd,</span><br><span>@@ -469,6 +515,11 @@</span><br><span>         install_lib_element(CBSP_NODE, &cfg_cbsp_local_ip_cmd);</span><br><span>  install_lib_element(CBSP_NODE, &cfg_cbsp_local_port_cmd);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+     install_lib_element(CBC_NODE, &cfg_ecbe_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+     install_node(&ecbe_node, config_write_ecbe);</span><br><span style="color: hsl(120, 100%, 40%);">+      install_lib_element(ECBE_NODE, &cfg_ecbe_local_ip_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+   install_lib_element(ECBE_NODE, &cfg_ecbe_local_port_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>      install_lib_element(CBC_NODE, &cfg_cbc_peer_cmd);</span><br><span>        install_lib_element(CBC_NODE, &cfg_cbc_no_peer_cmd);</span><br><span>     install_node(&peer_node, config_write_peer);</span><br><span>diff --git a/src/internal.h b/src/internal.h</span><br><span>index e493c86..29093b5 100644</span><br><span>--- a/src/internal.h</span><br><span>+++ b/src/internal.h</span><br><span>@@ -25,7 +25,7 @@</span><br><span> </span><br><span> </span><br><span> /* rest_api.c */</span><br><span style="color: hsl(0, 100%, 40%);">-int rest_api_init(void *ctx, uint16_t port);</span><br><span style="color: hsl(120, 100%, 40%);">+int rest_api_init(void *ctx, const char *bind_addr, uint16_t port);</span><br><span> void rest_api_fin(void);</span><br><span> </span><br><span> /* cbc_vty.c */</span><br><span>diff --git a/src/rest_api.c b/src/rest_api.c</span><br><span>index 9473a01..91e7d40 100644</span><br><span>--- a/src/rest_api.c</span><br><span>+++ b/src/rest_api.c</span><br><span>@@ -1,6 +1,6 @@</span><br><span> /* Osmocom CBC (Cell Broacast Centre) */</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/* (C) 2019-2020 by Harald Welte <laforge@gnumonks.org></span><br><span style="color: hsl(120, 100%, 40%);">+/* (C) 2019-2021 by Harald Welte <laforge@gnumonks.org></span><br><span>  * All Rights Reserved</span><br><span>  *</span><br><span>  * SPDX-License-Identifier: AGPL-3.0+</span><br><span>@@ -31,6 +31,7 @@</span><br><span> </span><br><span> #include <osmocom/core/utils.h></span><br><span> #include <osmocom/core/linuxlist.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/sockaddr_str.h></span><br><span> </span><br><span> #include <osmocom/gsm/protocol/gsm_48_049.h></span><br><span> </span><br><span>@@ -677,8 +678,9 @@</span><br><span> }</span><br><span> #endif</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int rest_api_init(void *ctx, uint16_t port)</span><br><span style="color: hsl(120, 100%, 40%);">+int rest_api_init(void *ctx, const char *bind_addr, uint16_t port)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+  struct osmo_sockaddr_str sastr;</span><br><span>      int i;</span><br><span> </span><br><span> #ifdef ULFIUS_MALLOC_NOT_BROKEN</span><br><span>@@ -687,18 +689,37 @@</span><br><span>        o_set_alloc_funcs(my_o_malloc, my_o_realloc, my_o_free);</span><br><span> #endif</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  if (ulfius_init_instance(&g_instance, port, NULL, NULL) != U_OK)</span><br><span style="color: hsl(0, 100%, 40%);">-            return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    OSMO_STRLCPY_ARRAY(sastr.ip, bind_addr);</span><br><span style="color: hsl(120, 100%, 40%);">+      sastr.port = port;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  if (strchr(bind_addr, ':')) {</span><br><span style="color: hsl(120, 100%, 40%);">+#if (ULFIUS_VERSION_MAJOR > 2) || (ULFIUS_VERSION_MAJOR == 2) && (ULFIUS_VERSION_MINOR >= 6)</span><br><span style="color: hsl(120, 100%, 40%);">+             struct sockaddr_in6 sin6;</span><br><span style="color: hsl(120, 100%, 40%);">+             sastr.af = AF_INET6;</span><br><span style="color: hsl(120, 100%, 40%);">+          osmo_sockaddr_str_to_sockaddr_in6(&sastr, &sin6);</span><br><span style="color: hsl(120, 100%, 40%);">+             if (ulfius_init_instance_ipv6(&g_instance, port, &sin6, U_USE_IPV6, NULL) != U_OK)</span><br><span style="color: hsl(120, 100%, 40%);">+                    return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+#else</span><br><span style="color: hsl(120, 100%, 40%);">+             LOGP(DREST, LOGL_FATAL, "IPv6 requires ulfius version >= 2.6\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                return -2;</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+    } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              struct sockaddr_in sin;</span><br><span style="color: hsl(120, 100%, 40%);">+               sastr.af = AF_INET;</span><br><span style="color: hsl(120, 100%, 40%);">+           osmo_sockaddr_str_to_sockaddr_in(&sastr, &sin);</span><br><span style="color: hsl(120, 100%, 40%);">+               if (ulfius_init_instance(&g_instance, port, &sin, NULL) != U_OK)</span><br><span style="color: hsl(120, 100%, 40%);">+                      return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span>    g_instance.mhd_response_copy_data = 1;</span><br><span> </span><br><span>   for (i = 0; i < ARRAY_SIZE(api_endpoints); i++)</span><br><span>           ulfius_add_endpoint(&g_instance, &api_endpoints[i]);</span><br><span> </span><br><span>     if (ulfius_start_framework(&g_instance) != U_OK) {</span><br><span style="color: hsl(0, 100%, 40%);">-          LOGP(DREST, LOGL_FATAL, "Cannot start REST API on port %u\n", port);</span><br><span style="color: hsl(120, 100%, 40%);">+                LOGP(DREST, LOGL_FATAL, "Cannot start ECBE REST API at %s:%u\n", bind_addr, port);</span><br><span>                 return -1;</span><br><span>   }</span><br><span style="color: hsl(0, 100%, 40%);">-       LOGP(DREST, LOGL_NOTICE, "Started REST API on port %u\n", port);</span><br><span style="color: hsl(120, 100%, 40%);">+    LOGP(DREST, LOGL_NOTICE, "Started ECBE REST API at %s:%u\n", bind_addr, port);</span><br><span>     return 0;</span><br><span> }</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-cbc/+/22402">change 22402</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-cbc/+/22402"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-cbc </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I656d0d1c7b21db90b62e71109d9844476a2e3215 </div>
<div style="display:none"> Gerrit-Change-Number: 22402 </div>
<div style="display:none"> Gerrit-PatchSet: 2 </div>
<div style="display:none"> Gerrit-Owner: laforge <laforge@osmocom.org> </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-MessageType: merged </div>