pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmo-sigtran/+/43845?usp=email )
Change subject: Support AS routing filtering based on its routing-key SI ......................................................................
Support AS routing filtering based on its routing-key SI
Pass the full ss7_mtp3_rtlabel instead of the generic osmo_ss7_routing_label to combined_linkset() lookup, which contains also the SIO of the message being routed. Then, update ss7_route_is_available_for_rtlabel() -> ss7_route_is_available_for_mtp3_rtlabel() to also take into account the SIO field when figuring out if the message can be routed to an AS.
Also update the VTY "route-lookup" command to require an SI from the user, since routing may changed based on it now.
Related: OS#7070 Change-Id: Iec4af5d9a3607747006c26e2baa61ab945f88532 --- M src/ss7_combined_linkset.c M src/ss7_combined_linkset.h M src/ss7_route.c M src/ss7_route.h M src/ss7_route_table.c M src/ss7_vty.c M tests/vty/osmo_stp_route_prio.vty 7 files changed, 41 insertions(+), 37 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmo-sigtran refs/changes/45/43845/1
diff --git a/src/ss7_combined_linkset.c b/src/ss7_combined_linkset.c index 59c7007..b3b4ccd 100644 --- a/src/ss7_combined_linkset.c +++ b/src/ss7_combined_linkset.c @@ -172,11 +172,11 @@ return avail; }
-static ext_sls_t osmo_ss7_instance_calc_itu_ext_sls(const struct osmo_ss7_instance *inst, const struct osmo_ss7_route_label *rtlabel) +static ext_sls_t osmo_ss7_instance_calc_itu_ext_sls(const struct osmo_ss7_instance *inst, const struct ss7_mtp3_rtlabel *mtp3_rtlb) { /* 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); + uint8_t opc6 = (uint8_t)((mtp3_rtlb->rtlabel.opc >> inst->cfg.opc_shift) & 0x3f); + uint8_t dpc6 = (uint8_t)((mtp3_rtlb->rtlabel.dpc >> inst->cfg.dpc_shift) & 0x3f);
/* Derivate 3-bit value from OPC and DPC: */ uint8_t opc3 = ((opc6 >> 3) ^ (opc6 & 0x07)) & 0x07; @@ -184,7 +184,7 @@ 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); + uint8_t ext_sls = (opc_dpc3 << 4) | ((mtp3_rtlb->rtlabel.sls) & 0x0f); OSMO_ASSERT(ext_sls < NUM_EXT_SLS);
/* Pick extended-SLS bits according to config: */ @@ -194,11 +194,11 @@
/* 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, - const struct osmo_ss7_route_label *rtlabel) + const struct ss7_mtp3_rtlabel *mtp3_rtlb) { - if (eslse->normal_rt && ss7_route_is_available_for_rtlabel(eslse->normal_rt, rtlabel)) + if (eslse->normal_rt && ss7_route_is_available_for_mtp3_rtlabel(eslse->normal_rt, mtp3_rtlb)) return eslse->normal_rt; - if (eslse->alt_rt && ss7_route_is_available_for_rtlabel(eslse->alt_rt, rtlabel)) + if (eslse->alt_rt && ss7_route_is_available_for_mtp3_rtlabel(eslse->alt_rt, mtp3_rtlb)) return eslse->alt_rt; return NULL; } @@ -225,29 +225,29 @@
/* Pick an available route from Combined Linkset in a round-robin fashion, to send a message through. */ static struct osmo_ss7_route *ss7_combined_linkset_select_route_roundrobin(struct osmo_ss7_combined_linkset *clset, - const struct osmo_ss7_route_label *rtlabel) + const struct ss7_mtp3_rtlabel *mtp3_rtlb) { struct osmo_ss7_route *rt;
for (unsigned int i = 0; i < clset->num_routes; i++) { rt = ss7_llist_round_robin(&clset->routes, &clset->last_route_roundrobin_tx, struct osmo_ss7_route, list); - if (rt && ss7_route_is_available_for_rtlabel(rt, rtlabel)) + if (rt && ss7_route_is_available_for_mtp3_rtlabel(rt, mtp3_rtlb)) return 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) +ss7_combined_linkset_lookup_route(struct osmo_ss7_combined_linkset *clset, const struct ss7_mtp3_rtlabel *mtp3_rtlb) { struct osmo_ss7_route *rt; struct osmo_ss7_instance *inst = clset->rtable->inst; - ext_sls_t esls = osmo_ss7_instance_calc_itu_ext_sls(inst, rtlabel); + ext_sls_t esls = osmo_ss7_instance_calc_itu_ext_sls(inst, mtp3_rtlb); struct osmo_ss7_esls_entry *eslse = &clset->esls_table[esls]; char buf[256];
/* First check if we have a cached route for this ESLS */ - rt = current_rt(eslse, rtlabel); + rt = current_rt(eslse, mtp3_rtlb); if (rt) { if (rt == eslse->normal_rt) { /* We can transmit over normal route. @@ -255,14 +255,14 @@ if (eslse->alt_rt) { LOGPCLSET(clset, DLSS7, LOGL_NOTICE, "RT lookup: %s -> eSLS=%u: " "Normal Route via '%s' became available, drop use of Alternative Route via '%s'\n", - ss7_route_label_to_str(buf, sizeof(buf), inst, rtlabel), esls, + ss7_mtp3_rtlabel_to_str(buf, sizeof(buf), inst, mtp3_rtlb), esls, eslse->normal_rt->dest.as ? eslse->normal_rt->dest.as->cfg.name : "<linkset>", eslse->alt_rt->dest.as ? eslse->alt_rt->dest.as->cfg.name : "<linkset>"); eslse->alt_rt = NULL; } LOGPCLSET(clset, DLSS7, LOGL_DEBUG, "RT lookup: %s -> eSLS=%u: use Normal Route via '%s'\n", - ss7_route_label_to_str(buf, sizeof(buf), inst, rtlabel), esls, + ss7_mtp3_rtlabel_to_str(buf, sizeof(buf), inst, mtp3_rtlb), esls, eslse->normal_rt->dest.as ? eslse->normal_rt->dest.as->cfg.name : "<linkset>"); return rt; } @@ -281,10 +281,10 @@ if (!rt) return NULL; eslse->normal_rt = rt; - rt_avail = ss7_route_is_available_for_rtlabel(eslse->normal_rt, rtlabel); + rt_avail = ss7_route_is_available_for_mtp3_rtlabel(eslse->normal_rt, mtp3_rtlb); LOGPCLSET(clset, DLSS7, LOGL_INFO, "RT loookup: %s -> eSLS=%u: " "picked Normal Route via '%s' round-robin style (%s)\n", - ss7_route_label_to_str(buf, sizeof(buf), inst, rtlabel), esls, + ss7_mtp3_rtlabel_to_str(buf, sizeof(buf), inst, mtp3_rtlb), esls, rt->dest.as ? rt->dest.as->cfg.name : "<linkset>", rt_avail ? "available" : "unavailable"); if (rt_avail) { @@ -297,19 +297,19 @@
/* Normal route unavailable and no alternative route (or unavailable too). * start ITU Q.704 section 7 "forced rerouting" procedure: */ - rt = ss7_combined_linkset_select_route_roundrobin(clset, rtlabel); + rt = ss7_combined_linkset_select_route_roundrobin(clset, mtp3_rtlb); if (rt) { eslse->alt_rt = rt; LOGPCLSET(clset, DLSS7, LOGL_NOTICE, "RT Lookup: %s -> eSLS=%u: " "Normal Route via '%s' unavailable, picked Alternative Route via '%s' round-robin style\n", - ss7_route_label_to_str(buf, sizeof(buf), inst, rtlabel), esls, + ss7_mtp3_rtlabel_to_str(buf, sizeof(buf), inst, mtp3_rtlb), esls, eslse->normal_rt->dest.as ? eslse->normal_rt->dest.as->cfg.name : "<linkset>", eslse->alt_rt->dest.as ? eslse->alt_rt->dest.as->cfg.name : "<linkset>"); } else { /* No alternative route found, NULL is returned. */ LOGPCLSET(clset, DLSS7, LOGL_INFO, "RT Lookup: %s -> eSLS=%u: " "Normal Route via '%s' unavailable, all Alternative Routes unavailable\n", - ss7_route_label_to_str(buf, sizeof(buf), inst, rtlabel), esls, + ss7_mtp3_rtlabel_to_str(buf, sizeof(buf), inst, mtp3_rtlb), esls, eslse->normal_rt->dest.as ? eslse->normal_rt->dest.as->cfg.name : "<linkset>"); } return rt; diff --git a/src/ss7_combined_linkset.h b/src/ss7_combined_linkset.h index e3756b6..8058b6a 100644 --- a/src/ss7_combined_linkset.h +++ b/src/ss7_combined_linkset.h @@ -10,7 +10,7 @@
struct osmo_ss7_instance; struct osmo_ss7_link; -struct osmo_ss7_route_label; +struct ss7_mtp3_rtlabel;
#define NUM_EXT_SLS 128 typedef uint8_t ext_sls_t; /* range: 0-127, 7 bit */ @@ -56,7 +56,7 @@ 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); +ss7_combined_linkset_lookup_route(struct osmo_ss7_combined_linkset *clset, const struct ss7_mtp3_rtlabel *mtp3_rtlb); bool ss7_combined_linkset_is_available(const struct osmo_ss7_combined_linkset *clset);
#define LOGPCLSET(clset, subsys, level, fmt, args ...) do { \ diff --git a/src/ss7_route.c b/src/ss7_route.c index d0a6c69..550bfae 100644 --- a/src/ss7_route.c +++ b/src/ss7_route.c @@ -461,8 +461,8 @@ return false; }
-bool ss7_route_is_available_for_rtlabel(const struct osmo_ss7_route *rt, - const struct osmo_ss7_route_label *rtlabel) +bool ss7_route_is_available_for_mtp3_rtlabel(const struct osmo_ss7_route *rt, + const struct ss7_mtp3_rtlabel *mtp3_rtlb) { if (!ss7_route_dest_is_available(rt)) return false; @@ -470,11 +470,13 @@ struct osmo_ss7_as *as = rt->dest.as; OSMO_ASSERT(as); struct osmo_ss7_routing_key *rkey = &as->cfg.routing_key; - if (rtlabel->dpc != rkey->pc) + if (mtp3_rtlb->rtlabel.dpc != rkey->pc) return false; - if ((rtlabel->opc & rkey->opc_mask) != rkey->opc) + if ((mtp3_rtlb->rtlabel.opc & rkey->opc_mask) != rkey->opc) return false; - /* TODO: match rkey->si */ + if (rkey->si != OSSMO_SS7_RKEY_SI_UNSET && + MTP_SIO_SI(mtp3_rtlb->sio) != rkey->si) + return false; /* TODO: match rkey->ssn */ } return true; diff --git a/src/ss7_route.h b/src/ss7_route.h index fa6bdc9..04edb8c 100644 --- a/src/ss7_route.h +++ b/src/ss7_route.h @@ -10,7 +10,7 @@
struct osmo_ss7_instance; struct osmo_ss7_route_table; -struct osmo_ss7_route_label; +struct ss7_mtp3_rtlabel; struct osmo_ss7_linkset; struct osmo_ss7_as;
@@ -77,8 +77,8 @@
bool ss7_route_dest_is_available(const struct osmo_ss7_route *rt); bool ss7_route_is_available(const struct osmo_ss7_route *rt); -bool ss7_route_is_available_for_rtlabel(const struct osmo_ss7_route *rt, - const struct osmo_ss7_route_label *rtlabel); +bool ss7_route_is_available_for_mtp3_rtlabel(const struct osmo_ss7_route *rt, + const struct ss7_mtp3_rtlabel *mtp3_rtlb);
bool ss7_route_is_fully_qualified(const struct osmo_ss7_route *rt); static inline bool ss7_route_is_summary(const struct osmo_ss7_route *rt) diff --git a/src/ss7_route_table.c b/src/ss7_route_table.c index 9523d99..b115c24 100644 --- a/src/ss7_route_table.c +++ b/src/ss7_route_table.c @@ -361,7 +361,7 @@ llist_for_each_entry(clset, &rtbl->combined_linksets, list) { if ((rtlb.rtlabel.dpc & clset->cfg.mask) != clset->cfg.pc) continue; - rt = ss7_combined_linkset_lookup_route(clset, &rtlb.rtlabel); + rt = ss7_combined_linkset_lookup_route(clset, &rtlb); if (!rt) continue; return rt; diff --git a/src/ss7_vty.c b/src/ss7_vty.c index 2127958..e53f36f 100644 --- a/src/ss7_vty.c +++ b/src/ss7_vty.c @@ -736,19 +736,21 @@ }
DEFUN(show_cs7_route_lookup, show_cs7_route_lookup_cmd, - "show cs7 instance <0-15> route-lookup POINT_CODE from POINT_CODE sls <0-15> [list-asps]", + "show cs7 instance <0-15> route-lookup POINT_CODE from POINT_CODE sls <0-15> si <0-15> [list-asps]", SHOW_STR CS7_STR INST_STR INST_STR "Look up route\n" "Destination PC\n" "From\n" "Origin PC\n" "SLS\n" "SLS value\n" + "Service Indicator\n" "SI value\n" "List ASPs of the AS if route points to an AS") { int id = atoi(argv[0]); - bool list_asps = argc > 4; + bool list_asps = argc > 5; struct osmo_ss7_instance *inst; struct osmo_ss7_route *rt; struct ss7_mtp3_rtlabel mtp3_rtlb = {}; int pc; + int si;
inst = osmo_ss7_instance_find(id); if (!inst) { @@ -769,16 +771,16 @@ return CMD_WARNING; } mtp3_rtlb.rtlabel.opc = pc; - mtp3_rtlb.rtlabel.sls = atoi(argv[3]);
- /* TODO: set mtp3_rtlb.sio through VTY param once we use it during route lookup below: */ + si = atoi(argv[4]); + mtp3_rtlb.sio = MTP_SIO(si, inst->cfg.network_indicator);
rt = ss7_instance_lookup_route(inst, &mtp3_rtlb); if (!rt) { char buf[256]; vty_out(vty, "No route found for label '%s'%s", - ss7_route_label_to_str(buf, sizeof(buf), inst, &mtp3_rtlb.rtlabel), VTY_NEWLINE); + ss7_mtp3_rtlabel_to_str(buf, sizeof(buf), inst, &mtp3_rtlb), VTY_NEWLINE); return CMD_WARNING; }
diff --git a/tests/vty/osmo_stp_route_prio.vty b/tests/vty/osmo_stp_route_prio.vty index 2422043..a40e6f8 100644 --- a/tests/vty/osmo_stp_route_prio.vty +++ b/tests/vty/osmo_stp_route_prio.vty @@ -274,5 +274,5 @@ 127 - - - -
OsmoSTP(config-cs7-rt)# ! NOW TEST LOOKUP FAILS AS EXPECTED (all route links are down): -OsmoSTP(config-cs7-rt)# do show cs7 instance 0 route-lookup 3.2.1 from 0.0.1 sls 0 -No route found for label 'OPC=1=0.0.1,DPC=6161=3.2.1,SLS=0' +OsmoSTP(config-cs7-rt)# do show cs7 instance 0 route-lookup 3.2.1 from 0.0.1 sls 0 si 3 +No route found for label 'OPC=1=0.0.1,DPC=6161=3.2.1,SLS=0,SIO=3=sccp'