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 -----
  • 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

April 2023

  • 1 participants
  • 2252 discussions
[S] Change in osmo-ttcn3-hacks[master]: {RAN,BSSAP_LE}_Adapter: Support M3UA without routing context
by laforge 15 Apr '23

15 Apr '23
Attention is currently required from: laforge. Hello Jenkins Builder, pespin, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/32318 to look at the new patch set (#2). Change subject: {RAN,BSSAP_LE}_Adapter: Support M3UA without routing context ...................................................................... {RAN,BSSAP_LE}_Adapter: Support M3UA without routing context The 3rd-party M3UA_Emulation supports operation both with and without a routing context. Let's make sure the layers we build on top don't loose that capability by forcing routing context usage. Change-Id: Iff849953d923770c93029a6a5c5b86daa8c38f1e --- M library/BSSAP_LE_Adapter.ttcn M library/RAN_Adapter.ttcnpp 2 files changed, 29 insertions(+), 3 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-ttcn3-hacks refs/changes/18/32318/2 -- To view, visit https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/32318 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-ttcn3-hacks Gerrit-Branch: master Gerrit-Change-Id: Iff849953d923770c93029a6a5c5b86daa8c38f1e Gerrit-Change-Number: 32318 Gerrit-PatchSet: 2 Gerrit-Owner: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: pespin <pespin(a)sysmocom.de> Gerrit-Attention: laforge <laforge(a)osmocom.org> Gerrit-MessageType: newpatchset
1 0
0 0
[S] Change in osmo-ttcn3-hacks[master]: cosmetic: gbproxy: fix missing closing parenthesis in log line
by laforge 15 Apr '23

15 Apr '23
laforge has submitted this change. ( https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/32233 ) ( 1 is the latest approved patch-set. No files were changed between the latest approved patch-set and the submitted one. )Change subject: cosmetic: gbproxy: fix missing closing parenthesis in log line ...................................................................... cosmetic: gbproxy: fix missing closing parenthesis in log line Change-Id: I4f2b5ef048ccd03d5ac2f448ef14691ece3200d2 --- M gbproxy/GBProxy_Tests.ttcn 1 file changed, 10 insertions(+), 1 deletion(-) Approvals: fixeria: Looks good to me, but someone else must approve osmith: Looks good to me, approved Jenkins Builder: Verified diff --git a/gbproxy/GBProxy_Tests.ttcn b/gbproxy/GBProxy_Tests.ttcn index d32e3bb..ac81580 100644 --- a/gbproxy/GBProxy_Tests.ttcn +++ b/gbproxy/GBProxy_Tests.ttcn @@ -1319,7 +1319,7 @@ var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_DL_UD(g_pars.tlli, payload, tr_BSSGP_IMSI(g_pars.imsi)); - log("DL-UNITDATA(payload_size=", i); + log("DL-UNITDATA(payload_size=", i, ")"); f_sgsn2pcu(pdu_tx, pdu_rx); } setverdict(pass); -- To view, visit https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/32233 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-ttcn3-hacks Gerrit-Branch: master Gerrit-Change-Id: I4f2b5ef048ccd03d5ac2f448ef14691ece3200d2 Gerrit-Change-Number: 32233 Gerrit-PatchSet: 3 Gerrit-Owner: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: fixeria <vyanitskiy(a)sysmocom.de> Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: osmith <osmith(a)sysmocom.de> Gerrit-MessageType: merged
1 0
0 0
[M] Change in osmo-hnbgw[master]: charts: add sccp.dot
by neels 15 Apr '23

15 Apr '23
neels has posted comments on this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/32322 ) Change subject: charts: add sccp.dot ...................................................................... Patch Set 1: (1 comment) Patchset: PS1: Find a rendering here: https://people.osmocom.org/neels/hnbgw_cnpool/sccp0.png and the intended changes in two future patches: https://people.osmocom.org/neels/hnbgw_cnpool/sccp1.png https://people.osmocom.org/neels/hnbgw_cnpool/sccp2.png -- To view, visit https://gerrit.osmocom.org/c/osmo-hnbgw/+/32322 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-hnbgw Gerrit-Branch: master Gerrit-Change-Id: I109948758de998326a5e9f0dcdc84d5f11dfba02 Gerrit-Change-Number: 32322 Gerrit-PatchSet: 1 Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de> Gerrit-CC: Jenkins Builder Gerrit-Comment-Date: Sat, 15 Apr 2023 02:09:32 +0000 Gerrit-HasComments: Yes Gerrit-Has-Labels: No Gerrit-MessageType: comment
1 0
0 0
[M] Change in osmo-hnbgw[master]: sccp: add pooling for CN (MSCs, SGSNs)
by neels 15 Apr '23

15 Apr '23
neels has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/32324 ) Change subject: sccp: add pooling for CN (MSCs, SGSNs) ...................................................................... sccp: add pooling for CN (MSCs, SGSNs) NOT IMPLEMENTED besides the intended changes shown in chart sccp.dot. Related: SYS#6422 Change-Id: I5479eded786ec26062d49403a8be12967f113cdb --- M doc/charts/sccp.dot 1 file changed, 42 insertions(+), 11 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-hnbgw refs/changes/24/32324/1 diff --git a/doc/charts/sccp.dot b/doc/charts/sccp.dot index 6b67a99..a34f4a5 100644 --- a/doc/charts/sccp.dot +++ b/doc/charts/sccp.dot @@ -9,13 +9,15 @@ ss0 -> ss0ab msc0a [label="2.2.2"] - ss0ab -> msc0a + sgsn0a [label="3.3.3"] + msc1a [label="5.5.5"] + ss0ab -> msc0a,sgsn0a,msc1a } sccp0 [label="hnbgw_sccp_inst for '0'\n .osmo_sccp_instance\n .osmo_ss7_user SSN: RANAP"]; ss0 -> sccp0 [dir=back] - msc0 [label="hnbgw_cnlink for IuCS\n .sccp_addr -> 2.2.2"] + msc0 [label="hnbgw_cnlink 'msc0'\n .domain = IuCS\n .sccp_addr -> 2.2.2"] sccp0 -> msc0 [dir=back] msc0a -> msc0 [dir=back] @@ -23,26 +25,41 @@ cs1 [label="UE CS conn\n hnbgw_context_map"] msc0 -> cs0,cs1 + sgsn0 [label="hnbgw_cnlink 'sgsn0'\n .domain = IuPS\n .sccp_addr -> 3.3.3"] + sccp0 -> sgsn0 [dir=back] + sgsn0a -> sgsn0 [dir=back] + + ps0 [label="UE PS conn\n hnbgw_context_map"] + sgsn0 -> ps0 + + + subgraph cluster_ss1 { label="" ss1 [label="cs7 instance 1\n local pc: 4.4.4"] ss1ab [label="address book"] ss1 -> ss1ab - sgsn0a [label="3.3.3"] - ss1ab -> sgsn0a + sgsn1a [label="6.6.6"] + ss1ab -> sgsn1a } sccp1 [label="hnbgw_sccp_inst for '1'\n .osmo_sccp_instance\n .osmo_ss7_user SSN: RANAP"]; ss1 -> sccp1 [dir=back] - sgsn0 [label="hnbgw_cnlink for IuPS\n .sccp_addr -> 3.3.3"] - sccp1 -> sgsn0 [dir=back] - sgsn0a -> sgsn0 [dir=back] + msc1 [label="hnbgw_cnlink 'msc1'\n .domain = IuCS\n .sccp_addr -> 5.5.5"] + sccp0 -> msc1 [dir=back] + msc1a -> msc1 [dir=back] - ps0 [label="UE PS conn\n hnbgw_context_map"] - ps1 [label="UE PS conn\n hnbgw_context_map"] - sgsn0 -> ps0,ps1 + cs2 [label="UE CS conn\n hnbgw_context_map"] + msc1 -> cs2 + + sgsn1 [label="hnbgw_cnlink 'sgsn1'\n .domain = IuPS\n .sccp_addr -> 6.6.6"] + sccp1 -> sgsn1 [dir=back] + sgsn1a -> sgsn1 [dir=back] + + ps2 [label="UE PS conn\n hnbgw_context_map"] + sgsn1 -> ps2 subgraph cluster_sccp_inst { label="global sccp_instances (llist)" @@ -51,8 +68,10 @@ } subgraph cluster_hnbgw { - label="global hnb_gw" + label="global cn_pool (llist)" msc0 + msc1 sgsn0 + sgsn1 } } -- To view, visit https://gerrit.osmocom.org/c/osmo-hnbgw/+/32324 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-hnbgw Gerrit-Branch: master Gerrit-Change-Id: I5479eded786ec26062d49403a8be12967f113cdb Gerrit-Change-Number: 32324 Gerrit-PatchSet: 1 Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de> Gerrit-MessageType: newchange
1 0
0 0
[M] Change in osmo-hnbgw[master]: charts: add sccp.dot
by neels 15 Apr '23

15 Apr '23
neels has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/32322 ) Change subject: charts: add sccp.dot ...................................................................... charts: add sccp.dot Show current use of SCCP and SS7 by osmo-hnbgw, which is about to change (along with this chart). Related: SYS#6422 Change-Id: I109948758de998326a5e9f0dcdc84d5f11dfba02 --- M doc/charts/Makefile.am A doc/charts/sccp.dot 2 files changed, 51 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-hnbgw refs/changes/22/32322/1 diff --git a/doc/charts/Makefile.am b/doc/charts/Makefile.am index 52b111f..3ffcfc8 100644 --- a/doc/charts/Makefile.am +++ b/doc/charts/Makefile.am @@ -4,6 +4,7 @@ dot: \ $(builddir)/hnbgw_context_map_fsm.png \ + $(builddir)/sccp.png \ $(NULL) $(builddir)/%.png: $(srcdir)/%.msc diff --git a/doc/charts/sccp.dot b/doc/charts/sccp.dot new file mode 100644 index 0000000..9c04c35 --- /dev/null +++ b/doc/charts/sccp.dot @@ -0,0 +1,37 @@ +digraph G { +rankdir=TB +labelloc=t; label="SCCP/SS7 use in OsmoHNBGW" + + subgraph cluster_ss0 { + label="" + ss0 [label="cs7 instance 0\n local pc: 1.1.1"] + ss0ab [label="address book"] + ss0 -> ss0ab + + msc0a [label="2.2.2"] + sgsn0a [label="3.3.3"] + ss0ab -> msc0a,sgsn0a + } + + iucs_addr [label=".iucs_addr -> 2.2.2"] + iups_addr [label=".iups_addr -> 3.3.3"] + msc0a -> iucs_addr [dir=back] + sgsn0a -> iups_addr [dir=back] + cnlink [label="hnbgw_cnlink (singleton)\n .osmo_sccp_instance\n .osmo_ss7_user SSN: RANAP"]; + ss0 -> cnlink [dir=back] + + cs0 [label="UE CS conn\n hnbgw_context_map"] + cs1 [label="UE CS conn\n hnbgw_context_map"] + ps0 [label="UE PS conn\n hnbgw_context_map"] + ps1 [label="UE PS conn\n hnbgw_context_map"] + cnlink -> cs0,cs1,ps0,ps1 + iucs_addr -> cs0,cs1 [style=dotted,dir=none] + iups_addr -> ps0,ps1 [style=dotted,dir=none] + + subgraph cluster_hnbgw { + label="global hnb_gw" + cnlink + iucs_addr + iups_addr + } +} -- To view, visit https://gerrit.osmocom.org/c/osmo-hnbgw/+/32322 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-hnbgw Gerrit-Branch: master Gerrit-Change-Id: I109948758de998326a5e9f0dcdc84d5f11dfba02 Gerrit-Change-Number: 32322 Gerrit-PatchSet: 1 Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de> Gerrit-MessageType: newchange
1 0
0 0
[L] Change in osmo-hnbgw[master]: sccp: allow separate cs7 for IuPS and IuCS
by neels 15 Apr '23

15 Apr '23
neels has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/32323 ) Change subject: sccp: allow separate cs7 for IuPS and IuCS ...................................................................... sccp: allow separate cs7 for IuPS and IuCS Prepare for CN pooling; allow using separate SS7 instances for IuCS and IuPS. New struct hnbgw_sccp_inst describes an SCCP instance, one per cs7. Limit struct hnbgw_cnlink to describing a CN peer, using any SCCP instance. Chart sccp.dot shows the changes made. Related: SYS#6422 Change-Id: Iea1824f1c586723d989c80a909bae16bd2866e08 --- M doc/charts/sccp.dot M include/osmocom/hnbgw/context_map.h M include/osmocom/hnbgw/hnbgw.h M include/osmocom/hnbgw/hnbgw_cn.h M src/osmo-hnbgw/context_map.c M src/osmo-hnbgw/context_map_sccp.c M src/osmo-hnbgw/hnbgw.c M src/osmo-hnbgw/hnbgw_cn.c M src/osmo-hnbgw/hnbgw_rua.c M src/osmo-hnbgw/hnbgw_vty.c 10 files changed, 525 insertions(+), 247 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-hnbgw refs/changes/23/32323/1 diff --git a/doc/charts/sccp.dot b/doc/charts/sccp.dot index 9c04c35..6b67a99 100644 --- a/doc/charts/sccp.dot +++ b/doc/charts/sccp.dot @@ -9,29 +9,50 @@ ss0 -> ss0ab msc0a [label="2.2.2"] - sgsn0a [label="3.3.3"] - ss0ab -> msc0a,sgsn0a + ss0ab -> msc0a } - iucs_addr [label=".iucs_addr -> 2.2.2"] - iups_addr [label=".iups_addr -> 3.3.3"] - msc0a -> iucs_addr [dir=back] - sgsn0a -> iups_addr [dir=back] - cnlink [label="hnbgw_cnlink (singleton)\n .osmo_sccp_instance\n .osmo_ss7_user SSN: RANAP"]; - ss0 -> cnlink [dir=back] + sccp0 [label="hnbgw_sccp_inst for '0'\n .osmo_sccp_instance\n .osmo_ss7_user SSN: RANAP"]; + ss0 -> sccp0 [dir=back] + + msc0 [label="hnbgw_cnlink for IuCS\n .sccp_addr -> 2.2.2"] + sccp0 -> msc0 [dir=back] + msc0a -> msc0 [dir=back] cs0 [label="UE CS conn\n hnbgw_context_map"] cs1 [label="UE CS conn\n hnbgw_context_map"] + msc0 -> cs0,cs1 + + subgraph cluster_ss1 { + label="" + ss1 [label="cs7 instance 1\n local pc: 4.4.4"] + ss1ab [label="address book"] + ss1 -> ss1ab + + sgsn0a [label="3.3.3"] + ss1ab -> sgsn0a + } + + sccp1 [label="hnbgw_sccp_inst for '1'\n .osmo_sccp_instance\n .osmo_ss7_user SSN: RANAP"]; + ss1 -> sccp1 [dir=back] + + sgsn0 [label="hnbgw_cnlink for IuPS\n .sccp_addr -> 3.3.3"] + sccp1 -> sgsn0 [dir=back] + sgsn0a -> sgsn0 [dir=back] + ps0 [label="UE PS conn\n hnbgw_context_map"] ps1 [label="UE PS conn\n hnbgw_context_map"] - cnlink -> cs0,cs1,ps0,ps1 - iucs_addr -> cs0,cs1 [style=dotted,dir=none] - iups_addr -> ps0,ps1 [style=dotted,dir=none] + sgsn0 -> ps0,ps1 + + subgraph cluster_sccp_inst { + label="global sccp_instances (llist)" + sccp0 + sccp1 + } subgraph cluster_hnbgw { label="global hnb_gw" - cnlink - iucs_addr - iups_addr + msc0 + sgsn0 } } diff --git a/include/osmocom/hnbgw/context_map.h b/include/osmocom/hnbgw/context_map.h index b64358a..4e2c02c 100644 --- a/include/osmocom/hnbgw/context_map.h +++ b/include/osmocom/hnbgw/context_map.h @@ -72,11 +72,14 @@ struct hnbgw_context_map { /* entry in the per-CN list of mappings */ - struct llist_head cn_list; + struct llist_head hnbgw_cnlink_entry; /* entry in the per-HNB list of mappings. If hnb_ctx == NULL, then this llist entry has been llist_del()eted and * must not be used. */ struct llist_head hnb_list; + /* entry in the per-SCCP-conn-id hashtable */ + struct hlist_node hnbgw_sccp_inst_entry; + /* Backpointer to global hnb_gw. */ struct hnb_gw *gw; @@ -89,7 +92,7 @@ struct osmo_fsm_inst *rua_fi; /* Pointer to CN, to transceive SCCP. */ - struct hnbgw_cnlink *cn_link; + struct hnbgw_cnlink *cnlink; /* SCCP User SAP connection ID used in SCCP messages to/from the cn_link. */ uint32_t scu_conn_id; /* FSM handling the SCCP state for scu_conn_id. */ @@ -134,10 +137,8 @@ enum hnbgw_context_map_state map_rua_get_state(struct hnbgw_context_map *map); enum hnbgw_context_map_state map_sccp_get_state(struct hnbgw_context_map *map); -struct hnbgw_context_map * -context_map_alloc_by_hnb(struct hnb_context *hnb, uint32_t rua_ctx_id, - bool is_ps, - struct hnbgw_cnlink *cn_if_new); +struct hnbgw_context_map *context_map_find_or_create_by_rua_ctx_id(struct hnb_context *hnb, uint32_t rua_ctx_id, + bool is_ps); void map_rua_fsm_alloc(struct hnbgw_context_map *map); void map_sccp_fsm_alloc(struct hnbgw_context_map *map); diff --git a/include/osmocom/hnbgw/hnbgw.h b/include/osmocom/hnbgw/hnbgw.h index 1bf140a..e6e53c3 100644 --- a/include/osmocom/hnbgw/hnbgw.h +++ b/include/osmocom/hnbgw/hnbgw.h @@ -2,11 +2,14 @@ #include <osmocom/core/select.h> #include <osmocom/core/linuxlist.h> +#include <osmocom/core/hashtable.h> #include <osmocom/core/write_queue.h> #include <osmocom/core/timer.h> #include <osmocom/sigtran/sccp_sap.h> #include <osmocom/sigtran/osmo_ss7.h> #include <osmocom/ctrl/control_if.h> +#include <osmocom/ranap/RANAP_CN-DomainIndicator.h> + #define DEBUG #include <osmocom/core/logging.h> @@ -26,6 +29,9 @@ #define LOGHNB(HNB_CTX, ss, lvl, fmt, args ...) \ LOGP(ss, lvl, "(%s) " fmt, hnb_context_name(HNB_CTX), ## args) +#define DOMAIN_CS RANAP_CN_DomainIndicator_cs_domain +#define DOMAIN_PS RANAP_CN_DomainIndicator_ps_domain + enum hnb_ctrl_node { CTRL_NODE_HNB = _LAST_CTRL_NODE, _LAST_CTRL_NODE_HNB @@ -37,6 +43,10 @@ #define HNBGW_IUCS_REMOTE_IP_DEFAULT "127.0.0.1" #define HNBGW_IUPS_REMOTE_IP_DEFAULT "127.0.0.1" +#define DEFAULT_PC_HNBGW ((23 << 3) + 5) +#define DEFAULT_PC_MSC ((23 << 3) + 1) +#define DEFAULT_PC_SGSN ((23 << 3) + 4) + /* 25.467 Section 7.1 */ #define IUH_DEFAULT_SCTP_PORT 29169 #define RNA_DEFAULT_SCTP_PORT 25471 @@ -60,6 +70,25 @@ struct hnb_gw; +struct hnbgw_sccp_inst { + struct llist_head entry; + + struct hnb_gw *gw; + + char *name; + + /* There is one osmo_sccp_instance per cs7_instance. + * Below osmo_sccp_instance is running on this cs7 instance: */ + uint32_t cs7_instance; + struct osmo_sccp_instance *sccp; + /* for SSN = RANAP */ + struct osmo_sccp_user *sccp_user; + + uint32_t next_conn_id; + + DECLARE_HASHTABLE(hnbgw_context_map_by_conn_id, 6); +}; + enum hnbgw_cnlink_state { /* we have just been initialized or were disconnected */ CNLINK_S_NULL, @@ -73,21 +102,63 @@ CNLINK_S_EST_ACTIVE, }; +/* A CN peer, like MSC or SGSN. */ struct hnbgw_cnlink { - struct llist_head list; - enum hnbgw_cnlink_state state; + /* backpointer to global hnb_gw */ struct hnb_gw *gw; + + /* To print in logging/VTY */ + char *name; + + /* IuCS or IuPS? */ + RANAP_CN_DomainIndicator_t domain; + + /* FUTURE: In principle, there may be different local point-codes for separate CN links on the same SCCP + * instance. So far, each hnbgw_cnlink->local_addr just contains SSN = RANAP, so that the cs7 instance fills in + * its primary point code. */ + struct osmo_sccp_addr local_addr; + + /* cs7 address book entry to indicate both the remote point-code of the peer, as well as which cs7 instance to + * use. */ + const char *remote_addr_name; + + /* Copy of the address pointed at by remote_addr_name. */ + struct osmo_sccp_addr remote_addr; + + /* The SCCP instance for the cs7 instance indicated by remote_addr_name. (Multiple hnbgw_cnlinks may use the + * same hnbgw_sccp_inst -- there is exactly one hnbgw_sccp_inst per configured cs7 instance.) */ + struct hnbgw_sccp_inst *hnbgw_sccp_inst; + + enum hnbgw_cnlink_state state; /* timer for re-transmitting the RANAP Reset */ struct osmo_timer_list T_RafC; - /* reference to the SCCP User SAP by which we communicate */ - struct osmo_sccp_instance *sccp; - struct osmo_sccp_user *sccp_user; - uint32_t next_conn_id; /* linked list of hnbgw_context_map */ struct llist_head map_list; }; +#define LOG_CNLINK(CNLINK, SUBSYS, LEVEL, FMT, ARGS...) \ + LOGP(SUBSYS, LEVEL, "(%s) " FMT, (CNLINK) ? (CNLINK)->name : "null", ##ARGS) + +static inline bool cnlink_is_cs(const struct hnbgw_cnlink *cnlink) +{ + return cnlink && cnlink->domain == DOMAIN_CS; +} + +static inline bool cnlink_is_ps(const struct hnbgw_cnlink *cnlink) +{ + return cnlink && cnlink->domain == DOMAIN_PS; +} + +static inline struct osmo_sccp_instance *cnlink_sccp(const struct hnbgw_cnlink *cnlink) +{ + if (!cnlink) + return NULL; + if (!cnlink->hnbgw_sccp_inst) + return NULL; + return cnlink->hnbgw_sccp_inst->sccp; +} + /* The lifecycle of the hnb_context object is the same as its conn */ struct hnb_context { /*! Entry in HNB-global list of HNB */ @@ -157,11 +228,10 @@ struct ctrl_handle *ctrl; /* currently active CN links for CS and PS */ struct { - struct osmo_sccp_instance *client; - struct hnbgw_cnlink *cnlink; - struct osmo_sccp_addr local_addr; - struct osmo_sccp_addr iucs_remote_addr; - struct osmo_sccp_addr iups_remote_addr; + /* List of hnbgw_sccp_inst */ + struct llist_head instances; + struct hnbgw_cnlink *cnlink_iucs; + struct hnbgw_cnlink *cnlink_iups; } sccp; /* MGW pool, also includes the single MGCP client as fallback if no * pool is configured. */ @@ -205,3 +275,5 @@ } struct msgb *hnbgw_ranap_msg_alloc(const char *name); + +struct hnbgw_cnlink *hnbgw_cnlink_select(struct hnb_gw *gw, bool is_ps); diff --git a/include/osmocom/hnbgw/hnbgw_cn.h b/include/osmocom/hnbgw/hnbgw_cn.h index 0df2716..036fdc7 100644 --- a/include/osmocom/hnbgw/hnbgw_cn.h +++ b/include/osmocom/hnbgw/hnbgw_cn.h @@ -2,6 +2,10 @@ #include <osmocom/hnbgw/hnbgw.h> -int hnbgw_cnlink_init(struct hnb_gw *gw, const char *stp_host, uint16_t stp_port, const char *local_ip); +struct hnbgw_cnlink *hnbgw_cnlink_alloc(struct hnb_gw *gw, const char *remote_addr_name, + RANAP_CN_DomainIndicator_t domain); const struct osmo_sccp_addr *hnbgw_cn_get_remote_addr(struct hnb_gw *gw, bool is_ps); + +struct hnbgw_cnlink *hnbgw_cnlink_find_by_addr(const struct hnbgw_sccp_inst *hsi, + const struct osmo_sccp_addr *remote_addr); diff --git a/src/osmo-hnbgw/context_map.c b/src/osmo-hnbgw/context_map.c index 31f635d..06272d4 100644 --- a/src/osmo-hnbgw/context_map.c +++ b/src/osmo-hnbgw/context_map.c @@ -53,11 +53,11 @@ } /* is a given SCCP USER SAP Connection ID in use for a given CN link? */ -static int cn_id_in_use(struct hnbgw_cnlink *cn, uint32_t id) +static int sccp_id_in_use(struct hnbgw_sccp_inst *hsi, uint32_t id) { struct hnbgw_context_map *map; - llist_for_each_entry(map, &cn->map_list, cn_list) { + hash_for_each_possible(hsi->hnbgw_context_map_by_conn_id, map, hnbgw_sccp_inst_entry, id) { if (map->scu_conn_id == id) return 1; } @@ -65,11 +65,14 @@ } /* try to allocate a new SCCP User SAP Connection ID */ -static int alloc_cn_conn_id(struct hnbgw_cnlink *cn, uint32_t *id_out) +static int sccp_alloc_conn_id(struct hnbgw_sccp_inst *hsi, uint32_t *id_out) { uint32_t i; uint32_t id; + if (!hsi) + return -ENOENT; + /* SUA: RFC3868 sec 3.10.4: * The source reference number is a 4 octet long integer. * This is allocated by the source SUA instance. @@ -82,28 +85,28 @@ */ for (i = 0; i < 0x00ffffff; i++) { - id = cn->next_conn_id++; - if (cn->next_conn_id == 0x00ffffff) - cn->next_conn_id = 0; - if (!cn_id_in_use(cn, id)) { + id = hsi->next_conn_id++; + if (hsi->next_conn_id == 0x00ffffff) + hsi->next_conn_id = 0; + if (!sccp_id_in_use(hsi, id)) { *id_out = id; - return 1; + return 0; } } - return -1; + return -EADDRNOTAVAIL; } /* Map from a HNB + ContextID to the SCCP-side Connection ID */ -struct hnbgw_context_map * -context_map_alloc_by_hnb(struct hnb_context *hnb, uint32_t rua_ctx_id, - bool is_ps, - struct hnbgw_cnlink *cn_if_new) +struct hnbgw_context_map *context_map_find_or_create_by_rua_ctx_id(struct hnb_context *hnb, uint32_t rua_ctx_id, + bool is_ps) { struct hnbgw_context_map *map; uint32_t new_scu_conn_id; + struct hnbgw_cnlink *cnlink; + struct hnbgw_sccp_inst *hsi; llist_for_each_entry(map, &hnb->map_list, hnb_list) { - if (map->cn_link != cn_if_new) + if (map->is_ps != is_ps) continue; /* Matching on RUA context id -- only match for RUA context that has not been disconnected yet. If an @@ -112,24 +115,39 @@ if (!map_rua_is_active(map)) continue; - if (map->rua_ctx_id == rua_ctx_id - && map->is_ps == is_ps) { - return map; - } + if (map->rua_ctx_id != rua_ctx_id) + continue; + + /* Already exists */ + return map; } - if (alloc_cn_conn_id(cn_if_new, &new_scu_conn_id) < 0) { - LOGHNB(hnb, DMAIN, LOGL_ERROR, "Unable to allocate CN connection ID\n"); + /* Does not exist yet, create a new hnbgw_context_map. */ + + /* From the RANAP/RUA input, determine which cnlink to use */ + cnlink = hnbgw_cnlink_select(hnb->gw, is_ps); + if (!cnlink) { + LOGHNB(hnb, DMAIN, LOGL_ERROR, "Failed to select CN link\n"); return NULL; } - LOGHNB(hnb, DMAIN, LOGL_INFO, "Creating new Mapping RUA CTX %p/%u <-> SCU Conn ID %p/%u\n", - hnb, rua_ctx_id, cn_if_new, new_scu_conn_id); + /* Allocate new SCCP conn id on the SCCP instance the cnlink is on. */ + hsi = cnlink->hnbgw_sccp_inst; + if (!hsi) { + LOGHNB(hnb, DMAIN, LOGL_ERROR, "Cannot allocate context map: No SCCP instance for CN link %s\n", + cnlink->name); + return NULL; + } + + if (sccp_alloc_conn_id(hsi, &new_scu_conn_id)) { + LOGHNB(hnb, DMAIN, LOGL_ERROR, "Unable to allocate SCCP conn ID on %s\n", hsi->name); + return NULL; + } /* allocate a new map entry. */ map = talloc_zero(hnb, struct hnbgw_context_map); map->gw = hnb->gw; - map->cn_link = cn_if_new; + map->cnlink = cnlink; map->hnb_ctx = hnb; map->rua_ctx_id = rua_ctx_id; map->is_ps = is_ps; @@ -140,9 +158,12 @@ map_rua_fsm_alloc(map); map_sccp_fsm_alloc(map); - /* put it into both lists */ llist_add_tail(&map->hnb_list, &hnb->map_list); - llist_add_tail(&map->cn_list, &cn_if_new->map_list); + llist_add_tail(&map->hnbgw_cnlink_entry, &cnlink->map_list); + hash_add(hsi->hnbgw_context_map_by_conn_id, &map->hnbgw_sccp_inst_entry, new_scu_conn_id); + + LOG_MAP(map, DMAIN, LOGL_INFO, "Creating new Mapping RUA CTX %u <-> SCU Conn ID %s/%u\n", + rua_ctx_id, hsi->name, new_scu_conn_id); return map; } @@ -180,7 +201,9 @@ { struct hnbgw_context_map *map; - llist_for_each_entry(map, &cn->map_list, cn_list) { + /* TODO: use hashlist cnlink->hnbgw_sccp_inst->hnbgw_context_map_by_conn_id */ + + llist_for_each_entry(map, &cn->map_list, hnbgw_cnlink_entry) { /* Matching on SCCP conn id -- only match for SCCP conn that has not been disconnected yet. If an * inactive context map for an scu_conn_id is still around, we may have two entries for the same * scu_conn_id around at the same time. That should only stay until its RUA side is done releasing. */ @@ -240,8 +263,10 @@ hnbgw_gtpmap_release(map); #endif - if (map->cn_link) - llist_del(&map->cn_list); + if (map->cnlink) { + llist_del(&map->hnbgw_cnlink_entry); + hash_del(&map->hnbgw_sccp_inst_entry); + } if (map->hnb_ctx) llist_del(&map->hnb_list); diff --git a/src/osmo-hnbgw/context_map_sccp.c b/src/osmo-hnbgw/context_map_sccp.c index 65939f3..eab0029 100644 --- a/src/osmo-hnbgw/context_map_sccp.c +++ b/src/osmo-hnbgw/context_map_sccp.c @@ -123,6 +123,11 @@ struct osmo_scu_prim *prim; int rc; + if (!map->cnlink || !map->cnlink->hnbgw_sccp_inst) { + LOGPFSML(fi, LOGL_ERROR, "Failed to send SCCP Connection Request: no CN link\n"); + return -1; + } + if (!ranap_msg) { /* prepare a msgb to send an empty N-Connect prim (but this should never happen in practice) */ ranap_msg = hnbgw_ranap_msg_alloc("SCCP-CR-empty"); @@ -131,13 +136,13 @@ prim = (struct osmo_scu_prim *)msgb_push(ranap_msg, sizeof(*prim)); osmo_prim_init(&prim->oph, SCCP_SAP_USER, OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_REQUEST, ranap_msg); prim->u.connect.called_addr = *hnbgw_cn_get_remote_addr(map->gw, map->is_ps); - prim->u.connect.calling_addr = map->gw->sccp.local_addr; + prim->u.connect.calling_addr = map->cnlink->local_addr; prim->u.connect.sccp_class = 2; prim->u.connect.conn_id = map->scu_conn_id; - rc = osmo_sccp_user_sap_down_nofree(map->cn_link->sccp_user, &prim->oph); + rc = osmo_sccp_user_sap_down_nofree(map->cnlink->hnbgw_sccp_inst->sccp_user, &prim->oph); if (rc) - LOGPFSML(fi, LOGL_ERROR, "Failed to forward SCCP Connectoin Request to CN\n"); + LOGPFSML(fi, LOGL_ERROR, "Failed to send SCCP Connection Request to CN\n"); return rc; } @@ -150,20 +155,31 @@ if (!msg_has_l2_data(ranap_msg)) return 0; + if (!map->cnlink || !map->cnlink->hnbgw_sccp_inst) { + LOGPFSML(fi, LOGL_ERROR, "Failed to send SCCP Data Form 1: no CN link\n"); + return -1; + } + prim = (struct osmo_scu_prim *)msgb_push(ranap_msg, sizeof(*prim)); osmo_prim_init(&prim->oph, SCCP_SAP_USER, OSMO_SCU_PRIM_N_DATA, PRIM_OP_REQUEST, ranap_msg); prim->u.data.conn_id = map->scu_conn_id; - rc = osmo_sccp_user_sap_down_nofree(map->cn_link->sccp_user, &prim->oph); + rc = osmo_sccp_user_sap_down_nofree(map->cnlink->hnbgw_sccp_inst->sccp_user, &prim->oph); if (rc) - LOGPFSML(fi, LOGL_ERROR, "Failed to forward SCCP Data Form 1 to CN\n"); + LOGPFSML(fi, LOGL_ERROR, "Failed to send SCCP Data Form 1 to CN\n"); return rc; } static int tx_sccp_rlsd(struct osmo_fsm_inst *fi) { struct hnbgw_context_map *map = fi->priv; - return osmo_sccp_tx_disconn(map->cn_link->sccp_user, map->scu_conn_id, NULL, 0); + + if (!map->cnlink || !map->cnlink->hnbgw_sccp_inst) { + LOGPFSML(fi, LOGL_ERROR, "Failed to send SCCP RLSD: no CN link\n"); + return -1; + } + + return osmo_sccp_tx_disconn(map->cnlink->hnbgw_sccp_inst->sccp_user, map->scu_conn_id, NULL, 0); } static int destruct_ranap_ran_rx_co_ies(ranap_message *ranap_message_p) @@ -455,7 +471,7 @@ /* send SCCP RLSD. libosmo-sigtran/sccp_scoc.c will do the SCCP connection cleanup. * (It will repeatedly send SCCP RLSD until the peer responded with SCCP RLC, or until the * sccp_connection->t_int timer expires, and the sccp_connection is freed.) */ - if (map->cn_link && map->cn_link->sccp_user) + if (map->cnlink) tx_sccp_rlsd(fi); map_sccp_fsm_state_chg(MAP_SCCP_ST_DISCONNECTED); return 0; diff --git a/src/osmo-hnbgw/hnbgw.c b/src/osmo-hnbgw/hnbgw.c index bd45dda..e4a2302 100644 --- a/src/osmo-hnbgw/hnbgw.c +++ b/src/osmo-hnbgw/hnbgw.c @@ -97,6 +97,7 @@ gw->next_ue_ctx_id = 23; INIT_LLIST_HEAD(&gw->hnb_list); INIT_LLIST_HEAD(&gw->ue_list); + INIT_LLIST_HEAD(&gw->sccp.instances); gw->mgw_pool = mgcp_client_pool_alloc(gw); gw->config.mgcp_client = talloc_zero(tall_hnb_ctx, struct mgcp_client_conf); @@ -806,11 +807,13 @@ ranap_set_log_area(DRANAP); - rc = hnbgw_cnlink_init(g_hnb_gw, "localhost", M3UA_PORT, "localhost"); - if (rc < 0) { + if (!hnbgw_cnlink_alloc(g_hnb_gw, g_hnb_gw->config.iucs_remote_addr_name, DOMAIN_CS) + || !hnbgw_cnlink_alloc(g_hnb_gw, g_hnb_gw->config.iups_remote_addr_name, DOMAIN_PS)) { LOGP(DMAIN, LOGL_ERROR, "Failed to initialize SCCP link to CN\n"); exit(1); } + OSMO_ASSERT(g_hnb_gw->sccp.cnlink_iucs); + OSMO_ASSERT(g_hnb_gw->sccp.cnlink_iups); LOGP(DHNBAP, LOGL_NOTICE, "Using RNC-Id %u\n", g_hnb_gw->config.rnc_id); @@ -871,3 +874,12 @@ ranap_msg->l2h = ranap_msg->data; return ranap_msg; } + +struct hnbgw_cnlink *hnbgw_cnlink_select(struct hnb_gw *gw, bool is_ps) +{ + /* FUTURE: soon we will pick one of many configurable CN peers from a pool. There will be more input arguments + * (MI, or TMSI, or NRI decoded from RANAP) and this function will do round robin for new subscribers. */ + if (is_ps) + return gw->sccp.cnlink_iups; + return gw->sccp.cnlink_iucs; +} diff --git a/src/osmo-hnbgw/hnbgw_cn.c b/src/osmo-hnbgw/hnbgw_cn.c index e2dccf9..e358c11 100644 --- a/src/osmo-hnbgw/hnbgw_cn.c +++ b/src/osmo-hnbgw/hnbgw_cn.c @@ -33,6 +33,7 @@ #include <osmocom/hnbgw/hnbgw.h> #include <osmocom/hnbgw/hnbgw_rua.h> +#include <osmocom/hnbgw/hnbgw_cn.h> #include <osmocom/ranap/ranap_ies_defs.h> #include <osmocom/ranap/ranap_msg_factory.h> #include <osmocom/hnbgw/context_map.h> @@ -43,8 +44,7 @@ void hnbgw_cnlink_change_state(struct hnbgw_cnlink *cnlink, enum hnbgw_cnlink_state state); -static int transmit_rst(struct hnb_gw *gw, RANAP_CN_DomainIndicator_t domain, - struct osmo_sccp_addr *remote_addr) +static int transmit_rst(struct hnbgw_cnlink *cnlink) { struct msgb *msg; RANAP_Cause_t cause = { @@ -52,43 +52,57 @@ .choice. transmissionNetwork = RANAP_CauseTransmissionNetwork_signalling_transport_resource_failure, }; - LOGP(DRANAP, LOGL_NOTICE, "Tx RESET to %s %s\n", - domain == RANAP_CN_DomainIndicator_cs_domain ? "IuCS" : "IuPS", - osmo_sccp_inst_addr_name(gw->sccp.cnlink->sccp, remote_addr)); + if (!cnlink) + return -1; - msg = ranap_new_msg_reset(domain, &cause); + if (!cnlink->hnbgw_sccp_inst) { + LOG_CNLINK(cnlink, DRANAP, LOGL_ERROR, "cannot send RANAP RESET: no CN link\n"); + return -1; + } - return osmo_sccp_tx_unitdata_msg(gw->sccp.cnlink->sccp_user, - &gw->sccp.local_addr, - remote_addr, + 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_inst->sccp, &cnlink->remote_addr)); + + msg = ranap_new_msg_reset(cnlink->domain, &cause); + + return osmo_sccp_tx_unitdata_msg(cnlink->hnbgw_sccp_inst->sccp_user, + &cnlink->local_addr, + &cnlink->remote_addr, msg); } -static int transmit_reset_ack(struct hnb_gw *gw, RANAP_CN_DomainIndicator_t domain, - const struct osmo_sccp_addr *remote_addr) +static int transmit_reset_ack(struct hnbgw_cnlink *cnlink) { struct msgb *msg; + struct osmo_sccp_instance *sccp = cnlink_sccp(cnlink); - LOGP(DRANAP, LOGL_NOTICE, "Tx RESET ACK to %s %s\n", - domain == RANAP_CN_DomainIndicator_cs_domain ? "IuCS" : "IuPS", - osmo_sccp_inst_addr_name(gw->sccp.cnlink->sccp, remote_addr)); + if (!sccp) { + LOG_CNLINK(cnlink, DRANAP, LOGL_ERROR, "cannot send RANAP RESET ACK: no CN link\n"); + return -1; + } - msg = ranap_new_msg_reset_ack(domain, NULL); + LOG_CNLINK(cnlink, DRANAP, LOGL_NOTICE, "Tx RANAP RESET ACK %s %s --> %s\n", + cnlink_is_cs(cnlink) ? "IuCS" : "IuPS", + osmo_sccp_inst_addr_to_str_c(OTC_SELECT, cnlink->hnbgw_sccp_inst->sccp, &cnlink->local_addr), + osmo_sccp_inst_addr_to_str_c(OTC_SELECT, cnlink->hnbgw_sccp_inst->sccp, &cnlink->remote_addr)); - return osmo_sccp_tx_unitdata_msg(gw->sccp.cnlink->sccp_user, - &gw->sccp.local_addr, - remote_addr, + msg = ranap_new_msg_reset_ack(cnlink->domain, NULL); + + return osmo_sccp_tx_unitdata_msg(cnlink->hnbgw_sccp_inst->sccp_user, + &cnlink->local_addr, + &cnlink->remote_addr, msg); } /* Timer callback once T_RafC expires */ static void cnlink_trafc_cb(void *data) { - struct hnb_gw *gw = data; + struct hnbgw_cnlink *cnlink = data; - transmit_rst(gw, RANAP_CN_DomainIndicator_cs_domain, &gw->sccp.iucs_remote_addr); - transmit_rst(gw, RANAP_CN_DomainIndicator_ps_domain, &gw->sccp.iups_remote_addr); - hnbgw_cnlink_change_state(gw->sccp.cnlink, CNLINK_S_EST_RST_TX_WAIT_ACK); + /* FUTURE: there will be a list of cnlinks and we will do llist_for_each_entry(gw->sccp.cnlinks) here. */ + transmit_rst(cnlink); + hnbgw_cnlink_change_state(cnlink, CNLINK_S_EST_RST_TX_WAIT_ACK); /* The spec states that we should abandon after a configurable * number of times. We decide to simply continue trying */ } @@ -101,7 +115,7 @@ case CNLINK_S_EST_PEND: break; case CNLINK_S_EST_CONF: - cnlink_trafc_cb(cnlink->gw); + cnlink_trafc_cb(cnlink); break; case CNLINK_S_EST_RST_TX_WAIT_ACK: osmo_timer_schedule(&cnlink->T_RafC, 5, 0); @@ -128,16 +142,16 @@ domain = ies.cN_DomainIndicator; ranap_free_reseties(&ies); - LOGP(DRANAP, LOGL_NOTICE, "Rx RESET from %s %s, returning ACK\n", - domain == RANAP_CN_DomainIndicator_cs_domain ? "IuCS" : "IuPS", - osmo_sccp_inst_addr_name(cnlink->sccp, &unitdata->calling_addr)); + 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)); /* FIXME: actually reset connections, if any */ - if (transmit_reset_ack(cnlink->gw, domain, &unitdata->calling_addr)) + if (transmit_reset_ack(cnlink)) LOGP(DRANAP, LOGL_ERROR, "Error: cannot send RESET ACK to %s %s\n", - domain == RANAP_CN_DomainIndicator_cs_domain ? "IuCS" : "IuPS", - osmo_sccp_inst_addr_name(cnlink->sccp, &unitdata->calling_addr)); + domain == DOMAIN_CS ? "IuCS" : "IuPS", + osmo_sccp_inst_addr_name(cnlink_sccp(cnlink), &unitdata->calling_addr)); return rc; } @@ -280,102 +294,97 @@ return rc; } -static bool pc_and_ssn_match(const struct osmo_sccp_addr *a, const struct osmo_sccp_addr *b) +static struct hnbgw_cnlink *cnlink_from_addr(struct hnbgw_sccp_inst *hsi, const struct osmo_sccp_addr *calling_addr, + const struct osmo_prim_hdr *oph) { - return (a == b) - || ((a->pc == b->pc) - && (a->ssn == b->ssn)); + struct hnbgw_cnlink *cnlink = NULL; + cnlink = hnbgw_cnlink_find_by_addr(hsi, calling_addr); + if (!cnlink) { + LOGP(DRANAP, LOGL_ERROR, "Rx from unknown SCCP peer: %s: %s\n", + osmo_sccp_inst_addr_name(hsi->sccp, calling_addr), + osmo_scu_prim_hdr_name_c(OTC_SELECT, oph)); + return NULL; + } + return cnlink; } -static int classify_cn_remote_addr(const struct hnb_gw *gw, - const struct osmo_sccp_addr *cn_remote_addr, - bool *is_ps) +static struct hnbgw_context_map *map_from_conn_id(struct hnbgw_sccp_inst *hsi, uint32_t conn_id, + const struct osmo_prim_hdr *oph) { - if (pc_and_ssn_match(cn_remote_addr, &gw->sccp.iucs_remote_addr)) { - if (is_ps) - *is_ps = false; - return 0; - } - if (pc_and_ssn_match(cn_remote_addr, &gw->sccp.iups_remote_addr)) { - if (is_ps) - *is_ps = true; - return 0; - } - LOGP(DMAIN, LOGL_ERROR, "Unexpected remote address, matches neither CS nor PS address: %s\n", - osmo_sccp_addr_dump(cn_remote_addr)); - return -1; + struct hnbgw_context_map *map; + hash_for_each_possible(hsi->hnbgw_context_map_by_conn_id, map, hnbgw_sccp_inst_entry, conn_id) + return map; + LOGP(DRANAP, LOGL_ERROR, "Rx for unknown SCCP connection ID: %u: %s\n", + conn_id, osmo_scu_prim_hdr_name_c(OTC_SELECT, oph)); + return NULL; } -static int handle_cn_unitdata(struct hnbgw_cnlink *cnlink, +static int handle_cn_unitdata(struct hnbgw_sccp_inst *hsi, const struct osmo_scu_unitdata_param *param, struct osmo_prim_hdr *oph) { + struct hnbgw_cnlink *cnlink = cnlink_from_addr(hsi, &param->calling_addr, oph); + if (!cnlink) + return -ENOENT; + if (param->called_addr.ssn != OSMO_SCCP_SSN_RANAP) { LOGP(DMAIN, LOGL_NOTICE, "N-UNITDATA.ind for unknown SSN %u\n", param->called_addr.ssn); return -1; } - if (classify_cn_remote_addr(cnlink->gw, &param->calling_addr, NULL) < 0) - return -1; - return handle_cn_ranap(cnlink, param, msgb_l2(oph->msg), msgb_l2len(oph->msg)); } -static int handle_cn_conn_conf(struct hnbgw_cnlink *cnlink, +static int handle_cn_conn_conf(struct hnbgw_sccp_inst *hsi, const struct osmo_scu_connect_param *param, struct osmo_prim_hdr *oph) { - struct osmo_ss7_instance *ss7 = osmo_sccp_get_ss7(cnlink->gw->sccp.client); struct hnbgw_context_map *map; + struct osmo_sccp_instance *sccp; + + map = map_from_conn_id(hsi, param->conn_id, oph); + if (!map || !map->cnlink) + return -ENOENT; + + sccp = cnlink_sccp(map->cnlink); LOGP(DMAIN, LOGL_DEBUG, "handle_cn_conn_conf() conn_id=%d, addrs: called=%s calling=%s responding=%s\n", param->conn_id, - osmo_sccp_addr_to_str_c(OTC_SELECT, ss7, &param->called_addr), - osmo_sccp_addr_to_str_c(OTC_SELECT, ss7, &param->calling_addr), - osmo_sccp_addr_to_str_c(OTC_SELECT, ss7, &param->responding_addr)); - - map = context_map_by_cn(cnlink, param->conn_id); - if (!map) { - /* We have no such SCCP connection. Ignore. */ - return 0; - } + osmo_sccp_inst_addr_to_str_c(OTC_SELECT, sccp, &param->called_addr), + osmo_sccp_inst_addr_to_str_c(OTC_SELECT, sccp, &param->calling_addr), + osmo_sccp_inst_addr_to_str_c(OTC_SELECT, sccp, &param->responding_addr)); map_sccp_dispatch(map, MAP_SCCP_EV_RX_CONNECTION_CONFIRM, oph->msg); return 0; } -static int handle_cn_data_ind(struct hnbgw_cnlink *cnlink, +static int handle_cn_data_ind(struct hnbgw_sccp_inst *hsi, const struct osmo_scu_data_param *param, struct osmo_prim_hdr *oph) { struct hnbgw_context_map *map; - map = context_map_by_cn(cnlink, param->conn_id); - if (!map) { - /* We have no such SCCP connection. Ignore. */ - return 0; - } + map = map_from_conn_id(hsi, param->conn_id, oph); + if (!map || !map->cnlink) + return -ENOENT; return map_sccp_dispatch(map, MAP_SCCP_EV_RX_DATA_INDICATION, oph->msg); } -static int handle_cn_disc_ind(struct hnbgw_cnlink *cnlink, +static int handle_cn_disc_ind(struct hnbgw_sccp_inst *hsi, const struct osmo_scu_disconn_param *param, struct osmo_prim_hdr *oph) { struct hnbgw_context_map *map; - LOGP(DMAIN, LOGL_DEBUG, "handle_cn_disc_ind() conn_id=%d originator=%d\n", - param->conn_id, param->originator); - LOGP(DMAIN, LOGL_DEBUG, "handle_cn_disc_ind() responding_addr=%s\n", - inet_ntoa(param->responding_addr.ip.v4)); + map = map_from_conn_id(hsi, param->conn_id, oph); + if (!map || !map->cnlink) + return -ENOENT; - map = context_map_by_cn(cnlink, param->conn_id); - if (!map) { - /* We have no connection. Ignore. */ - return 0; - } + LOGP(DMAIN, LOGL_DEBUG, "handle_cn_disc_ind() conn_id=%u responding_addr=%s\n", + param->conn_id, + osmo_sccp_inst_addr_to_str_c(OTC_SELECT, cnlink_sccp(map->cnlink), &param->responding_addr)); return map_sccp_dispatch(map, MAP_SCCP_EV_RX_RELEASED, oph->msg); } @@ -384,7 +393,7 @@ static int sccp_sap_up(struct osmo_prim_hdr *oph, void *ctx) { struct osmo_sccp_user *scu = ctx; - struct hnbgw_cnlink *cnlink; + struct hnbgw_sccp_inst *hsi; struct osmo_scu_prim *prim = (struct osmo_scu_prim *) oph; int rc = 0; @@ -397,10 +406,10 @@ return -1; } - cnlink = osmo_sccp_user_get_priv(scu); - if (!cnlink) { + hsi = osmo_sccp_user_get_priv(scu); + if (!hsi) { LOGP(DMAIN, LOGL_ERROR, - "sccp_sap_up(): NULL hnbgw_cnlink, cannot send prim (sap %u prim %u op %d)\n", + "sccp_sap_up(): NULL hnbgw_sccp_inst, cannot send prim (sap %u prim %u op %d)\n", oph->sap, oph->primitive, oph->operation); return -1; } @@ -409,16 +418,16 @@ switch (OSMO_PRIM_HDR(oph)) { case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_INDICATION): - rc = handle_cn_unitdata(cnlink, &prim->u.unitdata, oph); + rc = handle_cn_unitdata(hsi, &prim->u.unitdata, oph); break; case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_CONFIRM): - rc = handle_cn_conn_conf(cnlink, &prim->u.connect, oph); + rc = handle_cn_conn_conf(hsi, &prim->u.connect, oph); break; case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_INDICATION): - rc = handle_cn_data_ind(cnlink, &prim->u.data, oph); + rc = handle_cn_data_ind(hsi, &prim->u.data, oph); break; case OSMO_PRIM(OSMO_SCU_PRIM_N_DISCONNECT, PRIM_OP_INDICATION): - rc = handle_cn_disc_ind(cnlink, &prim->u.disconnect, oph); + rc = handle_cn_disc_ind(hsi, &prim->u.disconnect, oph); break; case OSMO_PRIM(OSMO_SCU_PRIM_N_PCSTATE, PRIM_OP_INDICATION): LOGP(DMAIN, LOGL_DEBUG, "Ignoring prim %s from SCCP USER SAP\n", @@ -447,8 +456,6 @@ const char *addr_name, const char *label, uint32_t default_pc) { - struct osmo_ss7_instance *ss7_tmp; - if (!addr_name) { osmo_sccp_make_addr_pc_ssn(dest, default_pc, OSMO_SCCP_SSN_RANAP); LOGP(DMAIN, LOGL_INFO, "%s remote addr not configured, using default: %s\n", label, @@ -456,21 +463,13 @@ return 0; } - ss7_tmp = osmo_sccp_addr_by_name(dest, addr_name); - if (!ss7_tmp) { + *ss7 = osmo_sccp_addr_by_name(dest, addr_name); + if (!*ss7) { LOGP(DMAIN, LOGL_ERROR, "%s remote addr: no such SCCP address book entry: '%s'\n", - label, addr_name); + label, addr_name); return -1; } - if (*ss7 && (*ss7 != ss7_tmp)) { - LOGP(DMAIN, LOGL_ERROR, "IuCS and IuPS cannot be served from separate CS7 instances," - " cs7 instance %d != %d\n", (*ss7)->cfg.id, ss7_tmp->cfg.id); - return -1; - } - - *ss7 = ss7_tmp; - osmo_sccp_addr_set_ssn(dest, OSMO_SCCP_SSN_RANAP); if (!addr_has_pc_and_ssn(dest)) { @@ -484,78 +483,173 @@ return 0; } -int hnbgw_cnlink_init(struct hnb_gw *gw, const char *stp_host, uint16_t stp_port, const char *local_ip) +void cnlink_set_sccp_inst(struct hnbgw_cnlink *cnlink, struct hnbgw_sccp_inst *hsi) { - struct hnbgw_cnlink *cnlink; - struct osmo_ss7_instance *ss7; uint32_t local_pc; - OSMO_ASSERT(!gw->sccp.client); - OSMO_ASSERT(!gw->sccp.cnlink); + cnlink->hnbgw_sccp_inst = hsi; - ss7 = NULL; - if (resolve_addr_name(&gw->sccp.iucs_remote_addr, &ss7, - gw->config.iucs_remote_addr_name, "IuCS", (23 << 3) + 1)) - return -1; - if (resolve_addr_name(&gw->sccp.iups_remote_addr, &ss7, - gw->config.iups_remote_addr_name, "IuPS", (23 << 3) + 4)) - return -1; - - if (!ss7) { - LOGP(DRANAP, LOGL_NOTICE, "No cs7 instance configured for IuCS nor IuPS," - " creating default instance\n"); - ss7 = osmo_ss7_instance_find_or_create(gw, 0); - if (!ss7) - return -1; - ss7->cfg.primary_pc = (23 << 3) + 5; + if ((cnlink->local_addr.presence & OSMO_SCCP_ADDR_T_PC) + && osmo_ss7_pc_is_valid(cnlink->local_addr.pc)) { + local_pc = cnlink->local_addr.pc; + } else { + struct osmo_ss7_instance *ss7 = osmo_sccp_get_ss7(hsi->sccp); + OSMO_ASSERT(ss7); + local_pc = ss7->cfg.primary_pc; } - if (!osmo_ss7_pc_is_valid(ss7->cfg.primary_pc)) { - LOGP(DMAIN, LOGL_ERROR, "IuCS/IuPS uplink cannot be setup: CS7 instance %d has no point-code set\n", - ss7->cfg.id); - return -1; - } - local_pc = ss7->cfg.primary_pc; + osmo_sccp_make_addr_pc_ssn(&cnlink->local_addr, local_pc, OSMO_SCCP_SSN_RANAP); +} - osmo_sccp_make_addr_pc_ssn(&gw->sccp.local_addr, local_pc, OSMO_SCCP_SSN_RANAP); - LOGP(DRANAP, LOGL_NOTICE, "Local SCCP addr: %s\n", osmo_sccp_addr_name(ss7, &gw->sccp.local_addr)); +/* If not present yet, set up all of osmo_ss7_instance, osmo_sccp_instance and hnbgw_sccp_inst for the given cnlink. + * The cs7 instance nr to use is determined by cnlink->remote_addr_name, or cs7 instance 0 if that is not present. + * Set cnlink->hnbgw_sccp_inst to the new SCCP instance. Return 0 on success, negative on error. */ +int cnlink_ensure_sccp(struct hnbgw_cnlink *cnlink) +{ + struct hnb_gw *gw = cnlink->gw; + struct osmo_ss7_instance *ss7 = NULL; + struct osmo_sccp_instance *sccp; + struct osmo_sccp_user *sccp_user; + uint32_t local_pc; + struct hnbgw_sccp_inst *hsi; - gw->sccp.client = osmo_sccp_simple_client_on_ss7_id(gw, ss7->cfg.id, "OsmoHNBGW", - local_pc, OSMO_SS7_ASP_PROT_M3UA, - 0, local_ip, stp_port, stp_host); - if (!gw->sccp.client) { - LOGP(DMAIN, LOGL_ERROR, "Failed to init SCCP Client\n"); - return -1; + /* If a hnbgw_sccp_inst has already been set up, use that. */ + if (cnlink->hnbgw_sccp_inst) + return 0; + + /* Figure out which cs7 instance to use. If cnlink->remote_addr_name is set, it points to an address book entry + * in a specific cs7 instance. If it is not set, leave ss7 == NULL to use cs7 instance 0. */ + if (cnlink->remote_addr_name) { + if (resolve_addr_name(&cnlink->remote_addr, &ss7, cnlink->remote_addr_name, cnlink->name, + DEFAULT_PC_HNBGW)) { + LOG_CNLINK(cnlink, DCN, LOGL_ERROR, "cannot initialize SCCP: there is no SCCP address named '%s'\n", + cnlink->remote_addr_name); + return -ENOENT; + } + + LOG_CNLINK(cnlink, DCN, LOGL_NOTICE, "using cs7 instance %u\n", ss7->cfg.id); + + /* Has another cnlink already set up an SCCP instance for this ss7? */ + llist_for_each_entry(hsi, &gw->sccp.instances, entry) { + if (hsi->cs7_instance != ss7->cfg.id) + continue; + cnlink_set_sccp_inst(cnlink, hsi); + return 0; + } + /* else cnlink->hnbgw_sccp_inst stays NULL and is set up below. */ + + /* All SCCP instances should originate from this function. So if there is no hnbgw_sccp_inst for the cs7 + * instance, then the cs7 instance should not have an SCCP instance yet. */ + OSMO_ASSERT(!ss7->sccp); } - cnlink = talloc_zero(gw, struct hnbgw_cnlink); - cnlink->gw = gw; - INIT_LLIST_HEAD(&cnlink->map_list); - cnlink->T_RafC.cb = cnlink_trafc_cb; - cnlink->T_RafC.data = gw; - cnlink->next_conn_id = 1000; + /* No SCCP instance yet for this ss7. Create it. */ + sccp = osmo_sccp_simple_client_on_ss7_id(gw, ss7 ? ss7->cfg.id : 0, cnlink->name, DEFAULT_PC_HNBGW, + OSMO_SS7_ASP_PROT_M3UA, 0, "localhost", -1, "localhost"); + if (!sccp) { + LOG_CNLINK(cnlink, DCN, LOGL_ERROR, "Failed to configure 'cs7 instance %u'\n", ss7->cfg.id); + return -1; + } + ss7 = osmo_sccp_get_ss7(sccp); - cnlink->sccp_user = osmo_sccp_user_bind_pc(gw->sccp.client, "OsmoHNBGW", sccp_sap_up, - OSMO_SCCP_SSN_RANAP, gw->sccp.local_addr.pc); - if (!cnlink->sccp_user) { + /* If the cnlink provides a local point-code, use that. */ + if ((cnlink->local_addr.presence & OSMO_SCCP_ADDR_T_PC) + && osmo_ss7_pc_is_valid(cnlink->local_addr.pc)) + local_pc = cnlink->local_addr.pc; + else if (osmo_ss7_pc_is_valid(ss7->cfg.primary_pc)) + local_pc = ss7->cfg.primary_pc; + else + local_pc = DEFAULT_PC_HNBGW; + + sccp_user = osmo_sccp_user_bind_pc(sccp, "OsmoHNBGW", sccp_sap_up, OSMO_SCCP_SSN_RANAP, local_pc); + if (!sccp_user) { LOGP(DMAIN, LOGL_ERROR, "Failed to init SCCP User\n"); return -1; } - LOGP(DRANAP, LOGL_NOTICE, "Remote SCCP addr: IuCS: %s\n", - osmo_sccp_addr_name(ss7, &gw->sccp.iucs_remote_addr)); - LOGP(DRANAP, LOGL_NOTICE, "Remote SCCP addr: IuPS: %s\n", - osmo_sccp_addr_name(ss7, &gw->sccp.iups_remote_addr)); + hsi = talloc(cnlink, struct hnbgw_sccp_inst); + *hsi = (struct hnbgw_sccp_inst){ + .gw = gw, + .name = talloc_asprintf(hsi, "cs7-%u.sccp", ss7->cfg.id), + .cs7_instance = ss7->cfg.id, + .sccp = sccp, + .sccp_user = sccp_user, + .next_conn_id = 1, + }; + hash_init(hsi->hnbgw_context_map_by_conn_id); - /* In sccp_sap_up() we expect the cnlink in the user's priv. */ - osmo_sccp_user_set_priv(cnlink->sccp_user, cnlink); + osmo_sccp_user_set_priv(sccp_user, hsi); - gw->sccp.cnlink = cnlink; + llist_add_tail(&hsi->entry, &gw->sccp.instances); + cnlink_set_sccp_inst(cnlink, hsi); return 0; } +struct hnbgw_cnlink *hnbgw_cnlink_alloc(struct hnb_gw *gw, const char *remote_addr_name, + RANAP_CN_DomainIndicator_t domain) +{ + struct hnbgw_cnlink *cnlink; + + cnlink = talloc(gw, struct hnbgw_cnlink); + *cnlink = (struct hnbgw_cnlink){ + .gw = gw, + .name = talloc_strdup(cnlink, remote_addr_name), + .domain = domain, + .remote_addr_name = talloc_strdup(cnlink, remote_addr_name), + .T_RafC = { + .cb = cnlink_trafc_cb, + .data = cnlink, + }, + }; + + INIT_LLIST_HEAD(&cnlink->map_list); + + if (cnlink_ensure_sccp(cnlink)) { + /* error logging already in cnlink_ensure_sccp() */ + talloc_free(cnlink); + return NULL; + } + + switch (domain) { + case DOMAIN_CS: + OSMO_ASSERT(!gw->sccp.cnlink_iucs); + gw->sccp.cnlink_iucs = cnlink; + break; + case DOMAIN_PS: + OSMO_ASSERT(!gw->sccp.cnlink_iups); + gw->sccp.cnlink_iups = cnlink; + break; + default: + OSMO_ASSERT(false); + } + + return cnlink; +} + const struct osmo_sccp_addr *hnbgw_cn_get_remote_addr(struct hnb_gw *gw, bool is_ps) { - return is_ps ? &gw->sccp.iups_remote_addr : &gw->sccp.iucs_remote_addr; + struct hnbgw_cnlink *cnlink = is_ps ? gw->sccp.cnlink_iups : gw->sccp.cnlink_iucs; + if (!cnlink) + return NULL; + return &cnlink->remote_addr; +} + +static bool cnlink_matches(const struct hnbgw_cnlink *cnlink, const struct hnbgw_sccp_inst *hsi, const struct osmo_sccp_addr *remote_addr) +{ + if (cnlink->hnbgw_sccp_inst != hsi) + return false; + if (osmo_sccp_addr_cmp(&cnlink->remote_addr, remote_addr, OSMO_SCCP_ADDR_T_SSN | OSMO_SCCP_ADDR_T_PC)) + return false; + return true; +} +struct hnbgw_cnlink *hnbgw_cnlink_find_by_addr(const struct hnbgw_sccp_inst *hsi, + const struct osmo_sccp_addr *remote_addr) +{ + /* FUTURE: loop over llist g_hnb_gw->sccp.cnlinks */ + if (cnlink_matches(hsi->gw->sccp.cnlink_iucs, hsi, remote_addr)) + return hsi->gw->sccp.cnlink_iucs; + if (cnlink_matches(hsi->gw->sccp.cnlink_iups, hsi, remote_addr)) + return hsi->gw->sccp.cnlink_iups; + return NULL; } diff --git a/src/osmo-hnbgw/hnbgw_rua.c b/src/osmo-hnbgw/hnbgw_rua.c index 83410b9..f0dc124 100644 --- a/src/osmo-hnbgw/hnbgw_rua.c +++ b/src/osmo-hnbgw/hnbgw_rua.c @@ -200,7 +200,6 @@ { struct msgb *ranap_msg = NULL; struct hnbgw_context_map *map = NULL; - struct hnbgw_cnlink *cn = hnb->gw->sccp.cnlink; bool is_ps; switch (cN_DomainIndicator) { @@ -215,11 +214,6 @@ return -1; } - if (!cn) { - LOGHNB(hnb, DRUA, LOGL_NOTICE, "CN=NULL, discarding message\n"); - return 0; - } - /* If there is RANAP data, include it in the msgb. In RUA there is always data in practice, but theoretically it * could be an empty Connect or Disconnect. */ if (data && len) { @@ -230,8 +224,13 @@ memcpy(ranap_msg->l2h, data, len); } - map = context_map_alloc_by_hnb(hnb, context_id, is_ps, cn); - OSMO_ASSERT(map); + map = context_map_find_or_create_by_rua_ctx_id(hnb, context_id, is_ps); + if (!map) { + LOGHNB(hnb, DRUA, LOGL_ERROR, + "Failed to create context map for %s: rx RUA %s with %u bytes RANAP data\n", + is_ps ? "IuPS" : "IuCS", rua_procedure_code_name(rua_procedure), data ? len : 0); + return -1; + } LOG_MAP(map, DRUA, LOGL_DEBUG, "rx RUA %s with %u bytes RANAP data\n", rua_procedure_code_name(rua_procedure), data ? len : 0); diff --git a/src/osmo-hnbgw/hnbgw_vty.c b/src/osmo-hnbgw/hnbgw_vty.c index 8d2366f..1be9ce0 100644 --- a/src/osmo-hnbgw/hnbgw_vty.c +++ b/src/osmo-hnbgw/hnbgw_vty.c @@ -134,36 +134,51 @@ return vty->node; } -DEFUN(show_cnlink, show_cnlink_cmd, "show cnlink", - SHOW_STR "Display information on core network link\n") +static void _show_cnlink(struct vty *vty, struct hnbgw_cnlink *cnlink) { struct osmo_ss7_route *rt; - struct osmo_ss7_instance *ss7 = osmo_sccp_get_ss7(g_hnb_gw->sccp.client); + struct osmo_ss7_instance *ss7; + + if (!cnlink) { + vty_out(vty, "NULL%s", VTY_NEWLINE); + return; + } + + if (!cnlink->hnbgw_sccp_inst) { + vty_out(vty, "no SCCP instance%s", VTY_NEWLINE); + return; + } + + if (!cnlink->hnbgw_sccp_inst->sccp_user) { + vty_out(vty, "no SCCP user%s", VTY_NEWLINE); + return; + } + + ss7 = osmo_sccp_get_ss7(cnlink->hnbgw_sccp_inst->sccp); #define GUARD(STR) \ STR ? STR : "", \ STR ? ":" : "" - vty_out(vty, "IuCS: %s <->", - osmo_sccp_user_name(g_hnb_gw->sccp.cnlink->sccp_user)); + vty_out(vty, "%s <->", + osmo_sccp_user_name(cnlink->hnbgw_sccp_inst->sccp_user)); vty_out(vty, " %s%s%s%s", - GUARD(g_hnb_gw->config.iucs_remote_addr_name), - osmo_sccp_inst_addr_name(g_hnb_gw->sccp.client, &g_hnb_gw->sccp.iucs_remote_addr), + GUARD(cnlink->remote_addr_name), + osmo_sccp_inst_addr_name(cnlink->hnbgw_sccp_inst->sccp, &cnlink->remote_addr), VTY_NEWLINE); - rt = osmo_ss7_route_lookup(ss7, g_hnb_gw->sccp.iucs_remote_addr.pc); - vty_out(vty, " SS7 route: %s%s", osmo_ss7_route_name(rt, true), VTY_NEWLINE); - - vty_out(vty, "IuPS: %s <->", - osmo_sccp_user_name(g_hnb_gw->sccp.cnlink->sccp_user)); - vty_out(vty, " %s%s%s%s", - GUARD(g_hnb_gw->config.iups_remote_addr_name), - osmo_sccp_inst_addr_name(g_hnb_gw->sccp.client, &g_hnb_gw->sccp.iups_remote_addr), - VTY_NEWLINE); - - rt = osmo_ss7_route_lookup(ss7, g_hnb_gw->sccp.iups_remote_addr.pc); + rt = osmo_ss7_route_lookup(ss7, cnlink->remote_addr.pc); vty_out(vty, " SS7 route: %s%s", osmo_ss7_route_name(rt, true), VTY_NEWLINE); #undef GUARD +} + +DEFUN(show_cnlink, show_cnlink_cmd, "show cnlink", + SHOW_STR "Display information on core network link\n") +{ + vty_out(vty, "IuCS: "); + _show_cnlink(vty, g_hnb_gw->sccp.cnlink_iucs); + vty_out(vty, "IuPS: "); + _show_cnlink(vty, g_hnb_gw->sccp.cnlink_iups); return CMD_SUCCESS; } -- To view, visit https://gerrit.osmocom.org/c/osmo-hnbgw/+/32323 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-hnbgw Gerrit-Branch: master Gerrit-Change-Id: Iea1824f1c586723d989c80a909bae16bd2866e08 Gerrit-Change-Number: 32323 Gerrit-PatchSet: 1 Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de> Gerrit-MessageType: newchange
1 0
0 0
[M] Change in libosmo-sccp[master]: sccp_scoc.c: fix infinite loop on conn ID exhaustion
by neels 14 Apr '23

14 Apr '23
neels has posted comments on this change. ( https://gerrit.osmocom.org/c/libosmo-sccp/+/32320 ) Change subject: sccp_scoc.c: fix infinite loop on conn ID exhaustion ...................................................................... Patch Set 1: (1 comment) File src/sccp_scoc.c: https://gerrit.osmocom.org/c/libosmo-sccp/+/32320/comment/fa9c4504_b97b3fda PS1, Line 589: 0 re above comment: 0 here means always iterate the entire connection ID number space. For outbound SCCP connections, the caller can adjust the number of sane iterations, for inbound SCCP connections there is no way to do so yet. -- To view, visit https://gerrit.osmocom.org/c/libosmo-sccp/+/32320 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Change-Id: Ib64e0cb1ae0cc8b7bebcb2a352d4068b496b304a Gerrit-Change-Number: 32320 Gerrit-PatchSet: 1 Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Comment-Date: Fri, 14 Apr 2023 23:43:25 +0000 Gerrit-HasComments: Yes Gerrit-Has-Labels: No Gerrit-MessageType: comment
1 0
0 0
[M] Change in libosmo-sccp[master]: sccp_scoc.c: fix infinite loop on conn ID exhaustion
by neels 14 Apr '23

14 Apr '23
neels has posted comments on this change. ( https://gerrit.osmocom.org/c/libosmo-sccp/+/32320 ) Change subject: sccp_scoc.c: fix infinite loop on conn ID exhaustion ...................................................................... Patch Set 1: (1 comment) Commit Message: https://gerrit.osmocom.org/c/libosmo-sccp/+/32320/comment/2a4e333f_3cb54e64 PS1, Line 17: entire SCCP conn id number space before exiting in failure. ...which raises the question: should the max_iterations for inbound SCCP be configurable by the caller? The answer 'yes' would mean another patch following this one. -- To view, visit https://gerrit.osmocom.org/c/libosmo-sccp/+/32320 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Change-Id: Ib64e0cb1ae0cc8b7bebcb2a352d4068b496b304a Gerrit-Change-Number: 32320 Gerrit-PatchSet: 1 Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de> Gerrit-CC: Jenkins Builder Gerrit-Comment-Date: Fri, 14 Apr 2023 23:41:27 +0000 Gerrit-HasComments: Yes Gerrit-Has-Labels: No Gerrit-MessageType: comment
1 0
0 0
[S] Change in libosmo-sccp[master]: add public API: osmo_sccp_instance_next_conn_id()
by neels 14 Apr '23

14 Apr '23
neels has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmo-sccp/+/32321 ) Change subject: add public API: osmo_sccp_instance_next_conn_id() ...................................................................... add public API: osmo_sccp_instance_next_conn_id() In struct osmo_sccp_instance, we have a next_id, to find an unused SCCP connection ID. This is used for inbound SCCP connections. At the same time, in each of our SCCP client programs, we have a separate mechanism to find a connection ID for outbound connections. See for example bsc_sccp.c: bsc_sccp_inst_next_conn_id() It makes much more sense for callers to use the same osmo_sccp_instance->next_id counter: - Currently the inbound and outbound counters go out of sync: For example, in osmo-bsc, if we have three MS doing a usual Complete Layer 3, osmo-bsc's counter increments by three. If we then have one Handover Required coming back from the MSC, i.e. inbound SCCP connection, the sccp_inst->next_id is behind by three, and will iterate SCCP connections three times before finding an unused id. - Each implementation has to take care to properly wrap the ID in its valid range, e.g. in osmo-bsc: test_id = (test_id + 1) & 0x00FFFFFF; if (OSMO_UNLIKELY(test_id == 0x00FFFFFF)) test_id = 0; Add public API so that callers can benefit from the internal osmo_sccp_instance->next_id and do not need to duplicate the code for staying within the proper range. Change-Id: If59d524fbe1088a59ae1b69908e2d4bf67113439 --- M include/osmocom/sigtran/sccp_sap.h M src/sccp_scoc.c 2 files changed, 41 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/21/32321/1 diff --git a/include/osmocom/sigtran/sccp_sap.h b/include/osmocom/sigtran/sccp_sap.h index 24d8832..403928f 100644 --- a/include/osmocom/sigtran/sccp_sap.h +++ b/include/osmocom/sigtran/sccp_sap.h @@ -339,3 +339,5 @@ int osmo_sccp_gt_cmp(const struct osmo_sccp_gt *a, const struct osmo_sccp_gt *b); const char *osmo_sccp_user_name(struct osmo_sccp_user *scu); + +int osmo_sccp_instance_next_conn_id(struct osmo_sccp_instance *sccp, uint32_t max_attempts); diff --git a/src/sccp_scoc.c b/src/sccp_scoc.c index 6d2499c..f42a88d 100644 --- a/src/sccp_scoc.c +++ b/src/sccp_scoc.c @@ -546,7 +546,7 @@ * \param[in] max_attempts Number of iterations to find an unused ID, or zero to iterate the entire ID number space. * \return unused ID on success (>=0) or negative on elapsed max_attempts without an unused id (<0). */ -static int osmo_sccp_instance_next_conn_id(struct osmo_sccp_instance *sccp, uint32_t max_attempts) +int osmo_sccp_instance_next_conn_id(struct osmo_sccp_instance *sccp, uint32_t max_attempts) { if (!max_attempts || max_attempts > 0x00FFFFFE) { /* Maximally iterate the entire conn id number space once. */ -- To view, visit https://gerrit.osmocom.org/c/libosmo-sccp/+/32321 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Change-Id: If59d524fbe1088a59ae1b69908e2d4bf67113439 Gerrit-Change-Number: 32321 Gerrit-PatchSet: 1 Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de> Gerrit-MessageType: newchange
1 0
0 0
[M] Change in libosmo-sccp[master]: sccp_scoc.c: fix infinite loop on conn ID exhaustion
by neels 14 Apr '23

14 Apr '23
neels has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmo-sccp/+/32320 ) Change subject: sccp_scoc.c: fix infinite loop on conn ID exhaustion ...................................................................... sccp_scoc.c: fix infinite loop on conn ID exhaustion Looking for an unused SCCP connection ID has no exit condition if all connection IDs are in use. However unlikely it is that there are 16777215 active connections on one SCCP instance, add an exit condition. Do so by implementing the ID lookup in a new separate function, which qualifies for public API (upcoming patch). So far, use an exit condition closest to previous behavior: iterate the entire SCCP conn id number space before exiting in failure. Change-Id: Ib64e0cb1ae0cc8b7bebcb2a352d4068b496b304a --- M src/sccp_scoc.c 1 file changed, 52 insertions(+), 6 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/20/32320/1 diff --git a/src/sccp_scoc.c b/src/sccp_scoc.c index c929ed6..6d2499c 100644 --- a/src/sccp_scoc.c +++ b/src/sccp_scoc.c @@ -539,10 +539,19 @@ return conn; } -/* Search for next free connection ID and allocate conn */ -static struct sccp_connection *conn_create(struct osmo_sccp_user *user) +/* Return an unused SCCP connection ID. + * Callers *must* check the returned value, even if max_attempts == 0: on negative return value, there are no unused IDs + * available. + * \param[in] sccp The SCCP instance to determine a new connection ID for. + * \param[in] max_attempts Number of iterations to find an unused ID, or zero to iterate the entire ID number space. + * \return unused ID on success (>=0) or negative on elapsed max_attempts without an unused id (<0). + */ +static int osmo_sccp_instance_next_conn_id(struct osmo_sccp_instance *sccp, uint32_t max_attempts) { - struct osmo_sccp_instance *sccp = user->inst; + if (!max_attempts || max_attempts > 0x00FFFFFE) { + /* Maximally iterate the entire conn id number space once. */ + max_attempts = 0x00FFFFFE; + } /* SUA: RFC3868 sec 3.10.4: * The source reference number is a 4 octet long integer. @@ -555,14 +564,32 @@ * Hence, as we currently use the connection ID also as local reference, * let's simply use 24 bit ids to fit all link types (excluding 0x00ffffff). */ - do { + while (1) { /* Optimized modulo operation (% 0x00FFFFFE) using bitwise AND plus CMP: */ sccp->next_id = (sccp->next_id + 1) & 0x00FFFFFF; if (OSMO_UNLIKELY(sccp->next_id == 0x00FFFFFF)) sccp->next_id = 0; - } while (conn_find_by_id(sccp, sccp->next_id)); - return conn_create_id(user, sccp->next_id); + if (!conn_find_by_id(sccp, sccp->next_id)) + return sccp->next_id; + + if (max_attempts) { + max_attempts--; + if (!max_attempts) + break; + } + } + + return -1; +} + +/* Search for next free connection ID and allocate conn */ +static struct sccp_connection *conn_create(struct osmo_sccp_user *user) +{ + int conn_id = osmo_sccp_instance_next_conn_id(user->inst, 0); + if (conn_id < 0) + return NULL; + return conn_create_id(user, conn_id); } static void conn_opt_data_clear_cache(struct sccp_connection *conn) -- To view, visit https://gerrit.osmocom.org/c/libosmo-sccp/+/32320 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Change-Id: Ib64e0cb1ae0cc8b7bebcb2a352d4068b496b304a Gerrit-Change-Number: 32320 Gerrit-PatchSet: 1 Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de> Gerrit-MessageType: newchange
1 0
0 0
  • ← Newer
  • 1
  • ...
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • ...
  • 226
  • Older →

HyperKitty Powered by HyperKitty version 1.3.12.