asp: Make ASP default LM timers VTY configurable
Related: SYS#6511 Change-Id: Ib62e19f2e528e8b2792cbb51a5900dc3463ebd06
This commit is contained in:
parent
5cf725b191
commit
4ddaee9362
|
@ -437,6 +437,9 @@ struct osmo_ss7_asp {
|
|||
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;
|
||||
};
|
||||
|
||||
|
|
|
@ -1538,6 +1538,11 @@ osmo_ss7_asp_alloc(struct osmo_ss7_instance *inst, const char *name,
|
|||
asp->cfg.local.port = local_port;
|
||||
asp->cfg.proto = proto;
|
||||
asp->cfg.name = talloc_strdup(asp, name);
|
||||
|
||||
asp->cfg.T_defs_lm = talloc_memdup(asp, 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 */
|
||||
|
|
|
@ -790,6 +790,77 @@ DEFUN_ATTR(asp_no_quirk, asp_no_quirk_cmd,
|
|||
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 @@ static void write_one_asp(struct vty *vty, struct osmo_ss7_asp *asp, bool show_d
|
|||
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 @@ static void vty_init_shared(void *ctx)
|
|||
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);
|
||||
|
|
|
@ -76,17 +76,53 @@ static const struct value_string lm_event_names[] = {
|
|||
{ 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 @@ static void lm_idle(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
|||
|
||||
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 @@ static void lm_wait_asp_up(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
|||
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 @@ static int lm_timer_cb(struct osmo_fsm_inst *fi)
|
|||
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 @@ static int lm_timer_cb(struct osmo_fsm_inst *fi)
|
|||
/* 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 @@ static int lm_timer_cb(struct osmo_fsm_inst *fi)
|
|||
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 @@ static void lm_wait_notify(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
|||
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 @@ static void lm_wait_notify(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
|||
* 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_wait_notify(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
|||
|
||||
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 @@ static void lm_rkm_reg(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -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_asp_send_xlm_prim_simple(struct osmo_ss7_asp *asp,
|
|||
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[];
|
||||
|
|
Loading…
Reference in New Issue