<p>laforge has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/libosmo-sccp/+/23894">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">ipa: Move automatic route add/del from ASP to AS level<br><br>SS7 routes operate on AS level, not ASP level.  However, the<br>automatic SS7 route creation/destruction for IPA was implemented<br>at the ASP level.  This works for single-connection ASs, but<br>obviously fails in load-share situations:  We attempt to add the<br>same route several times, and we delete it at the first ASP<br>disconnect, even while other ASPs still exist.<br><br>This patch moves the IPA route creation/deletion from the ASP level<br>to the AS level.  When the AS becomes active, the route is added;<br>when it goes to DOWN state, it is removed.<br><br>Change-Id: Idb602beae3e9bc19f7bd96355c02ec8dfd9c5d6c<br>---<br>M src/xua_as_fsm.c<br>M src/xua_asp_fsm.c<br>2 files changed, 64 insertions(+), 55 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/94/23894/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/xua_as_fsm.c b/src/xua_as_fsm.c</span><br><span>index 7c791cf..f66ba88 100644</span><br><span>--- a/src/xua_as_fsm.c</span><br><span>+++ b/src/xua_as_fsm.c</span><br><span>@@ -202,6 +202,66 @@</span><br><span>         } recovery;</span><br><span> };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* is the given AS one with a single ASP of IPA type? */</span><br><span style="color: hsl(120, 100%, 40%);">+static bool is_single_ipa_asp(struct osmo_ss7_as *as)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     unsigned int asp_count = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+   int i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                struct osmo_ss7_asp *asp = as->cfg.asps[i];</span><br><span style="color: hsl(120, 100%, 40%);">+                if (!asp)</span><br><span style="color: hsl(120, 100%, 40%);">+                     continue;</span><br><span style="color: hsl(120, 100%, 40%);">+             asp_count++;</span><br><span style="color: hsl(120, 100%, 40%);">+          if (asp->cfg.proto != OSMO_SS7_ASP_PROT_IPA)</span><br><span style="color: hsl(120, 100%, 40%);">+                       return false;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (asp_count == 1)</span><br><span style="color: hsl(120, 100%, 40%);">+           return true;</span><br><span style="color: hsl(120, 100%, 40%);">+  return false;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void ipa_add_route(struct osmo_fsm_inst *fi)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    struct xua_as_fsm_priv *xafp = (struct xua_as_fsm_priv *) fi->priv;</span><br><span style="color: hsl(120, 100%, 40%);">+        struct osmo_ss7_as *as = xafp->as;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_ss7_instance *inst = as->inst;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* As opposed to M3UA, there is no RKM and we have to implicitly</span><br><span style="color: hsl(120, 100%, 40%);">+       * automatically add a route once an IPA connection has come up */</span><br><span style="color: hsl(120, 100%, 40%);">+    osmo_ss7_route_create(inst->rtable_system, as->cfg.routing_key.pc, 0xffffff, as->cfg.name);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void ipa_del_route(struct osmo_fsm_inst *fi)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     struct xua_as_fsm_priv *xafp = (struct xua_as_fsm_priv *) fi->priv;</span><br><span style="color: hsl(120, 100%, 40%);">+        struct osmo_ss7_as *as = xafp->as;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_ss7_instance *inst = as->inst;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_ss7_route *rt;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* find the route which we have created if we ever reached ipa_asp_fsm_wait_id_ack2 */</span><br><span style="color: hsl(120, 100%, 40%);">+        rt = osmo_ss7_route_find_dpc_mask(inst->rtable_system, as->cfg.routing_key.pc, 0xffffff);</span><br><span style="color: hsl(120, 100%, 40%);">+       /* no route found, bail out */</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!rt) {</span><br><span style="color: hsl(120, 100%, 40%);">+            LOGPFSML(fi, LOGL_NOTICE, "Attempting to delete route for this IPA AS, but cannot "</span><br><span style="color: hsl(120, 100%, 40%);">+                  "find route for DPC %s. Did you manually delete it?\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                     osmo_ss7_pointcode_print(inst, as->cfg.routing_key.pc));</span><br><span style="color: hsl(120, 100%, 40%);">+          return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* route points to different AS, bail out */</span><br><span style="color: hsl(120, 100%, 40%);">+  if (rt->dest.as != as) {</span><br><span style="color: hsl(120, 100%, 40%);">+           LOGPFSML(fi, LOGL_NOTICE, "Attempting to delete route for this IPA ASP, but found "</span><br><span style="color: hsl(120, 100%, 40%);">+                  "route for DPC %s points to different AS (%s)\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                   osmo_ss7_pointcode_print(inst, as->cfg.routing_key.pc), rt->dest.as->cfg.name);</span><br><span style="color: hsl(120, 100%, 40%);">+             return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   osmo_ss7_route_destroy(rt);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* is any other ASP in this AS in state != DOWN? */</span><br><span> static bool check_any_other_asp_not_down(struct osmo_ss7_as *as, struct osmo_ss7_asp *asp_cmp)</span><br><span> {</span><br><span>@@ -309,12 +369,16 @@</span><br><span>           npar.status_info = M3UA_NOTIFY_I_AS_INACT;</span><br><span>           break;</span><br><span>       case XUA_AS_S_ACTIVE:</span><br><span style="color: hsl(120, 100%, 40%);">+         if (is_single_ipa_asp(as))</span><br><span style="color: hsl(120, 100%, 40%);">+                    ipa_add_route(fi);</span><br><span>           npar.status_info = M3UA_NOTIFY_I_AS_ACT;</span><br><span>             break;</span><br><span>       case XUA_AS_S_PENDING:</span><br><span>               npar.status_info = M3UA_NOTIFY_I_AS_PEND;</span><br><span>            break;</span><br><span>       case XUA_AS_S_DOWN:</span><br><span style="color: hsl(120, 100%, 40%);">+           if (is_single_ipa_asp(as))</span><br><span style="color: hsl(120, 100%, 40%);">+                    ipa_del_route(fi);</span><br><span>           /* RFC4666 sec 4.3.2 AS States:</span><br><span>                 If we end up here, it means no ASP is ACTIVE or INACTIVE,</span><br><span>                    meaning no ASP can have already configured the traffic mode</span><br><span>diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c</span><br><span>index f8683d5..ec85d21 100644</span><br><span>--- a/src/xua_asp_fsm.c</span><br><span>+++ b/src/xua_asp_fsm.c</span><br><span>@@ -939,23 +939,11 @@</span><br><span> /* Server: We're waiting for an ID ACK */</span><br><span> static void ipa_asp_fsm_wait_id_ack2(struct osmo_fsm_inst *fi, uint32_t event, void *data)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-     struct ipa_asp_fsm_priv *iafp = fi->priv;</span><br><span style="color: hsl(0, 100%, 40%);">-    struct osmo_ss7_asp *asp = iafp->asp;</span><br><span style="color: hsl(0, 100%, 40%);">-        struct osmo_ss7_instance *inst = asp->inst;</span><br><span style="color: hsl(0, 100%, 40%);">-  struct osmo_ss7_as *as;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- xua_find_as_for_asp(&as, asp, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-        OSMO_ASSERT(as);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>     switch (event) {</span><br><span>     case IPA_ASP_E_ID_ACK:</span><br><span>               /* ACK received, we can go to active state now.  The</span><br><span>                  * ACTIVE onenter function will inform the AS */</span><br><span>             osmo_fsm_inst_state_chg(fi, IPA_ASP_S_ACTIVE, 0, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-            /* As opposed to M3UA, there is no RKM and we have to implicitly automatically add</span><br><span style="color: hsl(0, 100%, 40%);">-               * a route once an IPA connection has come up */</span><br><span style="color: hsl(0, 100%, 40%);">-                osmo_ss7_route_create(inst->rtable_system, as->cfg.routing_key.pc, 0xffffff,</span><br><span style="color: hsl(0, 100%, 40%);">-                                    as->cfg.name);</span><br><span>              break;</span><br><span>       }</span><br><span> }</span><br><span>@@ -1011,48 +999,12 @@</span><br><span>      }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void ipa_asp_fsm_del_route(struct osmo_fsm_inst *fi)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  struct ipa_asp_fsm_priv *iafp = fi->priv;</span><br><span style="color: hsl(0, 100%, 40%);">-    struct osmo_ss7_asp *asp = iafp->asp;</span><br><span style="color: hsl(0, 100%, 40%);">-        struct osmo_ss7_instance *inst = asp->inst;</span><br><span style="color: hsl(0, 100%, 40%);">-  struct osmo_ss7_as *as;</span><br><span style="color: hsl(0, 100%, 40%);">- struct osmo_ss7_route *rt;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      xua_find_as_for_asp(&as, asp, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-        OSMO_ASSERT(as);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        /* find the route which we have created if we ever reached ipa_asp_fsm_wait_id_ack2 */</span><br><span style="color: hsl(0, 100%, 40%);">-  rt = osmo_ss7_route_find_dpc_mask(inst->rtable_system, as->cfg.routing_key.pc, 0xffffff);</span><br><span style="color: hsl(0, 100%, 40%);">- /* no route found, bail out */</span><br><span style="color: hsl(0, 100%, 40%);">-  if (!rt) {</span><br><span style="color: hsl(0, 100%, 40%);">-              LOGPFSML(fi, LOGL_NOTICE, "Attempting to delete route for this IPA ASP, but cannot "</span><br><span style="color: hsl(0, 100%, 40%);">-                   "find route for DPC %s. Did you manually delete it?\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                       osmo_ss7_pointcode_print(inst, as->cfg.routing_key.pc));</span><br><span style="color: hsl(0, 100%, 40%);">-            return;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* route points to different AS, bail out */</span><br><span style="color: hsl(0, 100%, 40%);">-    if (rt->dest.as != as) {</span><br><span style="color: hsl(0, 100%, 40%);">-             LOGPFSML(fi, LOGL_NOTICE, "Attempting to delete route for this IPA ASP, but found "</span><br><span style="color: hsl(0, 100%, 40%);">-                    "route for DPC %s points to different AS (%s)\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                     osmo_ss7_pointcode_print(inst, as->cfg.routing_key.pc), rt->dest.as->cfg.name);</span><br><span style="color: hsl(0, 100%, 40%);">-               return;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       osmo_ss7_route_destroy(rt);</span><br><span style="color: hsl(0, 100%, 40%);">-     /* FIXME: Why don't we also delete this timer if we return early above?</span><br><span style="color: hsl(0, 100%, 40%);">-      * FIXME: Where is this timer even scheduled? */</span><br><span style="color: hsl(0, 100%, 40%);">-        osmo_timer_del(&iafp->pong_timer);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> /* Server + Client: We're actively transmitting user data */</span><br><span> static void ipa_asp_fsm_active(struct osmo_fsm_inst *fi, uint32_t event, void *data)</span><br><span> {</span><br><span>  switch (event) {</span><br><span>     case XUA_ASP_E_M_ASP_DOWN_REQ:</span><br><span>       case XUA_ASP_E_M_ASP_INACTIVE_REQ:</span><br><span style="color: hsl(0, 100%, 40%);">-              ipa_asp_fsm_del_route(fi);</span><br><span>           osmo_fsm_inst_state_chg(fi, IPA_ASP_S_DOWN, 0, 0);</span><br><span>           break;</span><br><span>       }</span><br><span>@@ -1062,7 +1014,6 @@</span><br><span> {</span><br><span>       switch (event) {</span><br><span>     case XUA_ASP_E_M_ASP_DOWN_REQ:</span><br><span style="color: hsl(0, 100%, 40%);">-          ipa_asp_fsm_del_route(fi);</span><br><span>           osmo_fsm_inst_state_chg(fi, IPA_ASP_S_DOWN, 0, 0);</span><br><span>           break;</span><br><span>       }</span><br><span>@@ -1187,11 +1138,6 @@</span><br><span>   },</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void ipa_asp_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  ipa_asp_fsm_del_route(fi);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> struct osmo_fsm ipa_asp_fsm = {</span><br><span>       .name = "IPA_ASP",</span><br><span>         .states = ipa_asp_states,</span><br><span>@@ -1204,7 +1150,6 @@</span><br><span>                           S(XUA_ASP_E_ASPSM_BEAT) |</span><br><span>                            S(XUA_ASP_E_ASPSM_BEAT_ACK),</span><br><span>  .allstate_action = ipa_asp_allstate,</span><br><span style="color: hsl(0, 100%, 40%);">-    .cleanup = ipa_asp_fsm_cleanup,</span><br><span> };</span><br><span> </span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/libosmo-sccp/+/23894">change 23894</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/libosmo-sccp/+/23894"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: libosmo-sccp </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: Idb602beae3e9bc19f7bd96355c02ec8dfd9c5d6c </div>
<div style="display:none"> Gerrit-Change-Number: 23894 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>