pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmo-sigtran/+/40543?usp=email )
Change subject: Differentiate between dynamic and static routes ......................................................................
Differentiate between dynamic and static routes
Differentiation is important because for instance * It shall not be possible to delete dynamic routes over VTY "remove route" command. * Dynamic routes should not be stored in config, ie. not appear during "show running-config" or "write running-config". * During VTY "show cs7 instance 0 route", a "dyn" string keyword sohuld be displayed on each dynamic route row.
Related: OS#6755 Change-Id: Ic6c6b46084a1e4063ebf1f5d13e0e03386bb4c45 --- M src/sccp_user.c M src/ss7_as_vty.c M src/ss7_route.c M src/ss7_route.h M src/ss7_route_table.c M src/ss7_route_table.h M src/ss7_vty.c M src/xua_as_fsm.c M src/xua_rkm.c M tests/ss7/ss7_test.c M tests/vty/osmo_stp_route_prio.vty 11 files changed, 76 insertions(+), 47 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmo-sigtran refs/changes/43/40543/1
diff --git a/src/sccp_user.c b/src/sccp_user.c index 18561c4..bf92c1a 100644 --- a/src/sccp_user.c +++ b/src/sccp_user.c @@ -618,12 +618,12 @@ LOGP(DLSCCP, LOGL_NOTICE, "%s: Using AS instance %s\n", name, as->cfg.name);
- /* Create a default route if necessary */ - rt = ss7_route_table_find_route_by_dpc_mask(ss7->rtable_system, 0, 0); + /* Create a default dynamic route if necessary */ + rt = ss7_route_table_find_route_by_dpc_mask(ss7->rtable_system, 0, 0, true); if (!rt) { LOGP(DLSCCP, LOGL_NOTICE, "%s: Creating default route\n", name); rt = ss7_route_create(ss7->rtable_system, 0, 0, - as->cfg.name); + true, as->cfg.name); if (!rt) goto out_as; rt_created = true; @@ -867,7 +867,7 @@ goto out_strings;
/* route only selected PC to the client */ - rt = ss7_route_create(ss7->rtable_system, pc, 0xffff, as_name); + rt = ss7_route_create(ss7->rtable_system, pc, 0xffff, true, as_name); if (!rt) goto out_as;
diff --git a/src/ss7_as_vty.c b/src/ss7_as_vty.c index c7658d1..c34bbed 100644 --- a/src/ss7_as_vty.c +++ b/src/ss7_as_vty.c @@ -299,12 +299,14 @@
/* When libosmo-sigtran is used in ASP role, the VTY routing table node * (config-cs7-rt) is not available. However, when we add a routing key - * to an AS we still have to put a matching route into the routing - * table. This is done automatically by first removing the old route + * to an AS we still have to put a matching dynamic route into the routing + * table. This is done automatically by first removing the old dynamic route * (users may change the routing key via VTY during runtime) and then - * putting a new route (see below). */ + * putting a new dynamic route (see below). */ if (cs7_role == CS7_ROLE_ASP) { - rt = ss7_route_table_find_route_by_dpc_mask(as->inst->rtable_system, rkey->pc, 0xffffff); + rt = ss7_route_table_find_route_by_dpc_mask(as->inst->rtable_system, + rkey->pc, 0xffffff, + true); if (rt) ss7_route_destroy(rt); } @@ -315,9 +317,9 @@ rkey->si = si ? get_string_value(mtp_si_vals, si) : 0; /* FIXME: input validation */ rkey->ssn = ssn ? atoi(ssn) : 0; /* FIXME: input validation */
- /* automatically add new route (see also comment above) */ + /* automatically add new dynamic route (see also comment above) */ if (cs7_role == CS7_ROLE_ASP) { - if (!ss7_route_create(as->inst->rtable_system, rkey->pc, 0xffffff, as->cfg.name)) { + if (!ss7_route_create(as->inst->rtable_system, rkey->pc, 0xffffff, true, as->cfg.name)) { vty_out(vty, "Cannot create route (pc=%s, linkset=%s) to AS %s", dpc, as->cfg.name, VTY_NEWLINE); return CMD_WARNING; } diff --git a/src/ss7_route.c b/src/ss7_route.c index 6350f71..cfcbd8a 100644 --- a/src/ss7_route.c +++ b/src/ss7_route.c @@ -42,6 +42,7 @@ * \param[in] rtbl Routing Table where the route belongs * \param[in] pc Point Code of the destination of the route * \param[in] mask Mask of the destination Point Code \ref pc + * \param[in] dynamic Whether the route is dynamic * \returns Allocated route (not yet inserted into its rtbl), NULL on error * * The returned route has no linkset associated yet, user *must* associate it @@ -58,9 +59,14 @@ * The route entry allocated with this API can be destroyed/freed at any point using API * ss7_route_destroy(), regardless of it being already inserted or not in * its routing table. + * + * Dynamic routes are not configured by the user (VTY), and hence cannot be + * removed by the user. Dynamic routes are not stored in the config and hence + * they don't show up in eg "show running-confing"; they can be listed using + * specific VTY commands like "show cs7 instance 0 route". */ struct osmo_ss7_route * -ss7_route_alloc(struct osmo_ss7_route_table *rtbl, uint32_t pc, uint32_t mask) +ss7_route_alloc(struct osmo_ss7_route_table *rtbl, uint32_t pc, uint32_t mask, bool dynamic) { struct osmo_ss7_route *rt;
@@ -78,6 +84,7 @@ rt->cfg.mask = osmo_ss7_pc_normalize(&rtbl->inst->cfg.pc_fmt, mask); rt->cfg.pc = osmo_ss7_pc_normalize(&rtbl->inst->cfg.pc_fmt, pc); rt->cfg.priority = OSMO_SS7_ROUTE_PRIO_DEFAULT; + rt->cfg.dyn_allocated = dynamic; return rt; }
@@ -160,7 +167,8 @@ if (clset) { /* check for duplicates */ struct osmo_ss7_route *prev_rt; llist_for_each_entry(prev_rt, &clset->routes, list) { - if (!strcmp(prev_rt->cfg.linkset_name, rt->cfg.linkset_name)) { + if (strcmp(prev_rt->cfg.linkset_name, rt->cfg.linkset_name) == 0 && + prev_rt->cfg.dyn_allocated == rt->cfg.dyn_allocated) { LOGSS7(rtbl->inst, LOGL_ERROR, "Refusing to create route with existing linkset name: pc=%u=%s mask=0x%x via linkset/AS '%s'\n", rt->cfg.pc, osmo_ss7_pointcode_print(rtbl->inst, rt->cfg.pc), @@ -181,6 +189,7 @@ * \param[in] rtbl Routing Table in which the route is to be created * \param[in] pc Point Code of the destination of the route * \param[in] mask Mask of the destination Point Code \ref pc + * \param[in] dynamic Whether the route is dynamic * \param[in] linkset_name string name of the linkset to be used * \returns callee-allocated + initialized route, NULL on error * @@ -192,12 +201,12 @@ */ struct osmo_ss7_route * ss7_route_create(struct osmo_ss7_route_table *rtbl, uint32_t pc, - uint32_t mask, const char *linkset_name) + uint32_t mask, bool dynamic, const char *linkset_name) { struct osmo_ss7_route *rt; int rc;
- rt = ss7_route_alloc(rtbl, pc, mask); + rt = ss7_route_alloc(rtbl, pc, mask, dynamic); if (!rt) return NULL;
@@ -210,7 +219,7 @@ /* Keep old behavior, return already existing route: */ if (rc == -EADDRINUSE) { talloc_free(rt); - return ss7_route_table_find_route_by_dpc_mask(rtbl, pc, mask); + return ss7_route_table_find_route_by_dpc_mask(rtbl, pc, mask, dynamic); }
return rt; @@ -309,8 +318,11 @@ } while (0)
APPEND("pc=%u=%s mask=0x%x=%s", - rt->cfg.pc, osmo_ss7_pointcode_print_buf(pc_str, sizeof(pc_str), inst, rt->cfg.pc), - rt->cfg.mask, osmo_ss7_pointcode_print_buf(mask_str, sizeof(mask_str), inst, rt->cfg.mask)); + rt->cfg.pc, osmo_ss7_pointcode_print_buf(pc_str, sizeof(pc_str), inst, rt->cfg.pc), + rt->cfg.mask, osmo_ss7_pointcode_print_buf(mask_str, sizeof(mask_str), inst, rt->cfg.mask)); + + if (rt->cfg.dyn_allocated) + APPEND(" dyn");
if (rt->dest.as) { struct osmo_ss7_as *as = rt->dest.as; diff --git a/src/ss7_route.h b/src/ss7_route.h index 0dcc34e..4bb7a2b 100644 --- a/src/ss7_route.h +++ b/src/ss7_route.h @@ -1,6 +1,7 @@ #pragma once
#include <stdint.h> +#include <stdbool.h> #include <osmocom/core/linuxlist.h>
/*********************************************************************** @@ -38,14 +39,15 @@ /*! lower priority is higher */ uint32_t priority; uint8_t qos_class; + bool dyn_allocated; } cfg; };
struct osmo_ss7_route * -ss7_route_alloc(struct osmo_ss7_route_table *rtbl, uint32_t pc, uint32_t mask); +ss7_route_alloc(struct osmo_ss7_route_table *rtbl, uint32_t pc, uint32_t mask, bool dynamic); struct osmo_ss7_route * ss7_route_create(struct osmo_ss7_route_table *rtbl, uint32_t dpc, - uint32_t mask, const char *linkset_name); + uint32_t mask, bool dynamic, const char *linkset_name); void ss7_route_destroy(struct osmo_ss7_route *rt);
struct osmo_ss7_route * diff --git a/src/ss7_route_table.c b/src/ss7_route_table.c index d2f34a6..5d044f3 100644 --- a/src/ss7_route_table.c +++ b/src/ss7_route_table.c @@ -110,7 +110,7 @@ */ struct osmo_ss7_route * ss7_route_table_find_route_by_dpc_mask(struct osmo_ss7_route_table *rtbl, uint32_t dpc, - uint32_t mask) + uint32_t mask, bool dynamic) { struct osmo_ss7_combined_linkset *clset; struct osmo_ss7_route *rt; @@ -123,8 +123,12 @@ clset = ss7_route_table_find_combined_linkset_by_dpc_mask(rtbl, dpc, mask); if (!clset) return NULL; - rt = llist_first_entry_or_null(&clset->routes, struct osmo_ss7_route, list); - return rt; + llist_for_each_entry(rt, &clset->routes, list) { + if (rt->cfg.dyn_allocated != dynamic) + continue; + return rt; + } + return NULL; }
struct osmo_ss7_combined_linkset * diff --git a/src/ss7_route_table.h b/src/ss7_route_table.h index 1de3be5..9f27412 100644 --- a/src/ss7_route_table.h +++ b/src/ss7_route_table.h @@ -39,7 +39,7 @@
struct osmo_ss7_route * ss7_route_table_find_route_by_dpc_mask(struct osmo_ss7_route_table *rtbl, uint32_t dpc, - uint32_t mask); + uint32_t mask, bool dynamic); struct osmo_ss7_route * ss7_route_table_lookup_route(struct osmo_ss7_route_table *rtbl, const struct osmo_ss7_route_label *rtlabel);
diff --git a/src/ss7_vty.c b/src/ss7_vty.c index 66efc03..a5f5310 100644 --- a/src/ss7_vty.c +++ b/src/ss7_vty.c @@ -398,7 +398,7 @@ return CMD_WARNING; }
- rt = ss7_route_alloc(rtable, dpc, mask); + rt = ss7_route_alloc(rtable, dpc, mask, false); if (!rt) { vty_out(vty, "%% Cannot allocate new route%s", VTY_NEWLINE); return CMD_WARNING; @@ -464,7 +464,7 @@ return CMD_WARNING; }
- rt = ss7_route_table_find_route_by_dpc_mask(rtable, dpc, mask); + rt = ss7_route_table_find_route_by_dpc_mask(rtable, dpc, mask, false); if (!rt) { vty_out(vty, "cannot find route to be deleted%s", VTY_NEWLINE); return CMD_WARNING; @@ -484,6 +484,8 @@ vty_out(vty, " description %s%s", rtable->cfg.description, VTY_NEWLINE); llist_for_each_entry(clset, &rtable->combined_linksets, list) { llist_for_each_entry(rt, &clset->routes, list) { + if (rt->cfg.dyn_allocated) + continue; vty_out(vty, " update route %s %s linkset %s", osmo_ss7_pointcode_print(rtable->inst, rt->cfg.pc), osmo_ss7_pointcode_print2(rtable->inst, rt->cfg.mask), @@ -516,7 +518,7 @@ llist_for_each_entry(rt, &clset->routes, list) { bool rt_avail = ss7_route_is_available(rt);
- vty_out(vty, "%-16s %-5s %c %c %u %-19s %-7s %-7s %-7s%s", + vty_out(vty, "%-16s %-5s %c %c %u %-19s %-7s %-7s %-7s%-3s%s", osmo_ss7_route_print(rt), rt_avail ? "acces" : "INACC", ' ', @@ -526,6 +528,7 @@ rt_avail ? "avail" : "UNAVAIL", "?", rt_avail ? "avail" : "UNAVAIL", + rt->cfg.dyn_allocated ? "dyn" : "", VTY_NEWLINE); } } diff --git a/src/xua_as_fsm.c b/src/xua_as_fsm.c index 3e117ee..6a8941b 100644 --- a/src/xua_as_fsm.c +++ b/src/xua_as_fsm.c @@ -277,12 +277,14 @@ struct osmo_ss7_as *as = xafp->as; struct osmo_ss7_instance *inst = as->inst;
- if (ss7_route_table_find_route_by_dpc_mask(inst->rtable_system, as->cfg.routing_key.pc, 0xffffff)) + if (ss7_route_table_find_route_by_dpc_mask(inst->rtable_system, + as->cfg.routing_key.pc, 0xffffff, + true)) return;
/* As opposed to M3UA, there is no RKM and we have to implicitly - * automatically add a route once an IPA connection has come up */ - if (ss7_route_create(inst->rtable_system, as->cfg.routing_key.pc, 0xffffff, as->cfg.name)) + * automatically add a dynamic route once an IPA connection has come up */ + if (ss7_route_create(inst->rtable_system, as->cfg.routing_key.pc, 0xffffff, true, as->cfg.name)) xafp->ipa_route_created = true; }
@@ -298,7 +300,9 @@ return;
/* find the route which we have created if we ever reached ipa_asp_fsm_wait_id_ack2 */ - rt = ss7_route_table_find_route_by_dpc_mask(inst->rtable_system, as->cfg.routing_key.pc, 0xffffff); + rt = ss7_route_table_find_route_by_dpc_mask(inst->rtable_system, + as->cfg.routing_key.pc, 0xffffff, + true); /* no route found, bail out */ if (!rt) { LOGPFSML(fi, LOGL_NOTICE, "Attempting to delete route for this IPA AS, but cannot " diff --git a/src/xua_rkm.c b/src/xua_rkm.c index 1ae5ea6..f03397c 100644 --- a/src/xua_rkm.c +++ b/src/xua_rkm.c @@ -279,8 +279,8 @@ as->cfg.routing_key.pc = dpc; as->cfg.routing_key.context = rctx;
- /* add route for that routing key */ - rt = ss7_route_create(as->inst->rtable_system, dpc, 0xFFFFFF, namebuf); + /* add dynamic route for that routing key */ + rt = ss7_route_create(as->inst->rtable_system, dpc, 0xFFFFFF, true, namebuf); if (!rt) { LOGPASP(asp, DLSS7, LOGL_ERROR, "RKM: Cannot insert route for DPC %s / as %s\n", osmo_ss7_pointcode_print(asp->inst, dpc), namebuf); @@ -393,7 +393,9 @@ return -1; }
- rt = ss7_route_table_find_route_by_dpc_mask(inst->rtable_system, as->cfg.routing_key.pc, 0xffffff); + rt = ss7_route_table_find_route_by_dpc_mask(inst->rtable_system, + as->cfg.routing_key.pc, 0xffffff, + true); if (!rt) { msgb_append_dereg_res(resp, M3UA_RKM_DEREG_ERR_UNKNOWN, 0); return -1; diff --git a/tests/ss7/ss7_test.c b/tests/ss7/ss7_test.c index bb96e71..c8e1c67 100644 --- a/tests/ss7/ss7_test.c +++ b/tests/ss7/ss7_test.c @@ -188,7 +188,7 @@ /* route with full mask */ 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"); + rt = ss7_route_create(rtbl, 12, 0xffff, false, "a"); printf("route with full mask: %s\n", osmo_ss7_route_print(rt)); OSMO_ASSERT(rt); route_label = RT_LABEL(0, 12, 0); @@ -196,7 +196,7 @@ ss7_route_destroy(rt);
/* route with partial mask */ - rt = ss7_route_create(rtbl, 8, 0xfff8, "a"); + rt = ss7_route_create(rtbl, 8, 0xfff8, false, "a"); printf("route with partial mask: %s\n", osmo_ss7_route_print(rt)); route_label = RT_LABEL(0, 8, 0); OSMO_ASSERT(ss7_route_table_lookup_route(rtbl, &route_label) == rt); @@ -210,7 +210,7 @@ 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"); + rt12 = ss7_route_create(rtbl, 12, 0xffff, false, "b"); 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); @@ -218,7 +218,7 @@ 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"); + rtdef = ss7_route_create(rtbl, 0, 0, false, "a"); 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); @@ -230,7 +230,7 @@ ss7_route_destroy(rt12); ss7_route_destroy(rt);
- rt = ss7_route_create(rtbl, 8, 0xfff9, "a"); + rt = ss7_route_create(rtbl, 8, 0xfff9, false, "a"); printf("route with non-consecutive mask: %s\n", osmo_ss7_route_print(rt)); ss7_route_destroy(rt);
diff --git a/tests/vty/osmo_stp_route_prio.vty b/tests/vty/osmo_stp_route_prio.vty index 1a3b516..1db0a19 100644 --- a/tests/vty/osmo_stp_route_prio.vty +++ b/tests/vty/osmo_stp_route_prio.vty @@ -92,9 +92,9 @@
Destination C Q P Linkset Name Linkset Non-adj Route ---------------------- - - - ------------------- ------- ------- ------- -3.2.1/14 INACC 0 2 as3 UNAVAIL ? UNAVAIL -3.2.1/14 INACC 0 5 as2 UNAVAIL ? UNAVAIL -3.2.1/14 INACC 7 6 as1 UNAVAIL ? UNAVAIL +3.2.1/14 INACC 0 2 as3 UNAVAIL ? UNAVAIL +3.2.1/14 INACC 0 5 as2 UNAVAIL ? UNAVAIL +3.2.1/14 INACC 7 6 as1 UNAVAIL ? UNAVAIL
OsmoSTP(config-cs7-rt)# ! NOW ADD MORE GENERIC ROUTES (SMALLER BITMASK LENGTH) OsmoSTP(config-cs7-rt)# update route 3.2.0 7.255.0 linkset as1 priority 1 @@ -118,12 +118,12 @@
Destination C Q P Linkset Name Linkset Non-adj Route ---------------------- - - - ------------------- ------- ------- ------- -3.2.1/14 INACC 0 2 as3 UNAVAIL ? UNAVAIL -3.2.1/14 INACC 0 5 as2 UNAVAIL ? UNAVAIL -3.2.1/14 INACC 7 6 as1 UNAVAIL ? UNAVAIL -3.2.0/11 INACC 0 1 as1 UNAVAIL ? UNAVAIL -3.2.0/11 INACC 0 1 as2 UNAVAIL ? UNAVAIL -3.2.0/11 INACC 0 1 as3 UNAVAIL ? UNAVAIL +3.2.1/14 INACC 0 2 as3 UNAVAIL ? UNAVAIL +3.2.1/14 INACC 0 5 as2 UNAVAIL ? UNAVAIL +3.2.1/14 INACC 7 6 as1 UNAVAIL ? UNAVAIL +3.2.0/11 INACC 0 1 as1 UNAVAIL ? UNAVAIL +3.2.0/11 INACC 0 1 as2 UNAVAIL ? UNAVAIL +3.2.0/11 INACC 0 1 as3 UNAVAIL ? UNAVAIL
OsmoSTP(config-cs7-rt)# do show cs7 instance 0 route binding-table 3.2.1