laforge submitted this change.
TCAP: implement fallback routing when no TCAP ASP can be found.
If a TCAP message from an ongoing session can't be routed by
either the TCAP session cache or by the destination TID to a known
ASP, allow to route the packet to a different destination.
Change-Id: I3e4e634b38a1845c2ce62a3805ff91a530520d88
---
M src/ss7_as.c
M src/ss7_as.h
M src/ss7_as_vty.c
M src/tcap_as_loadshare.c
M tests/vty/osmo_stp_test_tcap.vty
5 files changed, 78 insertions(+), 12 deletions(-)
diff --git a/src/ss7_as.c b/src/ss7_as.c
index 064ea4f..fe236cf 100644
--- a/src/ss7_as.c
+++ b/src/ss7_as.c
@@ -94,8 +94,9 @@
};
struct value_string osmo_ss7_as_tcap_unroutable_vals[] = {
- { SS7_AS_TCAP_UNROUTABLE_REJECT_UDTS, "reject-udts" },
- { SS7_AS_TCAP_UNROUTABLE_LOAD_SHARE_AS, "load-share-over-as" },
+ { SS7_AS_TCAP_UNROUTABLE_REJECT_UDTS, "reject-udts" },
+ { SS7_AS_TCAP_UNROUTABLE_LOAD_SHARE_AS, "load-share-over-as" },
+ { SS7_AS_TCAP_UNROUTABLE_ROUTE_FALLBACK, "route-fallback" },
{ 0, NULL }
};
diff --git a/src/ss7_as.h b/src/ss7_as.h
index 7d873b8..3d36102 100644
--- a/src/ss7_as.h
+++ b/src/ss7_as.h
@@ -75,11 +75,12 @@
#endif /* WITH_TCAP_LOADSHARING */
};
-/* when receiving an TCAP Continue/End/Abort which can't be assosiated to a node (either by sesssion tracking or by DTID over TCAP ranges,
+/* when receiving an TCAP Continue/End/Abort which can't be associated to a node (either by sesssion tracking or by DTID over TCAP ranges,
* how to handle those */
enum ss7_as_tcap_unroutable {
SS7_AS_TCAP_UNROUTABLE_REJECT_UDTS, /*! reject the unroutable TCAP message with a UDTS */
SS7_AS_TCAP_UNROUTABLE_LOAD_SHARE_AS, /*! fallback to round robin load-share over all available ASP */
+ SS7_AS_TCAP_UNROUTABLE_ROUTE_FALLBACK, /*! route to a different destination */
};
extern struct value_string osmo_ss7_as_tcap_unroutable_vals[];
@@ -181,6 +182,8 @@
bool enabled;
unsigned int timeout_s;
enum ss7_as_tcap_unroutable unroutable_tcap_msg;
+ /* when unroutable_tcap_msg == SS7_AS_TCPA_UNROUTABLE_ROUTE_FALLBACK, replace DPC with this */
+ uint32_t unroutable_tcap_fallback_dpc;
} tcap;
#endif /* WITH_TCAP_LOADSHARING */
} loadshare;
diff --git a/src/ss7_as_vty.c b/src/ss7_as_vty.c
index 0370f2f..4d7d460 100644
--- a/src/ss7_as_vty.c
+++ b/src/ss7_as_vty.c
@@ -249,9 +249,10 @@
DEFUN_USRATTR(as_tcap_unroutable_sessions, as_tcap_unroutable_sessions_cmd,
OSMO_SCCP_LIB_ATTR_RSTRT_ASP,
"tcap-unroutable-sessions (reject-udts | load-share-over-as)",
- "When receiving a TCAP Continue/End/Abort message where no ASP can be assosiated (either via session tracking or by TCAP range for dtid). How should this message handled.\n"
+ "When receiving a TCAP Continue/End/Abort message where no ASP can be associated (either via session tracking or by TCAP range for dtid). How should this message be handled.\n"
"Reject the message with a UDTS\n"
- "Fallback to load-share over AS by using all available AS (round robin)\n")
+ "Fallback to load-share over AS by using all available AS (round robin)\n"
+ "Route to a different M3UA PC\n")
{
struct osmo_ss7_as *as = vty->index;
int value = get_string_value(osmo_ss7_as_tcap_unroutable_vals, argv[0]);
@@ -261,6 +262,25 @@
as->cfg.loadshare.tcap.unroutable_tcap_msg = value;
return CMD_SUCCESS;
}
+
+DEFUN_USRATTR(as_tcap_unroutable_sessions_fallback, as_tcap_unroutable_sessions_fallback_cmd,
+ OSMO_SCCP_LIB_ATTR_RSTRT_ASP,
+ "tcap-unroutable-sessions route-fallback DPC",
+ "When receiving a TCAP Continue/End/Abort message where no ASP can be associated (either via session tracking or by TCAP range for dtid). How should this message be handled.\n"
+ "Route to a different M3UA PC\n"
+ "Destination Point Code\n")
+{
+ struct osmo_ss7_as *as = vty->index;
+ int pc = osmo_ss7_pointcode_parse(as->inst, argv[0]);
+ if (pc < 0) {
+ vty_out(vty, "Invalid point code (%s)%s", argv[0], VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ as->cfg.loadshare.tcap.unroutable_tcap_msg = SS7_AS_TCAP_UNROUTABLE_ROUTE_FALLBACK;
+ as->cfg.loadshare.tcap.unroutable_tcap_fallback_dpc = pc;
+ return CMD_SUCCESS;
+}
#endif /* WITH_TCAP_LOADSHARING */
DEFUN_ATTR(as_bindingtable_reset, as_bindingtable_reset_cmd,
@@ -524,12 +544,23 @@
if (as->cfg.loadshare.tcap.enabled)
vty_out(vty, " tcap-routing%s", VTY_NEWLINE);
- if (as->cfg.loadshare.tcap.unroutable_tcap_msg != SS7_AS_TCAP_UNROUTABLE_REJECT_UDTS) {
- const char *str = get_value_string_or_null(osmo_ss7_as_tcap_unroutable_vals,
- as->cfg.loadshare.tcap.unroutable_tcap_msg);
- if (str)
- vty_out(vty, " tcap-unroutable-sessions %s%s", str, VTY_NEWLINE);
+ const char *tcap_unroutable_str = get_value_string_or_null(osmo_ss7_as_tcap_unroutable_vals,
+ as->cfg.loadshare.tcap.unroutable_tcap_msg);
+ switch (as->cfg.loadshare.tcap.unroutable_tcap_msg) {
+ case SS7_AS_TCAP_UNROUTABLE_REJECT_UDTS:
+ /* default value, no need to write it out */
+ break;
+ case SS7_AS_TCAP_UNROUTABLE_ROUTE_FALLBACK:
+ vty_out(vty, " tcap-route-fallback %s%s%s", tcap_unroutable_str,
+ osmo_ss7_pointcode_print(as->inst, as->cfg.loadshare.tcap.unroutable_tcap_fallback_dpc),
+ VTY_NEWLINE);
+ break;
+ case SS7_AS_TCAP_UNROUTABLE_LOAD_SHARE_AS:
+ vty_out(vty, " tcap-route-fallback %s%s", tcap_unroutable_str, VTY_NEWLINE);
+ default:
+ break;
}
+
#endif /* WITH_TCAP_LOADSHARING */
if (as->cfg.recovery_timeout_msec != 2000) {
@@ -738,6 +769,7 @@
install_lib_element(L_CS7_AS_NODE, &as_tcap_routing_cmd);
install_lib_element(L_CS7_AS_NODE, &as_no_tcap_routing_cmd);
install_lib_element(L_CS7_AS_NODE, &as_tcap_unroutable_sessions_cmd);
+ install_lib_element(L_CS7_AS_NODE, &as_tcap_unroutable_sessions_fallback_cmd);
}
#endif /* WITH_TCAP_LOADSHARING */
install_lib_element(L_CS7_AS_NODE, &as_bindingtable_reset_cmd);
diff --git a/src/tcap_as_loadshare.c b/src/tcap_as_loadshare.c
index a24d56e..8cc32d6 100644
--- a/src/tcap_as_loadshare.c
+++ b/src/tcap_as_loadshare.c
@@ -454,6 +454,30 @@
return rc;
}
+/*! When a TCAP message can't be routed by TID or session cache and
+ * unroutable_tcap_msg == SS7_AS_TCPA_UNROUTABLE_ROUTE_FALLBACK, route to a different DPC.
+ *
+ * \param[in] as
+ * \param[in] mtp MTP routing information
+ * \param[in] sccp_msg the SCCP message.
+ * \return 0 on success or -ENOKEY
+ */
+static int asp_loadshare_tcap_route_fallback(struct osmo_ss7_as *as,
+ const struct osmo_mtp_transfer_param *orig_mtp,
+ const struct msgb *sccp_msg)
+{
+ struct osmo_mtp_transfer_param new_mtp = *orig_mtp;
+ int rc = 0;
+ new_mtp.dpc = as->cfg.loadshare.tcap.unroutable_tcap_fallback_dpc;
+
+ /* l2 contains the sccp message */
+ rc = mtp3_hmrt_mtp_xfer_request_l4_to_l3(as->inst, &new_mtp, msgb_l2(sccp_msg), msgb_l2len(sccp_msg));
+ if (!rc)
+ return -ENOKEY;
+
+ return 0;
+}
+
/*! When a TCAP MSU from an ongoing session (TCAP != Begin) could not be routed either by the TCAP session tracking or
* by the TID range, such messages will be passed to this function.
*
@@ -461,7 +485,7 @@
* \param[in] as the AS to which this MSU was routed to
* \param[in] mtp
* \param[in] sccp_msg
- * \return 0 on success
+ * \return 0 on success and asp is set, < 0 on error, > 0 when message is routed elsewhere
*/
static int asp_loadshare_tcap_handle_unroutable(struct osmo_ss7_asp **rasp,
struct osmo_ss7_as *as,
@@ -479,6 +503,12 @@
if (asp)
rc = 0;
break;
+ case SS7_AS_TCAP_UNROUTABLE_ROUTE_FALLBACK:
+ /* No ASP selection. Try to route the SCCP msg to the fallback DPC */
+ rc = asp_loadshare_tcap_route_fallback(as, mtp, sccp_msg);
+ if (!rc) /* rc == 0 would require a valid asp, use > 0 to drop the msg, but don't send an error back if needed */
+ rc = 1;
+ break;
case SS7_AS_TCAP_UNROUTABLE_REJECT_UDTS:
default:
/* default case, asp stays NULL, will reject when returning -ENOKEY */
diff --git a/tests/vty/osmo_stp_test_tcap.vty b/tests/vty/osmo_stp_test_tcap.vty
index 7ffff77..d32c237 100644
--- a/tests/vty/osmo_stp_test_tcap.vty
+++ b/tests/vty/osmo_stp_test_tcap.vty
@@ -34,7 +34,7 @@
traffic-mode Specifies traffic mode of operation of the ASP within the AS
sls-shift Shift SLS bits used during routing decision
tcap-routing Enable TCAP-based routing when in traffic-mode loadshare
- tcap-unroutable-sessions When receiving a TCAP Continue/End/Abort message where no ASP can be assosiated (either via session tracking or by TCAP range for dtid). How should this message handled.
+ tcap-unroutable-sessions When receiving a TCAP Continue/End/Abort message where no ASP can be associated (either via session tracking or by TCAP range for dtid). How should this message be handled.
binding-table AS Loadshare binding table operations
recovery-timeout Specifies RFC4666 recovery timer T(r) timeout
qos-class Specity QoS Class of AS
To view, visit change 43008. To unsubscribe, or for help writing mail filters, visit settings.