diff options
author | Pau Espin Pedrol <pespin@sysmocom.de> | 2023-09-29 17:35:48 +0200 |
---|---|---|
committer | Pau Espin Pedrol <pespin@sysmocom.de> | 2023-09-29 17:36:32 +0200 |
commit | 4a744e223420c6d4003fb825e9e2b674ee79a216 (patch) | |
tree | 9bec42877e9cd68de1bd457dd8e81aebf38c6088 | |
parent | e39a1047270f49d849754cc5c931cdce4c451b4d (diff) |
Split osmo_ss7_as functionalities to its own file
Change-Id: I6e39dcb594ffe918ba117fce08cae7b5a6fd2dcc
-rw-r--r-- | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/osmo_ss7.c | 172 | ||||
-rw-r--r-- | src/osmo_ss7_as.c | 211 | ||||
-rw-r--r-- | src/ss7_internal.h | 2 |
4 files changed, 215 insertions, 171 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 2067259..be6442d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -37,6 +37,7 @@ libosmo_sigtran_la_SOURCES = \ ipa.c \ m3ua.c \ osmo_ss7.c \ + osmo_ss7_as.c \ osmo_ss7_asp.c \ osmo_ss7_asp_peer.c \ osmo_ss7_hmrt.c \ diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 1e8bcfb..dbbef6b 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -69,14 +69,6 @@ const struct value_string mtp_unavail_cause_vals[] = { { 0, NULL } }; -struct value_string osmo_ss7_as_traffic_mode_vals[] = { - { OSMO_SS7_AS_TMOD_BCAST, "broadcast" }, - { OSMO_SS7_AS_TMOD_LOADSHARE, "loadshare" }, - { OSMO_SS7_AS_TMOD_ROUNDROBIN, "round-robin" }, - { OSMO_SS7_AS_TMOD_OVERRIDE, "override" }, - { 0, NULL } -}; - int osmo_ss7_find_free_rctx(struct osmo_ss7_instance *inst) { int32_t rctx; @@ -88,7 +80,7 @@ int osmo_ss7_find_free_rctx(struct osmo_ss7_instance *inst) return -1; } -static uint32_t find_free_l_rk_id(struct osmo_ss7_instance *inst) +uint32_t ss7_find_free_l_rk_id(struct osmo_ss7_instance *inst) { uint32_t l_rk_id; @@ -855,19 +847,6 @@ const char *osmo_ss7_route_print(const struct osmo_ss7_route *rt) * SS7 Application Server ***********************************************************************/ -static const struct rate_ctr_desc ss7_as_rcd[] = { - [SS7_AS_CTR_RX_MSU_TOTAL] = { "rx:msu:total", "Total number of MSU received" }, - [SS7_AS_CTR_TX_MSU_TOTAL] = { "tx:msu:total", "Total number of MSU transmitted" }, -}; - -static const struct rate_ctr_group_desc ss7_as_rcgd = { - .group_name_prefix = "sigtran_as", - .group_description = "SIGTRAN Application Server", - .num_ctr = ARRAY_SIZE(ss7_as_rcd), - .ctr_desc = ss7_as_rcd, -}; -static unsigned int g_ss7_as_rcg_idx; - /*! \brief Find Application Server by given name * \param[in] inst SS7 Instance on which we operate * \param[in] name Name of AS @@ -954,37 +933,6 @@ struct osmo_ss7_as *osmo_ss7_as_find_by_proto(struct osmo_ss7_instance *inst, return as_without_asp; } -/*! \brief Allocate an Application Server - * \param[in] inst SS7 Instance on which we operate - * \param[in] name Name of Application Server - * \param[in] proto Protocol of Application Server - * \returns pointer to Application Server on success; NULL otherwise */ -struct osmo_ss7_as *ss7_as_alloc(struct osmo_ss7_instance *inst, const char *name, - enum osmo_ss7_asp_protocol proto) -{ - struct osmo_ss7_as *as; - - as = talloc_zero(inst, struct osmo_ss7_as); - if (!as) - return NULL; - as->ctrg = rate_ctr_group_alloc(as, &ss7_as_rcgd, g_ss7_as_rcg_idx++); - if (!as->ctrg) { - talloc_free(as); - return NULL; - } - rate_ctr_group_set_name(as->ctrg, name); - as->inst = inst; - as->cfg.name = talloc_strdup(as, name); - as->cfg.proto = proto; - as->cfg.mode = OSMO_SS7_AS_TMOD_OVERRIDE; - as->cfg.recovery_timeout_msec = 2000; - as->cfg.routing_key.l_rk_id = find_free_l_rk_id(inst); - as->fi = xua_as_fsm_start(as, LOGL_DEBUG); - llist_add_tail(&as->list, &inst->as_list); - - return as; -} - /*! \brief Find or Create Application Server * \param[in] inst SS7 Instance on which we operate * \param[in] name Name of Application Server @@ -1012,124 +960,6 @@ osmo_ss7_as_find_or_create(struct osmo_ss7_instance *inst, const char *name, return as; } -/*! \brief Add given ASP to given AS - * \param[in] as Application Server to which \ref asp is added - * \param[in] asp Application Server Process to be added to \ref as - * \returns 0 on success; negative in case of error */ -int osmo_ss7_as_add_asp(struct osmo_ss7_as *as, const char *asp_name) -{ - struct osmo_ss7_asp *asp; - unsigned int i; - - OSMO_ASSERT(ss7_initialized); - asp = osmo_ss7_asp_find_by_name(as->inst, asp_name); - if (!asp) - return -ENODEV; - - LOGPAS(as, DLSS7, LOGL_INFO, "Adding ASP %s to AS\n", asp->cfg.name); - - if (osmo_ss7_as_has_asp(as, asp)) - return 0; - - for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { - if (!as->cfg.asps[i]) { - as->cfg.asps[i] = asp; - return 0; - } - } - - return -ENOSPC; -} - -/*! \brief Delete given ASP from given AS - * \param[in] as Application Server from which \ref asp is deleted - * \param[in] asp Application Server Process to delete from \ref as - * \returns 0 on success; negative in case of error */ -int osmo_ss7_as_del_asp(struct osmo_ss7_as *as, const char *asp_name) -{ - struct osmo_ss7_asp *asp; - unsigned int i; - - OSMO_ASSERT(ss7_initialized); - asp = osmo_ss7_asp_find_by_name(as->inst, asp_name); - if (!asp) - return -ENODEV; - - LOGPAS(as, DLSS7, LOGL_INFO, "Removing ASP %s from AS\n", asp->cfg.name); - - for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { - if (as->cfg.asps[i] == asp) { - as->cfg.asps[i] = NULL; - return 0; - } - } - - return -EINVAL; -} - -/*! \brief Destroy given Application Server - * \param[in] as Application Server to destroy */ -void osmo_ss7_as_destroy(struct osmo_ss7_as *as) -{ - struct osmo_ss7_route *rt, *rt2; - - OSMO_ASSERT(ss7_initialized); - LOGPAS(as, DLSS7, LOGL_INFO, "Destroying AS\n"); - - if (as->fi) - osmo_fsm_inst_term(as->fi, OSMO_FSM_TERM_REQUEST, NULL); - - /* find any routes pointing to this AS and remove them */ - llist_for_each_entry_safe(rt, rt2, &as->inst->rtable_system->routes, list) { - if (rt->dest.as == as) - osmo_ss7_route_destroy(rt); - } - - as->inst = NULL; - llist_del(&as->list); - rate_ctr_group_free(as->ctrg); - talloc_free(as); -} - -/*! \brief Determine if given AS contains ASP - * \param[in] as Application Server in which to look for \ref asp - * \param[in] asp Application Server Process to look for in \ref as - * \returns true in case \ref asp is part of \ref as; false otherwise */ -bool osmo_ss7_as_has_asp(const struct osmo_ss7_as *as, - const struct osmo_ss7_asp *asp) -{ - unsigned int i; - - OSMO_ASSERT(ss7_initialized); - for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { - if (as->cfg.asps[i] == asp) - return true; - } - return false; -} - -/*! Determine if given AS is in the active state. - * \param[in] as Application Server. - * \returns true in case as is active; false otherwise. */ -bool osmo_ss7_as_active(const struct osmo_ss7_as *as) -{ - if (!as->fi) - return false; - return as->fi->state == XUA_AS_S_ACTIVE; -} - -/*! Determine if given AS is in the down state. - * \param[in] as Application Server. - * \returns true in case as is down; false otherwise. */ -bool osmo_ss7_as_down(const struct osmo_ss7_as *as) -{ - OSMO_ASSERT(as); - - if (!as->fi) - return true; - return as->fi->state == XUA_AS_S_DOWN; -} - bool ss7_ipv6_sctp_supported(const char *host, bool bind) { int rc; diff --git a/src/osmo_ss7_as.c b/src/osmo_ss7_as.c new file mode 100644 index 0000000..34baf52 --- /dev/null +++ b/src/osmo_ss7_as.c @@ -0,0 +1,211 @@ +/* Core SS7 AS Handling */ + +/* (C) 2015-2017 by Harald Welte <laforge@gnumonks.org> + * (C) 2023 by sysmocom s.f.m.c. GmbH <info@sysmocom.de> + * All Rights Reserved + * + * SPDX-License-Identifier: GPL-2.0+ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <inttypes.h> + +#include <osmocom/sigtran/osmo_ss7.h> + +#include <osmocom/core/linuxlist.h> +#include <osmocom/core/utils.h> +#include <osmocom/core/talloc.h> +#include <osmocom/core/logging.h> + +#include "ss7_internal.h" +#include "xua_as_fsm.h" + +/*********************************************************************** + * SS7 Application Server + ***********************************************************************/ + +struct value_string osmo_ss7_as_traffic_mode_vals[] = { + { OSMO_SS7_AS_TMOD_BCAST, "broadcast" }, + { OSMO_SS7_AS_TMOD_LOADSHARE, "loadshare" }, + { OSMO_SS7_AS_TMOD_ROUNDROBIN, "round-robin" }, + { OSMO_SS7_AS_TMOD_OVERRIDE, "override" }, + { 0, NULL } +}; + +static const struct rate_ctr_desc ss7_as_rcd[] = { + [SS7_AS_CTR_RX_MSU_TOTAL] = { "rx:msu:total", "Total number of MSU received" }, + [SS7_AS_CTR_TX_MSU_TOTAL] = { "tx:msu:total", "Total number of MSU transmitted" }, +}; + +static const struct rate_ctr_group_desc ss7_as_rcgd = { + .group_name_prefix = "sigtran_as", + .group_description = "SIGTRAN Application Server", + .num_ctr = ARRAY_SIZE(ss7_as_rcd), + .ctr_desc = ss7_as_rcd, +}; +static unsigned int g_ss7_as_rcg_idx; + +/*! \brief Allocate an Application Server + * \param[in] inst SS7 Instance on which we operate + * \param[in] name Name of Application Server + * \param[in] proto Protocol of Application Server + * \returns pointer to Application Server on success; NULL otherwise */ +struct osmo_ss7_as *ss7_as_alloc(struct osmo_ss7_instance *inst, const char *name, + enum osmo_ss7_asp_protocol proto) +{ + struct osmo_ss7_as *as; + + as = talloc_zero(inst, struct osmo_ss7_as); + if (!as) + return NULL; + as->ctrg = rate_ctr_group_alloc(as, &ss7_as_rcgd, g_ss7_as_rcg_idx++); + if (!as->ctrg) { + talloc_free(as); + return NULL; + } + rate_ctr_group_set_name(as->ctrg, name); + as->inst = inst; + as->cfg.name = talloc_strdup(as, name); + as->cfg.proto = proto; + as->cfg.mode = OSMO_SS7_AS_TMOD_OVERRIDE; + as->cfg.recovery_timeout_msec = 2000; + as->cfg.routing_key.l_rk_id = ss7_find_free_l_rk_id(inst); + as->fi = xua_as_fsm_start(as, LOGL_DEBUG); + llist_add_tail(&as->list, &inst->as_list); + + return as; +} + +/*! \brief Add given ASP to given AS + * \param[in] as Application Server to which \ref asp is added + * \param[in] asp Application Server Process to be added to \ref as + * \returns 0 on success; negative in case of error */ +int osmo_ss7_as_add_asp(struct osmo_ss7_as *as, const char *asp_name) +{ + struct osmo_ss7_asp *asp; + unsigned int i; + + OSMO_ASSERT(ss7_initialized); + asp = osmo_ss7_asp_find_by_name(as->inst, asp_name); + if (!asp) + return -ENODEV; + + LOGPAS(as, DLSS7, LOGL_INFO, "Adding ASP %s to AS\n", asp->cfg.name); + + if (osmo_ss7_as_has_asp(as, asp)) + return 0; + + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + if (!as->cfg.asps[i]) { + as->cfg.asps[i] = asp; + return 0; + } + } + + return -ENOSPC; +} + +/*! \brief Delete given ASP from given AS + * \param[in] as Application Server from which \ref asp is deleted + * \param[in] asp Application Server Process to delete from \ref as + * \returns 0 on success; negative in case of error */ +int osmo_ss7_as_del_asp(struct osmo_ss7_as *as, const char *asp_name) +{ + struct osmo_ss7_asp *asp; + unsigned int i; + + OSMO_ASSERT(ss7_initialized); + asp = osmo_ss7_asp_find_by_name(as->inst, asp_name); + if (!asp) + return -ENODEV; + + LOGPAS(as, DLSS7, LOGL_INFO, "Removing ASP %s from AS\n", asp->cfg.name); + + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + if (as->cfg.asps[i] == asp) { + as->cfg.asps[i] = NULL; + return 0; + } + } + + return -EINVAL; +} + +/*! \brief Destroy given Application Server + * \param[in] as Application Server to destroy */ +void osmo_ss7_as_destroy(struct osmo_ss7_as *as) +{ + struct osmo_ss7_route *rt, *rt2; + + OSMO_ASSERT(ss7_initialized); + LOGPAS(as, DLSS7, LOGL_INFO, "Destroying AS\n"); + + if (as->fi) + osmo_fsm_inst_term(as->fi, OSMO_FSM_TERM_REQUEST, NULL); + + /* find any routes pointing to this AS and remove them */ + llist_for_each_entry_safe(rt, rt2, &as->inst->rtable_system->routes, list) { + if (rt->dest.as == as) + osmo_ss7_route_destroy(rt); + } + + as->inst = NULL; + llist_del(&as->list); + rate_ctr_group_free(as->ctrg); + talloc_free(as); +} + +/*! \brief Determine if given AS contains ASP + * \param[in] as Application Server in which to look for \ref asp + * \param[in] asp Application Server Process to look for in \ref as + * \returns true in case \ref asp is part of \ref as; false otherwise */ +bool osmo_ss7_as_has_asp(const struct osmo_ss7_as *as, + const struct osmo_ss7_asp *asp) +{ + unsigned int i; + + OSMO_ASSERT(ss7_initialized); + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + if (as->cfg.asps[i] == asp) + return true; + } + return false; +} + +/*! Determine if given AS is in the active state. + * \param[in] as Application Server. + * \returns true in case as is active; false otherwise. */ +bool osmo_ss7_as_active(const struct osmo_ss7_as *as) +{ + if (!as->fi) + return false; + return as->fi->state == XUA_AS_S_ACTIVE; +} + +/*! Determine if given AS is in the down state. + * \param[in] as Application Server. + * \returns true in case as is down; false otherwise. */ +bool osmo_ss7_as_down(const struct osmo_ss7_as *as) +{ + OSMO_ASSERT(as); + + if (!as->fi) + return true; + return as->fi->state == XUA_AS_S_DOWN; +} diff --git a/src/ss7_internal.h b/src/ss7_internal.h index 4539609..6449c5b 100644 --- a/src/ss7_internal.h +++ b/src/ss7_internal.h @@ -3,9 +3,11 @@ /* Internal header used by libosmo-sccp, not available publicly for lib users */ #include <stdbool.h> +#include <stdint.h> #include <osmocom/sigtran/osmo_ss7.h> extern bool ss7_initialized; +uint32_t ss7_find_free_l_rk_id(struct osmo_ss7_instance *inst); bool ss7_ipv6_sctp_supported(const char *host, bool bind); |