diff options
author | Harald Welte <laforge@osmocom.org> | 2023-03-23 23:18:08 +0100 |
---|---|---|
committer | Harald Welte <laforge@osmocom.org> | 2023-04-14 01:22:37 +0800 |
commit | 08685036887759ef44bf7a69b7e26966c2b6009a (patch) | |
tree | 54a6d84b944bbb3e6ab677a357a537b8d55888b8 | |
parent | ba1e74c4f4fd44d89f3b1435486672344cc2a993 (diff) |
WIP: rate counters for SCCP stacklaforge/secondary_pc
TODO:
* testing
Change-Id: I79df56d956aaf7dee1c4f879097100e39347e44d
-rw-r--r-- | src/sccp_internal.h | 27 | ||||
-rw-r--r-- | src/sccp_sclc.c | 5 | ||||
-rw-r--r-- | src/sccp_scoc.c | 22 | ||||
-rw-r--r-- | src/sccp_user.c | 71 |
4 files changed, 124 insertions, 1 deletions
diff --git a/src/sccp_internal.h b/src/sccp_internal.h index bfdca34..8a05afb 100644 --- a/src/sccp_internal.h +++ b/src/sccp_internal.h @@ -4,12 +4,36 @@ #include <osmocom/core/prim.h> #include <osmocom/core/linuxlist.h> #include <osmocom/core/linuxrbtree.h> +#include <osmocom/core/rate_ctr.h> #include <osmocom/sigtran/sccp_sap.h> #include <osmocom/sigtran/osmo_ss7.h> #include <osmocom/sigtran/protocol/mtp.h> #define SCCP_STR "Signalling Connection Control Part\n" +enum sccp_user_ctr { + SCU_CTR_CLDT_OUT_COUNT, + SCU_CTR_CLDT_OUT_BYTES, + SCU_CTR_CLDT_IN_COUNT, + SCU_CTR_CLDT_IN_BYTES, + + SCU_CTR_CONN_DISC_TIAR_EXP, /* number of T(iar) expirations (peer dead) */ + + SCU_CTR_CONN_OUT_REQ, /* number of outgoing SCCP connections requested */ + SCU_CTR_CONN_OUT_EST, /* number of outgoing SCCP connections established */ + SCU_CTR_CONN_OUT_TIMEOUT, + SCU_CTR_CONN_OUT_CREF, + SCU_CTR_CONN_OUT_RLSD, + SCU_CTR_CONN_OUT_DATA_COUNT, + SCU_CTR_CONN_OUT_DATA_BYTES, + + SCU_CTR_CONN_IN_REQ, /* number of incoming SCCP connections requested */ + SCU_CTR_CONN_IN_EST, /* number of incoming SCCP connections requested */ + SCU_CTR_CONN_IN_CREF, + SCU_CTR_CONN_IN_DATA_COUNT, + SCU_CTR_CONN_IN_DATA_BYTES, +}; + /* Appendix C.4 of Q.714 */ enum osmo_sccp_timer { OSMO_SCCP_TIMER_CONN_EST, @@ -81,6 +105,9 @@ struct osmo_sccp_user { /* Application Server FSM Instance */ struct osmo_fsm_inst *as_fi; + + /* Rate counters for this user */ + struct rate_ctr_group *ctrg; }; extern int DSCCP; diff --git a/src/sccp_sclc.c b/src/sccp_sclc.c index 186efbd..bba28c4 100644 --- a/src/sccp_sclc.c +++ b/src/sccp_sclc.c @@ -130,6 +130,8 @@ int sccp_sclc_user_sap_down_nofree(struct osmo_sccp_user *scu, struct osmo_prim_ switch (OSMO_PRIM_HDR(&prim->oph)) { case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_REQUEST): /* Connectionless by-passes this altogether */ + rate_ctr_inc2(scu->ctrg, SCU_CTR_CLDT_OUT_COUNT); + rate_ctr_add2(scu->ctrg, SCU_CTR_CLDT_OUT_BYTES, msgb_l2len(prim->oph.msg)); return xua_gen_encode_and_send(scu, -1, prim, SUA_CL_CLDT); default: LOGP(DLSCCP, LOGL_ERROR, "Received unknown SCCP User " @@ -192,6 +194,9 @@ static int sclc_rx_cldt(struct osmo_sccp_instance *inst, struct xua_msg *xua) return 0; } + rate_ctr_inc2(scu->ctrg, SCU_CTR_CLDT_IN_COUNT); + rate_ctr_add2(scu->ctrg, SCU_CTR_CLDT_IN_BYTES, data_ie->len); + /* copy data */ upmsg->l2h = msgb_put(upmsg, data_ie->len); memcpy(upmsg->l2h, data_ie->dat, data_ie->len); diff --git a/src/sccp_scoc.c b/src/sccp_scoc.c index c929ed6..d2bd305 100644 --- a/src/sccp_scoc.c +++ b/src/sccp_scoc.c @@ -846,6 +846,12 @@ static struct xua_msg *xua_gen_msg_co(struct sccp_connection *conn, uint32_t eve xua_msg_free(xua); return NULL; } + + if (encode_opt_data) { + rate_ctr_inc2(conn->user->ctrg, SCU_CTR_CONN_OUT_DATA_COUNT); + rate_ctr_add2(conn->user->ctrg, SCU_CTR_CONN_OUT_DATA_BYTES, msgb_l2len(prim->oph.msg)); + } + return xua; prim_needed: @@ -972,6 +978,11 @@ static void scu_gen_encode_and_send(struct sccp_connection *conn, uint32_t event return; } + if (msgb_l2(scu_prim->oph.msg)) { + rate_ctr_inc2(conn->user->ctrg, SCU_CTR_CONN_IN_DATA_COUNT); + rate_ctr_add2(conn->user->ctrg, SCU_CTR_CONN_IN_DATA_BYTES, msgb_l2len(scu_prim->oph.msg)); + } + sccp_user_prim_up(conn->user, scu_prim); } @@ -993,11 +1004,12 @@ static void scoc_fsm_idle(struct osmo_fsm_inst *fi, uint32_t event, void *data) case SCOC_E_SCU_N_CONN_REQ: prim = data; uconp = &prim->u.connect; + /* generate + send CR PDU to SCRC */ /* copy relevant parameters from prim to conn */ conn->called_addr = uconp->called_addr; conn->calling_addr = uconp->calling_addr; conn->sccp_class = uconp->sccp_class; - /* generate + send CR PDU to SCRC */ + rate_ctr_inc2(conn->user->ctrg, SCU_CTR_CONN_OUT_REQ); rc = xua_gen_encode_and_send(conn, event, prim, SUA_CO_CORE); if (rc < 0) LOGPFSML(fi, LOGL_ERROR, "Failed to initiate connection: %s\n", strerror(-rc)); @@ -1030,6 +1042,7 @@ static void scoc_fsm_idle(struct osmo_fsm_inst *fi, uint32_t event, void *data) /* Figure C.3 / Q.714 (sheet 1 of 6) */ case SCOC_E_RCOC_CONN_IND: xua = data; + rate_ctr_inc2(conn->user->ctrg, SCU_CTR_CONN_IN_REQ); /* copy relevant parameters from xua to conn */ sua_addr_parse(&conn->calling_addr, xua, SUA_IEI_SRC_ADDR); sua_addr_parse(&conn->called_addr, xua, SUA_IEI_DEST_ADDR); @@ -1070,6 +1083,7 @@ static void scoc_fsm_conn_pend_in(struct osmo_fsm_inst *fi, uint32_t event, void switch (event) { case SCOC_E_SCU_N_CONN_RESP: prim = data; + rate_ctr_inc2(conn->user->ctrg, SCU_CTR_CONN_IN_EST); /* FIXME: assign local reference (only now?) */ /* FIXME: assign sls, protocol class and credit */ xua_gen_encode_and_send(conn, event, prim, SUA_CO_COAK); @@ -1080,6 +1094,7 @@ static void scoc_fsm_conn_pend_in(struct osmo_fsm_inst *fi, uint32_t event, void break; case SCOC_E_SCU_N_DISC_REQ: prim = data; + rate_ctr_inc2(conn->user->ctrg, SCU_CTR_CONN_IN_CREF); /* release resources: implicit */ xua_gen_encode_and_send(conn, event, prim, SUA_CO_COREF); /* N. B: we've ignored CREF sending errors as there's no recovery option anyway */ @@ -1103,6 +1118,7 @@ static void scoc_fsm_conn_pend_out(struct osmo_fsm_inst *fi, uint32_t event, voi /* keep conn timer running(!) */ break; case SCOC_E_CONN_TMR_EXP: + rate_ctr_inc2(conn->user->ctrg, SCU_CTR_CONN_OUT_TIMEOUT); /* N-DISCONNECT.ind to user */ scu_gen_encode_and_send(conn, event, NULL, OSMO_SCU_PRIM_N_DISCONNECT, PRIM_OP_INDICATION); @@ -1112,6 +1128,7 @@ static void scoc_fsm_conn_pend_out(struct osmo_fsm_inst *fi, uint32_t event, voi case SCOC_E_RCOC_ROUT_FAIL_IND: case SCOC_E_RCOC_CREF_IND: xua = data; + rate_ctr_inc2(conn->user->ctrg, SCU_CTR_CONN_OUT_CREF); /* stop conn timer */ conn_stop_connect_timer(conn); /* release local res + ref (implicit by going to idle) */ @@ -1123,6 +1140,7 @@ static void scoc_fsm_conn_pend_out(struct osmo_fsm_inst *fi, uint32_t event, voi break; case SCOC_E_RCOC_RLSD_IND: xua = data; + rate_ctr_inc2(conn->user->ctrg, SCU_CTR_CONN_OUT_RLSD); /* RLC to SCRC */ xua_gen_encode_and_send(conn, event, NULL, SUA_CO_RELCO); /* stop conn timer */ @@ -1144,6 +1162,7 @@ static void scoc_fsm_conn_pend_out(struct osmo_fsm_inst *fi, uint32_t event, voi break; case SCOC_E_RCOC_CC_IND: xua = data; + rate_ctr_inc2(conn->user->ctrg, SCU_CTR_CONN_OUT_EST); /* stop conn timer */ conn_stop_connect_timer(conn); /* start inactivity timers */ @@ -1266,6 +1285,7 @@ static void scoc_fsm_active(struct osmo_fsm_inst *fi, uint32_t event, void *data osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); break; case SCOC_E_T_IAR_EXP: + rate_ctr_inc2(conn->user->ctrg, SCU_CTR_CONN_DISC_TIAR_EXP); /* stop inact timers */ conn_stop_inact_timers(conn); xua = xua_msg_alloc(); diff --git a/src/sccp_user.c b/src/sccp_user.c index e619c90..3d1141e 100644 --- a/src/sccp_user.c +++ b/src/sccp_user.c @@ -40,6 +40,70 @@ #include "xua_internal.h" #include "ss7_internal.h" +static const struct rate_ctr_desc sccp_user_ctr_desc[] = { + [SCU_CTR_CLDT_OUT_COUNT] = { + "cldt.out.count", "Total number of outbound connectionless SCCP messages" + }, + [SCU_CTR_CLDT_OUT_BYTES] = { + "cldt.out.bytes", "Total number of user bytes in outbound connectionless SCCP messages" + }, + [SCU_CTR_CLDT_IN_COUNT] = { + "cldt.in.count", "Total number of inbound connectionless SCCP messages" + }, + [SCU_CTR_CLDT_IN_BYTES] = { + "cldt.in.bytes", "Total number of user bytes in inbound connectionless SCCP messages" + }, + + [SCU_CTR_CONN_DISC_TIAR_EXP] = { + "conn.t_iar.expired", "Total number SCCP disconnects due to T(iar) expiration" + }, + + [SCU_CTR_CONN_OUT_REQ] = { + "conn.out.est.requested", "Total number of outbound SCCP connections requested" + }, + [SCU_CTR_CONN_OUT_EST] = { + "conn.out.est.established", "Total number of outbound SCCP connections established" + }, + [SCU_CTR_CONN_OUT_TIMEOUT] = { + "conn.out.est.timeout", "Total number of outbound SCCP connection attempts timing out" + }, + [SCU_CTR_CONN_OUT_CREF] = { + "conn.out.est.refused", "Total number of outbound SCCP connection attempts refused by peer" + }, + [SCU_CTR_CONN_OUT_RLSD] = { + "conn.out.est.released", "Total number of outbound SCCP connection attempts released by peer" + }, + [SCU_CTR_CONN_OUT_DATA_COUNT] = { + "conn.out.data.count", "Total number of user data chunks transmitted" + }, + [SCU_CTR_CONN_OUT_DATA_BYTES] = { + "conn.out.data.bytes", "Total number of user data bytes transmitted" + }, + + [SCU_CTR_CONN_IN_REQ] = { + "conn.in.est.requested", "Total number of inbound SCCP connections requested" + }, + [SCU_CTR_CONN_IN_EST] = { + "conn.in.est.established", "Total number of inbound SCCP connections established" + }, + [SCU_CTR_CONN_IN_CREF] = { + "conn.in.est.refused", "Total number of inbound SCCP connection attempts refused" + }, + [SCU_CTR_CONN_IN_DATA_COUNT] = { + "conn.in.data.count", "Total number of user data chunks received" + }, + [SCU_CTR_CONN_IN_DATA_BYTES] = { + "conn.in.data.bytes", "Total number of user data bytes received" + }, +}; + +static const struct rate_ctr_group_desc sccp_user_ctrg_desc = { + .group_name_prefix = "sccp.user", + .group_description = "Counters related to one SCCP User", + .num_ctr = ARRAY_SIZE(sccp_user_ctr_desc), + .ctr_desc = sccp_user_ctr_desc, +}; + /*! \brief Find a SCCP User registered for given PC+SSN or SSN only * First search all users with a valid PC for a full PC+SSN match. * If no such match was found, search all users with an invalid PC for an SSN-only match. @@ -113,9 +177,15 @@ sccp_user_bind_pc(struct osmo_sccp_instance *inst, const char *name, scu->prim_cb = prim_cb; scu->ssn = ssn; scu->pc = pc; + scu->ctrg = rate_ctr_group_alloc(scu, &sccp_user_ctrg_desc, (pc << 8) | ssn); + if (!scu->ctrg) + goto out_free; llist_add_tail(&scu->list, &inst->users); return scu; +out_free: + talloc_free(scu); + return NULL; } /*! \brief Bind a given SCCP User to a given SSN+PC @@ -153,6 +223,7 @@ void osmo_sccp_user_unbind(struct osmo_sccp_user *scu) osmo_ss7_pointcode_print(scu->inst->ss7, scu->pc)); /* FIXME: free/release all connections held by this user? */ llist_del(&scu->list); + rate_ctr_group_free(scu->ctrg); talloc_free(scu); } |