summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@osmocom.org>2019-10-22 20:24:14 +0200
committerlaforge <laforge@osmocom.org>2019-11-05 20:50:26 +0000
commitebd2fc60461763e756e5a6c3176a33f3fa005282 (patch)
treee92825f86065ed3f06024456e34624e2eb97600a
parent907121b85d50283a7e08eede27fd5d7bb112b89b (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.h3
-rw-r--r--src/osmo_ss7.c25
-rw-r--r--src/xua_asp_fsm.c5
-rw-r--r--src/xua_rkm.c5
4 files changed, 30 insertions, 8 deletions
diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h
index 4f20d81..04058c2 100644
--- a/include/osmocom/sigtran/osmo_ss7.h
+++ b/include/osmocom/sigtran/osmo_ss7.h
@@ -316,7 +316,7 @@ struct osmo_ss7_as {
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) or ASPAC */
+ /* traffic mode was configured by RKM (routing key management) or first ASPAC */
bool mode_set_by_peer;
uint32_t recovery_timeout_msec;
uint8_t qos_class;
@@ -346,6 +346,7 @@ int osmo_ss7_as_del_asp(struct osmo_ss7_as *as, const char *asp_name);
void osmo_ss7_as_destroy(struct osmo_ss7_as *as);
bool osmo_ss7_as_has_asp(struct osmo_ss7_as *as,
struct osmo_ss7_asp *asp);
+bool osmo_ss7_as_tmode_compatible_xua(struct osmo_ss7_as *as, uint32_t m3ua_tmt);
void osmo_ss7_asp_disconnect(struct osmo_ss7_asp *asp);
diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c
index efbceb8..87f1245 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_peer)
+ 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 5814532..16c06d6 100644
--- a/src/xua_asp_fsm.c
+++ b/src/xua_asp_fsm.c
@@ -483,10 +483,7 @@ static void xua_asp_fsm_inactive(struct osmo_fsm_inst *fi, uint32_t event, void
LOGPAS(as, DLSS7, LOGL_INFO,
"ASPAC: Traffic mode set dynamically by peer to %s\n",
osmo_ss7_as_traffic_mode_name(as->cfg.mode));
- } else if (as->cfg.mode != tmode) {
- /*FIXME: ^ properly check if tmode is
- compatible with already set
- as->cfg.mode */
+ } else if (!osmo_ss7_as_tmode_compatible_xua(as, traf_mode)) {
peer_send_error(fi, M3UA_ERR_UNSUPP_TRAF_MOD_TYP);
return;
}
diff --git a/src/xua_rkm.c b/src/xua_rkm.c
index a61ac31..10335ea 100644
--- a/src/xua_rkm.c
+++ b/src/xua_rkm.c
@@ -225,9 +225,8 @@ static int handle_rkey_reg(struct osmo_ss7_asp *asp, struct xua_msg *inner,
LOGPAS(as, DLSS7, LOGL_INFO,
"RKM: Traffic mode set dynamically by peer to %s\n",
osmo_ss7_as_traffic_mode_name(as->cfg.mode));
- } else if (as->cfg.mode != tmode) {
- /*FIXME: ^ properly check if tmode is
- compatible with already set as->cfg.mode */
+ /* verify if existing AS has same traffic-mode as new request (if any) */
+ } else if (!osmo_ss7_as_tmode_compatible_xua(as, _tmode)) {
LOGPASP(asp, DLSS7, LOGL_NOTICE, "RKM: Non-matching Traffic Mode %s\n",
osmo_ss7_as_traffic_mode_name(tmode));
msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_UNSUPP_TRAF_MODE, 0);