pespin has submitted this change. ( https://gerrit.osmocom.org/c/libosmo-sigtran/+/40011?usp=email )
Change subject: Tx multiple Routing Contexts in NOTIFY on ASPs serving multiple AS ......................................................................
Tx multiple Routing Contexts in NOTIFY on ASPs serving multiple AS
Routing Context IE in NOTIFY msg should contain n X 32-bit integers, one for each Routing Context (AS) this ASP is serving. This fixes only 1 AS being announced during NOTIFY if the ASP was configured to server more than one AS.
Change-Id: I646301ec3d08ef98f227cf4d19da1039e40cedd2 --- M include/osmocom/sigtran/sigtran_sap.h M src/m3ua.c M src/osmo_ss7_asp.c M src/ss7_asp.h M src/xua_as_fsm.c M src/xua_msg.c M src/xua_msg.h 7 files changed, 87 insertions(+), 16 deletions(-)
Approvals: laforge: Looks good to me, but someone else must approve pespin: Looks good to me, approved Jenkins Builder: Verified osmith: Looks good to me, but someone else must approve
diff --git a/include/osmocom/sigtran/sigtran_sap.h b/include/osmocom/sigtran/sigtran_sap.h index 87504c8..610c711 100644 --- a/include/osmocom/sigtran/sigtran_sap.h +++ b/include/osmocom/sigtran/sigtran_sap.h @@ -39,7 +39,8 @@ uint16_t status_type; uint16_t status_info; uint32_t asp_id; - uint32_t route_ctx; + uint32_t route_ctx_count; + uint32_t route_ctx[OSMO_SS7_MAX_RCTX_COUNT]; char *info_string; };
diff --git a/src/m3ua.c b/src/m3ua.c index 04ee7c5..b64bfad 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -427,8 +427,11 @@ xua_msg_add_u32(xua, M3UA_IEI_ASP_ID, npar->asp_id);
/* Optional Routing Context */ - if (npar->presence & NOTIFY_PAR_P_ROUTE_CTX) - xua_msg_add_u32(xua, M3UA_IEI_ROUTE_CTX, npar->route_ctx); + if (npar->presence & NOTIFY_PAR_P_ROUTE_CTX) { + xua_msg_add_u32_data(xua, M3UA_IEI_ROUTE_CTX, + npar->route_ctx_count * sizeof(npar->route_ctx[0]), + (uint8_t *)&npar->route_ctx[0]); + }
/* Optional: Info String */ if (npar->info_string) @@ -468,7 +471,20 @@ }
if (rctx_ie) { - npar->route_ctx = xua_msg_part_get_u32(rctx_ie); + if (rctx_ie->len & 0x03) { + LOGP(DLM3UA, LOGL_ERROR, + "M3UA NOTIFY with Routing Context IE length non-multiple of 4!\n"); + return -1; + } + if (rctx_ie->len > sizeof(npar->route_ctx)) { + LOGP(DLM3UA, LOGL_ERROR, + "M3UA NOTIFY with Routing Context IE containing > %zu items not supported!\n", + ARRAY_SIZE(npar->route_ctx)); + return -1; + } + npar->route_ctx_count = rctx_ie->len >> 2; + for (unsigned int i = 0; i < npar->route_ctx_count; i++) + npar->route_ctx[i] = ntohl(*(uint32_t *)&rctx_ie->dat[i << 2]); npar->presence |= NOTIFY_PAR_P_ROUTE_CTX; }
diff --git a/src/osmo_ss7_asp.c b/src/osmo_ss7_asp.c index 02dbcb8..f2d511a 100644 --- a/src/osmo_ss7_asp.c +++ b/src/osmo_ss7_asp.c @@ -1313,8 +1313,8 @@ }
/* Obtain all routing contexts (in network byte order) that exist within the given ASP */ -unsigned int ss7_asp_get_all_rctx_be(const struct osmo_ss7_asp *asp, uint32_t *rctx, unsigned int rctx_size, - const struct osmo_ss7_as *excl_as) +static unsigned int _ss7_asp_get_all_rctx(const struct osmo_ss7_asp *asp, uint32_t *rctx, unsigned int rctx_size, + const struct osmo_ss7_as *excl_as, bool network_byte_order) { unsigned int count = 0; struct osmo_ss7_as *as; @@ -1328,8 +1328,25 @@ continue; if (count >= rctx_size) break; - rctx[count] = htonl(as->cfg.routing_key.context); + if (network_byte_order) + rctx[count] = htonl(as->cfg.routing_key.context); + else + rctx[count] = as->cfg.routing_key.context; count++; } return count; } + +/* Obtain all routing contexts (in network byte order) that exist within the given ASP */ +unsigned int ss7_asp_get_all_rctx_be(const struct osmo_ss7_asp *asp, uint32_t *rctx, unsigned int rctx_size, + const struct osmo_ss7_as *excl_as) +{ + return _ss7_asp_get_all_rctx(asp, rctx, rctx_size, excl_as, true); +} + +/* Obtain all routing contexts (in host byte order) that exist within the given ASP */ +unsigned int ss7_asp_get_all_rctx(const struct osmo_ss7_asp *asp, uint32_t *rctx, unsigned int rctx_size, + const struct osmo_ss7_as *excl_as) +{ + return _ss7_asp_get_all_rctx(asp, rctx, rctx_size, excl_as, false); +} diff --git a/src/ss7_asp.h b/src/ss7_asp.h index bdde5bd..5dee90a 100644 --- a/src/ss7_asp.h +++ b/src/ss7_asp.h @@ -128,6 +128,8 @@ void ss7_asp_restart_after_reconfigure(struct osmo_ss7_asp *asp); void osmo_ss7_asp_remove_default_lm(struct osmo_ss7_asp *asp);
+unsigned int ss7_asp_get_all_rctx(const struct osmo_ss7_asp *asp, uint32_t *rctx, unsigned int rctx_size, + const struct osmo_ss7_as *excl_as); unsigned int ss7_asp_get_all_rctx_be(const struct osmo_ss7_asp *asp, uint32_t *rctx, unsigned int rctx_size, const struct osmo_ss7_as *excl_as);
diff --git a/src/xua_as_fsm.c b/src/xua_as_fsm.c index 5adc469..7f7c7d6 100644 --- a/src/xua_as_fsm.c +++ b/src/xua_as_fsm.c @@ -39,7 +39,15 @@ return msg; }
-static void tx_notify(struct osmo_ss7_asp *asp, const struct osmo_xlm_prim_notify *npar) +static int fill_notify_route_ctx(const struct osmo_ss7_asp *asp, struct osmo_xlm_prim_notify *npar) +{ + npar->route_ctx_count = ss7_asp_get_all_rctx(asp, npar->route_ctx, ARRAY_SIZE(npar->route_ctx), NULL); + if (npar->route_ctx_count > 0) + npar->presence |= NOTIFY_PAR_P_ROUTE_CTX; + return 0; +} + +static void tx_notify(struct osmo_ss7_asp *asp, 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); @@ -48,6 +56,7 @@
LOGPASP(asp, DLSS7, LOGL_INFO, "Tx NOTIFY Type %s:%s (%s)\n", type_name, info_name, info_str); + fill_notify_route_ctx(asp, npar); struct msgb *msg = encode_notify(npar); osmo_ss7_asp_send(asp, msg); } @@ -93,6 +102,7 @@
LOGPASP(asp, DLSS7, LOGL_INFO, "Tx NOTIFY Type %s:%s (%s)\n", type_name, info_name, info_str); + fill_notify_route_ctx(asp, npar); msg = encode_notify(npar); osmo_ss7_asp_send(asp, msg); sent++; @@ -221,8 +231,6 @@
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, }; @@ -242,12 +250,6 @@ /* 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? */ diff --git a/src/xua_msg.c b/src/xua_msg.c index 5584b82..d32d824 100644 --- a/src/xua_msg.c +++ b/src/xua_msg.c @@ -83,6 +83,38 @@ return 0; }
+/* Add Array of host-byte-order u32 converting them to network-byte-order: */ +int xua_msg_add_u32_data(struct xua_msg *msg, uint16_t tag, + uint16_t len, const uint8_t *dat) +{ + struct xua_msg_part *part; + + if (len & 0x03) + return -1; /* non-multiple-of-4 */ + + part = talloc_zero(msg, struct xua_msg_part); + if (!part) + return -1; + + part->tag = tag; + part->len = len; + + /* do we have any data? */ + if (part->len != 0) { + part->dat = talloc_size(part, len); + if (!part->dat) { + talloc_free(part); + return -1; + } + /* Copy over data converting it to network-byte-order: */ + for (unsigned int i = 0; i < len ; i += sizeof(uint32_t)) + *((uint32_t *)&part->dat[i]) = htonl(*(uint32_t *)&dat[i]); + } + + llist_add_tail(&part->entry, &msg->headers); + return 0; +} + struct xua_msg_part *xua_msg_find_tag(const struct xua_msg *xua, uint16_t tag) { struct xua_msg_part *part; diff --git a/src/xua_msg.h b/src/xua_msg.h index 79af86f..80d4c79 100644 --- a/src/xua_msg.h +++ b/src/xua_msg.h @@ -76,6 +76,7 @@ void xua_msg_free(struct xua_msg *msg);
int xua_msg_add_data(struct xua_msg *msg, uint16_t tag, uint16_t len, const uint8_t *dat); +int xua_msg_add_u32_data(struct xua_msg *msg, uint16_t tag, uint16_t len, const uint8_t *dat);
struct xua_msg_part *xua_msg_find_tag(const struct xua_msg *msg, uint16_t tag); int xua_msg_free_tag(struct xua_msg *xua, uint16_t tag);