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