pespin has submitted this change. (
https://gerrit.osmocom.org/c/libosmo-sigtran/+/39377?usp=email )
Change subject: AS loadsharing: Initial routing implementation based on extended-SLS
......................................................................
AS loadsharing: Initial routing implementation based on extended-SLS
This commit adds a new set of APIs and structs to support routing based
on OPC,DPC,SLS fields and hence to support AS-loadshare.
The routing decision is still actually left as beforehand, ie. the first
AS/linkset in the combined_linkset is selected.
This will allow future work, i.e to:
- Check if data can be sent over the combined link (at least one
AS/linkset is ACTIVE), and otherwise try using a combined link with a
less specific match (shorter prefix mask or/and lower priority).
- Select one of the AS/linksets in the combined link based on a
round robin approach.
Related: SYS#7112
Change-Id: I0fb4ca4959096f748a23082efa0481300de56436
---
M include/osmocom/sigtran/osmo_ss7.h
M src/osmo_ss7_combined_linkset.c
M src/osmo_ss7_hmrt.c
M src/osmo_ss7_instance.c
M src/osmo_ss7_route.c
M src/osmo_ss7_route_table.c
M src/osmo_ss7_vty.c
M src/sccp_scrc.c
M src/ss7_combined_linkset.h
M src/ss7_instance.h
M src/ss7_route_table.h
M src/xua_rkm.c
M src/xua_snm.c
M tests/ss7/ss7_test.c
M tests/vty/osmo_stp_test.vty
15 files changed, 293 insertions(+), 48 deletions(-)
Approvals:
Jenkins Builder: Verified
osmith: Looks good to me, but someone else must approve
laforge: Looks good to me, but someone else must approve
pespin: Looks good to me, approved
diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h
index 66cbfe6..264507b 100644
--- a/include/osmocom/sigtran/osmo_ss7.h
+++ b/include/osmocom/sigtran/osmo_ss7.h
@@ -125,7 +125,8 @@
struct osmo_ss7_route;
struct osmo_ss7_route *
-osmo_ss7_route_lookup(struct osmo_ss7_instance *inst, uint32_t dpc);
+osmo_ss7_route_lookup(struct osmo_ss7_instance *inst, uint32_t dpc)
+ OSMO_DEPRECATED("Use internal ss7_instance_lookup_route() instead");
const char *osmo_ss7_route_print(const struct osmo_ss7_route *rt);
const char *osmo_ss7_route_name(struct osmo_ss7_route *rt, bool list_asps);
struct osmo_ss7_as *
diff --git a/src/osmo_ss7_combined_linkset.c b/src/osmo_ss7_combined_linkset.c
index 2e068b4..90a54f6 100644
--- a/src/osmo_ss7_combined_linkset.c
+++ b/src/osmo_ss7_combined_linkset.c
@@ -126,9 +126,86 @@
void ss7_combined_linkset_del_route(struct osmo_ss7_route *rt)
{
struct osmo_ss7_combined_linkset *clset = rt->clset;
+
+ /* Remove route from eSLS table: */
+ for (unsigned int i = 0; i < ARRAY_SIZE(clset->esls_table); i++) {
+ if (clset->esls_table[i].normal_rt == rt)
+ clset->esls_table[i].normal_rt = NULL;
+ if (clset->esls_table[i].alt_rt == rt)
+ clset->esls_table[i].alt_rt = NULL;
+ }
+
llist_del(&rt->list);
rt->clset = NULL;
clset->num_routes--;
if (clset->num_routes == 0)
ss7_combined_linkset_free(clset);
}
+
+static ext_sls_t osmo_ss7_instance_calc_itu_ext_sls(const struct osmo_ss7_instance *inst,
const struct osmo_ss7_route_label *rtlabel)
+{
+ /* Take 6 bits from OPC and DPC according to config: */
+ uint8_t opc6 = (uint8_t)((rtlabel->opc >> inst->cfg.opc_shift) & 0x3f);
+ uint8_t dpc6 = (uint8_t)((rtlabel->dpc >> inst->cfg.dpc_shift) & 0x3f);
+
+ /* Derivate 3-bit value from OPC and DPC: */
+ uint8_t opc3 = ((opc6 >> 3) ^ (opc6 & 0x07)) & 0x07;
+ uint8_t dpc3 = ((dpc6 >> 3) ^ (dpc6 & 0x07)) & 0x07;
+ uint8_t opc_dpc3 = (opc3 ^ dpc3) & 0x07;
+
+ /* Generate 7 bit extended-SLS: 3-bit OPC-DPC + 4 bit SLS: */
+ uint8_t ext_sls = (opc_dpc3 << 4) | ((rtlabel->sls) & 0x0f);
+ OSMO_ASSERT(ext_sls < NUM_EXT_SLS);
+
+ /* Pick extended-SLS bits according to config: */
+ ext_sls = ext_sls >> inst->cfg.sls_shift;
+ return ext_sls;
+}
+
+/* ITU Q.704 4.2.1: "current link set (combined link set)". Pick available
already selected route */
+struct osmo_ss7_route *current_rt(const struct osmo_ss7_esls_entry *eslse)
+{
+ if (eslse->normal_rt && ss7_route_is_available(eslse->normal_rt))
+ return eslse->normal_rt;
+ if (eslse->alt_rt && ss7_route_is_available(eslse->alt_rt))
+ return eslse->alt_rt;
+ return NULL;
+}
+
+struct osmo_ss7_route *
+ss7_combined_linkset_lookup_route(struct osmo_ss7_combined_linkset *clset, const struct
osmo_ss7_route_label *rtlabel)
+{
+ struct osmo_ss7_route *rt;
+ ext_sls_t esls = osmo_ss7_instance_calc_itu_ext_sls(clset->rtable->inst,
rtlabel);
+ struct osmo_ss7_esls_entry *eslse = &clset->esls_table[esls];
+
+ /* First check if we have a cached route for this ESLS */
+ rt = current_rt(eslse);
+ if (rt) {
+ if (rt == eslse->normal_rt) {
+ /* We can transmit over normal route.
+ * Clean up alternative route since it's not needed anymore */
+ eslse->alt_rt = NULL;
+ return rt;
+ }
+ /* We can transmit over alternative route: */
+ return rt;
+ }
+
+ /* TODO: Check if the AS/linkset in rt is actually UP and can be
+ * used, otherwise start ITU Q.704 section 7 "forced rerouting" prcoedure:
+ * we need to pick a temporary dst (update the esls_table entry) while the
+ * original one is DOWN. */
+
+ /* We need to pick a new AS/linkset from the combined linkset and cache
+ * it so it is always used for this eSLS: */
+ /* FIXME: for now we simply take the first AS in the combined linksed, to be improved
later... */
+ rt = llist_first_entry_or_null(&clset->routes, struct osmo_ss7_route, list);
+
+ /* TODO: here we'd need to actually check if dst AS/linkset in the route
+ * is actually UP, otherwise pick next one in the roundrobin list... */
+ if (rt)
+ clset->esls_table[esls].normal_rt = rt;
+
+ return rt;
+}
diff --git a/src/osmo_ss7_hmrt.c b/src/osmo_ss7_hmrt.c
index 118acab..1e000b4 100644
--- a/src/osmo_ss7_hmrt.c
+++ b/src/osmo_ss7_hmrt.c
@@ -153,11 +153,16 @@
struct xua_msg *xua)
{
uint32_t dpc = xua->mtp.dpc;
+ struct osmo_ss7_route_label rtlabel = {
+ .opc = xua->mtp.opc,
+ .dpc = xua->mtp.dpc,
+ .sls = xua->mtp.sls,
+ };
struct osmo_ss7_route *rt;
- /* find route for DPC */
+ /* find route for OPC+DPC+SLS: */
/* FIXME: unify with gen_mtp_transfer_req_xua() */
- rt = osmo_ss7_route_lookup(inst, dpc);
+ rt = ss7_instance_lookup_route(inst, &rtlabel);
if (rt) {
/* FIXME: DPC SP restart? */
/* FIXME: DPC Congested? */
diff --git a/src/osmo_ss7_instance.c b/src/osmo_ss7_instance.c
index f7d9a41..527cf2a 100644
--- a/src/osmo_ss7_instance.c
+++ b/src/osmo_ss7_instance.c
@@ -202,6 +202,15 @@
return -1;
}
+/*! \brief Find a SS7 route for given destination point code in given SS7 */
+struct osmo_ss7_route *
+ss7_instance_lookup_route(struct osmo_ss7_instance *inst, const struct
osmo_ss7_route_label *rtlabel)
+{
+ OSMO_ASSERT(ss7_initialized);
+ return ss7_route_table_lookup_route(inst->rtable_system, rtlabel);
+}
+
+
/***********************************************************************
* SS7 Application Server
***********************************************************************/
diff --git a/src/osmo_ss7_route.c b/src/osmo_ss7_route.c
index f1fe150..f75e32a 100644
--- a/src/osmo_ss7_route.c
+++ b/src/osmo_ss7_route.c
@@ -335,12 +335,21 @@
return buf;
}
-/*! \brief Find a SS7 route for given destination point code in given SS7 */
+/*! \brief Find a SS7 route for given destination point code in given SS7
+ *
+ * NOTE: DEPRECATED, use ss7_instance_lookup_route() instead
+ */
struct osmo_ss7_route *
osmo_ss7_route_lookup(struct osmo_ss7_instance *inst, uint32_t dpc)
{
OSMO_ASSERT(ss7_initialized);
- return ss7_route_table_find_route_by_dpc(inst->rtable_system, dpc);
+ struct osmo_ss7_route_label rtlb = {
+ .opc = 0,
+ .dpc = dpc,
+ .sls = 0,
+ };
+
+ return ss7_instance_lookup_route(inst, &rtlb);
}
/*! \brief Get destination AS of route
@@ -353,7 +362,6 @@
return rt->dest.as;
}
-
/* Whether route is available, ITU Q.704 */
bool ss7_route_is_available(const struct osmo_ss7_route *rt)
{
diff --git a/src/osmo_ss7_route_table.c b/src/osmo_ss7_route_table.c
index b230521..734db88 100644
--- a/src/osmo_ss7_route_table.c
+++ b/src/osmo_ss7_route_table.c
@@ -19,6 +19,8 @@
*
*/
+ #include <stdio.h>
+
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/logging.h>
#include <osmocom/sigtran/mtp_sap.h>
@@ -29,6 +31,22 @@
#include "ss7_route_table.h"
#include "ss7_internal.h"
+
+/***********************************************************************
+ * SS7 Route Label
+ ***********************************************************************/
+
+char *ss7_route_label_to_str(char *buf, size_t buf_len, const struct osmo_ss7_instance
*inst, const struct osmo_ss7_route_label *rtlb)
+{
+ if (buf_len == 0)
+ return NULL;
+ snprintf(buf, buf_len, "OPC=%u=%s,DPC=%u=%s,SLS=%u",
+ rtlb->opc, osmo_ss7_pointcode_print(inst, rtlb->opc),
+ rtlb->dpc, osmo_ss7_pointcode_print2(inst, rtlb->dpc),
+ rtlb->sls);
+ return buf;
+}
+
/***********************************************************************
* SS7 Route Tables
***********************************************************************/
@@ -83,25 +101,10 @@
talloc_free(rtbl);
}
-/*! \brief Find a SS7 route for given destination point code in given table */
-struct osmo_ss7_route *
-ss7_route_table_find_route_by_dpc(struct osmo_ss7_route_table *rtbl, uint32_t dpc)
-{
- struct osmo_ss7_combined_linkset *clset;
- struct osmo_ss7_route *rt;
-
- OSMO_ASSERT(ss7_initialized);
-
- dpc = osmo_ss7_pc_normalize(&rtbl->inst->cfg.pc_fmt, dpc);
-
- clset = ss7_route_table_find_combined_linkset_by_dpc(rtbl, dpc);
- if (!clset)
- return NULL;
- rt = llist_first_entry_or_null(&clset->routes, struct osmo_ss7_route, list);
- return rt;
-}
-
-/*! \brief Find a SS7 route for given destination point code + mask in given table */
+/*! \brief Find a SS7 route for given destination point code + mask in given table.
+ *
+ * This function is used for route management procedures, not for packet routing lookup
procedures!
+ */
struct osmo_ss7_route *
ss7_route_table_find_route_by_dpc_mask(struct osmo_ss7_route_table *rtbl, uint32_t dpc,
uint32_t mask)
@@ -227,3 +230,27 @@
}
}
}
+
+struct osmo_ss7_route *
+ss7_route_table_lookup_route(struct osmo_ss7_route_table *rtbl, const struct
osmo_ss7_route_label *rtlabel)
+{
+ struct osmo_ss7_combined_linkset *clset;
+ struct osmo_ss7_route *rt;
+ struct osmo_ss7_route_label rtlb = {
+ .opc = osmo_ss7_pc_normalize(&rtbl->inst->cfg.pc_fmt, rtlabel->opc),
+ .dpc = osmo_ss7_pc_normalize(&rtbl->inst->cfg.pc_fmt, rtlabel->dpc),
+ .sls = rtlabel->sls,
+ };
+ /* we assume the combined_links are sorted by mask length, i.e. more
+ * specific combined links first, and less specific combined links with shorter
+ * mask later */
+ llist_for_each_entry(clset, &rtbl->combined_linksets, list) {
+ if ((rtlb.dpc & clset->cfg.mask) != clset->cfg.pc)
+ continue;
+ rt = ss7_combined_linkset_lookup_route(clset, &rtlb);
+ if (!rt)
+ continue;
+ return rt;
+ }
+ return NULL;
+}
diff --git a/src/osmo_ss7_vty.c b/src/osmo_ss7_vty.c
index 2704742..81ce0ce 100644
--- a/src/osmo_ss7_vty.c
+++ b/src/osmo_ss7_vty.c
@@ -290,6 +290,41 @@
return CMD_SUCCESS;
}
+
+DEFUN_ATTR(cs7_opc_dpc_shift, cs7_opc_dpc_shift_cmd,
+ "sls-opc-dpc [opc-shift] [<0-8>] [dpc-shift] [<0-8>]",
+ "Shift OPC and DPC bits used during routing decision\n"
+ "Shift OPC bits used during routing decision\n"
+ "How many bits from ITU OPC field (starting from least-significant-bit) to skip
(default=0). 6 bits are always used\n"
+ "Shift DPC bits used during routing decision\n"
+ "How many bits from ITU DPC field (starting from least-significant-bit) to skip
(default=0). 6 bits are always used\n",
+ CMD_ATTR_IMMEDIATE)
+{
+ struct osmo_ss7_instance *inst = vty->index;
+ if (argc == 4)
+ inst->cfg.dpc_shift = atoi(argv[3]);
+ else if (argc == 3)
+ inst->cfg.dpc_shift = 0;
+ if (argc >= 2)
+ inst->cfg.opc_shift = atoi(argv[1]);
+ else if (argc == 1)
+ inst->cfg.opc_shift = 0;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN_ATTR(cs7_sls_shift, cs7_sls_shift_cmd,
+ "sls-shift <0-6>",
+ "Shift SLS bits used during routing decision\n"
+ "How many bits from derivated 7-bit extended-SLS (OPC, DPC, SLS) field (starting
from least-significant-bit) to skip\n",
+ CMD_ATTR_IMMEDIATE)
+{
+ struct osmo_ss7_instance *inst = vty->index;
+ inst->cfg.sls_shift = atoi(argv[0]);
+
+ return CMD_SUCCESS;
+}
+
static void write_one_cs7(struct vty *vty, struct osmo_ss7_instance *inst, bool
show_dyn_config);
static int write_all_cs7(struct vty *vty, bool show_dyn_config)
@@ -584,7 +619,7 @@
bool list_asps = argc > 4;
struct osmo_ss7_instance *inst;
struct osmo_ss7_route *rt;
- uint32_t dpc;
+ struct osmo_ss7_route_label rtlabel = {};
int pc;
inst = osmo_ss7_instance_find(id);
@@ -598,18 +633,22 @@
vty_out(vty, "Invalid point code (%s)%s", argv[1], VTY_NEWLINE);
return CMD_WARNING;
}
- dpc = pc;
+ rtlabel.dpc = pc;
pc = osmo_ss7_pointcode_parse(inst, argv[2]);
if (pc < 0 || !osmo_ss7_pc_is_valid((uint32_t)pc)) {
vty_out(vty, "Invalid point code (%s)%s", argv[2], VTY_NEWLINE);
return CMD_WARNING;
}
+ rtlabel.opc = pc;
- rt = osmo_ss7_route_lookup(inst, dpc);
+ rtlabel.sls = atoi(argv[3]);
+
+ rt = ss7_instance_lookup_route(inst, &rtlabel);
if (!rt) {
- vty_out(vty, "No route found for DPC %s%s",
- osmo_ss7_pointcode_print(inst, dpc), VTY_NEWLINE);
+ char buf[256];
+ vty_out(vty, "No route found for label '%s'%s",
+ ss7_route_label_to_str(buf, sizeof(buf), inst, &rtlabel), VTY_NEWLINE);
return CMD_WARNING;
}
@@ -2971,6 +3010,13 @@
if (inst->cfg.permit_dyn_rkm_alloc)
vty_out(vty, " xua rkm routing-key-allocation dynamic-permitted%s",
VTY_NEWLINE);
+ if (inst->cfg.opc_shift != 0 || inst->cfg.dpc_shift != 0)
+ vty_out(vty, " sls-opc-dpc opc-shift %u dpc-shift %u%s",
+ inst->cfg.opc_shift, inst->cfg.dpc_shift, VTY_NEWLINE);
+
+ if (inst->cfg.sls_shift != 0)
+ vty_out(vty, " sls-shift %u%s", inst->cfg.sls_shift, VTY_NEWLINE);
+
/* first dump ASPs, as ASs reference them */
llist_for_each_entry(asp, &inst->asp_list, list)
write_one_asp(vty, asp, show_dyn_config);
@@ -3133,6 +3179,8 @@
install_lib_element(L_CS7_NODE, &cs7_pc_format_def_cmd);
install_lib_element(L_CS7_NODE, &cs7_pc_delimiter_cmd);
install_lib_element(L_CS7_NODE, &cs7_permit_dyn_rkm_cmd);
+ install_lib_element(L_CS7_NODE, &cs7_opc_dpc_shift_cmd);
+ install_lib_element(L_CS7_NODE, &cs7_sls_shift_cmd);
install_node(&asp_node, NULL);
install_lib_element_ve(&show_cs7_asp_cmd);
diff --git a/src/sccp_scrc.c b/src/sccp_scrc.c
index 23c3f2d..869235c 100644
--- a/src/sccp_scrc.c
+++ b/src/sccp_scrc.c
@@ -37,6 +37,7 @@
#include "ss7_instance.h"
#include "ss7_linkset.h"
#include "ss7_route.h"
+#include "ss7_route_table.h"
#include "xua_internal.h"
@@ -120,6 +121,7 @@
const struct osmo_sccp_addr *called)
{
struct osmo_ss7_route *rt;
+ struct osmo_ss7_route_label rtlabel;
/* this is a bit fishy due to the different requirements of
* classic SSCP/MTP compared to various SIGTRAN stackings.
@@ -144,7 +146,13 @@
return -1;
}
- rt = osmo_ss7_route_lookup(inst->ss7, xua->mtp.dpc);
+ rtlabel = (struct osmo_ss7_route_label){
+ .opc = xua->mtp.opc,
+ .dpc = xua->mtp.dpc,
+ .sls = xua->mtp.sls,
+ };
+
+ rt = ss7_instance_lookup_route(inst->ss7, &rtlabel);
if (!rt) {
LOGP(DLSCCP, LOGL_ERROR, "MTP-TRANSFER.req from SCCP for "
"DPC %u: no route!\n", xua->mtp.dpc);
diff --git a/src/ss7_combined_linkset.h b/src/ss7_combined_linkset.h
index 1c3b684..e2f9c9d 100644
--- a/src/ss7_combined_linkset.h
+++ b/src/ss7_combined_linkset.h
@@ -10,6 +10,17 @@
struct osmo_ss7_instance;
struct osmo_ss7_link;
+struct osmo_ss7_route_label;
+
+#define NUM_EXT_SLS 128
+typedef uint8_t ext_sls_t; /* range: 0-127, 7 bit */
+
+struct osmo_ss7_esls_entry {
+ /* ITU Q.704 4.2.1: "normal link set (combined link set)" */
+ struct osmo_ss7_route *normal_rt;
+ /* ITU Q.704 4.2.1: "alternative link set (combined link set)" */
+ struct osmo_ss7_route *alt_rt;
+};
struct osmo_ss7_combined_linkset {
/*! member in \ref osmo_ss7_route_table.combined_linksets */
@@ -17,6 +28,7 @@
/*! \ref osmo_ss7_route_table to which we belong */
struct osmo_ss7_route_table *rtable;
+ struct osmo_ss7_esls_entry esls_table[NUM_EXT_SLS];
/*! list of \ref osmo_ss7_route */
struct llist_head routes;
@@ -41,3 +53,5 @@
ss7_combined_linkset_add_route(struct osmo_ss7_combined_linkset *clset, struct
osmo_ss7_route *rt);
void
ss7_combined_linkset_del_route(struct osmo_ss7_route *rt);
+struct osmo_ss7_route *
+ss7_combined_linkset_lookup_route(struct osmo_ss7_combined_linkset *clset, const struct
osmo_ss7_route_label *rtlabel);
diff --git a/src/ss7_instance.h b/src/ss7_instance.h
index d76891f..bb8815b 100644
--- a/src/ss7_instance.h
+++ b/src/ss7_instance.h
@@ -10,6 +10,7 @@
struct osmo_ss7_user;
struct osmo_ss7_route_table;
+struct osmo_ss7_route_label;
struct osmo_sccp_instance;
struct osmo_ss7_pc_fmt {
@@ -49,6 +50,15 @@
bool permit_dyn_rkm_alloc;
struct llist_head sccp_address_book;
uint32_t secondary_pc;
+ /* How many bits from ITU OPC/DPC field (starting from least-significant-bit)
+ * to skip for routing decisions (always takes 6 bits).
+ * range 0-8, defaults to 0, which means take least significant 6 bits. */
+ uint8_t opc_shift;
+ uint8_t dpc_shift;
+ /* How many bits from ITU SLS field (starting from least-significant-bit)
+ * to skip for routing decisions.
+ * range 0-3, defaults to 0, which means take all 4 bits. */
+ uint8_t sls_shift;
} cfg;
};
@@ -56,6 +66,8 @@
ss7_instance_alloc(void *ctx, uint32_t id);
uint32_t ss7_find_free_l_rk_id(struct osmo_ss7_instance *inst);
+struct osmo_ss7_route *
+ss7_instance_lookup_route(struct osmo_ss7_instance *inst, const struct
osmo_ss7_route_label *rtlabel);
#define _LOGSS7(inst, subsys, level, fmt, args ...) \
LOGP(subsys, level, "%u: " fmt, inst ? (inst)->cfg.id : 0, ## args)
diff --git a/src/ss7_route_table.h b/src/ss7_route_table.h
index c88c742..1de3be5 100644
--- a/src/ss7_route_table.h
+++ b/src/ss7_route_table.h
@@ -1,6 +1,7 @@
#pragma once
#include <stdint.h>
+#include <unistd.h>
#include <osmocom/core/linuxlist.h>
/***********************************************************************
@@ -9,6 +10,13 @@
struct osmo_ss7_instance;
+struct osmo_ss7_route_label {
+ uint32_t opc;
+ uint32_t dpc;
+ uint8_t sls;
+};
+char *ss7_route_label_to_str(char *buf, size_t buf_len, const struct osmo_ss7_instance
*inst, const struct osmo_ss7_route_label *rtlb);
+
struct osmo_ss7_route_table {
/*! member in list of routing tables */
struct llist_head list;
@@ -30,10 +38,10 @@
void ss7_route_table_destroy(struct osmo_ss7_route_table *rtbl);
struct osmo_ss7_route *
-ss7_route_table_find_route_by_dpc(struct osmo_ss7_route_table *rtbl, uint32_t dpc);
-struct osmo_ss7_route *
ss7_route_table_find_route_by_dpc_mask(struct osmo_ss7_route_table *rtbl, uint32_t dpc,
uint32_t mask);
+struct osmo_ss7_route *
+ss7_route_table_lookup_route(struct osmo_ss7_route_table *rtbl, const struct
osmo_ss7_route_label *rtlabel);
struct osmo_ss7_combined_linkset *
ss7_route_table_find_combined_linkset(struct osmo_ss7_route_table *rtbl, uint32_t dpc,
uint32_t mask, uint32_t prio);
diff --git a/src/xua_rkm.c b/src/xua_rkm.c
index 98f41c5..8fa8c3b 100644
--- a/src/xua_rkm.c
+++ b/src/xua_rkm.c
@@ -393,7 +393,7 @@
return -1;
}
- rt = ss7_route_table_find_route_by_dpc(inst->rtable_system,
as->cfg.routing_key.pc);
+ rt = ss7_route_table_find_route_by_dpc_mask(inst->rtable_system,
as->cfg.routing_key.pc, 0xffffff);
if (!rt) {
msgb_append_dereg_res(resp, M3UA_RKM_DEREG_ERR_UNKNOWN, 0);
return -1;
diff --git a/src/xua_snm.c b/src/xua_snm.c
index 971380b..acdfe0c 100644
--- a/src/xua_snm.c
+++ b/src/xua_snm.c
@@ -34,6 +34,7 @@
#include "ss7_as.h"
#include "ss7_asp.h"
#include "ss7_internal.h"
+#include "ss7_route_table.h"
#include "xua_internal.h"
#include "sccp_internal.h"
@@ -340,8 +341,14 @@
if (mask == 0) {
/* one single point code */
+ struct osmo_ss7_route_label rtlabel = {
+ .opc = xua->mtp.opc, /* Use OPC of received DAUD. FIXME: is this correct? */
+ .dpc = pc,
+ .sls = 0,
+ };
+
/* FIXME: don't just check for a route; but also check if the route is
"active" */
- if (osmo_ss7_route_lookup(s7i, pc))
+ if (ss7_instance_lookup_route(s7i, &rtlabel))
is_available = true;
xua_tx_snm_available(asp, rctx, num_rctx, &aff_pc[i], 1, "Response to
DAUD",
diff --git a/tests/ss7/ss7_test.c b/tests/ss7/ss7_test.c
index 6fe1110..95fa1b1 100644
--- a/tests/ss7/ss7_test.c
+++ b/tests/ss7/ss7_test.c
@@ -147,11 +147,15 @@
osmo_ss7_user_destroy(user2);
}
+#define RT_LABEL(opc_val, dpc_val, sls_val) \
+ (struct osmo_ss7_route_label){ .opc = (opc_val), .dpc = (dpc_val), .sls = (sls_val) }
+
static void test_route(void)
{
struct osmo_ss7_route_table *rtbl;
struct osmo_ss7_linkset *lset_a, *lset_b;
struct osmo_ss7_route *rt, *rt12, *rtdef;
+ struct osmo_ss7_route_label route_label;
printf("Testing SS7 routing\n");
@@ -173,32 +177,45 @@
OSMO_ASSERT(lset_b);
/* route with full mask */
- OSMO_ASSERT(ss7_route_table_find_route_by_dpc(rtbl, 12) == NULL);
+ route_label = RT_LABEL(0, 12, 0);
+ OSMO_ASSERT(ss7_route_table_lookup_route(rtbl, &route_label) == NULL);
rt = ss7_route_create(rtbl, 12, 0xffff, "a");
printf("route with full mask: %s\n", osmo_ss7_route_print(rt));
OSMO_ASSERT(rt);
- OSMO_ASSERT(ss7_route_table_find_route_by_dpc(rtbl, 12) == rt);
+ route_label = RT_LABEL(0, 12, 0);
+ OSMO_ASSERT(ss7_route_table_lookup_route(rtbl, &route_label) == rt);
ss7_route_destroy(rt);
/* route with partial mask */
rt = ss7_route_create(rtbl, 8, 0xfff8, "a");
printf("route with partial mask: %s\n", osmo_ss7_route_print(rt));
- OSMO_ASSERT(ss7_route_table_find_route_by_dpc(rtbl, 8) == rt);
- OSMO_ASSERT(ss7_route_table_find_route_by_dpc(rtbl, 9) == rt);
- OSMO_ASSERT(ss7_route_table_find_route_by_dpc(rtbl, 12) == rt);
- OSMO_ASSERT(ss7_route_table_find_route_by_dpc(rtbl, 15) == rt);
- OSMO_ASSERT(ss7_route_table_find_route_by_dpc(rtbl, 16) == NULL);
+ route_label = RT_LABEL(0, 8, 0);
+ OSMO_ASSERT(ss7_route_table_lookup_route(rtbl, &route_label) == rt);
+ route_label = RT_LABEL(0, 9, 0);
+ OSMO_ASSERT(ss7_route_table_lookup_route(rtbl, &route_label) == rt);
+ route_label = RT_LABEL(0, 12, 0);
+ OSMO_ASSERT(ss7_route_table_lookup_route(rtbl, &route_label) == rt);
+ route_label = RT_LABEL(0, 15, 0);
+ OSMO_ASSERT(ss7_route_table_lookup_route(rtbl, &route_label) == rt);
+ route_label = RT_LABEL(0, 16, 0);
+ OSMO_ASSERT(ss7_route_table_lookup_route(rtbl, &route_label) == NULL);
/* insert more specific route for 12, must have higher priority
* than existing one */
rt12 = ss7_route_create(rtbl, 12, 0xffff, "b");
- OSMO_ASSERT(ss7_route_table_find_route_by_dpc(rtbl, 12) == rt12);
- OSMO_ASSERT(ss7_route_table_find_route_by_dpc(rtbl, 15) == rt);
- OSMO_ASSERT(ss7_route_table_find_route_by_dpc(rtbl, 16) == NULL);
+ route_label = RT_LABEL(0, 12, 0);
+ OSMO_ASSERT(ss7_route_table_lookup_route(rtbl, &route_label) == rt12);
+ route_label = RT_LABEL(0, 15, 0);
+ OSMO_ASSERT(ss7_route_table_lookup_route(rtbl, &route_label) == rt);
+ route_label = RT_LABEL(0, 16, 0);
+ OSMO_ASSERT(ss7_route_table_lookup_route(rtbl, &route_label) == NULL);
/* add a default route, which should have lowest precedence */
rtdef = ss7_route_create(rtbl, 0, 0, "a");
- OSMO_ASSERT(ss7_route_table_find_route_by_dpc(rtbl, 12) == rt12);
- OSMO_ASSERT(ss7_route_table_find_route_by_dpc(rtbl, 15) == rt);
- OSMO_ASSERT(ss7_route_table_find_route_by_dpc(rtbl, 16) == rtdef);
+ route_label = RT_LABEL(0, 12, 0);
+ OSMO_ASSERT(ss7_route_table_lookup_route(rtbl, &route_label) == rt12);
+ route_label = RT_LABEL(0, 15, 0);
+ OSMO_ASSERT(ss7_route_table_lookup_route(rtbl, &route_label) == rt);
+ route_label = RT_LABEL(0, 16, 0);
+ OSMO_ASSERT(ss7_route_table_lookup_route(rtbl, &route_label) == rtdef);
ss7_route_destroy(rtdef);
ss7_route_destroy(rt12);
diff --git a/tests/vty/osmo_stp_test.vty b/tests/vty/osmo_stp_test.vty
index 747c7b7..200fff8 100644
--- a/tests/vty/osmo_stp_test.vty
+++ b/tests/vty/osmo_stp_test.vty
@@ -112,6 +112,8 @@
point-code format default
point-code delimiter (default|dash)
xua rkm routing-key-allocation (static-only|dynamic-permitted)
+ sls-opc-dpc [opc-shift] [<0-8>] [dpc-shift] [<0-8>]
+ sls-shift <0-6>
asp NAME <0-65535> <0-65535> (sua|m3ua|ipa)
asp NAME <0-65535> <0-65535> (sua|m3ua|ipa) (sctp|tcp)
no asp NAME
@@ -132,6 +134,8 @@
point-code Configure the local Point Code
secondary-pc Configure the local Secondary Point Code
xua SIGTRAN xxxUA related
+ sls-opc-dpc Shift OPC and DPC bits used during routing decision
+ sls-shift Shift SLS bits used during routing decision
asp Configure Application Server Process
no Negate a command or set its defaults
as Configure an Application Server
--
To view, visit
https://gerrit.osmocom.org/c/libosmo-sigtran/+/39377?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: merged
Gerrit-Project: libosmo-sigtran
Gerrit-Branch: master
Gerrit-Change-Id: I0fb4ca4959096f748a23082efa0481300de56436
Gerrit-Change-Number: 39377
Gerrit-PatchSet: 12
Gerrit-Owner: pespin <pespin(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: osmith <osmith(a)sysmocom.de>
Gerrit-Reviewer: pespin <pespin(a)sysmocom.de>