pespin submitted this change.
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(-)
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);
To view, visit change 40011. To unsubscribe, or for help writing mail filters, visit settings.