mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-hnbgw.git
synced 2025-11-02 21:13:20 +00:00
sccp: Handle N-NOTICE.ind (Routing Failure of SCCP CL messages)
ITU Q.714 2.8: """ When an end node is informed of a routing failure, this information is forwarded towards the SCCP user by using the N-DISCONNECT primitive (refer to reason for release in 2.1.1.2.4/Q.711) or the N-NOTICE primitive (refer to reason for return in 2.2.2.2.4/Q.711) """ We are already handling N-DISCONNECT.ind for CO messages, but N-NOTICE.ind for CL messages was not being handled. If CL messages are not arriving to the peer (cnlink), then reset the link and mark the peer as disconnected, until a new RESET can successfully fo through. Related: OS#5917 Change-Id: Ie5f643ba9ac8c443ce95c7f0a89a198fb804c94d
This commit is contained in:
@@ -32,6 +32,7 @@ enum hnbgw_cnlink_ctr {
|
||||
/* SCCP Counters: */
|
||||
CNLINK_CTR_SCCP_N_UNITDATA_REQ,
|
||||
CNLINK_CTR_SCCP_N_UNITDATA_IND,
|
||||
CNLINK_CTR_SCCP_N_NOTICE_IND,
|
||||
CNLINK_CTR_SCCP_N_CONNECT_REQ,
|
||||
CNLINK_CTR_SCCP_N_CONNECT_CNF,
|
||||
CNLINK_CTR_SCCP_N_DATA_REQ,
|
||||
|
||||
@@ -84,6 +84,10 @@ static const struct rate_ctr_desc cnlink_ctr_description[] = {
|
||||
"sccp:n_unit_data:ind",
|
||||
"Received SCCP N-UNITDATA.ind (DL)"
|
||||
},
|
||||
[CNLINK_CTR_SCCP_N_NOTICE_IND] = {
|
||||
"sccp:n_notice:ind",
|
||||
"Received SCCP N-NOTICE.ind"
|
||||
},
|
||||
[CNLINK_CTR_SCCP_N_CONNECT_REQ] = {
|
||||
"sccp:n_connect:req",
|
||||
"Submit SCCP N-CONNECT.req (UL SCCP CR)"
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <osmocom/sigtran/sccp_sap.h>
|
||||
#include <osmocom/sigtran/sccp_helpers.h>
|
||||
#include <osmocom/sigtran/protocol/sua.h>
|
||||
#include <osmocom/sccp/sccp_types.h>
|
||||
|
||||
#include <osmocom/hnbgw/hnbgw_cn.h>
|
||||
#include <osmocom/hnbgw/context_map.h>
|
||||
@@ -111,6 +112,38 @@ static int handle_cn_unitdata(struct hnbgw_sccp_user *hsu,
|
||||
return hnbgw_ranap_rx_udt_dl(cnlink, param, msgb_l2(oph->msg), msgb_l2len(oph->msg));
|
||||
}
|
||||
|
||||
static void handle_notice_ind(struct hnbgw_sccp_user *hsu,
|
||||
const struct osmo_scu_notice_param *param,
|
||||
const struct osmo_prim_hdr *oph)
|
||||
{
|
||||
struct hnbgw_cnlink *cnlink;
|
||||
|
||||
cnlink = cnlink_from_addr(hsu, ¶m->calling_addr, oph);
|
||||
if (!cnlink) {
|
||||
LOGP(DCN, LOGL_DEBUG, "(calling_addr=%s) N-NOTICE.ind cause=%u='%s' importance=%u didn't match any cnlink, ignoring\n",
|
||||
osmo_sccp_addr_dump(¶m->calling_addr),
|
||||
param->cause, osmo_sccp_return_cause_name(param->cause),
|
||||
param->importance);
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_CNLINK(cnlink, DCN, LOGL_NOTICE, "N-NOTICE.ind cause=%u='%s' importance=%u\n",
|
||||
param->cause, osmo_sccp_return_cause_name(param->cause),
|
||||
param->importance);
|
||||
CNLINK_CTR_INC(cnlink, CNLINK_CTR_SCCP_N_NOTICE_IND);
|
||||
switch (param->cause) {
|
||||
case SCCP_RETURN_CAUSE_SUBSYSTEM_CONGESTION:
|
||||
case SCCP_RETURN_CAUSE_NETWORK_CONGESTION:
|
||||
/* Transient failures (hopefully), keep going. */
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Messages are not arriving to destination of cnlink. Kick it back to DISC state. */
|
||||
cnlink_set_disconnected(cnlink);
|
||||
}
|
||||
|
||||
static int handle_cn_conn_conf(struct hnbgw_sccp_user *hsu,
|
||||
const struct osmo_scu_connect_param *param,
|
||||
struct osmo_prim_hdr *oph)
|
||||
@@ -318,6 +351,9 @@ static int sccp_sap_up(struct osmo_prim_hdr *oph, void *ctx)
|
||||
case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_INDICATION):
|
||||
rc = handle_cn_unitdata(hsu, &prim->u.unitdata, oph);
|
||||
break;
|
||||
case OSMO_PRIM(OSMO_SCU_PRIM_N_NOTICE, PRIM_OP_INDICATION):
|
||||
handle_notice_ind(hsu, &prim->u.notice, oph);
|
||||
break;
|
||||
case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_CONFIRM):
|
||||
rc = handle_cn_conn_conf(hsu, &prim->u.connect, oph);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user