pespin has submitted this change. (
https://gerrit.osmocom.org/c/libosmo-sigtran/+/39640?usp=email )
Change subject: Make sure to NOTIFY current state to peer after ASP UP ACK / REG RESP
......................................................................
Make sure to NOTIFY current state to peer after ASP UP ACK / REG RESP
As per RFC4666 4.3.4.5:
"""
When an ASP moves from ASP-DOWN to ASP-INACTIVE within a particular AS,
a Notify message SHOULD be sent, by the ASP-UP receptor, after sending
the ASP-UP-ACK, in order to inform the ASP of the current AS state."""
It also needs to be done for REG RESP in order to support dynamic
ASPs/ASs, since in that case if dynamic ASP sends to SG an ASP-UP msg,
it contains no RCTX/AS reference, and hence the ASP will only be
assigned to an AS after the REG-REQ is sent, at which point we can send
the AS status to it.
Change-Id: I3dffa2e9c554f03c7c721b757ff33a89961665b5
---
M src/xua_as_fsm.c
M src/xua_as_fsm.h
M src/xua_asp_fsm.c
M src/xua_rkm.c
4 files changed, 129 insertions(+), 27 deletions(-)
Approvals:
laforge: Looks good to me, but someone else must approve
osmith: Looks good to me, but someone else must approve
Jenkins Builder: Verified
pespin: Looks good to me, approved
diff --git a/src/xua_as_fsm.c b/src/xua_as_fsm.c
index 577c7d3..c4a167c 100644
--- a/src/xua_as_fsm.c
+++ b/src/xua_as_fsm.c
@@ -39,6 +39,19 @@
return msg;
}
+static void tx_notify(struct osmo_ss7_asp *asp, const struct osmo_xlm_prim_notify *npar)
+{
+ const char *type_name, *info_name, *info_str;
+ type_name = get_value_string(m3ua_ntfy_type_names, npar->status_type);
+ info_name = m3ua_ntfy_info_name(npar->status_type, npar->status_info);
+ info_str = npar->info_string ? npar->info_string : "";
+
+ LOGPASP(asp, DLSS7, LOGL_INFO, "Tx NOTIFY Type %s:%s (%s)\n",
+ type_name, info_name, info_str);
+ struct msgb *msg = encode_notify(npar);
+ osmo_ss7_asp_send(asp, msg);
+}
+
static int as_notify_all_asp(struct osmo_ss7_as *as, struct osmo_xlm_prim_notify *npar)
{
struct msgb *msg;
@@ -184,6 +197,37 @@
bool ipa_route_created;
};
+static void fill_notify_statchg_pars(const struct osmo_fsm_inst *fi, struct
osmo_xlm_prim_notify *npar)
+{
+ struct xua_as_fsm_priv *xafp = (struct xua_as_fsm_priv *) fi->priv;
+ struct osmo_ss7_as *as = xafp->as;
+ *npar = (struct osmo_xlm_prim_notify){
+ .status_type = M3UA_NOTIFY_T_STATCHG,
+ };
+
+ switch (fi->state) {
+ case XUA_AS_S_INACTIVE:
+ npar->status_info = M3UA_NOTIFY_I_AS_INACT;
+ break;
+ case XUA_AS_S_ACTIVE:
+ npar->status_info = M3UA_NOTIFY_I_AS_ACT;
+ break;
+ case XUA_AS_S_PENDING:
+ npar->status_info = M3UA_NOTIFY_I_AS_PEND;
+ break;
+ case XUA_AS_S_DOWN:
+ default:
+ /* Nothing will be sent anyway... */
+ return;
+ }
+
+ /* Add the routing context, if it is configured */
+ if (as->cfg.routing_key.context) {
+ npar->presence |= NOTIFY_PAR_P_ROUTE_CTX;
+ npar->route_ctx = as->cfg.routing_key.context;
+ }
+}
+
/* is the given AS one with a single ASP of IPA type? */
static bool is_single_ipa_asp(struct osmo_ss7_as *as)
{
@@ -351,21 +395,21 @@
{
struct xua_as_fsm_priv *xafp = (struct xua_as_fsm_priv *) fi->priv;
struct osmo_ss7_as *as = xafp->as;
- struct osmo_xlm_prim_notify npar = {
- .status_type = M3UA_NOTIFY_T_STATCHG,
- };
+ struct osmo_xlm_prim_notify npar;
+
+ fill_notify_statchg_pars(fi, &npar);
switch (fi->state) {
case XUA_AS_S_INACTIVE:
- npar.status_info = M3UA_NOTIFY_I_AS_INACT;
+ /* continue below */
break;
case XUA_AS_S_ACTIVE:
if (is_single_ipa_asp(as))
ipa_add_route(fi);
- npar.status_info = M3UA_NOTIFY_I_AS_ACT;
+ /* continue below */
break;
case XUA_AS_S_PENDING:
- npar.status_info = M3UA_NOTIFY_I_AS_PEND;
+ /* continue below */
break;
case XUA_AS_S_DOWN:
if (is_single_ipa_asp(as))
@@ -384,11 +428,7 @@
return;
}
- /* Add the routing context, if it is configured */
- if (as->cfg.routing_key.context) {
- npar.presence |= NOTIFY_PAR_P_ROUTE_CTX;
- npar.route_ctx = as->cfg.routing_key.context;
- }
+ fill_notify_statchg_pars(fi, &npar);
/* TODO: ASP-Id of ASP triggering this state change */
@@ -409,10 +449,13 @@
static void xua_as_fsm_inactive(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 xua_as_event_asp_inactive_ind_pars *inact_ind_pars;
+ struct osmo_xlm_prim_notify npar;
switch (event) {
case XUA_ASPAS_ASP_DOWN_IND:
+ asp = data;
/* one ASP transitions into ASP-DOWN */
if (check_any_other_asp_not_down(xafp->as, asp)) {
/* ignore, we stay AS_INACTIVE */
@@ -424,7 +467,11 @@
osmo_fsm_inst_state_chg(fi, XUA_AS_S_ACTIVE, 0, 0);
break;
case XUA_ASPAS_ASP_INACTIVE_IND:
- /* ignore */
+ inact_ind_pars = data;
+ if (inact_ind_pars->asp_requires_notify) {
+ fill_notify_statchg_pars(fi, &npar);
+ tx_notify(inact_ind_pars->asp, &npar);
+ }
break;
}
}
@@ -433,14 +480,19 @@
{
struct xua_as_fsm_priv *xafp = (struct xua_as_fsm_priv *) fi->priv;
struct osmo_ss7_asp *asp;
+ struct xua_as_event_asp_inactive_ind_pars *inact_ind_pars;
struct msgb *msg;
+ struct osmo_xlm_prim_notify npar;
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 */
+ inact_ind_pars = data;
+ if (check_any_other_asp_in_active(xafp->as, inact_ind_pars->asp)) {
+ if (event == XUA_ASPAS_ASP_INACTIVE_IND &&
inact_ind_pars->asp_requires_notify) {
+ fill_notify_statchg_pars(fi, &npar);
+ tx_notify(inact_ind_pars->asp, &npar);
+ } /* ASP_DOWN_IND: ignore, nothing to be sent */
} else {
uint32_t recovery_msec = xafp->as->cfg.recovery_timeout_msec;
osmo_fsm_inst_state_chg(fi, XUA_AS_S_PENDING, 0, 0);
@@ -467,7 +519,9 @@
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 xua_as_event_asp_inactive_ind_pars *inact_ind_pars;
struct msgb *msg;
+ struct osmo_xlm_prim_notify npar;
switch (event) {
case XUA_ASPAS_ASP_ACTIVE_IND:
@@ -479,7 +533,11 @@
xua_as_transmit_msg(xafp->as, msg);
break;
case XUA_ASPAS_ASP_INACTIVE_IND:
- /* ignore */
+ inact_ind_pars = data;
+ if (inact_ind_pars->asp_requires_notify) {
+ fill_notify_statchg_pars(fi, &npar);
+ tx_notify(inact_ind_pars->asp, &npar);
+ }
break;
case XUA_ASPAS_ASP_DOWN_IND:
/* ignore */
diff --git a/src/xua_as_fsm.h b/src/xua_as_fsm.h
index 0e71350..cf897e2 100644
--- a/src/xua_as_fsm.h
+++ b/src/xua_as_fsm.h
@@ -1,6 +1,7 @@
#pragma once
struct osmo_ss7_as;
+struct osmo_ss7_asp;
enum xua_as_state {
XUA_AS_S_DOWN,
@@ -9,8 +10,17 @@
XUA_AS_S_PENDING,
};
+struct xua_as_event_asp_inactive_ind_pars {
+ struct osmo_ss7_asp *asp;
+ /* RFC4666 4.3.4.5: "When an ASP moves from ASP-DOWN to ASP-INACTIVE within a
+ * particular AS, a Notify message SHOULD be sent, by the ASP-UP receptor,
+ * after sending the ASP-UP-ACK, in order to inform the ASP of the current AS
+ * state." */
+ bool asp_requires_notify;
+};
+
enum xua_as_event {
- XUA_ASPAS_ASP_INACTIVE_IND,
+ XUA_ASPAS_ASP_INACTIVE_IND, /* param: struct xua_as_event_asp_inactive_ind_pars* */
XUA_ASPAS_ASP_DOWN_IND,
XUA_ASPAS_ASP_ACTIVE_IND,
XUA_AS_E_RECOVERY_EXPD,
diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c
index 12640d6..0e39b0d 100644
--- a/src/xua_asp_fsm.c
+++ b/src/xua_asp_fsm.c
@@ -355,7 +355,7 @@
/* Helper function to dispatch an ASP->AS event to all AS of which this
* ASP is a memmber. Ignores routing contexts for now. */
-static void dispatch_to_all_as(struct osmo_fsm_inst *fi, uint32_t event)
+static void dispatch_to_all_as(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
struct xua_asp_fsm_priv *xafp = fi->priv;
struct osmo_ss7_asp *asp = xafp->asp;
@@ -365,7 +365,7 @@
llist_for_each_entry(as, &inst->as_list, list) {
if (!osmo_ss7_as_has_asp(as, asp))
continue;
- osmo_fsm_inst_dispatch(as->fi, event, asp);
+ osmo_fsm_inst_dispatch(as->fi, event, data);
}
}
@@ -418,7 +418,9 @@
static void xua_asp_fsm_down_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)
{
- dispatch_to_all_as(fi, XUA_ASPAS_ASP_DOWN_IND);
+ struct xua_asp_fsm_priv *xafp = fi->priv;
+ struct osmo_ss7_asp *asp = xafp->asp;
+ dispatch_to_all_as(fi, XUA_ASPAS_ASP_DOWN_IND, asp);
}
static void xua_asp_fsm_down(struct osmo_fsm_inst *fi, uint32_t event, void *data)
@@ -478,7 +480,17 @@
static void xua_asp_fsm_inactive_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)
{
- dispatch_to_all_as(fi, XUA_ASPAS_ASP_INACTIVE_IND);
+ struct xua_asp_fsm_priv *xafp = fi->priv;
+ /* RFC4666 4.3.4.5: "When an ASP moves from ASP-DOWN to ASP-INACTIVE within a
+ * particular AS, a Notify message SHOULD be sent, by the ASP-UP receptor,
+ * after sending the ASP-UP-ACK, in order to inform the ASP of the current AS
+ * state."
+ */
+ struct xua_as_event_asp_inactive_ind_pars pars = {
+ .asp = xafp->asp,
+ .asp_requires_notify = (prev_state == XUA_ASP_S_DOWN),
+ };
+ dispatch_to_all_as(fi, XUA_ASPAS_ASP_INACTIVE_IND, &pars);
}
static void xua_asp_fsm_inactive(struct osmo_fsm_inst *fi, uint32_t event, void *data)
@@ -596,7 +608,9 @@
static void xua_asp_fsm_active_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)
{
- dispatch_to_all_as(fi, XUA_ASPAS_ASP_ACTIVE_IND);
+ struct xua_asp_fsm_priv *xafp = fi->priv;
+ struct osmo_ss7_asp *asp = xafp->asp;
+ dispatch_to_all_as(fi, XUA_ASPAS_ASP_ACTIVE_IND, asp);
}
static void xua_asp_fsm_active(struct osmo_fsm_inst *fi, uint32_t event, void *data)
@@ -1047,8 +1061,14 @@
static void ipa_asp_fsm_active_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)
{
- dispatch_to_all_as(fi, XUA_ASPAS_ASP_INACTIVE_IND);
- dispatch_to_all_as(fi, XUA_ASPAS_ASP_ACTIVE_IND);
+ struct ipa_asp_fsm_priv *iafp = fi->priv;
+ struct osmo_ss7_asp *asp = iafp->asp;
+ struct xua_as_event_asp_inactive_ind_pars pars = {
+ .asp = asp,
+ .asp_requires_notify = false,
+ };
+ dispatch_to_all_as(fi, XUA_ASPAS_ASP_INACTIVE_IND, &pars);
+ dispatch_to_all_as(fi, XUA_ASPAS_ASP_ACTIVE_IND, asp);
}
/* Server + Client: We're actively transmitting user data */
@@ -1064,7 +1084,12 @@
static void ipa_asp_fsm_inactive_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)
{
- dispatch_to_all_as(fi, XUA_ASPAS_ASP_INACTIVE_IND);
+ struct ipa_asp_fsm_priv *iafp = fi->priv;
+ struct xua_as_event_asp_inactive_ind_pars pars = {
+ .asp = iafp->asp,
+ .asp_requires_notify = false,
+ };
+ dispatch_to_all_as(fi, XUA_ASPAS_ASP_INACTIVE_IND, &pars);
}
static void ipa_asp_fsm_inactive(struct osmo_fsm_inst *fi, uint32_t event, void *data)
diff --git a/src/xua_rkm.c b/src/xua_rkm.c
index f616a3a..9e77095 100644
--- a/src/xua_rkm.c
+++ b/src/xua_rkm.c
@@ -346,7 +346,16 @@
if (!as)
continue;
/* Notify AS that it has an INACTIVE ASP */
- osmo_fsm_inst_dispatch(as->fi, XUA_ASPAS_ASP_INACTIVE_IND, asp);
+ /* RFC4666 4.3.4.5: "When an ASP moves from ASP-DOWN to ASP-INACTIVE within a
+ * particular AS, a Notify message SHOULD be sent, by the ASP-UP receptor,
+ * after sending the ASP-UP-ACK, in order to inform the ASP of the current AS
+ * state."
+ */
+ struct xua_as_event_asp_inactive_ind_pars pars = {
+ .asp = asp,
+ .asp_requires_notify = true,
+ };
+ osmo_fsm_inst_dispatch(as->fi, XUA_ASPAS_ASP_INACTIVE_IND, &pars);
}
return 0;
--
To view, visit
https://gerrit.osmocom.org/c/libosmo-sigtran/+/39640?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: I3dffa2e9c554f03c7c721b757ff33a89961665b5
Gerrit-Change-Number: 39640
Gerrit-PatchSet: 6
Gerrit-Owner: pespin <pespin(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: osmith <osmith(a)sysmocom.de>
Gerrit-Reviewer: pespin <pespin(a)sysmocom.de>