pespin has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/libosmo-sccp/+/33648 )


Change subject: asp: Make ASP default LM timers VTY configurable
......................................................................

asp: Make ASP default LM timers VTY configurable

Related: SYS#6511
Change-Id: Ib62e19f2e528e8b2792cbb51a5900dc3463ebd06
---
M include/osmocom/sigtran/osmo_ss7.h
M src/osmo_ss7.c
M src/osmo_ss7_vty.c
M src/xua_default_lm_fsm.c
M src/xua_internal.h
5 files changed, 167 insertions(+), 20 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/48/33648/1

diff --git a/include/osmocom/sigtran/osmo_ss7.h 
b/include/osmocom/sigtran/osmo_ss7.h
index 3c72394..ba1e214 100644
--- a/include/osmocom/sigtran/osmo_ss7.h
+++ b/include/osmocom/sigtran/osmo_ss7.h
@@ -437,6 +437,9 @@
                struct osmo_ss7_asp_peer remote;
                uint8_t qos_class;
                uint32_t quirks;
+
+               /* T_defs used by the default_lm: */
+               struct osmo_tdef *T_defs_lm;
        } cfg;
 };

diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c
index 839d756..7e171fd 100644
--- a/src/osmo_ss7.c
+++ b/src/osmo_ss7.c
@@ -1538,6 +1538,11 @@
        asp->cfg.local.port = local_port;
        asp->cfg.proto = proto;
        asp->cfg.name = talloc_strdup(asp, name);
+
+       asp->cfg.T_defs_lm = talloc_size(asp, 
sizeof(ss7_asp_lm_timer_defaults));
+       memcpy(asp->cfg.T_defs_lm, ss7_asp_lm_timer_defaults, 
sizeof(ss7_asp_lm_timer_defaults));
+       osmo_tdefs_reset(asp->cfg.T_defs_lm);
+
        llist_add_tail(&asp->list, &inst->asp_list);

        /* The SUA code internally needs SCCP to work */
diff --git a/src/osmo_ss7_vty.c b/src/osmo_ss7_vty.c
index 9398bc1..61f14cd 100644
--- a/src/osmo_ss7_vty.c
+++ b/src/osmo_ss7_vty.c
@@ -790,6 +790,77 @@
        return CMD_SUCCESS;
 }

+/* timer lm <name> <1-999999>
+ * (cmdstr and doc are dynamically generated from ss7_asp_lm_timer_names.) */
+DEFUN_ATTR(asp_timer, asp_timer_cmd,
+          NULL, NULL, CMD_ATTR_IMMEDIATE)
+{
+       struct osmo_ss7_asp *asp = vty->index;
+       enum ss7_asp_lm_timer timer = get_string_value(ss7_asp_lm_timer_names, 
argv[0]);
+
+       if (timer <= 0 || timer >= SS7_ASP_LM_TIMERS_LEN) {
+               vty_out(vty, "%% Invalid timer: %s%s", argv[0], VTY_NEWLINE);
+               return CMD_WARNING;
+       }
+
+       osmo_tdef_set(asp->cfg.T_defs_lm, timer, atoi(argv[1]), OSMO_TDEF_S);
+       return CMD_SUCCESS;
+}
+
+static void gen_asp_timer_cmd_strs(struct cmd_element *cmd)
+{
+       int i;
+       char *cmd_str = NULL;
+       char *doc_str = NULL;
+
+       OSMO_ASSERT(cmd->string == NULL);
+       OSMO_ASSERT(cmd->doc == NULL);
+
+       osmo_talloc_asprintf(tall_vty_ctx, cmd_str, "timer lm (");
+       osmo_talloc_asprintf(tall_vty_ctx, doc_str,
+                            "Configure ASP default timer values\n"
+                            "Configure ASP default lm timer values\n");
+
+       for (i = 0; ss7_asp_lm_timer_names[i].str; i++) {
+               const struct osmo_tdef *def;
+               enum ss7_asp_lm_timer timer;
+
+               timer = ss7_asp_lm_timer_names[i].value;
+               def = osmo_tdef_get_entry((struct osmo_tdef 
*)&ss7_asp_lm_timer_defaults, timer);
+               OSMO_ASSERT(def);
+
+               osmo_talloc_asprintf(tall_vty_ctx, cmd_str, "%s%s",
+                                    i ? "|" : "",
+                                    ss7_asp_lm_timer_names[i].str);
+               osmo_talloc_asprintf(tall_vty_ctx, doc_str, "%s (default: 
%lu)\n",
+                                    def->desc,
+                                    def->default_val);
+       }
+
+       osmo_talloc_asprintf(tall_vty_ctx, cmd_str, ") <1-999999>");
+       osmo_talloc_asprintf(tall_vty_ctx, doc_str,
+                            "Timer value, in seconds\n");
+
+       cmd->string = cmd_str;
+       cmd->doc = doc_str;
+}
+
+static void write_asp_timers(struct vty *vty, const char *indent,
+                               struct osmo_ss7_asp *asp)
+{
+       int i;
+
+       for (i = 0; ss7_asp_lm_timer_names[i].str; i++) {
+               const struct osmo_tdef *tdef = 
osmo_tdef_get_entry(asp->cfg.T_defs_lm, ss7_asp_lm_timer_names[i].value);
+               if (!tdef)
+                       continue;
+               if (tdef->val == tdef->default_val)
+                       continue;
+               vty_out(vty, "%stimer lm %s %lu%s", indent, 
ss7_asp_lm_timer_names[i].str,
+                       tdef->val, VTY_NEWLINE);
+       }
+}
+
 static char *as_list_for_asp(const struct osmo_ss7_asp *asp, char *buf, size_t 
buf_len)
 {
        struct osmo_strbuf sb = { .buf = buf, .len = buf_len };
@@ -882,6 +953,7 @@
                        continue;
                vty_out(vty, "  quirk %s%s", get_value_string(asp_quirk_names, 
(1 << i)), VTY_NEWLINE);
        }
+       write_asp_timers(vty, "  ", asp);
 }


@@ -2127,6 +2199,8 @@
        install_lib_element(L_CS7_ASP_NODE, &asp_shutdown_cmd);
        install_lib_element(L_CS7_ASP_NODE, &asp_quirk_cmd);
        install_lib_element(L_CS7_ASP_NODE, &asp_no_quirk_cmd);
+       gen_asp_timer_cmd_strs(&asp_timer_cmd);
+       install_lib_element(L_CS7_ASP_NODE, &asp_timer_cmd);

        install_node(&as_node, NULL);
        install_lib_element_ve(&show_cs7_as_cmd);
diff --git a/src/xua_default_lm_fsm.c b/src/xua_default_lm_fsm.c
index 15958f2..fb0465e 100644
--- a/src/xua_default_lm_fsm.c
+++ b/src/xua_default_lm_fsm.c
@@ -76,17 +76,53 @@
        { 0, NULL }
 };

-enum lm_timer {
-       T_WAIT_ASP_UP,
-       T_WAIT_NOTIFY,
-       T_WAIT_NOTIFY_RKM,
-       T_WAIT_RK_REG_RESP,
+/***********************************************************************
+ * Timer Handling
+ ***********************************************************************/
+
+const struct osmo_tdef ss7_asp_lm_timer_defaults[SS7_ASP_LM_TIMERS_LEN] = {
+       { .T = SS7_ASP_LM_T_WAIT_ASP_UP,        .default_val = 20,      .unit = 
OSMO_TDEF_S,
+         .desc = "Restart ASP after timeout waiting for ASP UP (SG role) / ASP 
UP ACK (ASP role) (s)" },
+       { .T = SS7_ASP_LM_T_WAIT_NOTIFY,        .default_val = 2,       .unit = 
OSMO_TDEF_S,
+         .desc = "Restart ASP after timeout waiting for NOTIFY (s)" },
+       { .T = SS7_ASP_LM_T_WAIT_NOTIY_RKM,     .default_val = 20,      .unit = 
OSMO_TDEF_S,
+         .desc = "Restart ASP after timeout waiting for NOTIFY after RKM 
registration (s)" },
+       { .T = SS7_ASP_LM_T_WAIT_RK_REG_RESP,   .default_val = 10,      .unit = 
OSMO_TDEF_S,
+         .desc = "Restart ASP after timeout waiting for RK_REG_RESP (s)" },
+       {}
+};
+
+/* Appendix C.4 of ITU-T Q.714 */
+const struct value_string ss7_asp_lm_timer_names[] = {
+       { SS7_ASP_LM_T_WAIT_ASP_UP, "wait_asp_up" },
+       { SS7_ASP_LM_T_WAIT_NOTIFY, "wait_notify" },
+       { SS7_ASP_LM_T_WAIT_NOTIY_RKM, "wait_notify_rkm" },
+       { SS7_ASP_LM_T_WAIT_RK_REG_RESP, "wait_rk_reg_resp" },
+       {}
+};
+
+osmo_static_assert(ARRAY_SIZE(ss7_asp_lm_timer_defaults) == 
(SS7_ASP_LM_TIMERS_LEN) &&
+                  ARRAY_SIZE(ss7_asp_lm_timer_names) == 
(SS7_ASP_LM_TIMERS_LEN),
+                  assert_ss7_asp_lm_timer_count);
+
+static const struct osmo_tdef_state_timeout lm_fsm_timeouts[32] = {
+       [S_IDLE]        = { },
+       [S_WAIT_ASP_UP] = { .T = SS7_ASP_LM_T_WAIT_ASP_UP },
+       [S_WAIT_NOTIFY] = { .T = SS7_ASP_LM_T_WAIT_NOTIFY }, /* 
SS7_ASP_LM_T_WAIT_NOTIY_RKM if coming from S_RKM_REG */
+       [S_RKM_REG]     = { .T = SS7_ASP_LM_T_WAIT_RK_REG_RESP },
+       [S_ACTIVE]      = { },
 };

 struct lm_fsm_priv {
        struct osmo_ss7_asp *asp;
 };

+#define lm_fsm_state_chg(fi, NEXT_STATE) \
+       osmo_tdef_fsm_inst_state_chg(fi, NEXT_STATE, \
+                                    lm_fsm_timeouts, \
+                                   ((struct lm_fsm_priv 
*)(fi->priv))->asp->cfg.T_defs_lm, \
+                                    -1)
+
 static struct osmo_ss7_as *find_first_as_in_asp(struct osmo_ss7_asp *asp)
 {
        struct osmo_ss7_as *as;
@@ -138,8 +174,8 @@

        switch (event) {
        case LM_E_SCTP_EST_IND:
-               /* Try to transition to ASP-UP, wait for 20s */
-               osmo_fsm_inst_state_chg(fi, S_WAIT_ASP_UP, 20, T_WAIT_ASP_UP);
+               /* Try to transition to ASP-UP, wait to receive message for a 
few seconds */
+               lm_fsm_state_chg(fi, S_WAIT_ASP_UP);
                osmo_fsm_inst_dispatch(lmp->asp->fi, XUA_ASP_E_M_ASP_UP_REQ, 
NULL);
                break;
        }
@@ -151,7 +187,7 @@
        case LM_E_ASP_UP_CONF:
                /* ASP is up, wait for some time if any NOTIFY
                 * indications about AS in this ASP are received */
-               osmo_fsm_inst_state_chg(fi, S_WAIT_NOTIFY, 2, T_WAIT_NOTIFY);
+               lm_fsm_state_chg(fi, S_WAIT_NOTIFY);
                break;
        }
 }
@@ -164,13 +200,13 @@
        struct osmo_ss7_as *as;

        switch (fi->T) {
-       case T_WAIT_ASP_UP:
+       case SS7_ASP_LM_T_WAIT_ASP_UP:
                /* we have been waiting for the ASP to come up, but it
                 * failed to do so */
                LOGPFSML(fi, LOGL_NOTICE, "Peer didn't send any ASP_UP in time! 
restarting ASP\n");
                restart_asp(fi);
                break;
-       case T_WAIT_NOTIFY:
+       case SS7_ASP_LM_T_WAIT_NOTIFY:
                if (lmp->asp->cfg.quirks & OSMO_SS7_ASP_QUIRK_NO_NOTIFY) {
                        /* some implementations don't send the NOTIFY which 
they SHOULD
                         * according to RFC4666 (see OS#5145) */
@@ -181,7 +217,7 @@
                /* No AS has reported via NOTIFY that is was
                 * (statically) configured at the SG for this ASP, so
                 * let's dynamically register */
-               osmo_fsm_inst_state_chg(fi, S_RKM_REG, 10, T_WAIT_RK_REG_RESP);
+               lm_fsm_state_chg(fi, S_RKM_REG);
                prim = xua_xlm_prim_alloc(OSMO_XLM_PRIM_M_RK_REG, 
PRIM_OP_REQUEST);
                OSMO_ASSERT(prim);
                as = find_first_as_in_asp(lmp->asp);
@@ -195,12 +231,12 @@
                prim->u.rk_reg.traf_mode = as->cfg.mode;
                osmo_xlm_sap_down(lmp->asp, &prim->oph);
                break;
-       case T_WAIT_NOTIFY_RKM:
+       case SS7_ASP_LM_T_WAIT_NOTIY_RKM:
                /* No AS has reported via NOTIFY even after dynamic RKM
                 * configuration */
                restart_asp(fi);
                break;
-       case T_WAIT_RK_REG_RESP:
+       case SS7_ASP_LM_T_WAIT_RK_REG_RESP:
                /* timeout of registration of routing key */
                restart_asp(fi);
                break;
@@ -220,7 +256,7 @@
                if (oxp->u.notify.status_type == M3UA_NOTIFY_T_STATCHG &&
                    (oxp->u.notify.status_info == M3UA_NOTIFY_I_AS_INACT ||
                     oxp->u.notify.status_info == M3UA_NOTIFY_I_AS_PEND)) {
-                       osmo_fsm_inst_state_chg(fi, S_ACTIVE, 0, 0);
+                       lm_fsm_state_chg(fi, S_ACTIVE);
                        osmo_fsm_inst_dispatch(lmp->asp->fi, 
XUA_ASP_E_M_ASP_ACTIVE_REQ, NULL);
                }
                break;
@@ -229,7 +265,7 @@
                 * the SG, and that this AS is currently inactive */
                /* request the ASP to go into active state (which
                 * hopefully will bring the AS to active, too) */
-               osmo_fsm_inst_state_chg(fi, S_ACTIVE, 0, 0);
+               lm_fsm_state_chg(fi, S_ACTIVE);
                osmo_fsm_inst_dispatch(lmp->asp->fi, 
XUA_ASP_E_M_ASP_ACTIVE_REQ, NULL);
                break;
        }
@@ -237,6 +273,7 @@

 static void lm_rkm_reg(struct osmo_fsm_inst *fi, uint32_t event, void *data)
 {
+       struct lm_fsm_priv *lmp = fi->priv;
        struct osmo_xlm_prim *oxp;
        int rc;

@@ -247,14 +284,15 @@
                        LOGPFSML(fi, LOGL_NOTICE, "Received RKM_REG_RSP with 
negative result\n");
                        restart_asp(fi);
                } else {
+                       unsigned long timeout_sec;
                        rc = handle_reg_conf(fi, oxp->u.rk_reg.key.l_rk_id, 
oxp->u.rk_reg.key.context);
                        if (rc < 0)
                                restart_asp(fi);
-                       /* RKM registration was successful, we can
-                        * transition to WAIT_NOTIFY state and assume
-                        * that an NOTIFY/AS-INACTIVE arrives within 20
-                        * seconds */
-                       osmo_fsm_inst_state_chg(fi, S_WAIT_NOTIFY, 20, 
T_WAIT_NOTIFY_RKM);
+                       /* RKM registration was successful, we can transition 
to WAIT_NOTIFY
+                        * state and assume that an NOTIFY/AS-INACTIVE arrives 
within
+                        * T_WAIT_NOTIFY_RKM seconds */
+                       timeout_sec = osmo_tdef_get(lmp->asp->cfg.T_defs_lm, 
SS7_ASP_LM_T_WAIT_NOTIY_RKM, OSMO_TDEF_S, -1);
+                       osmo_fsm_inst_state_chg(fi, S_WAIT_NOTIFY, timeout_sec, 
SS7_ASP_LM_T_WAIT_NOTIY_RKM);
                }
                break;
        }
diff --git a/src/xua_internal.h b/src/xua_internal.h
index 5dd7066..26cb3fc 100644
--- a/src/xua_internal.h
+++ b/src/xua_internal.h
@@ -1,5 +1,6 @@
 #pragma once

+#include <osmocom/core/tdef.h>
 #include <osmocom/sigtran/osmo_ss7.h>
 #include <osmocom/sigtran/xua_msg.h>

@@ -85,6 +86,22 @@
 void xua_snm_pc_available(struct osmo_ss7_as *as, const uint32_t *aff_pc,
                           unsigned int num_aff_pc, const char *info_str, bool 
available);

+enum ss7_asp_lm_timer {
+       /* 0 kept unused on purpose since it's handled specially by osmo_fsm */
+       SS7_ASP_LM_T_WAIT_ASP_UP = 1,
+       SS7_ASP_LM_T_WAIT_NOTIFY,
+       SS7_ASP_LM_T_WAIT_NOTIY_RKM,
+       SS7_ASP_LM_T_WAIT_RK_REG_RESP,
+       /* This must remain the last item: */
+       SS7_ASP_LM_TIMERS_LEN
+};
+
+extern const struct osmo_tdef ss7_asp_lm_timer_defaults[SS7_ASP_LM_TIMERS_LEN];
+
+extern const struct value_string ss7_asp_lm_timer_names[];
+static inline const char *ss7_asp_lm_timer_name(enum ss7_asp_lm_timer val)
+{ return get_value_string(ss7_asp_lm_timer_names, val); }
+
 extern struct osmo_fsm xua_default_lm_fsm;
 extern const struct value_string m3ua_rkm_reg_status_vals[];
 extern const struct value_string m3ua_rkm_dereg_status_vals[];

--
To view, visit https://gerrit.osmocom.org/c/libosmo-sccp/+/33648
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: libosmo-sccp
Gerrit-Branch: master
Gerrit-Change-Id: Ib62e19f2e528e8b2792cbb51a5900dc3463ebd06
Gerrit-Change-Number: 33648
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <[email protected]>
Gerrit-MessageType: newchange

Reply via email to