aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2019-11-05 18:24:29 +0100
committerlaforge <laforge@osmocom.org>2019-11-05 20:41:56 +0000
commit907121b85d50283a7e08eede27fd5d7bb112b89b (patch)
tree3b4134a8a161729de2ac02c91f1def3c6f0888f8
parent02d0228a4000234bfb1aafb40d6adff5d9ce4c55 (diff)
xua: Allow traffic mode set by peer if not set by VTY
-rw-r--r--include/osmocom/sigtran/osmo_ss7.h3
-rw-r--r--src/xua_asp_fsm.c33
-rw-r--r--src/xua_rkm.c24
3 files changed, 53 insertions, 7 deletions
diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h
index 1b5fc31..4f20d81 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) or ASPAC */
+ bool mode_set_by_peer;
uint32_t recovery_timeout_msec;
uint8_t qos_class;
struct {
diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c
index a6ee2ec..5814532 100644
--- a/src/xua_asp_fsm.c
+++ b/src/xua_asp_fsm.c
@@ -415,10 +415,11 @@ 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 osmo_ss7_as *as;
struct xua_msg *xua_in;
- uint32_t traf_mode;
+ uint32_t traf_mode = 0;
+ enum osmo_ss7_as_traffic_mode tmode;
struct xua_msg_part *part;
- uint32_t rctx;
int i;
check_stop_t_ack(fi, event);
@@ -459,16 +460,40 @@ static void xua_asp_fsm_inactive(struct osmo_fsm_inst *fi, uint32_t event, void
peer_send_error(fi, M3UA_ERR_UNSUPP_TRAF_MOD_TYP);
return;
}
+ tmode = osmo_ss7_tmode_from_xua(traf_mode);
}
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)]);
+ 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 */
+ llist_for_each_entry(as, &asp->inst->as_list, list) {
+ if (!osmo_ss7_as_has_asp(as, asp))
+ continue;
+
+ if (!as->cfg.mode_set_by_peer && !as->cfg.mode_set_by_vty) {
+ as->cfg.mode = tmode;
+ 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 */
+ peer_send_error(fi, M3UA_ERR_UNSUPP_TRAF_MOD_TYP);
+ return;
+ }
+ as->cfg.mode_set_by_peer = true;
+ }
+ }
+
/* send ACK */
peer_send(fi, XUA_ASP_E_ASPTM_ASPAC_ACK, xua_in);
/* transition state and inform layer manager */
diff --git a/src/xua_rkm.c b/src/xua_rkm.c
index b3c785f..a61ac31 100644
--- a/src/xua_rkm.c
+++ b/src/xua_rkm.c
@@ -152,6 +152,7 @@ static int handle_rkey_reg(struct osmo_ss7_asp *asp, struct xua_msg *inner,
unsigned int max_nas_idx, unsigned int *nas_idx)
{
uint32_t rk_id, rctx, _tmode, dpc;
+ enum osmo_ss7_as_traffic_mode tmode;
struct osmo_ss7_as *as;
struct osmo_ss7_route *rt;
char namebuf[32];
@@ -217,8 +218,23 @@ 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)
- as->cfg.mode = osmo_ss7_tmode_from_xua(_tmode);
+ if (_tmode) { /* if the peer has specified a traffic mode at all */
+ tmode = osmo_ss7_tmode_from_xua(_tmode);
+ if (!as->cfg.mode_set_by_peer && !as->cfg.mode_set_by_vty) {
+ as->cfg.mode = tmode;
+ 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 */
+ 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);
+ return -1;
+ }
+ as->cfg.mode_set_by_peer = true;
+ }
} else if (asp->inst->cfg.permit_dyn_rkm_alloc) {
/* Create an AS for this routing key */
snprintf(namebuf, sizeof(namebuf), "as-rkm-%u", rctx);
@@ -231,8 +247,10 @@ static int handle_rkey_reg(struct osmo_ss7_asp *asp, struct xua_msg *inner,
as->cfg.description = talloc_strdup(as, "Auto-generated by RKM");
as->rkm_dyn_allocated = true;
- 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_peer = true;
+ }
/* fill routing key */
as->cfg.routing_key.pc = dpc;
as->cfg.routing_key.context = rctx;