lynxis lazus has uploaded this change for review.

View Change

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

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

Gerrit-MessageType: newchange
Gerrit-Project: libosmo-sigtran
Gerrit-Branch: master
Gerrit-Change-Id: Ic1c876da30b05065a476d3a7c1bbf0680adf55bd
Gerrit-Change-Number: 42760
Gerrit-PatchSet: 1
Gerrit-Owner: lynxis lazus <lynxis@fe80.eu>