laforge has submitted this change. ( https://gerrit.osmocom.org/c/libosmo-sigtran/+/43008?usp=email )
Change subject: TCAP: implement fallback routing when no TCAP ASP can be found. ......................................................................
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(-)
Approvals: pespin: Looks good to me, approved Jenkins Builder: Verified
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