lynxis lazus has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmo-sigtran/+/42760?usp=email )
Change subject: TCAP loadshare: allow to define the fallback mechanism for unroutable TCAP messages ......................................................................
TCAP loadshare: allow to define the fallback mechanism for unroutable TCAP messages
When a TCAP Continue/End/Abort message is received, but no TCAP session entry can be found and no valid TCAP range is available for the dtid, the message can be either:
- rejected by returning an error with UTDS - routed by round robin to all available ASP of this AS
To define the behaviour, a new vty option is introduced: ``` tcap-unroutable-sessions (reject-utds | load-share-over-as) ``` Defaults to reject-utds.
Related: SYS#5432 Change-Id: Ic1c876da30b05065a476d3a7c1bbf0680adf55bd --- 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, 70 insertions(+), 21 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmo-sigtran refs/changes/60/42760/1
diff --git a/src/ss7_as.c b/src/ss7_as.c index 8cddae9..b5f05fe 100644 --- a/src/ss7_as.c +++ b/src/ss7_as.c @@ -93,6 +93,12 @@ { 0, NULL } };
+struct value_string osmo_ss7_as_tcap_unroutable_vals[] = { + { SS7_AS_TCAP_UNROUTABLE_REJECT_UTDS, "reject-utds" }, + { SS7_AS_TCAP_UNROUTABLE_LOAD_SHARE_AS, "load-share-over-as" }, + { 0, NULL } +}; + #define SS7_AS_CTR_RX_MSU_SLS_STR "Number of MSU received on SLS " #define SS7_AS_CTR_TX_MSU_SLS_STR "Number of MSU transmitted on SLS " static const struct rate_ctr_desc ss7_as_rcd[] = { @@ -135,7 +141,7 @@ [SS7_AS_CTR_RX_TCAP_DECODED] = { "tcap:decoded", "Number of TCAP-messages decoded successfully (loadshare-tcap)" }, [SS7_AS_CTR_RX_TCAP_FAILED] = { "tcap:failed", "Number of TCAP-messages that failed decoding (loadshare-tcap)" }, [SS7_AS_CTR_TCAP_ASP_SELECTED] = { "tcap:asp:selected", "ASP selection successful for a TCAP-message (loadshare-tcap)" }, - [SS7_AS_CTR_TCAP_ASP_FALLBACK] = { "tcap:asp:fallback", "Fallback ASP selected for a TCAP-message (loadshare-tcap)" }, + [SS7_AS_CTR_TCAP_ASP_FALLBACK] = { "tcap:asp:fallback", "A non-starting TCAP message had to be routed by round-robin over all ASP. (loadshare-tcap)" }, [SS7_AS_CTR_TCAP_ASP_FAILED] = { "tcap:asp:failed", "ASP selection failed for a TCAP-message (loadshare-tcap)" }, [SS7_AS_CTR_TCAP_ASP_MISS] = { "tcap:session:miss", "A non-starting TCAP message (Continue, End, Abort) was missing a session entry, but routed successful. (loadshare-tcap)" }, #endif /* WITH_TCAP_LOADSHARING */ @@ -184,6 +190,7 @@
/* TODO: use Tdef */ as->cfg.loadshare.tcap.timeout_s = 30; + as->cfg.loadshare.tcap.unroutable_tcap_msg = SS7_AS_TCAP_UNROUTABLE_REJECT_UTDS; #endif /* WITH_TCAP_LOADSHARING */
as->fi = xua_as_fsm_start(as, LOGL_DEBUG); diff --git a/src/ss7_as.h b/src/ss7_as.h index e67ca1b..8293e0c 100644 --- a/src/ss7_as.h +++ b/src/ss7_as.h @@ -75,6 +75,14 @@ #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, + * how to handle those */ +enum ss7_as_tcap_unroutable { + SS7_AS_TCAP_UNROUTABLE_REJECT_UTDS, /*! reject the unroutable TCAP message with a UTDS */ + SS7_AS_TCAP_UNROUTABLE_LOAD_SHARE_AS, /*! fallback to round robin load-share over all available ASP */ +}; +extern struct value_string osmo_ss7_as_tcap_unroutable_vals[]; + #define NUM_AS_EXT_SLS 128 typedef uint8_t as_ext_sls_t; /* range: 0-127, 7 bit */ struct osmo_ss7_as_esls_entry { @@ -172,6 +180,7 @@ bool enabled; unsigned int timeout_s; struct ss7_as_asp_assoc *last_asp_idx_sent; + enum ss7_as_tcap_unroutable unroutable_tcap_msg; } tcap; #endif /* WITH_TCAP_LOADSHARING */ } loadshare; diff --git a/src/ss7_as_vty.c b/src/ss7_as_vty.c index d9fd58d..da95560 100644 --- a/src/ss7_as_vty.c +++ b/src/ss7_as_vty.c @@ -245,6 +245,22 @@
return CMD_SUCCESS; } + +DEFUN_USRATTR(as_tcap_unroutable_sessions, as_tcap_unroutable_sessions_cmd, + OSMO_SCCP_LIB_ATTR_RSTRT_ASP, + "tcap-unroutable-sessions (reject-utds | 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" + "Reject the message with a UTDS\n" + "Fallback to load-share over AS by using all available AS (round robin)\n") +{ + struct osmo_ss7_as *as = vty->index; + int value = get_string_value(osmo_ss7_as_tcap_unroutable_vals, argv[0]); + if (value < 0) + return CMD_WARNING; + + as->cfg.loadshare.tcap.unroutable_tcap_msg = value; + return CMD_SUCCESS; +} #endif /* WITH_TCAP_LOADSHARING */
DEFUN_ATTR(as_bindingtable_reset, as_bindingtable_reset_cmd, @@ -507,6 +523,13 @@ #ifdef WITH_TCAP_LOADSHARING 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_UTDS) { + 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); + } #endif /* WITH_TCAP_LOADSHARING */
if (as->cfg.recovery_timeout_msec != 2000) { @@ -714,6 +737,7 @@ if (cs7_role == CS7_ROLE_SG) { 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); } #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 a6b71d2..dccf84f 100644 --- a/src/tcap_as_loadshare.c +++ b/src/tcap_as_loadshare.c @@ -254,14 +254,17 @@
/* Select a TCAP-enabled ASP in round-robin fashion */ -static struct osmo_ss7_asp *select_asp_tcap_enabled_rr(struct osmo_ss7_as *as) +static struct osmo_ss7_asp *select_asp_tcap_enabled_rr(struct osmo_ss7_as *as, bool fallback) { struct ss7_as_asp_assoc *assoc;
for (unsigned int i = 0; i < as->num_assoc_asps; i++) { assoc = ss7_as_asp_assoc_llist_round_robin(as, &as->cfg.loadshare.tcap.last_asp_idx_sent); - if (assoc && osmo_ss7_asp_active(assoc->asp) && assoc->asp->tcap.enabled) + if (assoc && osmo_ss7_asp_active(assoc->asp) && assoc->asp->tcap.enabled) { + if (fallback) + rate_ctr_inc2(as->ctrg, SS7_AS_CTR_TCAP_ASP_FALLBACK); return assoc->asp; + } } return NULL; } @@ -522,7 +525,7 @@ goto out_free_sua; }
- asp = select_asp_tcap_enabled_rr(as); + asp = select_asp_tcap_enabled_rr(as, false); if (asp) { rate_ctr_inc2(as->ctrg, SS7_AS_CTR_TCAP_ASP_SELECTED); } else { @@ -548,6 +551,9 @@ asp = tcap_as_asp_find_by_tcap_id(as, &calling_addr, &called_addr, parsed.dtid); if (asp) tcap_trans_track_entry_create(as, asp, &called_addr, &parsed.dtid, &calling_addr, &parsed.otid); + + if (!asp && as->cfg.loadshare.tcap.unroutable_tcap_msg == SS7_AS_TCAP_UNROUTABLE_LOAD_SHARE_AS) + asp = select_asp_tcap_enabled_rr(as, true); } rc = asp ? 0 : -ENOKEY; break; @@ -564,6 +570,8 @@ LOGPAS(as, DLTCAP, LOGL_INFO, "Couldn't find cached ASP for TCAP End, dtid %u, using tcap route", parsed.dtid); rate_ctr_inc2(as->ctrg, SS7_AS_CTR_TCAP_ASP_MISS); asp = tcap_as_asp_find_by_tcap_id(as, &calling_addr, &called_addr, parsed.dtid); + if (!asp && as->cfg.loadshare.tcap.unroutable_tcap_msg == SS7_AS_TCAP_UNROUTABLE_LOAD_SHARE_AS) + asp = select_asp_tcap_enabled_rr(as, true); /* Don't create an entry for an End */ } rc = asp ? 0 : -ENOKEY; diff --git a/tests/vty/osmo_stp_test_tcap.vty b/tests/vty/osmo_stp_test_tcap.vty index 3085074..7ffff77 100644 --- a/tests/vty/osmo_stp_test_tcap.vty +++ b/tests/vty/osmo_stp_test_tcap.vty @@ -22,23 +22,24 @@ ...
OsmoSTP(config-cs7-as)# ? - help Description of the interactive help system - list Print command list - show Show running system information - write Write running configuration to memory, network, or terminal - exit Exit current mode and down to previous mode - end End current mode and change to enable mode. - description Save human-readable description of the object - asp Specify that a given ASP is part of this AS - no Negate a command or set its defaults - 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 - binding-table AS Loadshare binding table operations - recovery-timeout Specifies RFC4666 recovery timer T(r) timeout - qos-class Specity QoS Class of AS - routing-key Define a routing key - point-code Point Code Specific Features + help Description of the interactive help system + list Print command list + show Show running system information + write Write running configuration to memory, network, or terminal + exit Exit current mode and down to previous mode + end End current mode and change to enable mode. + description Save human-readable description of the object + asp Specify that a given ASP is part of this AS + no Negate a command or set its defaults + 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. + binding-table AS Loadshare binding table operations + recovery-timeout Specifies RFC4666 recovery timer T(r) timeout + qos-class Specity QoS Class of AS + routing-key Define a routing key + point-code Point Code Specific Features
OsmoSTP(config-cs7-as)# no ? asp Specify ASP to be removed from this AS