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>

Reply via email to