pespin has uploaded this change for review.

View Change

WIP: Tx DAUD when ASP becomes activated

Otherwise the local Signalling Point has no way to know whether the
remote Signalling Points it wants to talk to are actually already
connected to the STP when it becomes active after the process starts up.
This pocedure is documented both for M3UA and SUA:
* RFC4666 4.6, RFC3868 4.6
* RFC4666 4.5.3, RFC3868 4.5.3 "ASP Auditing"
* RFC4666 5.5.1.1.3 "Support for ASP Querying of SS7 Destination States"

The M3UA specs (RFC4666 5.5.1.1.3) explicitly state that the point codes to audit are not
to be provided by uppers layers, so picking the ones from the locally
configured address book for now:
"""
Note: there is no primitive for the
MTP3-User to request this audit from the M3UA layer, as this is
initiated by an internal M3UA management function.
"""

Related: OS#5917
Related: SYS#7501
Change-Id: I7c8c5099d4d00ea6f4a8db59ed6b833fb0ffa43d
---
M src/m3ua.c
M src/sua.c
M src/xua_asp_fsm.c
M src/xua_internal.h
M src/xua_snm.c
5 files changed, 110 insertions(+), 4 deletions(-)

git pull ssh://gerrit.osmocom.org:29418/libosmo-sigtran refs/changes/01/40501/1
diff --git a/src/m3ua.c b/src/m3ua.c
index f073c8e..b3b0797 100644
--- a/src/m3ua.c
+++ b/src/m3ua.c
@@ -883,7 +883,6 @@
return xua;
}

-#if 0 /* not used so far */
/* 3.4.3 Destination Available (DAUD) */
static struct xua_msg *m3ua_encode_daud(const uint32_t *rctx, unsigned int num_rctx,
const uint32_t *aff_pc, unsigned int num_aff_pc,
@@ -895,7 +894,6 @@
xua->hdr.msg_type = M3UA_SNM_DAUD;
return xua;
}
-#endif

/* 3.4.5 Destination User Part Unavailable (DUPU) */
static struct xua_msg *m3ua_encode_dupu(const uint32_t *rctx, unsigned int num_rctx,
@@ -976,6 +974,22 @@
m3ua_tx_xua_asp(asp, xua);
}

+/*! Transmit SSNM DAUD message requesting [un]availability status of certain point code[s]
+ * \param[in] asp ASP through which to transmit message. Must be ACTIVE.
+ * \param[in] rctx array of Routing Contexts in network byte order.
+ * \param[in] num_rctx number of rctx
+ * \param[in] aff_pc array of 'Affected Point Code' in network byte order.
+ * \param[in] num_aff_pc number of aff_pc
+ * \param[in] info_string optional information string (can be NULL).
+ */
+void m3ua_tx_snm_daud(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_string)
+{
+ /* encoding is exactly identical to DUNA */
+ struct xua_msg *xua = m3ua_encode_daud(rctx, num_rctx, aff_pc, num_aff_pc, info_string);
+ m3ua_tx_xua_asp(asp, xua);
+}
+
/*! Transmit SSNM DUPU message indicating user unavailability.
* \param[in] asp ASP through which to transmit message. Must be ACTIVE.
* \param[in] rctx array of Routing Contexts in network byte order.
diff --git a/src/sua.c b/src/sua.c
index 7d14f3b..9d3e3f1 100644
--- a/src/sua.c
+++ b/src/sua.c
@@ -825,7 +825,6 @@
return xua;
}

-#if 0 /* not used so far */
/* 3.4.3 Destination Available (DAUD) */
static struct xua_msg *sua_encode_daud(const uint32_t *rctx, unsigned int num_rctx,
const uint32_t *aff_pc, unsigned int num_aff_pc,
@@ -837,7 +836,6 @@
xua->hdr.msg_type = SUA_SNM_DAUD;
return xua;
}
-#endif

/* 3.4.5 Destination User Part Unavailable (DUPU) */
static struct xua_msg *sua_encode_dupu(const uint32_t *rctx, unsigned int num_rctx,
@@ -914,6 +912,23 @@
xua_msg_add_data(xua, SUA_IEI_INFO_STRING, strlen(info_string)+1, (const uint8_t *) info_string);
}

+/*! Transmit SSNM DAUD message requesting [un]availability status of certain point code[s]
+ * \param[in] asp ASP through which to transmit message. Must be ACTIVE.
+ * \param[in] rctx array of Routing Contexts in network byte order.
+ * \param[in] num_rctx number of rctx
+ * \param[in] aff_pc array of 'Affected Point Code' in network byte order.
+ * \param[in] num_aff_pc number of aff_pc
+ * \param[in] aff_ssn affected SSN (optional)
+ * \param[in] smi subsystem multiplicity indicator (optional)
+ * \param[in] info_string optional information strng (can be NULL).
+ */
+void sua_tx_snm_daud(struct osmo_ss7_asp *asp, const uint32_t *rctx, unsigned int num_rctx,
+ const uint32_t *aff_pc, unsigned int num_aff_pc, const uint32_t *aff_ssn,
+ const uint32_t *smi, const char *info_string)
+{
+ struct xua_msg *xua = sua_encode_daud(rctx, num_rctx, aff_pc, num_aff_pc, aff_ssn, smi, info_string);
+ sua_tx_xua_asp(asp, xua);
+}

/*! Transmit SSNM DUPU message indicating user unavailability.
* \param[in] asp ASP through which to transmit message. Must be ACTIVE.
diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c
index 26f3a78..96bceb8 100644
--- a/src/xua_asp_fsm.c
+++ b/src/xua_asp_fsm.c
@@ -31,6 +31,7 @@
#include "ss7_asp.h"
#include "ss7_internal.h"
#include "ss7_xua_srv.h"
+#include "sccp_internal.h"
#include "xua_asp_fsm.h"
#include "xua_as_fsm.h"
#include "xua_internal.h"
@@ -146,6 +147,47 @@
xua_asp_send_xlm_prim_simple(asp, prim_type, op);
}

+static void xua_asp_tx_snm_daud_address_book(struct osmo_ss7_asp *asp)
+{
+ struct osmo_ss7_instance *inst = asp->inst;
+ uint32_t rctx[OSMO_SS7_MAX_RCTX_COUNT];
+ unsigned int num_rctx;
+ uint32_t *aff_pc = NULL;
+ unsigned int num_aff_pc = 0;
+ struct osmo_sccp_addr_entry *entry;
+
+ num_rctx = ss7_asp_get_all_rctx_be(asp, rctx, ARRAY_SIZE(rctx), NULL);
+
+ llist_for_each_entry(entry, &inst->cfg.sccp_address_book, list) {
+ if (entry->addr.presence & OSMO_SCCP_ADDR_T_PC)
+ num_aff_pc++;
+ }
+ if (num_aff_pc == 0) {
+ LOGPASP(asp, DLSS7, LOGL_ERROR, "Tx DAUD: No SCCP in address book! skip\n");
+ return;
+ }
+ aff_pc = talloc_size(asp, sizeof(*aff_pc) * num_aff_pc);
+ OSMO_ASSERT(aff_pc);
+ num_aff_pc = 0;
+ llist_for_each_entry(entry, &inst->cfg.sccp_address_book, list) {
+ uint32_t curr_aff_pc;
+ unsigned int i;
+ if (!(entry->addr.presence & OSMO_SCCP_ADDR_T_PC))
+ continue;
+ LOGPASP(asp, DLSS7, LOGL_DEBUG, "Tx DAUD: Requesting status of DPC=%u=%s\n",
+ entry->addr.pc, osmo_ss7_pointcode_print2(inst, entry->addr.pc));
+ curr_aff_pc = htonl(entry->addr.pc); /* mask = 0 */
+ for (i = 0; i < num_aff_pc; i++)
+ if (aff_pc[i] == curr_aff_pc)
+ break;
+ if (i == num_aff_pc) /* not found in array */
+ aff_pc[num_aff_pc++] = curr_aff_pc;
+ }
+
+ xua_tx_snm_daud(asp, rctx, num_rctx, aff_pc, num_aff_pc, "ASP_ACTIVATE_DAUD");
+ talloc_free(aff_pc);
+}
+
/* determine the osmo_ss7_as_traffic_mode to be used by this ASP; will
* iterate over all AS configured for this ASP. If they're compatible,
* a single traffic mode is returned as enum osmo_ss7_as_traffic_mode.
@@ -702,6 +744,18 @@
xua_t_beat_send(fi);
}

+ if (asp->cfg.role == OSMO_SS7_ASP_ROLE_ASP) {
+ /* RFC4666 4.6, RFC3868 4.6: "The ASP MAY choose to audit the availability
+ * of unavailable destinations by sending DAUD messages.
+ * This would be the case when, for example, an AS becomes active at an ASP
+ * and does not have current destination statuses."
+ * See also RFC4666 4.5.3, RFC3868 4.5.3 "ASP Auditing".
+ * See also RFC4666 5.5.1.1.3 "Support for ASP Querying of SS7 Destination States"
+ */
+ LOGPFSML(fi, LOGL_NOTICE, "Tx DAUD\n");
+ xua_asp_tx_snm_daud_address_book(asp);
+ }
+
dispatch_to_all_as(fi, XUA_ASPAS_ASP_ACTIVE_IND, asp);
}

diff --git a/src/xua_internal.h b/src/xua_internal.h
index 576708f..58aed4a 100644
--- a/src/xua_internal.h
+++ b/src/xua_internal.h
@@ -28,6 +28,9 @@
void sua_tx_snm_congestion(struct osmo_ss7_asp *asp, const uint32_t *rctx, unsigned int num_rctx,
const uint32_t *aff_pc, unsigned int num_aff_pc, const uint32_t *ssn,
const uint8_t cong_level, const char *info_string);
+void sua_tx_snm_daud(struct osmo_ss7_asp *asp, const uint32_t *rctx, unsigned int num_rctx,
+ const uint32_t *aff_pc, unsigned int num_aff_pc, const uint32_t *aff_ssn,
+ const uint32_t *smi, const char *info_string);
void sua_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);

@@ -42,6 +45,8 @@
const uint32_t *aff_pc, unsigned int num_aff_pc,
const uint32_t *concerned_dpc, const uint8_t *cong_level,
const char *info_string);
+void m3ua_tx_snm_daud(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_string);
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);

@@ -91,6 +96,9 @@
void xua_snm_pc_available(struct osmo_ss7_as *as, const uint32_t *aff_pc,
unsigned int num_aff_pc, const char *info_str, bool available);

+void xua_tx_snm_daud(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);
+
enum ss7_asp_lm_timer {
/* 0 kept unused on purpose since it's handled specially by osmo_fsm */
SS7_ASP_LM_T_WAIT_ASP_UP = 1,
diff --git a/src/xua_snm.c b/src/xua_snm.c
index f3c8bb8..2d4b038 100644
--- a/src/xua_snm.c
+++ b/src/xua_snm.c
@@ -82,6 +82,21 @@
}
}

+void xua_tx_snm_daud(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)
+{
+ switch (asp->cfg.proto) {
+ case OSMO_SS7_ASP_PROT_M3UA:
+ m3ua_tx_snm_daud(asp, rctx, num_rctx, aff_pc, num_aff_pc, info_str);
+ break;
+ case OSMO_SS7_ASP_PROT_SUA:
+ sua_tx_snm_daud(asp, rctx, num_rctx, aff_pc, num_aff_pc, NULL, NULL, info_str);
+ break;
+ default:
+ break;
+ }
+}
+
static void xua_tx_upu(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)
{

To view, visit change 40501. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-MessageType: newchange
Gerrit-Project: libosmo-sigtran
Gerrit-Branch: master
Gerrit-Change-Id: I7c8c5099d4d00ea6f4a8db59ed6b833fb0ffa43d
Gerrit-Change-Number: 40501
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin@sysmocom.de>