diff options
author | Harald Welte <laforge@osmocom.org> | 2021-04-25 18:45:07 +0200 |
---|---|---|
committer | laforge <laforge@osmocom.org> | 2021-04-26 19:43:31 +0000 |
commit | 5b0ec1ce67ede894d2fc8f96422f915280d07611 (patch) | |
tree | 7c7c25a7301fb5a5b6c14fbe883a23e68698dd86 /src/xua_as_fsm.c | |
parent | 6b799aeb67c09ce4c4b9e531afb0bcc7093ebd37 (diff) |
ipa: Move automatic route add/del from ASP to AS level
SS7 routes operate on AS level, not ASP level. However, the
automatic SS7 route creation/destruction for IPA was implemented
at the ASP level. This works for single-connection ASs, but
obviously fails in load-share situations: We attempt to add the
same route several times, and we delete it at the first ASP
disconnect, even while other ASPs still exist.
This patch moves the IPA route creation/deletion from the ASP level
to the AS level. When the AS becomes active, the route is added;
when it goes to DOWN state, it is removed.
Change-Id: Idb602beae3e9bc19f7bd96355c02ec8dfd9c5d6c
Diffstat (limited to 'src/xua_as_fsm.c')
-rw-r--r-- | src/xua_as_fsm.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/src/xua_as_fsm.c b/src/xua_as_fsm.c index 7c791cf..f66ba88 100644 --- a/src/xua_as_fsm.c +++ b/src/xua_as_fsm.c @@ -202,6 +202,66 @@ struct xua_as_fsm_priv { } recovery; }; +/* is the given AS one with a single ASP of IPA type? */ +static bool is_single_ipa_asp(struct osmo_ss7_as *as) +{ + unsigned int asp_count = 0; + int i; + + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + struct osmo_ss7_asp *asp = as->cfg.asps[i]; + if (!asp) + continue; + asp_count++; + if (asp->cfg.proto != OSMO_SS7_ASP_PROT_IPA) + return false; + } + if (asp_count == 1) + return true; + return false; +} + +static void ipa_add_route(struct osmo_fsm_inst *fi) +{ + struct xua_as_fsm_priv *xafp = (struct xua_as_fsm_priv *) fi->priv; + struct osmo_ss7_as *as = xafp->as; + struct osmo_ss7_instance *inst = as->inst; + + /* As opposed to M3UA, there is no RKM and we have to implicitly + * automatically add a route once an IPA connection has come up */ + osmo_ss7_route_create(inst->rtable_system, as->cfg.routing_key.pc, 0xffffff, as->cfg.name); +} + +static void ipa_del_route(struct osmo_fsm_inst *fi) +{ + struct xua_as_fsm_priv *xafp = (struct xua_as_fsm_priv *) fi->priv; + struct osmo_ss7_as *as = xafp->as; + struct osmo_ss7_instance *inst = as->inst; + struct osmo_ss7_route *rt; + + /* find the route which we have created if we ever reached ipa_asp_fsm_wait_id_ack2 */ + rt = osmo_ss7_route_find_dpc_mask(inst->rtable_system, as->cfg.routing_key.pc, 0xffffff); + /* no route found, bail out */ + if (!rt) { + LOGPFSML(fi, LOGL_NOTICE, "Attempting to delete route for this IPA AS, but cannot " + "find route for DPC %s. Did you manually delete it?\n", + osmo_ss7_pointcode_print(inst, as->cfg.routing_key.pc)); + return; + } + + /* route points to different AS, bail out */ + if (rt->dest.as != as) { + LOGPFSML(fi, LOGL_NOTICE, "Attempting to delete route for this IPA ASP, but found " + "route for DPC %s points to different AS (%s)\n", + osmo_ss7_pointcode_print(inst, as->cfg.routing_key.pc), rt->dest.as->cfg.name); + return; + } + + osmo_ss7_route_destroy(rt); +} + + + /* is any other ASP in this AS in state != DOWN? */ static bool check_any_other_asp_not_down(struct osmo_ss7_as *as, struct osmo_ss7_asp *asp_cmp) { @@ -309,12 +369,16 @@ static void xua_as_fsm_onenter(struct osmo_fsm_inst *fi, uint32_t old_state) npar.status_info = M3UA_NOTIFY_I_AS_INACT; break; case XUA_AS_S_ACTIVE: + if (is_single_ipa_asp(as)) + ipa_add_route(fi); npar.status_info = M3UA_NOTIFY_I_AS_ACT; break; case XUA_AS_S_PENDING: npar.status_info = M3UA_NOTIFY_I_AS_PEND; break; case XUA_AS_S_DOWN: + if (is_single_ipa_asp(as)) + ipa_del_route(fi); /* RFC4666 sec 4.3.2 AS States: If we end up here, it means no ASP is ACTIVE or INACTIVE, meaning no ASP can have already configured the traffic mode |