This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
Harald Welte gerrit-no-reply at lists.osmocom.orgHello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2349 to look at the new patch set (#2). SUA/M3UA: Implement T(r) recovery timer of Application Server FSM When an AS goes "down" it first entres a recovery state, in which any to-be-transmitted messages are enqueued until the timer T(r) expires. Once the timer expires, the messages are discarded. If the AS goes ACTIVE before timer expiration, queued messages are sent. Change-Id: I22725bf35306299a00c66d7b3637f5e198c26247 --- M src/m3ua.c M src/sua.c M src/xua_as_fsm.c M src/xua_as_fsm.h M src/xua_asp_fsm.c 5 files changed, 147 insertions(+), 46 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/49/2349/2 diff --git a/src/m3ua.c b/src/m3ua.c index 7dc2afb..a7ef06c 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -39,6 +39,7 @@ #include <osmocom/sigtran/protocol/m3ua.h> #include <osmocom/sigtran/protocol/sua.h> +#include "xua_as_fsm.h" #include "xua_asp_fsm.h" #include "xua_internal.h" @@ -420,16 +421,14 @@ * Transmitting M3UA messsages to SCTP ***********************************************************************/ -/* transmit given xua_msg via given ASP. callee takes xua ownership */ -static int m3ua_tx_xua_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua) +/* Convert M3UA from xua_msg to msgb and set PPID/stream */ +static struct msgb *m3ua_to_msg(struct xua_msg *xua) { struct msgb *msg = xua_to_msg(M3UA_VERSION, xua); - OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA); - if (!msg) { LOGP(DLM3UA, LOGL_ERROR, "Error encoding M3UA Msg\n"); - return -1; + return NULL; } if (xua->hdr.msg_class == M3UA_MSGC_XFER) @@ -437,6 +436,20 @@ else msgb_sctp_stream(msg) = 0; msgb_sctp_ppid(msg) = M3UA_PPID; + + return msg; +} + +/* transmit given xua_msg via given ASP */ +static int m3ua_tx_xua_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + struct msgb *msg = m3ua_to_msg(xua); + + OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA); + + if (!msg) + return -1; + return osmo_ss7_asp_send(asp, msg); } @@ -446,8 +459,8 @@ * \return 0 on success; negative on error */ int m3ua_tx_xua_as(struct osmo_ss7_as *as, struct xua_msg *xua) { - struct osmo_ss7_asp *asp; - unsigned int i; + struct msgb *msg; + int rc; OSMO_ASSERT(as->cfg.proto == OSMO_SS7_ASP_PROT_M3UA); @@ -455,19 +468,16 @@ if (as->cfg.routing_key.context) xua_msg_add_u32(xua, M3UA_IEI_ROUTE_CTX, as->cfg.routing_key.context); - for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { - asp = as->cfg.asps[i]; - if (!asp) - continue; - if (asp) - break; - } - if (!asp) { - LOGP(DLM3UA, LOGL_ERROR, "No ASP entroy in AS, dropping message\n"); - return -ENODEV; - } + msg = m3ua_to_msg(xua); + if (!msg) + return -1; - return m3ua_tx_xua_asp(asp, xua); + /* send the msg to the AS for transmission. The AS FSM might + * (depending on its state) enqueue it before trnsmission */ + rc = osmo_fsm_inst_dispatch(as->fi, XUA_AS_E_TRANSFER_REQ, msg); + if (rc < 0) + msgb_free(msg); + return rc; } /*********************************************************************** diff --git a/src/sua.c b/src/sua.c index 3bff855..97a0785 100644 --- a/src/sua.c +++ b/src/sua.c @@ -40,6 +40,7 @@ #include <osmocom/sigtran/protocol/m3ua.h> #include <osmocom/sigtran/osmo_ss7.h> +#include "xua_as_fsm.h" #include "xua_asp_fsm.h" #include "xua_internal.h" #include "sccp_internal.h" @@ -252,18 +253,38 @@ * Transmitting SUA messsages to SCTP ***********************************************************************/ -static int sua_tx_xua_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua) +static struct msgb *sua_to_msg(struct xua_msg *xua) { struct msgb *msg = xua_to_msg(SUA_VERSION, xua); - OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_SUA); - if (!msg) { - LOGPASP(asp, DLSUA, LOGL_ERROR, "Error encoding SUA Msg\n"); - return -1; + LOGP(DLSUA, LOGL_ERROR, "Error encoding SUA Msg\n"); + return NULL; } + switch (xua->hdr.msg_class) { + case SUA_MSGC_CL: + case SUA_MSGC_CO: + msgb_sctp_stream(msg) = 1; + break; + default: + msgb_sctp_stream(msg) = 0; + break; + } msgb_sctp_ppid(msg) = SUA_PPID; + + return msg; +} + +static int sua_tx_xua_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + struct msgb *msg = sua_to_msg(xua); + + OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_SUA); + + if (!msg) + return -1; + return osmo_ss7_asp_send(asp, msg); } @@ -273,25 +294,25 @@ * \return 0 on success; negative on error */ int sua_tx_xua_as(struct osmo_ss7_as *as, struct xua_msg *xua) { - struct osmo_ss7_asp *asp; - unsigned int i; + struct msgb *msg; + int rc; OSMO_ASSERT(as->cfg.proto == OSMO_SS7_ASP_PROT_SUA); - /* FIXME: Select ASP within AS depending on traffic mode */ - for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { - asp = as->cfg.asps[i]; - if (!asp) - continue; - if (asp) - break; - } - if (!asp) { - LOGP(DLSUA, LOGL_ERROR, "No ASP in AS, dropping message\n"); - return -ENODEV; - } + /* Add RC for this AS */ + if (as->cfg.routing_key.context) + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, as->cfg.routing_key.context); - return sua_tx_xua_asp(asp, xua); + msg = sua_to_msg(xua); + if (!msg) + return -1; + + /* send the msg to the AS for transmission. The AS FSM might + * (depending on its state) enqueue it before trnsmission */ + rc = osmo_fsm_inst_dispatch(as->fi, XUA_AS_E_TRANSFER_REQ, msg); + if (rc < 0) + msgb_free(msg); + return rc; } /*********************************************************************** diff --git a/src/xua_as_fsm.c b/src/xua_as_fsm.c index 740070b..282a6bf 100644 --- a/src/xua_as_fsm.c +++ b/src/xua_as_fsm.c @@ -65,12 +65,39 @@ return sent; } +/* actually transmit a message through this AS */ +static int xua_as_transmit_msg(struct osmo_ss7_as *as, struct msgb *msg) +{ + struct osmo_ss7_asp *asp; + unsigned int i; + + /* FIXME: proper selection of the ASP based on the SLS and the + * traffic mode type! */ + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + asp = as->cfg.asps[i]; + if (!asp) + continue; + if (asp) + break; + } + + if (!asp) { + LOGPFSM(as->fi, "No ASP in AS, dropping message\n"); + msgb_free(msg); + return -1; + } + + return osmo_ss7_asp_send(asp, msg); +} + /*********************************************************************** * Actual FSM ***********************************************************************/ #define S(x) (1 << (x)) + +#define MSEC_TO_S_US(x) (x/1000), ((x%1000)*10) enum xua_as_state { XUA_AS_S_DOWN, @@ -83,11 +110,17 @@ { XUA_ASPAS_ASP_INACTIVE_IND, "ASPAS-ASP_INACTIVE.ind" }, { XUA_ASPAS_ASP_DOWN_IND, "ASPAS-ASP_DOWN.ind" }, { XUA_ASPAS_ASP_ACTIVE_IND, "ASPAS-ASP_ACTIVE.ind" }, + { XUA_AS_E_RECOVERY_EXPD, "AS-T_REC_EXPD.ind" }, + { XUA_AS_E_TRANSFER_REQ, "AS-TRANSFER.req" }, { 0, NULL } }; struct xua_as_fsm_priv { struct osmo_ss7_as *as; + struct { + struct osmo_timer_list t_r; + struct llist_head queued_msgs; + } recovery; }; /* is any other ASP in this AS in state != DOWN? */ @@ -130,6 +163,11 @@ return false; } +static void t_r_callback(void *_fi) +{ + struct osmo_fsm_inst *fi = _fi; + osmo_fsm_inst_dispatch(fi, XUA_AS_E_RECOVERY_EXPD, NULL); +} static void xua_as_fsm_down(struct osmo_fsm_inst *fi, uint32_t event, void *data) { @@ -205,16 +243,20 @@ static void xua_as_fsm_active(struct osmo_fsm_inst *fi, uint32_t event, void *data) { struct xua_as_fsm_priv *xafp = (struct xua_as_fsm_priv *) fi->priv; - struct osmo_ss7_asp *asp = data; + struct osmo_ss7_asp *asp; + struct msgb *msg; switch (event) { case XUA_ASPAS_ASP_DOWN_IND: case XUA_ASPAS_ASP_INACTIVE_IND: + asp = data; if (check_any_other_asp_in_active(xafp->as, asp)) { /* ignore, we stay AS_ACTIVE */ } else { + uint32_t recovery_msec = xafp->as->cfg.recovery_timeout_msec; osmo_fsm_inst_state_chg(fi, XUA_AS_S_PENDING, 0, 0); - /* FIXME: Start T(r) */ + /* Start T(r) */ + osmo_timer_schedule(&xafp->recovery.t_r, MSEC_TO_S_US(recovery_msec)); /* FIXME: Queue all signalling messages until * recovery or T(r) expiry */ } @@ -222,21 +264,44 @@ case XUA_ASPAS_ASP_ACTIVE_IND: /* ignore */ break; + case XUA_AS_E_TRANSFER_REQ: + /* message for transmission */ + msg = data; + xua_as_transmit_msg(xafp->as, msg); + break; } } static void xua_as_fsm_pending(struct osmo_fsm_inst *fi, uint32_t event, void *data) { + struct xua_as_fsm_priv *xafp = (struct xua_as_fsm_priv *) fi->priv; + struct msgb *msg; + switch (event) { case XUA_ASPAS_ASP_ACTIVE_IND: /* one ASP transitions into ASP-ACTIVE */ + osmo_timer_del(&xafp->recovery.t_r); osmo_fsm_inst_state_chg(fi, XUA_AS_S_ACTIVE, 0, 0); + /* push out any pending queued messages */ + while ((msg = msgb_dequeue(&xafp->recovery.queued_msgs))) + xua_as_transmit_msg(xafp->as, msg); break; case XUA_ASPAS_ASP_INACTIVE_IND: /* ignore */ break; case XUA_ASPAS_ASP_DOWN_IND: /* ignore */ + break; + case XUA_AS_E_RECOVERY_EXPD: + LOGPFSM(fi, "T(r) expired; dropping queued messages\n"); + while ((msg = msgb_dequeue(&xafp->recovery.queued_msgs))) + talloc_free(msg); + osmo_fsm_inst_state_chg(fi, XUA_AS_S_DOWN, 0, 0); + break; + case XUA_AS_E_TRANSFER_REQ: + /* enqueue the to-be-transferred message */ + msg = data; + msgb_enqueue(&xafp->recovery.queued_msgs, msg); break; } } @@ -264,7 +329,8 @@ [XUA_AS_S_ACTIVE] = { .in_event_mask = S(XUA_ASPAS_ASP_DOWN_IND) | S(XUA_ASPAS_ASP_INACTIVE_IND) | - S(XUA_ASPAS_ASP_ACTIVE_IND), + S(XUA_ASPAS_ASP_ACTIVE_IND) | + S(XUA_AS_E_TRANSFER_REQ), .out_state_mask = S(XUA_AS_S_ACTIVE) | S(XUA_AS_S_PENDING), .name = "AS_ACTIVE", @@ -274,7 +340,9 @@ [XUA_AS_S_PENDING] = { .in_event_mask = S(XUA_ASPAS_ASP_INACTIVE_IND) | S(XUA_ASPAS_ASP_DOWN_IND) | - S(XUA_ASPAS_ASP_ACTIVE_IND), + S(XUA_ASPAS_ASP_ACTIVE_IND) | + S(XUA_AS_E_TRANSFER_REQ) | + S(XUA_AS_E_RECOVERY_EXPD), .out_state_mask = S(XUA_AS_S_DOWN) | S(XUA_AS_S_INACTIVE) | S(XUA_AS_S_ACTIVE) | @@ -310,6 +378,9 @@ return NULL; } xafp->as = as; + xafp->recovery.t_r.cb = t_r_callback; + xafp->recovery.t_r.data = fi; + INIT_LLIST_HEAD(&xafp->recovery.queued_msgs); fi->priv = xafp; diff --git a/src/xua_as_fsm.h b/src/xua_as_fsm.h index 3b8e5b7..0128919 100644 --- a/src/xua_as_fsm.h +++ b/src/xua_as_fsm.h @@ -6,6 +6,8 @@ XUA_ASPAS_ASP_INACTIVE_IND, XUA_ASPAS_ASP_DOWN_IND, XUA_ASPAS_ASP_ACTIVE_IND, + XUA_AS_E_RECOVERY_EXPD, + XUA_AS_E_TRANSFER_REQ, }; extern struct osmo_fsm xua_as_fsm; diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index 59887a4..f4d9cf0 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -380,9 +380,6 @@ struct osmo_ss7_instance *inst = asp->inst; struct osmo_ss7_as *as; - if (xafp->role != XUA_ASPFSM_ROLE_SG) - return; - llist_for_each_entry(as, &inst->as_list, list) { if (!osmo_ss7_as_has_asp(as, asp)) continue; -- To view, visit https://gerrit.osmocom.org/2349 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I22725bf35306299a00c66d7b3637f5e198c26247 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte <laforge at gnumonks.org> Gerrit-Reviewer: Jenkins Builder