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 <pes...@sysmocom.de>