pespin has uploaded this change for review. (
https://gerrit.osmocom.org/c/libosmo-sigtran/+/42105?usp=email )
Change subject: Introduce struct osmo_ss7_as_asp_assoc
......................................................................
Introduce struct osmo_ss7_as_asp_assoc
This new struct allows supporting unlimited number of ASPs per AS.
It can also potentially be used in the future to:
* Hold M3UA "ASP Identifier" per AS<->ASP association
* Speed up iterating over AS served by a given ASP.
NOTE: Having >16 ASPs per AS may not be desirable, for instance under
loadshare traffic mode ITU SLS is 4 bit, so despite having ext_sls
extending the table to 128 entries based on OPC, it may not provide
enough entropy to properly loadshare among all of them.
Related: OS#7519
Change-Id: I149ab467899633ac50cba3e482b2cae02124279d
---
M src/ss7_as.c
M src/ss7_as.h
M src/ss7_as_vty.c
M src/ss7_combined_linkset.c
M src/ss7_instance.c
M src/ss7_internal.h
M src/ss7_route.c
M src/tcap_as_loadshare.c
M src/xua_as_fsm.c
M src/xua_asp_fsm.c
M src/xua_default_lm_fsm.c
11 files changed, 189 insertions(+), 180 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmo-sigtran
refs/changes/05/42105/1
diff --git a/src/ss7_as.c b/src/ss7_as.c
index f1c9528..f5f7c82 100644
--- a/src/ss7_as.c
+++ b/src/ss7_as.c
@@ -51,6 +51,31 @@
#include "xua_msg.h"
/***********************************************************************
+ * SS7 AS<->ASP association (N<->M arity)
+ ***********************************************************************/
+static struct ss7_as_asp_assoc *ss7_as_asp_assoc_alloc(struct osmo_ss7_as *as,
struct osmo_ss7_asp *asp)
+{
+ struct ss7_as_asp_assoc *assoc;
+
+ assoc = talloc_zero(as->inst, struct ss7_as_asp_assoc);
+ if (!as)
+ return NULL;
+ assoc->as = as;
+ assoc->asp = asp;
+ llist_add_tail(&assoc->as_entry, &as->asp_list);
+ as->num_asps++;
+
+ return assoc;
+}
+
+static void ss7_as_asp_assoc_free(struct ss7_as_asp_assoc *assoc)
+{
+ llist_del(&assoc->as_entry);
+ assoc->as->num_asps--;
+ talloc_free(assoc);
+}
+
+/***********************************************************************
* SS7 Application Server
***********************************************************************/
@@ -137,15 +162,13 @@
}
rate_ctr_group_set_name(as->ctrg, name);
as->inst = inst;
+ INIT_LLIST_HEAD(&as->asp_list);
as->cfg.name = talloc_strdup(as, name);
as->cfg.proto = proto;
as->cfg.mode = OSMO_SS7_AS_TMOD_OVERRIDE;
as->cfg.recovery_timeout_msec = 2000;
as->cfg.routing_key.l_rk_id = ss7_find_free_l_rk_id(inst);
- /* Pick 1st ASP upon 1st roundrobin assignment: */
- as->cfg.last_asp_idx_assigned = ARRAY_SIZE(as->cfg.asps) - 1;
-
#ifdef WITH_TCAP_LOADSHARING
/* loadshare-tcap based id sharing */
hash_init(as->tcap.tid_ranges);
@@ -176,7 +199,8 @@
* \returns 0 on success; negative in case of error */
int ss7_as_add_asp(struct osmo_ss7_as *as, struct osmo_ss7_asp *asp)
{
- unsigned int i;
+ struct ss7_as_asp_assoc *assoc;
+ OSMO_ASSERT(as);
OSMO_ASSERT(asp);
if (osmo_ss7_as_has_asp(as, asp))
@@ -184,17 +208,13 @@
LOGPAS(as, DLSS7, LOGL_INFO, "Adding ASP %s to AS\n", asp->cfg.name);
- for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) {
- if (!as->cfg.asps[i]) {
- as->cfg.asps[i] = asp;
- if (asp->fi)
- osmo_fsm_inst_dispatch(asp->fi,
XUA_ASP_E_AS_ASSIGNED, as);
- return 0;
- }
- }
+ assoc = ss7_as_asp_assoc_alloc(as, asp);
+ OSMO_ASSERT(assoc);
- LOGPAS(as, DLSS7, LOGL_ERROR, "Failed adding ASP %s to AS, ASP table is
full!\n", asp->cfg.name);
- return -ENOSPC;
+ if (asp->fi)
+ osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_AS_ASSIGNED, as);
+
+ return 0;
}
/*! \brief Add given ASP to given AS
@@ -213,6 +233,36 @@
return ss7_as_add_asp(as, asp);
}
+static struct ss7_as_asp_assoc *ss7_as_asp_assoc_find(const struct osmo_ss7_as
*as,
+ const struct osmo_ss7_asp
*asp)
+{
+ struct ss7_as_asp_assoc *assoc;
+ llist_for_each_entry(assoc, &as->asp_list, as_entry) {
+ if (assoc->asp == asp)
+ return assoc;
+ }
+ return NULL;
+}
+
+/* Update a given llist_round_robin state pointer which may point to an asp
being freed.
+ * Selects next in list if available, or sets pointer to null. */
+void ss7_as_del_asp_update_llist_round_robin(struct osmo_ss7_as *as, struct
osmo_ss7_asp *asp, struct ss7_as_asp_assoc **state)
+{
+ struct ss7_as_asp_assoc *assoc;
+
+ OSMO_ASSERT(state);
+ assoc = *state;
+ if (!assoc)
+ return;
+ if (asp != assoc->asp)
+ return;
+
+ assoc = ss7_as_asp_assoc_llist_round_robin(as, (void **)state);
+ /* If there's only one left, remove state: */
+ if (asp == assoc->asp)
+ *state = NULL;
+}
+
/*! \brief Delete given ASP from given AS
* \param[in] as Application Server from which \ref asp is deleted
* \param[in] asp Application Server Process to delete from \ref as
@@ -221,8 +271,11 @@
* \ref as may be freed during the function call. */
int ss7_as_del_asp(struct osmo_ss7_as *as, struct osmo_ss7_asp *asp)
{
- unsigned int i;
- bool found = false;
+ struct ss7_as_asp_assoc *assoc;
+
+ assoc = ss7_as_asp_assoc_find(as, asp);
+ if (!assoc)
+ return -EINVAL;
LOGPAS(as, DLSS7, LOGL_INFO, "Removing ASP %s from AS\n",
asp->cfg.name);
@@ -238,23 +291,19 @@
tcap_as_del_asp(as, asp);
#endif /* WITH_TCAP_LOADSHARING */
- for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) {
- if (as->cfg.asps[i] == asp) {
- as->cfg.asps[i] = NULL;
- found = true;
- break;
- }
- }
+ /* Update round robin state */
+ ss7_as_del_asp_update_llist_round_robin(as, asp,
&as->last_asp_idx_assigned);
+ ss7_as_del_asp_update_llist_round_robin(as, asp,
&as->last_asp_idx_sent);
+ ss7_as_asp_assoc_free(assoc);
/* RKM-dynamically allocated AS: If there are no other ASPs, destroy
the AS.
* RFC 4666 4.4.2: "If a Deregistration results in no more ASPs in an
* Application Server, an SG MAY delete the Routing Key data."
*/
- if (as->rkm_dyn_allocated && osmo_ss7_as_count_asp(as) == 0)
+ if (as->rkm_dyn_allocated && llist_empty(&as->asp_list))
osmo_ss7_as_destroy(as);
-
- return found ? 0 : -EINVAL;
+ return 0;
}
/*! \brief Delete given ASP from given AS
@@ -277,6 +326,7 @@
* \param[in] as Application Server to destroy */
void osmo_ss7_as_destroy(struct osmo_ss7_as *as)
{
+ struct ss7_as_asp_assoc *assoc;
OSMO_ASSERT(ss7_initialized);
LOGPAS(as, DLSS7, LOGL_INFO, "Destroying AS\n");
@@ -290,6 +340,9 @@
/* find any routes pointing to this AS and remove them */
ss7_route_table_del_routes_by_as(as->inst->rtable_system, as);
+ while ((assoc = llist_first_entry_or_null(&as->asp_list, struct
ss7_as_asp_assoc, as_entry)))
+ ss7_as_asp_assoc_free(assoc);
+
as->inst = NULL;
llist_del(&as->list);
rate_ctr_group_free(as->ctrg);
@@ -303,48 +356,22 @@
bool osmo_ss7_as_has_asp(const struct osmo_ss7_as *as,
const struct osmo_ss7_asp *asp)
{
- unsigned int i;
-
OSMO_ASSERT(ss7_initialized);
- for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) {
- if (as->cfg.asps[i] == asp)
- return true;
- }
- return false;
-}
-
-/*! Determine amount of ASPs associated to an AS.
- * \param[in] as Application Server.
- * \returns number of ASPs associated to as */
-unsigned int osmo_ss7_as_count_asp(const struct osmo_ss7_as *as)
-{
- unsigned int i;
- unsigned int cnt = 0;
-
- for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) {
- if (as->cfg.asps[i])
- cnt++;
- }
- return cnt;
+ return !!ss7_as_asp_assoc_find(as, asp);
}
/* Determine which role (SG/ASP/IPSP) we operate in.
* return enum osmo_ss7_asp_role on success, negative otherwise. */
int ss7_as_get_local_role(const struct osmo_ss7_as *as)
{
- unsigned int i;
+ struct ss7_as_asp_assoc *assoc;
/* this is a bit tricky. "osmo_ss7_as" has no configuration of a role,
* only the ASPs have. As they all must be of the same role, let's
simply
* find the first one and return its role */
- for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) {
- struct osmo_ss7_asp *asp = as->cfg.asps[i];
+ llist_for_each_entry(assoc, &as->asp_list, as_entry)
+ return assoc->asp->cfg.role;
- if (!asp)
- continue;
-
- return asp->cfg.role;
- }
/* No ASPs associated to this AS yet? */
return -1;
}
@@ -373,16 +400,13 @@
static struct osmo_ss7_asp *ss7_as_select_asp_override(struct osmo_ss7_as *as)
{
- struct osmo_ss7_asp *asp;
- unsigned int i;
+ struct ss7_as_asp_assoc *assoc;
- /* FIXME: proper selection of the ASP based on the SLS! */
- for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) {
- asp = as->cfg.asps[i];
- if (asp && osmo_ss7_asp_active(asp))
- break;
+ llist_for_each_entry(assoc, &as->asp_list, as_entry) {
+ if (osmo_ss7_asp_active(assoc->asp))
+ return assoc->asp;
}
- return asp;
+ return NULL;
}
/* Pick an ASP serving AS in a round-robin fashion.
@@ -394,41 +418,27 @@
* distribution. */
static struct osmo_ss7_asp *ss7_as_assign_asp_roundrobin(struct osmo_ss7_as
*as)
{
- struct osmo_ss7_asp *asp;
- unsigned int i;
- unsigned int first_idx;
+ struct ss7_as_asp_assoc *assoc;
- first_idx = (as->cfg.last_asp_idx_assigned + 1) %
ARRAY_SIZE(as->cfg.asps);
- i = first_idx;
- do {
- asp = as->cfg.asps[i];
- if (asp)
- break;
- i = (i + 1) % ARRAY_SIZE(as->cfg.asps);
- } while (i != first_idx);
- as->cfg.last_asp_idx_assigned = i;
-
- return asp;
+ for (unsigned int i = 0; i < as->num_asps; i++) {
+ assoc = ss7_as_asp_assoc_llist_round_robin(as,
&as->last_asp_idx_assigned);
+ if (assoc)
+ return assoc->asp;
+ }
+ return NULL;
}
/* Pick an active ASP serving AS in a round-robin fashion, to send a message
to. */
static struct osmo_ss7_asp *ss7_as_select_asp_roundrobin(struct osmo_ss7_as
*as)
{
- struct osmo_ss7_asp *asp;
- unsigned int i;
- unsigned int first_idx;
+ struct ss7_as_asp_assoc *assoc;
- first_idx = (as->cfg.last_asp_idx_sent + 1) % ARRAY_SIZE(as->cfg.asps);
- i = first_idx;
- do {
- asp = as->cfg.asps[i];
- if (asp && osmo_ss7_asp_active(asp))
- break;
- i = (i + 1) % ARRAY_SIZE(as->cfg.asps);
- } while (i != first_idx);
- as->cfg.last_asp_idx_sent = i;
-
- return asp;
+ for (unsigned int i = 0; i < as->num_asps; i++) {
+ assoc = ss7_as_asp_assoc_llist_round_robin(as,
&as->last_asp_idx_sent);
+ if (assoc && osmo_ss7_asp_active(assoc->asp))
+ return assoc->asp;
+ }
+ return NULL;
}
/* Reset loadshare bindings table. It will be filled in as needed.
@@ -437,7 +447,7 @@
void ss7_as_loadshare_binding_table_reset(struct osmo_ss7_as *as)
{
memset(&as->aesls_table[0], 0, sizeof(as->aesls_table));
- as->cfg.last_asp_idx_assigned = ARRAY_SIZE(as->cfg.asps) - 1;
+ as->last_asp_idx_assigned = NULL;
}
static as_ext_sls_t osmo_ss7_instance_calc_itu_as_ext_sls(const struct
osmo_ss7_as *as, uint32_t opc, uint8_t sls)
@@ -550,16 +560,15 @@
/* returns NULL if multiple ASPs would need to be selected. */
static struct osmo_ss7_asp *ss7_as_select_asp_broadcast(struct osmo_ss7_as *as)
{
- struct osmo_ss7_asp *asp;
+ struct ss7_as_asp_assoc *assoc;
struct osmo_ss7_asp *asp_found = NULL;
- for (unsigned int i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) {
- asp = as->cfg.asps[i];
- if (!asp || !osmo_ss7_asp_active(asp))
+ llist_for_each_entry(assoc, &as->asp_list, as_entry) {
+ if (!osmo_ss7_asp_active(assoc->asp))
continue;
if (asp_found) /* >1 ASPs selected, early return */
return NULL;
- asp_found = asp;
+ asp_found = assoc->asp;
}
return asp_found;
}
diff --git a/src/ss7_as.h b/src/ss7_as.h
index 252e863..4819c8e 100644
--- a/src/ss7_as.h
+++ b/src/ss7_as.h
@@ -83,6 +83,13 @@
struct osmo_ss7_asp *alt_asp;
};
+struct ss7_as_asp_assoc {
+ /* Entry in (struct osmo_ss7_as*)->asp_list */
+ struct llist_head as_entry;
+ struct osmo_ss7_as *as; /* backpointer */
+ struct osmo_ss7_asp *asp; /* backpointer */
+};
+
struct osmo_ss7_as {
/*! entry in 'ref osmo_ss7_instance.as_list */
struct llist_head list;
@@ -118,6 +125,13 @@
} tcap;
#endif /* WITH_TCAP_LOADSHARING */
+ /* used for load-sharing traffic mode (round robin implementation) */
+ struct ss7_as_asp_assoc *last_asp_idx_assigned;
+ struct ss7_as_asp_assoc *last_asp_idx_sent;
+
+ struct llist_head asp_list; /* list of struct ss7_as_asp_assoc */
+ unsigned long num_asps; /* amount of ss7_as_asp_assoc/ss7_asp in
asp_list */
+
struct {
char *name;
char *description;
@@ -138,11 +152,6 @@
enum osmo_ss7_as_patch_sccp_mode sccp_mode;
} pc_override;
- struct osmo_ss7_asp *asps[16];
- /* used for load-sharing traffic mode (round robin
implementation) */
- uint8_t last_asp_idx_assigned;
- uint8_t last_asp_idx_sent;
-
struct {
/* How many bits from ITU SLS field (starting from
least-significant-bit)
* to skip for routing decisions.
@@ -159,7 +168,7 @@
struct {
bool enabled;
unsigned int timeout_s;
- uint8_t last_asp_idx_sent;
+ struct ss7_as_asp_assoc *last_asp_idx_sent;
} tcap;
#endif /* WITH_TCAP_LOADSHARING */
} loadshare;
@@ -169,11 +178,14 @@
enum osmo_ss7_asp_protocol proto);
struct osmo_ss7_asp *ss7_as_select_asp(struct osmo_ss7_as *as, const struct
xua_msg *xua);
-unsigned int osmo_ss7_as_count_asp(const struct osmo_ss7_as *as);
int ss7_as_add_asp(struct osmo_ss7_as *as, struct osmo_ss7_asp *asp);
int ss7_as_del_asp(struct osmo_ss7_as *as, struct osmo_ss7_asp *asp);
int ss7_as_get_local_role(const struct osmo_ss7_as *as);
void ss7_as_loadshare_binding_table_reset(struct osmo_ss7_as *as);
+void ss7_as_del_asp_update_llist_round_robin(struct osmo_ss7_as *as, struct
osmo_ss7_asp *asp, struct ss7_as_asp_assoc **state);
+#define ss7_as_asp_assoc_llist_round_robin(as, state) \
+ ss7_llist_round_robin(&(as)->asp_list, (void **)state, struct
ss7_as_asp_assoc, as_entry)
+
#define LOGPAS(as, subsys, level, fmt, args ...) \
_LOGSS7((as)->inst, subsys, level, "AS(%s) " fmt, (as)->cfg.name, ##
args)
diff --git a/src/ss7_as_vty.c b/src/ss7_as_vty.c
index f92b6d7..6e2b582 100644
--- a/src/ss7_as_vty.c
+++ b/src/ss7_as_vty.c
@@ -41,6 +41,7 @@
#ifdef WITH_TCAP_LOADSHARING
#include "tcap_as_loadshare.h"
#endif /* WITH_TCAP_LOADSHARING */
+#include "ss7_as.h"
#include "ss7_asp.h"
#include "ss7_route.h"
#include "ss7_route_table.h"
@@ -468,7 +469,7 @@
void ss7_vty_write_one_as(struct vty *vty, struct osmo_ss7_as *as, bool
show_dyn_config)
{
struct osmo_ss7_routing_key *rkey;
- unsigned int i;
+ struct ss7_as_asp_assoc *assoc;
/* skip any dynamically allocated AS definitions */
if ((as->rkm_dyn_allocated || as->simple_client_allocated)
@@ -479,8 +480,8 @@
osmo_ss7_asp_protocol_name(as->cfg.proto), VTY_NEWLINE);
if (as->cfg.description)
vty_out(vty, " description %s%s", as->cfg.description,
VTY_NEWLINE);
- for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) {
- struct osmo_ss7_asp *asp = as->cfg.asps[i];
+ llist_for_each_entry(assoc, &as->asp_list, as_entry) {
+ struct osmo_ss7_asp *asp = assoc->asp;
if (!asp)
continue;
/* skip any dynamically created ASPs (e.g. auto-created at
connect time) */
diff --git a/src/ss7_combined_linkset.c b/src/ss7_combined_linkset.c
index 0b6dd3c..9f53b7b 100644
--- a/src/ss7_combined_linkset.c
+++ b/src/ss7_combined_linkset.c
@@ -50,20 +50,6 @@
* link set) or of an alternative link set (combined link set)."
*****************************************************************************/
-static inline struct llist_head *_ss7_llist_round_robin(struct llist_head
*list, void **state)
-{
- struct llist_head *e = *state;
- if (!e || e->next == list)
- e = list;
- e = e->next;
- if (e == list)
- e = NULL;
- *state = e;
- return e;
-}
-#define ss7_llist_round_robin(list, state, struct_type, entry_name) \
- llist_entry(_ss7_llist_round_robin(list, state), struct_type,
entry_name)
-
/*! \brief Insert combined_link into its routing table
* \param[in] clset Combined link to be inserted into its routing table
* \returns 0 on success, negative on error
diff --git a/src/ss7_instance.c b/src/ss7_instance.c
index b51f1b9..9cf4710 100644
--- a/src/ss7_instance.c
+++ b/src/ss7_instance.c
@@ -408,11 +408,11 @@
osmo_ss7_asp_find_by_proto(struct osmo_ss7_as *as,
enum osmo_ss7_asp_protocol proto)
{
- unsigned int i;
+ struct ss7_as_asp_assoc *assoc;
- for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) {
- if (as->cfg.asps[i] && as->cfg.asps[i]->cfg.proto == proto)
- return as->cfg.asps[i];
+ llist_for_each_entry(assoc, &as->asp_list, as_entry) {
+ if (assoc->asp->cfg.proto == proto)
+ return assoc->asp;
}
return NULL;
diff --git a/src/ss7_internal.h b/src/ss7_internal.h
index cfa092a..b70954e 100644
--- a/src/ss7_internal.h
+++ b/src/ss7_internal.h
@@ -4,6 +4,8 @@
#include <stdbool.h>
#include <stdint.h>
+
+#include <osmocom/core/linuxlist.h>
#include <osmocom/netif/stream.h>
#include <osmocom/sigtran/osmo_ss7.h>
@@ -28,5 +30,19 @@
int xua_tcp_segmentation_cb(struct msgb *msg);
+static inline struct llist_head *_ss7_llist_round_robin(struct llist_head
*list, void **state)
+{
+ struct llist_head *e = *state;
+ if (!e || e->next == list)
+ e = list;
+ e = e->next;
+ if (e == list)
+ e = NULL;
+ *state = e;
+ return e;
+}
+#define ss7_llist_round_robin(list, state, struct_type, entry_name) \
+ llist_entry(_ss7_llist_round_robin(list, state), struct_type,
entry_name)
+
/* VTY */
#define XUA_VAR_STR "(sua|m3ua|ipa)"
diff --git a/src/ss7_route.c b/src/ss7_route.c
index 713cc6a..914e615 100644
--- a/src/ss7_route.c
+++ b/src/ss7_route.c
@@ -326,14 +326,12 @@
if (rt->dest.as) {
struct osmo_ss7_as *as = rt->dest.as;
- int i;
APPEND(" via AS %s proto=%s", as->cfg.name,
osmo_ss7_asp_protocol_name(as->cfg.proto));
if (list_asps) {
- for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) {
- struct osmo_ss7_asp *asp = as->cfg.asps[i];
- if (!asp)
- continue;
+ struct ss7_as_asp_assoc *assoc;
+ llist_for_each_entry(assoc, &as->asp_list, as_entry) {
+ struct osmo_ss7_asp *asp = assoc->asp;
APPEND(" ASP");
if (asp->cfg.name)
APPEND(" %s", asp->cfg.name);
diff --git a/src/tcap_as_loadshare.c b/src/tcap_as_loadshare.c
index 5c964ce..f9b8bdd 100644
--- a/src/tcap_as_loadshare.c
+++ b/src/tcap_as_loadshare.c
@@ -230,21 +230,13 @@
static struct osmo_ss7_asp *find_asp_no_tcap_range(struct osmo_ss7_as *as)
{
- struct osmo_ss7_asp *asp;
- unsigned int i;
- unsigned int first_idx;
+ struct ss7_as_asp_assoc *assoc;
- first_idx = (as->cfg.loadshare.tcap.last_asp_idx_sent + 1) %
ARRAY_SIZE(as->cfg.asps);
- i = first_idx;
- do {
- asp = as->cfg.asps[i];
- if (asp && osmo_ss7_asp_active(asp) && asp->tcap.enabled) {
- as->cfg.loadshare.tcap.last_asp_idx_sent = i;
- return asp;
- }
- i = (i + 1) % ARRAY_SIZE(as->cfg.asps);
- } while (i != first_idx);
-
+ for (unsigned int i = 0; i < as->num_asps; i++) {
+ assoc = ss7_as_asp_assoc_llist_round_robin(as,
&as->cfg.loadshare.tcap.last_asp_idx_sent);
+ if (assoc && osmo_ss7_asp_active(assoc->asp) &&
assoc->asp->tcap.enabled)
+ return assoc->asp;
+ }
return NULL;
}
@@ -923,6 +915,8 @@
if (!asp->tcap.enabled)
return;
+ /* Update round robin state */
+ ss7_as_del_asp_update_llist_round_robin(as, asp,
&as->cfg.loadshare.tcap.last_asp_idx_sent);
_tcap_range_asp_down(as, asp);
if (as->tcap.contains_pc || as->tcap.contains_ssn)
tcap_range_as_update_pc_ssn(as);
@@ -945,6 +939,7 @@
as->cfg.loadshare.tcap.enabled = false;
as->tcap.contains_pc = false;
as->tcap.contains_ssn = false;
+ as->cfg.loadshare.tcap.last_asp_idx_sent = NULL;
tcap_trans_track_garbage_collect_stop(as);
tcap_trans_track_entries_free_all(as);
}
diff --git a/src/xua_as_fsm.c b/src/xua_as_fsm.c
index 53e2c00..0dbb481 100644
--- a/src/xua_as_fsm.c
+++ b/src/xua_as_fsm.c
@@ -103,8 +103,9 @@
static int as_notify_all_asp(struct osmo_ss7_as *as, struct
osmo_xlm_prim_notify *npar)
{
struct msgb *msg;
- unsigned int i, sent = 0;
+ unsigned int sent = 0;
const char *type_name, *info_name, *info_str;
+ struct ss7_as_asp_assoc *assoc;
/* we don't send notify to IPA peers! */
if (as->cfg.proto == OSMO_SS7_ASP_PROT_IPA)
@@ -117,11 +118,8 @@
type_name, info_name, info_str);
/* iterate over all non-DOWN ASPs and send them the message */
- for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) {
- struct osmo_ss7_asp *asp = as->cfg.asps[i];
-
- if (!asp)
- continue;
+ llist_for_each_entry(assoc, &as->asp_list, as_entry) {
+ struct osmo_ss7_asp *asp = assoc->asp;
/* NOTIFY are only sent by SG or IPSP role */
if (asp->cfg.role == OSMO_SS7_ASP_ROLE_ASP)
@@ -165,7 +163,7 @@
int xua_as_transmit_msg_broadcast(struct osmo_ss7_as *as, struct xua_msg *xua)
{
struct osmo_ss7_asp *asp;
- unsigned int i;
+ struct ss7_as_asp_assoc *assoc;
struct msgb *msg;
struct msgb *msg_cpy;
bool sent = false;
@@ -173,9 +171,9 @@
msg = xua_as_encode_msg(as, xua);
OSMO_ASSERT(msg);
- for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) {
- asp = as->cfg.asps[i];
- if (!asp || !osmo_ss7_asp_active(asp))
+ llist_for_each_entry(assoc, &as->asp_list, as_entry) {
+ asp = assoc->asp;
+ if (!osmo_ss7_asp_active(asp))
continue;
msg_cpy = msgb_copy(msg, "xua_bcast_cpy");
if (osmo_ss7_asp_send(asp, msg_cpy) == 0)
@@ -273,13 +271,10 @@
/* is any other ASP in this AS in state != DOWN? */
static bool check_any_other_asp_not_down(struct osmo_ss7_as *as, struct
osmo_ss7_asp *asp_cmp)
{
- unsigned int i;
+ struct ss7_as_asp_assoc *assoc;
- for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) {
- struct osmo_ss7_asp *asp = as->cfg.asps[i];
- if (!asp)
- continue;
-
+ llist_for_each_entry(assoc, &as->asp_list, as_entry) {
+ struct osmo_ss7_asp *asp = assoc->asp;
if (asp_cmp == asp)
continue;
@@ -293,13 +288,10 @@
/* is any other ASP in this AS in state ACTIVE? */
static bool check_any_other_asp_in_active(struct osmo_ss7_as *as, struct
osmo_ss7_asp *asp_cmp)
{
- unsigned int i;
+ struct ss7_as_asp_assoc *assoc;
- for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) {
- struct osmo_ss7_asp *asp = as->cfg.asps[i];
- if (!asp)
- continue;
-
+ llist_for_each_entry(assoc, &as->asp_list, as_entry) {
+ struct osmo_ss7_asp *asp = assoc->asp;
if (asp_cmp == asp)
continue;
@@ -316,7 +308,7 @@
* */
static void notify_any_other_active_asp_as_inactive(struct osmo_ss7_as *as,
struct osmo_ss7_asp *asp_cmp)
{
- unsigned int i;
+ struct ss7_as_asp_assoc *assoc;
struct msgb *msg;
struct osmo_xlm_prim_notify npar = {
.status_type = M3UA_NOTIFY_T_OTHER,
@@ -326,9 +318,9 @@
if (asp_cmp->remote_asp_id_present)
npar.asp_id = asp_cmp->remote_asp_id;
- for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) {
- struct osmo_ss7_asp *asp = as->cfg.asps[i];
- if (!asp || !osmo_ss7_asp_active(asp))
+ llist_for_each_entry(assoc, &as->asp_list, as_entry) {
+ struct osmo_ss7_asp *asp = assoc->asp;
+ if (!osmo_ss7_asp_active(asp))
continue;
if (asp_cmp == asp)
diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c
index 5ae0d0f..ea5f64c 100644
--- a/src/xua_asp_fsm.c
+++ b/src/xua_asp_fsm.c
@@ -1355,14 +1355,14 @@
{
for (unsigned int sls = 0; sls <= 0x0f; sls++) {
bool used = false;
- for (unsigned i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) {
- if (!as->cfg.asps[i])
+ struct ss7_as_asp_assoc *assoc;
+ llist_for_each_entry(assoc, &as->asp_list, as_entry) {
+ struct osmo_ss7_asp *asp_it = assoc->asp;
+ if (asp_it == asp)
continue;
- if (as->cfg.asps[i] == asp)
+ if (!asp_it->ipa.sls_assigned)
continue;
- if (!as->cfg.asps[i]->ipa.sls_assigned)
- continue;
- if (as->cfg.asps[i]->ipa.sls == sls) {
+ if (asp_it->ipa.sls == sls) {
used = true;
break;
}
diff --git a/src/xua_default_lm_fsm.c b/src/xua_default_lm_fsm.c
index fb9ac1e..07c00fd 100644
--- a/src/xua_default_lm_fsm.c
+++ b/src/xua_default_lm_fsm.c
@@ -160,9 +160,9 @@
struct osmo_ss7_as *as;
llist_for_each_entry(as, &asp->inst->as_list, list) {
- unsigned int i;
- for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) {
- if (as->cfg.asps[i] == asp)
+ struct ss7_as_asp_assoc *assoc;
+ llist_for_each_entry(assoc, &as->asp_list, as_entry) {
+ if (assoc->asp == asp)
return as;
}
}
--
To view, visit https://gerrit.osmocom.org/c/libosmo-sigtran/+/42105?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: libosmo-sigtran
Gerrit-Branch: master
Gerrit-Change-Id: I149ab467899633ac50cba3e482b2cae02124279d
Gerrit-Change-Number: 42105
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <[email protected]>