lists.osmocom.org
Sign In Sign Up
Manage this list Sign In Sign Up

Keyboard Shortcuts

Thread View

  • j: Next unread message
  • k: Previous unread message
  • j a: Jump to all threads
  • j l: Jump to MailingList overview

gerrit-log

Thread Start a new thread
Download
Threads by month
  • ----- 2026 -----
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2025 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2024 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2023 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2022 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
gerrit-log@lists.osmocom.org

June 2023

  • 1 participants
  • 2480 discussions
[S] Change in osmo-hnbgw[master]: add ranap_domain_name()
by neels 22 Jun '23

22 Jun '23
neels has submitted this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/33174 ) ( 4 is the latest approved patch-set. No files were changed between the latest approved patch-set and the submitted one. )Change subject: add ranap_domain_name() ...................................................................... add ranap_domain_name() As simple as it may seem, turning the RANAP CS/PS domain indicator to a string so far is cumbersome. It is usually only CS or PS, but to be accurate we should also expect invalid values. After the umpteenth switch statement breaking up otherwise trivial code, I decided that yes, after all, a value_string[] is a good idea even for just two enum values that have only two-letter names. Callers will follow in upcoming patches. Related: SYS#6412 Change-Id: Ib3c5d772ccea8c854eec007de5c996d1b6640bc0 --- M include/osmocom/hnbgw/hnbgw.h M src/osmo-hnbgw/hnbgw.c M src/osmo-hnbgw/hnbgw_rua.c 3 files changed, 32 insertions(+), 13 deletions(-) Approvals: pespin: Looks good to me, approved laforge: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/hnbgw/hnbgw.h b/include/osmocom/hnbgw/hnbgw.h index 90aee5b..3e1b6a4 100644 --- a/include/osmocom/hnbgw/hnbgw.h +++ b/include/osmocom/hnbgw/hnbgw.h @@ -36,6 +36,12 @@ #define DOMAIN_CS RANAP_CN_DomainIndicator_cs_domain #define DOMAIN_PS RANAP_CN_DomainIndicator_ps_domain +extern const struct value_string ranap_domain_names[]; +static inline const char *ranap_domain_name(RANAP_CN_DomainIndicator_t domain) +{ + return get_value_string(ranap_domain_names, domain); +} + enum hnb_ctrl_node { CTRL_NODE_HNB = _LAST_CTRL_NODE, _LAST_CTRL_NODE_HNB diff --git a/src/osmo-hnbgw/hnbgw.c b/src/osmo-hnbgw/hnbgw.c index fc9e698..7faf7f7 100644 --- a/src/osmo-hnbgw/hnbgw.c +++ b/src/osmo-hnbgw/hnbgw.c @@ -41,6 +41,12 @@ struct hnbgw *g_hnbgw = NULL; +const struct value_string ranap_domain_names[] = { + { DOMAIN_CS, "CS" }, + { DOMAIN_PS, "PS" }, + {} +}; + void g_hnbgw_alloc(void *ctx) { OSMO_ASSERT(!g_hnbgw); diff --git a/src/osmo-hnbgw/hnbgw_rua.c b/src/osmo-hnbgw/hnbgw_rua.c index a354e4d..073f3ce 100644 --- a/src/osmo-hnbgw/hnbgw_rua.c +++ b/src/osmo-hnbgw/hnbgw_rua.c @@ -42,18 +42,6 @@ #include <osmocom/hnbap/HNBAP_CN-DomainIndicator.h> #include <osmocom/ranap/ranap_ies_defs.h> -static const char *cn_domain_indicator_to_str(RUA_CN_DomainIndicator_t cN_DomainIndicator) -{ - switch (cN_DomainIndicator) { - case RUA_CN_DomainIndicator_cs_domain: - return "IuCS"; - case RUA_CN_DomainIndicator_ps_domain: - return "IuPS"; - default: - return "(unknown-domain)"; - } -} - static int hnbgw_rua_tx(struct hnb_context *ctx, struct msgb *msg) { if (!msg) @@ -371,7 +359,7 @@ context_id = asn1bitstr_to_u24(&ies.context_ID); LOGHNB(hnb, DRUA, LOGL_DEBUG, "RUA %s Connect.req(ctx=0x%x, %s)\n", - cn_domain_indicator_to_str(ies.cN_DomainIndicator), context_id, + ranap_domain_name(ies.cN_DomainIndicator), context_id, ies.establishment_Cause == RUA_Establishment_Cause_emergency_call ? "emergency" : "normal"); rc = rua_to_scu(hnb, ies.cN_DomainIndicator, RUA_ProcedureCode_id_Connect, -- To view, visit https://gerrit.osmocom.org/c/osmo-hnbgw/+/33174 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-hnbgw Gerrit-Branch: master Gerrit-Change-Id: Ib3c5d772ccea8c854eec007de5c996d1b6640bc0 Gerrit-Change-Number: 33174 Gerrit-PatchSet: 8 Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: neels <nhofmeyr(a)sysmocom.de> Gerrit-Reviewer: pespin <pespin(a)sysmocom.de> Gerrit-MessageType: merged
1 0
0 0
[L] Change in osmo-hnbgw[master]: detect in/active CN links by RANAP RESET
by neels 22 Jun '23

22 Jun '23
neels has submitted this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/33175 ) ( 7 is the latest approved patch-set. No files were changed between the latest approved patch-set and the submitted one. )Change subject: detect in/active CN links by RANAP RESET ...................................................................... detect in/active CN links by RANAP RESET Implement cnlink FSM. This is a copy of osmo-bsc/bssmap_reset.c, except for the connection success/failure counting. The reason to exclude the CONN_CFM_FAILURE/_SUCCESS: it is a rather experimental feature and should probably rather be covered by PCSTATE notifications and protocol layer timeout tuning (e.g. SCCP ia timers). Related: SYS#6412 Change-Id: Id3eefdea889a736fd5957b80280fa45b9547b792 --- M include/osmocom/hnbgw/hnbgw.h M include/osmocom/hnbgw/hnbgw_cn.h M src/osmo-hnbgw/Makefile.am A src/osmo-hnbgw/cnlink.c M src/osmo-hnbgw/context_map.c M src/osmo-hnbgw/hnbgw_cn.c M src/osmo-hnbgw/hnbgw_vty.c M src/osmo-hnbgw/tdefs.c M tests/cnpool.vty 9 files changed, 424 insertions(+), 91 deletions(-) Approvals: neels: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/hnbgw/hnbgw.h b/include/osmocom/hnbgw/hnbgw.h index 3e1b6a4..69ce186 100644 --- a/include/osmocom/hnbgw/hnbgw.h +++ b/include/osmocom/hnbgw/hnbgw.h @@ -158,6 +158,8 @@ /* backpointer to CS or PS CN pool. */ struct hnbgw_cnpool *pool; + struct osmo_fsm_inst *fi; + int nr; struct hnbgw_cnlink_cfg vty; diff --git a/include/osmocom/hnbgw/hnbgw_cn.h b/include/osmocom/hnbgw/hnbgw_cn.h index bd54a1f..04498d8 100644 --- a/include/osmocom/hnbgw/hnbgw_cn.h +++ b/include/osmocom/hnbgw/hnbgw_cn.h @@ -3,6 +3,7 @@ #include <osmocom/core/rate_ctr.h> #include <osmocom/hnbgw/hnbgw.h> +struct hnbgw_cnlink *cnlink_alloc(struct hnbgw_cnpool *cnpool, int nr); struct hnbgw_cnlink *hnbgw_cnlink_find_by_addr(const struct hnbgw_sccp_user *hsu, const struct osmo_sccp_addr *remote_addr); struct hnbgw_cnlink *hnbgw_cnlink_select(struct hnbgw_context_map *map); @@ -14,6 +15,12 @@ char *cnlink_sccp_addr_to_str(struct hnbgw_cnlink *cnlink, const struct osmo_sccp_addr *addr); +bool cnlink_is_conn_ready(const struct hnbgw_cnlink *cnlink); +void cnlink_rx_reset_cmd(struct hnbgw_cnlink *cnlink); +void cnlink_rx_reset_ack(struct hnbgw_cnlink *cnlink); +void cnlink_resend_reset(struct hnbgw_cnlink *cnlink); +void cnlink_set_disconnected(struct hnbgw_cnlink *cnlink); + enum hnbgw_cnpool_ctr { /* TODO: basic counters completely missing * ... diff --git a/src/osmo-hnbgw/Makefile.am b/src/osmo-hnbgw/Makefile.am index 5fbdf74..910fdda 100644 --- a/src/osmo-hnbgw/Makefile.am +++ b/src/osmo-hnbgw/Makefile.am @@ -41,6 +41,7 @@ context_map_rua.c \ context_map_sccp.c \ hnbgw_cn.c \ + cnlink.c \ ranap_rab_ass.c \ mgw_fsm.c \ tdefs.c \ diff --git a/src/osmo-hnbgw/cnlink.c b/src/osmo-hnbgw/cnlink.c new file mode 100644 index 0000000..a6e9e17 --- /dev/null +++ b/src/osmo-hnbgw/cnlink.c @@ -0,0 +1,316 @@ +/* (C) 2023 by sysmocom s.f.m.c. GmbH <info(a)sysmocom.de> + * All Rights Reserved + * + * Author: Neels Hofmeyr + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <osmocom/core/fsm.h> +#include <osmocom/core/tdef.h> + +#include <osmocom/gsm/gsm23236.h> + +#include <osmocom/sigtran/sccp_helpers.h> + +#include <osmocom/ranap/ranap_ies_defs.h> +#include <osmocom/ranap/ranap_msg_factory.h> + +#include <osmocom/hnbgw/hnbgw.h> +#include <osmocom/hnbgw/hnbgw_cn.h> +#include <osmocom/hnbgw/tdefs.h> +#include <osmocom/hnbgw/context_map.h> + +static struct osmo_fsm cnlink_fsm; + +enum cnlink_fsm_state { + CNLINK_ST_DISC, + CNLINK_ST_CONN, +}; + +enum cnlink_fsm_event { + CNLINK_EV_RX_RESET, + CNLINK_EV_RX_RESET_ACK, +}; + +static const struct value_string cnlink_fsm_event_names[] = { + OSMO_VALUE_STRING(CNLINK_EV_RX_RESET), + OSMO_VALUE_STRING(CNLINK_EV_RX_RESET_ACK), + {} +}; + +static const struct osmo_tdef_state_timeout cnlink_timeouts[32] = { + [CNLINK_ST_DISC] = { .T = 4 }, +}; + +#define cnlink_fsm_state_chg(FI, STATE) \ + osmo_tdef_fsm_inst_state_chg(FI, STATE, \ + cnlink_timeouts, \ + hnbgw_T_defs, \ + -1) + +struct hnbgw_cnlink *cnlink_alloc(struct hnbgw_cnpool *cnpool, int nr) +{ + struct osmo_fsm_inst *fi; + struct hnbgw_cnlink *cnlink; + + char *name = talloc_asprintf(OTC_SELECT, "%s-%d", cnpool->peer_name, nr); + + fi = osmo_fsm_inst_alloc(&cnlink_fsm, g_hnbgw, NULL, LOGL_DEBUG, name); + OSMO_ASSERT(fi); + cnlink = talloc_zero(g_hnbgw, struct hnbgw_cnlink); + fi->priv = cnlink; + + *cnlink = (struct hnbgw_cnlink){ + .name = name, + .pool = cnpool, + .fi = fi, + .nr = nr, + .vty = { + /* VTY config defaults for the new cnlink */ + .nri_ranges = osmo_nri_ranges_alloc(cnlink), + }, + .allow_attach = true, + .ctrs = rate_ctr_group_alloc(g_hnbgw, cnpool->cnlink_ctrg_desc, nr), + }; + talloc_steal(cnlink, name); + INIT_LLIST_HEAD(&cnlink->map_list); + + llist_add_tail(&cnlink->entry, &cnpool->cnlinks); + LOG_CNLINK(cnlink, DCN, LOGL_DEBUG, "allocated\n"); + + /* Immediately (1ms) kick off reset sending mechanism */ + osmo_fsm_inst_state_chg_ms(fi, CNLINK_ST_DISC, 1, 0); + return cnlink; +} + +void cnlink_term_and_free(struct hnbgw_cnlink *cnlink) +{ + if (!cnlink) + return; + osmo_fsm_inst_term(cnlink->fi, OSMO_FSM_TERM_REQUEST, NULL); + talloc_free(cnlink); +} + +static void link_up(struct hnbgw_cnlink *cnlink) +{ + LOGPFSML(cnlink->fi, LOGL_NOTICE, "link up\n"); +} + +static void link_lost(struct hnbgw_cnlink *cnlink) +{ + struct hnbgw_context_map *map, *map2; + + LOGPFSML(cnlink->fi, LOGL_NOTICE, "link lost\n"); + + llist_for_each_entry_safe(map, map2, &cnlink->map_list, hnbgw_cnlink_entry) + context_map_cnlink_lost(map); +} + +static void tx_reset(struct hnbgw_cnlink *cnlink) +{ + struct msgb *msg; + RANAP_Cause_t cause = { + .present = RANAP_Cause_PR_transmissionNetwork, + .choice. transmissionNetwork = RANAP_CauseTransmissionNetwork_signalling_transport_resource_failure, + }; + + if (!cnlink) + return; + + /* We need to have chosen an SCCP instance, and the remote SCCP address needs to be set. + * Only check the remote_addr, allowing use.remote_addr_name to be NULL: if the user has not set an explicit + * remote address book entry, auto-configuration may still have chosen a default remote point-code. */ + if (!cnlink->hnbgw_sccp_user + || !osmo_sccp_check_addr(&cnlink->remote_addr, OSMO_SCCP_ADDR_T_PC | OSMO_SCCP_ADDR_T_SSN)) { + LOG_CNLINK(cnlink, DRANAP, LOGL_DEBUG, "not yet configured, not sending RANAP RESET\n"); + return; + } + + LOG_CNLINK(cnlink, DRANAP, LOGL_DEBUG, "Tx RANAP RESET to %s %s\n", + cnlink_is_cs(cnlink) ? "IuCS" : "IuPS", + cnlink_sccp_addr_to_str(cnlink, &cnlink->remote_addr)); + + msg = ranap_new_msg_reset(cnlink->pool->domain, &cause); + + osmo_sccp_tx_unitdata_msg(cnlink->hnbgw_sccp_user->sccp_user, + &cnlink->hnbgw_sccp_user->local_addr, + &cnlink->remote_addr, + msg); +} + +static void tx_reset_ack(struct hnbgw_cnlink *cnlink) +{ + struct msgb *msg; + struct osmo_sccp_instance *sccp = cnlink_sccp(cnlink); + + if (!sccp) { + LOG_CNLINK(cnlink, DRANAP, LOGL_ERROR, "cannot send RANAP RESET ACK: no CN link\n"); + return; + } + + LOG_CNLINK(cnlink, DRANAP, LOGL_NOTICE, "Tx RANAP RESET ACK %s %s --> %s\n", + cnlink_is_cs(cnlink) ? "IuCS" : "IuPS", + cnlink_sccp_addr_to_str(cnlink, &cnlink->hnbgw_sccp_user->local_addr), + cnlink_sccp_addr_to_str(cnlink, &cnlink->remote_addr)); + + msg = ranap_new_msg_reset_ack(cnlink->pool->domain, NULL); + + osmo_sccp_tx_unitdata_msg(cnlink->hnbgw_sccp_user->sccp_user, + &cnlink->hnbgw_sccp_user->local_addr, + &cnlink->remote_addr, + msg); +} + +static void cnlink_disc_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct hnbgw_cnlink *cnlink = (struct hnbgw_cnlink *)fi->priv; + if (prev_state == CNLINK_ST_CONN) + link_lost(cnlink); +} + +static void cnlink_disc_action(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct hnbgw_cnlink *cnlink = (struct hnbgw_cnlink *)fi->priv; + switch (event) { + + case CNLINK_EV_RX_RESET: + tx_reset_ack(cnlink); + cnlink_fsm_state_chg(fi, CNLINK_ST_CONN); + break; + + case CNLINK_EV_RX_RESET_ACK: + cnlink_fsm_state_chg(fi, CNLINK_ST_CONN); + break; + + default: + OSMO_ASSERT(false); + } +} + +static void cnlink_conn_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct hnbgw_cnlink *cnlink = (struct hnbgw_cnlink *)fi->priv; + if (prev_state != CNLINK_ST_CONN) + link_up(cnlink); +} + +static void cnlink_conn_action(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct hnbgw_cnlink *cnlink = (struct hnbgw_cnlink *)fi->priv; + + switch (event) { + + case CNLINK_EV_RX_RESET: + /* We were connected, but the remote side has restarted. */ + link_lost(cnlink); + tx_reset_ack(cnlink); + link_up(cnlink); + break; + + case CNLINK_EV_RX_RESET_ACK: + LOGPFSML(fi, LOGL_INFO, "Link is already up, ignoring RESET ACK\n"); + break; + + default: + OSMO_ASSERT(false); + } +} + +static int cnlink_fsm_timer_cb(struct osmo_fsm_inst *fi) +{ + struct hnbgw_cnlink *cnlink = (struct hnbgw_cnlink *)fi->priv; + + tx_reset(cnlink); + + /* (re-)enter disconnect state to resend RESET after timeout. */ + cnlink_fsm_state_chg(fi, CNLINK_ST_DISC); + + /* Return 0 to not terminate the fsm */ + return 0; +} + +#define S(x) (1 << (x)) + +static struct osmo_fsm_state cnlink_fsm_states[] = { + [CNLINK_ST_DISC] = { + .name = "DISC", + .in_event_mask = 0 + | S(CNLINK_EV_RX_RESET) + | S(CNLINK_EV_RX_RESET_ACK) + , + .out_state_mask = 0 + | S(CNLINK_ST_DISC) + | S(CNLINK_ST_CONN) + , + .onenter = cnlink_disc_onenter, + .action = cnlink_disc_action, + }, + [CNLINK_ST_CONN] = { + .name = "CONN", + .in_event_mask = 0 + | S(CNLINK_EV_RX_RESET) + | S(CNLINK_EV_RX_RESET_ACK) + , + .out_state_mask = 0 + | S(CNLINK_ST_DISC) + | S(CNLINK_ST_CONN) + , + .onenter = cnlink_conn_onenter, + .action = cnlink_conn_action, + }, +}; + +static struct osmo_fsm cnlink_fsm = { + .name = "cnlink", + .states = cnlink_fsm_states, + .num_states = ARRAY_SIZE(cnlink_fsm_states), + .log_subsys = DRANAP, + .timer_cb = cnlink_fsm_timer_cb, + .event_names = cnlink_fsm_event_names, +}; + +bool cnlink_is_conn_ready(const struct hnbgw_cnlink *cnlink) +{ + return cnlink->fi->state == CNLINK_ST_CONN; +} + +void cnlink_resend_reset(struct hnbgw_cnlink *cnlink) +{ + /* Immediately (1ms) kick off reset sending mechanism */ + osmo_fsm_inst_state_chg_ms(cnlink->fi, CNLINK_ST_DISC, 1, 0); +} + +void cnlink_set_disconnected(struct hnbgw_cnlink *cnlink) +{ + /* Go to disconnected state, with the normal RESET timeout to re-send RESET. */ + cnlink_fsm_state_chg(cnlink->fi, CNLINK_ST_DISC); +} + +static __attribute__((constructor)) void cnlink_fsm_init(void) +{ + OSMO_ASSERT(osmo_fsm_register(&cnlink_fsm) == 0); +} + +void cnlink_rx_reset_cmd(struct hnbgw_cnlink *cnlink) +{ + osmo_fsm_inst_dispatch(cnlink->fi, CNLINK_EV_RX_RESET, NULL); +} + +void cnlink_rx_reset_ack(struct hnbgw_cnlink *cnlink) +{ + osmo_fsm_inst_dispatch(cnlink->fi, CNLINK_EV_RX_RESET_ACK, NULL); +} + diff --git a/src/osmo-hnbgw/context_map.c b/src/osmo-hnbgw/context_map.c index 12d9889..08d6a39 100644 --- a/src/osmo-hnbgw/context_map.c +++ b/src/osmo-hnbgw/context_map.c @@ -133,6 +133,7 @@ cnlink_selected->use.remote_addr_name ? " " : "", cnlink_selected->use.remote_addr_name ? : "", hsu->name, + /* printing the entire SCCP address is quite long, rather just print the point-code */ osmo_ss7_pointcode_print(hsu->ss7, hsu->local_addr.pc), osmo_ss7_pointcode_print2(hsu->ss7, cnlink_selected->remote_addr.pc) ); diff --git a/src/osmo-hnbgw/hnbgw_cn.c b/src/osmo-hnbgw/hnbgw_cn.c index 537544f..977766b 100644 --- a/src/osmo-hnbgw/hnbgw_cn.c +++ b/src/osmo-hnbgw/hnbgw_cn.c @@ -41,60 +41,6 @@ #include <osmocom/ranap/ranap_msg_factory.h> #include <osmocom/hnbgw/context_map.h> -#if 0 -this code will soon move to new file cnlink.c -static int transmit_rst(struct hnbgw_cnlink *cnlink) -{ - struct msgb *msg; - RANAP_Cause_t cause = { - .present = RANAP_Cause_PR_transmissionNetwork, - .choice. transmissionNetwork = RANAP_CauseTransmissionNetwork_signalling_transport_resource_failure, - }; - - if (!cnlink) - return -1; - - if (!cnlink->hnbgw_sccp_user) { - LOG_CNLINK(cnlink, DRANAP, LOGL_ERROR, "cannot send RANAP RESET: no CN link\n"); - return -1; - } - - LOG_CNLINK(cnlink, DRANAP, LOGL_NOTICE, "Tx RANAP RESET to %s %s\n", - cnlink_is_cs(cnlink) ? "IuCS" : "IuPS", - osmo_sccp_inst_addr_name(cnlink->hnbgw_sccp_user->sccp, &cnlink->remote_addr)); - - msg = ranap_new_msg_reset(cnlink->pool->domain, &cause); - - return osmo_sccp_tx_unitdata_msg(cnlink->hnbgw_sccp_user->sccp_user, - &cnlink->local_addr, - &cnlink->remote_addr, - msg); -} -#endif - -static int transmit_reset_ack(struct hnbgw_cnlink *cnlink) -{ - struct msgb *msg; - struct osmo_sccp_instance *sccp = cnlink_sccp(cnlink); - - if (!sccp) { - LOG_CNLINK(cnlink, DRANAP, LOGL_ERROR, "cannot send RANAP RESET ACK: no CN link\n"); - return -1; - } - - LOG_CNLINK(cnlink, DRANAP, LOGL_NOTICE, "Tx RANAP RESET ACK %s %s --> %s\n", - cnlink_is_cs(cnlink) ? "IuCS" : "IuPS", - cnlink_sccp_addr_to_str(cnlink, &cnlink->hnbgw_sccp_user->local_addr), - cnlink_sccp_addr_to_str(cnlink, &cnlink->remote_addr)); - - msg = ranap_new_msg_reset_ack(cnlink->pool->domain, NULL); - - return osmo_sccp_tx_unitdata_msg(cnlink->hnbgw_sccp_user->sccp_user, - &cnlink->hnbgw_sccp_user->local_addr, - &cnlink->remote_addr, - msg); -} - /*********************************************************************** * Incoming primitives from SCCP User SAP ***********************************************************************/ @@ -111,33 +57,45 @@ domain = ies.cN_DomainIndicator; ranap_free_reseties(&ies); - LOG_CNLINK(cnlink, DRANAP, LOGL_NOTICE, "Rx RESET from %s %s, returning ACK\n", - domain == DOMAIN_CS ? "IuCS" : "IuPS", - osmo_sccp_inst_addr_name(cnlink_sccp(cnlink), &unitdata->calling_addr)); + if (rc) { + LOG_CNLINK(cnlink, DCN, LOGL_ERROR, "Rx RESET: cannot decode IEs\n"); + return -1; + } - /* FIXME: actually reset connections, if any */ + if (cnlink->pool->domain != domain) { + LOG_CNLINK(cnlink, DCN, LOGL_ERROR, "Rx RESET indicates domain %s, but this is %s on domain %s\n", + ranap_domain_name(domain), cnlink->name, ranap_domain_name(cnlink->pool->domain)); + return -1; + } - if (transmit_reset_ack(cnlink)) - LOGP(DRANAP, LOGL_ERROR, "Error: cannot send RESET ACK to %s %s\n", - domain == DOMAIN_CS ? "IuCS" : "IuPS", - osmo_sccp_inst_addr_name(cnlink_sccp(cnlink), &unitdata->calling_addr)); - - return rc; + cnlink_rx_reset_cmd(cnlink); + return 0; } static int cn_ranap_rx_reset_ack(struct hnbgw_cnlink *cnlink, RANAP_SuccessfulOutcome_t *omsg) { + RANAP_CN_DomainIndicator_t domain; RANAP_ResetAcknowledgeIEs_t ies; int rc; rc = ranap_decode_resetacknowledgeies(&ies, &omsg->value); - - /* FUTURE: will do something useful in commit 'detect in/active CN links by RANAP RESET' - * Id3eefdea889a736fd5957b80280fa45b9547b792 */ - + domain = ies.cN_DomainIndicator; ranap_free_resetacknowledgeies(&ies); - return rc; + + if (rc) { + LOG_CNLINK(cnlink, DCN, LOGL_ERROR, "Rx RESET ACK: cannot decode IEs\n"); + return -1; + } + + if (cnlink->pool->domain != domain) { + LOG_CNLINK(cnlink, DCN, LOGL_ERROR, "Rx RESET ACK indicates domain %s, but this is %s on domain %s\n", + ranap_domain_name(domain), cnlink->name, ranap_domain_name(cnlink->pool->domain)); + return -1; + } + + cnlink_rx_reset_ack(cnlink); + return 0; } static int cn_ranap_rx_paging_cmd(struct hnbgw_cnlink *cnlink, @@ -654,28 +612,6 @@ hnbgw_cnpool_cnlinks_start_or_restart(cnpool); } -static struct hnbgw_cnlink *cnlink_alloc(struct hnbgw_cnpool *cnpool, int nr) -{ - struct hnbgw_cnlink *cnlink; - cnlink = talloc_zero(g_hnbgw, struct hnbgw_cnlink); - *cnlink = (struct hnbgw_cnlink){ - .name = talloc_asprintf(cnlink, "%s-%d", cnpool->peer_name, nr), - .pool = cnpool, - .nr = nr, - .vty = { - /* VTY config defaults for the new cnlink */ - .nri_ranges = osmo_nri_ranges_alloc(cnlink), - }, - .allow_attach = true, - .ctrs = rate_ctr_group_alloc(g_hnbgw, cnpool->cnlink_ctrg_desc, nr), - }; - INIT_LLIST_HEAD(&cnlink->map_list); - - llist_add_tail(&cnlink->entry, &cnpool->cnlinks); - LOG_CNLINK(cnlink, DCN, LOGL_DEBUG, "allocated\n"); - return cnlink; -} - struct hnbgw_cnlink *cnlink_get_nr(struct hnbgw_cnpool *cnpool, int nr, bool create_if_missing) { struct hnbgw_cnlink *cnlink; diff --git a/src/osmo-hnbgw/hnbgw_vty.c b/src/osmo-hnbgw/hnbgw_vty.c index 462a4fc..bee34f1 100644 --- a/src/osmo-hnbgw/hnbgw_vty.c +++ b/src/osmo-hnbgw/hnbgw_vty.c @@ -710,6 +710,35 @@ return CMD_SUCCESS; } +DEFUN(cnlink_ranap_reset, cnlink_ranap_reset_cmd, + "(msc|sgsn) " CNLINK_NR_RANGE " ranap reset", + "Manipulate an IuCS link to an MSC\n" + "Manipulate an IuPS link to an SGSN\n" + "MSC/SGSN nr\n" + "Manipulate RANAP layer of Iu-interface\n" + "Flip this CN link to disconnected state and re-send RANAP RESET\n") +{ + struct hnbgw_cnpool *cnpool; + struct hnbgw_cnlink *cnlink; + const char *msc_sgsn = argv[0]; + int nr = atoi(argv[1]); + + if (!strcmp("msc", msc_sgsn)) + cnpool = &g_hnbgw->sccp.cnpool_iucs; + else + cnpool = &g_hnbgw->sccp.cnpool_iups; + + cnlink = cnlink_get_nr(cnpool, nr, false); + if (!cnlink) { + vty_out(vty, "%% No such %s: nr %d\n", msc_sgsn, nr); + return CMD_WARNING; + } + + LOG_CNLINK(cnlink, DCN, LOGL_NOTICE, "VTY requests BSSMAP RESET\n"); + cnlink_resend_reset(cnlink); + return CMD_SUCCESS; +} + #define APPLY_STR "Immediately use configuration modified via telnet VTY, and restart components as needed.\n" #define SCCP_RESTART_STR \ " If 'remote-addr' changed, related SCCP links will be restarted, possibly dropping active UE contexts." @@ -976,4 +1005,5 @@ install_element_ve(&show_nri_cmd); install_element(ENABLE_NODE, &cnpool_roundrobin_next_cmd); + install_element(ENABLE_NODE, &cnlink_ranap_reset_cmd); } diff --git a/src/osmo-hnbgw/tdefs.c b/src/osmo-hnbgw/tdefs.c index 645cdbf..992c140 100644 --- a/src/osmo-hnbgw/tdefs.c +++ b/src/osmo-hnbgw/tdefs.c @@ -32,6 +32,7 @@ }; struct osmo_tdef hnbgw_T_defs[] = { + {.T = 4, .default_val = 5, .desc = "Timeout to receive RANAP RESET ACKNOWLEDGE from an MSC/SGSN" }, {.T = -31, .default_val = 5, .desc = "Timeout for discarding a partially released context map (RUA <-> SCCP)" }, {.T = -1002, .default_val = 10, .desc = "Timeout for the HNB to respond to PS RAB Assignment Request" }, { } diff --git a/tests/cnpool.vty b/tests/cnpool.vty index 9745306..2de56a7 100644 --- a/tests/cnpool.vty +++ b/tests/cnpool.vty @@ -1,4 +1,26 @@ OsmoHNBGW> enable +OsmoHNBGW# list +... + (msc|sgsn) <0-1000> ranap reset +... +OsmoHNBGW# msc? + msc Manipulate an IuCS link to an MSC +OsmoHNBGW# msc ? + <0-1000> MSC/SGSN nr +OsmoHNBGW# msc 0 ? + ranap Manipulate RANAP layer of Iu-interface +OsmoHNBGW# msc 0 ranap ? + reset Flip this CN link to disconnected state and re-send RANAP RESET + +OsmoHNBGW# sgsn? + sgsn Manipulate an IuPS link to an SGSN +OsmoHNBGW# sgsn ? + <0-1000> MSC/SGSN nr +OsmoHNBGW# sgsn 0 ? + ranap Manipulate RANAP layer of Iu-interface +OsmoHNBGW# sgsn 0 ranap ? + reset Flip this CN link to disconnected state and re-send RANAP RESET + OsmoHNBGW# configure terminal OsmoHNBGW(config)# ### cnpool doc strings -- To view, visit https://gerrit.osmocom.org/c/osmo-hnbgw/+/33175 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-hnbgw Gerrit-Branch: master Gerrit-Change-Id: Id3eefdea889a736fd5957b80280fa45b9547b792 Gerrit-Change-Number: 33175 Gerrit-PatchSet: 8 Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: neels <nhofmeyr(a)sysmocom.de> Gerrit-Reviewer: pespin <pespin(a)sysmocom.de> Gerrit-MessageType: merged
1 0
0 0
[S] Change in osmo-hnbgw[master]: use cnlink state in cnpool decisions
by neels 22 Jun '23

22 Jun '23
neels has submitted this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/33176 ) ( 4 is the latest approved patch-set. No files were changed between the latest approved patch-set and the submitted one. )Change subject: use cnlink state in cnpool decisions ...................................................................... use cnlink state in cnpool decisions Change-Id: I28490a4a27bcda8fd689db8b8652e451103e3a9d --- M src/osmo-hnbgw/hnbgw_cn.c 1 file changed, 11 insertions(+), 1 deletion(-) Approvals: pespin: Looks good to me, but someone else must approve laforge: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo-hnbgw/hnbgw_cn.c b/src/osmo-hnbgw/hnbgw_cn.c index 977766b..cf22ba4 100644 --- a/src/osmo-hnbgw/hnbgw_cn.c +++ b/src/osmo-hnbgw/hnbgw_cn.c @@ -656,7 +656,8 @@ return false; if (!cnlink->hnbgw_sccp_user || !cnlink->hnbgw_sccp_user->sccp_user) return false; - // TODO indicator whether the CN link is actually active, akin to bssmap_reset_is_conn_ready() + if (!cnlink_is_conn_ready(cnlink)) + return false; return true; } -- To view, visit https://gerrit.osmocom.org/c/osmo-hnbgw/+/33176 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-hnbgw Gerrit-Branch: master Gerrit-Change-Id: I28490a4a27bcda8fd689db8b8652e451103e3a9d Gerrit-Change-Number: 33176 Gerrit-PatchSet: 8 Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: neels <nhofmeyr(a)sysmocom.de> Gerrit-Reviewer: pespin <pespin(a)sysmocom.de> Gerrit-MessageType: merged
1 0
0 0
[L] Change in osmo-hnbgw[master]: cnpool: return Paging Resp to the exact CN link that Paged
by neels 22 Jun '23

22 Jun '23
neels has submitted this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/33177 ) ( 4 is the latest approved patch-set. No files were changed between the latest approved patch-set and the submitted one. )Change subject: cnpool: return Paging Resp to the exact CN link that Paged ...................................................................... cnpool: return Paging Resp to the exact CN link that Paged Implement Paging record, remembering which CN link paged for which mobile identity, for a set time period roundabout 15 seconds. When receiving a Paging Response from a UE, connect it to the CN link that sent the Paging. Related: SYS#6412 Change-Id: I907dbcaeb442ca5630146f8cad40601c448fc40e --- M include/osmocom/hnbgw/hnbgw.h M src/osmo-hnbgw/cnlink.c M src/osmo-hnbgw/hnbgw_cn.c M src/osmo-hnbgw/tdefs.c 4 files changed, 347 insertions(+), 9 deletions(-) Approvals: pespin: Looks good to me, but someone else must approve laforge: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/hnbgw/hnbgw.h b/include/osmocom/hnbgw/hnbgw.h index 69ce186..ed3cd62 100644 --- a/include/osmocom/hnbgw/hnbgw.h +++ b/include/osmocom/hnbgw/hnbgw.h @@ -180,6 +180,7 @@ bool allow_attach; bool allow_emerg; + struct llist_head paging; struct rate_ctr_group *ctrs; }; diff --git a/src/osmo-hnbgw/cnlink.c b/src/osmo-hnbgw/cnlink.c index a6e9e17..c98d713 100644 --- a/src/osmo-hnbgw/cnlink.c +++ b/src/osmo-hnbgw/cnlink.c @@ -87,6 +87,7 @@ }; talloc_steal(cnlink, name); INIT_LLIST_HEAD(&cnlink->map_list); + INIT_LLIST_HEAD(&cnlink->paging); llist_add_tail(&cnlink->entry, &cnpool->cnlinks); LOG_CNLINK(cnlink, DCN, LOGL_DEBUG, "allocated\n"); diff --git a/src/osmo-hnbgw/hnbgw_cn.c b/src/osmo-hnbgw/hnbgw_cn.c index cf22ba4..58b0af8 100644 --- a/src/osmo-hnbgw/hnbgw_cn.c +++ b/src/osmo-hnbgw/hnbgw_cn.c @@ -23,6 +23,8 @@ #include <arpa/inet.h> #include <errno.h> +#include <asn1c/asn1helpers.h> + #include <osmocom/core/msgb.h> #include <osmocom/core/utils.h> #include <osmocom/core/timer.h> @@ -37,8 +39,10 @@ #include <osmocom/hnbgw/hnbgw.h> #include <osmocom/hnbgw/hnbgw_rua.h> #include <osmocom/hnbgw/hnbgw_cn.h> +#include <osmocom/hnbgw/tdefs.h> #include <osmocom/ranap/ranap_ies_defs.h> #include <osmocom/ranap/ranap_msg_factory.h> +#include <osmocom/ranap/iu_helpers.h> #include <osmocom/hnbgw/context_map.h> /*********************************************************************** @@ -98,25 +102,212 @@ return 0; } +struct cnlink_paging { + struct llist_head entry; + + struct osmo_mobile_identity mi; + struct osmo_mobile_identity mi2; + time_t timestamp; +}; + +static int cnlink_paging_destructor(struct cnlink_paging *p) +{ + llist_del(&p->entry); + return 0; +} + +/* Return current timestamp in *timestamp, and the oldest still valid timestamp according to T3113 timeout. */ +static const char *cnlink_paging_gettime(time_t *timestamp_p, time_t *timeout_p) +{ + struct timespec now; + time_t timestamp; + + /* get timestamp */ + if (osmo_clock_gettime(CLOCK_MONOTONIC, &now) != 0) + return "cannot get timestamp"; + timestamp = now.tv_sec; + + if (timestamp_p) + *timestamp_p = timestamp; + if (timeout_p) + *timeout_p = timestamp - osmo_tdef_get(hnbgw_T_defs, 3113, OSMO_TDEF_S, 15); + return NULL; +} + +static const char *cnlink_paging_add(struct hnbgw_cnlink *cnlink, const struct osmo_mobile_identity *mi, + const struct osmo_mobile_identity *mi2) +{ + struct cnlink_paging *p, *p2; + time_t timestamp; + time_t timeout; + const char *errmsg; + + errmsg = cnlink_paging_gettime(&timestamp, &timeout); + if (errmsg) + return errmsg; + + /* Prune all paging records that are older than the configured timeout. */ + llist_for_each_entry_safe(p, p2, &cnlink->paging, entry) { + if (p->timestamp >= timeout) + continue; + talloc_free(p); + } + + /* Add new entry */ + p = talloc_zero(cnlink, struct cnlink_paging); + *p = (struct cnlink_paging){ + .timestamp = timestamp, + .mi = *mi, + .mi2 = *mi2, + }; + llist_add_tail(&p->entry, &cnlink->paging); + talloc_set_destructor(p, cnlink_paging_destructor); + + LOG_CNLINK(cnlink, DCN, LOGL_INFO, "Rx Paging from CN for %s %s\n", + osmo_mobile_identity_to_str_c(OTC_SELECT, mi), + osmo_mobile_identity_to_str_c(OTC_SELECT, mi2)); + return NULL; +} + +static const char *omi_from_ranap_ue_id(struct osmo_mobile_identity *mi, const RANAP_PermanentNAS_UE_ID_t *ranap_mi) +{ + if (!ranap_mi) + return "null UE ID"; + + if (ranap_mi->present != RANAP_PermanentNAS_UE_ID_PR_iMSI) + return talloc_asprintf(OTC_SELECT, "unsupported UE ID type %u in RANAP Paging", ranap_mi->present); + + if (ranap_mi->choice.iMSI.size > sizeof(mi->imsi)) + return talloc_asprintf(OTC_SELECT, "invalid IMSI size %d > %zu", + ranap_mi->choice.iMSI.size, sizeof(mi->imsi)); + + *mi = (struct osmo_mobile_identity){ + .type = GSM_MI_TYPE_IMSI, + }; + ranap_bcd_decode(mi->imsi, sizeof(mi->imsi), ranap_mi->choice.iMSI.buf, ranap_mi->choice.iMSI.size); + LOGP(DCN, LOGL_DEBUG, "ranap MI %s = %s\n", osmo_hexdump(ranap_mi->choice.iMSI.buf, ranap_mi->choice.iMSI.size), + mi->imsi); + return NULL; +} + +static const char *omi_from_ranap_temp_ue_id(struct osmo_mobile_identity *mi, const RANAP_TemporaryUE_ID_t *ranap_tmsi) +{ + const OCTET_STRING_t *tmsi_str; + + if (!ranap_tmsi) + return "null UE ID"; + + switch (ranap_tmsi->present) { + case RANAP_TemporaryUE_ID_PR_tMSI: + tmsi_str = &ranap_tmsi->choice.tMSI; + break; + case RANAP_TemporaryUE_ID_PR_p_TMSI: + tmsi_str = &ranap_tmsi->choice.p_TMSI; + break; + default: + return talloc_asprintf(OTC_SELECT, "unsupported Temporary UE ID type %u in RANAP Paging", ranap_tmsi->present); + } + + *mi = (struct osmo_mobile_identity){ + .type = GSM_MI_TYPE_TMSI, + .tmsi = asn1str_to_u32(tmsi_str), + }; + LOGP(DCN, LOGL_DEBUG, "ranap temp UE ID = %s\n", osmo_mobile_identity_to_str_c(OTC_SELECT, mi)); + return NULL; +} + +static const char *cnlink_paging_add_ranap(struct hnbgw_cnlink *cnlink, RANAP_InitiatingMessage_t *imsg) +{ + RANAP_PagingIEs_t ies; + struct osmo_mobile_identity mi = {}; + struct osmo_mobile_identity mi2 = {}; + RANAP_CN_DomainIndicator_t domain; + const char *errmsg; + + if (ranap_decode_pagingies(&ies, &imsg->value) < 0) + return "decoding RANAP IEs failed"; + + domain = ies.cN_DomainIndicator; + errmsg = omi_from_ranap_ue_id(&mi, &ies.permanentNAS_UE_ID); + + if (!errmsg && (ies.presenceMask & PAGINGIES_RANAP_TEMPORARYUE_ID_PRESENT)) + errmsg = omi_from_ranap_temp_ue_id(&mi2, &ies.temporaryUE_ID); + + ranap_free_pagingies(&ies); + LOG_CNLINK(cnlink, DCN, LOGL_DEBUG, "Decoded Paging: %s %s %s%s%s\n", + ranap_domain_name(domain), osmo_mobile_identity_to_str_c(OTC_SELECT, &mi), + mi2.type ? osmo_mobile_identity_to_str_c(OTC_SELECT, &mi2) : "-", + errmsg ? " -- MI error: " : "", + errmsg ? : ""); + + if (cnlink->pool->domain != domain) + return talloc_asprintf(OTC_SELECT, "message indicates domain %s, but this is %s on domain %s\n", + ranap_domain_name(domain), cnlink->name, ranap_domain_name(cnlink->pool->domain)); + + if (errmsg) + return errmsg; + + return cnlink_paging_add(cnlink, &mi, &mi2); +} + +/* If this cnlink has a recent Paging for the given MI, return true and drop the Paging record. + * Else return false. */ +static bool cnlink_match_paging_mi(struct hnbgw_cnlink *cnlink, const struct osmo_mobile_identity *mi, time_t timeout) +{ + struct cnlink_paging *p, *p2; + llist_for_each_entry_safe(p, p2, &cnlink->paging, entry) { + if (p->timestamp < timeout) { + talloc_free(p); + continue; + } + if (osmo_mobile_identity_cmp(&p->mi, mi) + && osmo_mobile_identity_cmp(&p->mi2, mi)) + continue; + talloc_free(p); + return true; + } + return false; +} + +static struct hnbgw_cnlink *cnlink_find_by_paging_mi(struct hnbgw_cnpool *cnpool, const struct osmo_mobile_identity *mi) +{ + struct hnbgw_cnlink *cnlink; + time_t timeout = 0; + const char *errmsg; + + errmsg = cnlink_paging_gettime(NULL, &timeout); + if (errmsg) + LOGP(DCN, LOGL_ERROR, "%s\n", errmsg); + + llist_for_each_entry(cnlink, &cnpool->cnlinks, entry) { + if (!cnlink_match_paging_mi(cnlink, mi, timeout)) + continue; + return cnlink; + } + return NULL; +} + static int cn_ranap_rx_paging_cmd(struct hnbgw_cnlink *cnlink, RANAP_InitiatingMessage_t *imsg, const uint8_t *data, unsigned int len) { + const char *errmsg; struct hnb_context *hnb; - RANAP_PagingIEs_t ies; - int rc; - rc = ranap_decode_pagingies(&ies, &imsg->value); - if (rc < 0) - return rc; + errmsg = cnlink_paging_add_ranap(cnlink, imsg); + if (errmsg) { + LOG_CNLINK(cnlink, DCN, LOGL_ERROR, "Rx Paging from CN: %s. Dropping paging record." + " Later on, the Paging Response may be forwarded to the wrong CN peer.\n", + errmsg); + return -1; + } /* FIXME: determine which HNBs to send this Paging command, * rather than broadcasting to all HNBs */ llist_for_each_entry(hnb, &g_hnbgw->hnb_list, list) { - rc = rua_tx_udt(hnb, data, len); + rua_tx_udt(hnb, data, len); } - ranap_free_pagingies(&ies); return 0; } @@ -314,6 +505,122 @@ return map_sccp_dispatch(map, MAP_SCCP_EV_RX_RELEASED, oph->msg); } +static struct hnbgw_cnlink *_cnlink_find_by_remote_pc(struct hnbgw_cnpool *cnpool, struct osmo_ss7_instance *cs7, uint32_t pc) +{ + struct hnbgw_cnlink *cnlink; + llist_for_each_entry(cnlink, &cnpool->cnlinks, entry) { + if (!cnlink->hnbgw_sccp_user) + continue; + if (cnlink->hnbgw_sccp_user->ss7 != cs7) + continue; + if ((cnlink->remote_addr.presence & OSMO_SCCP_ADDR_T_PC) == 0) + continue; + if (cnlink->remote_addr.pc != pc) + continue; + return cnlink; + } + return NULL; +} + +/* Find a cnlink by its remote sigtran point code on a given cs7 instance. */ +static struct hnbgw_cnlink *cnlink_find_by_remote_pc(struct osmo_ss7_instance *cs7, uint32_t pc) +{ + struct hnbgw_cnlink *cnlink; + cnlink = _cnlink_find_by_remote_pc(&g_hnbgw->sccp.cnpool_iucs, cs7, pc); + if (!cnlink) + cnlink = _cnlink_find_by_remote_pc(&g_hnbgw->sccp.cnpool_iups, cs7, pc); + return cnlink; +} + +static void handle_pcstate_ind(struct hnbgw_sccp_user *hsu, const struct osmo_scu_pcstate_param *pcst) +{ + struct hnbgw_cnlink *cnlink; + bool connected; + bool disconnected; + struct osmo_ss7_instance *cs7 = hsu->ss7; + + LOGP(DCN, LOGL_DEBUG, "N-PCSTATE ind: affected_pc=%u sp_status=%s remote_sccp_status=%s\n", + pcst->affected_pc, osmo_sccp_sp_status_name(pcst->sp_status), + osmo_sccp_rem_sccp_status_name(pcst->remote_sccp_status)); + + /* If we don't care about that point-code, ignore PCSTATE. */ + cnlink = cnlink_find_by_remote_pc(cs7, pcst->affected_pc); + if (!cnlink) + return; + + /* See if this marks the point code to have become available, or to have been lost. + * + * I want to detect two events: + * - connection event (both indicators say PC is reachable). + * - disconnection event (at least one indicator says the PC is not reachable). + * + * There are two separate incoming indicators with various possible values -- the incoming events can be: + * + * - neither connection nor disconnection indicated -- just indicating congestion + * connected == false, disconnected == false --> do nothing. + * - both incoming values indicate that we are connected + * --> trigger connected + * - both indicate we are disconnected + * --> trigger disconnected + * - one value indicates 'connected', the other indicates 'disconnected' + * --> trigger disconnected + * + * Congestion could imply that we're connected, but it does not indicate that a PC's reachability changed, so no need to + * trigger on that. + */ + connected = false; + disconnected = false; + + switch (pcst->sp_status) { + case OSMO_SCCP_SP_S_ACCESSIBLE: + connected = true; + break; + case OSMO_SCCP_SP_S_INACCESSIBLE: + disconnected = true; + break; + default: + case OSMO_SCCP_SP_S_CONGESTED: + /* Neither connecting nor disconnecting */ + break; + } + + switch (pcst->remote_sccp_status) { + case OSMO_SCCP_REM_SCCP_S_AVAILABLE: + if (!disconnected) + connected = true; + break; + case OSMO_SCCP_REM_SCCP_S_UNAVAILABLE_UNKNOWN: + case OSMO_SCCP_REM_SCCP_S_UNEQUIPPED: + case OSMO_SCCP_REM_SCCP_S_INACCESSIBLE: + disconnected = true; + connected = false; + break; + default: + case OSMO_SCCP_REM_SCCP_S_CONGESTED: + /* Neither connecting nor disconnecting */ + break; + } + + if (disconnected && cnlink_is_conn_ready(cnlink)) { + LOG_CNLINK(cnlink, DCN, LOGL_NOTICE, + "now unreachable: N-PCSTATE ind: pc=%u sp_status=%s remote_sccp_status=%s\n", + pcst->affected_pc, + osmo_sccp_sp_status_name(pcst->sp_status), + osmo_sccp_rem_sccp_status_name(pcst->remote_sccp_status)); + /* A previously usable cnlink has disconnected. Kick it back to DISC state. */ + cnlink_set_disconnected(cnlink); + } else if (connected && !cnlink_is_conn_ready(cnlink)) { + LOG_CNLINK(cnlink, DCN, LOGL_NOTICE, + "now available: N-PCSTATE ind: pc=%u sp_status=%s remote_sccp_status=%s\n", + pcst->affected_pc, + osmo_sccp_sp_status_name(pcst->sp_status), + osmo_sccp_rem_sccp_status_name(pcst->remote_sccp_status)); + /* A previously unusable cnlink has become reachable. Trigger immediate RANAP RESET -- we would resend a + * RESET either way, but we might as well do it now to speed up connecting. */ + cnlink_resend_reset(cnlink); + } +} + /* Entry point for primitives coming up from SCCP User SAP */ static int sccp_sap_up(struct osmo_prim_hdr *oph, void *ctx) { @@ -355,9 +662,9 @@ rc = handle_cn_disc_ind(hsu, &prim->u.disconnect, oph); break; case OSMO_PRIM(OSMO_SCU_PRIM_N_PCSTATE, PRIM_OP_INDICATION): - LOGP(DCN, LOGL_DEBUG, "Ignoring prim %s from SCCP USER SAP\n", - osmo_scu_prim_hdr_name_c(OTC_SELECT, oph)); + handle_pcstate_ind(hsu, &prim->u.pcstate); break; + default: LOGP(DCN, LOGL_ERROR, "Received unknown prim %u from SCCP USER SAP\n", @@ -678,6 +985,18 @@ bool is_null_nri = false; uint8_t nri_bitlen = cnpool->use.nri_bitlen; + /* Match IMSI with previous Paging */ + if (map->l3.gsm48_msg_type == GSM48_MT_RR_PAG_RESP) { + cnlink = cnlink_find_by_paging_mi(cnpool, &map->l3.mi); + if (cnlink) { + LOG_MAP(map, DCN, LOGL_INFO, "CN link paging record selects %s %d\n", cnpool->peer_name, + cnlink->nr); + rate_ctr_inc(rate_ctr_group_get_ctr(cnlink->ctrs, CNLINK_CTR_CNPOOL_SUBSCR_PAGED)); + return cnlink; + } + /* If there is no match, go on with other ways */ + } + #define LOG_NRI(LOGLEVEL, FORMAT, ARGS...) \ LOG_MAP(map, DCN, LOGLEVEL, "%s NRI(%dbit)=0x%x=%d: " FORMAT, osmo_mobile_identity_to_str_c(OTC_SELECT, &map->l3.mi), \ nri_bitlen, nri_v, nri_v, ##ARGS) diff --git a/src/osmo-hnbgw/tdefs.c b/src/osmo-hnbgw/tdefs.c index 992c140..601f704 100644 --- a/src/osmo-hnbgw/tdefs.c +++ b/src/osmo-hnbgw/tdefs.c @@ -32,6 +32,7 @@ }; struct osmo_tdef hnbgw_T_defs[] = { + {.T = 3113, .default_val = 15, .desc = "Time to keep Paging record, for CN pools with more than one link" }, {.T = 4, .default_val = 5, .desc = "Timeout to receive RANAP RESET ACKNOWLEDGE from an MSC/SGSN" }, {.T = -31, .default_val = 5, .desc = "Timeout for discarding a partially released context map (RUA <-> SCCP)" }, {.T = -1002, .default_val = 10, .desc = "Timeout for the HNB to respond to PS RAB Assignment Request" }, -- To view, visit https://gerrit.osmocom.org/c/osmo-hnbgw/+/33177 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-hnbgw Gerrit-Branch: master Gerrit-Change-Id: I907dbcaeb442ca5630146f8cad40601c448fc40e Gerrit-Change-Number: 33177 Gerrit-PatchSet: 8 Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: neels <nhofmeyr(a)sysmocom.de> Gerrit-Reviewer: pespin <pespin(a)sysmocom.de> Gerrit-MessageType: merged
1 0
0 0
[M] Change in osmo-hnbgw[master]: cfg: add 'hnbgw' / 'plmn MCC MNC'
by neels 22 Jun '23

22 Jun '23
neels has submitted this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/33178 ) ( 5 is the latest approved patch-set. No files were changed between the latest approved patch-set and the submitted one. )Change subject: cfg: add 'hnbgw' / 'plmn MCC MNC' ...................................................................... cfg: add 'hnbgw' / 'plmn MCC MNC' According to 3GPP TS 25.413 8.26.2.2, "The RNC shall include the Global RNC-ID IE in the RESET message." To be able to do that, osmo-hnbgw needs to know the local PLMN. Introduce explicit knowledge of the local PLMN by config, and use this configured local PLMN in places where the local PLMN was so far derived otherwise. Subsequent patches will separately add the RNC-ID to the RANAP RESET messages. Since the PLMN is required to send correct RESET and RESET ACK, include the new 'plmn' config item in all example configurations. Related: SYS#6441 Change-Id: If404c3859acdfba274c719c7cb7d16f97d831a2a --- M doc/examples/osmo-hnbgw/osmo-hnbgw-cnpool.cfg M doc/examples/osmo-hnbgw/osmo-hnbgw-cs7.cfg M doc/examples/osmo-hnbgw/osmo-hnbgw-pfcp.cfg M doc/examples/osmo-hnbgw/osmo-hnbgw.cfg M include/osmocom/hnbgw/hnbgw.h M src/osmo-hnbgw/hnbgw.c M src/osmo-hnbgw/hnbgw_l3.c M src/osmo-hnbgw/hnbgw_vty.c M tests/osmo-hnbgw.vty 9 files changed, 115 insertions(+), 6 deletions(-) Approvals: laforge: Looks good to me, but someone else must approve pespin: Looks good to me, but someone else must approve neels: Looks good to me, approved Jenkins Builder: Verified diff --git a/doc/examples/osmo-hnbgw/osmo-hnbgw-cnpool.cfg b/doc/examples/osmo-hnbgw/osmo-hnbgw-cnpool.cfg index 2d0348d..3236afb 100644 --- a/doc/examples/osmo-hnbgw/osmo-hnbgw-cnpool.cfg +++ b/doc/examples/osmo-hnbgw/osmo-hnbgw-cnpool.cfg @@ -19,6 +19,7 @@ point-code 0.2.0 hnbgw + plmn 001 01 iucs nri bitlen 10 nri null add 0 7 diff --git a/doc/examples/osmo-hnbgw/osmo-hnbgw-cs7.cfg b/doc/examples/osmo-hnbgw/osmo-hnbgw-cs7.cfg index 601c02e..8be4b1b 100644 --- a/doc/examples/osmo-hnbgw/osmo-hnbgw-cs7.cfg +++ b/doc/examples/osmo-hnbgw/osmo-hnbgw-cs7.cfg @@ -10,6 +10,7 @@ point-code 1.4.2 hnbgw + plmn 001 01 iuh local-ip 0.0.0.0 hnbap-allow-tmsi 1 diff --git a/doc/examples/osmo-hnbgw/osmo-hnbgw-pfcp.cfg b/doc/examples/osmo-hnbgw/osmo-hnbgw-pfcp.cfg index cc853d5..087764c 100644 --- a/doc/examples/osmo-hnbgw/osmo-hnbgw-pfcp.cfg +++ b/doc/examples/osmo-hnbgw/osmo-hnbgw-pfcp.cfg @@ -8,6 +8,7 @@ logging print extended-timestamp 1 logging level set-all notice hnbgw + plmn 001 01 iuh local-ip 0.0.0.0 hnbap-allow-tmsi 1 diff --git a/doc/examples/osmo-hnbgw/osmo-hnbgw.cfg b/doc/examples/osmo-hnbgw/osmo-hnbgw.cfg index 82731a8..a9edc77 100644 --- a/doc/examples/osmo-hnbgw/osmo-hnbgw.cfg +++ b/doc/examples/osmo-hnbgw/osmo-hnbgw.cfg @@ -8,6 +8,7 @@ logging print extended-timestamp 1 logging level set-all notice hnbgw + plmn 001 01 iuh local-ip 0.0.0.0 hnbap-allow-tmsi 1 diff --git a/include/osmocom/hnbgw/hnbgw.h b/include/osmocom/hnbgw/hnbgw.h index ed3cd62..e62fc71 100644 --- a/include/osmocom/hnbgw/hnbgw.h +++ b/include/osmocom/hnbgw/hnbgw.h @@ -6,6 +6,7 @@ #include <osmocom/core/write_queue.h> #include <osmocom/core/timer.h> #include <osmocom/core/rate_ctr.h> +#include <osmocom/gsm/gsm23003.h> #include <osmocom/sigtran/sccp_sap.h> #include <osmocom/sigtran/osmo_ss7.h> #include <osmocom/ctrl/control_if.h> @@ -253,6 +254,7 @@ /*! The UDP port where we receive multiplexed CS user * plane traffic from HNBs */ uint16_t iuh_cs_mux_port; + struct osmo_plmn_id plmn; uint16_t rnc_id; bool hnbap_allow_tmsi; /*! print hnb-id (true) or MCC-MNC-LAC-RAC-SAC (false) in logs */ diff --git a/src/osmo-hnbgw/hnbgw.c b/src/osmo-hnbgw/hnbgw.c index 7faf7f7..086582e 100644 --- a/src/osmo-hnbgw/hnbgw.c +++ b/src/osmo-hnbgw/hnbgw.c @@ -57,6 +57,9 @@ g_hnbgw->config.iuh_local_port = IUH_DEFAULT_SCTP_PORT; g_hnbgw->config.log_prefix_hnb_id = true; + /* Set zero PLMN to detect a missing PLMN when transmitting RESET */ + g_hnbgw->config.plmn = (struct osmo_plmn_id){ 0, 0, false }; + g_hnbgw->next_ue_ctx_id = 23; INIT_LLIST_HEAD(&g_hnbgw->hnb_list); INIT_LLIST_HEAD(&g_hnbgw->ue_list); diff --git a/src/osmo-hnbgw/hnbgw_l3.c b/src/osmo-hnbgw/hnbgw_l3.c index 6a9c62f..a6b48ce 100644 --- a/src/osmo-hnbgw/hnbgw_l3.c +++ b/src/osmo-hnbgw/hnbgw_l3.c @@ -279,15 +279,21 @@ static int peek_l3_initial_ue(struct hnbgw_context_map *map, const RANAP_InitialUE_MessageIEs_t *ies) { - struct osmo_plmn_id plmn; + struct osmo_plmn_id local_plmn; - if (ies->lai.pLMNidentity.size < 3) { - LOGP(DCN, LOGL_ERROR, "Missing PLMN in RANAP InitialUE message\n"); - return -EINVAL; + if (g_hnbgw->config.plmn.mcc) { + /* The user has configured a PLMN */ + local_plmn = g_hnbgw->config.plmn; + } else { + /* The user has not configured a PLMN, guess from the InitialUE message's LAI IE's PLMN */ + if (ies->lai.pLMNidentity.size < 3) { + LOGP(DCN, LOGL_ERROR, "Missing PLMN in RANAP InitialUE message\n"); + return -EINVAL; + } + osmo_plmn_from_bcd(ies->lai.pLMNidentity.buf, &local_plmn); } - osmo_plmn_from_bcd(ies->lai.pLMNidentity.buf, &plmn); - return peek_l3_nas(map, ies->nas_pdu.buf, ies->nas_pdu.size, &plmn); + return peek_l3_nas(map, ies->nas_pdu.buf, ies->nas_pdu.size, &local_plmn); } /* Extract a Layer 3 message (NAS PDU) from the RANAP message, and put the info obtained in map->l3. This is relevant diff --git a/src/osmo-hnbgw/hnbgw_vty.c b/src/osmo-hnbgw/hnbgw_vty.c index bee34f1..8cbe249 100644 --- a/src/osmo-hnbgw/hnbgw_vty.c +++ b/src/osmo-hnbgw/hnbgw_vty.c @@ -281,6 +281,28 @@ return CMD_SUCCESS; } +DEFUN(cfg_hnbgw_plmn, cfg_hnbgw_plmn_cmd, + "plmn <1-999> <0-999>", + "Configure the HNBGW's PLMN. The PLMN is transmitted in RANAP RESET towards the CN.\n" + "MCC, Mobile Country Code\n" + "MNC, Mobile Network Code\n") +{ + struct osmo_plmn_id plmn; + + if (osmo_mcc_from_str(argv[0], &plmn.mcc)) { + vty_out(vty, "%% Error decoding MCC: %s%s", argv[0], VTY_NEWLINE); + return CMD_WARNING; + } + + if (osmo_mnc_from_str(argv[1], &plmn.mnc, &plmn.mnc_3_digits)) { + vty_out(vty, "%% Error decoding MNC: %s%s", argv[1], VTY_NEWLINE); + return CMD_WARNING; + } + + g_hnbgw->config.plmn = plmn; + return CMD_SUCCESS; +} + DEFUN(cfg_hnbgw_rnc_id, cfg_hnbgw_rnc_id_cmd, "rnc-id <0-65535>", "Configure the HNBGW's RNC Id, the common RNC Id used for all connected hNodeB. It is sent to" @@ -849,6 +871,12 @@ { vty_out(vty, "hnbgw%s", VTY_NEWLINE); + if (g_hnbgw->config.plmn.mcc) + vty_out(vty, " plmn %s %s%s", + osmo_mcc_name_c(OTC_SELECT, g_hnbgw->config.plmn.mcc), + osmo_mnc_name_c(OTC_SELECT, g_hnbgw->config.plmn.mnc, g_hnbgw->config.plmn.mnc_3_digits), + VTY_NEWLINE); + vty_out(vty, " rnc-id %u%s", g_hnbgw->config.rnc_id, VTY_NEWLINE); vty_out(vty, " log-prefix %s%s", g_hnbgw->config.log_prefix_hnb_id ? "hnb-id" : "umts-cell-id", @@ -941,6 +969,7 @@ install_element(CONFIG_NODE, &cfg_hnbgw_cmd); install_node(&hnbgw_node, config_write_hnbgw); + install_element(HNBGW_NODE, &cfg_hnbgw_plmn_cmd); install_element(HNBGW_NODE, &cfg_hnbgw_rnc_id_cmd); install_element(HNBGW_NODE, &cfg_hnbgw_log_prefix_cmd); install_element(HNBGW_NODE, &cfg_hnbgw_max_sccp_cr_payload_len_cmd); diff --git a/tests/osmo-hnbgw.vty b/tests/osmo-hnbgw.vty index 72916fb..41bcb73 100644 --- a/tests/osmo-hnbgw.vty +++ b/tests/osmo-hnbgw.vty @@ -11,6 +11,7 @@ OsmoHNBGW(config)# hnbgw OsmoHNBGW(config-hnbgw)# list ... + plmn <1-999> <0-999> rnc-id <0-65535> log-prefix (hnb-id|umts-cell-id) iuh @@ -18,6 +19,46 @@ iups ... +OsmoHNBGW(config-hnbgw)# plmn? + plmn Configure the HNBGW's PLMN. The PLMN is transmitted in RANAP RESET towards the CN. +OsmoHNBGW(config-hnbgw)# plmn ? + <1-999> MCC, Mobile Country Code +OsmoHNBGW(config-hnbgw)# plmn 1 ? + <0-999> MNC, Mobile Network Code +OsmoHNBGW(config-hnbgw)# show running-config +... !plmn +OsmoHNBGW(config-hnbgw)# plmn 001 01 +OsmoHNBGW(config-hnbgw)# show running-config +... +hnbgw +... + plmn 001 01 +... + +OsmoHNBGW(config-hnbgw)# plmn 001 001 +OsmoHNBGW(config-hnbgw)# show running-config +... +hnbgw +... + plmn 001 001 +... + +OsmoHNBGW(config-hnbgw)# plmn 999 999 +OsmoHNBGW(config-hnbgw)# show running-config +... +hnbgw +... + plmn 999 999 +... + +OsmoHNBGW(config-hnbgw)# plmn 23 42 +OsmoHNBGW(config-hnbgw)# show running-config +... +hnbgw +... + plmn 023 42 +... + OsmoHNBGW(config-hnbgw)# rnc-id? rnc-id Configure the HNBGW's RNC Id, the common RNC Id used for all connected hNodeB. It is sent to each hNodeB upon HNBAP HNB-Register-Accept, and the hNodeB will subsequently send this as RANAP InitialUE Messages' GlobalRNC-ID IE. Takes effect as soon as the hNodeB re-registers. -- To view, visit https://gerrit.osmocom.org/c/osmo-hnbgw/+/33178 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-hnbgw Gerrit-Branch: master Gerrit-Change-Id: If404c3859acdfba274c719c7cb7d16f97d831a2a Gerrit-Change-Number: 33178 Gerrit-PatchSet: 8 Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: neels <nhofmeyr(a)sysmocom.de> Gerrit-Reviewer: pespin <pespin(a)sysmocom.de> Gerrit-MessageType: merged
1 0
0 0
[S] Change in osmo-hnbgw[master]: include Global RNC-ID in RESET
by neels 22 Jun '23

22 Jun '23
neels has submitted this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/33179 ) ( 5 is the latest approved patch-set. No files were changed between the latest approved patch-set and the submitted one. )Change subject: include Global RNC-ID in RESET ...................................................................... include Global RNC-ID in RESET According to 3GPP TS 25.413 8.26.2.2, "The RNC shall include the Global RNC-ID IE in the RESET message." Related: SYS#6441 Change-Id: I2cd5d7ea86a6ed0916befe219dbf21373afbd95b --- M TODO-RELEASE M src/osmo-hnbgw/cnlink.c 2 files changed, 44 insertions(+), 1 deletion(-) Approvals: laforge: Looks good to me, but someone else must approve pespin: Looks good to me, approved Jenkins Builder: Verified diff --git a/TODO-RELEASE b/TODO-RELEASE index 10cb13b..37cadc5 100644 --- a/TODO-RELEASE +++ b/TODO-RELEASE @@ -12,3 +12,4 @@ Uses osmo_scu_prim_hdr_name_c() libosmo-mgcp-client > 1.11.0 mgcp_client_pool_empty(), mgcp_client_conf_alloc() libosmo-sigtran >1.7.0 Require presence of vty 'cs7 instance'/'sccp max-optional-data' that the deprecated+fatal 'hnbgw'/'sccp cr...' tells the user to use instead. +libosmo-ranap >1.4.0 ranap_new_msg_reset2() diff --git a/src/osmo-hnbgw/cnlink.c b/src/osmo-hnbgw/cnlink.c index c98d713..1b4af7f 100644 --- a/src/osmo-hnbgw/cnlink.c +++ b/src/osmo-hnbgw/cnlink.c @@ -25,6 +25,7 @@ #include <osmocom/sigtran/sccp_helpers.h> +#include <asn1c/asn1helpers.h> #include <osmocom/ranap/ranap_ies_defs.h> #include <osmocom/ranap/ranap_msg_factory.h> @@ -127,6 +128,9 @@ .present = RANAP_Cause_PR_transmissionNetwork, .choice. transmissionNetwork = RANAP_CauseTransmissionNetwork_signalling_transport_resource_failure, }; + RANAP_GlobalRNC_ID_t grnc_id; + RANAP_GlobalRNC_ID_t *use_grnc_id = NULL; + uint8_t plmn_buf[3]; if (!cnlink) return; @@ -144,7 +148,32 @@ cnlink_is_cs(cnlink) ? "IuCS" : "IuPS", cnlink_sccp_addr_to_str(cnlink, &cnlink->remote_addr)); - msg = ranap_new_msg_reset(cnlink->pool->domain, &cause); + if (g_hnbgw->config.plmn.mcc) { + osmo_plmn_to_bcd(plmn_buf, &g_hnbgw->config.plmn); + grnc_id = (RANAP_GlobalRNC_ID_t){ + .pLMNidentity = { + .buf = plmn_buf, + .size = 3, + }, + .rNC_ID = g_hnbgw->config.rnc_id, + }; + use_grnc_id = &grnc_id; + } else { + /* If no PLMN is configured, omit the Global RNC Id from the RESET message. + * + * According to 3GPP TS 25.413 8.26.2.2, "The RNC shall include the Global RNC-ID IE in the RESET + * message", so it should be considered a mandatory IE when coming from us, the RNC. + * + * But osmo-hnbgw < v1.5 worked well with osmo-hnbgw.cfg files that have no PLMN configured, and we are + * trying to stay backwards compatible for those users. Such a site should still work, but they should + * now see these error logs and can adjust the config. + */ + LOG_CNLINK(cnlink, DRANAP, LOGL_ERROR, + "No local PLMN is configured, so outgoing RESET messages omit the mandatory Global RNC-ID" + " IE. You should set a 'hnbgw' / 'plmn' in your config file (since v1.5)\n"); + } + + msg = ranap_new_msg_reset2(cnlink->pool->domain, &cause, use_grnc_id); osmo_sccp_tx_unitdata_msg(cnlink->hnbgw_sccp_user->sccp_user, &cnlink->hnbgw_sccp_user->local_addr, -- To view, visit https://gerrit.osmocom.org/c/osmo-hnbgw/+/33179 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-hnbgw Gerrit-Branch: master Gerrit-Change-Id: I2cd5d7ea86a6ed0916befe219dbf21373afbd95b Gerrit-Change-Number: 33179 Gerrit-PatchSet: 8 Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: neels <nhofmeyr(a)sysmocom.de> Gerrit-Reviewer: pespin <pespin(a)sysmocom.de> Gerrit-MessageType: merged
1 0
0 0
[S] Change in osmo-hnbgw[master]: include Global RNC-ID in RESET-ACK
by neels 22 Jun '23

22 Jun '23
neels has submitted this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/33180 ) ( 5 is the latest approved patch-set. No files were changed between the latest approved patch-set and the submitted one. )Change subject: include Global RNC-ID in RESET-ACK ...................................................................... include Global RNC-ID in RESET-ACK According to 3GPP TS 25.413 8.26.2.1, "The RNC shall include the Global RNC-ID IE in the RESET ACKNOWLEDGE message." Related: SYS#6441 Change-Id: I49d351e90dfe4a7c4dfdd26542565f2d9bd3d605 --- M src/osmo-hnbgw/cnlink.c 1 file changed, 42 insertions(+), 1 deletion(-) Approvals: laforge: Looks good to me, but someone else must approve pespin: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo-hnbgw/cnlink.c b/src/osmo-hnbgw/cnlink.c index 1b4af7f..0ff8163 100644 --- a/src/osmo-hnbgw/cnlink.c +++ b/src/osmo-hnbgw/cnlink.c @@ -185,6 +185,9 @@ { struct msgb *msg; struct osmo_sccp_instance *sccp = cnlink_sccp(cnlink); + RANAP_GlobalRNC_ID_t grnc_id; + RANAP_GlobalRNC_ID_t *use_grnc_id = NULL; + uint8_t plmn_buf[3]; if (!sccp) { LOG_CNLINK(cnlink, DRANAP, LOGL_ERROR, "cannot send RANAP RESET ACK: no CN link\n"); @@ -196,7 +199,32 @@ cnlink_sccp_addr_to_str(cnlink, &cnlink->hnbgw_sccp_user->local_addr), cnlink_sccp_addr_to_str(cnlink, &cnlink->remote_addr)); - msg = ranap_new_msg_reset_ack(cnlink->pool->domain, NULL); + if (g_hnbgw->config.plmn.mcc) { + osmo_plmn_to_bcd(plmn_buf, &g_hnbgw->config.plmn); + grnc_id = (RANAP_GlobalRNC_ID_t){ + .pLMNidentity = { + .buf = plmn_buf, + .size = 3, + }, + .rNC_ID = g_hnbgw->config.rnc_id, + }; + use_grnc_id = &grnc_id; + } else { + /* If no PLMN is configured, omit the Global RNC Id from the RESET ACK message. + * + * According to 3GPP TS 25.413 8.26.2.1, "The RNC shall include the Global RNC-ID IE in the RESET + * ACKNOWLEDGE message", so it should be considered a mandatory IE when coming from us, the RNC. + * + * But osmo-hnbgw < v1.5 worked well with osmo-hnbgw.cfg files that have no PLMN configured, and we are + * trying to stay backwards compatible for those users. Such a site should still work, but they should + * now see these error logs and can adjust the config. + */ + LOG_CNLINK(cnlink, DRANAP, LOGL_ERROR, + "No local PLMN is configured, so outgoing RESET ACKNOWLEDGE messages omit the mandatory" + " Global RNC-ID IE. You should set a 'hnbgw' / 'plmn' in your config file (since v1.5)\n"); + } + + msg = ranap_new_msg_reset_ack(cnlink->pool->domain, use_grnc_id); osmo_sccp_tx_unitdata_msg(cnlink->hnbgw_sccp_user->sccp_user, &cnlink->hnbgw_sccp_user->local_addr, -- To view, visit https://gerrit.osmocom.org/c/osmo-hnbgw/+/33180 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-hnbgw Gerrit-Branch: master Gerrit-Change-Id: I49d351e90dfe4a7c4dfdd26542565f2d9bd3d605 Gerrit-Change-Number: 33180 Gerrit-PatchSet: 8 Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: neels <nhofmeyr(a)sysmocom.de> Gerrit-Reviewer: pespin <pespin(a)sysmocom.de> Gerrit-MessageType: merged
1 0
0 0
[S] Change in osmo-hnbgw[master]: RUA: log tweak
by neels 22 Jun '23

22 Jun '23
neels has submitted this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/33331 ) ( 2 is the latest approved patch-set. No files were changed between the latest approved patch-set and the submitted one. )Change subject: RUA: log tweak ...................................................................... RUA: log tweak I noticed that the log is awfully silent about disconnecting RUA, even with DEBUG turned on. It is an important item that should show in the logs. Change-Id: I87592cbf197d5d3d2a22b04d9f6b64422af65ded --- M src/osmo-hnbgw/context_map_rua.c 1 file changed, 14 insertions(+), 0 deletions(-) Approvals: pespin: Looks good to me, but someone else must approve neels: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo-hnbgw/context_map_rua.c b/src/osmo-hnbgw/context_map_rua.c index 09c275d..6064b1c 100644 --- a/src/osmo-hnbgw/context_map_rua.c +++ b/src/osmo-hnbgw/context_map_rua.c @@ -262,6 +262,7 @@ .present = RUA_Cause_PR_radioNetwork, .choice.radioNetwork = RUA_CauseRadioNetwork_network_release, }; + LOGPFSML(fi, LOGL_INFO, "Tx RUA Disconnect\n"); if (rua_tx_disc(map->hnb_ctx, map->is_ps, map->rua_ctx_id, &rua_cause, NULL, 0)) LOGPFSML(fi, LOGL_ERROR, "Failed to send Disconnect to RUA\n"); } -- To view, visit https://gerrit.osmocom.org/c/osmo-hnbgw/+/33331 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-hnbgw Gerrit-Branch: master Gerrit-Change-Id: I87592cbf197d5d3d2a22b04d9f6b64422af65ded Gerrit-Change-Number: 33331 Gerrit-PatchSet: 3 Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: neels <nhofmeyr(a)sysmocom.de> Gerrit-Reviewer: pespin <pespin(a)sysmocom.de> Gerrit-MessageType: merged
1 0
0 0
[S] Change in osmo-hnbgw[master]: startup config tests: show default 'msc 0', 'sgsn 0'
by neels 22 Jun '23

22 Jun '23
neels has submitted this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/33330 ) Change subject: startup config tests: show default 'msc 0', 'sgsn 0' ...................................................................... startup config tests: show default 'msc 0', 'sgsn 0' Even when the config file did not configure any, the 'show running-config' shows the default 'msc 0' and 'sgsn 0' that were created. Let's also show that in the vty scripts. Change-Id: Ia4e43fa9b5d9fda1ae374d3d31965aafe85d493d --- M tests/config/defaults.vty M tests/config/one_cs7.vty M tests/config/two_cs7.vty 3 files changed, 22 insertions(+), 0 deletions(-) Approvals: Jenkins Builder: Verified pespin: Looks good to me, but someone else must approve laforge: Looks good to me, approved diff --git a/tests/config/defaults.vty b/tests/config/defaults.vty index 4f685f8..82d2654 100644 --- a/tests/config/defaults.vty +++ b/tests/config/defaults.vty @@ -30,3 +30,6 @@ iuh mgw 0 ... +msc 0 +sgsn 0 +... diff --git a/tests/config/one_cs7.vty b/tests/config/one_cs7.vty index 0ec8818..ea19415 100644 --- a/tests/config/one_cs7.vty +++ b/tests/config/one_cs7.vty @@ -24,3 +24,6 @@ point-code 1.1.1 hnbgw ... +msc 0 +sgsn 0 +... diff --git a/tests/config/two_cs7.vty b/tests/config/two_cs7.vty index 010cdd3..f8a5f0d 100644 --- a/tests/config/two_cs7.vty +++ b/tests/config/two_cs7.vty @@ -30,3 +30,6 @@ point-code 2.2.2 hnbgw ... +msc 0 +sgsn 0 +... -- To view, visit https://gerrit.osmocom.org/c/osmo-hnbgw/+/33330 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-hnbgw Gerrit-Branch: master Gerrit-Change-Id: Ia4e43fa9b5d9fda1ae374d3d31965aafe85d493d Gerrit-Change-Number: 33330 Gerrit-PatchSet: 1 Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: neels <nhofmeyr(a)sysmocom.de> Gerrit-Reviewer: pespin <pespin(a)sysmocom.de> Gerrit-MessageType: merged
1 0
0 0
[M] Change in osmo-hnbgw[master]: add rate_ctr infra; add rate_ctrs for cnpool
by neels 22 Jun '23

22 Jun '23
neels has submitted this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/33134 ) ( 2 is the latest approved patch-set. No files were changed between the latest approved patch-set and the submitted one. )Change subject: add rate_ctr infra; add rate_ctrs for cnpool ...................................................................... add rate_ctr infra; add rate_ctrs for cnpool Introduce rate counter stats to osmo-hnbgw. Add the first rate counters -- they will be fed in upcoming commit "cnpool: select CN link from pool by NRI or round robin" I66fba27cfbe6e2b27ee3443718846ecfbbd8a974 Related: SYS#6412 Change-Id: I0132d053223a38e5756cede74106019c47ddcd94 --- M include/osmocom/hnbgw/hnbgw.h M include/osmocom/hnbgw/hnbgw_cn.h M src/osmo-hnbgw/hnbgw.c M src/osmo-hnbgw/hnbgw_cn.c M src/osmo-hnbgw/osmo_hnbgw_main.c 5 files changed, 153 insertions(+), 0 deletions(-) Approvals: pespin: Looks good to me, but someone else must approve laforge: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/hnbgw/hnbgw.h b/include/osmocom/hnbgw/hnbgw.h index 8183cbc..62e5392 100644 --- a/include/osmocom/hnbgw/hnbgw.h +++ b/include/osmocom/hnbgw/hnbgw.h @@ -5,6 +5,7 @@ #include <osmocom/core/hashtable.h> #include <osmocom/core/write_queue.h> #include <osmocom/core/timer.h> +#include <osmocom/core/rate_ctr.h> #include <osmocom/sigtran/sccp_sap.h> #include <osmocom/sigtran/osmo_ss7.h> #include <osmocom/ctrl/control_if.h> @@ -135,6 +136,12 @@ /* Emergency calls potentially select a different set of MSCs, so to not mess up the normal round-robin * behavior, emergency calls need a separate round-robin counter. */ unsigned int round_robin_next_emerg_nr; + + /* rate counter group that child hnbgw_cnlinks should use (points to msc_ctrg_desc or sgsn_ctrg_desc) */ + const struct rate_ctr_group_desc *cnlink_ctrg_desc; + + /* Running counters for this pool */ + struct rate_ctr_group *ctrs; }; /* A CN peer, like 'msc 0' or 'sgsn 23' */ @@ -164,6 +171,8 @@ bool allow_attach; bool allow_emerg; + + struct rate_ctr_group *ctrs; }; #define LOG_CNLINK(CNLINK, SUBSYS, LEVEL, FMT, ARGS...) \ diff --git a/include/osmocom/hnbgw/hnbgw_cn.h b/include/osmocom/hnbgw/hnbgw_cn.h index 79d3c27..bd54a1f 100644 --- a/include/osmocom/hnbgw/hnbgw_cn.h +++ b/include/osmocom/hnbgw/hnbgw_cn.h @@ -1,5 +1,6 @@ #pragma once +#include <osmocom/core/rate_ctr.h> #include <osmocom/hnbgw/hnbgw.h> struct hnbgw_cnlink *hnbgw_cnlink_find_by_addr(const struct hnbgw_sccp_user *hsu, @@ -13,3 +14,33 @@ char *cnlink_sccp_addr_to_str(struct hnbgw_cnlink *cnlink, const struct osmo_sccp_addr *addr); +enum hnbgw_cnpool_ctr { + /* TODO: basic counters completely missing + * ... + */ + + /* Counters related to link selection from a CN pool. */ + CNPOOL_CTR_SUBSCR_NO_CNLINK, + CNPOOL_CTR_EMERG_FORWARDED, + CNPOOL_CTR_EMERG_LOST, +}; + +extern const struct rate_ctr_group_desc iucs_ctrg_desc; +extern const struct rate_ctr_group_desc iups_ctrg_desc; + +enum hnbgw_cnlink_ctr { + /* TODO: basic counters completely missing + * ... + */ + + /* Counters related to link selection from a CN pool. */ + CNLINK_CTR_CNPOOL_SUBSCR_NEW, + CNLINK_CTR_CNPOOL_SUBSCR_REATTACH, + CNLINK_CTR_CNPOOL_SUBSCR_KNOWN, + CNLINK_CTR_CNPOOL_SUBSCR_PAGED, + CNLINK_CTR_CNPOOL_SUBSCR_ATTACH_LOST, + CNLINK_CTR_CNPOOL_EMERG_FORWARDED, +}; + +extern const struct rate_ctr_group_desc msc_ctrg_desc; +extern const struct rate_ctr_group_desc sgsn_ctrg_desc; diff --git a/src/osmo-hnbgw/hnbgw.c b/src/osmo-hnbgw/hnbgw.c index e76dfde..4166ab3 100644 --- a/src/osmo-hnbgw/hnbgw.c +++ b/src/osmo-hnbgw/hnbgw.c @@ -36,6 +36,7 @@ #include <osmocom/hnbgw/hnbgw.h> #include <osmocom/hnbgw/hnbgw_hnbap.h> #include <osmocom/hnbgw/hnbgw_rua.h> +#include <osmocom/hnbgw/hnbgw_cn.h> #include <osmocom/hnbgw/context_map.h> struct hnbgw *g_hnbgw = NULL; @@ -71,6 +72,9 @@ .nri_bitlen = OSMO_NRI_BITLEN_DEFAULT, .null_nri_ranges = osmo_nri_ranges_alloc(g_hnbgw), }, + .cnlink_ctrg_desc = &msc_ctrg_desc, + + .ctrs = rate_ctr_group_alloc(g_hnbgw, &iucs_ctrg_desc, 0), }; INIT_LLIST_HEAD(&g_hnbgw->sccp.cnpool_iucs.cnlinks); @@ -83,6 +87,9 @@ .nri_bitlen = OSMO_NRI_BITLEN_DEFAULT, .null_nri_ranges = osmo_nri_ranges_alloc(g_hnbgw), }, + .cnlink_ctrg_desc = &sgsn_ctrg_desc, + + .ctrs = rate_ctr_group_alloc(g_hnbgw, &iups_ctrg_desc, 0), }; INIT_LLIST_HEAD(&g_hnbgw->sccp.cnpool_iups.cnlinks); } diff --git a/src/osmo-hnbgw/hnbgw_cn.c b/src/osmo-hnbgw/hnbgw_cn.c index 9dc2016..486d30a 100644 --- a/src/osmo-hnbgw/hnbgw_cn.c +++ b/src/osmo-hnbgw/hnbgw_cn.c @@ -26,6 +26,7 @@ #include <osmocom/core/msgb.h> #include <osmocom/core/utils.h> #include <osmocom/core/timer.h> +#include <osmocom/core/stats.h> #include <osmocom/gsm/gsm23236.h> @@ -655,6 +656,7 @@ .nri_ranges = osmo_nri_ranges_alloc(cnlink), }, .allow_attach = true, + .ctrs = rate_ctr_group_alloc(g_hnbgw, cnpool->cnlink_ctrg_desc, nr), }; INIT_LLIST_HEAD(&cnlink->map_list); @@ -724,3 +726,81 @@ return osmo_sccp_addr_dump(addr); return osmo_sccp_inst_addr_to_str_c(OTC_SELECT, sccp, addr); } + +static const struct rate_ctr_desc cnlink_ctr_description[] = { + + /* Indicators for CN pool usage */ + [CNLINK_CTR_CNPOOL_SUBSCR_NEW] = { + "cnpool:subscr:new", + "Complete Layer 3 requests assigned to this CN link by round-robin (no NRI was assigned yet).", + }, + [CNLINK_CTR_CNPOOL_SUBSCR_REATTACH] = { + "cnpool:subscr:reattach", + "Complete Layer 3 requests assigned to this CN link by round-robin because the subscriber indicates a" + " NULL-NRI (previously assigned by another CN link).", + }, + [CNLINK_CTR_CNPOOL_SUBSCR_KNOWN] = { + "cnpool:subscr:known", + "Complete Layer 3 requests directed to this CN link because the subscriber indicates an NRI of this CN link.", + }, + [CNLINK_CTR_CNPOOL_SUBSCR_PAGED] = { + "cnpool:subscr:paged", + "Paging Response directed to this CN link because the subscriber was recently paged by this CN link.", + }, + [CNLINK_CTR_CNPOOL_SUBSCR_ATTACH_LOST] = { + "cnpool:subscr:attach_lost", + "A subscriber indicates an NRI value matching this CN link, but the CN link is not connected:" + " a re-attach to another CN link (if available) was forced, with possible service failure.", + }, + [CNLINK_CTR_CNPOOL_EMERG_FORWARDED] = { + "cnpool:emerg:forwarded", + "Emergency call requests forwarded to this CN link.", + }, +}; + +const struct rate_ctr_group_desc msc_ctrg_desc = { + "msc", + "MSC", + OSMO_STATS_CLASS_GLOBAL, + ARRAY_SIZE(cnlink_ctr_description), + cnlink_ctr_description, +}; + +const struct rate_ctr_group_desc sgsn_ctrg_desc = { + "sgsn", + "SGSN", + OSMO_STATS_CLASS_GLOBAL, + ARRAY_SIZE(cnlink_ctr_description), + cnlink_ctr_description, +}; + +static const struct rate_ctr_desc cnpool_ctr_description[] = { + [CNPOOL_CTR_SUBSCR_NO_CNLINK] = { + "cnpool:subscr:no_cnlink", + "Complete Layer 3 requests lost because no connected CN link is found available", + }, + [CNPOOL_CTR_EMERG_FORWARDED] = { + "cnpool:emerg:forwarded", + "Emergency call requests forwarded to a CN link (see also per-CN-link counters)", + }, + [CNPOOL_CTR_EMERG_LOST] = { + "cnpool:emerg:lost", + "Emergency call requests lost because no CN link was found available", + }, +}; + +const struct rate_ctr_group_desc iucs_ctrg_desc = { + "iucs", + "IuCS", + OSMO_STATS_CLASS_GLOBAL, + ARRAY_SIZE(cnpool_ctr_description), + cnpool_ctr_description, +}; + +const struct rate_ctr_group_desc iups_ctrg_desc = { + "iups", + "IuPS", + OSMO_STATS_CLASS_GLOBAL, + ARRAY_SIZE(cnpool_ctr_description), + cnpool_ctr_description, +}; diff --git a/src/osmo-hnbgw/osmo_hnbgw_main.c b/src/osmo-hnbgw/osmo_hnbgw_main.c index 30f3de9..d371914 100644 --- a/src/osmo-hnbgw/osmo_hnbgw_main.c +++ b/src/osmo-hnbgw/osmo_hnbgw_main.c @@ -25,6 +25,7 @@ #include <osmocom/core/application.h> #include <osmocom/core/logging.h> +#include <osmocom/core/stats.h> #include <osmocom/vty/vty.h> #include <osmocom/vty/command.h> @@ -32,6 +33,7 @@ #include <osmocom/vty/misc.h> #include <osmocom/vty/telnet_interface.h> #include <osmocom/vty/ports.h> +#include <osmocom/vty/stats.h> #include <osmocom/ctrl/control_vty.h> #include <osmocom/ctrl/ports.h> @@ -194,6 +196,13 @@ if (rc < 0) exit(1); + osmo_stats_init(g_hnbgw); + rc = rate_ctr_init(g_hnbgw); + if (rc) { + LOGP(DMAIN, LOGL_FATAL, "rate_ctr_init() failed with rc=%d\n", rc); + exit(1); + } + osmo_fsm_log_timeouts(true); rc = osmo_ss7_init(); @@ -211,6 +220,7 @@ ctrl_vty_init(g_hnbgw); logging_vty_add_cmds(); osmo_talloc_vty_add_cmds(); + osmo_stats_vty_add_cmds(); /* Handle options after vty_init(), for --version */ handle_options(argc, argv); -- To view, visit https://gerrit.osmocom.org/c/osmo-hnbgw/+/33134 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-hnbgw Gerrit-Branch: master Gerrit-Change-Id: I0132d053223a38e5756cede74106019c47ddcd94 Gerrit-Change-Number: 33134 Gerrit-PatchSet: 7 Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: neels <nhofmeyr(a)sysmocom.de> Gerrit-Reviewer: pespin <pespin(a)sysmocom.de> Gerrit-MessageType: merged
1 0
0 0
  • ← Newer
  • 1
  • ...
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • ...
  • 248
  • Older →

HyperKitty Powered by HyperKitty version 1.3.12.