From 99beede80cc054ac84c80d90a3aa7330cd519076 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Wed, 13 Mar 2019 00:33:06 +0100 Subject: Fix output of route destination in 'show ss7 instance <0-15> route' We were printing the mask of the route, but not the point code itself. Best would probably be to print both? Closes: OS#3835 Change-Id: Ifa4fdbad953d40f222beb470a082eed8c20991ef --- include/osmocom/sigtran/osmo_ss7.h | 1 + src/osmo_ss7.c | 42 ++++++++++++++++++++++++++++++++++++++ src/osmo_ss7_vty.c | 2 +- tests/ss7/ss7_test.c | 6 ++++++ tests/ss7/ss7_test.ok | 3 +++ 5 files changed, 53 insertions(+), 1 deletion(-) diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index a97e236..f448ce7 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -238,6 +238,7 @@ struct osmo_ss7_route * osmo_ss7_route_create(struct osmo_ss7_route_table *rtbl, uint32_t dpc, uint32_t mask, const char *linkset_name); void osmo_ss7_route_destroy(struct osmo_ss7_route *rt); +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); diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index f8633b6..e8a6918 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -838,6 +838,48 @@ void osmo_ss7_route_destroy(struct osmo_ss7_route *rt) talloc_free(rt); } +/* count number of consecutive leading (MSB) bits that are '1' */ +static unsigned int count_leading_one_bits(uint32_t inp, unsigned int nbits) +{ + unsigned int i; + + for (i = 0; i < nbits; i++) { + if (!(inp & (1 << (nbits-1-i)))) + return i; + } + return i; +} + +/* determine the mask length in number of bits; negative if non-consecutive mask */ +static int u32_masklen(uint32_t mask, unsigned int nbits) +{ + unsigned int i; + unsigned int leading_one_bits = count_leading_one_bits(mask, nbits); + + /* are there any bits set after the initial bits? */ + for (i = leading_one_bits; i < nbits; i++) { + if (mask & (1 << (nbits-1-i))) + return -1; /* not a simple prefix mask */ + } + return leading_one_bits; +} + +const char *osmo_ss7_route_print(const struct osmo_ss7_route *rt) +{ + const struct osmo_ss7_instance *inst = rt->rtable->inst; + unsigned int pc_width = osmo_ss7_pc_width(&inst->cfg.pc_fmt); + static char buf[64]; + int rc = u32_masklen(rt->cfg.mask, pc_width); + + if (rc < 0) + snprintf(buf, sizeof(buf), "%s/%s", osmo_ss7_pointcode_print(inst, rt->cfg.pc), + osmo_ss7_pointcode_print2(inst, rt->cfg.mask)); + else + snprintf(buf, sizeof(buf), "%s/%u", osmo_ss7_pointcode_print(inst, rt->cfg.pc), rc); + return buf; +} + + /*********************************************************************** * SS7 Application Server ***********************************************************************/ diff --git a/src/osmo_ss7_vty.c b/src/osmo_ss7_vty.c index 950eb08..cc53b05 100644 --- a/src/osmo_ss7_vty.c +++ b/src/osmo_ss7_vty.c @@ -384,7 +384,7 @@ static void vty_dump_rtable(struct vty *vty, struct osmo_ss7_route_table *rtbl) llist_for_each_entry(rt, &rtbl->routes, list) { vty_out(vty, "%-22s %c %c %u %-19s %-7s %-7s %-7s%s", - osmo_ss7_pointcode_print(rtbl->inst, rt->cfg.mask), + osmo_ss7_route_print(rt), ' ', ' ', rt->cfg.priority, rt->cfg.linkset_name, "?", "?", "?", VTY_NEWLINE); } } diff --git a/tests/ss7/ss7_test.c b/tests/ss7/ss7_test.c index 0c0cf25..a3f47b6 100644 --- a/tests/ss7/ss7_test.c +++ b/tests/ss7/ss7_test.c @@ -162,12 +162,14 @@ static void test_route(void) /* route with full mask */ OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 12) == NULL); rt = osmo_ss7_route_create(rtbl, 12, 0xffff, "a"); + printf("route with full mask: %s\n", osmo_ss7_route_print(rt)); OSMO_ASSERT(rt); OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 12) == rt); osmo_ss7_route_destroy(rt); /* route with partial mask */ rt = osmo_ss7_route_create(rtbl, 8, 0xfff8, "a"); + printf("route with partial mask: %s\n", osmo_ss7_route_print(rt)); OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 8) == rt); OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 9) == rt); OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 12) == rt); @@ -189,6 +191,10 @@ static void test_route(void) osmo_ss7_route_destroy(rt12); osmo_ss7_route_destroy(rt); + rt = osmo_ss7_route_create(rtbl, 8, 0xfff9, "a"); + printf("route with non-consecutive mask: %s\n", osmo_ss7_route_print(rt)); + osmo_ss7_route_destroy(rt); + osmo_ss7_linkset_destroy(lset_a); osmo_ss7_linkset_destroy(lset_b); } diff --git a/tests/ss7/ss7_test.ok b/tests/ss7/ss7_test.ok index 8aea63d..1f8c0d8 100644 --- a/tests/ss7/ss7_test.ok +++ b/tests/ss7/ss7_test.ok @@ -24,4 +24,7 @@ mask /16 => 16776960 (0xffff00) 255-255-0 mask /24 => 16777215 (0xffffff) 255-255-255 Testing SS7 user Testing SS7 routing +route with full mask: 0.1.4/14 +route with partial mask: 0.1.0/11 +route with non-consecutive mask: 0.1.0/7.255.1 Testing SS7 linkset/link -- cgit v1.2.3