Change in libosmocore[master]: gprs_ns2: implement local update weight procedure

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.org
Wed Apr 14 18:17:44 UTC 2021


lynxis 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>


More information about the gerrit-log mailing list