<p>laforge has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/libosmocore/+/23521">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">WIP: ns2: Support "Foreign" SNS IP endpoints for fail-over scenarios<br><br>In fail-over scenarios, we want to be able to advertise "foreign"<br>IP endpoints, i.e. endpoints which do not have local sockets but<br>which are advertised as additional endpoints on "our" side of the<br>link.<br><br>This patch introduces support for them within pre-configured NSEs,<br>such as it is the case for the PCU/BSS role.<br><br>For the SGSN role, where typically we create the NSEs for BSS/PCU<br>dynamically as they create, another mechanism needs to be developed.<br><br>Change-Id: If9c4d3f62bfc2a47518dce90188e5fa85e21e4cc<br>Related: OS#4522<br>---<br>M include/osmocom/gprs/gprs_ns2.h<br>M src/gb/gprs_ns2_sns.c<br>M src/gb/gprs_ns2_vty.c<br>3 files changed, 234 insertions(+), 1 deletion(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/21/23521/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/gprs/gprs_ns2.h b/include/osmocom/gprs/gprs_ns2.h</span><br><span>index be59a67..d58d537 100644</span><br><span>--- a/include/osmocom/gprs/gprs_ns2.h</span><br><span>+++ b/include/osmocom/gprs/gprs_ns2.h</span><br><span>@@ -233,6 +233,10 @@</span><br><span> const struct osmo_sockaddr *saddr);</span><br><span> int gprs_ns2_sns_del_endpoint(struct gprs_ns2_nse *nse,</span><br><span> const struct osmo_sockaddr *saddr);</span><br><span style="color: hsl(120, 100%, 40%);">+int gprs_ns2_sns_add_foreign_endpoint(struct gprs_ns2_nse *nse, const struct osmo_sockaddr *saddr,</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t sig_weight, uint16_t data_weight);</span><br><span style="color: hsl(120, 100%, 40%);">+int gprs_ns2_sns_del_foreign_endpoint(struct gprs_ns2_nse *nse,</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct osmo_sockaddr *saddr);</span><br><span> int gprs_ns2_sns_add_bind(struct gprs_ns2_nse *nse, struct gprs_ns2_vc_bind *bind);</span><br><span> int gprs_ns2_sns_del_bind(struct gprs_ns2_nse *nse, struct gprs_ns2_vc_bind *bind);</span><br><span> const struct osmo_sockaddr *gprs_ns2_nse_sns_remote(struct gprs_ns2_nse *nse);</span><br><span>diff --git a/src/gb/gprs_ns2_sns.c b/src/gb/gprs_ns2_sns.c</span><br><span>index 144ab21..3b2b938 100644</span><br><span>--- a/src/gb/gprs_ns2_sns.c</span><br><span>+++ b/src/gb/gprs_ns2_sns.c</span><br><span>@@ -117,6 +117,13 @@</span><br><span> struct osmo_sockaddr saddr;</span><br><span> };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+struct sns_foreign_endpoint {</span><br><span style="color: hsl(120, 100%, 40%);">+ struct llist_head list;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_sockaddr saddr;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t sig_weight;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t data_weight;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> struct ns2_sns_bind {</span><br><span> struct llist_head list;</span><br><span> struct gprs_ns2_vc_bind *bind;</span><br><span>@@ -132,6 +139,8 @@</span><br><span> struct llist_head sns_endpoints;</span><br><span> /* list of used struct ns2_sns_bind */</span><br><span> struct llist_head binds;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* list of foreign local IP endpoints */</span><br><span style="color: hsl(120, 100%, 40%);">+ struct llist_head foreign_local_endpoints;</span><br><span> /* pointer to the bind which was used to initiate the SNS connection */</span><br><span> struct ns2_sns_bind *initial_bind;</span><br><span> /* prevent recursive reselection */</span><br><span>@@ -790,6 +799,7 @@</span><br><span> const struct osmo_sockaddr *remote;</span><br><span> const struct osmo_sockaddr *sa;</span><br><span> struct osmo_sockaddr local;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct sns_foreign_endpoint *flep;</span><br><span> int count;</span><br><span> </span><br><span> ns2_clear_ipv46_entries_local(gss);</span><br><span>@@ -803,7 +813,7 @@</span><br><span> remote = gprs_ns2_ip_vc_remote(gss->sns_nsvc);</span><br><span> </span><br><span> /* count how many bindings are available (only UDP binds) */</span><br><span style="color: hsl(0, 100%, 40%);">- count = llist_count(&gss->binds);</span><br><span style="color: hsl(120, 100%, 40%);">+ count = llist_count(&gss->binds) + llist_count(&gss->foreign_local_endpoints);</span><br><span> if (count == 0) {</span><br><span> LOGPFSML(fi, LOGL_ERROR, "No local binds for this NSE -> cannot determine IP endpoints\n");</span><br><span> return;</span><br><span>@@ -841,6 +851,19 @@</span><br><span> ip4_elems++;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ llist_for_each_entry(flep, &gss->foreign_local_endpoints, list) {</span><br><span style="color: hsl(120, 100%, 40%);">+ sa = &flep->saddr;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (sa->u.sas.ss_family != AF_INET)</span><br><span style="color: hsl(120, 100%, 40%);">+ continue;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ip4_elems->ip_addr = sa->u.sin.sin_addr.s_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+ ip4_elems->udp_port = sa->u.sin.sin_port;</span><br><span style="color: hsl(120, 100%, 40%);">+ ip4_elems->sig_weight = flep->sig_weight;</span><br><span style="color: hsl(120, 100%, 40%);">+ ip4_elems->data_weight = flep->data_weight;</span><br><span style="color: hsl(120, 100%, 40%);">+ ip4_elems++;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> gss->num_ip4_local = count;</span><br><span> gss->num_max_nsvcs = OSMO_MAX(gss->num_max_ip4_remote * gss->num_ip4_local, 8);</span><br><span> break;</span><br><span>@@ -877,6 +900,21 @@</span><br><span> </span><br><span> ip6_elems++;</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ llist_for_each_entry(flep, &gss->foreign_local_endpoints, list) {</span><br><span style="color: hsl(120, 100%, 40%);">+ sa = &flep->saddr;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (sa->u.sas.ss_family != AF_INET6)</span><br><span style="color: hsl(120, 100%, 40%);">+ continue;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ip6_elems->ip_addr = sa->u.sin6.sin6_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+ ip6_elems->udp_port = sa->u.sin6.sin6_port;</span><br><span style="color: hsl(120, 100%, 40%);">+ ip6_elems->sig_weight = flep->sig_weight;</span><br><span style="color: hsl(120, 100%, 40%);">+ ip6_elems->data_weight = flep->data_weight;</span><br><span style="color: hsl(120, 100%, 40%);">+ ip6_elems++;</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> gss->num_ip6_local = count;</span><br><span> gss->num_max_nsvcs = OSMO_MAX(gss->num_max_ip6_remote * gss->num_ip6_local, 8);</span><br><span> break;</span><br><span>@@ -1735,6 +1773,7 @@</span><br><span> struct ns2_sns_state *gss;</span><br><span> struct osmo_sockaddr_str addr_str;</span><br><span> struct sns_endpoint *endpoint;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct sns_foreign_endpoint *fendpoint;</span><br><span> </span><br><span> if (!nse->bss_sns_fi)</span><br><span> return;</span><br><span>@@ -1746,6 +1785,13 @@</span><br><span> addr_str = (struct osmo_sockaddr_str) { .ip = "<INVALID>" };</span><br><span> vty_out(vty, " ip-sns-remote %s %u%s", addr_str.ip, addr_str.port, VTY_NEWLINE);</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+ llist_for_each_entry(fendpoint, &gss->foreign_local_endpoints, list) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (osmo_sockaddr_str_from_sockaddr(&addr_str, &fendpoint->saddr.u.sas) != 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ addr_str = (struct osmo_sockaddr_str) { .ip = "<INVALID>" };</span><br><span style="color: hsl(120, 100%, 40%);">+ vty_out(vty, " ip-sns-foreign %s %u signalling-weight %u data-weight %u%s",</span><br><span style="color: hsl(120, 100%, 40%);">+ addr_str.ip, addr_str.port, fendpoint->sig_weight, fendpoint->data_weight,</span><br><span style="color: hsl(120, 100%, 40%);">+ VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> }</span><br><span> </span><br><span> static struct sns_endpoint *ns2_get_sns_endpoint(struct ns2_sns_state *state,</span><br><span>@@ -1761,6 +1807,19 @@</span><br><span> return NULL;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static struct sns_foreign_endpoint *</span><br><span style="color: hsl(120, 100%, 40%);">+ns2_get_sns_foreign_endpoint(struct ns2_sns_state *state, const struct osmo_sockaddr *saddr)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct sns_foreign_endpoint *fendpoint;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ llist_for_each_entry(fendpoint, &state->foreign_local_endpoints, list) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!osmo_sockaddr_cmp(saddr, &fendpoint->saddr))</span><br><span style="color: hsl(120, 100%, 40%);">+ return fendpoint;</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%);">+ return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! gprs_ns2_sns_add_endpoint</span><br><span> * \param[in] nse</span><br><span> * \param[in] sockaddr</span><br><span>@@ -1855,6 +1914,77 @@</span><br><span> return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! Add a foreign IP endpoint to the "local" side.</span><br><span style="color: hsl(120, 100%, 40%);">+ * This is mostly useful in fail-over situations where the current "master"</span><br><span style="color: hsl(120, 100%, 40%);">+ * node would want to advertise the IP endpoints of a current "slave" node</span><br><span style="color: hsl(120, 100%, 40%);">+ * together with the truly local endpoints.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] nse NS entity to which the foreign EP shall be added</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] sockaddr the socket address of the foreign EP</span><br><span style="color: hsl(120, 100%, 40%);">+ * \return 0 on success; negative on error</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int gprs_ns2_sns_add_foreign_endpoint(struct gprs_ns2_nse *nse,</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct osmo_sockaddr *foreign,</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t sig_weight, uint16_t data_weight)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ns2_sns_state *gss;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct sns_foreign_endpoint *fendpoint;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (nse->ll != GPRS_NS2_LL_UDP) {</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (nse->dialect != GPRS_NS2_DIALECT_SNS) {</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ gss = nse->bss_sns_fi->priv;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ns2_get_sns_foreign_endpoint(gss, foreign))</span><br><span style="color: hsl(120, 100%, 40%);">+ return -EADDRINUSE;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ fendpoint = talloc_zero(nse->bss_sns_fi->priv, struct sns_foreign_endpoint);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!fendpoint)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -ENOMEM;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ fendpoint->saddr = *foreign;</span><br><span style="color: hsl(120, 100%, 40%);">+ fendpoint->sig_weight = sig_weight;</span><br><span style="color: hsl(120, 100%, 40%);">+ fendpoint->data_weight = data_weight;</span><br><span style="color: hsl(120, 100%, 40%);">+ llist_add_tail(&fendpoint->list, &gss->foreign_local_endpoints);</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 style="color: hsl(120, 100%, 40%);">+/*! Delete a foreign IP endpoint from the "local" side.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] nse NS entity from which the foreign EP shall be deleted</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] sockaddr the socket address of the foreign EP</span><br><span style="color: hsl(120, 100%, 40%);">+ * \return 0 on success, otherwise < 0</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int gprs_ns2_sns_del_foreign_endpoint(struct gprs_ns2_nse *nse,</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct osmo_sockaddr *foreign)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ns2_sns_state *gss;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct sns_foreign_endpoint *fendpoint;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (nse->ll != GPRS_NS2_LL_UDP) {</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (nse->dialect != GPRS_NS2_DIALECT_SNS) {</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ gss = nse->bss_sns_fi->priv;</span><br><span style="color: hsl(120, 100%, 40%);">+ fendpoint = ns2_get_sns_foreign_endpoint(gss, foreign);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!fendpoint)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -ENOENT;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ llist_del(&fendpoint->list);</span><br><span style="color: hsl(120, 100%, 40%);">+ talloc_free(fendpoint);</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> /*! gprs_ns2_sns_count</span><br><span> * \param[in] nse NS Entity whose IP-SNS endpoints shall be printed</span><br><span> * \return the count of endpoints or < 0 if NSE doesn't contain sns.</span><br><span>@@ -2280,6 +2410,7 @@</span><br><span> gss->nse = nse;</span><br><span> gss->role = GPRS_SNS_ROLE_SGSN;</span><br><span> INIT_LLIST_HEAD(&gss->sns_endpoints);</span><br><span style="color: hsl(120, 100%, 40%);">+ INIT_LLIST_HEAD(&gss->foreign_local_endpoints);</span><br><span> INIT_LLIST_HEAD(&gss->binds);</span><br><span> </span><br><span> return fi;</span><br><span>diff --git a/src/gb/gprs_ns2_vty.c b/src/gb/gprs_ns2_vty.c</span><br><span>index fc060ae..6eea00d 100644</span><br><span>--- a/src/gb/gprs_ns2_vty.c</span><br><span>+++ b/src/gb/gprs_ns2_vty.c</span><br><span>@@ -1473,6 +1473,102 @@</span><br><span> return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+DEFUN(cfg_ns_nse_ip_sns_foreign, cfg_ns_nse_ip_sns_foreign_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+ "ip-sns-foreign " VTY_IPV46_CMD " <1-65535> signalling-weight <0-254> data-weight <0-254>",</span><br><span style="color: hsl(120, 100%, 40%);">+ "SNS Foreign Local Endpoint (for fail-over)\n"</span><br><span style="color: hsl(120, 100%, 40%);">+ "PCU Foreign IPv4 Address\n" "PCU Foreign IPv6 Address\n"</span><br><span style="color: hsl(120, 100%, 40%);">+ "PCU Foreign UDP Port\n"</span><br><span style="color: hsl(120, 100%, 40%);">+ "signalling weight used by IP-SNS dynamic configuration\n"</span><br><span style="color: hsl(120, 100%, 40%);">+ "signalling weight used by IP-SNS dynamic configuration\n"</span><br><span style="color: hsl(120, 100%, 40%);">+ "data weight used by IP-SNS dynamic configuration\n"</span><br><span style="color: hsl(120, 100%, 40%);">+ "data weight used by IP-SNS dynamic configuration\n"</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%);">+ struct gprs_ns2_nse *nse = vty->index;</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%);">+ struct osmo_sockaddr_str foreign_str;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_sockaddr foreign;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t port = atoi(argv[1]);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (nse->ll != GPRS_NS2_LL_UDP) {</span><br><span style="color: hsl(120, 100%, 40%);">+ vty_out(vty, "Can not mix NS-VC with different link layer%s", VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+ goto err;</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 (nse->dialect != GPRS_NS2_DIALECT_SNS) {</span><br><span style="color: hsl(120, 100%, 40%);">+ vty_out(vty, "Can not mix NS-VC with different dialects%s", VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+ goto err;</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 (osmo_sockaddr_str_from_str(&foreign_str, argv[0], port)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ vty_out(vty, "Can not parse IPv4/IPv6 or port.%s", VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+ goto err;</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 (osmo_sockaddr_str_to_sockaddr(&foreign_str, &foreign.u.sas)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ vty_out(vty, "Can not parse IPv4/IPv6 or port.%s", VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+ goto err;</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%);">+ rc = gprs_ns2_sns_add_foreign_endpoint(nse, &foreign, atoi(argv[2]), atoi(argv[3]));</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (rc) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case 0:</span><br><span style="color: hsl(120, 100%, 40%);">+ return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+ case -EADDRINUSE:</span><br><span style="color: hsl(120, 100%, 40%);">+ vty_out(vty, "Specified SNS endpoint already part of the NSE.%s", VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+ return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+ default:</span><br><span style="color: hsl(120, 100%, 40%);">+ vty_out(vty, "Can not add specified SNS endpoint.%s", VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+ return CMD_WARNING;</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%);">+err:</span><br><span style="color: hsl(120, 100%, 40%);">+ return CMD_WARNING;</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_no_ns_nse_ip_sns_foreign, cfg_no_ns_nse_ip_sns_foreign_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+ "no ip-sns-foreign " VTY_IPV46_CMD " <1-65535>",</span><br><span style="color: hsl(120, 100%, 40%);">+ NO_STR</span><br><span style="color: hsl(120, 100%, 40%);">+ "Delete a SNS Foreign Local Endpoint\n"</span><br><span style="color: hsl(120, 100%, 40%);">+ "PCU Foreign IPv4 Address\n" "PCU Foreign IPv6 Address\n"</span><br><span style="color: hsl(120, 100%, 40%);">+ "PCU Foreign UDP Port\n"</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%);">+ struct gprs_ns2_nse *nse = vty->index;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_sockaddr_str foreign_str; /* argv[0] */</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_sockaddr foreign;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t port = atoi(argv[1]);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (nse->ll != GPRS_NS2_LL_UDP) {</span><br><span style="color: hsl(120, 100%, 40%);">+ vty_out(vty, "This NSE doesn't support UDP.%s", VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+ return CMD_WARNING;</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 (nse->dialect != GPRS_NS2_DIALECT_SNS) {</span><br><span style="color: hsl(120, 100%, 40%);">+ vty_out(vty, "This NSE doesn't support UDP with dialect ip-sns.%s", VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+ return CMD_WARNING;</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 (osmo_sockaddr_str_from_str(&foreign_str, argv[0], port)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ vty_out(vty, "Can not parse IPv4/IPv6 or port.%s", VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+ return CMD_WARNING;</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 (osmo_sockaddr_str_to_sockaddr(&foreign_str, &foreign.u.sas)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ vty_out(vty, "Can not parse IPv4/IPv6 or port.%s", VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+ return CMD_WARNING;</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 (gprs_ns2_sns_del_foreign_endpoint(nse, &foreign)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ vty_out(vty, "Can not remove specified foreign SNS endpoint.%s", VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+ return CMD_WARNING;</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%);">+ 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> DEFUN(cfg_ns_nse_ip_sns_remote, cfg_ns_nse_ip_sns_remote_cmd,</span><br><span> "ip-sns-remote " VTY_IPV46_CMD " <1-65535>",</span><br><span> "SNS Initial Endpoint\n"</span><br><span>@@ -2230,6 +2326,8 @@</span><br><span> install_lib_element(L_NS_NSE_NODE, &cfg_no_ns_nse_ip_sns_remote_cmd);</span><br><span> install_lib_element(L_NS_NSE_NODE, &cfg_ns_nse_ip_sns_bind_cmd);</span><br><span> install_lib_element(L_NS_NSE_NODE, &cfg_no_ns_nse_ip_sns_bind_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+ install_lib_element(L_NS_NSE_NODE, &cfg_ns_nse_ip_sns_foreign_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+ install_lib_element(L_NS_NSE_NODE, &cfg_no_ns_nse_ip_sns_foreign_cmd);</span><br><span> </span><br><span> return 0;</span><br><span> }</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/libosmocore/+/23521">change 23521</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/libosmocore/+/23521"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: libosmocore </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: If9c4d3f62bfc2a47518dce90188e5fa85e21e4cc </div>
<div style="display:none"> Gerrit-Change-Number: 23521 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>