pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmo-sigtran/+/40564?usp=email )
Change subject: Send DUNA during ASP ACT time
......................................................................
Send DUNA during ASP ACT time
As explained in RFC 4666 4.5.1, this helps ASPs figuring quickly
figuring out that some destinations may not be available.
Change-Id: Id9d92c3fda7423a9c79fffac6b650abba9651853
---
M src/xua_as_fsm.c
M src/xua_internal.h
M src/xua_snm.c
3 files changed, 52 insertions(+), 3 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmo-sigtran refs/changes/64/40564/1
diff --git a/src/xua_as_fsm.c b/src/xua_as_fsm.c
index 8e4282c..619142a 100644
--- a/src/xua_as_fsm.c
+++ b/src/xua_as_fsm.c
@@ -12,6 +12,7 @@
#include <arpa/inet.h>
#include <osmocom/core/fsm.h>
+#include <osmocom/core/linuxlist.h>
#include <osmocom/core/utils.h>
#include <osmocom/core/timer.h>
#include <osmocom/core/prim.h>
@@ -64,6 +65,41 @@
osmo_ss7_asp_send(asp, msg);
}
+/* RFC 4666 4.5.1: "For the particular case that an ASP becomes active for an AS and
+ * destinations normally accessible to the AS are inaccessible, restricted, or congested,
+ * the SG MAY send DUNA, DRST, or SCON messages for the inaccessible, restricted, or
+ * congested destinations to the ASP newly active for the AS to prevent the ASP from
+ * sending traffic for destinations that it might not otherwise know that are inaccessible,
+ * restricted, or congested" */
+static void as_tx_duna_during_asp_act(struct osmo_ss7_as *as, struct osmo_ss7_asp *asp)
+{
+ struct osmo_ss7_instance *inst = as->inst;
+ struct osmo_ss7_route_table *rtbl = inst->rtable_system;
+ struct osmo_ss7_as *as_it;
+ uint32_t aff_pc[32];
+ unsigned int num_aff_pc = 0;
+ uint32_t rctx_be = htonl(as->cfg.routing_key.context);
+
+ /* Send up to 32 PC per DUNA: */
+ llist_for_each_entry(as_it, &inst->as_list, list) {
+ if (as == as_it)
+ continue;
+ if (ss7_route_table_dpc_is_accessible_skip_as(rtbl, as_it->cfg.routing_key.pc, as))
+ continue;
+ aff_pc[num_aff_pc++] = htonl(as_it->cfg.routing_key.pc); /* mask = 0 */
+ if (num_aff_pc == ARRAY_SIZE(aff_pc)) {
+ xua_tx_snm_available(asp, &rctx_be, 1,
+ aff_pc, num_aff_pc,
+ "RFC4666 4.5.1", false);
+ num_aff_pc = 0;
+ }
+ }
+ if (num_aff_pc > 0)
+ xua_tx_snm_available(asp, &rctx_be, 1,
+ aff_pc, num_aff_pc,
+ "RFC4666 4.5.1", false);
+}
+
static int as_notify_all_asp(struct osmo_ss7_as *as, struct osmo_xlm_prim_notify *npar)
{
struct msgb *msg;
@@ -622,8 +658,11 @@
osmo_fsm_inst_state_chg(fi, XUA_AS_S_DOWN, 0, 0);
break;
case XUA_ASPAS_ASP_ACTIVE_IND:
+ asp = data;
/* one ASP transitions into ASP-ACTIVE */
osmo_fsm_inst_state_chg(fi, XUA_AS_S_ACTIVE, 0, 0);
+ if (asp->cfg.role == OSMO_SS7_ASP_ROLE_SG)
+ as_tx_duna_during_asp_act(xafp->as, asp);
break;
case XUA_ASPAS_ASP_INACTIVE_IND:
inact_ind_pars = data;
@@ -666,6 +705,9 @@
/* RFC466 sec 4.3.4.3 ASP Active Procedures*/
if (xafp->as->cfg.mode == OSMO_SS7_AS_TMOD_OVERRIDE)
notify_any_other_active_asp_as_inactive(xafp->as, asp);
+ /* SG role: No need to send DUNA for unknown destinations here
+ * (see as_tx_duna_during_asp_act()), since the AS was already
+ * active so the peer should know current status. */
break;
case XUA_AS_E_TRANSFER_REQ:
/* message for transmission */
@@ -694,6 +736,9 @@
llist_del(&xua->entry);
xua_as_transmit_msg(xafp->as, xua);
}
+ /* SG role: No need to send DUNA for unknown destinations here
+ * (see as_tx_duna_during_asp_act()), since the AS was already
+ * active so the peer should know current status. */
break;
case XUA_ASPAS_ASP_INACTIVE_IND:
inact_ind_pars = data;
diff --git a/src/xua_internal.h b/src/xua_internal.h
index 576708f..b0bc98c 100644
--- a/src/xua_internal.h
+++ b/src/xua_internal.h
@@ -45,6 +45,10 @@
void m3ua_tx_dupu(struct osmo_ss7_asp *asp, const uint32_t *rctx, unsigned int num_rctx,
uint32_t dpc, uint16_t user, uint16_t cause, const char *info_str);
+void xua_tx_snm_available(struct osmo_ss7_asp *asp, const uint32_t *rctx, unsigned int num_rctx,
+ const uint32_t *aff_pc, unsigned int num_aff_pc,
+ const char *info_str, bool available);
+
void xua_snm_rx_daud(struct osmo_ss7_asp *asp, struct xua_msg *xua);
void xua_snm_rx_duna(struct osmo_ss7_asp *asp, struct osmo_ss7_as *as, struct xua_msg *xua);
void xua_snm_rx_dava(struct osmo_ss7_asp *asp, struct osmo_ss7_as *as, struct xua_msg *xua);
diff --git a/src/xua_snm.c b/src/xua_snm.c
index 207b042..6bbeec7 100644
--- a/src/xua_snm.c
+++ b/src/xua_snm.c
@@ -67,9 +67,9 @@
return out;
}
-static void xua_tx_snm_available(struct osmo_ss7_asp *asp, const uint32_t *rctx, unsigned int num_rctx,
- const uint32_t *aff_pc, unsigned int num_aff_pc,
- const char *info_str, bool available)
+void xua_tx_snm_available(struct osmo_ss7_asp *asp, const uint32_t *rctx, unsigned int num_rctx,
+ const uint32_t *aff_pc, unsigned int num_aff_pc,
+ const char *info_str, bool available)
{
switch (asp->cfg.proto) {
case OSMO_SS7_ASP_PROT_M3UA:
--
To view, visit https://gerrit.osmocom.org/c/libosmo-sigtran/+/40564?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: Id9d92c3fda7423a9c79fffac6b650abba9651853
Gerrit-Change-Number: 40564
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin(a)sysmocom.de>
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>