summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@osmocom.org>2019-10-22 20:24:14 +0200
committerHarald Welte <laforge@osmocom.org>2019-10-29 14:21:56 +0100
commitf3254d5b2191579c449e44aacb431e8e514d0d54 (patch)
treec3150be5be2895c7d0de9f6a2e6f1eb2770dd57a
parentbe1210f6b4bc39b083d676c883edb813d5cc4e62 (diff)
M3UA: Reject ASP activation + RKM registration for incompatible traffic-mode
If the AS is e.g. configured as broadcast, then individual ASPs cannot be activated in loadshare or override. Everyone must agree. Change-Id: Ic73410fbc88d50710202453f759fa132ce14db4c
-rw-r--r--include/osmocom/sigtran/osmo_ss7.h4
-rw-r--r--src/osmo_ss7.c25
-rw-r--r--src/xua_asp_fsm.c18
-rw-r--r--src/xua_rkm.c12
4 files changed, 53 insertions, 6 deletions
diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h
index 1b5fc31..e1f72fd 100644
--- a/include/osmocom/sigtran/osmo_ss7.h
+++ b/include/osmocom/sigtran/osmo_ss7.h
@@ -314,7 +314,10 @@ struct osmo_ss7_as {
enum osmo_ss7_asp_protocol proto;
struct osmo_ss7_routing_key routing_key;
enum osmo_ss7_as_traffic_mode mode;
+ /* traffic mode was configured by VTY / config file */
bool mode_set_by_vty;
+ /* traffic mode was configured by RKM (routing key management) */
+ bool mode_set_by_rkm;
uint32_t recovery_timeout_msec;
uint8_t qos_class;
struct {
@@ -525,6 +528,7 @@ osmo_sccp_simple_server_add_clnt(struct osmo_sccp_instance *inst,
enum osmo_ss7_as_traffic_mode osmo_ss7_tmode_from_xua(uint32_t in);
int osmo_ss7_tmode_to_xua(enum osmo_ss7_as_traffic_mode tmod);
+bool osmo_ss7_as_tmode_compatible_xua(struct osmo_ss7_as *as, uint32_t m3ua_tmt);
/* VTY related */
struct vty;
diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c
index efbceb8..c982370 100644
--- a/src/osmo_ss7.c
+++ b/src/osmo_ss7.c
@@ -2059,6 +2059,31 @@ enum osmo_ss7_as_traffic_mode osmo_ss7_tmode_from_xua(uint32_t in)
}
}
+bool osmo_ss7_as_tmode_compatible_xua(struct osmo_ss7_as *as, uint32_t m3ua_tmt)
+{
+ if (!as->cfg.mode_set_by_vty && !as->cfg.mode_set_by_rkm)
+ return true;
+
+ switch (m3ua_tmt) {
+ case M3UA_TMOD_OVERRIDE:
+ if (as->cfg.mode== OSMO_SS7_AS_TMOD_OVERRIDE)
+ return true;
+ break;
+ case M3UA_TMOD_LOADSHARE:
+ if (as->cfg.mode == OSMO_SS7_AS_TMOD_LOADSHARE ||
+ as->cfg.mode == OSMO_SS7_AS_TMOD_ROUNDROBIN)
+ return true;
+ break;
+ case M3UA_TMOD_BCAST:
+ if (as->cfg.mode == OSMO_SS7_AS_TMOD_BCAST)
+ return true;
+ break;
+ default:
+ break;
+ }
+ return false;
+}
+
static osmo_ss7_asp_rx_unknown_cb *g_osmo_ss7_asp_rx_unknown_cb;
int ss7_asp_rx_unknown(struct osmo_ss7_asp *asp, int ppid_mux, struct msgb *msg)
diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c
index 9880d55..1f27201 100644
--- a/src/xua_asp_fsm.c
+++ b/src/xua_asp_fsm.c
@@ -416,9 +416,8 @@ static void xua_asp_fsm_inactive(struct osmo_fsm_inst *fi, uint32_t event, void
struct xua_asp_fsm_priv *xafp = fi->priv;
struct osmo_ss7_asp *asp = xafp->asp;
struct xua_msg *xua_in;
- uint32_t traf_mode;
+ uint32_t traf_mode = 0;
struct xua_msg_part *part;
- uint32_t rctx;
int i;
check_stop_t_ack(fi, event);
@@ -457,16 +456,25 @@ static void xua_asp_fsm_inactive(struct osmo_fsm_inst *fi, uint32_t event, void
traf_mode != M3UA_TMOD_LOADSHARE &&
traf_mode != M3UA_TMOD_BCAST) {
peer_send_error(fi, M3UA_ERR_UNSUPP_TRAF_MOD_TYP);
- break;
+ return;
}
}
if ((part = xua_msg_find_tag(xua_in, M3UA_IEI_ROUTE_CTX))) {
for (i = 0; i < part->len / sizeof(uint32_t); i++) {
- rctx = osmo_load32be(&part->dat[i * sizeof(uint32_t)]);
- if (!osmo_ss7_as_find_by_rctx(asp->inst, rctx)) {
+ uint32_t rctx = osmo_load32be(&part->dat[i * sizeof(uint32_t)]);
+ struct osmo_ss7_as *as = osmo_ss7_as_find_by_rctx(asp->inst, rctx);
+ if (!as) {
peer_send_error(fi, M3UA_ERR_INVAL_ROUT_CTX);
return;
}
+ if (traf_mode) { /* if the peer has specified a traffic mode at all */
+ /* Check if given AS(s) are configured for the respective
+ * traffic mode type; send ERROR if not */
+ if (!osmo_ss7_as_tmode_compatible_xua(as, traf_mode)) {
+ peer_send_error(fi, M3UA_ERR_UNSUPP_TRAF_MOD_TYP);
+ return;
+ }
+ }
}
}
/* send ACK */
diff --git a/src/xua_rkm.c b/src/xua_rkm.c
index b3c785f..c9dfc2e 100644
--- a/src/xua_rkm.c
+++ b/src/xua_rkm.c
@@ -217,8 +217,18 @@ static int handle_rkey_reg(struct osmo_ss7_asp *asp, struct xua_msg *inner,
msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_INVAL_RKEY, 0);
return -1;
}
- if (!as->cfg.mode_set_by_vty && _tmode)
+ if (!as->cfg.mode_set_by_vty && _tmode) {
as->cfg.mode = osmo_ss7_tmode_from_xua(_tmode);
+ as->cfg.mode_set_by_rkm = true;
+ } else if (_tmode) {
+ /* verify if existing AS has same traffic-mode as new request (if any) */
+ if (!osmo_ss7_as_tmode_compatible_xua(as, _tmode)) {
+ LOGPASP(asp, DLSS7, LOGL_NOTICE, "RKM: Non-matching Traffic Mode %u\n",
+ _tmode);
+ msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_UNSUPP_TRAF_MODE, 0);
+ return -1;
+ }
+ }
} else if (asp->inst->cfg.permit_dyn_rkm_alloc) {
/* Create an AS for this routing key */
snprintf(namebuf, sizeof(namebuf), "as-rkm-%u", rctx);