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
--
To view, visit
https://gerrit.osmocom.org/c/libosmo-sigtran/+/40543?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: libosmo-sigtran
Gerrit-Branch: master
Gerrit-Change-Id: Ic6c6b46084a1e4063ebf1f5d13e0e03386bb4c45
Gerrit-Change-Number: 40543
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin(a)sysmocom.de>