aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am1
-rw-r--r--README.md2
-rw-r--r--TODO-RELEASE13
-rw-r--r--configure.ac22
-rwxr-xr-xcontrib/jenkins.sh4
-rw-r--r--contrib/osmo-sgsn.spec.in138
-rw-r--r--debian/changelog40
-rw-r--r--debian/control16
-rwxr-xr-xdebian/osmo-gtphub.init150
-rwxr-xr-xdebian/postinst20
-rw-r--r--doc/examples/osmo-sgsn/osmo-sgsn-accept-all.cfg1
-rw-r--r--doc/examples/osmo-sgsn/osmo-sgsn.cfg1
-rw-r--r--doc/examples/osmo-sgsn/osmo-sgsn_custom-sccp.cfg1
-rw-r--r--include/osmocom/sgsn/gprs_bssgp.h3
-rw-r--r--include/osmocom/sgsn/gprs_gmm.h5
-rw-r--r--include/osmocom/sgsn/gprs_mm_state_iu_fsm.h1
-rw-r--r--include/osmocom/sgsn/gprs_sndcp.h2
-rw-r--r--include/osmocom/sgsn/gtp.h3
-rw-r--r--include/osmocom/sgsn/mmctx.h9
-rw-r--r--include/osmocom/sgsn/pdpctx.h4
-rw-r--r--include/osmocom/sgsn/sgsn.h2
-rw-r--r--osmoappdesc.py5
-rw-r--r--src/sgsn/Makefile.am1
-rw-r--r--src/sgsn/gprs_bssgp.c8
-rw-r--r--src/sgsn/gprs_gmm.c54
-rw-r--r--src/sgsn/gprs_llc.c2
-rw-r--r--src/sgsn/gprs_mm_state_iu_fsm.c66
-rw-r--r--src/sgsn/gprs_ranap.c2
-rw-r--r--src/sgsn/gprs_sm.c7
-rw-r--r--src/sgsn/gprs_sndcp.c2
-rw-r--r--src/sgsn/gprs_subscriber.c4
-rw-r--r--src/sgsn/mmctx.c27
-rw-r--r--src/sgsn/sgsn.c2
-rw-r--r--src/sgsn/sgsn_auth.c6
-rw-r--r--src/sgsn/sgsn_cdr.c4
-rw-r--r--src/sgsn/sgsn_libgtp.c83
-rw-r--r--src/sgsn/sgsn_vty.c9
-rw-r--r--tests/Makefile.am4
-rwxr-xr-xtests/ctrl_test_runner.py3
-rw-r--r--tests/osmo-sgsn-accept-all.cfg38
-rw-r--r--tests/osmo-sgsn.cfg40
-rw-r--r--tests/sgsn/Makefile.am1
-rw-r--r--tests/sgsn/sgsn_test.c26
-rw-r--r--tests/sndcp_xid/Makefile.am1
-rwxr-xr-xtests/vty_test_runner.py3
-rw-r--r--tests/xid/Makefile.am1
46 files changed, 407 insertions, 430 deletions
diff --git a/Makefile.am b/Makefile.am
index b70eb4b5d..fab0291d5 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -20,7 +20,6 @@ BUILT_SOURCES = $(top_srcdir)/.version
EXTRA_DIST = \
.version \
README.md \
- contrib/osmo-sgsn.spec.in \
debian \
git-version-gen \
osmoappdesc.py \
diff --git a/README.md b/README.md
index 3143d048a..9be245f02 100644
--- a/README.md
+++ b/README.md
@@ -83,7 +83,7 @@ Contributing
Our coding standards are described at
<https://osmocom.org/projects/cellular-infrastructure/wiki/Coding_standards>
-We us a gerrit based patch submission/review process for managing
+We use a Gerrit based patch submission/review process for managing
contributions. Please see
<https://osmocom.org/projects/cellular-infrastructure/wiki/Gerrit> for
more details
diff --git a/TODO-RELEASE b/TODO-RELEASE
index df983c1c4..eb1cdfdb1 100644
--- a/TODO-RELEASE
+++ b/TODO-RELEASE
@@ -1,2 +1,11 @@
-#component what description / commit summary line
-libosmocore > 1.9.0 gsup.h: Using new fields in struct osmo_gsup_pdp_info (ABI break) \ No newline at end of file
+# When cleaning up this file: bump API version in corresponding Makefile.am and rename corresponding debian/lib*.install
+# according to https://osmocom.org/projects/cellular-infrastructure/wiki/Make_a_new_release
+# In short: https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html#Updating-version-info
+# LIBVERSION=c:r:a
+# If the library source code has changed at all since the last update, then increment revision: c:r + 1:a.
+# If any interfaces have been added, removed, or changed since the last update: c + 1:0:a.
+# If any interfaces have been added since the last public release: c:r:a + 1.
+# If any interfaces have been removed or changed since the last public release: c:r:0.
+#library what description / commit summary line
+libgtp >1.12.0 new field dir_tun_flags in struct pdp_t
+libgtp >1.12.0 gtp_set_cb_update_context_ind(), gtp_update_context_resp()
diff --git a/configure.ac b/configure.ac
index ddd91ab2b..5286d2ee9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -38,23 +38,22 @@ dnl use a defined standard across all builds and don't depend on compiler defaul
CFLAGS="$CFLAGS -std=gnu11"
dnl checks for libraries
-PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.9.0)
-PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.9.0)
-PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.9.0)
-PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.9.0)
-PKG_CHECK_MODULES(LIBOSMOGB, libosmogb >= 1.9.0)
-PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 1.5.0)
-PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 1.4.0)
-PKG_CHECK_MODULES(LIBOSMOGSUPCLIENT, libosmo-gsup-client >= 1.7.0)
-PKG_CHECK_MODULES(LIBGTP, libgtp >= 1.11.0)
+PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.10.0)
+PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.10.0)
+PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.10.0)
+PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.10.0)
+PKG_CHECK_MODULES(LIBOSMOGB, libosmogb >= 1.10.0)
+PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 1.6.0)
+PKG_CHECK_MODULES(LIBOSMOGSUPCLIENT, libosmo-gsup-client >= 1.8.0)
+PKG_CHECK_MODULES(LIBGTP, libgtp >= 1.12.0)
# Enable/disable 3G aka IuPS + IuCS support?
AC_ARG_ENABLE([iu], [AS_HELP_STRING([--enable-iu], [Build 3G support, aka IuPS and IuCS interfaces])],
[osmo_ac_iu="$enableval"],[osmo_ac_iu="no"])
if test "x$osmo_ac_iu" = "xyes" ; then
- PKG_CHECK_MODULES(LIBOSMOSIGTRAN, libosmo-sigtran >= 1.8.0)
+ PKG_CHECK_MODULES(LIBOSMOSIGTRAN, libosmo-sigtran >= 1.9.0)
PKG_CHECK_MODULES(LIBASN1C, libasn1c >= 0.9.30)
- PKG_CHECK_MODULES(LIBOSMORANAP, libosmo-ranap >= 1.5.0)
+ PKG_CHECK_MODULES(LIBOSMORANAP, libosmo-ranap >= 1.6.0)
AC_DEFINE(BUILD_IU, 1, [Define if we want to build IuPS and IuCS interfaces support])
fi
AM_CONDITIONAL(BUILD_IU, test "x$osmo_ac_iu" = "xyes")
@@ -255,5 +254,4 @@ AC_OUTPUT(
doc/manuals/Makefile
contrib/Makefile
contrib/systemd/Makefile
- contrib/osmo-sgsn.spec
Makefile)
diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh
index 321beef1b..c04bc9eb6 100755
--- a/contrib/jenkins.sh
+++ b/contrib/jenkins.sh
@@ -33,12 +33,12 @@ export LD_LIBRARY_PATH="$inst/lib"
export PATH="$inst/bin:$PATH"
osmo-build-dep.sh libosmo-abis
-osmo-build-dep.sh libosmo-netif
osmo-build-dep.sh osmo-ggsn
osmo-build-dep.sh osmo-hlr
if [ "x$IU" = "x--enable-iu" ]; then
- osmo-build-dep.sh libosmo-sccp
+ osmo-build-dep.sh libosmo-netif
+ osmo-build-dep.sh libosmo-sigtran
osmo-build-dep.sh libasn1c
#osmo-build-dep.sh asn1c aper-prefix # only needed for make regen in osmo-iuh
osmo-build-dep.sh osmo-iuh
diff --git a/contrib/osmo-sgsn.spec.in b/contrib/osmo-sgsn.spec.in
deleted file mode 100644
index b0fae9e9e..000000000
--- a/contrib/osmo-sgsn.spec.in
+++ /dev/null
@@ -1,138 +0,0 @@
-#
-# spec file for package osmo-sgsn
-#
-# Copyright (c) 2017, Martin Hauke <mardnh@gmx.de>
-#
-# All modifications and additions to the file contributed by third parties
-# remain the property of their copyright owners, unless otherwise agreed
-# upon. The license for this file, and modifications and additions to the
-# file, is the same license as for the pristine package itself (unless the
-# license for the pristine package is not an Open Source License, in which
-# case the license is the MIT License). An "Open Source License" is a
-# license that conforms to the Open Source Definition (Version 1.9)
-# published by the Open Source Initiative.
-
-## Disable LTO for now since it breaks compilation of the tests
-## https://osmocom.org/issues/4116
-%define _lto_cflags %{nil}
-
-%define with_iu 1
-Name: osmo-sgsn
-Version: @VERSION@
-Release: 0
-Summary: Osmocom's SGSN for 2G and 3G packet-switched mobile networks
-License: AGPL-3.0-or-later AND GPL-2.0-or-later
-Group: Productivity/Telephony/Servers
-URL: https://osmocom.org/projects/osmosgsn
-Source: %{name}-%{version}.tar.xz
-BuildRequires: autoconf
-BuildRequires: automake
-BuildRequires: libtool
-BuildRequires: pkgconfig
-%if 0%{?suse_version}
-BuildRequires: systemd-rpm-macros
-%endif
-BuildRequires: pkgconfig(libcares)
-BuildRequires: pkgconfig(libcrypto) >= 0.9.5
-BuildRequires: pkgconfig(libgtp) >= 1.11.0
-BuildRequires: pkgconfig(libosmo-gsup-client) >= 1.7.0
-BuildRequires: pkgconfig(libosmo-netif) >= 1.4.0
-BuildRequires: pkgconfig(libosmoabis) >= 1.5.0
-BuildRequires: pkgconfig(libosmocore) >= 1.9.0
-BuildRequires: pkgconfig(libosmoctrl) >= 1.9.0
-BuildRequires: pkgconfig(libosmogb) >= 1.9.0
-BuildRequires: pkgconfig(libosmogsm) >= 1.9.0
-BuildRequires: pkgconfig(libosmovty) >= 1.9.0
-%{?systemd_requires}
-%if %{with_iu}
-BuildRequires: pkgconfig(libasn1c)
-BuildRequires: pkgconfig(libosmo-ranap) >= 1.5.0
-BuildRequires: pkgconfig(libosmo-sigtran) >= 1.8.0
-%endif
-
-%description
-OsmoSGSN is Osmocom's Serving GPRS Support Node for 2G and 3G
-packet-switched mobile networks.
-
-%package -n osmo-gtphub
-Summary: Osmocom GTP Hub: Proxy for GTP traffic between multiple SGSNs and GGSNs
-Group: Productivity/Telephony/Servers
-
-%description -n osmo-gtphub
-Osmocom GTP Hub: Proxy for GTP traffic between multiple SGSNs and GGSNs.
-
-%prep
-%setup -q
-
-%build
-echo "%{version}" >.tarball-version
-autoreconf -fi
-%configure \
-%if %{with_iu}
- --enable-iu \
-%endif
- --docdir=%{_docdir}/%{name} \
- --with-systemdsystemunitdir=%{_unitdir}
-make %{?_smp_mflags}
-
-%install
-%make_install
-
-%if 0%{?suse_version}
-%preun %service_del_preun %{name}.service
-%postun %service_del_postun %{name}.service
-%endif
-
-%pre
-getent group osmocom >/dev/null || groupadd --system osmocom
-getent passwd osmocom >/dev/null || useradd --system --gid osmocom --home-dir /var/lib/osmocom \
- --shell /sbin/nologin --comment "Open Source Mobile Communications" osmocom
-%if 0%{?suse_version}
-%service_add_pre %{name}.service
-%endif
-
-%post
-%if 0%{?suse_version}
-%service_add_post %{name}.service
-%endif
-chown osmocom:osmocom /etc/osmocom/osmo-sgsn.cfg
-chmod 0660 /etc/osmocom/osmo-sgsn.cfg
-chown root:osmocom /etc/osmocom
-chmod 2775 /etc/osmocom
-mkdir -p /var/lib/osmocom
-chown -R osmocom:osmocom /var/lib/osmocom
-
-%if 0%{?suse_version}
-%preun -n osmo-gtphub %service_del_preun osmo-gtphub.service
-%postun -n osmo-gtphub %service_del_postun osmo-gtphub.service
-%pre -n osmo-gtphub %service_add_pre osmo-gtphub.service
-%post -n osmo-gtphub %service_add_post osmo-gtphub.service
-%endif
-
-%check
-make %{?_smp_mflags} check || (find . -name testsuite.log -exec cat {} +)
-
-%files
-%doc AUTHORS README.md
-%dir %{_docdir}/%{name}/examples
-%dir %{_docdir}/%{name}/examples/osmo-sgsn
-%exclude %{_docdir}/%{name}/examples/osmo-gtphub
-%{_docdir}/%{name}/examples/osmo-sgsn/osmo-sgsn-accept-all.cfg
-%{_docdir}/%{name}/examples/osmo-sgsn/osmo-sgsn.cfg
-%{_docdir}/%{name}/examples/osmo-sgsn/osmo-sgsn_custom-sccp.cfg
-%{_bindir}/osmo-sgsn
-%dir %{_sysconfdir}/osmocom
-%config(noreplace) %{_sysconfdir}/osmocom/osmo-sgsn.cfg
-%{_unitdir}/%{name}.service
-
-%files -n osmo-gtphub
-%dir %{_docdir}/%{name}/examples
-%dir %{_docdir}/%{name}/examples/osmo-gtphub
-%{_docdir}/%{name}/examples/osmo-gtphub/osmo-gtphub-1iface.cfg
-%{_docdir}/%{name}/examples/osmo-gtphub/osmo-gtphub.cfg
-%{_bindir}/osmo-gtphub
-%dir %{_sysconfdir}/osmocom
-%config(noreplace) %{_sysconfdir}/osmocom/osmo-gtphub.cfg
-%{_unitdir}/osmo-gtphub.service
-
-%changelog
diff --git a/debian/changelog b/debian/changelog
index cb629fbdc..a1f0216d8 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,43 @@
+osmo-sgsn (1.12.0) unstable; urgency=medium
+
+ [ Andreas Eversberg ]
+ * Use uniform log format for default config files
+
+ [ Vadim Yanitskiy ]
+ * build: include README.md into the release tarball
+ * gmm: cosmetic: fix preprocessor macro formatting
+ * gmm: mmctx_timer_stop(): warn about timer not running
+ * VTY: move default settings to sgsn_instance_alloc()
+ * VTY: sync default UMTS UEA config with osmo-msc
+ * README.md: cosmetic: fix a typo
+
+ [ Pau Espin Pedrol ]
+ * gsup: Use new libosmogsm struct osmo_gsup_pdp_info fields
+
+ [ Harald Welte ]
+ * Add funding link to github mirror
+ * README.md: Overhaul (more links; improved formatting)
+ * README.md: Add Forum and Issue Tracker sections
+
+ [ Max ]
+ * .deb/.rpm: add osmocom user during package install
+
+ [ Oliver Smith ]
+ * contrib/osmo-sgsn.spec: fix build for almalinux:8
+ * .deb/.rpm: various fixes related to non-root
+ * contrib: remove rpm spec file
+ * debian/postinst: add checks, be verbose
+ * sgsn/sgsn_vty: create state-dir
+ * debian/osmo-gtphub.init: delete
+ * doc: set state-dir to /var/lib/osmocom/osmo-sgsn
+
+ [ Alexander Couzens ]
+ * docs: replace legacy NS with new NS2 chapters
+ * docs: update year to 2024
+ * docs: front page: use https:// instead of http://
+
+ -- Oliver Smith <osmith@sysmocom.de> Wed, 24 Jul 2024 17:31:38 +0200
+
osmo-sgsn (1.11.1) unstable; urgency=medium
[ Philipp Maier ]
diff --git a/debian/control b/debian/control
index aa594553b..2a3d427b2 100644
--- a/debian/control
+++ b/debian/control
@@ -11,16 +11,14 @@ Build-Depends: debhelper (>= 10),
pkg-config,
libtalloc-dev,
libc-ares-dev,
- libgtp-dev (>= 1.11.0),
- libosmocore-dev (>= 1.9.0),
- libosmo-abis-dev (>= 1.5.0),
- libosmo-netif-dev (>= 1.4.0),
- libosmo-gsup-client-dev (>= 1.7.0),
+ libgtp-dev (>= 1.12.0),
+ libosmocore-dev (>= 1.10.0),
+ libosmo-abis-dev (>= 1.6.0),
+ libosmo-gsup-client-dev (>= 1.8.0),
libasn1c-dev (>= 0.9.30),
- libosmo-ranap-dev (>= 1.5.0),
- libosmo-sigtran-dev (>= 1.8.0),
- libosmo-sccp-dev (>= 1.8.0),
- osmo-gsm-manuals-dev (>= 1.5.0)
+ libosmo-ranap-dev (>= 1.6.0),
+ libosmo-sigtran-dev (>= 1.9.0),
+ osmo-gsm-manuals-dev (>= 1.6.0)
Standards-Version: 3.9.8
Vcs-Git: https://gitea.osmocom.org/cellular-infrastructure/osmo-sgsn
Vcs-Browser: https://gitea.osmocom.org/cellular-infrastructure/osmo-sgsn
diff --git a/debian/osmo-gtphub.init b/debian/osmo-gtphub.init
deleted file mode 100755
index 160d55b70..000000000
--- a/debian/osmo-gtphub.init
+++ /dev/null
@@ -1,150 +0,0 @@
-#!/bin/sh
-### BEGIN INIT INFO
-# Provides: osmo-gtphub
-# Required-Start: $network $local_fs
-# Required-Stop:
-# Default-Start: 2 3 4 5
-# Default-Stop: 0 1 6
-# Short-Description: Osmocom GTP hub
-# Description: Osmocom GTP hub
-### END INIT INFO
-
-# Author: Neels Hofmeyr <nhofmeyr@sysmocom.de>
-
-# PATH should only include /usr/* if it runs after the mountnfs.sh script
-PATH=/sbin:/usr/sbin:/bin:/usr/bin
-NAME=osmo-gtphub # Introduce the short server's name here
-DESC="Osmocom GTP hub" # Introduce a short description here
-DAEMON=/usr/bin/osmo-gtphub # Introduce the server's location here
-SCRIPTNAME=/etc/init.d/osmo-gtphub
-
-# Exit if the package is not installed
-[ -x $DAEMON ] || exit 0
-
-# Read configuration variable file if it is present
-[ -r /etc/default/osmo-gtphub ] && . /etc/default/osmo-gtphub
-
-# Load the VERBOSE setting and other rcS variables
-. /lib/init/vars.sh
-
-# Define LSB log_* functions.
-# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
-. /lib/lsb/init-functions
-
-DAEMON_ARGS="$DAEMON_ARGS -D -c $CONFIG_FILE"
-
-#
-# Function that starts the daemon/service
-#
-do_start()
-{
- # Return
- # 0 if daemon has been started
- # 1 if daemon was already running
- # 2 if daemon could not be started
- start-stop-daemon --start --quiet --exec $DAEMON --test > /dev/null \
- || return 1
- start-stop-daemon --start --quiet --exec $DAEMON -- \
- $DAEMON_ARGS \
- || return 2
- # Add code here, if necessary, that waits for the process to be ready
- # to handle requests from services started subsequently which depend
- # on this one. As a last resort, sleep for some time.
-}
-
-#
-# Function that stops the daemon/service
-#
-do_stop()
-{
- # Return
- # 0 if daemon has been stopped
- # 1 if daemon was already stopped
- # 2 if daemon could not be stopped
- # other if a failure occurred
- start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --name $NAME
- RETVAL="$?"
- [ "$RETVAL" = 2 ] && return 2
- # Wait for children to finish too if this is a daemon that forks
- # and if the daemon is only ever run from this initscript.
- # If the above conditions are not satisfied then add some other code
- # that waits for the process to drop all resources that could be
- # needed by services started subsequently. A last resort is to
- # sleep for some time.
- start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
- [ "$?" = 2 ] && return 2
- return "$RETVAL"
-}
-
-#
-# Function that sends a SIGHUP to the daemon/service
-#
-do_reload() {
- #
- # If the daemon can reload its configuration without
- # restarting (for example, when it is sent a SIGHUP),
- # then implement that here.
- #
- start-stop-daemon --stop --signal 1 --quiet $PIDFILE --name $NAME
- return 0
-}
-
-case "$1" in
- start)
- [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC " "$NAME"
- do_start
- case "$?" in
- 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
- 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
- esac
- ;;
- stop)
- [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
- do_stop
- case "$?" in
- 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
- 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
- esac
- ;;
- status)
- status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
- ;;
- #reload|force-reload)
- #
- # If do_reload() is not implemented then leave this commented out
- # and leave 'force-reload' as an alias for 'restart'.
- #
- #log_daemon_msg "Reloading $DESC" "$NAME"
- #do_reload
- #log_end_msg $?
- #;;
- restart|force-reload)
- #
- # If the "reload" option is implemented then remove the
- # 'force-reload' alias
- #
- log_daemon_msg "Restarting $DESC" "$NAME"
- do_stop
- case "$?" in
- 0|1)
- do_start
- case "$?" in
- 0) log_end_msg 0 ;;
- 1) log_end_msg 1 ;; # Old process is still running
- *) log_end_msg 1 ;; # Failed to start
- esac
- ;;
- *)
- # Failed to stop
- log_end_msg 1
- ;;
- esac
- ;;
- *)
- #echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
- echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
- exit 3
- ;;
-esac
-
-:
diff --git a/debian/postinst b/debian/postinst
index 4ac99e443..25127b510 100755
--- a/debian/postinst
+++ b/debian/postinst
@@ -16,12 +16,20 @@ case "$1" in
fi
# Fix permissions of previous (root-owned) install (OS#4107)
- chown osmocom:osmocom /etc/osmocom/osmo-sgsn.cfg
- chmod 0660 /etc/osmocom/osmo-sgsn.cfg
- chown root:osmocom /etc/osmocom
- chmod 2775 /etc/osmocom
- mkdir -p /var/lib/osmocom
- chown -R osmocom:osmocom /var/lib/osmocom
+ if dpkg --compare-versions "$2" le "1.12.0"; then
+ if [ -e /etc/osmocom/osmo-sgsn.cfg ]; then
+ chown -v osmocom:osmocom /etc/osmocom/osmo-sgsn.cfg
+ chmod -v 0660 /etc/osmocom/osmo-sgsn.cfg
+ fi
+
+ if [ -d /etc/osmocom ]; then
+ chown -v root:osmocom /etc/osmocom
+ chmod -v 2775 /etc/osmocom
+ fi
+
+ mkdir -p /var/lib/osmocom
+ chown -R -v osmocom:osmocom /var/lib/osmocom
+ fi
;;
esac
diff --git a/doc/examples/osmo-sgsn/osmo-sgsn-accept-all.cfg b/doc/examples/osmo-sgsn/osmo-sgsn-accept-all.cfg
index 69000b439..9bc1520aa 100644
--- a/doc/examples/osmo-sgsn/osmo-sgsn-accept-all.cfg
+++ b/doc/examples/osmo-sgsn/osmo-sgsn-accept-all.cfg
@@ -14,6 +14,7 @@ line vty
no login
!
sgsn
+ gtp state-dir /var/lib/osmocom/osmo-sgsn
gtp local-ip 127.0.0.1
ggsn 0 remote-ip 127.0.0.2
ggsn 0 gtp-version 1
diff --git a/doc/examples/osmo-sgsn/osmo-sgsn.cfg b/doc/examples/osmo-sgsn/osmo-sgsn.cfg
index 0b5ef4b19..81047254f 100644
--- a/doc/examples/osmo-sgsn/osmo-sgsn.cfg
+++ b/doc/examples/osmo-sgsn/osmo-sgsn.cfg
@@ -14,6 +14,7 @@ line vty
no login
!
sgsn
+ gtp state-dir /var/lib/osmocom/osmo-sgsn
gtp local-ip 127.0.0.1
ggsn 0 remote-ip 127.0.0.2
ggsn 0 gtp-version 1
diff --git a/doc/examples/osmo-sgsn/osmo-sgsn_custom-sccp.cfg b/doc/examples/osmo-sgsn/osmo-sgsn_custom-sccp.cfg
index a7ed9cf1e..d7fbd75af 100644
--- a/doc/examples/osmo-sgsn/osmo-sgsn_custom-sccp.cfg
+++ b/doc/examples/osmo-sgsn/osmo-sgsn_custom-sccp.cfg
@@ -23,6 +23,7 @@ cs7 instance 0
asp asp-clnt-OsmoSGSN-A
routing-key 3 0.23.4
sgsn
+ gtp state-dir /var/lib/osmocom/osmo-sgsn
gtp local-ip 127.0.0.1
ggsn 0 remote-ip 127.0.0.2
ggsn 0 gtp-version 1
diff --git a/include/osmocom/sgsn/gprs_bssgp.h b/include/osmocom/sgsn/gprs_bssgp.h
index 0feaa9762..abfe9f197 100644
--- a/include/osmocom/sgsn/gprs_bssgp.h
+++ b/include/osmocom/sgsn/gprs_bssgp.h
@@ -2,6 +2,9 @@
#include <osmocom/core/msgb.h>
+struct osmo_prim_hdr;
+struct sgsn_mm_ctx;
+
/* Called by bssgp layer when a prim is received from lower layers. */
int sgsn_bssgp_rx_prim(struct osmo_prim_hdr *oph);
diff --git a/include/osmocom/sgsn/gprs_gmm.h b/include/osmocom/sgsn/gprs_gmm.h
index 71dd1fa7f..6fca77e05 100644
--- a/include/osmocom/sgsn/gprs_gmm.h
+++ b/include/osmocom/sgsn/gprs_gmm.h
@@ -9,6 +9,7 @@
struct sgsn_mm_ctx;
struct gprs_llc_llme;
+struct osmo_routing_area_id;
int gsm48_tx_gmm_auth_ciph_req(struct sgsn_mm_ctx *mm,
const struct osmo_auth_vector *vec,
@@ -28,8 +29,8 @@ void gsm0408_gprs_access_denied(struct sgsn_mm_ctx *mmctx, int gmm_cause);
void gsm0408_gprs_access_cancelled(struct sgsn_mm_ctx *mmctx, int gmm_cause);
void gsm0408_gprs_authenticate(struct sgsn_mm_ctx *mmctx);
-int gprs_gmm_rx_suspend(struct gprs_ra_id *raid, uint32_t tlli);
-int gprs_gmm_rx_resume(struct gprs_ra_id *raid, uint32_t tlli,
+int gprs_gmm_rx_suspend(struct osmo_routing_area_id *raid, uint32_t tlli);
+int gprs_gmm_rx_resume(struct osmo_routing_area_id *raid, uint32_t tlli,
uint8_t suspend_ref);
int gsm0408_gprs_rcvmsg_gb(struct msgb *msg, struct gprs_llc_llme *llme,
diff --git a/include/osmocom/sgsn/gprs_mm_state_iu_fsm.h b/include/osmocom/sgsn/gprs_mm_state_iu_fsm.h
index 6dae759b0..1d0333c98 100644
--- a/include/osmocom/sgsn/gprs_mm_state_iu_fsm.h
+++ b/include/osmocom/sgsn/gprs_mm_state_iu_fsm.h
@@ -17,6 +17,7 @@ enum mm_state_iu_fsm_events {
E_PMM_PS_CONN_RELEASE,
E_PMM_PS_CONN_ESTABLISH,
E_PMM_RA_UPDATE, /* = Serving RNC relocation */
+ E_PMM_RX_GGSN_GTPU_DT_EI, /* param: struct sgsn_pdp_ctx *pctx */
};
extern struct osmo_fsm mm_state_iu_fsm;
diff --git a/include/osmocom/sgsn/gprs_sndcp.h b/include/osmocom/sgsn/gprs_sndcp.h
index 30ea05308..058cb2952 100644
--- a/include/osmocom/sgsn/gprs_sndcp.h
+++ b/include/osmocom/sgsn/gprs_sndcp.h
@@ -47,7 +47,7 @@ struct gprs_sndcp_entity {
struct llist_head list;
/* FIXME: move this RA_ID up to the LLME or even higher */
- struct gprs_ra_id ra_id;
+ struct osmo_routing_area_id ra_id;
/* reference to the LLC Entity below this SNDCP entity */
struct gprs_llc_lle *lle;
/* The NSAPI we shall use on top of LLC */
diff --git a/include/osmocom/sgsn/gtp.h b/include/osmocom/sgsn/gtp.h
index 2aec55333..ed6cbf508 100644
--- a/include/osmocom/sgsn/gtp.h
+++ b/include/osmocom/sgsn/gtp.h
@@ -23,8 +23,7 @@ struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct sgsn_ggsn_ctx *ggsn,
uint16_t nsapi,
struct tlv_parsed *tp);
-int sgsn_gtp_data_req(struct gprs_ra_id *ra_id, int32_t tlli, uint8_t nsapi,
+int sgsn_gtp_data_req(struct osmo_routing_area_id *ra_id, int32_t tlli, uint8_t nsapi,
struct msgb *msg, uint32_t npdu_len, uint8_t *npdu);
int sgsn_delete_pdp_ctx(struct sgsn_pdp_ctx *pctx);
-void sgsn_pdp_upd_gtp_u(struct sgsn_pdp_ctx *pdp, void *addr, size_t alen);
int send_act_pdp_cont_acc(struct sgsn_pdp_ctx *pctx);
diff --git a/include/osmocom/sgsn/mmctx.h b/include/osmocom/sgsn/mmctx.h
index c19f599c5..03bb8452e 100644
--- a/include/osmocom/sgsn/mmctx.h
+++ b/include/osmocom/sgsn/mmctx.h
@@ -105,7 +105,7 @@ struct sgsn_mm_ctx {
char imei[GSM23003_IMEISV_NUM_DIGITS+1];
/* Opt: Software Version Numbber / TS 23.195 */
char msisdn[GSM_EXTENSION_LENGTH];
- struct gprs_ra_id ra;
+ struct osmo_routing_area_id ra;
struct {
uint16_t cell_id; /* Gb only */
uint32_t cell_id_age; /* Gb only */
@@ -253,18 +253,19 @@ static inline bool sgsn_mm_ctx_is_authenticated(struct sgsn_mm_ctx *ctx)
/* look-up a SGSN MM context based on TLLI + RAI */
struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli(uint32_t tlli,
- const struct gprs_ra_id *raid);
+ const struct osmo_routing_area_id *raid);
struct sgsn_mm_ctx *sgsn_mm_ctx_by_ptmsi(uint32_t tmsi);
struct sgsn_mm_ctx *sgsn_mm_ctx_by_imsi(const char *imsi);
struct sgsn_mm_ctx *sgsn_mm_ctx_by_ue_ctx(const void *uectx);
+struct sgsn_mm_ctx *sgsn_mm_ctx_by_llme(const struct gprs_llc_llme *llme);
/* look-up by matching TLLI and P-TMSI (think twice before using this) */
struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli_and_ptmsi(uint32_t tlli,
- const struct gprs_ra_id *raid);
+ const struct osmo_routing_area_id *raid);
/* Allocate a new SGSN MM context */
struct sgsn_mm_ctx *sgsn_mm_ctx_alloc_gb(uint32_t tlli,
- const struct gprs_ra_id *raid);
+ const struct osmo_routing_area_id *raid);
struct sgsn_mm_ctx *sgsn_mm_ctx_alloc_iu(void *uectx);
void sgsn_mm_ctx_cleanup_free(struct sgsn_mm_ctx *ctx);
diff --git a/include/osmocom/sgsn/pdpctx.h b/include/osmocom/sgsn/pdpctx.h
index 255a77d3f..39d744a1d 100644
--- a/include/osmocom/sgsn/pdpctx.h
+++ b/include/osmocom/sgsn/pdpctx.h
@@ -68,6 +68,10 @@ struct sgsn_pdp_ctx {
//uint32_t qos_profile_neg;
uint8_t radio_prio;
//uint32_t charging_id;
+ bool ue_pdp_active; /* PDP Context is active for this NSAPI? */
+ /* Keeps original SGSN local TEID when lib->teid_own is updated with
+ * RNC's TEID upon use of Direct Tunnel feature: */
+ uint32_t sgsn_teid_own;
struct osmo_timer_list timer;
unsigned int T; /* Txxxx number */
diff --git a/include/osmocom/sgsn/sgsn.h b/include/osmocom/sgsn/sgsn.h
index 6e93178af..9e091845c 100644
--- a/include/osmocom/sgsn/sgsn.h
+++ b/include/osmocom/sgsn/sgsn.h
@@ -21,7 +21,7 @@
#endif
#include <ares.h>
-#include <gtp.h>
+#include <osmocom/gtp/gtp.h>
struct hostent;
diff --git a/osmoappdesc.py b/osmoappdesc.py
index c3275978b..b0a916444 100644
--- a/osmoappdesc.py
+++ b/osmoappdesc.py
@@ -16,7 +16,7 @@
app_configs = {
- "sgsn": ["doc/examples/osmo-sgsn/osmo-sgsn.cfg"],
+ "sgsn": ["tests/osmo-sgsn.cfg"],
"gtphub": ["doc/examples/osmo-gtphub/osmo-gtphub-1iface.cfg"]
}
@@ -25,7 +25,6 @@ apps = [(4245, "src/sgsn/osmo-sgsn", "OsmoSGSN", "sgsn"),
(4253, "src/gtphub/osmo-gtphub", "OsmoGTPhub", "gtphub")
]
-vty_command = ["./src/sgsn/osmo-sgsn", "-c",
- "doc/examples/osmo-sgsn/osmo-sgsn.cfg"]
+vty_command = ["./src/sgsn/osmo-sgsn", "-c", "tests/osmo-sgsn.cfg"]
vty_app = apps[0]
diff --git a/src/sgsn/Makefile.am b/src/sgsn/Makefile.am
index 93b9fa058..487dead4f 100644
--- a/src/sgsn/Makefile.am
+++ b/src/sgsn/Makefile.am
@@ -79,7 +79,6 @@ osmo_sgsn_LDADD = \
$(top_builddir)/src/gprs/gprs_utils.o \
$(top_builddir)/src/gprs/sgsn_ares.o \
$(OSMO_LIBS) \
- $(LIBOSMOABIS_LIBS) \
$(LIBOSMOGSUPCLIENT_LIBS) \
$(LIBCARES_LIBS) \
$(LIBGTP_LIBS) \
diff --git a/src/sgsn/gprs_bssgp.c b/src/sgsn/gprs_bssgp.c
index 5db751cce..0a9bb915b 100644
--- a/src/sgsn/gprs_bssgp.c
+++ b/src/sgsn/gprs_bssgp.c
@@ -26,6 +26,8 @@
#include <osmocom/gprs/gprs_bssgp.h>
#include <osmocom/gprs/gprs_ns2.h>
+#include <osmocom/gsm/gsm48.h>
+
#include <osmocom/sgsn/gprs_llc.h>
#include <osmocom/sgsn/gprs_gmm.h>
#include <osmocom/sgsn/sgsn_rim.h>
@@ -35,6 +37,7 @@
int sgsn_bssgp_rx_prim(struct osmo_prim_hdr *oph)
{
struct osmo_bssgp_prim *bp;
+ struct osmo_routing_area_id ra_id = {};
bp = container_of(oph, struct osmo_bssgp_prim, oph);
switch (oph->sap) {
@@ -45,11 +48,12 @@ int sgsn_bssgp_rx_prim(struct osmo_prim_hdr *oph)
}
break;
case SAP_BSSGP_GMM:
+ gprs_rai_to_osmo(&ra_id, bp->ra_id);
switch (oph->primitive) {
case PRIM_BSSGP_GMM_SUSPEND:
- return gprs_gmm_rx_suspend(bp->ra_id, bp->tlli);
+ return gprs_gmm_rx_suspend(&ra_id, bp->tlli);
case PRIM_BSSGP_GMM_RESUME:
- return gprs_gmm_rx_resume(bp->ra_id, bp->tlli,
+ return gprs_gmm_rx_resume(&ra_id, bp->tlli,
bp->u.resume.suspend_ref);
}
break;
diff --git a/src/sgsn/gprs_gmm.c b/src/sgsn/gprs_gmm.c
index 653c42527..7f702607b 100644
--- a/src/sgsn/gprs_gmm.c
+++ b/src/sgsn/gprs_gmm.c
@@ -312,7 +312,7 @@ int gsm48_tx_gmm_att_ack(struct sgsn_mm_ctx *mm)
t = osmo_tdef_get(sgsn->cfg.T_defs, 3312, OSMO_TDEF_S, -1);
aa->ra_upd_timer = gprs_secs_to_tmr_floor(t);
aa->radio_prio = 0x44; /* lowest */
- gsm48_encode_ra(&aa->ra_id, &mm->ra);
+ osmo_routing_area_id_encode_buf((uint8_t *) &aa->ra_id, sizeof(struct gsm48_ra_id), &mm->ra);
#if 0
/* Optional: P-TMSI signature */
@@ -1195,7 +1195,7 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg,
uint8_t msnc_len, att_type, mi_len, ms_ra_acc_cap_len;
uint16_t drx_par;
char mi_log_string[32];
- struct gprs_ra_id ra_id;
+ struct osmo_routing_area_id ra_id;
uint16_t cid = 0;
enum gsm48_gmm_cause reject_cause;
struct osmo_mobile_identity mi;
@@ -1210,10 +1210,10 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg,
if (!MSG_IU_UE_CTX(msg)) {
/* Gb mode */
- cid = bssgp_parse_cell_id(&ra_id, msgb_bcid(msg));
+ bssgp_parse_cell_id2(&ra_id, &cid, msgb_bcid(msg), 8);
} else {
#ifdef BUILD_IU
- ra_id = MSG_IU_UE_CTX(msg)->ra_id;
+ gprs_rai_to_osmo(&ra_id, &MSG_IU_UE_CTX(msg)->ra_id);
#else
LOGMMCTXP(LOGL_ERROR, ctx, "Cannot handle Iu Attach Request, built without Iu support\n");
return -ENOTSUP;
@@ -1515,7 +1515,7 @@ static int gsm48_tx_gmm_ra_upd_ack(struct sgsn_mm_ctx *mm)
t = osmo_tdef_get(sgsn->cfg.T_defs, 3312, OSMO_TDEF_S, -1);
rua->ra_upd_timer = gprs_secs_to_tmr_floor(t);
- gsm48_encode_ra(&rua->ra_id, &mm->ra);
+ osmo_routing_area_id_encode_buf((uint8_t *)&rua->ra_id, sizeof(struct gsm48_ra_id), &mm->ra);
#if 0
/* Optional: P-TMSI signature */
@@ -1591,6 +1591,7 @@ static void process_ms_ctx_status(struct sgsn_mm_ctx *mmctx,
LOGMMCTXP(LOGL_NOTICE, mmctx, "Dropping PDP context for NSAPI=%u "
"due to PDP CTX STATUS IE=0x%02x%02x\n",
pdp->nsapi, pdp_status[1], pdp_status[0]);
+ pdp->ue_pdp_active = false;
if (pdp->ggsn)
sgsn_delete_pdp_ctx(pdp);
else /* GTP side already detached, freeing */
@@ -1621,7 +1622,7 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg);
uint8_t *cur = gh->data;
uint8_t ms_ra_acc_cap_len;
- struct gprs_ra_id old_ra_id;
+ struct osmo_routing_area_id old_ra_id;
struct tlv_parsed tp;
uint8_t upd_type;
enum gsm48_gmm_cause reject_cause = GMM_CAUSE_PROTO_ERR_UNSPEC;
@@ -1641,7 +1642,7 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
get_value_string(gprs_upd_t_strs, upd_type));
/* Old routing area identification 10.5.5.15 */
- gsm48_parse_ra(&old_ra_id, cur);
+ osmo_routing_area_id_decode(&old_ra_id, cur, msgb_l3len(msg) - (cur - msgb_gmmh(msg)));
cur += 6;
/* MS Radio Access Capability 10.5.5.12a */
@@ -1708,7 +1709,7 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
msgb_tlli(msg),
mmctx->p_tmsi, mmctx->p_tmsi_old,
mmctx->gb.tlli, mmctx->gb.tlli_new,
- osmo_rai_name(&mmctx->ra));
+ osmo_rai_name2(&mmctx->ra));
/* A RAT change will trigger the common procedure
* below after handling the RAT change. Protect it
* here from being called twice */
@@ -1716,26 +1717,26 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
osmo_fsm_inst_dispatch(mmctx->gmm_fsm, E_GMM_COMMON_PROC_INIT_REQ, NULL);
}
- } else if (!gprs_ra_id_equals(&mmctx->ra, &old_ra_id) ||
+ } else if (osmo_rai_cmp(&mmctx->ra, &old_ra_id) ||
mmctx->gmm_fsm->state == ST_GMM_DEREGISTERED)
{
/* We've received either a RAU for a MS which isn't registered
* or a RAU with an unknown RA ID. As long the SGSN doesn't support
* PS handover we treat this as invalid RAU */
- struct gprs_ra_id new_ra_id;
+ struct osmo_routing_area_id new_ra_id = {};
char new_ra[32];
- bssgp_parse_cell_id(&new_ra_id, msgb_bcid(msg));
- osmo_rai_name_buf(new_ra, sizeof(new_ra), &new_ra_id);
+ bssgp_parse_cell_id2(&new_ra_id, NULL, msgb_bcid(msg), 8);
+ osmo_rai_name2_buf(new_ra, sizeof(new_ra), &new_ra_id);
if (mmctx->gmm_fsm->state == ST_GMM_DEREGISTERED)
LOGMMCTXP(LOGL_INFO, mmctx,
"Rejecting RAU - GMM state is deregistered. Old RA: %s New RA: %s\n",
- osmo_rai_name(&old_ra_id), new_ra);
+ osmo_rai_name2(&old_ra_id), new_ra);
else
LOGMMCTXP(LOGL_INFO, mmctx,
"Rejecting RAU - Old RA doesn't match MM. Old RA: %s New RA: %s\n",
- osmo_rai_name(&old_ra_id), new_ra);
+ osmo_rai_name2(&old_ra_id), new_ra);
reject_cause = GMM_CAUSE_IMPL_DETACHED;
goto rejected;
@@ -1747,6 +1748,21 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
* in the MS */
LOGGBP(llme, DMM, LOGL_NOTICE, "LLC XID RESET\n");
gprs_llgmm_reset_oldmsg(msg, GPRS_SAPI_GMM, llme);
+
+ /* The RAU didn't come from expected TLLI+RAI, so it's for sure bad and should be rejected.
+ * In any case, before unassigning (freeing) the LLME during the REJECT below, make sure
+ * beforehand that if there's an mmctx relating to that llme it is also freed.
+ * Otherwise it would be kept pointining at a dangling freed llme object.
+ */
+ mmctx = sgsn_mm_ctx_by_llme(llme);
+ if (mmctx) {
+ char old_ra_id_name[32];
+ osmo_rai_name2_buf(old_ra_id_name, sizeof(old_ra_id_name), &old_ra_id);
+ LOGMMCTXP(LOGL_NOTICE, mmctx,
+ "Rx RA Update Request with unexpected TLLI=%08x Old RA=%s (expected Old RA: %s)!\n",
+ msgb_tlli(msg), old_ra_id_name, osmo_rai_name2(&mmctx->ra));
+ /* mmctx will be released (and its llme un assigned) after REJECT below. */
+ }
}
/* The MS has to perform GPRS attach */
/* Device is still IMSI attached for CS but initiate GPRS ATTACH,
@@ -1768,7 +1784,7 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
/* Update the MM context with the new RA-ID */
if (mmctx->ran_type == MM_CTX_T_GERAN_Gb && msgb_bcid(msg)) {
- bssgp_parse_cell_id(&mmctx->ra, msgb_bcid(msg));
+ bssgp_parse_cell_id2(&mmctx->ra, NULL, msgb_bcid(msg), 8);
/* Update the MM context with the new (i.e. foreign) TLLI */
mmctx->gb.tlli = msgb_tlli(msg);
}
@@ -2276,7 +2292,7 @@ int gsm0408_gprs_force_reattach(struct sgsn_mm_ctx *mmctx)
return rc;
}
-int gprs_gmm_rx_suspend(struct gprs_ra_id *raid, uint32_t tlli)
+int gprs_gmm_rx_suspend(struct osmo_routing_area_id *raid, uint32_t tlli)
{
struct sgsn_mm_ctx *mmctx;
@@ -2298,7 +2314,7 @@ int gprs_gmm_rx_suspend(struct gprs_ra_id *raid, uint32_t tlli)
return 0;
}
-int gprs_gmm_rx_resume(struct gprs_ra_id *raid, uint32_t tlli,
+int gprs_gmm_rx_resume(struct osmo_routing_area_id *raid, uint32_t tlli,
uint8_t suspend_ref)
{
struct sgsn_mm_ctx *mmctx;
@@ -2339,10 +2355,10 @@ int gsm0408_gprs_rcvmsg_gb(struct msgb *msg, struct gprs_llc_llme *llme,
struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg);
uint8_t pdisc = gsm48_hdr_pdisc(gh);
struct sgsn_mm_ctx *mmctx;
- struct gprs_ra_id ra_id;
+ struct osmo_routing_area_id ra_id = {};
int rc = -EINVAL;
- bssgp_parse_cell_id(&ra_id, msgb_bcid(msg));
+ bssgp_parse_cell_id2(&ra_id, NULL, msgb_bcid(msg), 8);
mmctx = sgsn_mm_ctx_by_tlli(msgb_tlli(msg), &ra_id);
if (mmctx) {
rate_ctr_inc(rate_ctr_group_get_ctr(mmctx->ctrg, GMM_CTR_PKTS_SIG_IN));
diff --git a/src/sgsn/gprs_llc.c b/src/sgsn/gprs_llc.c
index 6f563851f..82e876d2e 100644
--- a/src/sgsn/gprs_llc.c
+++ b/src/sgsn/gprs_llc.c
@@ -1112,7 +1112,7 @@ int gprs_llgmm_assign(struct gprs_llc_llme *llme,
llme->state = GPRS_LLMS_ASSIGNED;
} else if (old_tlli != TLLI_UNASSIGNED && new_tlli == TLLI_UNASSIGNED) {
/* TLLI Unassignment 8.3.3) */
- llme->tlli = llme->old_tlli = 0;
+ llme->tlli = llme->old_tlli = TLLI_UNASSIGNED;
llme->state = GPRS_LLMS_UNASSIGNED;
for (i = 0; i < ARRAY_SIZE(llme->lle); i++) {
struct gprs_llc_lle *l = &llme->lle[i];
diff --git a/src/sgsn/gprs_mm_state_iu_fsm.c b/src/sgsn/gprs_mm_state_iu_fsm.c
index c2e9c4498..c42667822 100644
--- a/src/sgsn/gprs_mm_state_iu_fsm.c
+++ b/src/sgsn/gprs_mm_state_iu_fsm.c
@@ -30,6 +30,7 @@
#include <osmocom/sgsn/sgsn.h>
#include <osmocom/sgsn/gprs_ranap.h>
#include <osmocom/sgsn/gtp.h>
+#include <osmocom/sgsn/gtp_ggsn.h>
#include <osmocom/sgsn/pdpctx.h>
#include <osmocom/sgsn/mmctx.h>
@@ -44,17 +45,30 @@ static const struct osmo_tdef_state_timeout mm_state_iu_fsm_timeouts[32] = {
#define mm_state_iu_fsm_state_chg(fi, NEXT_STATE) \
osmo_tdef_fsm_inst_state_chg(fi, NEXT_STATE, mm_state_iu_fsm_timeouts, sgsn->cfg.T_defs, -1)
-static void mmctx_change_gtpu_endpoints_to_sgsn(struct sgsn_mm_ctx *mm_ctx)
+
+static void pdpctx_change_gtpu_endpoint_to_sgsn(const struct sgsn_mm_ctx *mm_ctx, struct sgsn_pdp_ctx *pdp)
{
char buf[INET_ADDRSTRLEN];
+ LOGMMCTXP(LOGL_INFO, mm_ctx, "Changing GTP-U endpoints %s/0x%08x -> %s/0x%08x\n",
+ sgsn_gtp_ntoa(&pdp->lib->gsnlu), pdp->lib->teid_own,
+ inet_ntop(AF_INET, &sgsn->cfg.gtp_listenaddr.sin_addr, buf, sizeof(buf)),
+ pdp->sgsn_teid_own);
+ pdp->lib->gsnlu.l = sizeof(sgsn->cfg.gtp_listenaddr.sin_addr);
+ memcpy(pdp->lib->gsnlu.v, &sgsn->cfg.gtp_listenaddr.sin_addr,
+ sizeof(sgsn->cfg.gtp_listenaddr.sin_addr));
+ pdp->lib->teid_own = pdp->sgsn_teid_own;
+ /* Disable Direct Tunnel Flags DTI. Other flags make no sense here, so also set to 0. */
+ pdp->lib->dir_tun_flags.l = 1;
+ pdp->lib->dir_tun_flags.v[0] = 0x00;
+}
+
+static void mmctx_change_gtpu_endpoints_to_sgsn(struct sgsn_mm_ctx *mm_ctx, struct sgsn_pdp_ctx *pdp_skip_gtp_upd_req)
+{
struct sgsn_pdp_ctx *pdp;
llist_for_each_entry(pdp, &mm_ctx->pdp_list, list) {
- LOGMMCTXP(LOGL_INFO, mm_ctx, "Changing GTP-U endpoints %s -> %s\n",
- sgsn_gtp_ntoa(&pdp->lib->gsnlu),
- inet_ntop(AF_INET, &sgsn->cfg.gtp_listenaddr.sin_addr, buf, sizeof(buf)));
- sgsn_pdp_upd_gtp_u(pdp,
- &sgsn->cfg.gtp_listenaddr.sin_addr,
- sizeof(sgsn->cfg.gtp_listenaddr.sin_addr));
+ pdpctx_change_gtpu_endpoint_to_sgsn(mm_ctx, pdp);
+ if (pdp != pdp_skip_gtp_upd_req)
+ gtp_update_context(pdp->ggsn->gsn, pdp->lib, pdp, &pdp->lib->hisaddr0);
}
}
@@ -66,17 +80,24 @@ static void st_pmm_detached(struct osmo_fsm_inst *fi, uint32_t event, void *data
break;
case E_PMM_PS_DETACH:
break;
+ case E_PMM_RX_GGSN_GTPU_DT_EI:
+ /* This should in general not happen, since Direct Tunnel is not
+ * enabled during PMM-IDLE, but there may be a race condition of
+ * packets/events, so simply ignore it. */
+ break;
}
}
static void st_pmm_connected(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
struct sgsn_mm_ctx *ctx = fi->priv;
+ struct sgsn_pdp_ctx *pctx;
switch(event) {
case E_PMM_PS_CONN_RELEASE:
sgsn_ranap_iu_free(ctx);
mm_state_iu_fsm_state_chg(fi, ST_PMM_IDLE);
+ mmctx_change_gtpu_endpoints_to_sgsn(ctx, NULL);
break;
case E_PMM_PS_DETACH:
sgsn_ranap_iu_release_free(ctx, NULL);
@@ -84,16 +105,16 @@ static void st_pmm_connected(struct osmo_fsm_inst *fi, uint32_t event, void *dat
break;
case E_PMM_RA_UPDATE:
break;
+ case E_PMM_RX_GGSN_GTPU_DT_EI:
+ /* GTPU Direct Tunnel (RNC<->GGSN): GGSN Received Error Indication when transmitting DL data*/
+ pctx = (struct sgsn_pdp_ctx *)data;
+ sgsn_ranap_iu_free(ctx);
+ mm_state_iu_fsm_state_chg(fi, ST_PMM_IDLE);
+ mmctx_change_gtpu_endpoints_to_sgsn(ctx, pctx);
+ break;
}
}
-static void st_pmm_idle_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
-{
- struct sgsn_mm_ctx *ctx = fi->priv;
-
- mmctx_change_gtpu_endpoints_to_sgsn(ctx);
-}
-
static void st_pmm_idle(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
switch(event) {
@@ -104,12 +125,19 @@ static void st_pmm_idle(struct osmo_fsm_inst *fi, uint32_t event, void *data)
case E_PMM_PS_DETACH:
mm_state_iu_fsm_state_chg(fi, ST_PMM_DETACHED);
break;
+ case E_PMM_RX_GGSN_GTPU_DT_EI:
+ /* This should in general not happen, since Direct Tunnel is not
+ * enabled during PMM-IDLE, but there may be a race condition of
+ * packets/events, so simply ignore it. */
+ break;
}
}
static struct osmo_fsm_state mm_state_iu_fsm_states[] = {
[ST_PMM_DETACHED] = {
- .in_event_mask = X(E_PMM_PS_ATTACH) | X(E_PMM_PS_DETACH),
+ .in_event_mask = X(E_PMM_PS_ATTACH) |
+ X(E_PMM_PS_DETACH) |
+ X(E_PMM_RX_GGSN_GTPU_DT_EI),
.out_state_mask = X(ST_PMM_CONNECTED),
.name = "Detached",
.action = st_pmm_detached,
@@ -118,7 +146,8 @@ static struct osmo_fsm_state mm_state_iu_fsm_states[] = {
.in_event_mask =
X(E_PMM_PS_CONN_RELEASE) |
X(E_PMM_RA_UPDATE) |
- X(E_PMM_PS_DETACH),
+ X(E_PMM_PS_DETACH) |
+ X(E_PMM_RX_GGSN_GTPU_DT_EI),
.out_state_mask = X(ST_PMM_DETACHED) | X(ST_PMM_IDLE),
.name = "Connected",
.action = st_pmm_connected,
@@ -127,10 +156,10 @@ static struct osmo_fsm_state mm_state_iu_fsm_states[] = {
.in_event_mask =
X(E_PMM_PS_DETACH) |
X(E_PMM_PS_CONN_ESTABLISH) |
- X(E_PMM_PS_ATTACH),
+ X(E_PMM_PS_ATTACH) |
+ X(E_PMM_RX_GGSN_GTPU_DT_EI),
.out_state_mask = X(ST_PMM_DETACHED) | X(ST_PMM_CONNECTED),
.name = "Idle",
- .onenter = st_pmm_idle_on_enter,
.action = st_pmm_idle,
},
};
@@ -141,6 +170,7 @@ const struct value_string mm_state_iu_fsm_event_names[] = {
OSMO_VALUE_STRING(E_PMM_PS_CONN_ESTABLISH),
OSMO_VALUE_STRING(E_PMM_PS_DETACH),
OSMO_VALUE_STRING(E_PMM_RA_UPDATE),
+ OSMO_VALUE_STRING(E_PMM_RX_GGSN_GTPU_DT_EI),
{ 0, NULL }
};
diff --git a/src/sgsn/gprs_ranap.c b/src/sgsn/gprs_ranap.c
index 5e0d8edc6..51954ce20 100644
--- a/src/sgsn/gprs_ranap.c
+++ b/src/sgsn/gprs_ranap.c
@@ -103,6 +103,8 @@ static int sgsn_ranap_rab_ass_resp(struct sgsn_mm_ctx *ctx, RANAP_RAB_SetupOrMod
LOGP(DRANAP, LOGL_DEBUG, "Updating TEID on RNC side from 0x%08x to 0x%08x\n",
pdp->lib->teid_own, tei);
pdp->lib->teid_own = tei;
+ pdp->lib->dir_tun_flags.l = 1;
+ pdp->lib->dir_tun_flags.v[0] = 0x01; /* Set DTI flag in Direct Tunnel Flags */
require_pdp_update = true;
}
diff --git a/src/sgsn/gprs_sm.c b/src/sgsn/gprs_sm.c
index 88d1feb5a..bcf292312 100644
--- a/src/sgsn/gprs_sm.c
+++ b/src/sgsn/gprs_sm.c
@@ -114,9 +114,14 @@ static void pdpctx_timer_start(struct sgsn_pdp_ctx *pdp, unsigned int T)
static void pdpctx_timer_stop(struct sgsn_pdp_ctx *pdp, unsigned int T)
{
- if (pdp->T != T)
+ if (!osmo_timer_pending(&pdp->timer)) {
+ LOGPDPCTXP(LOGL_NOTICE, pdp, "Stopping *inactive* PDP timer %u\n", T);
+ return;
+ }
+ if (pdp->T != T) {
LOGPDPCTXP(LOGL_ERROR, pdp, "Stopping PDP timer %u but "
"%u is running\n", T, pdp->T);
+ }
osmo_timer_del(&pdp->timer);
}
diff --git a/src/sgsn/gprs_sndcp.c b/src/sgsn/gprs_sndcp.c
index 3eae127fc..636fe2e4b 100644
--- a/src/sgsn/gprs_sndcp.c
+++ b/src/sgsn/gprs_sndcp.c
@@ -834,7 +834,7 @@ int sndcp_ll_unitdata_ind(struct msgb *msg, struct gprs_llc_lle *lle,
return -EIO;
}
/* FIXME: move this RA_ID up to the LLME or even higher */
- bssgp_parse_cell_id(&sne->ra_id, msgb_bcid(msg));
+ bssgp_parse_cell_id2(&sne->ra_id, NULL, msgb_bcid(msg), 8);
mmctx = sgsn_mm_ctx_by_tlli(msgb_tlli(msg), &sne->ra_id);
if (!mmctx) {
diff --git a/src/sgsn/gprs_subscriber.c b/src/sgsn/gprs_subscriber.c
index a52abe8f1..07ea4c26c 100644
--- a/src/sgsn/gprs_subscriber.c
+++ b/src/sgsn/gprs_subscriber.c
@@ -877,8 +877,8 @@ struct gprs_subscr *gprs_subscr_get_or_create_by_mmctx(struct sgsn_mm_ctx *mmctx
osmo_strlcpy(subscr->imei, mmctx->imei, sizeof(subscr->imei));
- if (subscr->lac != mmctx->ra.lac)
- subscr->lac = mmctx->ra.lac;
+ if (subscr->lac != mmctx->ra.lac.lac)
+ subscr->lac = mmctx->ra.lac.lac;
subscr->sgsn_data->mm = mmctx;
mmctx->subscr = gprs_subscr_get(subscr);
diff --git a/src/sgsn/mmctx.c b/src/sgsn/mmctx.c
index 0e9309284..e0af4edd0 100644
--- a/src/sgsn/mmctx.c
+++ b/src/sgsn/mmctx.c
@@ -105,15 +105,30 @@ struct sgsn_mm_ctx *sgsn_mm_ctx_by_ue_ctx(const void *uectx)
return NULL;
}
+
+/* look-up an SGSN MM context based on Gb LLME context (struct gprs_llc_llme)*/
+struct sgsn_mm_ctx *sgsn_mm_ctx_by_llme(const struct gprs_llc_llme *llme)
+{
+ struct sgsn_mm_ctx *ctx;
+
+ llist_for_each_entry (ctx, &sgsn->mm_list, list) {
+ if (ctx->ran_type == MM_CTX_T_GERAN_Gb
+ && llme == ctx->gb.llme)
+ return ctx;
+ }
+
+ return NULL;
+}
+
/* look-up a SGSN MM context based on TLLI + RAI */
struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli(uint32_t tlli,
- const struct gprs_ra_id *raid)
+ const struct osmo_routing_area_id *raid)
{
struct sgsn_mm_ctx *ctx;
llist_for_each_entry(ctx, &sgsn->mm_list, list) {
if ((tlli == ctx->gb.tlli || tlli == ctx->gb.tlli_new) &&
- gprs_ra_id_equals(raid, &ctx->ra))
+ !osmo_rai_cmp(raid, &ctx->ra))
return ctx;
}
@@ -121,7 +136,7 @@ struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli(uint32_t tlli,
}
struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli_and_ptmsi(uint32_t tlli,
- const struct gprs_ra_id *raid)
+ const struct osmo_routing_area_id *raid)
{
struct sgsn_mm_ctx *ctx;
int tlli_type;
@@ -138,7 +153,7 @@ struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli_and_ptmsi(uint32_t tlli,
llist_for_each_entry(ctx, &sgsn->mm_list, list) {
if ((gprs_tmsi2tlli(ctx->p_tmsi, tlli_type) == tlli ||
gprs_tmsi2tlli(ctx->p_tmsi_old, tlli_type) == tlli) &&
- gprs_ra_id_equals(raid, &ctx->ra))
+ !osmo_rai_cmp(raid, &ctx->ra))
return ctx;
}
@@ -224,7 +239,7 @@ out:
}
/* Allocate a new SGSN MM context for GERAN_Gb */
struct sgsn_mm_ctx *sgsn_mm_ctx_alloc_gb(uint32_t tlli,
- const struct gprs_ra_id *raid)
+ const struct osmo_routing_area_id *raid)
{
struct sgsn_mm_ctx *ctx;
@@ -252,7 +267,7 @@ struct sgsn_mm_ctx *sgsn_mm_ctx_alloc_iu(void *uectx)
return NULL;
/* Need to get RAID from IU conn */
- ctx->ra = ue_ctx->ra_id;
+ gprs_rai_to_osmo(&ctx->ra, &ue_ctx->ra_id);
ctx->ran_type = MM_CTX_T_UTRAN_Iu;
ctx->iu.ue_ctx = ue_ctx;
ctx->iu.ue_ctx->rab_assign_addr_enc = sgsn->cfg.iu.rab_assign_addr_enc;
diff --git a/src/sgsn/sgsn.c b/src/sgsn/sgsn.c
index c3b7fda36..57a2c38a9 100644
--- a/src/sgsn/sgsn.c
+++ b/src/sgsn/sgsn.c
@@ -166,7 +166,7 @@ struct sgsn_instance *sgsn_instance_alloc(void *talloc_ctx)
inst->cfg.gtp_statedir = talloc_strdup(inst, "./");
inst->cfg.auth_policy = SGSN_AUTH_POLICY_CLOSED;
inst->cfg.gea_encryption_mask = (1 << GPRS_ALGO_GEA0); /* no encryption */
- inst->cfg.uea_encryption_mask = (1 << OSMO_UTRAN_UEA0); /* no encryption */
+ inst->cfg.uea_encryption_mask = (1 << OSMO_UTRAN_UEA2) | (1 << OSMO_UTRAN_UEA1);
inst->cfg.require_authentication = true; /* only applies if auth_policy is REMOTE */
inst->cfg.gsup_server_port = OSMO_GSUP_PORT;
diff --git a/src/sgsn/sgsn_auth.c b/src/sgsn/sgsn_auth.c
index cbff6f8ba..2f5bc8cf9 100644
--- a/src/sgsn/sgsn_auth.c
+++ b/src/sgsn/sgsn_auth.c
@@ -133,9 +133,9 @@ enum sgsn_auth_state sgsn_auth_state(struct sgsn_mm_ctx *mmctx)
/* We simply assume that the IMSI exists, as long as it is part
* of 'our' network */
snprintf(mccmnc, sizeof(mccmnc), "%s%s",
- osmo_mcc_name(mmctx->ra.mcc),
- osmo_mnc_name(mmctx->ra.mnc, mmctx->ra.mnc_3_digits));
- if (strncmp(mccmnc, mmctx->imsi, mmctx->ra.mnc_3_digits ? 6 : 5) == 0)
+ osmo_mcc_name(mmctx->ra.lac.plmn.mcc),
+ osmo_mnc_name(mmctx->ra.lac.plmn.mnc, mmctx->ra.lac.plmn.mnc_3_digits));
+ if (strncmp(mccmnc, mmctx->imsi, mmctx->ra.lac.plmn.mnc_3_digits ? 6 : 5) == 0)
return SGSN_AUTH_ACCEPTED;
}
diff --git a/src/sgsn/sgsn_cdr.c b/src/sgsn/sgsn_cdr.c
index 1536c135a..1979d9261 100644
--- a/src/sgsn/sgsn_cdr.c
+++ b/src/sgsn/sgsn_cdr.c
@@ -92,7 +92,7 @@ static int cdr_snprintf_mm(char *buf, size_t size, const char *ev,
mmctx->imei,
mmctx->msisdn,
mmctx->gb.cell_id,
- mmctx->ra.lac,
+ mmctx->ra.lac.lac,
mmctx->hlr,
ev);
return ret;
@@ -194,7 +194,7 @@ static int cdr_snprintf_pdp(char *buf, size_t size, const char *ev,
pdp->mm ? pdp->mm->imei : "N/A",
pdp->mm ? pdp->mm->msisdn : "N/A",
pdp->mm ? pdp->mm->gb.cell_id : -1,
- pdp->mm ? pdp->mm->ra.lac : -1,
+ pdp->mm ? pdp->mm->ra.lac.lac : -1,
pdp->mm ? pdp->mm->hlr : "N/A",
ev,
(unsigned long ) duration,
diff --git a/src/sgsn/sgsn_libgtp.c b/src/sgsn/sgsn_libgtp.c
index 9edd0c60e..faf0e7f57 100644
--- a/src/sgsn/sgsn_libgtp.c
+++ b/src/sgsn/sgsn_libgtp.c
@@ -55,6 +55,7 @@
#include <osmocom/sgsn/gprs_ranap.h>
#include <osmocom/sgsn/gprs_gmm_fsm.h>
#include <osmocom/sgsn/gprs_mm_state_gb_fsm.h>
+#include <osmocom/sgsn/gprs_mm_state_iu_fsm.h>
#include <osmocom/sgsn/gtp_ggsn.h>
#include <osmocom/sgsn/gtp_mme.h>
#include <osmocom/sgsn/sgsn_rim.h>
@@ -142,7 +143,7 @@ struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct sgsn_ggsn_ctx *ggsn,
uint16_t nsapi,
struct tlv_parsed *tp)
{
- struct gprs_ra_id raid;
+ struct osmo_routing_area_id raid = {};
struct sgsn_pdp_ctx *pctx;
struct pdp_t *pdp;
uint64_t imsi_ui64;
@@ -166,6 +167,9 @@ struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct sgsn_ggsn_ctx *ggsn,
pdp->priv = pctx;
pctx->lib = pdp;
+ /* Back up our own local TEID in case we update the library one with RNC TEID when setting up Direct Tunnel: */
+ pctx->sgsn_teid_own = pdp->teid_own;
+
//pdp->peer = /* sockaddr_in of GGSN (receive) */
//pdp->ipif = /* not used by library */
pdp->version = ggsn->gtp_version;
@@ -269,9 +273,9 @@ struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct sgsn_ggsn_ctx *ggsn,
/* Routing Area Identifier with LAC and RAC fixed values, as
* requested in 29.006 7.3.1 */
raid = mmctx->ra;
- raid.lac = 0xFFFE;
+ raid.lac.lac = 0xFFFE;
raid.rac = 0xFF;
- gsm48_encode_ra((struct gsm48_ra_id *)pdp->rai.v, &raid);
+ osmo_routing_area_id_encode_buf(pdp->rai.v, pdp->rai.l, &raid);
/* Encode User Location Information accordint to TS 29.060 7.7.51 */
pdp->userloc_given = 1;
@@ -286,12 +290,12 @@ struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct sgsn_ggsn_ctx *ggsn,
pdp->userloc_given = 1;
pdp->userloc.l = 8;
pdp->userloc.v[0] = 0; /* CGI for GERAN */
- bssgp_create_cell_id(&pdp->userloc.v[1], &mmctx->ra, mmctx->gb.cell_id);
+ bssgp_create_cell_id2(&pdp->userloc.v[1], 8, &mmctx->ra, mmctx->gb.cell_id);
break;
case MM_CTX_T_UTRAN_Iu:
pdp->userloc.v[0] = 1; /* SAI for UTRAN */
/* SAI is like CGI but with SAC instead of CID, so we can abuse this function */
- bssgp_create_cell_id(&pdp->userloc.v[1], &mmctx->ra, mmctx->iu.sac);
+ bssgp_create_cell_id2(&pdp->userloc.v[1], 8, &mmctx->ra, mmctx->iu.sac);
break;
}
@@ -378,6 +382,7 @@ int send_act_pdp_cont_acc(struct sgsn_pdp_ctx *pctx)
rc = gsm48_tx_gsm_act_pdp_acc(pctx);
if (rc < 0)
return rc;
+ pctx->ue_pdp_active = true;
if (pctx->mm->ran_type == MM_CTX_T_GERAN_Gb) {
/* Send SNDCP XID to MS */
@@ -464,13 +469,6 @@ reject:
return EOF;
}
-void sgsn_pdp_upd_gtp_u(struct sgsn_pdp_ctx *pdp, void *addr, size_t alen)
-{
- pdp->lib->gsnlu.l = alen;
- memcpy(pdp->lib->gsnlu.v, addr, alen);
- gtp_update_context(pdp->ggsn->gsn, pdp->lib, pdp, &pdp->lib->hisaddr0);
-}
-
void sgsn_ggsn_echo_req(struct sgsn_ggsn_ctx *ggc)
{
LOGGGSN(ggc, LOGL_INFO, "GTP Tx Echo Request\n");
@@ -567,9 +565,11 @@ static int delete_pdp_conf(struct pdp_t *pdp, void *cbp, int cause)
return -ENOTSUP;
#endif
}
-
- /* Confirm deactivation of PDP context to MS */
- rc = gsm48_tx_gsm_deact_pdp_acc(pctx);
+ if (pctx->ue_pdp_active) {
+ /* Confirm deactivation of PDP context to MS */
+ rc = gsm48_tx_gsm_deact_pdp_acc(pctx);
+ pctx->ue_pdp_active = false;
+ }
} else {
LOGPDPCTXP(LOGL_NOTICE, pctx,
"Not deactivating SNDCP layer since the MM context "
@@ -649,6 +649,52 @@ static int cb_conf(int type, int cause, struct pdp_t *pdp, void *cbp)
return 0;
}
+/* Called whenever a PDP context is updated from the GGSN for any reason */
+static int cb_update_context_ind(struct pdp_t *pdp)
+{
+ struct sgsn_pdp_ctx *pctx;
+ struct sgsn_mm_ctx *mm;
+ int rc;
+
+ LOGPDPX(DGPRS, LOGL_INFO, pdp, "Context %p was updated\n", pdp);
+
+ pctx = pdp->priv;
+ if (!pctx) {
+ LOGP(DGPRS, LOGL_NOTICE,
+ "GTP DATA IND from GGSN for unknown PDP\n");
+ return -EIO;
+ }
+ mm = pctx->mm;
+ if (!mm) {
+ LOGP(DGPRS, LOGL_ERROR,
+ "PDP context (address=%u) without MM context!\n",
+ pctx->address);
+ return -EIO;
+ }
+
+ if (mm->ran_type == MM_CTX_T_UTRAN_Iu) {
+#ifdef BUILD_IU
+ if (pdp->dir_tun_flags.v[0] & 0x04) { /* EI bit set ? */
+ /* GGSN informed us that it received an Error Indication when sending DL data to the RNC.
+ * This probably means the RNC lost its state, aka crashed or was rebooted.
+ * Page the UE so it re-creates the state at the RNC. */
+ LOGMMCTXP(LOGL_INFO, mm,
+ "GGSN received ErrorInd from RNC while tx DL data. Paging UE in state %s\n",
+ osmo_fsm_inst_state_name(mm->gmm_fsm));
+ rc = osmo_fsm_inst_dispatch(mm->iu.mm_state_fsm, E_PMM_RX_GGSN_GTPU_DT_EI, pctx);
+ rc = gtp_update_context_resp(sgsn->gsn, pdp,
+ GTPCAUSE_ACC_REQ);
+ ranap_iu_page_ps(mm->imsi, &mm->p_tmsi, mm->ra.lac.lac, mm->ra.rac);
+ return rc;
+ }
+#endif
+ }
+
+ rc = gtp_update_context_resp(sgsn->gsn, pdp,
+ GTPCAUSE_ACC_REQ);
+ return rc;
+}
+
/* Called whenever a PDP context is deleted for any reason */
static int cb_delete_context(struct pdp_t *pdp)
{
@@ -780,7 +826,9 @@ static int cb_data_ind(struct pdp_t *lib, void *packet, unsigned int len)
#ifdef BUILD_IU
/* Ignore the packet for now and page the UE to get the RAB
* reestablished */
- ranap_iu_page_ps(mm->imsi, &mm->p_tmsi, mm->ra.lac, mm->ra.rac);
+ LOGMMCTXP(LOGL_INFO, mm, "Rx GTP for UE in PMM state %s, paging it\n",
+ osmo_fsm_inst_state_name(mm->iu.mm_state_fsm));
+ ranap_iu_page_ps(mm->imsi, &mm->p_tmsi, mm->ra.lac.lac, mm->ra.rac);
return 0;
#else
@@ -842,7 +890,7 @@ static int cb_data_ind(struct pdp_t *lib, void *packet, unsigned int len)
}
/* Called by SNDCP when it has received/re-assembled a N-PDU */
-int sgsn_gtp_data_req(struct gprs_ra_id *ra_id, int32_t tlli, uint8_t nsapi,
+int sgsn_gtp_data_req(struct osmo_routing_area_id *ra_id, int32_t tlli, uint8_t nsapi,
struct msgb *msg, uint32_t npdu_len, uint8_t *npdu)
{
struct sgsn_mm_ctx *mmctx;
@@ -943,6 +991,7 @@ int sgsn_gtp_init(struct sgsn_instance *sgi)
}
/* Register callbackcs with libgtp */
+ gtp_set_cb_update_context_ind(gsn, cb_update_context_ind);
gtp_set_cb_delete_context(gsn, cb_delete_context);
gtp_set_cb_conf(gsn, cb_conf);
gtp_set_cb_recovery3(gsn, cb_recovery3);
diff --git a/src/sgsn/sgsn_vty.c b/src/sgsn/sgsn_vty.c
index 6837e7180..bcb8dc208 100644
--- a/src/sgsn/sgsn_vty.c
+++ b/src/sgsn/sgsn_vty.c
@@ -24,6 +24,8 @@
#include <arpa/inet.h>
#include <time.h>
#include <inttypes.h>
+#include <sys/stat.h>
+#include <sys/types.h>
#include <osmocom/core/talloc.h>
#include <osmocom/core/utils.h>
@@ -404,6 +406,11 @@ DEFUN(cfg_sgsn_state_dir, cfg_sgsn_state_dir_cmd,
"Set the directory for the GTP State file\n"
"Local Directory\n")
{
+ if (mkdir(argv[0], 0755) == -1 && errno != EEXIST) {
+ vty_out(vty, "%% Failed to create state-dir: %s%s", argv[0], VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
osmo_talloc_replace_string(sgsn, &sgsn->cfg.gtp_statedir, argv[0]);
return CMD_SUCCESS;
@@ -644,7 +651,7 @@ static void vty_dump_mmctx(struct vty *vty, const char *pfx,
pfx, mm->msisdn, id, mm->hlr, VTY_NEWLINE);
vty_out(vty, "%s GMM State: %s, Routeing Area: %s, Cell ID: %u%s",
pfx, osmo_fsm_inst_state_name(mm->gmm_fsm),
- osmo_rai_name(&mm->ra), mm->gb.cell_id, VTY_NEWLINE);
+ osmo_rai_name2(&mm->ra), mm->gb.cell_id, VTY_NEWLINE);
vty_out(vty, "%s MM State: %s, RAN Type: %s%s", pfx, mm_state_name,
get_value_string(sgsn_ran_type_names, mm->ran_type), VTY_NEWLINE);
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 2c07ac96e..fc5af0b7b 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -32,6 +32,8 @@ EXTRA_DIST = \
$(TESTSUITE) \
vty_test_runner.py \
ctrl_test_runner.py \
+ osmo-sgsn-accept-all.cfg \
+ osmo-sgsn.cfg \
osmo-sgsn_test-nodes.vty \
$(NULL)
@@ -62,7 +64,7 @@ vty-python-test: $(top_builddir)/src/sgsn/osmo-sgsn
vty-transcript-test: $(top_builddir)/src/sgsn/osmo-sgsn
osmo_verify_transcript_vty.py -v \
-n OsmoSGSN -p 4245 \
- -r "$(top_builddir)/src/sgsn/osmo-sgsn -c $(top_srcdir)/doc/examples/osmo-sgsn/osmo-sgsn.cfg" \
+ -r "$(top_builddir)/src/sgsn/osmo-sgsn -c $(top_srcdir)/tests/osmo-sgsn.cfg" \
$(U) $${T:-$(srcdir)/osmo-sgsn*.vty}
rm -f $(builddir)/gsn_restart
diff --git a/tests/ctrl_test_runner.py b/tests/ctrl_test_runner.py
index 69b247819..20c59eb01 100755
--- a/tests/ctrl_test_runner.py
+++ b/tests/ctrl_test_runner.py
@@ -145,8 +145,7 @@ class TestCtrlBase(unittest.TestCase):
class TestCtrlSGSN(TestCtrlBase):
def ctrl_command(self):
- return ["./src/sgsn/osmo-sgsn", "-c",
- "doc/examples/osmo-sgsn/osmo-sgsn.cfg"]
+ return ["./src/sgsn/osmo-sgsn", "-c", "tests/osmo-sgsn.cfg"]
def ctrl_app(self):
return (4251, "./src/sgsn/osmo-sgsn", "OsmoSGSN", "sgsn")
diff --git a/tests/osmo-sgsn-accept-all.cfg b/tests/osmo-sgsn-accept-all.cfg
new file mode 100644
index 000000000..46a5d614a
--- /dev/null
+++ b/tests/osmo-sgsn-accept-all.cfg
@@ -0,0 +1,38 @@
+# Same as doc/examples/osmo-sgsn/osmo-sgsn-accept-all.cfg, but without 'gtp state-dir'
+!
+! Osmocom SGSN configuration
+!
+!
+log stderr
+ logging color 1
+ logging print category-hex 0
+ logging print category 1
+ logging timestamp 0
+ logging print file basename last
+ logging print level 1
+
+line vty
+ no login
+!
+sgsn
+ gtp local-ip 127.0.0.1
+ ggsn 0 remote-ip 127.0.0.2
+ ggsn 0 gtp-version 1
+ ggsn 0 echo-interval 60
+ authentication optional
+ auth-policy accept-all
+!
+ns
+ timer tns-block 3
+ timer tns-block-retries 3
+ timer tns-reset 3
+ timer tns-reset-retries 3
+ timer tns-test 30
+ timer tns-alive 3
+ timer tns-alive-retries 10
+ bind udp local
+ listen 127.0.0.1 23000
+ accept-ipaccess
+!
+bssgp
+!
diff --git a/tests/osmo-sgsn.cfg b/tests/osmo-sgsn.cfg
new file mode 100644
index 000000000..cf8509c15
--- /dev/null
+++ b/tests/osmo-sgsn.cfg
@@ -0,0 +1,40 @@
+# Same as doc/examples/osmo-sgsn/osmo-sgsn.cfg, but without 'gtp state-dir'
+!
+! Osmocom SGSN configuration
+!
+!
+log stderr
+ logging color 1
+ logging print category-hex 0
+ logging print category 1
+ logging timestamp 0
+ logging print file basename last
+ logging print level 1
+
+line vty
+ no login
+!
+sgsn
+ gtp local-ip 127.0.0.1
+ ggsn 0 remote-ip 127.0.0.2
+ ggsn 0 gtp-version 1
+ ggsn 0 echo-interval 60
+ authentication required
+ auth-policy remote
+ gsup remote-ip 127.0.0.1
+ gsup remote-port 4222
+!
+ns
+ timer tns-block 3
+ timer tns-block-retries 3
+ timer tns-reset 3
+ timer tns-reset-retries 3
+ timer tns-test 30
+ timer tns-alive 3
+ timer tns-alive-retries 10
+ bind udp local
+ listen 127.0.0.1 23000
+ accept-ipaccess
+!
+bssgp
+!
diff --git a/tests/sgsn/Makefile.am b/tests/sgsn/Makefile.am
index c6c1f4a68..9cffdfd25 100644
--- a/tests/sgsn/Makefile.am
+++ b/tests/sgsn/Makefile.am
@@ -84,7 +84,6 @@ sgsn_test_LDADD = \
$(top_builddir)/src/gprs/gprs_llc_parse.o \
$(top_builddir)/src/gprs/crc24.o \
$(top_builddir)/src/gprs/sgsn_ares.o \
- $(LIBOSMOABIS_LIBS) \
$(LIBOSMOCORE_LIBS) \
$(LIBOSMOCTRL_LIBS) \
$(LIBOSMOGSM_LIBS) \
diff --git a/tests/sgsn/sgsn_test.c b/tests/sgsn/sgsn_test.c
index a149b8e2c..29dad74f0 100644
--- a/tests/sgsn/sgsn_test.c
+++ b/tests/sgsn/sgsn_test.c
@@ -181,7 +181,7 @@ static struct msgb *create_msg(const uint8_t *data, size_t len)
/*
* Create a context and search for it
*/
-static struct sgsn_mm_ctx *alloc_mm_ctx(uint32_t tlli, struct gprs_ra_id *raid)
+static struct sgsn_mm_ctx *alloc_mm_ctx(uint32_t tlli, struct osmo_routing_area_id *raid)
{
struct sgsn_mm_ctx *ctx, *ictx;
struct gprs_llc_lle *lle;
@@ -200,7 +200,7 @@ static struct sgsn_mm_ctx *alloc_mm_ctx(uint32_t tlli, struct gprs_ra_id *raid)
}
static void send_0408_message(struct gprs_llc_llme *llme, uint32_t tlli,
- const struct gprs_ra_id *bssgp_raid,
+ const struct osmo_routing_area_id *bssgp_raid,
const uint8_t *data, size_t data_len)
{
struct msgb *msg;
@@ -210,7 +210,7 @@ static void send_0408_message(struct gprs_llc_llme *llme, uint32_t tlli,
msg = create_msg(data, data_len);
msgb_tlli(msg) = tlli;
- bssgp_create_cell_id(msgb_bcid(msg), bssgp_raid, 0);
+ bssgp_create_cell_id2(msgb_bcid(msg), 8, bssgp_raid, 0);
gsm0408_gprs_rcvmsg_gb(msg, llme, false);
msgb_free(msg);
}
@@ -375,7 +375,7 @@ static void test_auth_triplets(void)
const char *imsi1 = "1234567890";
struct gsm_auth_tuple *at;
struct sgsn_mm_ctx *ctx;
- struct gprs_ra_id raid = { 0, };
+ struct osmo_routing_area_id raid = { 0, };
uint32_t local_tlli = 0xffeeddcc;
printf("Testing authentication triplet handling\n");
@@ -455,7 +455,7 @@ static void test_subscriber_gsup(void)
struct gprs_subscr *s1, *s1found;
const char *imsi1 = "1234567890";
struct sgsn_mm_ctx *ctx;
- struct gprs_ra_id raid = { 0, };
+ struct osmo_routing_area_id raid = { 0, };
uint32_t local_tlli = 0xffeeddcc;
struct sgsn_subscriber_pdp_data *pdpd;
int rc;
@@ -740,7 +740,7 @@ int my_gsup_client_send_dummy(struct osmo_gsup_client *gsupc, struct msgb *msg)
*/
static void test_gmm_detach(void)
{
- struct gprs_ra_id raid = { 0, };
+ struct osmo_routing_area_id raid = { 0, };
struct sgsn_mm_ctx *ctx, *ictx;
uint32_t local_tlli;
@@ -782,7 +782,7 @@ static void test_gmm_detach(void)
*/
static void test_gmm_detach_power_off(void)
{
- struct gprs_ra_id raid = { 0, };
+ struct osmo_routing_area_id raid = { 0, };
struct sgsn_mm_ctx *ctx, *ictx;
uint32_t local_tlli;
@@ -823,7 +823,7 @@ static void test_gmm_detach_power_off(void)
*/
static void test_gmm_detach_no_mmctx(void)
{
- struct gprs_ra_id raid = { 0, };
+ struct osmo_routing_area_id raid = { 0, };
struct gprs_llc_lle *lle;
uint32_t local_tlli;
@@ -860,7 +860,7 @@ static void test_gmm_detach_no_mmctx(void)
*/
static void test_gmm_detach_accept_unexpected(void)
{
- struct gprs_ra_id raid = { 0, };
+ struct osmo_routing_area_id raid = { 0, };
struct gprs_llc_lle *lle;
uint32_t local_tlli;
@@ -897,7 +897,7 @@ static void test_gmm_detach_accept_unexpected(void)
*/
static void test_gmm_status_no_mmctx(void)
{
- struct gprs_ra_id raid = { 0, };
+ struct osmo_routing_area_id raid = { 0, };
struct gprs_llc_lle *lle;
uint32_t local_tlli;
@@ -1092,7 +1092,7 @@ int my_gsup_client_send(struct osmo_gsup_client *gsupc, struct msgb *msg)
*/
static void test_gmm_reject(void)
{
- struct gprs_ra_id raid = { 0, };
+ struct osmo_routing_area_id raid = { 0, };
struct sgsn_mm_ctx *ctx = NULL;
uint32_t foreign_tlli;
struct gprs_llc_lle *lle;
@@ -1237,7 +1237,7 @@ static void test_gmm_reject(void)
*/
static void test_gmm_cancel(void)
{
- struct gprs_ra_id raid = { 0, };
+ struct osmo_routing_area_id raid = { 0, };
struct sgsn_mm_ctx *ctx = NULL;
struct sgsn_mm_ctx *ictx;
uint32_t ptmsi1;
@@ -1446,7 +1446,7 @@ static void test_ggsn_selection(void)
struct gprs_subscr *s1;
const char *imsi1 = "1234567890";
struct sgsn_mm_ctx *ctx;
- struct gprs_ra_id raid = { 0, };
+ struct osmo_routing_area_id raid = { 0, };
uint32_t local_tlli = 0xffeeddcc;
enum gsm48_gsm_cause gsm_cause;
struct tlv_parsed tp;
diff --git a/tests/sndcp_xid/Makefile.am b/tests/sndcp_xid/Makefile.am
index c4702b893..08bd27f1e 100644
--- a/tests/sndcp_xid/Makefile.am
+++ b/tests/sndcp_xid/Makefile.am
@@ -10,7 +10,6 @@ sndcp_xid_test_SOURCES = sndcp_xid_test.c
sndcp_xid_test_LDADD = \
$(top_builddir)/src/sgsn/gprs_sndcp_xid.o \
- $(LIBOSMOABIS_LIBS) \
$(LIBOSMOCORE_LIBS) \
$(LIBOSMOGSM_LIBS) \
$(LIBOSMOGB_LIBS) \
diff --git a/tests/vty_test_runner.py b/tests/vty_test_runner.py
index 0b7df8c89..aaa76ed44 100755
--- a/tests/vty_test_runner.py
+++ b/tests/vty_test_runner.py
@@ -70,8 +70,7 @@ class TestVTYBase(unittest.TestCase):
class TestVTYSGSN(TestVTYBase):
def vty_command(self):
- return ["./src/sgsn/osmo-sgsn", "-c",
- "doc/examples/osmo-sgsn/osmo-sgsn-accept-all.cfg"]
+ return ["./src/sgsn/osmo-sgsn", "-c", "tests/osmo-sgsn-accept-all.cfg"]
def vty_app(self):
return (4245, "./src/sgsn/osmo-sgsn", "OsmoSGSN", "sgsn")
diff --git a/tests/xid/Makefile.am b/tests/xid/Makefile.am
index d3a260bca..284e392f9 100644
--- a/tests/xid/Makefile.am
+++ b/tests/xid/Makefile.am
@@ -27,7 +27,6 @@ xid_test_SOURCES = \
xid_test_LDADD = \
$(top_builddir)/src/sgsn/gprs_llc_xid.o \
- $(LIBOSMOABIS_LIBS) \
$(LIBOSMOCORE_LIBS) \
$(LIBOSMOGSM_LIBS) \
$(LIBOSMOGB_LIBS) \