pespin has uploaded this change for review. ( 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/xua_as_fsm.c M src/xua_msg.c M src/xua_msg.h 5 files changed, 83 insertions(+), 13 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmo-sigtran refs/changes/11/40011/1
diff --git a/include/osmocom/sigtran/sigtran_sap.h b/include/osmocom/sigtran/sigtran_sap.h index 87504c8..e4f3766 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[16]; 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/xua_as_fsm.c b/src/xua_as_fsm.c index 5adc469..cb4d44c 100644 --- a/src/xua_as_fsm.c +++ b/src/xua_as_fsm.c @@ -39,7 +39,33 @@ 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) +{ + struct osmo_ss7_instance *inst = asp->inst; + struct osmo_ss7_as *as; + + npar->route_ctx_count = 0; + + llist_for_each_entry(as, &inst->as_list, list) { + if (!osmo_ss7_as_has_asp(as, asp)) + continue; + /* Add the routing context, if it is configured */ + if (as->cfg.routing_key.context) { + if (npar->route_ctx_count >= ARRAY_SIZE(npar->route_ctx)) { + LOGPASP(asp, DLSS7, LOGL_ERROR, + "Encoding NOTIFY with > %zu Routing Contexts unsupported!\n", + ARRAY_SIZE(npar->route_ctx)); + return -1; + } + npar->presence |= NOTIFY_PAR_P_ROUTE_CTX; + npar->route_ctx[npar->route_ctx_count] = as->cfg.routing_key.context; + npar->route_ctx_count++; + } + } + 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 +74,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 +120,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 +249,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 +268,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..71ba877 100644 --- a/src/xua_msg.c +++ b/src/xua_msg.c @@ -83,6 +83,38 @@ return 0; }
+/* Array of network-byte-order u32: */ +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);