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/.
lynxis lazus gerrit-no-reply at lists.osmocom.orglynxis lazus has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmocore/+/23758 )
Change subject: gprs_ns2: implement local update weight procedure
......................................................................
gprs_ns2: implement local update weight procedure
When changing the bind ip-sns weight, initiate a
SNS UPDATE WEIGHT procedure to inform the other side.
Related: OS#5036
Change-Id: If034ac371a604bab5e58beadb784382c8b97cca3
---
M src/gb/gprs_ns2.c
M src/gb/gprs_ns2_internal.h
M src/gb/gprs_ns2_sns.c
M src/gb/gprs_ns2_vty.c
M tests/gb/gprs_ns2_vty.vty
5 files changed, 298 insertions(+), 10 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/58/23758/1
diff --git a/src/gb/gprs_ns2.c b/src/gb/gprs_ns2.c
index 1148d6f..2f8396e 100644
--- a/src/gb/gprs_ns2.c
+++ b/src/gb/gprs_ns2.c
@@ -1400,6 +1400,7 @@
nsi->timeout[NS_TOUT_TSNS_PROV] = 3; /* 1..10 */
nsi->timeout[NS_TOUT_TSNS_SIZE_RETRIES] = 3;
nsi->timeout[NS_TOUT_TSNS_CONFIG_RETRIES] = 3;
+ nsi->timeout[NS_TOUT_TSNS_PROCEDURES_RETRIES] = 3;
return nsi;
}
diff --git a/src/gb/gprs_ns2_internal.h b/src/gb/gprs_ns2_internal.h
index 70e212a..8b02a88 100644
--- a/src/gb/gprs_ns2_internal.h
+++ b/src/gb/gprs_ns2_internal.h
@@ -46,8 +46,8 @@
struct gprs_ns2_vc_driver;
struct gprs_ns2_vc_bind;
-#define NS_TIMERS_COUNT 10
-#define NS_TIMERS "(tns-block|tns-block-retries|tns-reset|tns-reset-retries|tns-test|tns-alive|tns-alive-retries|tsns-prov|tsns-size-retries|tsns-config-retries)"
+#define NS_TIMERS_COUNT 11
+#define NS_TIMERS "(tns-block|tns-block-retries|tns-reset|tns-reset-retries|tns-test|tns-alive|tns-alive-retries|tsns-prov|tsns-size-retries|tsns-config-retries|tsns-procedures-retries)"
#define NS_TIMERS_HELP \
"(un)blocking Timer (Tns-block) timeout\n" \
"(un)blocking Timer (Tns-block) number of retries\n" \
@@ -59,6 +59,7 @@
"SNS Provision Timer (Tsns-prov) timeout\n" \
"SNS Size number of retries\n" \
"SNS Config number of retries\n" \
+ "SNS Procedures number of retries\n" \
/* Educated guess - LLC user payload is 1500 bytes plus possible headers */
#define NS_ALLOC_SIZE 3072
@@ -75,6 +76,7 @@
NS_TOUT_TSNS_PROV,
NS_TOUT_TSNS_SIZE_RETRIES,
NS_TOUT_TSNS_CONFIG_RETRIES,
+ NS_TOUT_TSNS_PROCEDURES_RETRIES,
};
enum nsvc_timer_mode {
diff --git a/src/gb/gprs_ns2_sns.c b/src/gb/gprs_ns2_sns.c
index c6e80af..a19171f 100644
--- a/src/gb/gprs_ns2_sns.c
+++ b/src/gb/gprs_ns2_sns.c
@@ -75,6 +75,7 @@
GPRS_SNS_ST_CONFIGURED,
GPRS_SNS_ST_SGSN_WAIT_CONFIG, /* !< SGSN role: Wait for CONFIG from BSS */
GPRS_SNS_ST_SGSN_WAIT_CONFIG_ACK, /* !< SGSN role: Wait for CONFIG-ACK from BSS */
+ GPRS_SNS_ST_LOCAL_PROCEDURE, /*!< in process of a ADD/DEL/UPDATE procedure towards SGSN (BSS->SGSN) */
};
enum gprs_sns_event {
@@ -92,6 +93,7 @@
GPRS_SNS_EV_REQ_NSVC_ALIVE, /*!< a NS-VC became alive */
GPRS_SNS_EV_REQ_ADD_BIND, /*!< add a new local bind to this NSE */
GPRS_SNS_EV_REQ_DELETE_BIND, /*!< remove a local bind from this NSE */
+ GPRS_SNS_EV_REQ_CHANGE_WEIGHT, /*!< a bind changed its weight */
};
static const struct value_string gprs_sns_event_names[] = {
@@ -109,17 +111,40 @@
{ GPRS_SNS_EV_REQ_NSVC_ALIVE, "REQ_NSVC_ALIVE"},
{ GPRS_SNS_EV_REQ_ADD_BIND, "REQ_ADD_BIND"},
{ GPRS_SNS_EV_REQ_DELETE_BIND, "REQ_DELETE_BIND"},
+ { GPRS_SNS_EV_REQ_CHANGE_WEIGHT, "REQ_UPDATE_WEIGHT"},
{ 0, NULL }
};
+enum sns_procedure {
+ SNS_NONE, /*!< used as invalid/idle value */
+ SNS_ADD,
+ SNS_DEL,
+ SNS_CHANGE_WEIGHT,
+};
+
+enum sns_bind_flag {
+ SNS_BIND_CHANGE_REQ, /*!< need to change */
+ SNS_BIND_CHANGE_IN_PROGRESS, /*!< change is going on */
+};
+
struct sns_endpoint {
struct llist_head list;
struct osmo_sockaddr saddr;
};
+struct ns2_sns_procedure {
+ struct llist_head list;
+ struct ns2_sns_bind *bind;
+ struct gprs_ns_ie_ip4_elem *ip4;
+ struct gprs_ns_ie_ip6_elem *ip6;
+ enum sns_procedure procedure;
+ uint8_t trans_id;
+};
+
struct ns2_sns_bind {
struct llist_head list;
struct gprs_ns2_vc_bind *bind;
+ uint8_t change_weight_state;
};
struct ns2_sns_state {
@@ -170,14 +195,46 @@
/* remote configuration as received */
struct gprs_ns_ie_ip6_elem *ip6_remote;
unsigned int num_ip6_remote;
+
+ struct ns2_sns_procedure current_procedure;
};
+static void ns2_procedure_set_endpoint(struct ns2_sns_state *gss);
+
static inline struct gprs_ns2_nse *nse_inst_from_fi(struct osmo_fsm_inst *fi)
{
struct ns2_sns_state *gss = (struct ns2_sns_state *) fi->priv;
return gss->nse;
}
+static struct gprs_ns_ie_ip4_elem *ip4_elem_by_saddr(struct gprs_ns_ie_ip4_elem *ip4, size_t num, const struct osmo_sockaddr *saddr)
+{
+ if (saddr->u.sa.sa_family != AF_INET)
+ return NULL;
+
+ for (size_t i = 0; i < num; i++) {
+ if (ip4[i].ip_addr == saddr->u.sin.sin_addr.s_addr &&
+ ip4->udp_port == saddr->u.sin.sin_port)
+ return &ip4[i];
+ }
+
+ return NULL;
+}
+
+static struct gprs_ns_ie_ip6_elem *ip6_elem_by_saddr(struct gprs_ns_ie_ip6_elem *ip6, size_t num, const struct osmo_sockaddr *saddr)
+{
+ if (saddr->u.sa.sa_family != AF_INET6)
+ return NULL;
+
+ for (size_t i = 0; i < num; i++) {
+ if (memcmp(&ip6[i].ip_addr, &saddr->u.sin6.sin6_addr, sizeof(struct in6_addr)) == 0 &&
+ ip6->udp_port == saddr->u.sin6.sin6_port)
+ return &ip6[i];
+ }
+
+ return NULL;
+}
+
/* helper function to compute the sum of all (data or signaling) weights */
static int ip4_weight_sum(const struct gprs_ns_ie_ip4_elem *ip4, unsigned int num,
bool data_weight)
@@ -298,6 +355,11 @@
osmo_fsm_inst_dispatch(fi, GPRS_SNS_EV_REQ_NO_NSVC, NULL);
}
+static void ns2_clear_procedures(struct ns2_sns_state *gss)
+{
+ memset(&gss->current_procedure, 0, sizeof(struct ns2_sns_state));
+}
+
static void ns2_clear_ipv46_entries_local(struct ns2_sns_state *gss)
{
TALLOC_FREE(gss->ip4_local);
@@ -896,6 +958,7 @@
if (old_state != GPRS_SNS_ST_BSS_SIZE)
gss->N = 0;
+ ns2_clear_procedures(gss);
gss->alive = false;
ns2_sns_compute_local_ep_from_binds(fi);
@@ -1372,7 +1435,102 @@
if (gss->sns_nsvc->sns_only)
gprs_ns2_free_nsvc(gss->sns_nsvc);
- ns2_prim_status_ind(nse, NULL, 0, GPRS_NS2_AFF_CAUSE_SNS_CONFIGURED);
+ if (old_state != GPRS_SNS_ST_LOCAL_PROCEDURE)
+ ns2_prim_status_ind(nse, NULL, 0, GPRS_NS2_AFF_CAUSE_SNS_CONFIGURED);
+}
+
+static void ns2_sns_st_local_procedure_onenter(struct osmo_fsm_inst *fi, uint32_t old_state)
+{
+ struct ns2_sns_state *gss = (struct ns2_sns_state *) fi->priv;
+ struct ns2_sns_bind *sns_bind;
+
+ if (gss->current_procedure.procedure == SNS_NONE) {
+ gss->N = 0;
+ /* select the next procedure */
+ llist_for_each_entry(sns_bind, &gss->binds, list) {
+ if (sns_bind->change_weight_state & S(SNS_BIND_CHANGE_REQ)) {
+ sns_bind->change_weight_state = 0;
+ gss->current_procedure.bind = sns_bind;
+ gss->current_procedure.procedure = SNS_CHANGE_WEIGHT;
+ ns2_procedure_set_endpoint(gss);
+ break;
+ }
+ }
+
+ if (gss->current_procedure.procedure == SNS_NONE) {
+ /* nothing to do */
+ osmo_fsm_inst_state_chg(fi, GPRS_SNS_ST_CONFIGURED, 0, 0);
+ return;
+ }
+ gss->current_procedure.trans_id++;
+ if (gss->current_procedure.trans_id == 0)
+ gss->current_procedure.trans_id = 1;
+ }
+
+ /* also takes care of retransmitting */
+ switch (gss->current_procedure.procedure) {
+ case SNS_ADD:
+ if (gss->ip == IPv4)
+ ns2_tx_sns_add(gss->sns_nsvc, gss->current_procedure.trans_id, gss->current_procedure.ip4, 1, NULL, 0);
+ else
+ ns2_tx_sns_add(gss->sns_nsvc, gss->current_procedure.trans_id, NULL, 0, gss->current_procedure.ip6, 1);
+ break;
+ case SNS_CHANGE_WEIGHT:
+ if (gss->ip == IPv4)
+ ns2_tx_sns_change_weight(gss->sns_nsvc, gss->current_procedure.trans_id, gss->current_procedure.ip4, 1, NULL, 0);
+ else
+ ns2_tx_sns_change_weight(gss->sns_nsvc, gss->current_procedure.trans_id, NULL, 0, gss->current_procedure.ip6, 1);
+ break;
+ case SNS_DEL:
+ if (gss->ip == IPv4)
+ ns2_tx_sns_del(gss->sns_nsvc, gss->current_procedure.trans_id, gss->current_procedure.ip4, 1, NULL, 0);
+ else
+ ns2_tx_sns_del(gss->sns_nsvc, gss->current_procedure.trans_id, NULL, 0, gss->current_procedure.ip6, 1);
+ break;
+ default:
+ break;
+ }
+}
+
+static void ns2_sns_st_local_procedure(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct ns2_sns_state *gss = (struct ns2_sns_state *) fi->priv;
+ struct gprs_ns2_nse *nse = nse_inst_from_fi(fi);
+ struct gprs_ns2_inst *nsi = nse->nsi;
+ struct tlv_parsed *tp = data;
+ uint8_t trans_id;
+
+ switch (event) {
+ case GPRS_SNS_EV_RX_ADD:
+ ns2_sns_st_configured_add(fi, gss, tp);
+ break;
+ case GPRS_SNS_EV_RX_DELETE:
+ ns2_sns_st_configured_delete(fi, gss, tp);
+ break;
+ case GPRS_SNS_EV_RX_CHANGE_WEIGHT:
+ ns2_sns_st_configured_change(fi, gss, tp);
+ break;
+ case GPRS_SNS_EV_RX_ACK:
+ /* presence of trans_id is already checked here */
+ trans_id = tlvp_val8(tp, NS_IE_TRANS_ID, 0);
+ if (trans_id != gss->current_procedure.trans_id) {
+ LOGPFSML(fi, LOGL_DEBUG, "NSEI=%u Rx SNS ACK with invalid transaction id %d. Valid %d\n",
+ nse->nsei, trans_id, gss->current_procedure.trans_id);
+ break;
+ }
+
+ if (!TLVP_PRESENT(tp, NS_IE_CAUSE)) {
+ gss->current_procedure.procedure = SNS_NONE;
+ /* everything ok, local_procedure_onenter() will check if there are more procedures required */
+
+ osmo_fsm_inst_state_chg(fi, GPRS_SNS_ST_LOCAL_PROCEDURE,
+ nsi->timeout[NS_TOUT_TSNS_PROV], GPRS_SNS_ST_LOCAL_PROCEDURE);
+ return;
+ } else {
+ /* what happend on error cause? return to size? */
+ }
+ break;
+ }
}
static const struct osmo_fsm_state ns2_sns_bss_states[] = {
@@ -1419,11 +1577,27 @@
S(GPRS_SNS_EV_RX_CHANGE_WEIGHT) |
S(GPRS_SNS_EV_REQ_NSVC_ALIVE),
.out_state_mask = S(GPRS_SNS_ST_UNCONFIGURED) |
- S(GPRS_SNS_ST_BSS_SIZE),
+ S(GPRS_SNS_ST_BSS_SIZE) |
+ S(GPRS_SNS_ST_LOCAL_PROCEDURE),
.name = "CONFIGURED",
.action = ns2_sns_st_configured,
.onenter = ns2_sns_st_configured_onenter,
},
+ [GPRS_SNS_ST_LOCAL_PROCEDURE] = {
+ .in_event_mask = S(GPRS_SNS_EV_RX_ADD) |
+ S(GPRS_SNS_EV_RX_DELETE) |
+ S(GPRS_SNS_EV_RX_CHANGE_WEIGHT) |
+ S(GPRS_SNS_EV_RX_ACK) |
+ S(GPRS_SNS_EV_REQ_NSVC_ALIVE),
+ .out_state_mask = S(GPRS_SNS_ST_UNCONFIGURED) |
+ S(GPRS_SNS_ST_BSS_SIZE) |
+ S(GPRS_SNS_ST_CONFIGURED) |
+ S(GPRS_SNS_ST_LOCAL_PROCEDURE),
+ .name = "LOCAL_PROCEDURE",
+ .action = ns2_sns_st_local_procedure,
+ .onenter = ns2_sns_st_local_procedure_onenter,
+ },
+
};
static int ns2_sns_fsm_bss_timer_cb(struct osmo_fsm_inst *fi)
@@ -1462,6 +1636,14 @@
LOGPFSML(fi, LOGL_ERROR, "NSE %d: Config succeeded but no NS-VC came online. Selecting next IP-SNS endpoint.\n", nse->nsei);
osmo_fsm_inst_dispatch(fi, GPRS_SNS_EV_REQ_SELECT_ENDPOINT, NULL);
break;
+ case GPRS_SNS_ST_LOCAL_PROCEDURE:
+ if (gss->N >= nsi->timeout[NS_TOUT_TSNS_CONFIG_RETRIES]) {
+ LOGPFSML(fi, LOGL_ERROR, "NSE %d: Procedure retries failed. Restarting NSE.\n", nse->nsei);
+ osmo_fsm_inst_dispatch(fi, GPRS_SNS_EV_REQ_SELECT_ENDPOINT, NULL);
+ } else {
+ osmo_fsm_inst_state_chg(fi, GPRS_SNS_ST_LOCAL_PROCEDURE, nsi->timeout[NS_TOUT_TSNS_PROV], GPRS_SNS_ST_LOCAL_PROCEDURE);
+ }
+ break;
}
return 0;
}
@@ -1518,6 +1700,21 @@
/* if this is the last bind, the free_nsvc() will trigger a reselection */
talloc_free(sbind);
break;
+ case GPRS_SNS_EV_REQ_CHANGE_WEIGHT:
+ sbind = data;
+ switch (fi->state) {
+ case GPRS_SNS_ST_UNCONFIGURED:
+ case GPRS_SNS_ST_BSS_SIZE:
+ /* unconfigured or size don't need a procedure */
+ break;
+ /* all other states */
+ default:
+ /* change the flag */
+ sbind->change_weight_state |= S(SNS_BIND_CHANGE_REQ);
+ osmo_fsm_inst_state_chg(fi, GPRS_SNS_ST_LOCAL_PROCEDURE, nse->nsi->timeout[NS_TOUT_TSNS_PROV], GPRS_SNS_ST_LOCAL_PROCEDURE);
+ break;
+ }
+ break;
}
}
@@ -1577,6 +1774,7 @@
.allstate_event_mask = S(GPRS_SNS_EV_REQ_NO_NSVC) |
S(GPRS_SNS_EV_REQ_SELECT_ENDPOINT) |
S(GPRS_SNS_EV_REQ_ADD_BIND) |
+ S(GPRS_SNS_EV_REQ_CHANGE_WEIGHT) |
S(GPRS_SNS_EV_REQ_DELETE_BIND),
.allstate_action = ns2_sns_st_all_action_bss,
.cleanup = NULL,
@@ -1911,7 +2109,7 @@
return;
gss = nse->bss_sns_fi->priv;
- if(nse->bss_sns_fi->state != GPRS_SNS_ST_CONFIGURED)
+ if(nse->bss_sns_fi->state != GPRS_SNS_ST_CONFIGURED && nse->bss_sns_fi->state != GPRS_SNS_ST_LOCAL_PROCEDURE)
return;
if (alive == gss->alive)
@@ -2005,12 +2203,71 @@
return 0;
}
-/* Update SNS weights
- * \param[in] nsvc the NSVC which should be updated
+/* Update SNS weights for a bind (local endpoint). */
+static void ns2_procedure_set_endpoint(struct ns2_sns_state *gss) {
+ struct osmo_sockaddr *local = NULL, *remote = NULL;
+ const struct osmo_sockaddr *sa;
+ struct gprs_ns_ie_ip4_elem *ip4;
+ struct gprs_ns_ie_ip6_elem *ip6;
+
+ /* TODO: ensure this bind is already added! */
+ OSMO_ASSERT(gss->current_procedure.procedure != SNS_NONE);
+ sa = gprs_ns2_ip_bind_sockaddr(gss->current_procedure.bind->bind);
+ if (!sa)
+ return;
+
+ switch (sa->u.sa.sa_family) {
+ case AF_INET:
+ if (sa->u.sin.sin_addr.s_addr == 0) {
+ if (osmo_sockaddr_local_ip(local, &gss->initial->saddr))
+ return;
+ ip4 = ip4_elem_by_saddr(gss->ip4_local, gss->num_ip4_local, local);
+ } else {
+ ip4 = ip4_elem_by_saddr(gss->ip4_local, gss->num_ip4_local, sa);
+ }
+
+ /* TODO: check if this bind is about to be added */
+ OSMO_ASSERT(ip4);
+ gss->current_procedure.ip4 = ip4;
+ break;
+ case AF_INET6:
+ // in6addr_any
+ if (memcmp(&sa->u.sin6.sin6_addr, &in6addr_any, sizeof(struct in6_addr))) {
+ if (osmo_sockaddr_local_ip(local, remote))
+ return;
+ ip6 = ip6_elem_by_saddr(gss->ip6_local, gss->num_ip6_local, local);
+ } else {
+ ip6 = ip6_elem_by_saddr(gss->ip6_local, gss->num_ip6_local, sa);
+ }
+ OSMO_ASSERT(ip6);
+ gss->current_procedure.ip6 = ip6;
+ break;
+ default:
+ OSMO_ASSERT(false);
+ break;
+ }
+}
+
+/* Update SNS weights for a bind (local endpoint).
+ * \param[in] bind the bind which has been updated
*/
void ns2_sns_update_weights(struct gprs_ns2_vc_bind *bind)
{
- /* TODO: implement weights after binds per sns implemented */
+ struct ns2_sns_bind *sns_bind;
+ struct gprs_ns2_nse *nse;
+ struct ns2_sns_state *gss;
+ llist_for_each_entry(nse, &bind->nsi->nse, list) {
+ if (!nse->bss_sns_fi)
+ continue;
+
+ gss = nse->bss_sns_fi->priv;
+ llist_for_each_entry(sns_bind, &gss->binds, list) {
+ if (sns_bind->bind == bind) {
+ osmo_fsm_inst_dispatch(gss->nse->bss_sns_fi, GPRS_SNS_EV_REQ_CHANGE_WEIGHT, sns_bind);
+ break;
+ }
+ }
+ }
}
@@ -2145,6 +2402,22 @@
.action = ns2_sns_st_configured,
.onenter = ns2_sns_st_configured_onenter,
},
+ [GPRS_SNS_ST_LOCAL_PROCEDURE] = {
+ .in_event_mask = S(GPRS_SNS_EV_RX_ADD) |
+ S(GPRS_SNS_EV_RX_DELETE) |
+ S(GPRS_SNS_EV_RX_CHANGE_WEIGHT) |
+ S(GPRS_SNS_EV_RX_ACK) |
+ S(GPRS_SNS_EV_REQ_CHANGE_WEIGHT) |
+ S(GPRS_SNS_EV_REQ_NSVC_ALIVE),
+ .out_state_mask = S(GPRS_SNS_ST_UNCONFIGURED) |
+ S(GPRS_SNS_ST_BSS_SIZE) |
+ S(GPRS_SNS_ST_CONFIGURED) |
+ S(GPRS_SNS_ST_LOCAL_PROCEDURE),
+ .name = "LOCAL_PROCEDURE",
+ /* shared with BSS side; once configured there's no difference */
+ .action = ns2_sns_st_local_procedure,
+ .onenter = ns2_sns_st_local_procedure_onenter,
+ },
};
static int ns2_sns_fsm_sgsn_timer_cb(struct osmo_fsm_inst *fi)
@@ -2166,11 +2439,20 @@
case 4:
LOGPFSML(fi, LOGL_ERROR, "NSE %d: Config succeeded but no NS-VC came online.\n", nse->nsei);
break;
+ case GPRS_SNS_ST_LOCAL_PROCEDURE:
+ if (gss->N >= nsi->timeout[NS_TOUT_TSNS_PROCEDURES_RETRIES]) {
+ LOGPFSML(fi, LOGL_ERROR, "NSE %d: SNS Procedure retries failed. Selecting next IP-SNS endpoint.\n", nse->nsei);
+ osmo_fsm_inst_dispatch(fi, GPRS_SNS_EV_REQ_SELECT_ENDPOINT, NULL);
+ } else {
+ osmo_fsm_inst_state_chg(fi, GPRS_SNS_ST_LOCAL_PROCEDURE, nsi->timeout[NS_TOUT_TSNS_PROV],
+ fi->T);
+ }
+ break;
}
+
return 0;
}
-
/* allstate-action for SGSN role */
static void ns2_sns_st_all_action_sgsn(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
@@ -2238,6 +2520,7 @@
/* clear all state */
osmo_fsm_inst_state_chg(fi, GPRS_SNS_ST_UNCONFIGURED, 0, 0);
gss->N = 0;
+ ns2_clear_procedures(gss);
ns2_clear_ipv46_entries_local(gss);
ns2_clear_ipv46_entries_remote(gss);
llist_for_each_entry_safe(nsvc, nsvc2, &gss->nse->nsvc, list) {
@@ -2272,6 +2555,7 @@
.allstate_event_mask = S(GPRS_SNS_EV_RX_SIZE) |
S(GPRS_SNS_EV_REQ_NO_NSVC) |
S(GPRS_SNS_EV_REQ_ADD_BIND) |
+ S(GPRS_SNS_EV_REQ_CHANGE_WEIGHT) |
S(GPRS_SNS_EV_REQ_DELETE_BIND),
.allstate_action = ns2_sns_st_all_action_sgsn,
.cleanup = NULL,
diff --git a/src/gb/gprs_ns2_vty.c b/src/gb/gprs_ns2_vty.c
index b678db4..169b891 100644
--- a/src/gb/gprs_ns2_vty.c
+++ b/src/gb/gprs_ns2_vty.c
@@ -100,6 +100,7 @@
{ 7, "tsns-prov" },
{ 8, "tsns-size-retries" },
{ 9, "tsns-config-retries" },
+ {10, "tsns-procedures-retries" },
{ 0, NULL }
};
diff --git a/tests/gb/gprs_ns2_vty.vty b/tests/gb/gprs_ns2_vty.vty
index 78c7e78..1c78069 100644
--- a/tests/gb/gprs_ns2_vty.vty
+++ b/tests/gb/gprs_ns2_vty.vty
@@ -17,7 +17,7 @@
OsmoNSdummy(config)# ns
OsmoNSdummy(config-ns)# list
...
- timer (tns-block|tns-block-retries|tns-reset|tns-reset-retries|tns-test|tns-alive|tns-alive-retries|tsns-prov|tsns-size-retries|tsns-config-retries) <0-65535>
+ timer (tns-block|tns-block-retries|tns-reset|tns-reset-retries|tns-test|tns-alive|tns-alive-retries|tsns-prov|tsns-size-retries|tsns-config-retries|tsns-procedures-retries) <0-65535>
nse <0-65535> [ip-sns-role-sgsn]
no nse <0-65535>
bind (fr|udp) ID
--
To view, visit https://gerrit.osmocom.org/c/libosmocore/+/23758
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Change-Id: If034ac371a604bab5e58beadb784382c8b97cca3
Gerrit-Change-Number: 23758
Gerrit-PatchSet: 1
Gerrit-Owner: lynxis lazus <lynxis at fe80.eu>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210414/f0284142/attachment.htm>