pespin has submitted this change. ( https://gerrit.osmocom.org/c/libosmo-sigtran/+/42561?usp=email )
Change subject: Move xUA<->LM SAP logic to its own file ......................................................................
Move xUA<->LM SAP logic to its own file
Right now it's difficult to grasp what's implemented of the SAP since it was scattered around several places. Put all the SAP forwarding logic into its own file so it's easy to follow and extend (eg. adding new helper functions, etc.)
Change-Id: I93d74dd7f6ea8f2e60a8bc41be15362e433e8962 --- M src/Makefile.am M src/m3ua.c M src/ss7_asp.c M src/ss7_xua_srv.c M src/xua_asp_fsm.c M src/xua_default_lm_fsm.c M src/xua_internal.h A src/xua_lm_sap.c A src/xua_lm_sap.h M src/xua_rkm.c 10 files changed, 206 insertions(+), 98 deletions(-)
Approvals: pespin: Looks good to me, approved Jenkins Builder: Verified
diff --git a/src/Makefile.am b/src/Makefile.am index 2ef226f..d8b42f9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -30,6 +30,7 @@ tcap_trans_tracking.h \ xua_asp_fsm.h \ xua_as_fsm.h \ + xua_lm_sap.h \ xua_internal.h \ xua_msg.h \ xua_types.h \ @@ -92,6 +93,7 @@ xua_asp_fsm.c \ xua_as_fsm.c \ xua_default_lm_fsm.c \ + xua_lm_sap.c \ xua_msg.c \ xua_rkm.c \ xua_shared.c \ diff --git a/src/m3ua.c b/src/m3ua.c index d982eeb..2dd8dfb 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -49,6 +49,7 @@ #include "ss7_asp.h" #include "ss7_internal.h" #include "xua_msg.h" +#include "xua_lm_sap.h"
#define M3UA_MSGB_SIZE 1500
@@ -700,8 +701,7 @@ xua_msg_dump(xua, &xua_dialect_m3ua));
/* report this to layer manager */ - prim = xua_xlm_prim_alloc(OSMO_XLM_PRIM_M_ERROR, PRIM_OP_INDICATION); - prim->u.error.code = err_code; + prim = xua_xlm_prim_alloc_m_error_ind(err_code); xua_asp_send_xlm_prim(asp, prim);
/* NEVER return != 0 here, as we cannot respont to an ERR @@ -724,9 +724,8 @@ ntfy.info_string ? ntfy.info_string : "");
/* report this to layer manager */ - prim = xua_xlm_prim_alloc(OSMO_XLM_PRIM_M_NOTIFY, PRIM_OP_INDICATION); - prim->u.notify = ntfy; - xua_asp_send_xlm_prim(asp,prim); + prim = xua_xlm_prim_alloc_m_notify_ind(&ntfy); + xua_asp_send_xlm_prim(asp, prim);
if (ntfy.info_string) talloc_free(ntfy.info_string); diff --git a/src/ss7_asp.c b/src/ss7_asp.c index 23a9b66..b33187c 100644 --- a/src/ss7_asp.c +++ b/src/ss7_asp.c @@ -59,6 +59,7 @@ #include "ss7_xua_srv.h" #include "xua_asp_fsm.h" #include "xua_as_fsm.h" +#include "xua_lm_sap.h"
static int _setsockopt_peer_primary_addr(int fd, const struct osmo_sockaddr *saddr) { @@ -1655,30 +1656,3 @@ } return true; } - -/* process a primitive from the xUA Layer Manager (LM) */ -int osmo_xlm_sap_down(struct osmo_ss7_asp *asp, struct osmo_prim_hdr *oph) -{ - struct osmo_xlm_prim *prim = (struct osmo_xlm_prim *) oph; - - LOGPASP(asp, DLSS7, LOGL_DEBUG, "Received XUA Layer Manager Primitive: %s)\n", - osmo_xlm_prim_name(&prim->oph)); - - switch (OSMO_PRIM_HDR(&prim->oph)) { - case OSMO_PRIM(OSMO_XLM_PRIM_M_RK_REG, PRIM_OP_REQUEST): - /* Layer Manager asks us to send a Routing Key Reg Request */ - xua_rkm_send_reg_req(asp, &prim->u.rk_reg.key, prim->u.rk_reg.traf_mode); - break; - case OSMO_PRIM(OSMO_XLM_PRIM_M_RK_DEREG, PRIM_OP_REQUEST): - /* Layer Manager asks us to send a Routing Key De-Reg Request */ - xua_rkm_send_dereg_req(asp, prim->u.rk_dereg.route_ctx); - break; - default: - LOGPASP(asp, DLSS7, LOGL_ERROR, "Unknown XUA Layer Manager Primitive: %s\n", - osmo_xlm_prim_name(&prim->oph)); - break; - } - - msgb_free(prim->oph.msg); - return 0; -} diff --git a/src/ss7_xua_srv.c b/src/ss7_xua_srv.c index 11e0d0b..0d095ee 100644 --- a/src/ss7_xua_srv.c +++ b/src/ss7_xua_srv.c @@ -55,6 +55,7 @@ #include "ss7_internal.h" #include "xua_asp_fsm.h" #include "xua_as_fsm.h" +#include "xua_lm_sap.h" #include "ss7_xua_srv.h"
/*********************************************************************** diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index 8ac31f6..946418c 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -36,6 +36,7 @@ #include "sccp_internal.h" #include "xua_asp_fsm.h" #include "xua_as_fsm.h" +#include "xua_lm_sap.h" #include "xua_internal.h"
#ifdef WITH_TCAP_LOADSHARING @@ -103,46 +104,6 @@ } t_beat; };
-struct osmo_xlm_prim *xua_xlm_prim_alloc(enum osmo_xlm_prim_type prim_type, - enum osmo_prim_operation op) -{ - struct osmo_xlm_prim *prim; - struct msgb *msg = msgb_alloc_headroom(2048+128, 128, "xua_asp-xlm msgb"); - if (!msg) - return NULL; - - prim = (struct osmo_xlm_prim *) msgb_put(msg, sizeof(*prim)); - osmo_prim_init(&prim->oph, XUA_SAP_LM, prim_type, op, msg); - - return prim; -} - -/* Send a XUA LM Primitive to the XUA Layer Manager (LM) */ -void xua_asp_send_xlm_prim(struct osmo_ss7_asp *asp, struct osmo_xlm_prim *prim) -{ - const struct osmo_xua_layer_manager *lm = asp->lm; - - if (lm && lm->prim_cb) - lm->prim_cb(&prim->oph, asp); - else { - LOGPFSML(asp->fi, LOGL_DEBUG, "No Layer Manager, dropping %s\n", - osmo_xlm_prim_name(&prim->oph)); - } - - msgb_free(prim->oph.msg); -} - -/* wrapper around send_xlm_prim for primitives without data */ -void xua_asp_send_xlm_prim_simple(struct osmo_ss7_asp *asp, - enum osmo_xlm_prim_type prim_type, - enum osmo_prim_operation op) -{ - struct osmo_xlm_prim *prim = xua_xlm_prim_alloc(prim_type, op); - if (!prim) - return; - xua_asp_send_xlm_prim(asp, prim); -} - static void send_xlm_prim_simple(struct osmo_fsm_inst *fi, enum osmo_xlm_prim_type prim_type, enum osmo_prim_operation op) diff --git a/src/xua_default_lm_fsm.c b/src/xua_default_lm_fsm.c index d526f74..9a3cb69 100644 --- a/src/xua_default_lm_fsm.c +++ b/src/xua_default_lm_fsm.c @@ -37,6 +37,7 @@
#include "xua_internal.h" #include "xua_asp_fsm.h" +#include "xua_lm_sap.h" #include "ss7_as.h" #include "ss7_asp.h" #include "ss7_xua_srv.h" @@ -178,12 +179,9 @@ { struct ss7_as_asp_assoc *assoc; llist_for_each_entry(assoc, &asp->assoc_as_list, asp_entry) { - struct osmo_ss7_as *as = assoc->as; struct osmo_xlm_prim *prim; - prim = xua_xlm_prim_alloc(OSMO_XLM_PRIM_M_RK_REG, PRIM_OP_REQUEST); - OSMO_ASSERT(prim); - prim->u.rk_reg.key = as->cfg.routing_key; - prim->u.rk_reg.traf_mode = as->cfg.mode; + prim = xua_xlm_prim_alloc_m_rk_reg_req(&assoc->as->cfg.routing_key, + assoc->as->cfg.mode); osmo_xlm_sap_down(asp, &prim->oph); } } diff --git a/src/xua_internal.h b/src/xua_internal.h index c8ae79f..3857a72 100644 --- a/src/xua_internal.h +++ b/src/xua_internal.h @@ -103,14 +103,6 @@ const struct xua_msg *xua); int m3ua_rx_rkm(struct osmo_ss7_asp *asp, struct xua_msg *xua);
-struct osmo_xlm_prim *xua_xlm_prim_alloc(enum osmo_xlm_prim_type prim_type, - enum osmo_prim_operation op); - -void xua_asp_send_xlm_prim(struct osmo_ss7_asp *asp, struct osmo_xlm_prim *prim); -void xua_asp_send_xlm_prim_simple(struct osmo_ss7_asp *asp, - enum osmo_xlm_prim_type prim_type, - enum osmo_prim_operation op); - void xua_snm_pc_available(struct osmo_ss7_as *as, const uint32_t *aff_pc, unsigned int num_aff_pc, const char *info_str, bool available);
diff --git a/src/xua_lm_sap.c b/src/xua_lm_sap.c new file mode 100644 index 0000000..6d870d6 --- /dev/null +++ b/src/xua_lm_sap.c @@ -0,0 +1,161 @@ +/* M3UA/SUA <-> XUA Layer Manager SAP, RFC466 1.6.3 & RFC3868 1.6.3 */ +/* (C) 2017-2021 by Harald Welte laforge@gnumonks.org + * 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/. + */ + +/* The idea of this default Layer Manager is as follows: + * - we wait until a SCTP connection is established + * - we issue the ASP-UP request and wait for the ASP being in UP state + * - we wait if we receive a M-NOTIFY indication about any AS in this ASP + * - if that's not received, we use RKM to register a routing context + * for our locally configured ASP and expect a positive registration + * result as well as a NOTIFY indication about AS-ACTIVE afterwards. + */ + +#include <errno.h> + +#include <osmocom/core/logging.h> +#include <osmocom/core/msgb.h> +#include <osmocom/core/prim.h> +#include <osmocom/sigtran/osmo_ss7.h> +#include <osmocom/sigtran/sigtran_sap.h> + +#include "xua_internal.h" +#include "ss7_asp.h" + + +struct osmo_xlm_prim *xua_xlm_prim_alloc(enum osmo_xlm_prim_type prim_type, + enum osmo_prim_operation op) +{ + struct osmo_xlm_prim *prim; + struct msgb *msg = msgb_alloc_headroom(2048+128, 128, "xua_asp-xlm msgb"); + if (!msg) + return NULL; + + prim = (struct osmo_xlm_prim *) msgb_put(msg, sizeof(*prim)); + osmo_prim_init(&prim->oph, XUA_SAP_LM, prim_type, op, msg); + + return prim; +} + +/* M-RK_REG request */ +struct osmo_xlm_prim *xua_xlm_prim_alloc_m_rk_reg_req(const struct osmo_ss7_routing_key *rkey, + enum osmo_ss7_as_traffic_mode mode) +{ + struct osmo_xlm_prim *prim; + prim = xua_xlm_prim_alloc(OSMO_XLM_PRIM_M_RK_REG, PRIM_OP_REQUEST); + OSMO_ASSERT(prim); + prim->u.rk_reg.key = *rkey; + prim->u.rk_reg.traf_mode = mode; + return prim; +} + +/* M-RK_REG confirm */ +struct osmo_xlm_prim *xua_xlm_prim_alloc_m_rk_reg_cfm(const struct osmo_ss7_routing_key *rkey, uint32_t status) +{ + struct osmo_xlm_prim *prim; + prim = xua_xlm_prim_alloc(OSMO_XLM_PRIM_M_RK_REG, PRIM_OP_CONFIRM); + OSMO_ASSERT(prim); + prim->u.rk_reg.key = *rkey; + prim->u.rk_reg.status = status; + return prim; +} + +/* M-RK_DEREG confirm */ +struct osmo_xlm_prim *xua_xlm_prim_alloc_m_rk_dereg_cfm(uint32_t route_ctx, uint32_t status) +{ + struct osmo_xlm_prim *prim; + prim = xua_xlm_prim_alloc(OSMO_XLM_PRIM_M_RK_DEREG, PRIM_OP_CONFIRM); + OSMO_ASSERT(prim); + prim->u.rk_dereg.route_ctx = route_ctx; + prim->u.rk_dereg.status = status; + return prim; +} + +/* M-ERROR indication */ +struct osmo_xlm_prim *xua_xlm_prim_alloc_m_error_ind(uint32_t err_code) +{ + struct osmo_xlm_prim *prim; + prim = xua_xlm_prim_alloc(OSMO_XLM_PRIM_M_ERROR, PRIM_OP_INDICATION); + OSMO_ASSERT(prim); + prim->u.error.code = err_code; + return prim; +} + +/* M-NOTIFY indication */ +struct osmo_xlm_prim *xua_xlm_prim_alloc_m_notify_ind(const struct osmo_xlm_prim_notify *ntfy) +{ + struct osmo_xlm_prim *prim; + prim = xua_xlm_prim_alloc(OSMO_XLM_PRIM_M_NOTIFY, PRIM_OP_INDICATION); + OSMO_ASSERT(prim); + prim->u.notify = *ntfy; + return prim; +} + +/* Send a XUA LM Primitive from M3UA/SUA to the XUA Layer Manager (LM) */ +void xua_asp_send_xlm_prim(struct osmo_ss7_asp *asp, struct osmo_xlm_prim *prim) +{ + const struct osmo_xua_layer_manager *lm = asp->lm; + + if (lm && lm->prim_cb) + lm->prim_cb(&prim->oph, asp); + else { + LOGPFSML(asp->fi, LOGL_DEBUG, "No Layer Manager, dropping %s\n", + osmo_xlm_prim_name(&prim->oph)); + } + + msgb_free(prim->oph.msg); +} + +/* wrapper around send_xlm_prim for primitives without data */ +void xua_asp_send_xlm_prim_simple(struct osmo_ss7_asp *asp, + enum osmo_xlm_prim_type prim_type, + enum osmo_prim_operation op) +{ + struct osmo_xlm_prim *prim = xua_xlm_prim_alloc(prim_type, op); + if (!prim) + return; + xua_asp_send_xlm_prim(asp, prim); +} + +/* process a primitive from the xUA Layer Manager (LM) to M3UA/SUA */ +int osmo_xlm_sap_down(struct osmo_ss7_asp *asp, struct osmo_prim_hdr *oph) +{ + struct osmo_xlm_prim *prim = (struct osmo_xlm_prim *) oph; + + LOGPASP(asp, DLSS7, LOGL_DEBUG, "Received XUA Layer Manager Primitive: %s)\n", + osmo_xlm_prim_name(&prim->oph)); + + switch (OSMO_PRIM_HDR(&prim->oph)) { + case OSMO_PRIM(OSMO_XLM_PRIM_M_RK_REG, PRIM_OP_REQUEST): + /* Layer Manager asks us to send a Routing Key Reg Request */ + xua_rkm_send_reg_req(asp, &prim->u.rk_reg.key, prim->u.rk_reg.traf_mode); + break; + case OSMO_PRIM(OSMO_XLM_PRIM_M_RK_DEREG, PRIM_OP_REQUEST): + /* Layer Manager asks us to send a Routing Key De-Reg Request */ + xua_rkm_send_dereg_req(asp, prim->u.rk_dereg.route_ctx); + break; + default: + LOGPASP(asp, DLSS7, LOGL_ERROR, "Unknown XUA Layer Manager Primitive: %s\n", + osmo_xlm_prim_name(&prim->oph)); + break; + } + + msgb_free(prim->oph.msg); + return 0; +} diff --git a/src/xua_lm_sap.h b/src/xua_lm_sap.h new file mode 100644 index 0000000..3609eb2 --- /dev/null +++ b/src/xua_lm_sap.h @@ -0,0 +1,24 @@ +/* M3UA/SUA <-> XUA Layer Manager SAP, RFC466 1.6.3 & RFC3868 1.6.3 */ +#pragma once + +#include <unistd.h> +#include <stdint.h> + +#include <osmocom/core/tdef.h> +#include <osmocom/sigtran/osmo_ss7.h> +#include <osmocom/sigtran/sigtran_sap.h> + +struct osmo_xlm_prim *xua_xlm_prim_alloc(enum osmo_xlm_prim_type prim_type, + enum osmo_prim_operation op); +struct osmo_xlm_prim *xua_xlm_prim_alloc_m_rk_reg_req(const struct osmo_ss7_routing_key *rkey, + enum osmo_ss7_as_traffic_mode mode); +struct osmo_xlm_prim *xua_xlm_prim_alloc_m_rk_reg_cfm(const struct osmo_ss7_routing_key *rkey, + uint32_t status); +struct osmo_xlm_prim *xua_xlm_prim_alloc_m_rk_dereg_cfm(uint32_t route_ctx, uint32_t status); +struct osmo_xlm_prim *xua_xlm_prim_alloc_m_error_ind(uint32_t err_code); +struct osmo_xlm_prim *xua_xlm_prim_alloc_m_notify_ind(const struct osmo_xlm_prim_notify *ntfy); + +void xua_asp_send_xlm_prim(struct osmo_ss7_asp *asp, struct osmo_xlm_prim *prim); +void xua_asp_send_xlm_prim_simple(struct osmo_ss7_asp *asp, + enum osmo_xlm_prim_type prim_type, + enum osmo_prim_operation op); diff --git a/src/xua_rkm.c b/src/xua_rkm.c index f3136e4..2e7c227 100644 --- a/src/xua_rkm.c +++ b/src/xua_rkm.c @@ -36,6 +36,7 @@ #include "xua_internal.h" #include "xua_as_fsm.h" #include "xua_asp_fsm.h" +#include "xua_lm_sap.h"
const struct value_string m3ua_rkm_reg_status_vals[] = { { M3UA_RKM_REG_SUCCESS, "SUCCESS" }, @@ -465,6 +466,7 @@ static int handle_rkey_reg_resp(struct osmo_ss7_asp *asp, struct xua_msg *inner) { struct osmo_xlm_prim *oxp; + struct osmo_ss7_routing_key rkey;
if (!xua_msg_find_tag(inner, M3UA_IEI_LOC_RKEY_ID) || !xua_msg_find_tag(inner, M3UA_IEI_REG_STATUS) || @@ -474,13 +476,11 @@ return -1; }
- oxp = xua_xlm_prim_alloc(OSMO_XLM_PRIM_M_RK_REG, PRIM_OP_CONFIRM); - if (!oxp) - return -1; - - oxp->u.rk_reg.key.l_rk_id = xua_msg_get_u32(inner, M3UA_IEI_LOC_RKEY_ID); - oxp->u.rk_reg.key.context = xua_msg_get_u32(inner, M3UA_IEI_ROUTE_CTX); - oxp->u.rk_reg.status = xua_msg_get_u32(inner, M3UA_IEI_REG_STATUS); + rkey = (struct osmo_ss7_routing_key){ + .l_rk_id = xua_msg_get_u32(inner, M3UA_IEI_LOC_RKEY_ID), + .context = xua_msg_get_u32(inner, M3UA_IEI_ROUTE_CTX), + }; + oxp = xua_xlm_prim_alloc_m_rk_reg_cfm(&rkey, xua_msg_get_u32(inner, M3UA_IEI_REG_STATUS));
LOGPASP(asp, DLSS7, LOGL_INFO, "Received RKM REG RES rctx=%u status=%s\n", oxp->u.rk_reg.key.context, @@ -528,12 +528,8 @@ return -1; }
- oxp = xua_xlm_prim_alloc(OSMO_XLM_PRIM_M_RK_DEREG, PRIM_OP_CONFIRM); - if (!oxp) - return -1; - - oxp->u.rk_dereg.route_ctx = xua_msg_get_u32(inner, M3UA_IEI_ROUTE_CTX); - oxp->u.rk_dereg.status = xua_msg_get_u32(inner, M3UA_IEI_DEREG_STATUS); + oxp = xua_xlm_prim_alloc_m_rk_dereg_cfm(xua_msg_get_u32(inner, M3UA_IEI_ROUTE_CTX), + xua_msg_get_u32(inner, M3UA_IEI_DEREG_STATUS));
LOGPASP(asp, DLSS7, LOGL_INFO, "Received RKM DEREG RES rctx=%u status=%s\n", oxp->u.rk_reg.key.context,