ipa: if there are PCs in the msg, use them for routing

patch_sccp_with_pc() overwrites the SCCP addresses' point-codes only if there
are none yet in the message.

ipa_rx_msg_sccp() feeds opc and dpc to patch into the message, and so far uses
these opc and dpc in the xua_msg_hdr even if there are different PCs in the
SCCP message already, and these opc and dpc were never patched into the msg.

Change the opc and dpc args of patch_sccp_with_pc() as in+out params, and if
not patched into the message, return the opc and dpc actually found in the
message.

Hence in ipa_rx_msg_sccp() compose the m3ua_data_hdr with the point-codes found
in the message, instead of those that would have been but were not actually
patched into the message and potentially mismatch it.

Testing with an SCCPlite MSC actually gives me complete SCCP addresses with
point-codes, so it is not set in stone to receive no point-codes over IPA.

If the cs7 vty config matches the point-codes received, there is no problem,
but I faced a weird situation when the config is wrong: osmo-bsc logs the PCs
received in the message while it confusingly uses the config ones for routing.

Change-Id: I157c43a5dc12f6e24828efef1dceac246497e313
This commit is contained in:
Neels Hofmeyr 2018-07-26 02:11:40 +02:00
parent 5e4643f4bc
commit 8b7968418d
1 changed files with 16 additions and 8 deletions

View File

@ -146,9 +146,10 @@ static struct osmo_ss7_as *find_as_for_asp(struct osmo_ss7_asp *asp)
return NULL;
}
/* Patch a SCCP message and add point codes to Called/Calling Party (if missing) */
/* Patch a SCCP message and add point codes to Called/Calling Party (if missing).
* If not missing, report back the actually present opc and dpc. */
static struct msgb *patch_sccp_with_pc(struct osmo_ss7_asp *asp, struct msgb *sccp_msg_in,
uint32_t opc, uint32_t dpc)
uint32_t *opc, uint32_t *dpc)
{
struct osmo_sccp_addr addr;
struct msgb *sccp_msg_out;
@ -169,11 +170,13 @@ static struct msgb *patch_sccp_with_pc(struct osmo_ss7_asp *asp, struct msgb *sc
rc = sua_addr_parse(&addr, sua, SUA_IEI_DEST_ADDR);
switch (rc) {
case 0:
if (addr.presence & OSMO_SCCP_ADDR_T_PC)
if (addr.presence & OSMO_SCCP_ADDR_T_PC) {
*dpc = addr.pc;
break;
}
/* if there's no point code in dest_addr, add one */
addr.presence |= OSMO_SCCP_ADDR_T_PC;
addr.pc = dpc;
addr.pc = *dpc;
xua_msg_free_tag(sua, SUA_IEI_DEST_ADDR);
xua_msg_add_sccp_addr(sua, SUA_IEI_DEST_ADDR, &addr);
break;
@ -187,11 +190,13 @@ static struct msgb *patch_sccp_with_pc(struct osmo_ss7_asp *asp, struct msgb *sc
rc = sua_addr_parse(&addr, sua, SUA_IEI_SRC_ADDR);
switch (rc) {
case 0:
if (addr.presence & OSMO_SCCP_ADDR_T_PC)
if (addr.presence & OSMO_SCCP_ADDR_T_PC) {
*opc = addr.pc;
break;
}
/* if there's no point code in src_addr, add one */
addr.presence |= OSMO_SCCP_ADDR_T_PC;
addr.pc = opc;
addr.pc = *opc;
xua_msg_free_tag(sua, SUA_IEI_SRC_ADDR);
xua_msg_add_sccp_addr(sua, SUA_IEI_SRC_ADDR, &addr);
break;
@ -229,7 +234,7 @@ static int ipa_rx_msg_sccp(struct osmo_ss7_asp *asp, struct msgb *msg)
/* We have received an IPA-encapsulated SCCP message, without
* any MTP routing label. Furthermore, the SCCP Called/Calling
* Party are SSN-only, with no GT or PC. This means we have no
* Party possibly are SSN-only, with no GT or PC. This means we have no
* real idea where it came from, nor where it goes to. We could
* simply treat it as being for the local point code, but then
* this means that we would have to implement SCCP connection
@ -257,11 +262,14 @@ static int ipa_rx_msg_sccp(struct osmo_ss7_asp *asp, struct msgb *msg)
opc = as->cfg.pc_override.dpc;
/* Destination: PC of the routing key */
dpc = as->cfg.routing_key.pc;
LOGPASP(asp, DLSS7, LOGL_INFO, "Rx message: setting opc=%u dpc=%u\n",
opc, dpc);
}
/* Second, patch this into the SCCP message */
if (as->cfg.pc_override.sccp_mode == OSMO_SS7_PATCH_BOTH) {
msg = patch_sccp_with_pc(asp, msg, opc, dpc);
msg = patch_sccp_with_pc(asp, msg, &opc, &dpc);
if (!msg) {
LOGPASP(asp, DLSS7, LOGL_ERROR, "Unable to patch PC into SCCP message; dropping\n");
return -1;