pespin has uploaded this change for review. (
https://gerrit.osmocom.org/c/libosmo-sigtran/+/40558?usp=email )
Change subject: xua_snm: Add fully qualified dynamic routes to track announced PCs
......................................................................
xua_snm: Add fully qualified dynamic routes to track announced PCs
This allows building up a set of "concerned remote PCs" which can be
used to indicate (MTP-PAUSE/RESUME.ind, N-PCSTATE.ind) upper layers that
specific remote PCs went down eg. when a local AS becomes inactive (for
instance because the last ASP SCTP/TCP link goes down).
Change-Id: Icd72e7b15ea3f18c7d1a9a7c821d6d7f7ab11a96
---
M src/ss7_route_table.c
M src/ss7_route_table.h
M src/xua_snm.c
3 files changed, 63 insertions(+), 5 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmo-sigtran refs/changes/58/40558/1
diff --git a/src/ss7_route_table.c b/src/ss7_route_table.c
index f216cff..e59fd55 100644
--- a/src/ss7_route_table.c
+++ b/src/ss7_route_table.c
@@ -137,6 +137,41 @@
return NULL;
}
+/*! \brief Find a SS7 route for given destination point code + mask in given table via
given AS.
+ *
+ * This function is used for route management procedures, not for packet routing lookup
procedures!
+ */
+struct osmo_ss7_route *
+ss7_route_table_find_route_by_dpc_mask_as(struct osmo_ss7_route_table *rtbl, uint32_t
dpc,
+ uint32_t mask, const struct osmo_ss7_as *as, bool dynamic)
+{
+ struct osmo_ss7_combined_linkset *clset;
+ struct osmo_ss7_route *rt;
+
+ OSMO_ASSERT(ss7_initialized);
+
+ dpc = osmo_ss7_pc_normalize(&rtbl->inst->cfg.pc_fmt, dpc);
+ mask = osmo_ss7_pc_normalize(&rtbl->inst->cfg.pc_fmt, mask);
+
+ /* we assume the combined_links are sorted by mask length, i.e. more
+ * specific combined links first, and less specific combined links with shorter
+ * mask later */
+ llist_for_each_entry(clset, &rtbl->combined_linksets, list) {
+ if ((dpc & clset->cfg.mask) != clset->cfg.pc)
+ continue;
+ if (mask != clset->cfg.mask)
+ continue;
+ llist_for_each_entry(rt, &clset->routes, list) {
+ if (rt->dest.as != as)
+ continue;
+ if (rt->cfg.dyn_allocated != dynamic)
+ continue;
+ return rt;
+ }
+ }
+ return NULL;
+}
+
struct osmo_ss7_combined_linkset *
ss7_route_table_find_combined_linkset_by_dpc(struct osmo_ss7_route_table *rtbl, uint32_t
dpc)
{
diff --git a/src/ss7_route_table.h b/src/ss7_route_table.h
index 1155600..a128915 100644
--- a/src/ss7_route_table.h
+++ b/src/ss7_route_table.h
@@ -42,6 +42,9 @@
ss7_route_table_find_route_by_dpc_mask(struct osmo_ss7_route_table *rtbl, uint32_t dpc,
uint32_t mask, bool dynamic);
struct osmo_ss7_route *
+ss7_route_table_find_route_by_dpc_mask_as(struct osmo_ss7_route_table *rtbl, uint32_t
dpc,
+ uint32_t mask, const struct osmo_ss7_as *as, bool dynamic);
+struct osmo_ss7_route *
ss7_route_table_lookup_route(struct osmo_ss7_route_table *rtbl, const struct
osmo_ss7_route_label *rtlabel);
struct osmo_ss7_combined_linkset *
diff --git a/src/xua_snm.c b/src/xua_snm.c
index 42361c9..d4c9a75 100644
--- a/src/xua_snm.c
+++ b/src/xua_snm.c
@@ -154,16 +154,36 @@
/* RFC4666 1.4.2.5: "maintain a dynamic table of available SGP routes
* for the SS7 destinations, taking into account the SS7 destination
* availability/restricted/congestion status received from the SGP "*/
-static void xua_snm_srm_pc_available(struct osmo_ss7_as *as,
- const uint32_t *aff_pc, unsigned int num_aff_pc,
- bool available)
+static void xua_snm_srm_pc_available_single(struct osmo_ss7_as *as, uint32_t pc, bool
available)
{
struct osmo_ss7_instance *s7i = as->inst;
enum osmo_ss7_route_status new_status;
+ struct osmo_ss7_route *rt;
new_status = available ? OSMO_SS7_ROUTE_STATUS_AVAILABLE :
OSMO_SS7_ROUTE_STATUS_UNAVAILABLE;
+ /* Check if we already have a dynamic fully qualified route towards that AS: */
+ rt = ss7_route_table_find_route_by_dpc_mask_as(s7i->rtable_system, pc, 0xffffff, as,
true);
+ if (!rt) {
+ /* No dynamic fully qualified route found. Add dynamic fully
+ * squalified route and mark it as (un)available: */
+ rt = ss7_route_create(s7i->rtable_system, pc, 0xffffff, true, as->cfg.name);
+ if (!rt) {
+ LOGPAS(as, DLSS7, LOGL_ERROR, "Unable to create dynamic route for pc=%u=%s
status=%s\n",
+ pc, osmo_ss7_pointcode_print(s7i, pc), ss7_route_status_name(new_status));
+ return;
+ }
+ ss7_route_update_route_status(rt, new_status);
+ /* No need to iterate over rtable below, since we know there was no route: */
+ return;
+ }
+ ss7_route_table_update_route_status_by_as(s7i->rtable_system, new_status, as, pc);
+}
+static void xua_snm_srm_pc_available(struct osmo_ss7_as *as,
+ const uint32_t *aff_pc, unsigned int num_aff_pc,
+ bool available)
+{
for (unsigned int i = 0; i < num_aff_pc; i++) {
/* 32bit "Affected Point Code" consists of a 7-bit mask followed by
14/16/24-bit SS7 PC,
* see RFC 4666 3.4.1 */
@@ -172,13 +192,13 @@
uint8_t mask = _aff_pc >> 24;
if (!mask) {
- ss7_route_table_update_route_status_by_as(s7i->rtable_system, new_status, as, pc);
+ xua_snm_srm_pc_available_single(as, pc, available);
} else {
/* Update only full DPC routes. */
uint32_t maskbits = (1 << mask) - 1;
uint32_t fullpc;
for (fullpc = (pc & ~maskbits); fullpc <= (pc | maskbits); fullpc++)
- ss7_route_table_update_route_status_by_as(s7i->rtable_system, new_status, as,
fullpc);
+ xua_snm_srm_pc_available_single(as, fullpc, available);
}
}
}
--
To view, visit
https://gerrit.osmocom.org/c/libosmo-sigtran/+/40558?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: Icd72e7b15ea3f18c7d1a9a7c821d6d7f7ab11a96
Gerrit-Change-Number: 40558
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin(a)sysmocom.de>