pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmo-sigtran/+/40560?usp=email )
Change subject: route_table: Introduce ss7_route_table_dpc_is_accessible() API ......................................................................
route_table: Introduce ss7_route_table_dpc_is_accessible() API
In some places we don't need to select/choose a specific route (hence requiring a loadshare decision and hence modifying state), but simply figure out whether there's an available route for a given rmeote PC.
Change-Id: Ia3b2eb17afae71dc7cec34b521693e776fa3576d --- M src/sccp_scrc.c M src/ss7_route_table.c M src/ss7_route_table.h M src/xua_snm.c 4 files changed, 29 insertions(+), 25 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmo-sigtran refs/changes/60/40560/1
diff --git a/src/sccp_scrc.c b/src/sccp_scrc.c index ebc9a11..d7a6428 100644 --- a/src/sccp_scrc.c +++ b/src/sccp_scrc.c @@ -70,9 +70,8 @@ static bool dpc_accessible(struct osmo_sccp_instance *inst, uint32_t dpc) { struct osmo_ss7_instance *ss7 = inst->ss7; - struct osmo_ss7_route *rt; - struct osmo_ss7_route_label rtlabel; char buf_dpc[MAX_PC_STR_LEN]; + bool found;
if (osmo_ss7_pc_is_local(ss7, dpc)) { LOGPSCI(inst, LOGL_DEBUG, "dpc_accessible(DPC=%u=%s): true (local)\n", @@ -80,22 +79,14 @@ return true; }
- rtlabel = (struct osmo_ss7_route_label){ - .opc = 0, - .dpc = dpc, - .sls = 0, - }; + found = ss7_route_table_dpc_is_accessible(ss7->rtable_system, dpc);
- rt = ss7_instance_lookup_route(ss7, &rtlabel); - if (!rt) { - LOGPSCI(inst, LOGL_INFO, "dpc_accessible(DPC=%u=%s): false\n", - dpc, osmo_ss7_pointcode_print_buf(buf_dpc, sizeof(buf_dpc), ss7, dpc)); - return false; - } + LOGPSCI(inst, found ? LOGL_DEBUG : LOGL_INFO, + "dpc_accessible(DPC=%u=%s): %s\n", + dpc, osmo_ss7_pointcode_print_buf(buf_dpc, sizeof(buf_dpc), ss7, dpc), + found ? "true" : "false"); + return found;
- LOGPSCI(inst, LOGL_DEBUG, "dpc_accessible(DPC=%u=%s): true\n", - dpc, osmo_ss7_pointcode_print_buf(buf_dpc, sizeof(buf_dpc), ss7, dpc)); - return true; }
static bool sccp_available(struct osmo_sccp_instance *inst, diff --git a/src/ss7_route_table.c b/src/ss7_route_table.c index bd7b305..16eb9bd 100644 --- a/src/ss7_route_table.c +++ b/src/ss7_route_table.c @@ -299,6 +299,8 @@ } }
+/* Choose a specific route to transmit a packet. + * Note: This function potentially modifies loadsharing state context of chosen combined linkset. */ struct osmo_ss7_route * ss7_route_table_lookup_route(const struct osmo_ss7_route_table *rtbl, const struct osmo_ss7_route_label *rtlabel) { @@ -322,3 +324,20 @@ } return NULL; } + +/* Figure out whether a remote PC is accessible over any route in the routing table. + * Note: Unlike ss7_route_table_lookup_route(), this function is read-only and doesn't modify any state. */ +bool ss7_route_table_dpc_is_accessible(const struct osmo_ss7_route_table *rtbl, uint32_t dpc) +{ + struct osmo_ss7_combined_linkset *clset; + /* 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 ((dpc & clset->cfg.mask) != clset->cfg.pc) + continue; + if (ss7_combined_linkset_is_available(clset)) + return true; + } + return false; +} diff --git a/src/ss7_route_table.h b/src/ss7_route_table.h index 5141c18..582a8d3 100644 --- a/src/ss7_route_table.h +++ b/src/ss7_route_table.h @@ -46,6 +46,7 @@ uint32_t mask, const struct osmo_ss7_as *as, bool dynamic); struct osmo_ss7_route * ss7_route_table_lookup_route(const struct osmo_ss7_route_table *rtbl, const struct osmo_ss7_route_label *rtlabel); +bool ss7_route_table_dpc_is_accessible(const struct osmo_ss7_route_table *rtbl, uint32_t dpc);
struct osmo_ss7_combined_linkset * ss7_route_table_find_combined_linkset(const struct osmo_ss7_route_table *rtbl, uint32_t dpc, uint32_t mask, uint32_t prio); diff --git a/src/xua_snm.c b/src/xua_snm.c index d4c9a75..207b042 100644 --- a/src/xua_snm.c +++ b/src/xua_snm.c @@ -375,16 +375,10 @@ uint8_t mask = _aff_pc >> 24; bool is_available;
- struct osmo_ss7_route_label rtlabel = { - .opc = xua->mtp.opc, /* Use OPC of received DAUD. */ - .dpc = pc, - .sls = 0, - }; - if (mask == 0) { /* one single point code */ /* Check if there's an "active" route available: */ - is_available = !!ss7_instance_lookup_route(s7i, &rtlabel); + is_available = ss7_route_table_dpc_is_accessible(s7i->rtable_system, pc);
xua_tx_snm_available(asp, rctx, num_rctx, &aff_pc[i], 1, "Response to DAUD", is_available); @@ -397,8 +391,7 @@ uint32_t *aff_pc_avail = talloc_size(asp, sizeof(uint32_t)*(1 << mask)); uint32_t *aff_pc_unavail = talloc_size(asp, sizeof(uint32_t)*(1 << mask)); for (fullpc = (pc & ~maskbits); fullpc <= (pc | maskbits); fullpc++) { - rtlabel.dpc = fullpc; - is_available = !!ss7_instance_lookup_route(s7i, &rtlabel); + is_available = ss7_route_table_dpc_is_accessible(s7i->rtable_system, fullpc); if (is_available) aff_pc_avail[num_aff_pc_avail++] = htonl(fullpc); /* mask = 0 */ else