pespin has uploaded this change for review. (
https://gerrit.osmocom.org/c/libosmo-sigtran/+/40563?usp=email )
Change subject: Indicate PC (un)availability from address-book when AS goes up/down
......................................................................
Indicate PC (un)availability from address-book when AS goes up/down
These are generally PCs the user wants to get information about, and
they may have no fully-qualified route because:
- user may not have configured such fully qualified route, but a
summary route (eg. 0.0.0/0 default route).
- peer SG may have not announced them (DAVA/DUNA)
Change-Id: I8b15b2ce46ced1be8fb6467cb3239337731b1090
---
M src/ss7_route_table.c
M src/ss7_route_table.h
M src/xua_as_fsm.c
3 files changed, 96 insertions(+), 0 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmo-sigtran refs/changes/63/40563/1
diff --git a/src/ss7_route_table.c b/src/ss7_route_table.c
index 16eb9bd..210d69c 100644
--- a/src/ss7_route_table.c
+++ b/src/ss7_route_table.c
@@ -341,3 +341,49 @@
}
return false;
}
+
+/* Figure out whether a remote PC is accessible over a route via a specific AS
+ * Note: Unlike ss7_route_table_lookup_route(), this function is read-only and
doesn't modify any state. */
+bool ss7_route_table_dpc_is_accessible_via_as(const struct osmo_ss7_route_table *rtbl,
uint32_t dpc, const struct osmo_ss7_as *as)
+{
+ struct osmo_ss7_combined_linkset *clset;
+ struct osmo_ss7_route *rt;
+ /* 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;
+ llist_for_each_entry(rt, &clset->routes, list) {
+ if (rt->dest.as != as)
+ continue;
+ if (!ss7_route_is_available(rt))
+ continue;
+ return true;
+ }
+ }
+ return false;
+}
+
+/* Figure out whether a remote PC is accessible over any route not going via a specific
excluded AS
+ * Note: Unlike ss7_route_table_lookup_route(), this function is read-only and
doesn't modify any state. */
+bool ss7_route_table_dpc_is_accessible_skip_as(const struct osmo_ss7_route_table *rtbl,
uint32_t dpc, const struct osmo_ss7_as *as)
+{
+ struct osmo_ss7_combined_linkset *clset;
+ struct osmo_ss7_route *rt;
+ /* 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;
+ llist_for_each_entry(rt, &clset->routes, list) {
+ if (rt->dest.as == as)
+ continue;
+ if (!ss7_route_is_available(rt))
+ continue;
+ return true;
+ }
+ }
+ return false;
+}
diff --git a/src/ss7_route_table.h b/src/ss7_route_table.h
index 582a8d3..98cddab 100644
--- a/src/ss7_route_table.h
+++ b/src/ss7_route_table.h
@@ -47,6 +47,8 @@
struct osmo_ss7_route *
ss7_route_table_lookup_route(const struct osmo_ss7_route_table *rtbl, const struct
osmo_ss7_route_label *rtlabel);
bool ss7_route_table_dpc_is_accessible(const struct osmo_ss7_route_table *rtbl, uint32_t
dpc);
+bool ss7_route_table_dpc_is_accessible_via_as(const struct osmo_ss7_route_table *rtbl,
uint32_t dpc, const struct osmo_ss7_as *as);
+bool ss7_route_table_dpc_is_accessible_skip_as(const struct osmo_ss7_route_table *rtbl,
uint32_t dpc, const struct osmo_ss7_as *as);
struct osmo_ss7_combined_linkset *
ss7_route_table_find_combined_linkset(const struct osmo_ss7_route_table *rtbl, uint32_t
dpc, uint32_t mask, uint32_t prio);
diff --git a/src/xua_as_fsm.c b/src/xua_as_fsm.c
index eb3ac49..8e4282c 100644
--- a/src/xua_as_fsm.c
+++ b/src/xua_as_fsm.c
@@ -24,6 +24,7 @@
#include <osmocom/sigtran/protocol/m3ua.h>
#include <sys/types.h>
+#include "sccp_internal.h"
#include "ss7_as.h"
#include "ss7_asp.h"
#include "ss7_combined_linkset.h"
@@ -451,6 +452,28 @@
xua_snm_pc_available(as, &aff_pc, 1, NULL, false);
}
}
+
+ /* Generate PC unavailability indications for PCs in the sccp address-book.
+ * These are generally PCs the user wants to get information about, and
+ * they may have no fully-qualified route because:
+ * - user may have not configured such fully qualified route, but a
+ * summary route (eg. 0.0.0/0 default route).
+ * - peer SG may have not announced them (DAVA/DUNA).
+ */
+ struct osmo_sccp_addr_entry *entry;
+ llist_for_each_entry(entry, &s7i->cfg.sccp_address_book, list) {
+ if (!(entry->addr.presence & OSMO_SCCP_ADDR_T_PC))
+ continue;
+ if (entry->addr.pc == s7i->cfg.primary_pc)
+ continue;
+ /* Still available: */
+ if (ss7_route_table_dpc_is_accessible_skip_as(rtbl, entry->addr.pc, as))
+ continue;
+ LOGPAS(as, DLSS7, LOGL_INFO, "AS became inactive => address-book pc=%u=%s is
now unavailable\n",
+ entry->addr.pc, osmo_ss7_pointcode_print(s7i, entry->addr.pc));
+ aff_pc = htonl(entry->addr.pc);
+ xua_snm_pc_available(as, &aff_pc, 1, NULL, true);
+ }
}
/* AS became active, trigger SNM PC availability for PCs it served: */
@@ -483,6 +506,31 @@
xua_snm_pc_available(as, &aff_pc, 1, NULL, true);
}
}
+
+ /* Generate PC availability indications for PCs in the sccp address-book.
+ * These are generally PCs the user wants to get information about, and
+ * they may have no fully-qualified route because:
+ * - user may have not configured such fully qualified route, but a
+ * summary route (eg. 0.0.0/0 default route).
+ * - peer SG may have not announced them (DAVA/DUNA).
+ */
+ struct osmo_sccp_addr_entry *entry;
+ llist_for_each_entry(entry, &s7i->cfg.sccp_address_book, list) {
+ if (!(entry->addr.presence & OSMO_SCCP_ADDR_T_PC))
+ continue;
+ if (entry->addr.pc == s7i->cfg.primary_pc)
+ continue;
+ /* PC was already available: */
+ if (ss7_route_table_dpc_is_accessible_skip_as(rtbl, entry->addr.pc, as))
+ continue;
+ /* Try to find if there's an available route via the AS matching this PC. */
+ if (!ss7_route_table_dpc_is_accessible_via_as(rtbl, entry->addr.pc, as))
+ continue;
+ LOGPAS(as, DLSS7, LOGL_INFO, "AS became active => address-book pc=%u=%s is now
available\n",
+ entry->addr.pc, osmo_ss7_pointcode_print(s7i, entry->addr.pc));
+ aff_pc = htonl(entry->addr.pc);
+ xua_snm_pc_available(as, &aff_pc, 1, NULL, true);
+ }
}
/* onenter call-back responsible of transmitting NTFY to all ASPs in
--
To view, visit
https://gerrit.osmocom.org/c/libosmo-sigtran/+/40563?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: I8b15b2ce46ced1be8fb6467cb3239337731b1090
Gerrit-Change-Number: 40563
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin(a)sysmocom.de>