pespin has submitted this change. ( 
https://gerrit.osmocom.org/c/libosmo-sigtran/+/39391?usp=email )

Change subject: AS loadsharing: Implement AS loadshare, skip unavailable 
AS/lset when choosing
......................................................................

AS loadsharing: Implement AS loadshare, skip unavailable AS/lset when choosing

Pick normal route containing destination AS/lset to serve a given
func(<OPC,DPC,SLS>)=eSLS on a round-robin base.
If normal route becomes unavailable, pick an alternative route in a
similar way. This alternative route will be used until itself becomes
unavailable or the normal route becomes available again.

Related: SYS#7112
Change-Id: I928fb1ef5db6922f1386a188e3fbf9e70780f25d
---
M src/osmo_ss7_combined_linkset.c
M src/osmo_ss7_hmrt.c
M src/ss7_combined_linkset.h
M src/xua_snm.c
M tests/ss7/ss7_test.c
M tests/vty/osmo_stp_route_prio.vty
6 files changed, 67 insertions(+), 21 deletions(-)

Approvals:
  Jenkins Builder: Verified
  pespin: Looks good to me, approved
  osmith: Looks good to me, but someone else must approve




diff --git a/src/osmo_ss7_combined_linkset.c b/src/osmo_ss7_combined_linkset.c
index 90a54f6..99b0c79 100644
--- a/src/osmo_ss7_combined_linkset.c
+++ b/src/osmo_ss7_combined_linkset.c
@@ -49,6 +49,20 @@
  * link set) or of an alternative link set (combined link set)."
  *****************************************************************************/

+static inline struct llist_head *_ss7_llist_round_robin(struct llist_head 
*list, void **state)
+{
+       struct llist_head *e = *state;
+       if (!e || e->next == list)
+               e = list;
+       e = e->next;
+       if (e == list)
+               e = NULL;
+       *state = e;
+       return e;
+}
+#define ss7_llist_round_robin(list, state, struct_type, entry_name) \
+       llist_entry(_ss7_llist_round_robin(list, state), struct_type, 
entry_name)
+
 /*! \brief Insert combined_link into its routing table
  *  \param[in] clset Combined link to be inserted into its routing table
  *  \returns 0 on success, negative on error
@@ -135,6 +149,14 @@
                        clset->esls_table[i].alt_rt = NULL;
        }

+       /* Update round robin state */
+       if (rt == clset->last_route_roundrobin) {
+               ss7_llist_round_robin(&clset->routes, 
&clset->last_route_roundrobin, struct osmo_ss7_route, list);
+               /* If there's only one left, remove state: */
+               if (rt == clset->last_route_roundrobin)
+                       clset->last_route_roundrobin = NULL;
+       }
+
        llist_del(&rt->list);
        rt->clset = NULL;
        clset->num_routes--;
@@ -172,6 +194,27 @@
        return NULL;
 }

+static struct osmo_ss7_route 
*ss7_combined_linkset_select_route_roundrobin(struct osmo_ss7_combined_linkset 
*clset)
+{
+       struct osmo_ss7_route *rt;
+       struct osmo_ss7_route *rt_found = NULL;
+       unsigned int i = 0;
+
+       while (i < clset->num_routes) {
+               i++;
+               rt = ss7_llist_round_robin(&clset->routes, 
&clset->last_route_roundrobin, struct osmo_ss7_route, list);
+               if (ss7_route_is_available(rt)) {
+                       rt_found = rt;
+                       break;
+               }
+       }
+
+       if (!rt_found)
+               return NULL;
+
+       return rt_found;
+}
+
 struct osmo_ss7_route *
 ss7_combined_linkset_lookup_route(struct osmo_ss7_combined_linkset *clset, 
const struct osmo_ss7_route_label *rtlabel)
 {
@@ -192,20 +235,20 @@
                return rt;
        }

-       /* TODO: Check if the AS/linkset in rt is actually UP and can be
-       * used, otherwise start ITU Q.704 section 7 "forced rerouting" 
prcoedure:
-       * we need to pick a temporary dst (update the esls_table entry) while 
the
-       * original one is DOWN. */
+       /* No current route available, try to find a new current route: */

-       /* We need to pick a new AS/linkset from the combined linkset and cache
-        * it so it is always used for this eSLS: */
-       /* FIXME: for now we simply take the first AS in the combined linksed, 
to be improved later... */
-       rt = llist_first_entry_or_null(&clset->routes, struct osmo_ss7_route, 
list);
+       /* No normal route selected yet: */
+       if (!eslse->normal_rt) {
+               rt = ss7_combined_linkset_select_route_roundrobin(clset);
+               /* Either a normal route was selected or none found: */
+               eslse->normal_rt = rt;
+               return rt;
+       }

-       /* TODO: here we'd need to actually check if dst AS/linkset in the route
-        * is actually UP, otherwise pick next one in the roundrobin list... */
+       /* 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);
        if (rt)
-               clset->esls_table[esls].normal_rt = rt;
-
+               eslse->alt_rt = rt;
        return rt;
 }
diff --git a/src/osmo_ss7_hmrt.c b/src/osmo_ss7_hmrt.c
index 1e000b4..72d5adc 100644
--- a/src/osmo_ss7_hmrt.c
+++ b/src/osmo_ss7_hmrt.c
@@ -180,12 +180,6 @@
                                       dpc, osmo_ss7_pointcode_print(inst, 
dpc), rt_name);
                        }

-                       if (osmo_ss7_as_down(as)) {
-                               LOGP(DLSS7, LOGL_ERROR, "Unable to route HMRT 
message: the AS %s is down\n",
-                                    as->cfg.name);
-                               return -ENETDOWN;
-                       }
-
                        rate_ctr_inc2(as->ctrg, SS7_AS_CTR_TX_MSU_TOTAL);

                        switch (as->cfg.proto) {
diff --git a/src/ss7_combined_linkset.h b/src/ss7_combined_linkset.h
index e2f9c9d..b80a007 100644
--- a/src/ss7_combined_linkset.h
+++ b/src/ss7_combined_linkset.h
@@ -33,6 +33,7 @@
        /*! list of \ref osmo_ss7_route */
        struct llist_head routes;
        unsigned int num_routes;
+       void *last_route_roundrobin;

        struct {
                uint32_t pc;
diff --git a/src/xua_snm.c b/src/xua_snm.c
index acdfe0c..1481178 100644
--- a/src/xua_snm.c
+++ b/src/xua_snm.c
@@ -347,7 +347,7 @@
                                .sls = 0,
                        };

-                       /* FIXME: don't just check for a route; but also check 
if the route is "active" */
+                       /* Check if there's an "active" route available: */
                        if (ss7_instance_lookup_route(s7i, &rtlabel))
                                is_available = true;

diff --git a/tests/ss7/ss7_test.c b/tests/ss7/ss7_test.c
index 95fa1b1..f61ee0a 100644
--- a/tests/ss7/ss7_test.c
+++ b/tests/ss7/ss7_test.c
@@ -154,6 +154,7 @@
 {
        struct osmo_ss7_route_table *rtbl;
        struct osmo_ss7_linkset *lset_a, *lset_b;
+       struct osmo_ss7_link *l_a, *l_b;
        struct osmo_ss7_route *rt, *rt12, *rtdef;
        struct osmo_ss7_route_label route_label;

@@ -173,8 +174,15 @@

        lset_a = ss7_linkset_find_or_create(s7i, "a", 100);
        OSMO_ASSERT(lset_a);
+       l_a = ss7_link_find_or_create(lset_a, 0);
+       OSMO_ASSERT(l_a);
+       l_a->cfg.adm_state = OSMO_SS7_LS_ENABLED;
+
        lset_b = ss7_linkset_find_or_create(s7i, "b", 200);
        OSMO_ASSERT(lset_b);
+       l_b = ss7_link_find_or_create(lset_b, 0);
+       OSMO_ASSERT(l_b);
+       l_b->cfg.adm_state = OSMO_SS7_LS_ENABLED;

        /* route with full mask */
        route_label = RT_LABEL(0, 12, 0);
diff --git a/tests/vty/osmo_stp_route_prio.vty 
b/tests/vty/osmo_stp_route_prio.vty
index 6f60d9a..2b7cec6 100644
--- a/tests/vty/osmo_stp_route_prio.vty
+++ b/tests/vty/osmo_stp_route_prio.vty
@@ -87,6 +87,6 @@
 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 TEST LOOKUP WORKS AS DESIRED (as3 PICKED):
+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
-pc=6161=3.2.1 mask=0x3fff=7.255.7 via AS as3 proto=m3ua
+No route found for label 'OPC=1=0.0.1,DPC=6161=3.2.1,SLS=0'

--
To view, visit https://gerrit.osmocom.org/c/libosmo-sigtran/+/39391?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings?usp=email

Gerrit-MessageType: merged
Gerrit-Project: libosmo-sigtran
Gerrit-Branch: master
Gerrit-Change-Id: I928fb1ef5db6922f1386a188e3fbf9e70780f25d
Gerrit-Change-Number: 39391
Gerrit-PatchSet: 11
Gerrit-Owner: pespin <[email protected]>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: osmith <[email protected]>
Gerrit-Reviewer: pespin <[email protected]>
Gerrit-CC: laforge <[email protected]>

Reply via email to