aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--configure.ac1
-rwxr-xr-xcontrib/gprs/gb-proxy-unblock-bug.py58
-rw-r--r--contrib/osmo-sgsn.spec.in22
-rw-r--r--contrib/systemd/Makefile.am2
-rw-r--r--contrib/systemd/osmo-gbproxy.service12
-rw-r--r--debian/control16
-rw-r--r--debian/copyright9
-rwxr-xr-xdebian/osmo-gbproxy.init151
-rw-r--r--debian/osmo-gbproxy.install4
-rwxr-xr-xdebian/rules1
-rw-r--r--doc/examples/Makefile.am2
-rw-r--r--doc/examples/osmo-gbproxy/osmo-gbproxy-legacy.cfg42
-rw-r--r--doc/examples/osmo-gbproxy/osmo-gbproxy-pool.cfg32
-rw-r--r--doc/examples/osmo-gbproxy/osmo-gbproxy.cfg23
-rw-r--r--doc/manuals/Makefile.am8
-rw-r--r--doc/manuals/chapters/gbproxy-configuration.adoc41
-rw-r--r--doc/manuals/chapters/gbproxy-control.adoc29
-rw-r--r--doc/manuals/chapters/gbproxy-details.adoc113
-rw-r--r--doc/manuals/chapters/gbproxy-overview.adoc95
-rw-r--r--doc/manuals/chapters/gbproxy-running.adoc39
-rw-r--r--doc/manuals/chapters/gbproxy-sgsnpool.adoc219
-rw-r--r--doc/manuals/osmogbproxy-usermanual-docinfo.xml46
-rw-r--r--doc/manuals/osmogbproxy-usermanual.adoc36
-rw-r--r--doc/manuals/osmogbproxy-vty-reference.xml38
-rwxr-xr-xdoc/manuals/regen_doc.sh6
-rw-r--r--doc/manuals/vty-osmogbproxy/gbproxy_vty_additions.xml5
-rw-r--r--doc/manuals/vty-osmogbproxy/gbproxy_vty_reference.xml1627
-rw-r--r--include/osmocom/sgsn/Makefile.am1
-rw-r--r--include/osmocom/sgsn/gb_proxy.h298
-rw-r--r--osmoappdesc.py6
-rw-r--r--src/Makefile.am1
-rw-r--r--src/gbproxy/Makefile.am40
-rw-r--r--src/gbproxy/gb_proxy.c1549
-rw-r--r--src/gbproxy/gb_proxy_ctrl.c137
-rw-r--r--src/gbproxy/gb_proxy_main.c336
-rw-r--r--src/gbproxy/gb_proxy_peer.c759
-rw-r--r--src/gbproxy/gb_proxy_vty.c778
-rw-r--r--tests/Makefile.am10
-rw-r--r--tests/osmo-gbproxy-pool_test-nodes.vty35
-rw-r--r--tests/osmo-gbproxy_test-nodes.vty32
-rwxr-xr-xtests/vty_test_runner.py55
42 files changed, 5 insertions, 6710 deletions
diff --git a/.gitignore b/.gitignore
index 466a744c2..3626a5a62 100644
--- a/.gitignore
+++ b/.gitignore
@@ -41,7 +41,6 @@ ltmain.sh
# apps and app data
src/sgsn/osmo-sgsn
-src/gbproxy/osmo-gbproxy
src/gtphub/osmo-gtphub
src/libcommon/gsup_test_client
diff --git a/configure.ac b/configure.ac
index f1a4ed480..947ecf152 100644
--- a/configure.ac
+++ b/configure.ac
@@ -259,7 +259,6 @@ AC_OUTPUT(
src/Makefile
src/gprs/Makefile
src/sgsn/Makefile
- src/gbproxy/Makefile
src/gtphub/Makefile
tests/Makefile
tests/atlocal
diff --git a/contrib/gprs/gb-proxy-unblock-bug.py b/contrib/gprs/gb-proxy-unblock-bug.py
deleted file mode 100755
index 0cd4b871f..000000000
--- a/contrib/gprs/gb-proxy-unblock-bug.py
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/usr/bin/env python
-
-"""
-demonstrate a unblock bug on the GB Proxy..
-"""
-
-bts_ns_reset = "\x02\x00\x81\x01\x01\x82\x1f\xe7\x04\x82\x1f\xe7"
-ns_reset_ack = "\x03\x01\x82\x1f\xe7\x04\x82\x1f\xe7"
-
-bts_ns_unblock = "\x06"
-ns_unblock_ack = "\x07"
-
-bts_bvc_reset_0 = "\x00\x00\x00\x00\x22\x04\x82\x00\x00\x07\x81\x03\x3b\x81\x02"
-ns_bvc_reset_0_ack = "\x00\x00\x00\x00\x23\x04\x82\x00\x00"
-
-bts_bvc_reset_8167 = "\x00\x00\x00\x00\x22\x04\x82\x1f\xe7\x07\x81\x08\x08\x88\x72\xf4\x80\x10\x1c\x00\x9c\x40"
-
-
-import socket
-socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
-socket.bind(("0.0.0.0", 0))
-socket.setblocking(1)
-
-
-import sys
-port = int(sys.argv[1])
-print "Sending data to port: %d" % port
-
-def send_and_receive(packet):
- socket.sendto(packet, ("127.0.0.1", port))
-
- try:
- data, addr = socket.recvfrom(4096)
- except socket.error, e:
- print "ERROR", e
- import sys
- sys.exit(0)
- return data
-
-#send stuff once
-
-to_send = [
- (bts_ns_reset, ns_reset_ack, "reset ack"),
- (bts_ns_unblock, ns_unblock_ack, "unblock ack"),
- (bts_bvc_reset_0, ns_bvc_reset_0_ack, "BVCI=0 reset ack"),
-]
-
-
-for (out, inp, type) in to_send:
- res = send_and_receive(out)
- if res != inp:
- print "Failed to get the %s" % type
- sys.exit(-1)
-
-import time
-time.sleep(3)
-res = send_and_receive(bts_bvc_reset_8167)
-print "Sent all messages... check wireshark for the last response"
diff --git a/contrib/osmo-sgsn.spec.in b/contrib/osmo-sgsn.spec.in
index ca66e2ea9..cd3b5b7bf 100644
--- a/contrib/osmo-sgsn.spec.in
+++ b/contrib/osmo-sgsn.spec.in
@@ -61,14 +61,6 @@ Group: Productivity/Telephony/Servers
%description -n osmo-gtphub
Osmocom GTP Hub: Proxy for GTP traffic between multiple SGSNs and GGSNs.
-%package -n osmo-gbproxy
-Summary: Osmocom GPRS Gb Interface Proxy
-Group: Productivity/Telephony/Servers
-
-%description -n osmo-gbproxy
-The purpose of the Gb proxy is to aggregate the Gb links of multiple
-BSS's and present them in one Gb link to the SGSN.
-
%prep
%setup -q
@@ -95,10 +87,6 @@ make %{?_smp_mflags}
%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
-%preun -n osmo-gbproxy %service_del_preun osmo-gbproxy.service
-%postun -n osmo-gbproxy %service_del_postun osmo-gbproxy.service
-%pre -n osmo-gbproxy %service_add_pre osmo-gbproxy.service
-%post -n osmo-gbproxy %service_add_post osmo-gbproxy.service
%endif
%check
@@ -109,7 +97,6 @@ make %{?_smp_mflags} check || (find . -name testsuite.log -exec cat {} +)
%dir %{_docdir}/%{name}/examples
%dir %{_docdir}/%{name}/examples/osmo-sgsn
%exclude %{_docdir}/%{name}/examples/osmo-gtphub
-%exclude %{_docdir}/%{name}/examples/osmo-gbproxy
%{_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
@@ -128,13 +115,4 @@ make %{?_smp_mflags} check || (find . -name testsuite.log -exec cat {} +)
%config(noreplace) %{_sysconfdir}/osmocom/osmo-gtphub.cfg
%{_unitdir}/osmo-gtphub.service
-%files -n osmo-gbproxy
-%dir %{_docdir}/%{name}/examples
-%dir %{_docdir}/%{name}/examples/osmo-gbproxy
-%{_docdir}/%{name}/examples/osmo-gbproxy/osmo-gbproxy.cfg
-%{_bindir}/osmo-gbproxy
-%dir %{_sysconfdir}/osmocom
-%config(noreplace) %{_sysconfdir}/osmocom/osmo-gbproxy.cfg
-%{_unitdir}/osmo-gbproxy.service
-
%changelog
diff --git a/contrib/systemd/Makefile.am b/contrib/systemd/Makefile.am
index 11e8f9815..ae4694c2a 100644
--- a/contrib/systemd/Makefile.am
+++ b/contrib/systemd/Makefile.am
@@ -1,11 +1,9 @@
EXTRA_DIST = \
- osmo-gbproxy.service \
osmo-gtphub.service \
osmo-sgsn.service
if HAVE_SYSTEMD
SYSTEMD_SERVICES = \
- osmo-gbproxy.service \
osmo-gtphub.service \
osmo-sgsn.service
diff --git a/contrib/systemd/osmo-gbproxy.service b/contrib/systemd/osmo-gbproxy.service
deleted file mode 100644
index a0b7829db..000000000
--- a/contrib/systemd/osmo-gbproxy.service
+++ /dev/null
@@ -1,12 +0,0 @@
-[Unit]
-Description=Osmocom Gb proxy
-
-[Service]
-Type=simple
-ExecStart=/usr/bin/osmo-gbproxy -c /etc/osmocom/osmo-gbproxy.cfg
-Restart=always
-RestartSec=2
-RestartPreventExitStatus=1
-
-[Install]
-WantedBy=multi-user.target
diff --git a/debian/control b/debian/control
index e512c8fb6..fe2f1e63f 100644
--- a/debian/control
+++ b/debian/control
@@ -53,22 +53,6 @@ Priority: extra
Depends: osmo-gtphub (= ${binary:Version}), ${misc:Depends}
Description: Debug symbols for Osmocom GTP Hub
-Package: osmo-gbproxy
-Architecture: any
-Depends: ${shlibs:Depends},
- ${misc:Depends}
-Recommends: osmo-sgsn
-Description: Osmocom GPRS Gb Interface Proxy
- The purpose of the Gb proxy is to aggregate the Gb links of multiple
- BSS's and present them in one Gb link to the SGSN.
-
-Package: osmo-gbproxy-dbg
-Architecture: any
-Section: debug
-Priority: extra
-Depends: osmo-gbproxy (= ${binary:Version}), ${misc:Depends}
-Description: Debug symbols for Osmocom GPRS Gb Interface Proxy
-
Package: osmo-sgsn-doc
Architecture: all
Section: doc
diff --git a/debian/copyright b/debian/copyright
index 5bc764d67..dd7b6672b 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -19,12 +19,10 @@ Files: .gitignore
contrib/ipa.py
contrib/jenkins.sh
contrib/soap.py
- contrib/systemd/osmo-gbproxy.service
contrib/systemd/osmo-sgsn.service
contrib/twisted_ipa.py
doc/Makefile.am
doc/examples/Makefile.am
- doc/examples/osmo-gbproxy/osmo-gbproxy.cfg
doc/examples/osmo-gtphub/gtphub-example.txt
doc/examples/osmo-gtphub/osmo-gtphub-1iface.cfg
doc/examples/osmo-gtphub/osmo-gtphub.cfg
@@ -50,8 +48,6 @@ Files: .gitignore
src/gprs/osmo_sgsn.cfg
tests/Makefile.am
tests/atlocal.in
- tests/gbproxy/Makefile.am
- tests/gbproxy/gbproxy_test.ok
tests/gprs/Makefile.am
tests/gprs/gprs_test.c
tests/gprs/gprs_test.ok
@@ -85,10 +81,6 @@ Files: include/osmocom/sgsn/a_reset.h
src/gprs/gprs_gb_parse.c
src/gprs/gprs_utils.c
src/gprs/sgsn_ares.c
- src/gbproxy/gb_proxy.c
- src/gbproxy/gb_proxy_main.c
- src/gbproxy/gb_proxy_peer.c
- src/gbproxy/gb_proxy_vty.c
src/gtphub/gtphub.c
src/gtphub/gtphub_main.c
src/gtphub/gtphub_vty.c
@@ -139,7 +131,6 @@ License: AGPL-3.0+
Files: src/gtphub/gtphub_ares.c
src/gtphub/gtphub_sock.c
- tests/gbproxy/gbproxy_test.c
Copyright: 2013 Jacob Erlbeck <jerlbeck@sysmocom.de>
2013 sysmocom s.f.m.c. GmbH
2014 Holger Hans Peter Freyther
diff --git a/debian/osmo-gbproxy.init b/debian/osmo-gbproxy.init
deleted file mode 100755
index 924f32d10..000000000
--- a/debian/osmo-gbproxy.init
+++ /dev/null
@@ -1,151 +0,0 @@
-#!/bin/sh
-### BEGIN INIT INFO
-# Provides: osmo-gbproxy
-# Required-Start: $network $local_fs
-# Required-Stop:
-# Default-Start: 2 3 4 5
-# Default-Stop: 0 1 6
-# Short-Description: Osmocom GBproxy
-# Description: A tool to proxy the GPRS Gb interface.
-### END INIT INFO
-
-# Author: Harald Welte <laforge@gnumonks.org>
-
-# PATH should only include /usr/* if it runs after the mountnfs.sh script
-PATH=/sbin:/usr/sbin:/bin:/usr/bin
-NAME=osmo-gbproxy # Introduce the short server's name here
-DESC="Osmocom GBProxy" # Introduce a short description here
-DAEMON=/usr/bin/osmo-gbproxy # Introduce the server's location here
-SCRIPTNAME=/etc/init.d/osmocom-gbproxy
-CONFIG_FILE=/etc/osmocom/osmocom-gbproxy.cfg
-
-# Exit if the package is not installed
-[ -x $DAEMON ] || exit 0
-
-# Read configuration variable file if it is present
-[ -r /etc/default/osmocom-gbproxy ] && . /etc/default/osmocom-gbproxy
-
-# 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="-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/osmo-gbproxy.install b/debian/osmo-gbproxy.install
deleted file mode 100644
index 1cb91d5d4..000000000
--- a/debian/osmo-gbproxy.install
+++ /dev/null
@@ -1,4 +0,0 @@
-etc/osmocom/osmo-gbproxy.cfg
-lib/systemd/system/osmo-gbproxy.service
-usr/bin/osmo-gbproxy
-usr/share/doc/osmo-sgsn/examples/osmo-gbproxy/osmo-gbproxy.cfg usr/share/doc/osmo-gbproxy/examples
diff --git a/debian/rules b/debian/rules
index cfd692a48..24161a190 100755
--- a/debian/rules
+++ b/debian/rules
@@ -58,7 +58,6 @@ override_dh_auto_configure:
override_dh_strip:
dh_strip -posmo-sgsn --dbg-package=osmo-sgsn-dbg
dh_strip -posmo-gtphub --dbg-package=osmo-gtphub-dbg
- dh_strip -posmo-gbproxy --dbg-package=osmo-gbproxy-dbg
# Print test results in case of a failure
override_dh_auto_test:
diff --git a/doc/examples/Makefile.am b/doc/examples/Makefile.am
index 2b5781a59..c725bc1ad 100644
--- a/doc/examples/Makefile.am
+++ b/doc/examples/Makefile.am
@@ -1,7 +1,7 @@
OSMOCONF_FILES = \
osmo-gtphub/osmo-gtphub.cfg \
osmo-sgsn/osmo-sgsn.cfg \
- osmo-gbproxy/osmo-gbproxy.cfg
+ $(NULL)
osmoconfdir = $(sysconfdir)/osmocom
osmoconf_DATA = $(OSMOCONF_FILES)
diff --git a/doc/examples/osmo-gbproxy/osmo-gbproxy-legacy.cfg b/doc/examples/osmo-gbproxy/osmo-gbproxy-legacy.cfg
deleted file mode 100644
index e30b9f7fe..000000000
--- a/doc/examples/osmo-gbproxy/osmo-gbproxy-legacy.cfg
+++ /dev/null
@@ -1,42 +0,0 @@
-!
-! OsmoGbProxy (UNKNOWN) configuration saved from vty
-!!
-!
-log stderr
- logging filter all 1
- logging color 1
- logging timestamp 0
- logging level all debug
- logging level gprs debug
- logging level ns info
- logging level bssgp debug
- logging level lglobal notice
- logging level llapd notice
- logging level linp notice
- logging level lmux notice
- logging level lmi notice
- logging level lmib notice
- logging level lsms notice
-!
-line vty
- no login
-!
-ns
- bind udp local
- listen 127.0.0.1 23000
- accept-ipaccess
- nse 666
- nsvc ipa local 127.0.0.1 23001 nsvci 666
- 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
-gbproxy
- sgsn nsei 666
- core-mobile-country-code 666
- core-mobile-network-code 6
- core-access-point-name none match-imsi ^666066|^66607
- tlli-list max-length 200
diff --git a/doc/examples/osmo-gbproxy/osmo-gbproxy-pool.cfg b/doc/examples/osmo-gbproxy/osmo-gbproxy-pool.cfg
deleted file mode 100644
index bbc8a1b70..000000000
--- a/doc/examples/osmo-gbproxy/osmo-gbproxy-pool.cfg
+++ /dev/null
@@ -1,32 +0,0 @@
-!
-! Osmocom Gb Proxy (0.9.0.404-6463) configuration saved from vty
-!!
-!
-line vty
- no login
-!
-gbproxy
- nri bitlen 4
- nri null add 0 4
-sgsn nsei 101
- name main
- nri add 1
- nri add 11
-sgsn nsei 102
- nri add 2
- nri add 12
-ns
- bind udp local
- listen 127.0.0.100 23000
- accept-ipaccess
- nse 101
- nsvc ipa local 192.168.100.239 7777 nsvci 101
- nse 102
- nsvc ipa local 192.168.100.239 7778 nsvci 102
- 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
diff --git a/doc/examples/osmo-gbproxy/osmo-gbproxy.cfg b/doc/examples/osmo-gbproxy/osmo-gbproxy.cfg
deleted file mode 100644
index 777d0b0f9..000000000
--- a/doc/examples/osmo-gbproxy/osmo-gbproxy.cfg
+++ /dev/null
@@ -1,23 +0,0 @@
-!
-! Osmocom Gb Proxy (0.9.0.404-6463) configuration saved from vty
-!!
-!
-line vty
- no login
-!
-gbproxy
-sgsn nsei 101
- name main
-ns
- bind udp local
- listen 127.0.0.100 23000
- accept-ipaccess
- nse 101
- nsvc ipa local 192.168.100.239 7777 nsvci 101
- 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
diff --git a/doc/manuals/Makefile.am b/doc/manuals/Makefile.am
index cd57cf148..bc3449743 100644
--- a/doc/manuals/Makefile.am
+++ b/doc/manuals/Makefile.am
@@ -1,21 +1,17 @@
EXTRA_DIST = osmosgsn-usermanual.adoc \
osmosgsn-usermanual-docinfo.xml \
osmosgsn-vty-reference.xml \
- osmogbproxy-usermanual.adoc \
- osmogbproxy-usermanual-docinfo.xml \
regen_doc.sh \
chapters \
vty \
- osmogbproxy-vty-reference.xml \
- vty-osmogbproxy \
$(NULL)
if BUILD_MANUALS
- ASCIIDOC = osmosgsn-usermanual.adoc osmogbproxy-usermanual.adoc
+ ASCIIDOC = osmosgsn-usermanual.adoc
ASCIIDOC_DEPS = $(srcdir)/chapters/*.adoc
include $(OSMO_GSM_MANUALS_DIR)/build/Makefile.asciidoc.inc
- VTY_REFERENCE = osmosgsn-vty-reference.xml osmogbproxy-vty-reference.xml
+ VTY_REFERENCE = osmosgsn-vty-reference.xml
include $(OSMO_GSM_MANUALS_DIR)/build/Makefile.vty-reference.inc
OSMO_REPOSITORY = osmo-sgsn
diff --git a/doc/manuals/chapters/gbproxy-configuration.adoc b/doc/manuals/chapters/gbproxy-configuration.adoc
deleted file mode 100644
index 87da471ff..000000000
--- a/doc/manuals/chapters/gbproxy-configuration.adoc
+++ /dev/null
@@ -1,41 +0,0 @@
-== Configuring OsmoGbProxy
-
-OsmoGbProxy requires very little configuration, most of it being the
-configuration of the NS links.
-Most config options specific to OsmoGbProxy are related to SGSN pooling and
-telling the proxy which NSE(s) it should use to talk to the SGSN(s).
-
-=== Configure the Network Service (NS)
-
-A detailed description of the NS configuration can be found in <<libosmogb>>.
-The following config snippets assume the SGSN(s) (NSEI 101 and 102) are using
-IP-SNS and listen on 10.0.1.1:23000 and 10.0.1.2:23000 respectively.
-
-This would be the NS config for the SGSN(s):
-
-.Example: NS configuration example (SGSN)
-----
-ns
- bind udp local
- listen 10.0.0.1 23000 <1>
- nse 101 <2>
- ip-sns 10.0.1.1 23000 <3>
- nse 102
- ip-sns 10.0.1.2 23000
-----
-<1> Define the local IP/port from which to connect
-<2> Define an NSE with NSEI
-<3> Use IP-SNS to connect to the SGSN
-
-=== Configure an SGSN
-
-Configuration of a single (non-pooling) SGSN is rather simple.
-
-.Example: SGSN configuration example
-----
-sgsn 101 <1>
- name Main SGSN <2>
-----
-<1> Each SGSN is identified by its NSEI (same as in the NS configuration)
-<2> An SGSN can optionally have a name. If none is set a default name will be used.
-
diff --git a/doc/manuals/chapters/gbproxy-control.adoc b/doc/manuals/chapters/gbproxy-control.adoc
deleted file mode 100644
index 2f83e6add..000000000
--- a/doc/manuals/chapters/gbproxy-control.adoc
+++ /dev/null
@@ -1,29 +0,0 @@
-[[control]]
-== Control interface
-
-The actual protocol is described in <<common-control-if>>, the variables
-common to all programs using it are described in <<ctrl_common_vars>>. Here we
-describe variables specific to OsmoGbProxy.
-
-.Variables available over control interface
-[options="header",width="100%",cols="20%,5%,5%,50%,20%"]
-|===
-|Name|Access|Trap|Value|Comment
-|nsvc-state|RO|No|"<nsei>,<nsvci>,<local-alive>,<local-blocked>,<remote-role>,<remote-alive>,<remote-blocked>"|See <<nsvc_state>> for details.
-|gbproxy-state|RO|No|"<nsei>,<bvci>,<mcc>,<mnc>,<lac>,<rac>,<blocked>"|See <<gbproxy_state>> for details.
-|number-of-peers|RO|No|"<num-of-bss>"|Count of concurrent BSS(BTS) peers.
-|===
-
-[[nsvc_state]]
-=== nsvc-state
-
-Return the list of active NS-VCs (NS Virtual Circuits), including information
-on the key parameters, such as NSEI, NSVCI and the local + remote ALIVE
-and BLOCKED state.
-
-[[gbproxy_state]]
-=== gbproxy-state
-
-Return the list of active Peers, including information on the key
-parameters, such as NSEI, BVCI, and the MCC-MNC-LAC-RAC of the attached
-BSS, as well as the overall state (BLOCKED or UNBLOCKED).
diff --git a/doc/manuals/chapters/gbproxy-details.adoc b/doc/manuals/chapters/gbproxy-details.adoc
deleted file mode 100644
index f77d40cf9..000000000
--- a/doc/manuals/chapters/gbproxy-details.adoc
+++ /dev/null
@@ -1,113 +0,0 @@
-[[chapter_details]]
-== Proxy details
-
-=== BVC handling
-
-This section describes in more detail how BVCs are handled in OsmoGbProxy
-
-If a BSS connects to OsmoGbProxy while the SGSN is not available it will
-acknowledge the BVC RESET on the signalling BVC, but ignore other messages
-(especially any PTP BVC RESET).
-
-.BSS connects to OsmoGbProxy
-[mscgen]
-----
-msc {
- hscale="1.8";
- bss1 [label="BSS1"], bss2 [label="BSS2"], gbproxy [label="GbProxy"], sgsn [label="SGSN"];
- bss1 <=> gbproxy [label="NS link available"];
- bss1 => gbproxy [label="BVC RESET (BVCI=0)"];
- gbproxy => bss1 [label="BVC RESET ACK"];
- bss1 -x gbproxy [label="PTP BVC RESET (ignored)"];
-}
-----
-
-As soon as the SGSN is reachable through NS OsmoGbProxy will send a BVC RESET
-to the signalling BVC towards the SGSN. After that completes it will reset the
-signalling BVC of all BSS connections. At this point the BSS will send a BVC
-RESET for its PTP BVCs which will be forwarded to the SGSN, similarly the PTP
-BVC RESET ACK from the SGSN will be sent back to the BSS.
-
-.SGSN connection to OsmoGbProxy
-[mscgen]
-----
-msc {
- hscale="1.8";
- bss1 [label="BSS1"], bss2 [label="BSS2"], gbproxy [label="GbProxy"], sgsn [label="SGSN"];
- gbproxy <=> sgsn [label="NS link available"];
- gbproxy => sgsn [label="BVC RESET (BVCI=0)"];
- sgsn => gbproxy [label="BVC RESET ACK"];
-
- gbproxy => bss1 [label="BVC RESET (BVCI=0)"];
- bss1 => gbproxy [label="BVC RESET ACK"];
- bss1 box bss1 [label="PTP BVCs need to be reset"];
- bss1 => gbproxy [label="PTP BVC RESET (BVCI=x)"];
- gbproxy => sgsn [label="PTP BVC RESET (BVCI=x)"];
- sgsn => gbproxy [label="PTP BVC RESET ACK (BVCI=x)"];
- gbproxy => bss1 [label="PTP BVC RESET ACK (BVCI=x)"];
- bss2 <=> sgsn [label="BVCI x established"];
-}
-----
-
-The communication on the PTP BVC will then be forwarded between the BSS and the
-SGSN.
-
-If a BSS connects while the SGSN is up the PTP BVC RESET will directly be
-forwarded.
-
-.BSS connects to OsmoGbProxy
-[mscgen]
-----
-msc {
- hscale="1.8";
- bss1 [label="BSS1"], bss2 [label="BSS2"], gbproxy [label="GbProxy"], sgsn [label="SGSN"];
- bss2 <=> gbproxy [label="NS link available"];
- bss2 => gbproxy [label="BVC RESET (BVCI=0)"];
- gbproxy => bss2 [label="BVC RESET ACK"];
- bss2 => gbproxy [label="PTP BVC RESET (BVCI=y)"];
- gbproxy => sgsn [label="PTP BVC RESET (BVCI=y)"];
- sgsn => gbproxy [label="PTP BVC RESET ACK (BVCI=y)"];
- gbproxy => bss2 [label="PTP BVC RESET ACK (BVCI=y)"];
- bss2 <=> sgsn [label="BVCI y established"];
-}
-----
-
-If OsmoGbProxy looses the connection to the SGSN it will reset the signalling
-BVC of all BSS connections. This ensures that the BSS will not send traffic
-over a PTP BVC before its reset procedure has been completed.
-
-.SGSN connection fails
-[mscgen]
-----
-msc {
- hscale="1.8";
- bss1 [label="BSS1"], bss2 [label="BSS2"], gbproxy [label="GbProxy"], sgsn [label="SGSN"];
- gbproxy <=> sgsn [label="NS link fails"];
- gbproxy => bss1 [label="BVC RESET (BVCI=0)"];
- gbproxy => bss2 [label="BVC RESET (BVCI=0)"];
-}
-----
-
-When the connection to the SGSN is eventually restored the signalling BVC
-between OsmoGbProxy and SGSN will be reset.
-
-After that completes OsmoGbProxy will reset the signalling BVC on all BSS NS
-connections and forward the PTP BVC RESET messages.
-
-.SGSN connection restored
-[mscgen]
-----
-msc {
- hscale="1.8";
- bss1 [label="BSS1"], bss2 [label="BSS2"], gbproxy [label="GbProxy"], sgsn [label="SGSN"];
- gbproxy <=> sgsn [label="NS link available"];
- gbproxy => sgsn [label="BVC RESET (BVCI=0)"];
- sgsn => gbproxy [label="BVC RESET ACK"];
- gbproxy => bss1 [label="BVC RESET (BVCI=0)"];
- bss1 => gbproxy [label="BVC RESET ACK"];
- bss1 box bss1 [label="PTP BVCs need to be reset"];
- gbproxy => bss2 [label="BVC RESET (BVCI=0)"];
- bss2 => gbproxy [label="BVC RESET ACK"];
- bss2 box bss2 [label="PTP BVCs need to be reset"];
-}
-----
diff --git a/doc/manuals/chapters/gbproxy-overview.adoc b/doc/manuals/chapters/gbproxy-overview.adoc
deleted file mode 100644
index 3cd0d73c8..000000000
--- a/doc/manuals/chapters/gbproxy-overview.adoc
+++ /dev/null
@@ -1,95 +0,0 @@
-[[chapter_overview]]
-== Overview
-
-IMPORTANT: If you have used an earlier version of OsmoGbProxy please note
-that support for various features such as PLMN/APN patching, support for a
-secondary SGSN has been removed.
-
-=== About OsmoGbProxy
-
-OsmoGbProxy is the Osmocom proxy for the 3GPP Gb interface. The Gb
-interface is defined by 3GPP as the protocol between the BSS and the
-SGSN inside the 2G/2.5G/2.75G packet switched network domain.
-
-As Osmocom implements a BTS-colocated PCU, there are potentially many
-Gb interface connections between all those many PCUs in the network
-and the SGSN. This can be cumbersome to configure/maintain at the
-SGSN side.
-
-OsmoGbProxy aggregates many PCU-facing Gb connections into one Gb
-connection to the SGSN. This is achieved by
-
-* maintaining separate NS-VCs on the PCU side and on the SGSN side
-* more or less transparently routing BSSGP peer-to-peer Virtual Circuits
- (BVCs) through the proxy
-* having some special handling for the signaling BVC (BVCI=0) which is
- shared among all the PCUs connected to the proxy
-
-
-=== Data Model
-
-==== gbproxy_config
-
-This contains the parsed configuration of the OsmoGbProxy.
-
-==== gbproxy_nse
-
-The remote NS-entity that the proxy interacts with. Includes
-information about:
-
-* the [unique] NSEI of the peer
-* the Routeing Area (RA) of the peer
-* which side this NSE is facing - SGSN or BSS
-* the list of BVCs in this NSE
-
-==== gbproxy_bvc
-
-A ptp-BVC on an NSE
-
-* the BVCI of this BVC
-* the routing area of this BVC
-* the BVC state machine
-
-==== gbproxy_cell
-
-This contains a view of the cell and its associated BVCs
-
-* the unique BVCI of this cell
-* the routing area of this cell
-* one bss-side BVC
-* one BVC per SGSN in the pool
-
-==== gbproxy_sgsn
-
-Represents one SGSN in the pool. Contains:
-
-* the NSE belonging to this SGSN
-* a (configurable) name of the SGSN
-* pool-related configuration of the SGSNs
-
-==== IMSI cache
-
-In order to route messages to the correct BSS or SGSN OsmoGbProxy
-sometimes needs to cache where messages came from.
-
-In BSS->SGSN direction the IMSI-cache is needed for
-
-* paging ps reject
-* dummy paging response
-
-when SGSN-pooling is enabled and multiple SGSNs are configured. The IMSI
-contained in a paging ps or dummy paging message is cached together with
-the originating SGSN/NSE. The answer, which also contains the IMSI, is
-then routed back to the original SGSN.
-
-==== TLLI cache
-
-In SGSN->BSS direction OsmoGbProxy needs a TLLI cache to correctly route the
-following messages:
-
-* suspend ack/nack
-* resume ack/nack
-
-Suspend/resume are sent over the signalling BVC to the SGSN. OsmoGbProxy saves
-the TLLI->NSE association in the TLLI cache and routes the ack/nack back to
-the signalling BVC of the originating NSE. \ No newline at end of file
diff --git a/doc/manuals/chapters/gbproxy-running.adoc b/doc/manuals/chapters/gbproxy-running.adoc
deleted file mode 100644
index 1f6b6a1bb..000000000
--- a/doc/manuals/chapters/gbproxy-running.adoc
+++ /dev/null
@@ -1,39 +0,0 @@
-== Running OsmoGbProxy
-
-The OsmoGbProxy executable (`osmo-gbproxy`) offers the following command-line
-options:
-
-
-=== SYNOPSIS
-
-*osmo-gbproxy* [-h|-V] [-d 'DBGMASK'] [-D] [-c 'CONFIGFILE'] [-s] [-e 'LOGLEVEL'] [-T]
-
-
-=== OPTIONS
-
-*-h, --help*::
- Print a short help message about the supported options
-*-V, --version*::
- Print the compile-time version number of the program
-*-d, --debug 'DBGMASK','DBGLEVELS'*::
- Set the log subsystems and levels for logging to stderr. This
- has mostly been superseded by VTY-based logging configuration,
- see <<logging>> for further information.
-*-D, --daemonize*::
- Fork the process as a daemon into background.
-*-c, --config-file 'CONFIGFILE'*::
- Specify the file and path name of the configuration file to be
- used. If none is specified, use `osmo_sgsn.cfg` in the current
- working directory.
-*-s, --disable-color*::
- Disable colors for logging to stderr. This has mostly been
- deprecated by VTY based logging configuration, see <<logging>>
- for more information.
-*-e, --log-level 'LOGLEVEL'*::
- Set the global log level for logging to stderr. This has mostly
- been deprecated by VTY based logging configuration, see
- <<logging>> for more information.
-*-T, --timestamp*::
- Enable prefixing each log line on stderr with a timestamp. This
- has mostly been deprecated by VTY based logging configuration, see
- <<logging>> for more information.
diff --git a/doc/manuals/chapters/gbproxy-sgsnpool.adoc b/doc/manuals/chapters/gbproxy-sgsnpool.adoc
deleted file mode 100644
index 61806af8c..000000000
--- a/doc/manuals/chapters/gbproxy-sgsnpool.adoc
+++ /dev/null
@@ -1,219 +0,0 @@
-== SGSN Pooling
-
-SGSN pooling is described in 3GPP TS 23.236 <<3gpp-ts-23-236>>, and is supported
-by OsmoGbProxy since early 2021.
-
-The aim of SGSN pooling is to distribute load from a BSS across multiple SGSNs,
-which are equivalent and redundant infrastructure for the same core network.
-
-The main mechanism for SGSN pooling is the TLLI/P-TMSI, which an SGSN hands out
-to its attached subscribers. Typically 10 bits of the P-TMSI are designated as a
-Network Resource Identifier (NRI) that identifies the originating SGSN, and
-allows OsmoGbProxy to direct a subscriber back to the same SGSN instance that
-previously negotiated the Attach procedure. Typically, the full NRI value
-range available is divided into N even ranges, where each SGSN is assigned one
-NRI range.
-
-Subscribers attaching without a TLLI, or those with unknown NRI value,
-are evenly distributed across SGSN instances. OsmoGbProxy uses a hash-based
-approach to distribute load across all connected SGSNs.
-
-A Paging Response from a subscriber is always returned back to whichever SGSN
-initiated the Paging, regardless of the Mobile Identity used.
-
-Finally, a NULL-NRI is a special NRI value that indicates that the SGSN wishes
-to offload this subscriber to a different SGSN. A NULL-NRI is an arbitrary NRI
-value that is chosen distinctly for each PLMN served by a BSS, so that a
-subscriber can be reassigned within that PLMN. Upon (periodic) Location
-Updating, an offloading SGSN hands out a NULL-NRI value in the assigned TLLI,
-along with a non-broadcast LAI. The subscriber will notice the LAI mismatch,
-and immediately re-attempt the attach using the TLLI containing the NULL-NRI.
-OsmoGbProxy recognises the NULL-NRI and redirects the subscriber to one of the
-other SGSNs. A prerequisite for this to work well is that the particular SGSN is
-previously marked as not accepting new subscribers, in OsmoGbProxy's configuration.
-
-The mechanisms described above make up the NAS node selection function
-implemented in OsmoGbProxy.
-
-3GPP TS 23.236 also defines that an offloading SGSN hands subscriber information
-to the newly assigned SGSN, which takes place outside the scope of OsmoGbProxy.
-
-=== Configuring SGSN Pooling
-
-The NRI ranges assigned to each SGSN must match in the OsmoGbProxy and the SGSN
-configuration. If inconsistent NRI value ranges are configured,
-attached subscribers would be redirected to SGSN instances that did not perform the
-attach, possibly rendering the core network unusable.
-
-==== Connecting Multiple SGSNs
-
-----
-# Configure the Network Service
-ns
- bind udp sgsn
- listen 10.0.0.1 23000
- nse 1
- ip-sns 10.0.1.1 23000
- ip-sns 10.0.1.1 23001
- nse 2
- ip-sns 10.0.1.2 23000
- nse 3
- ip-sns 10.0.1.3 23000
-# configure NRI value ranges
-gbproxy
- nri bitlen 10
- nri null add 0
-sgsn 1
- nri add 1 341
-sgsn 2
- nri add 342 682
-sgsn 3
- nri add 683 1023
-----
-
-==== NRI Value Bit Length
-
-In OsmGbProxy, the NRI value's bit length is freely configurable from 0 to 15
-bits. 3GPP TS 23.236 suggests a typical bit length of 10. Setting the length
-to 0 disables SGSN pooling, this is also the default.
-The NRI bit length must be identical across the entire SGSN pool.
-
-Change the NRI value bit length in OsmoGbProxy's VTY configuration like this:
-
-----
-gbproxy
- nri bitlen 10
-----
-
-In the TMSI bits, regardless of the NRI bit length, the NRI value always starts
-just after the most significant octet of a TMSI (most significant bit at TMSI's
-bit 23).
-
-==== NULL-NRI
-
-Since OsmoGbProxy supports serving only one PLMN, NULL-NRI are configured globally.
-Even though 3GPP TS 23.236 indicates that there is a single NULL-NRI per PLMN,
-OsmoGbProxy allows configuring multiple NULL-NRI values.
-
-----
-network
- nri null add 0
- nri null add 423
-----
-
-==== Assigning NRI Ranges to SGSNs
-
-Each SGSN configured in OsmoGbProxy must be assigned a distinct NRI value range.
-Overlapping NRI value ranges will cause failure to serve subscribers.
-
-NRI values are typically configured in ranges, here dividing a 10bit range
-(0..1023) into three equal ranges, while leaving 0 available to be configured
-as NULL-NRI:
-
-----
-sgsn nsei 1
- nri add 1 341
-sgsn nsei 2
- nri add 342 684
-sgsn nsei 3
- nri add 685 1023
-----
-
-NRI can also be assigned in single values:
-
-----
-sgsn nsei 1
- nri add 23
-----
-
-Ranges can be constructed arbitrarily by a sequence of `add` and `del`
-configurations, here a contrived example:
-
-----
-sgsn nsei 1
- nri add 0 342
- nri del 23
- nri del 42 235
- nri add 1000 1023
-----
-
-On the VIEW and ENABLE VTY nodes, `show nri all` shows all SGSNs:
-
-----
-OsmoGbProxy> show nri all
-sgsn nsei 1
- nri add 1 341
-sgsn nsei 2
- nri add 342 684
-sgsn nsei 3
- nri add 685 1023
-----
-
-When configuring overlapping NRI value ranges across SGSNs, the telnet VTY warns
-about it, and starting OsmoGbProxy with such a configuration will fail:
-
-----
-sgsn nsei 1
- nri add 1 511
-sgsn nsei 2
- nri add 512 1023
-sgsn nsei 3
- nri add 500 555
-----
-
-This results in:
-
-----
-$ osmo-gbproxy
-% Warning: NSE(00003/SGSN): NRI range [500..555] overlaps between NSE 00003 and NSE 00001. For overlaps, NSE 00001 has higher priority than NSE 00003
-% Warning: NSE(00003/SGSN): NRI range [500..555] overlaps between NSE 00003 and NSE 00002. For overlaps, NSE 00002 has higher priority than NSE 00003
-----
-
-==== SGSN Offloading
-
-To effectively offload a particular SGSN, it must be marked as no longer taking
-new subscribers in OsmoGbProxy. This can be achieved in the telnet VTY by:
-
-----
-sgsn nsei 1
- no allow-attach
-----
-
-This SGSN will, as long as it is connected, continue to serve subscribers
-already attached to it: those that yield an NRI matching this SGSN, and those
-that are being paged by this SGSN. But OsmoGbProxy will no longer direct new
-subscribers to this SGSN.
-
-TODO: Is paging response relevant for SGSN?
-
-To re-enable an SGSN for attaching new subscribers:
-
-----
-sgsn nsei 1
- allow-attach
-----
-
-==== Traffic allocation
-
-In a SGSN pool, osmo-gbproxy is facing the problem of dividing the downlink
-capacity of a cell towards the SGSN. The BSS advertises the per-BVC capacity
-by means of the BSSGP FLOW-CONTROL-BVC messages, but as there are multiple
-SGSN in a pool, they all have to share / divide that total capacity.
-
-By default, osmo-gbproxy advertises the full capacity to _each_ of the SGSN
-pool members, which results in significant over-provisioning and can lead to
-overload situations.
-
-The administrator can configure the _percentage_ of the overall BSS-advertised
-capacity that shall be reported to each pool member SGSN using the
-`pool bvc-flow-control-ratio <1-100>` configuration command.
-
-A setting of 100 means that each pool member is informed of 100% of the
-BSS side capacity.
-
-A setting of 25 means that each pool member is informed of 25% of the
-BSS side capacity. This would make most sense in a set-up with four
-SGSN of equal share.
-
-More complex capacity division schemes are so far not supported by
-osmo-gbproxy.
diff --git a/doc/manuals/osmogbproxy-usermanual-docinfo.xml b/doc/manuals/osmogbproxy-usermanual-docinfo.xml
deleted file mode 100644
index 29bb2aa74..000000000
--- a/doc/manuals/osmogbproxy-usermanual-docinfo.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<revhistory>
- <revision>
- <revnumber>1</revnumber>
- <date>March 21, 2019</date>
- <authorinitials>HW</authorinitials>
- <revremark>
- Initial version.
- </revremark>
- </revision>
-</revhistory>
-
-<authorgroup>
- <author>
- <firstname>Harald</firstname>
- <surname>Welte</surname>
- <email>hwelte@sysmocom.de</email>
- <authorinitials>HW</authorinitials>
- <affiliation>
- <shortaffil>sysmocom</shortaffil>
- <orgname>sysmocom - s.f.m.c. GmbH</orgname>
- <jobtitle>Managing Director</jobtitle>
- </affiliation>
- </author>
-</authorgroup>
-
-<copyright>
- <year>2013-2019</year>
- <holder>sysmocom - s.f.m.c. GmbH</holder>
-</copyright>
-
-<legalnotice>
- <para>
- Permission is granted to copy, distribute and/or modify this
- document under the terms of the GNU Free Documentation License,
- Version 1.3 or any later version published by the Free Software
- Foundation; with no Invariant Sections, no Front-Cover Texts,
- and no Back-Cover Texts. A copy of the license is included in
- the section entitled "GNU Free Documentation License".
- </para>
- <para>
- The Asciidoc source code of this manual can be found at
- <ulink url="https://git.osmocom.org/osmo-sgsn/doc/">
- https://git.osmocom.org/osmo-sgsn/doc/
- </ulink>
- </para>
-</legalnotice>
diff --git a/doc/manuals/osmogbproxy-usermanual.adoc b/doc/manuals/osmogbproxy-usermanual.adoc
deleted file mode 100644
index d19bdd4af..000000000
--- a/doc/manuals/osmogbproxy-usermanual.adoc
+++ /dev/null
@@ -1,36 +0,0 @@
-:gfdl-enabled:
-
-OsmoGbProxy User Manual
-=======================
-Harald Welte <hwelte@sysmocom.de>
-
-
-include::./common/chapters/preface.adoc[]
-
-include::{srcdir}/chapters/gbproxy-overview.adoc[]
-
-include::{srcdir}/chapters/gbproxy-details.adoc[]
-
-include::{srcdir}/chapters/gbproxy-running.adoc[]
-
-include::{srcdir}/chapters/gbproxy-control.adoc[]
-
-include::./common/chapters/vty.adoc[]
-
-include::./common/chapters/logging.adoc[]
-
-include::{srcdir}/chapters/gbproxy-configuration.adoc[]
-
-include::./common/chapters/gb.adoc[]
-
-include::./common/chapters/control_if.adoc[]
-
-//include::{srcdir}/chapters/counters.adoc[]
-
-include::./common/chapters/port_numbers.adoc[]
-
-include::./common/chapters/bibliography.adoc[]
-
-include::./common/chapters/glossary.adoc[]
-
-include::./common/chapters/gfdl.adoc[]
diff --git a/doc/manuals/osmogbproxy-vty-reference.xml b/doc/manuals/osmogbproxy-vty-reference.xml
deleted file mode 100644
index ecf226808..000000000
--- a/doc/manuals/osmogbproxy-vty-reference.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ex:ts=2:sw=42sts=2:et
- -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
--->
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML 5.0//EN"
-"http://docbook.org/xml/5.0/dtd/docbook.dtd" [
-<!ENTITY chapter-vty SYSTEM "./common/chapters/vty.xml" >
-<!ENTITY sections-vty SYSTEM "generated/docbook_osmogbproxy-vty-reference.xml" >
-]>
-
-<book>
- <info>
- <revhistory>
- <revision>
- <revnumber>v1</revnumber>
- <date>2nd December 2019</date>
- <authorinitials>hw</authorinitials>
- <revremark>Initial</revremark>
- </revision>
- </revhistory>
-
- <title>OsmoGbProxy VTY Reference</title>
-
- <copyright>
- <year>2019</year>
- </copyright>
-
- <legalnotice>
- <para>This work is copyright by <orgname>sysmocom - s.f.m.c. GmbH</orgname>. All rights reserved.
- </para>
- </legalnotice>
- </info>
-
- <!-- Main chapters-->
- &chapter-vty;
-</book>
-
diff --git a/doc/manuals/regen_doc.sh b/doc/manuals/regen_doc.sh
index 847b764aa..9fcebb8b4 100755
--- a/doc/manuals/regen_doc.sh
+++ b/doc/manuals/regen_doc.sh
@@ -62,12 +62,6 @@ interact_vty \
osmo-sgsn -c "../examples/osmo-sgsn/osmo-sgsn.cfg"
interact_vty \
- "update_vty_reference" \
- "vty-osmogbproxy/gbproxy_vty_reference.xml" \
- 4246 \
- osmo-gbproxy -c "../examples/osmo-gbproxy/osmo-gbproxy.cfg"
-
-interact_vty \
"update_counters" \
"chapters/counters_generated.adoc" \
4245 \
diff --git a/doc/manuals/vty-osmogbproxy/gbproxy_vty_additions.xml b/doc/manuals/vty-osmogbproxy/gbproxy_vty_additions.xml
deleted file mode 100644
index 6da2d2f2f..000000000
--- a/doc/manuals/vty-osmogbproxy/gbproxy_vty_additions.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<vtydoc xmlns='urn:osmocom:xml:libosmocore:vty:doc:1.0'>
- <node id='config-gbproxy'>
- <description>Configure the Gb proxy</description>
- </node>
-</vtydoc>
diff --git a/doc/manuals/vty-osmogbproxy/gbproxy_vty_reference.xml b/doc/manuals/vty-osmogbproxy/gbproxy_vty_reference.xml
deleted file mode 100644
index 1db3c0d2f..000000000
--- a/doc/manuals/vty-osmogbproxy/gbproxy_vty_reference.xml
+++ /dev/null
@@ -1,1627 +0,0 @@
-<vtydoc xmlns='urn:osmocom:xml:libosmocore:vty:doc:1.0'>
- <node id='_common_cmds_'>
- <name>Common Commands</name>
- <description>These commands are available on all VTY nodes. They are listed here only once, to unclutter the VTY reference.</description>
- <command id='help'>
- <params>
- <param name='help' doc='Description of the interactive help system' />
- </params>
- </command>
- <command id='list'>
- <params>
- <param name='list' doc='Print command list' />
- </params>
- </command>
- <command id='write terminal'>
- <params>
- <param name='write' doc='Write running configuration to memory, network, or terminal' />
- <param name='terminal' doc='Write to terminal' />
- </params>
- </command>
- <command id='write file [PATH]'>
- <params>
- <param name='write' doc='Write running configuration to memory, network, or terminal' />
- <param name='file' doc='Write to configuration file' />
- <param name='[PATH]' doc='Set file path to store the config, or replace if already exists' />
- </params>
- </command>
- <command id='write memory'>
- <params>
- <param name='write' doc='Write running configuration to memory, network, or terminal' />
- <param name='memory' doc='Write configuration to the file (same as write file)' />
- </params>
- </command>
- <command id='write'>
- <params>
- <param name='write' doc='Write running configuration to memory, network, or terminal' />
- </params>
- </command>
- <command id='show running-config'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='running-config' doc='running configuration' />
- </params>
- </command>
- <command id='exit'>
- <params>
- <param name='exit' doc='Exit current mode and down to previous mode' />
- </params>
- </command>
- <command id='end'>
- <params>
- <param name='end' doc='End current mode and change to enable mode.' />
- </params>
- </command>
- </node>
- <node id='view'>
- <name>view</name>
- <command id='show version'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='version' doc='Displays program version' />
- </params>
- </command>
- <command id='show online-help'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='online-help' doc='Online help' />
- </params>
- </command>
- <command id='enable'>
- <params>
- <param name='enable' doc='Turn on privileged mode command' />
- </params>
- </command>
- <command id='terminal length &lt;0-512&gt;'>
- <params>
- <param name='terminal' doc='Set terminal line parameters' />
- <param name='length' doc='Set number of lines on a screen' />
- <param name='&lt;0-512&gt;' doc='Number of lines on screen (0 for no pausing)' />
- </params>
- </command>
- <command id='terminal no length'>
- <params>
- <param name='terminal' doc='Set terminal line parameters' />
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='length' doc='Set number of lines on a screen' />
- </params>
- </command>
- <command id='who'>
- <params>
- <param name='who' doc='Display who is on vty' />
- </params>
- </command>
- <command id='show history'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='history' doc='Display the session command history' />
- </params>
- </command>
- <command id='logging enable'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='enable' doc='Enables logging to this vty' />
- </params>
- </command>
- <command id='logging disable'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='disable' doc='Disables logging to this vty' />
- </params>
- </command>
- <command id='logging filter all (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='filter' doc='Filter log messages' />
- <param name='all' doc='Do you want to log all messages?' />
- <param name='0' doc='Only print messages matched by other filters' />
- <param name='1' doc='Bypass filter and print all messages' />
- </params>
- </command>
- <command id='logging color (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='color' doc='Configure color-printing for log messages' />
- <param name='0' doc='Don&apos;t use color for printing messages' />
- <param name='1' doc='Use color for printing messages' />
- </params>
- </command>
- <command id='logging timestamp (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='timestamp' doc='Configure log message timestamping' />
- <param name='0' doc='Don&apos;t prefix each log message' />
- <param name='1' doc='Prefix each log message with current timestamp' />
- </params>
- </command>
- <command id='logging print extended-timestamp (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='print' doc='Log output settings' />
- <param name='extended-timestamp' doc='Configure log message timestamping' />
- <param name='0' doc='Don&apos;t prefix each log message' />
- <param name='1' doc='Prefix each log message with current timestamp with YYYYMMDDhhmmssnnn' />
- </params>
- </command>
- <command id='logging print category (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='print' doc='Log output settings' />
- <param name='category' doc='Configure log message' />
- <param name='0' doc='Don&apos;t prefix each log message' />
- <param name='1' doc='Prefix each log message with category/subsystem name' />
- </params>
- </command>
- <command id='logging print category-hex (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='print' doc='Log output settings' />
- <param name='category-hex' doc='Configure log message' />
- <param name='0' doc='Don&apos;t prefix each log message' />
- <param name='1' doc='Prefix each log message with category/subsystem nr in hex (&apos;&lt;000b&gt;&apos;)' />
- </params>
- </command>
- <command id='logging print level (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='print' doc='Log output settings' />
- <param name='level' doc='Configure log message' />
- <param name='0' doc='Don&apos;t prefix each log message' />
- <param name='1' doc='Prefix each log message with the log level name' />
- </params>
- </command>
- <command id='logging print file (0|1|basename) [last]'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='print' doc='Log output settings' />
- <param name='file' doc='Configure log message' />
- <param name='0' doc='Don&apos;t prefix each log message' />
- <param name='1' doc='Prefix each log message with the source file and line' />
- <param name='basename' doc='Prefix each log message with the source file&apos;s basename (strip leading paths) and line' />
- <param name='[last]' doc='Log source file info at the end of a log line. If omitted, log source file info just before the log text.' />
- </params>
- </command>
- <command id='logging set-log-mask MASK'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='set-log-mask' doc='Set the logmask of this logging target' />
- <param name='MASK' doc='List of logging categories to log, e.g. &apos;abc:mno:xyz&apos;. Available log categories depend on the specific application, refer to the &apos;logging level&apos; command. Optionally add individual log levels like &apos;abc,1:mno,3:xyz,5&apos;, where the level numbers are LOGL_DEBUG=1 LOGL_INFO=3 LOGL_NOTICE=5 LOGL_ERROR=7 LOGL_FATAL=8' />
- </params>
- </command>
- <command id='logging level (|gprs|ns|bssgp|lglobal|llapd|linp|lmux|lmi|lmib|lsms|lctrl|lgtp|lstats|lgsup|loap|lss7|lsccp|lsua|lm3ua|lmgcp|ljibuf|lrspro) (debug|info|notice|error|fatal)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='level' doc='Set the log level for a specified category' />
- <param name='gprs' doc='GPRS Packet Service' />
- <param name='ns' doc='GPRS Network Service (NS)' />
- <param name='bssgp' doc='GPRS BSS Gateway Protocol (BSSGP)' />
- <param name='lglobal' doc='Library-internal global log family' />
- <param name='llapd' doc='LAPD in libosmogsm' />
- <param name='linp' doc='A-bis Intput Subsystem' />
- <param name='lmux' doc='A-bis B-Subchannel TRAU Frame Multiplex' />
- <param name='lmi' doc='A-bis Input Driver for Signalling' />
- <param name='lmib' doc='A-bis Input Driver for B-Channels (voice)' />
- <param name='lsms' doc='Layer3 Short Message Service (SMS)' />
- <param name='lctrl' doc='Control Interface' />
- <param name='lgtp' doc='GPRS GTP library' />
- <param name='lstats' doc='Statistics messages and logging' />
- <param name='lgsup' doc='Generic Subscriber Update Protocol' />
- <param name='loap' doc='Osmocom Authentication Protocol' />
- <param name='lss7' doc='libosmo-sigtran Signalling System 7' />
- <param name='lsccp' doc='libosmo-sigtran SCCP Implementation' />
- <param name='lsua' doc='libosmo-sigtran SCCP User Adaptation' />
- <param name='lm3ua' doc='libosmo-sigtran MTP3 User Adaptation' />
- <param name='lmgcp' doc='libosmo-mgcp Media Gateway Control Protocol' />
- <param name='ljibuf' doc='libosmo-netif Jitter Buffer' />
- <param name='lrspro' doc='Remote SIM protocol' />
- <param name='debug' doc='Log debug messages and higher levels' />
- <param name='info' doc='Log informational messages and higher levels' />
- <param name='notice' doc='Log noticeable messages and higher levels' />
- <param name='error' doc='Log error messages and higher levels' />
- <param name='fatal' doc='Log only fatal messages' />
- </params>
- </command>
- <command id='logging level set-all (debug|info|notice|error|fatal)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='level' doc='Set the log level for a specified category' />
- <param name='set-all' doc='Once-off set all categories to the given log level. There is no single command to take back these changes -- each category is set to the given level, period.' />
- <param name='debug' doc='Log debug messages and higher levels' />
- <param name='info' doc='Log informational messages and higher levels' />
- <param name='notice' doc='Log noticeable messages and higher levels' />
- <param name='error' doc='Log error messages and higher levels' />
- <param name='fatal' doc='Log only fatal messages' />
- </params>
- </command>
- <command id='logging level force-all (debug|info|notice|error|fatal)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='level' doc='Set the log level for a specified category' />
- <param name='force-all' doc='Globally force all logging categories to a specific level. This is released by the &apos;no logging level force-all&apos; command. Note: any &apos;logging level &lt;category&gt; &lt;level&gt;&apos; commands will have no visible effect after this, until the forced level is released.' />
- <param name='debug' doc='Log debug messages and higher levels' />
- <param name='info' doc='Log informational messages and higher levels' />
- <param name='notice' doc='Log noticeable messages and higher levels' />
- <param name='error' doc='Log error messages and higher levels' />
- <param name='fatal' doc='Log only fatal messages' />
- </params>
- </command>
- <command id='no logging level force-all'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='logging' doc='Configure logging' />
- <param name='level' doc='Set the log level for a specified category' />
- <param name='force-all' doc='Release any globally forced log level set with &apos;logging level force-all &lt;level&gt;&apos;' />
- </params>
- </command>
- <command id='logp (|gprs|ns|bssgp|lglobal|llapd|linp|lmux|lmi|lmib|lsms|lctrl|lgtp|lstats|lgsup|loap|lss7|lsccp|lsua|lm3ua|lmgcp|ljibuf|lrspro) (debug|info|notice|error|fatal) .LOGMESSAGE'>
- <params>
- <param name='logp' doc='Print a message on all log outputs; useful for placing markers in test logs' />
- <param name='gprs' doc='GPRS Packet Service' />
- <param name='ns' doc='GPRS Network Service (NS)' />
- <param name='bssgp' doc='GPRS BSS Gateway Protocol (BSSGP)' />
- <param name='lglobal' doc='Library-internal global log family' />
- <param name='llapd' doc='LAPD in libosmogsm' />
- <param name='linp' doc='A-bis Intput Subsystem' />
- <param name='lmux' doc='A-bis B-Subchannel TRAU Frame Multiplex' />
- <param name='lmi' doc='A-bis Input Driver for Signalling' />
- <param name='lmib' doc='A-bis Input Driver for B-Channels (voice)' />
- <param name='lsms' doc='Layer3 Short Message Service (SMS)' />
- <param name='lctrl' doc='Control Interface' />
- <param name='lgtp' doc='GPRS GTP library' />
- <param name='lstats' doc='Statistics messages and logging' />
- <param name='lgsup' doc='Generic Subscriber Update Protocol' />
- <param name='loap' doc='Osmocom Authentication Protocol' />
- <param name='lss7' doc='libosmo-sigtran Signalling System 7' />
- <param name='lsccp' doc='libosmo-sigtran SCCP Implementation' />
- <param name='lsua' doc='libosmo-sigtran SCCP User Adaptation' />
- <param name='lm3ua' doc='libosmo-sigtran MTP3 User Adaptation' />
- <param name='lmgcp' doc='libosmo-mgcp Media Gateway Control Protocol' />
- <param name='ljibuf' doc='libosmo-netif Jitter Buffer' />
- <param name='lrspro' doc='Remote SIM protocol' />
- <param name='debug' doc='Log debug messages and higher levels' />
- <param name='info' doc='Log informational messages and higher levels' />
- <param name='notice' doc='Log noticeable messages and higher levels' />
- <param name='error' doc='Log error messages and higher levels' />
- <param name='fatal' doc='Log only fatal messages' />
- <param name='.LOGMESSAGE' doc='Arbitrary message to log on given category and log level' />
- </params>
- </command>
- <command id='show logging vty'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='logging' doc='Show current logging configuration' />
- <param name='vty' doc='Show current logging configuration for this vty' />
- </params>
- </command>
- <command id='show alarms'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='alarms' doc='Show current logging configuration' />
- </params>
- </command>
- <command id='show talloc-context (application|all) (full|brief|DEPTH)'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='talloc-context' doc='Show talloc memory hierarchy' />
- <param name='application' doc='Application&apos;s context' />
- <param name='all' doc='All contexts, if NULL-context tracking is enabled' />
- <param name='full' doc='Display a full talloc memory hierarchy' />
- <param name='brief' doc='Display a brief talloc memory hierarchy' />
- <param name='DEPTH' doc='Specify required maximal depth value' />
- </params>
- </command>
- <command id='show talloc-context (application|all) (full|brief|DEPTH) tree ADDRESS'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='talloc-context' doc='Show talloc memory hierarchy' />
- <param name='application' doc='Application&apos;s context' />
- <param name='all' doc='All contexts, if NULL-context tracking is enabled' />
- <param name='full' doc='Display a full talloc memory hierarchy' />
- <param name='brief' doc='Display a brief talloc memory hierarchy' />
- <param name='DEPTH' doc='Specify required maximal depth value' />
- <param name='tree' doc='Display only a specific memory chunk' />
- <param name='ADDRESS' doc='Chunk address (e.g. 0xdeadbeef)' />
- </params>
- </command>
- <command id='show talloc-context (application|all) (full|brief|DEPTH) filter REGEXP'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='talloc-context' doc='Show talloc memory hierarchy' />
- <param name='application' doc='Application&apos;s context' />
- <param name='all' doc='All contexts, if NULL-context tracking is enabled' />
- <param name='full' doc='Display a full talloc memory hierarchy' />
- <param name='brief' doc='Display a brief talloc memory hierarchy' />
- <param name='DEPTH' doc='Specify required maximal depth value' />
- <param name='filter' doc='Filter chunks using regular expression' />
- <param name='REGEXP' doc='Regular expression' />
- </params>
- </command>
- <command id='show stats'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='stats' doc='Show statistical values' />
- </params>
- </command>
- <command id='show stats level (global|peer|subscriber)'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='stats' doc='Show statistical values' />
- <param name='level' doc='Set the maximum group level' />
- <param name='global' doc='Show global groups only' />
- <param name='peer' doc='Show global and network peer related groups' />
- <param name='subscriber' doc='Show global, peer, and subscriber groups' />
- </params>
- </command>
- <command id='show asciidoc counters'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='asciidoc' doc='Asciidoc generation' />
- <param name='counters' doc='Generate table of all registered counters' />
- </params>
- </command>
- <command id='show rate-counters'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='rate-counters' doc='Show all rate counters' />
- </params>
- </command>
- <command id='show gbproxy [stats]'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='gbproxy' doc='Display information about the Gb proxy' />
- <param name='[stats]' doc='Show statistics' />
- </params>
- </command>
- <command id='show gbproxy links'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='gbproxy' doc='Display information about the Gb proxy' />
- <param name='links' doc='Show logical links' />
- </params>
- </command>
- <command id='show ns'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='ns' doc='Display information about the NS protocol' />
- </params>
- </command>
- <command id='show ns stats'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='ns' doc='Display information about the NS protocol' />
- <param name='stats' doc='Include statistics' />
- </params>
- </command>
- <command id='show ns persistent'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='ns' doc='Display information about the NS protocol' />
- <param name='persistent' doc='Show only persistent NS' />
- </params>
- </command>
- <command id='show ns (nsei|nsvc) &lt;0-65535&gt; [stats]'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='ns' doc='Display information about the NS protocol' />
- <param name='nsei' doc='Select one NSE by its NSE Identifier' />
- <param name='nsvc' doc='Select one NSE by its NS-VC Identifier' />
- <param name='&lt;0-65535&gt;' doc='The Identifier of selected type' />
- <param name='[stats]' doc='Include Statistics' />
- </params>
- </command>
- <command id='logging filter nsvc (nsei|nsvci) &lt;0-65535&gt;'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='filter' doc='Filter log messages' />
- <param name='nsvc' doc='Filter based on NS Virtual Connection' />
- <param name='nsei' doc='Identify NS-VC by NSEI' />
- <param name='nsvci' doc='Identify NS-VC by NSVCI' />
- <param name='&lt;0-65535&gt;' doc='Numeric identifier' />
- </params>
- </command>
- </node>
- <node id='enable'>
- <name>enable</name>
- <command id='disable'>
- <params>
- <param name='disable' doc='Turn off privileged mode command' />
- </params>
- </command>
- <command id='configure terminal'>
- <params>
- <param name='configure' doc='Configuration from vty interface' />
- <param name='terminal' doc='Configuration terminal' />
- </params>
- </command>
- <command id='copy running-config startup-config'>
- <params>
- <param name='copy' doc='Copy configuration' />
- <param name='running-config' doc='Copy running config to... ' />
- <param name='startup-config' doc='Copy running config to startup config (same as write file)' />
- </params>
- </command>
- <command id='show startup-config'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='startup-config' doc='Contentes of startup configuration' />
- </params>
- </command>
- <command id='show version'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='version' doc='Displays program version' />
- </params>
- </command>
- <command id='show online-help'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='online-help' doc='Online help' />
- </params>
- </command>
- <command id='terminal length &lt;0-512&gt;'>
- <params>
- <param name='terminal' doc='Set terminal line parameters' />
- <param name='length' doc='Set number of lines on a screen' />
- <param name='&lt;0-512&gt;' doc='Number of lines on screen (0 for no pausing)' />
- </params>
- </command>
- <command id='terminal no length'>
- <params>
- <param name='terminal' doc='Set terminal line parameters' />
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='length' doc='Set number of lines on a screen' />
- </params>
- </command>
- <command id='who'>
- <params>
- <param name='who' doc='Display who is on vty' />
- </params>
- </command>
- <command id='show history'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='history' doc='Display the session command history' />
- </params>
- </command>
- <command id='terminal monitor'>
- <params>
- <param name='terminal' doc='Set terminal line parameters' />
- <param name='monitor' doc='Copy debug output to the current terminal line' />
- </params>
- </command>
- <command id='terminal no monitor'>
- <params>
- <param name='terminal' doc='Set terminal line parameters' />
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='monitor' doc='Copy debug output to the current terminal line' />
- </params>
- </command>
- <command id='logging enable'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='enable' doc='Enables logging to this vty' />
- </params>
- </command>
- <command id='logging disable'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='disable' doc='Disables logging to this vty' />
- </params>
- </command>
- <command id='logging filter all (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='filter' doc='Filter log messages' />
- <param name='all' doc='Do you want to log all messages?' />
- <param name='0' doc='Only print messages matched by other filters' />
- <param name='1' doc='Bypass filter and print all messages' />
- </params>
- </command>
- <command id='logging color (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='color' doc='Configure color-printing for log messages' />
- <param name='0' doc='Don&apos;t use color for printing messages' />
- <param name='1' doc='Use color for printing messages' />
- </params>
- </command>
- <command id='logging timestamp (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='timestamp' doc='Configure log message timestamping' />
- <param name='0' doc='Don&apos;t prefix each log message' />
- <param name='1' doc='Prefix each log message with current timestamp' />
- </params>
- </command>
- <command id='logging print extended-timestamp (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='print' doc='Log output settings' />
- <param name='extended-timestamp' doc='Configure log message timestamping' />
- <param name='0' doc='Don&apos;t prefix each log message' />
- <param name='1' doc='Prefix each log message with current timestamp with YYYYMMDDhhmmssnnn' />
- </params>
- </command>
- <command id='logging print category (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='print' doc='Log output settings' />
- <param name='category' doc='Configure log message' />
- <param name='0' doc='Don&apos;t prefix each log message' />
- <param name='1' doc='Prefix each log message with category/subsystem name' />
- </params>
- </command>
- <command id='logging print category-hex (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='print' doc='Log output settings' />
- <param name='category-hex' doc='Configure log message' />
- <param name='0' doc='Don&apos;t prefix each log message' />
- <param name='1' doc='Prefix each log message with category/subsystem nr in hex (&apos;&lt;000b&gt;&apos;)' />
- </params>
- </command>
- <command id='logging print level (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='print' doc='Log output settings' />
- <param name='level' doc='Configure log message' />
- <param name='0' doc='Don&apos;t prefix each log message' />
- <param name='1' doc='Prefix each log message with the log level name' />
- </params>
- </command>
- <command id='logging print file (0|1|basename) [last]'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='print' doc='Log output settings' />
- <param name='file' doc='Configure log message' />
- <param name='0' doc='Don&apos;t prefix each log message' />
- <param name='1' doc='Prefix each log message with the source file and line' />
- <param name='basename' doc='Prefix each log message with the source file&apos;s basename (strip leading paths) and line' />
- <param name='[last]' doc='Log source file info at the end of a log line. If omitted, log source file info just before the log text.' />
- </params>
- </command>
- <command id='logging set-log-mask MASK'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='set-log-mask' doc='Set the logmask of this logging target' />
- <param name='MASK' doc='List of logging categories to log, e.g. &apos;abc:mno:xyz&apos;. Available log categories depend on the specific application, refer to the &apos;logging level&apos; command. Optionally add individual log levels like &apos;abc,1:mno,3:xyz,5&apos;, where the level numbers are LOGL_DEBUG=1 LOGL_INFO=3 LOGL_NOTICE=5 LOGL_ERROR=7 LOGL_FATAL=8' />
- </params>
- </command>
- <command id='logging level (|gprs|ns|bssgp|lglobal|llapd|linp|lmux|lmi|lmib|lsms|lctrl|lgtp|lstats|lgsup|loap|lss7|lsccp|lsua|lm3ua|lmgcp|ljibuf|lrspro) (debug|info|notice|error|fatal)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='level' doc='Set the log level for a specified category' />
- <param name='gprs' doc='GPRS Packet Service' />
- <param name='ns' doc='GPRS Network Service (NS)' />
- <param name='bssgp' doc='GPRS BSS Gateway Protocol (BSSGP)' />
- <param name='lglobal' doc='Library-internal global log family' />
- <param name='llapd' doc='LAPD in libosmogsm' />
- <param name='linp' doc='A-bis Intput Subsystem' />
- <param name='lmux' doc='A-bis B-Subchannel TRAU Frame Multiplex' />
- <param name='lmi' doc='A-bis Input Driver for Signalling' />
- <param name='lmib' doc='A-bis Input Driver for B-Channels (voice)' />
- <param name='lsms' doc='Layer3 Short Message Service (SMS)' />
- <param name='lctrl' doc='Control Interface' />
- <param name='lgtp' doc='GPRS GTP library' />
- <param name='lstats' doc='Statistics messages and logging' />
- <param name='lgsup' doc='Generic Subscriber Update Protocol' />
- <param name='loap' doc='Osmocom Authentication Protocol' />
- <param name='lss7' doc='libosmo-sigtran Signalling System 7' />
- <param name='lsccp' doc='libosmo-sigtran SCCP Implementation' />
- <param name='lsua' doc='libosmo-sigtran SCCP User Adaptation' />
- <param name='lm3ua' doc='libosmo-sigtran MTP3 User Adaptation' />
- <param name='lmgcp' doc='libosmo-mgcp Media Gateway Control Protocol' />
- <param name='ljibuf' doc='libosmo-netif Jitter Buffer' />
- <param name='lrspro' doc='Remote SIM protocol' />
- <param name='debug' doc='Log debug messages and higher levels' />
- <param name='info' doc='Log informational messages and higher levels' />
- <param name='notice' doc='Log noticeable messages and higher levels' />
- <param name='error' doc='Log error messages and higher levels' />
- <param name='fatal' doc='Log only fatal messages' />
- </params>
- </command>
- <command id='logging level set-all (debug|info|notice|error|fatal)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='level' doc='Set the log level for a specified category' />
- <param name='set-all' doc='Once-off set all categories to the given log level. There is no single command to take back these changes -- each category is set to the given level, period.' />
- <param name='debug' doc='Log debug messages and higher levels' />
- <param name='info' doc='Log informational messages and higher levels' />
- <param name='notice' doc='Log noticeable messages and higher levels' />
- <param name='error' doc='Log error messages and higher levels' />
- <param name='fatal' doc='Log only fatal messages' />
- </params>
- </command>
- <command id='logging level force-all (debug|info|notice|error|fatal)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='level' doc='Set the log level for a specified category' />
- <param name='force-all' doc='Globally force all logging categories to a specific level. This is released by the &apos;no logging level force-all&apos; command. Note: any &apos;logging level &lt;category&gt; &lt;level&gt;&apos; commands will have no visible effect after this, until the forced level is released.' />
- <param name='debug' doc='Log debug messages and higher levels' />
- <param name='info' doc='Log informational messages and higher levels' />
- <param name='notice' doc='Log noticeable messages and higher levels' />
- <param name='error' doc='Log error messages and higher levels' />
- <param name='fatal' doc='Log only fatal messages' />
- </params>
- </command>
- <command id='no logging level force-all'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='logging' doc='Configure logging' />
- <param name='level' doc='Set the log level for a specified category' />
- <param name='force-all' doc='Release any globally forced log level set with &apos;logging level force-all &lt;level&gt;&apos;' />
- </params>
- </command>
- <command id='logp (|gprs|ns|bssgp|lglobal|llapd|linp|lmux|lmi|lmib|lsms|lctrl|lgtp|lstats|lgsup|loap|lss7|lsccp|lsua|lm3ua|lmgcp|ljibuf|lrspro) (debug|info|notice|error|fatal) .LOGMESSAGE'>
- <params>
- <param name='logp' doc='Print a message on all log outputs; useful for placing markers in test logs' />
- <param name='gprs' doc='GPRS Packet Service' />
- <param name='ns' doc='GPRS Network Service (NS)' />
- <param name='bssgp' doc='GPRS BSS Gateway Protocol (BSSGP)' />
- <param name='lglobal' doc='Library-internal global log family' />
- <param name='llapd' doc='LAPD in libosmogsm' />
- <param name='linp' doc='A-bis Intput Subsystem' />
- <param name='lmux' doc='A-bis B-Subchannel TRAU Frame Multiplex' />
- <param name='lmi' doc='A-bis Input Driver for Signalling' />
- <param name='lmib' doc='A-bis Input Driver for B-Channels (voice)' />
- <param name='lsms' doc='Layer3 Short Message Service (SMS)' />
- <param name='lctrl' doc='Control Interface' />
- <param name='lgtp' doc='GPRS GTP library' />
- <param name='lstats' doc='Statistics messages and logging' />
- <param name='lgsup' doc='Generic Subscriber Update Protocol' />
- <param name='loap' doc='Osmocom Authentication Protocol' />
- <param name='lss7' doc='libosmo-sigtran Signalling System 7' />
- <param name='lsccp' doc='libosmo-sigtran SCCP Implementation' />
- <param name='lsua' doc='libosmo-sigtran SCCP User Adaptation' />
- <param name='lm3ua' doc='libosmo-sigtran MTP3 User Adaptation' />
- <param name='lmgcp' doc='libosmo-mgcp Media Gateway Control Protocol' />
- <param name='ljibuf' doc='libosmo-netif Jitter Buffer' />
- <param name='lrspro' doc='Remote SIM protocol' />
- <param name='debug' doc='Log debug messages and higher levels' />
- <param name='info' doc='Log informational messages and higher levels' />
- <param name='notice' doc='Log noticeable messages and higher levels' />
- <param name='error' doc='Log error messages and higher levels' />
- <param name='fatal' doc='Log only fatal messages' />
- <param name='.LOGMESSAGE' doc='Arbitrary message to log on given category and log level' />
- </params>
- </command>
- <command id='show logging vty'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='logging' doc='Show current logging configuration' />
- <param name='vty' doc='Show current logging configuration for this vty' />
- </params>
- </command>
- <command id='show alarms'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='alarms' doc='Show current logging configuration' />
- </params>
- </command>
- <command id='show talloc-context (application|all) (full|brief|DEPTH)'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='talloc-context' doc='Show talloc memory hierarchy' />
- <param name='application' doc='Application&apos;s context' />
- <param name='all' doc='All contexts, if NULL-context tracking is enabled' />
- <param name='full' doc='Display a full talloc memory hierarchy' />
- <param name='brief' doc='Display a brief talloc memory hierarchy' />
- <param name='DEPTH' doc='Specify required maximal depth value' />
- </params>
- </command>
- <command id='show talloc-context (application|all) (full|brief|DEPTH) tree ADDRESS'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='talloc-context' doc='Show talloc memory hierarchy' />
- <param name='application' doc='Application&apos;s context' />
- <param name='all' doc='All contexts, if NULL-context tracking is enabled' />
- <param name='full' doc='Display a full talloc memory hierarchy' />
- <param name='brief' doc='Display a brief talloc memory hierarchy' />
- <param name='DEPTH' doc='Specify required maximal depth value' />
- <param name='tree' doc='Display only a specific memory chunk' />
- <param name='ADDRESS' doc='Chunk address (e.g. 0xdeadbeef)' />
- </params>
- </command>
- <command id='show talloc-context (application|all) (full|brief|DEPTH) filter REGEXP'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='talloc-context' doc='Show talloc memory hierarchy' />
- <param name='application' doc='Application&apos;s context' />
- <param name='all' doc='All contexts, if NULL-context tracking is enabled' />
- <param name='full' doc='Display a full talloc memory hierarchy' />
- <param name='brief' doc='Display a brief talloc memory hierarchy' />
- <param name='DEPTH' doc='Specify required maximal depth value' />
- <param name='filter' doc='Filter chunks using regular expression' />
- <param name='REGEXP' doc='Regular expression' />
- </params>
- </command>
- <command id='show stats'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='stats' doc='Show statistical values' />
- </params>
- </command>
- <command id='show stats level (global|peer|subscriber)'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='stats' doc='Show statistical values' />
- <param name='level' doc='Set the maximum group level' />
- <param name='global' doc='Show global groups only' />
- <param name='peer' doc='Show global and network peer related groups' />
- <param name='subscriber' doc='Show global, peer, and subscriber groups' />
- </params>
- </command>
- <command id='show asciidoc counters'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='asciidoc' doc='Asciidoc generation' />
- <param name='counters' doc='Generate table of all registered counters' />
- </params>
- </command>
- <command id='show rate-counters'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='rate-counters' doc='Show all rate counters' />
- </params>
- </command>
- <command id='show gbproxy [stats]'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='gbproxy' doc='Display information about the Gb proxy' />
- <param name='[stats]' doc='Show statistics' />
- </params>
- </command>
- <command id='show gbproxy links'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='gbproxy' doc='Display information about the Gb proxy' />
- <param name='links' doc='Show logical links' />
- </params>
- </command>
- <command id='delete-gbproxy-peer &lt;0-65534&gt; bvci &lt;2-65534&gt;'>
- <params>
- <param name='delete-gbproxy-peer' doc='Delete a GBProxy peer by NSEI and optionally BVCI' />
- <param name='&lt;0-65534&gt;' doc='NSEI number' />
- <param name='bvci' doc='Only delete peer with a matching BVCI' />
- <param name='&lt;2-65534&gt;' doc='BVCI number' />
- </params>
- </command>
- <command id='delete-gbproxy-peer &lt;0-65534&gt; (only-bvc|only-nsvc|all) [dry-run]'>
- <params>
- <param name='delete-gbproxy-peer' doc='Delete a GBProxy peer by NSEI and optionally BVCI' />
- <param name='&lt;0-65534&gt;' doc='NSEI number' />
- <param name='only-bvc' doc='Only delete BSSGP connections (BVC)' />
- <param name='only-nsvc' doc='Only delete dynamic NS connections (NS-VC)' />
- <param name='all' doc='Delete BVC and dynamic NS connections' />
- <param name='[dry-run]' doc='Show what would be deleted instead of actually deleting' />
- </params>
- </command>
- <command id='delete-gbproxy-link &lt;0-65534&gt; (tlli|imsi|sgsn-nsei) IDENT'>
- <params>
- <param name='delete-gbproxy-link' doc='Delete a GBProxy logical link entry by NSEI and identification' />
- <param name='&lt;0-65534&gt;' doc='NSEI number' />
- <param name='tlli' doc='Delete entries with a matching TLLI (hex)' />
- <param name='imsi' doc='Delete entries with a matching IMSI' />
- <param name='sgsn-nsei' doc='Delete entries with a matching SGSN NSEI' />
- <param name='IDENT' doc='Identification to match' />
- </params>
- </command>
- <command id='delete-gbproxy-link &lt;0-65534&gt; (stale|de-registered)'>
- <params>
- <param name='delete-gbproxy-link' doc='Delete a GBProxy logical link entry by NSEI and identification' />
- <param name='&lt;0-65534&gt;' doc='NSEI number' />
- <param name='stale' doc='Delete stale entries' />
- <param name='de-registered' doc='Delete de-registered entries' />
- </params>
- </command>
- <command id='show ns'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='ns' doc='Display information about the NS protocol' />
- </params>
- </command>
- <command id='show ns stats'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='ns' doc='Display information about the NS protocol' />
- <param name='stats' doc='Include statistics' />
- </params>
- </command>
- <command id='show ns persistent'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='ns' doc='Display information about the NS protocol' />
- <param name='persistent' doc='Show only persistent NS' />
- </params>
- </command>
- <command id='show ns (nsei|nsvc) &lt;0-65535&gt; [stats]'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='ns' doc='Display information about the NS protocol' />
- <param name='nsei' doc='Select one NSE by its NSE Identifier' />
- <param name='nsvc' doc='Select one NSE by its NS-VC Identifier' />
- <param name='&lt;0-65535&gt;' doc='The Identifier of selected type' />
- <param name='[stats]' doc='Include Statistics' />
- </params>
- </command>
- <command id='logging filter nsvc (nsei|nsvci) &lt;0-65535&gt;'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='filter' doc='Filter log messages' />
- <param name='nsvc' doc='Filter based on NS Virtual Connection' />
- <param name='nsei' doc='Identify NS-VC by NSEI' />
- <param name='nsvci' doc='Identify NS-VC by NSVCI' />
- <param name='&lt;0-65535&gt;' doc='Numeric identifier' />
- </params>
- </command>
- <command id='nsvc (nsei|nsvci) &lt;0-65535&gt; (block|unblock|reset)'>
- <params>
- <param name='nsvc' doc='Perform an operation on a NSVC' />
- <param name='nsei' doc='NSEI to identify NS-VC Identifier (NS-VCI)' />
- <param name='nsvci' doc='NS-VC Identifier (NS-VCI)' />
- <param name='&lt;0-65535&gt;' doc='The NSEI' />
- <param name='block' doc='Initiate BLOCK procedure' />
- <param name='unblock' doc='Initiate UNBLOCK procedure' />
- <param name='reset' doc='Initiate RESET procedure' />
- </params>
- </command>
- </node>
- <node id='config'>
- <name>config</name>
- <command id='hostname WORD'>
- <params>
- <param name='hostname' doc='Set system&apos;s network name' />
- <param name='WORD' doc='This system&apos;s network name' />
- </params>
- </command>
- <command id='no hostname [HOSTNAME]'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='hostname' doc='Reset system&apos;s network name' />
- <param name='[HOSTNAME]' doc='Host name of this router' />
- </params>
- </command>
- <command id='password (8|) WORD'>
- <params>
- <param name='password' doc='Assign the terminal connection password' />
- <param name='8' doc='Specifies a HIDDEN password will follow' />
- <param name='' doc='dummy string ' />
- <param name='WORD' doc='The HIDDEN line password string' />
- </params>
- </command>
- <command id='password LINE'>
- <params>
- <param name='password' doc='Assign the terminal connection password' />
- <param name='LINE' doc='The UNENCRYPTED (cleartext) line password' />
- </params>
- </command>
- <command id='enable password (8|) WORD'>
- <params>
- <param name='enable' doc='Modify enable password parameters' />
- <param name='password' doc='Assign the privileged level password' />
- <param name='8' doc='Specifies a HIDDEN password will follow' />
- <param name='' doc='dummy string ' />
- <param name='WORD' doc='The HIDDEN &apos;enable&apos; password string' />
- </params>
- </command>
- <command id='enable password LINE'>
- <params>
- <param name='enable' doc='Modify enable password parameters' />
- <param name='password' doc='Assign the privileged level password' />
- <param name='LINE' doc='The UNENCRYPTED (cleartext) &apos;enable&apos; password' />
- </params>
- </command>
- <command id='no enable password'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='enable' doc='Modify enable password parameters' />
- <param name='password' doc='Assign the privileged level password' />
- </params>
- </command>
- <command id='banner motd default'>
- <params>
- <param name='banner' doc='Set banner string' />
- <param name='motd' doc='Strings for motd' />
- <param name='default' doc='Default string' />
- </params>
- </command>
- <command id='banner motd file [FILE]'>
- <params>
- <param name='banner' doc='Set banner' />
- <param name='motd' doc='Banner for motd' />
- <param name='file' doc='Banner from a file' />
- <param name='[FILE]' doc='Filename' />
- </params>
- </command>
- <command id='no banner motd'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='banner' doc='Set banner string' />
- <param name='motd' doc='Strings for motd' />
- </params>
- </command>
- <command id='service terminal-length &lt;0-512&gt;'>
- <params>
- <param name='service' doc='Set up miscellaneous service' />
- <param name='terminal-length' doc='System wide terminal length configuration' />
- <param name='&lt;0-512&gt;' doc='Number of lines of VTY (0 means no line control)' />
- </params>
- </command>
- <command id='no service terminal-length [&lt;0-512&gt;]'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='service' doc='Set up miscellaneous service' />
- <param name='terminal-length' doc='System wide terminal length configuration' />
- <param name='[&lt;0-512&gt;]' doc='Number of lines of VTY (0 means no line control)' />
- </params>
- </command>
- <command id='line vty'>
- <params>
- <param name='line' doc='Configure a terminal line' />
- <param name='vty' doc='Virtual terminal' />
- </params>
- </command>
- <command id='service advanced-vty'>
- <params>
- <param name='service' doc='Set up miscellaneous service' />
- <param name='advanced-vty' doc='Enable advanced mode vty interface' />
- </params>
- </command>
- <command id='no service advanced-vty'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='service' doc='Set up miscellaneous service' />
- <param name='advanced-vty' doc='Enable advanced mode vty interface' />
- </params>
- </command>
- <command id='show history'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='history' doc='Display the session command history' />
- </params>
- </command>
- <command id='log stderr'>
- <params>
- <param name='log' doc='Configure logging sub-system' />
- <param name='stderr' doc='Logging via STDERR of the process' />
- </params>
- </command>
- <command id='no log stderr'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='log' doc='Configure logging sub-system' />
- <param name='stderr' doc='Logging via STDERR of the process' />
- </params>
- </command>
- <command id='log file .FILENAME'>
- <params>
- <param name='log' doc='Configure logging sub-system' />
- <param name='file' doc='Logging to text file' />
- <param name='.FILENAME' doc='Filename' />
- </params>
- </command>
- <command id='no log file .FILENAME'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='log' doc='Configure logging sub-system' />
- <param name='file' doc='Logging to text file' />
- <param name='.FILENAME' doc='Filename' />
- </params>
- </command>
- <command id='log alarms &lt;2-32700&gt;'>
- <params>
- <param name='log' doc='Configure logging sub-system' />
- <param name='alarms' doc='Logging alarms to osmo_strrb' />
- <param name='&lt;2-32700&gt;' doc='Maximum number of messages to log' />
- </params>
- </command>
- <command id='no log alarms'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='log' doc='Configure logging sub-system' />
- <param name='alarms' doc='Logging alarms to osmo_strrb' />
- </params>
- </command>
- <command id='log syslog (authpriv|cron|daemon|ftp|lpr|mail|news|user|uucp)'>
- <params>
- <param name='log' doc='Configure logging sub-system' />
- <param name='syslog' doc='Logging via syslog' />
- <param name='authpriv' doc='Security/authorization messages facility' />
- <param name='cron' doc='Clock daemon (cron/at) facility' />
- <param name='daemon' doc='General system daemon facility' />
- <param name='ftp' doc='Ftp daemon facility' />
- <param name='lpr' doc='Line printer facility' />
- <param name='mail' doc='Mail facility' />
- <param name='news' doc='News facility' />
- <param name='user' doc='Generic facility' />
- <param name='uucp' doc='UUCP facility' />
- </params>
- </command>
- <command id='log syslog local &lt;0-7&gt;'>
- <params>
- <param name='log' doc='Configure logging sub-system' />
- <param name='syslog' doc='Logging via syslog' />
- <param name='local' doc='Syslog LOCAL facility' />
- <param name='&lt;0-7&gt;' doc='Local facility number' />
- </params>
- </command>
- <command id='no log syslog'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='log' doc='Configure logging sub-system' />
- <param name='syslog' doc='Logging via syslog' />
- </params>
- </command>
- <command id='log gsmtap [HOSTNAME]'>
- <params>
- <param name='log' doc='Configure logging sub-system' />
- <param name='gsmtap' doc='Logging via GSMTAP' />
- <param name='[HOSTNAME]' doc='Host name to send the GSMTAP logging to (UDP port 4729)' />
- </params>
- </command>
- <command id='stats reporter statsd'>
- <params>
- <param name='stats' doc='Configure stats sub-system' />
- <param name='reporter' doc='Configure a stats reporter' />
- <param name='statsd' doc='Report to a STATSD server' />
- </params>
- </command>
- <command id='no stats reporter statsd'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='stats' doc='Configure stats sub-system' />
- <param name='reporter' doc='Configure a stats reporter' />
- <param name='statsd' doc='Report to a STATSD server' />
- </params>
- </command>
- <command id='stats reporter log'>
- <params>
- <param name='stats' doc='Configure stats sub-system' />
- <param name='reporter' doc='Configure a stats reporter' />
- <param name='log' doc='Report to the logger' />
- </params>
- </command>
- <command id='no stats reporter log'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='stats' doc='Configure stats sub-system' />
- <param name='reporter' doc='Configure a stats reporter' />
- <param name='log' doc='Report to the logger' />
- </params>
- </command>
- <command id='stats interval &lt;1-65535&gt;'>
- <params>
- <param name='stats' doc='Configure stats sub-system' />
- <param name='interval' doc='Set the reporting interval' />
- <param name='&lt;1-65535&gt;' doc='Interval in seconds' />
- </params>
- </command>
- <command id='gbproxy'>
- <params>
- <param name='gbproxy' doc='Configure the Gb proxy' />
- </params>
- </command>
- <command id='ns'>
- <params>
- <param name='ns' doc='Configure the GPRS Network Service' />
- </params>
- </command>
- </node>
- <node id='config-log'>
- <name>config-log</name>
- <command id='logging filter all (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='filter' doc='Filter log messages' />
- <param name='all' doc='Do you want to log all messages?' />
- <param name='0' doc='Only print messages matched by other filters' />
- <param name='1' doc='Bypass filter and print all messages' />
- </params>
- </command>
- <command id='logging color (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='color' doc='Configure color-printing for log messages' />
- <param name='0' doc='Don&apos;t use color for printing messages' />
- <param name='1' doc='Use color for printing messages' />
- </params>
- </command>
- <command id='logging timestamp (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='timestamp' doc='Configure log message timestamping' />
- <param name='0' doc='Don&apos;t prefix each log message' />
- <param name='1' doc='Prefix each log message with current timestamp' />
- </params>
- </command>
- <command id='logging print extended-timestamp (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='print' doc='Log output settings' />
- <param name='extended-timestamp' doc='Configure log message timestamping' />
- <param name='0' doc='Don&apos;t prefix each log message' />
- <param name='1' doc='Prefix each log message with current timestamp with YYYYMMDDhhmmssnnn' />
- </params>
- </command>
- <command id='logging print category (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='print' doc='Log output settings' />
- <param name='category' doc='Configure log message' />
- <param name='0' doc='Don&apos;t prefix each log message' />
- <param name='1' doc='Prefix each log message with category/subsystem name' />
- </params>
- </command>
- <command id='logging print category-hex (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='print' doc='Log output settings' />
- <param name='category-hex' doc='Configure log message' />
- <param name='0' doc='Don&apos;t prefix each log message' />
- <param name='1' doc='Prefix each log message with category/subsystem nr in hex (&apos;&lt;000b&gt;&apos;)' />
- </params>
- </command>
- <command id='logging print level (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='print' doc='Log output settings' />
- <param name='level' doc='Configure log message' />
- <param name='0' doc='Don&apos;t prefix each log message' />
- <param name='1' doc='Prefix each log message with the log level name' />
- </params>
- </command>
- <command id='logging print file (0|1|basename) [last]'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='print' doc='Log output settings' />
- <param name='file' doc='Configure log message' />
- <param name='0' doc='Don&apos;t prefix each log message' />
- <param name='1' doc='Prefix each log message with the source file and line' />
- <param name='basename' doc='Prefix each log message with the source file&apos;s basename (strip leading paths) and line' />
- <param name='[last]' doc='Log source file info at the end of a log line. If omitted, log source file info just before the log text.' />
- </params>
- </command>
- <command id='logging level (|gprs|ns|bssgp|lglobal|llapd|linp|lmux|lmi|lmib|lsms|lctrl|lgtp|lstats|lgsup|loap|lss7|lsccp|lsua|lm3ua|lmgcp|ljibuf|lrspro) (debug|info|notice|error|fatal)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='level' doc='Set the log level for a specified category' />
- <param name='gprs' doc='GPRS Packet Service' />
- <param name='ns' doc='GPRS Network Service (NS)' />
- <param name='bssgp' doc='GPRS BSS Gateway Protocol (BSSGP)' />
- <param name='lglobal' doc='Library-internal global log family' />
- <param name='llapd' doc='LAPD in libosmogsm' />
- <param name='linp' doc='A-bis Intput Subsystem' />
- <param name='lmux' doc='A-bis B-Subchannel TRAU Frame Multiplex' />
- <param name='lmi' doc='A-bis Input Driver for Signalling' />
- <param name='lmib' doc='A-bis Input Driver for B-Channels (voice)' />
- <param name='lsms' doc='Layer3 Short Message Service (SMS)' />
- <param name='lctrl' doc='Control Interface' />
- <param name='lgtp' doc='GPRS GTP library' />
- <param name='lstats' doc='Statistics messages and logging' />
- <param name='lgsup' doc='Generic Subscriber Update Protocol' />
- <param name='loap' doc='Osmocom Authentication Protocol' />
- <param name='lss7' doc='libosmo-sigtran Signalling System 7' />
- <param name='lsccp' doc='libosmo-sigtran SCCP Implementation' />
- <param name='lsua' doc='libosmo-sigtran SCCP User Adaptation' />
- <param name='lm3ua' doc='libosmo-sigtran MTP3 User Adaptation' />
- <param name='lmgcp' doc='libosmo-mgcp Media Gateway Control Protocol' />
- <param name='ljibuf' doc='libosmo-netif Jitter Buffer' />
- <param name='lrspro' doc='Remote SIM protocol' />
- <param name='debug' doc='Log debug messages and higher levels' />
- <param name='info' doc='Log informational messages and higher levels' />
- <param name='notice' doc='Log noticeable messages and higher levels' />
- <param name='error' doc='Log error messages and higher levels' />
- <param name='fatal' doc='Log only fatal messages' />
- </params>
- </command>
- <command id='logging level set-all (debug|info|notice|error|fatal)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='level' doc='Set the log level for a specified category' />
- <param name='set-all' doc='Once-off set all categories to the given log level. There is no single command to take back these changes -- each category is set to the given level, period.' />
- <param name='debug' doc='Log debug messages and higher levels' />
- <param name='info' doc='Log informational messages and higher levels' />
- <param name='notice' doc='Log noticeable messages and higher levels' />
- <param name='error' doc='Log error messages and higher levels' />
- <param name='fatal' doc='Log only fatal messages' />
- </params>
- </command>
- <command id='logging level force-all (debug|info|notice|error|fatal)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='level' doc='Set the log level for a specified category' />
- <param name='force-all' doc='Globally force all logging categories to a specific level. This is released by the &apos;no logging level force-all&apos; command. Note: any &apos;logging level &lt;category&gt; &lt;level&gt;&apos; commands will have no visible effect after this, until the forced level is released.' />
- <param name='debug' doc='Log debug messages and higher levels' />
- <param name='info' doc='Log informational messages and higher levels' />
- <param name='notice' doc='Log noticeable messages and higher levels' />
- <param name='error' doc='Log error messages and higher levels' />
- <param name='fatal' doc='Log only fatal messages' />
- </params>
- </command>
- <command id='no logging level force-all'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='logging' doc='Configure logging' />
- <param name='level' doc='Set the log level for a specified category' />
- <param name='force-all' doc='Release any globally forced log level set with &apos;logging level force-all &lt;level&gt;&apos;' />
- </params>
- </command>
- <command id='logging filter nsvc (nsei|nsvci) &lt;0-65535&gt;'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='filter' doc='Filter log messages' />
- <param name='nsvc' doc='Filter based on NS Virtual Connection' />
- <param name='nsei' doc='Identify NS-VC by NSEI' />
- <param name='nsvci' doc='Identify NS-VC by NSVCI' />
- <param name='&lt;0-65535&gt;' doc='Numeric identifier' />
- </params>
- </command>
- </node>
- <node id='config-stats'>
- <name>config-stats</name>
- <command id='local-ip ADDR'>
- <params>
- <param name='local-ip' doc='Set the IP address to which we bind locally' />
- <param name='ADDR' doc='IP Address' />
- </params>
- </command>
- <command id='no local-ip'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='local-ip' doc='Set the IP address to which we bind locally' />
- </params>
- </command>
- <command id='remote-ip ADDR'>
- <params>
- <param name='remote-ip' doc='Set the remote IP address to which we connect' />
- <param name='ADDR' doc='IP Address' />
- </params>
- </command>
- <command id='remote-port &lt;1-65535&gt;'>
- <params>
- <param name='remote-port' doc='Set the remote port to which we connect' />
- <param name='&lt;1-65535&gt;' doc='Remote port number' />
- </params>
- </command>
- <command id='mtu &lt;100-65535&gt;'>
- <params>
- <param name='mtu' doc='Set the maximum packet size' />
- <param name='&lt;100-65535&gt;' doc='Size in byte' />
- </params>
- </command>
- <command id='no mtu'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='mtu' doc='Set the maximum packet size' />
- </params>
- </command>
- <command id='prefix PREFIX'>
- <params>
- <param name='prefix' doc='Set the item name prefix' />
- <param name='PREFIX' doc='The prefix string' />
- </params>
- </command>
- <command id='no prefix'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='prefix' doc='Set the item name prefix' />
- </params>
- </command>
- <command id='level (global|peer|subscriber)'>
- <params>
- <param name='level' doc='Set the maximum group level' />
- <param name='global' doc='Report global groups only' />
- <param name='peer' doc='Report global and network peer related groups' />
- <param name='subscriber' doc='Report global, peer, and subscriber groups' />
- </params>
- </command>
- <command id='enable'>
- <params>
- <param name='enable' doc='Enable the reporter' />
- </params>
- </command>
- <command id='disable'>
- <params>
- <param name='disable' doc='Disable the reporter' />
- </params>
- </command>
- </node>
- <node id='config-line'>
- <name>config-line</name>
- <command id='login'>
- <params>
- <param name='login' doc='Enable password checking' />
- </params>
- </command>
- <command id='no login'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='login' doc='Enable password checking' />
- </params>
- </command>
- <command id='bind A.B.C.D [&lt;0-65535&gt;]'>
- <params>
- <param name='bind' doc='Accept VTY telnet connections on local interface' />
- <param name='A.B.C.D' doc='Local interface IP address (default: 127.0.0.1)' />
- <param name='[&lt;0-65535&gt;]' doc='Local TCP port number' />
- </params>
- </command>
- </node>
- <node id='config-ns'>
- <name>config-ns</name>
- <command id='nse &lt;0-65535&gt; nsvci &lt;0-65534&gt;'>
- <params>
- <param name='nse' doc='Persistent NS Entity' />
- <param name='&lt;0-65535&gt;' doc='NS Entity ID (NSEI)' />
- <param name='nsvci' doc='NS Virtual Connection' />
- <param name='&lt;0-65534&gt;' doc='NS Virtual Connection ID (NSVCI)' />
- </params>
- </command>
- <command id='nse &lt;0-65535&gt; remote-ip A.B.C.D'>
- <params>
- <param name='nse' doc='Persistent NS Entity' />
- <param name='&lt;0-65535&gt;' doc='NS Entity ID (NSEI)' />
- <param name='remote-ip' doc='Remote IP Address' />
- <param name='A.B.C.D' doc='Remote IP Address' />
- </params>
- </command>
- <command id='nse &lt;0-65535&gt; remote-port &lt;0-65535&gt;'>
- <params>
- <param name='nse' doc='Persistent NS Entity' />
- <param name='&lt;0-65535&gt;' doc='NS Entity ID (NSEI)' />
- <param name='remote-port' doc='Remote UDP Port' />
- <param name='&lt;0-65535&gt;' doc='Remote UDP Port Number' />
- </params>
- </command>
- <command id='nse &lt;0-65535&gt; fr-dlci &lt;16-1007&gt;'>
- <params>
- <param name='nse' doc='Persistent NS Entity' />
- <param name='&lt;0-65535&gt;' doc='NS Entity ID (NSEI)' />
- <param name='fr-dlci' doc='Frame Relay DLCI' />
- <param name='&lt;16-1007&gt;' doc='Frame Relay DLCI Number' />
- </params>
- </command>
- <command id='nse &lt;0-65535&gt; encapsulation (udp|framerelay-gre)'>
- <params>
- <param name='nse' doc='Persistent NS Entity' />
- <param name='&lt;0-65535&gt;' doc='NS Entity ID (NSEI)' />
- <param name='encapsulation' doc='Encapsulation for NS' />
- <param name='udp' doc='UDP/IP Encapsulation' />
- <param name='framerelay-gre' doc='Frame-Relay/GRE/IP Encapsulation' />
- </params>
- </command>
- <command id='nse &lt;0-65535&gt; remote-role (sgsn|bss)'>
- <params>
- <param name='nse' doc='Persistent NS Entity' />
- <param name='&lt;0-65535&gt;' doc='NS Entity ID (NSEI)' />
- <param name='remote-role' doc='Remote NSE Role' />
- <param name='sgsn' doc='Remote Peer is SGSN' />
- <param name='bss' doc='Remote Peer is BSS' />
- </params>
- </command>
- <command id='no nse &lt;0-65535&gt;'>
- <params>
- <param name='no' doc='Delete Persistent NS Entity' />
- <param name='nse' doc='Delete Persistent NS Entity' />
- <param name='&lt;0-65535&gt;' doc='NS Entity ID (NSEI)' />
- </params>
- </command>
- <command id='timer (tns-block|tns-block-retries|tns-reset|tns-reset-retries|tns-test|tns-alive|tns-alive-retries|tsns-prov) &lt;0-65535&gt;'>
- <params>
- <param name='timer' doc='Network Service Timer' />
- <param name='tns-block' doc='(un)blocking Timer (Tns-block) timeout' />
- <param name='tns-block-retries' doc='(un)blocking Timer (Tns-block) number of retries' />
- <param name='tns-reset' doc='Reset Timer (Tns-reset) timeout' />
- <param name='tns-reset-retries' doc='Reset Timer (Tns-reset) number of retries' />
- <param name='tns-test' doc='Test Timer (Tns-test) timeout' />
- <param name='tns-alive' doc='Alive Timer (Tns-alive) timeout' />
- <param name='tns-alive-retries' doc='Alive Timer (Tns-alive) number of retries' />
- <param name='tsns-prov' doc='SNS Provision Timer (Tsns-prov) timeout' />
- <param name='&lt;0-65535&gt;' doc='Timer Value' />
- </params>
- </command>
- <command id='encapsulation udp local-ip A.B.C.D'>
- <params>
- <param name='encapsulation' doc='NS encapsulation options' />
- <param name='udp' doc='NS over UDP Encapsulation' />
- <param name='local-ip' doc='Set the IP address on which we listen for NS/UDP' />
- <param name='A.B.C.D' doc='IP Address' />
- </params>
- </command>
- <command id='encapsulation udp local-port &lt;0-65535&gt;'>
- <params>
- <param name='encapsulation' doc='NS encapsulation options' />
- <param name='udp' doc='NS over UDP Encapsulation' />
- <param name='local-port' doc='Set the UDP port on which we listen for NS/UDP' />
- <param name='&lt;0-65535&gt;' doc='UDP port number' />
- </params>
- </command>
- <command id='encapsulation udp dscp &lt;0-255&gt;'>
- <params>
- <param name='encapsulation' doc='NS encapsulation options' />
- <param name='udp' doc='NS over UDP Encapsulation' />
- <param name='dscp' doc='Set DSCP/TOS on the UDP socket' />
- <param name='&lt;0-255&gt;' doc='DSCP Value' />
- </params>
- </command>
- <command id='encapsulation framerelay-gre enabled (1|0)'>
- <params>
- <param name='encapsulation' doc='NS encapsulation options' />
- <param name='framerelay-gre' doc='NS over Frame Relay over GRE Encapsulation' />
- <param name='enabled' doc='Enable or disable Frame Relay over GRE' />
- <param name='1' doc='Enable' />
- <param name='0' doc='Disable' />
- </params>
- </command>
- <command id='encapsulation framerelay-gre local-ip A.B.C.D'>
- <params>
- <param name='encapsulation' doc='NS encapsulation options' />
- <param name='framerelay-gre' doc='NS over Frame Relay over GRE Encapsulation' />
- <param name='local-ip' doc='Set the IP address on which we listen for NS/FR/GRE' />
- <param name='A.B.C.D' doc='IP Address' />
- </params>
- </command>
- </node>
- <node id='config-gbproxy'>
- <name>config-gbproxy</name>
- <command id='sgsn nsei &lt;0-65534&gt;'>
- <params>
- <param name='sgsn' doc='SGSN information' />
- <param name='nsei' doc='NSEI to be used in the connection with the SGSN' />
- <param name='&lt;0-65534&gt;' doc='The NSEI' />
- </params>
- </command>
- <command id='core-mobile-country-code &lt;1-999&gt;'>
- <params>
- <param name='core-mobile-country-code' doc='Use this country code for the core network' />
- <param name='&lt;1-999&gt;' doc='MCC value' />
- </params>
- </command>
- <command id='core-mobile-network-code &lt;1-999&gt;'>
- <params>
- <param name='core-mobile-network-code' doc='Use this network code for the core network' />
- <param name='&lt;1-999&gt;' doc='NCC value' />
- </params>
- </command>
- <command id='match-imsi (patching|routing) .REGEXP'>
- <params>
- <param name='match-imsi' doc='Restrict actions to certain IMSIs' />
- <param name='patching' doc='Patch MS related information elements on match only' />
- <param name='routing' doc='Route to the secondary SGSN on match only' />
- <param name='.REGEXP' doc='Regular expression for the IMSI match' />
- </params>
- </command>
- <command id='core-access-point-name (APN|none)'>
- <params>
- <param name='core-access-point-name' doc='Use this access point name (APN) for the backbone' />
- <param name='APN' doc='Replace APN by this string' />
- <param name='none' doc='Remove APN' />
- </params>
- </command>
- <command id='secondary-sgsn nsei &lt;0-65534&gt;'>
- <params>
- <param name='secondary-sgsn' doc='Route matching LLC connections to a second SGSN (Experimental)' />
- <param name='nsei' doc='NSEI to be used in the connection with the SGSN' />
- <param name='&lt;0-65534&gt;' doc='The NSEI' />
- </params>
- </command>
- <command id='patch-ptmsi'>
- <params>
- <param name='patch-ptmsi' doc='Patch P-TMSI/TLLI' />
- </params>
- </command>
- <command id='acquire-imsi'>
- <params>
- <param name='acquire-imsi' doc='Acquire the IMSI before establishing a LLC connection (Experimental)' />
- </params>
- </command>
- <command id='link-list clean-stale-timer &lt;1-999999&gt;'>
- <params>
- <param name='link-list' doc='Set TLLI list parameters' />
- <param name='clean-stale-timer' doc='Periodic timer to clean stale links' />
- <param name='&lt;1-999999&gt;' doc='Frequency at which the periodic timer is fired (in seconds)' />
- </params>
- </command>
- <command id='link-list max-age &lt;1-999999&gt;'>
- <params>
- <param name='link-list' doc='Set TLLI list parameters' />
- <param name='max-age' doc='Limit maximum age' />
- <param name='&lt;1-999999&gt;' doc='Maximum age in seconds' />
- </params>
- </command>
- <command id='link-list max-length &lt;1-99999&gt;'>
- <params>
- <param name='link-list' doc='Set TLLI list parameters' />
- <param name='max-length' doc='Limit list length' />
- <param name='&lt;1-99999&gt;' doc='Maximum number of logical links in the list' />
- </params>
- </command>
- <command id='link-list keep-mode (never|re-attach|identified|always)'>
- <params>
- <param name='link-list' doc='Set TLLI list parameters' />
- <param name='keep-mode' doc='How to keep entries for detached logical links' />
- <param name='never' doc='Discard entry immediately after detachment' />
- <param name='re-attach' doc='Keep entry if a re-attachment has be requested' />
- <param name='identified' doc='Keep entry if it associated with an IMSI' />
- <param name='always' doc='Don&apos;t discard entries after detachment' />
- </params>
- </command>
- <command id='link stored-msgs-max-length &lt;1-99999&gt;'>
- <params>
- <param name='link' doc='Set TLLI parameters' />
- <param name='stored-msgs-max-length' doc='Limit list length' />
- <param name='&lt;1-99999&gt;' doc='Maximum number of msgb stored in the logical link waiting to acquire its IMSI' />
- </params>
- </command>
- <command id='no core-mobile-country-code'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='core-mobile-country-code' doc='Use this country code for the core network' />
- </params>
- </command>
- <command id='no core-mobile-network-code'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='core-mobile-network-code' doc='Use this network code for the core network' />
- </params>
- </command>
- <command id='no match-imsi'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='match-imsi' doc='Restrict actions to certain IMSIs' />
- </params>
- </command>
- <command id='no core-access-point-name'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='core-access-point-name' doc='Use this access point name (APN) for the backbone' />
- </params>
- </command>
- <command id='no secondary-sgsn'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='secondary-sgsn' doc='Route matching LLC connections to a second SGSN (Experimental)' />
- </params>
- </command>
- <command id='no patch-ptmsi'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='patch-ptmsi' doc='Patch P-TMSI/TLLI' />
- </params>
- </command>
- <command id='no acquire-imsi'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='acquire-imsi' doc='Acquire the IMSI before establishing a LLC connection (Experimental)' />
- </params>
- </command>
- <command id='no link-list clean-stale-timer'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='link-list' doc='Set TLLI list parameters' />
- <param name='clean-stale-timer' doc='Periodic timer to clean stale links' />
- </params>
- </command>
- <command id='no link-list max-age'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='link-list' doc='Set TLLI list parameters' />
- <param name='max-age' doc='Limit maximum age' />
- </params>
- </command>
- <command id='no link-list max-length'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='link-list' doc='Set TLLI list parameters' />
- <param name='max-length' doc='Limit list length' />
- </params>
- </command>
- <command id='no link stored-msgs-max-length'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='link' doc='Set TLLI parameters' />
- <param name='stored-msgs-max-length' doc='Limit list length' />
- </params>
- </command>
- </node>
-</vtydoc>
diff --git a/include/osmocom/sgsn/Makefile.am b/include/osmocom/sgsn/Makefile.am
index 95c811aa5..51bdee8f7 100644
--- a/include/osmocom/sgsn/Makefile.am
+++ b/include/osmocom/sgsn/Makefile.am
@@ -2,7 +2,6 @@ noinst_HEADERS = \
common.h \
crc24.h \
debug.h \
- gb_proxy.h \
gprs_gb.h \
gprs_gb_parse.h \
gprs_gmm.h \
diff --git a/include/osmocom/sgsn/gb_proxy.h b/include/osmocom/sgsn/gb_proxy.h
deleted file mode 100644
index d988cae7c..000000000
--- a/include/osmocom/sgsn/gb_proxy.h
+++ /dev/null
@@ -1,298 +0,0 @@
-#ifndef _GB_PROXY_H
-#define _GB_PROXY_H
-
-
-#include <osmocom/core/msgb.h>
-#include <osmocom/core/timer.h>
-#include <osmocom/core/fsm.h>
-#include <osmocom/core/hashtable.h>
-#include <osmocom/gsm/gsm23003.h>
-#include <osmocom/gsm/gsm23236.h>
-#include <osmocom/gsm/protocol/gsm_23_003.h>
-
-#include <osmocom/gprs/gprs_ns2.h>
-#include <osmocom/vty/command.h>
-
-#include <sys/types.h>
-#include <regex.h>
-#include <stdbool.h>
-
-#define GBPROXY_INIT_VU_GEN_TX 256
-#define GBPROXY_MAX_NR_SGSN 16
-
-/* BVCI uses 16 bits */
-#define BVC_LOG_CTX_FLAG (1<<17)
-
-struct rate_ctr_group;
-struct gprs_gb_parse_context;
-struct tlv_parsed;
-
-enum gbproxy_global_ctr {
- GBPROX_GLOB_CTR_INV_BVCI,
- GBPROX_GLOB_CTR_INV_LAI,
- GBPROX_GLOB_CTR_INV_RAI,
- GBPROX_GLOB_CTR_INV_NSEI,
- GBPROX_GLOB_CTR_PROTO_ERR_BSS,
- GBPROX_GLOB_CTR_PROTO_ERR_SGSN,
- GBPROX_GLOB_CTR_NOT_SUPPORTED_BSS,
- GBPROX_GLOB_CTR_NOT_SUPPORTED_SGSN,
- GBPROX_GLOB_CTR_RESTART_RESET_SGSN,
- GBPROX_GLOB_CTR_TX_ERR_SGSN,
- GBPROX_GLOB_CTR_OTHER_ERR,
-};
-
-enum gbproxy_bvc_ctr {
- GBPROX_PEER_CTR_BLOCKED,
- GBPROX_PEER_CTR_UNBLOCKED,
- GBPROX_PEER_CTR_DROPPED,
- GBPROX_PEER_CTR_INV_NSEI,
- GBPROX_PEER_CTR_TX_ERR,
- GBPROX_PEER_CTR_LAST,
-};
-
-/* global gb-proxy configuration */
-struct gbproxy_config {
- /* NS instance of libosmogb */
- struct gprs_ns2_inst *nsi;
-
- struct {
- /* percentage of BVC flow control advertised to each SGSN in the pool */
- uint8_t bvc_fc_ratio;
- /* NRI bitlen and usable NULL-NRI ranges */
- uint8_t nri_bitlen;
- struct osmo_nri_ranges *null_nri_ranges;
-
- /* Used for testing: If not NULL then this SGSN is returned by
- * gbproxy_sgsn_by_tlli() */
- struct gbproxy_sgsn *nsf_override;
- } pool;
-
- /* hash table of all BSS side Gb peers */
- DECLARE_HASHTABLE(bss_nses, 8);
-
- /* hash table of all SGSN-side Gb peers */
- DECLARE_HASHTABLE(sgsn_nses, 8);
-
- /* hash table of all gbproxy_cell */
- DECLARE_HASHTABLE(cells, 8);
-
- /* tlli<->nse cache used to map SUSPEND/RESUME (N)ACKS */
- struct {
- DECLARE_HASHTABLE(entries, 10);
- struct osmo_timer_list timer;
- /* Time in seconds that the entries should be valid */
- uint8_t timeout;
- } tlli_cache;
-
- /* imsi<->nse cache used for PAGING REJECT */
- struct {
- DECLARE_HASHTABLE(entries, 10);
- struct osmo_timer_list timer;
- /* Time in seconds that the entries should be valid */
- uint8_t timeout;
- } imsi_cache;
-
- /* List of all SGSNs */
- struct llist_head sgsns;
-
- /* Counter */
- struct rate_ctr_group *ctrg;
-};
-
-/* One Cell within the BSS: Links BSS-side BVC to SGSN-side BVCs */
-struct gbproxy_cell {
- /* linked to gbproxy_config.cells hashtable */
- struct hlist_node list;
-
- /* point back to the config */
- struct gbproxy_config *cfg;
-
- /* BVCI of PTP BVCs associated to this cell */
- uint16_t bvci;
-
- /* Routing Area that this BVC is part of (raw 04.08 encoding) */
- uint8_t ra[6];
-
- /* pointer to the BSS-side BVC */
- struct gbproxy_bvc *bss_bvc;
-
- /* pointers to SGSN-side BVC (one for each pool member) */
- struct gbproxy_bvc *sgsn_bvc[GBPROXY_MAX_NR_SGSN];
-};
-
-/* One BVC inside an NSE */
-struct gbproxy_bvc {
- /* linked to gbproxy_nse.bvcs */
- struct hlist_node list;
-
- /* The NSE this BVC belongs to */
- struct gbproxy_nse *nse;
-
- /* PTP BVCI of this BVC */
- uint16_t bvci;
-
- /* Routing Area that this BVC is part of (raw 04.08 encoding) */
- uint8_t ra[6];
-
- /* Counter */
- struct rate_ctr_group *ctrg;
-
- /* the cell to which this BVC belongs */
- struct gbproxy_cell *cell;
-
- /* per-BVC FSM instance */
- struct osmo_fsm_inst *fi;
-};
-
-/* one NS Entity that we interact with (BSS/PCU) */
-struct gbproxy_nse {
- /* linked to gbproxy_config.bss_nses */
- struct hlist_node list;
-
- /* point back to the config */
- struct gbproxy_config *cfg;
-
- /* NSEI of the NSE */
- uint16_t nsei;
-
- /* Are we facing towards a SGSN (true) or BSS (false) */
- bool sgsn_facing;
-
- /* List of all BVCs in this NSE */
- DECLARE_HASHTABLE(bvcs, 10);
-};
-
-/* SGSN configuration such as pool options (only for NSE where sgsn_facing == true) */
-struct gbproxy_sgsn {
- /* linked to gbproxy_config.sgsns */
- struct llist_head list;
-
- /* The NSE belonging to this SGSN */
- struct gbproxy_nse *nse;
-
- /* Name of the SGSN */
- char *name;
-
- /* Pool configuration for the sgsn (only valid if sgsn_facing == true) */
- struct {
- bool allow_attach;
- struct osmo_nri_ranges *nri_ranges;
- } pool;
-};
-
-/* TLLI cache */
-struct gbproxy_tlli_cache_entry {
- /* linked to gbproxy_config.tlli_cache.entries */
- struct hlist_node list;
-
- /* TLLI of the entry */
- uint32_t tlli;
- /* When was this entry last seen */
- time_t tstamp;
- /* The Cell this TLLI was last seen */
- struct gbproxy_nse *nse;
-};
-
-/* IMSI cache */
-struct gbproxy_imsi_cache_entry {
- /* linked to gbproxy_config.imsi_cache.entries */
- struct hlist_node list;
-
- /* IMSI of the entry */
- char imsi[OSMO_IMSI_BUF_SIZE];
- /* When was this entry last seen */
- time_t tstamp;
- /* The SGSN where the request came from */
- struct gbproxy_nse *nse;
-};
-
-/* Convenience logging macros for NSE/BVC */
-#define LOGPNSE_CAT(NSE, SUBSYS, LEVEL, FMT, ARGS...) \
- LOGP(SUBSYS, LEVEL, "NSE(%05u/%s) " FMT, (NSE)->nsei, \
- (NSE)->sgsn_facing ? "SGSN" : "BSS", ## ARGS)
-#define LOGPNSE(NSE, LEVEL, FMT, ARGS...) \
- LOGPNSE_CAT(NSE, DGPRS, LEVEL, FMT, ## ARGS)
-
-#define LOGPBVC_CAT(BVC, SUBSYS, LEVEL, FMT, ARGS...) \
- LOGP(SUBSYS, LEVEL, "NSE(%05u/%s)-BVC(%05u/%s) " FMT, (BVC)->nse->nsei, \
- (BVC)->nse->sgsn_facing ? "SGSN" : "BSS", (BVC)->bvci, \
- osmo_fsm_inst_state_name((BVC)->fi), ## ARGS)
-#define LOGPBVC(BVC, LEVEL, FMT, ARGS...) \
- LOGPBVC_CAT(BVC, DGPRS, LEVEL, FMT, ## ARGS)
-
-#define LOGPCELL_CAT(CELL, SUBSYS, LEVEL, FMT, ARGS...) \
- LOGP(SUBSYS, LEVEL, "CELL(%05u) " FMT, (CELL)->bvci, ## ARGS)
-#define LOGPCELL(CELL, LEVEL, FMT, ARGS...) \
- LOGPCELL_CAT(CELL, DGPRS, LEVEL, FMT, ## ARGS)
-
-#define LOGPSGSN_CAT(SGSN, SUBSYS, LEVEL, FMT, ARGS...) \
- LOGP(SUBSYS, LEVEL, "NSE(%05u)-SGSN(%s) " FMT, (SGSN)->nse->nsei, (SGSN)->name, ## ARGS)
-#define LOGPSGSN(SGSN, LEVEL, FMT, ARGS...) \
- LOGPSGSN_CAT(SGSN, DGPRS, LEVEL, FMT, ## ARGS)
-
-/* gb_proxy_vty .c */
-
-int gbproxy_vty_init(void);
-int gbproxy_parse_config(const char *config_file, struct gbproxy_config *cfg);
-
-/* gb_proxy_ctrl.c */
-int gb_ctrl_cmds_install(void);
-
-
-/* gb_proxy.c */
-int gbproxy_init_config(struct gbproxy_config *cfg);
-
-/* Main input function for Gb proxy */
-int gbprox_rcvmsg(void *ctx, struct msgb *msg);
-
-int gbprox_signal(unsigned int subsys, unsigned int signal,
- void *handler_data, void *signal_data);
-
-
-int gprs_ns2_prim_cb(struct osmo_prim_hdr *oph, void *ctx);
-
-void gbprox_reset(struct gbproxy_config *cfg);
-
-/* Peer handling */
-#define NSE_F_SGSN 0x0001
-#define NSE_F_BSS 0x0002
-
-struct gbproxy_bvc *gbproxy_bvc_by_bvci(struct gbproxy_nse *nse, uint16_t bvci);
-struct gbproxy_bvc *gbproxy_bvc_alloc(struct gbproxy_nse *nse, uint16_t bvci);
-void gbproxy_bvc_free(struct gbproxy_bvc *bvc);
-int gbproxy_cleanup_bvcs(struct gbproxy_nse *nse, uint16_t bvci);
-
-struct gbproxy_cell *gbproxy_cell_alloc(struct gbproxy_config *cfg, uint16_t bvci);
-struct gbproxy_cell *gbproxy_cell_by_bvci(struct gbproxy_config *cfg, uint16_t bvci);
-void gbproxy_cell_free(struct gbproxy_cell *cell);
-bool gbproxy_cell_add_sgsn_bvc(struct gbproxy_cell *cell, struct gbproxy_bvc *bvc);
-
-/* NSE handling */
-struct gbproxy_nse *gbproxy_nse_alloc(struct gbproxy_config *cfg, uint16_t nsei, bool sgsn_facing);
-void gbproxy_nse_free(struct gbproxy_nse *nse);
-struct gbproxy_nse *gbproxy_nse_by_nsei(struct gbproxy_config *cfg, uint16_t nsei, uint32_t flags);
-struct gbproxy_nse *gbproxy_nse_by_nsei_or_new(struct gbproxy_config *cfg, uint16_t nsei, bool sgsn_facing);
-struct gbproxy_nse *gbproxy_nse_by_tlli(struct gbproxy_config *cfg, uint32_t tlli);
-struct gbproxy_nse *gbproxy_nse_by_imsi(struct gbproxy_config *cfg, const char *imsi);
-
-/* TLLI cache */
-void gbproxy_tlli_cache_update(struct gbproxy_nse *nse, uint32_t tlli);
-void gbproxy_tlli_cache_remove(struct gbproxy_config *cfg, uint32_t tlli);
-int gbproxy_tlli_cache_cleanup(struct gbproxy_config *cfg);
-
-/* IMSI cache */
-void gbproxy_imsi_cache_update(struct gbproxy_nse *nse, const char *imsi);
-void gbproxy_imsi_cache_remove(struct gbproxy_config *cfg, const char *imsi);
-int gbproxy_imsi_cache_cleanup(struct gbproxy_config *cfg);
-
-/* SGSN handling */
-struct gbproxy_sgsn *gbproxy_sgsn_alloc(struct gbproxy_config *cfg, uint16_t nsei, const char *name);
-void gbproxy_sgsn_free(struct gbproxy_sgsn *sgsn);
-struct gbproxy_sgsn *gbproxy_sgsn_by_name(struct gbproxy_config *cfg, const char *name);
-struct gbproxy_sgsn *gbproxy_sgsn_by_nsei(struct gbproxy_config *cfg, uint16_t nsei);
-struct gbproxy_sgsn *gbproxy_sgsn_by_nsei_or_new(struct gbproxy_config *cfg, uint16_t nsei);
-struct gbproxy_sgsn *gbproxy_sgsn_by_nri(struct gbproxy_config *cfg, uint16_t nri, bool *null_nri);
-struct gbproxy_sgsn *gbproxy_sgsn_by_tlli(struct gbproxy_config *cfg, struct gbproxy_sgsn *sgsn_avoid,
- uint32_t tlli);
-
-#endif
diff --git a/osmoappdesc.py b/osmoappdesc.py
index 1fccafd7f..c3275978b 100644
--- a/osmoappdesc.py
+++ b/osmoappdesc.py
@@ -16,18 +16,16 @@
app_configs = {
- "gbproxy": ["doc/examples/osmo-gbproxy/osmo-gbproxy.cfg"],
"sgsn": ["doc/examples/osmo-sgsn/osmo-sgsn.cfg"],
"gtphub": ["doc/examples/osmo-gtphub/osmo-gtphub-1iface.cfg"]
}
-apps = [(4246, "src/gbproxy/osmo-gbproxy", "OsmoGbProxy", "gbproxy"),
- (4245, "src/sgsn/osmo-sgsn", "OsmoSGSN", "sgsn"),
+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_app = apps[1]
+vty_app = apps[0]
diff --git a/src/Makefile.am b/src/Makefile.am
index c45d3ab46..e389b7f65 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,6 +1,5 @@
SUBDIRS = \
gprs \
sgsn \
- gbproxy \
gtphub \
$(NULL)
diff --git a/src/gbproxy/Makefile.am b/src/gbproxy/Makefile.am
deleted file mode 100644
index 1500e1173..000000000
--- a/src/gbproxy/Makefile.am
+++ /dev/null
@@ -1,40 +0,0 @@
-AM_CPPFLAGS = \
- $(all_includes) \
- -I$(top_srcdir)/include \
- -I$(top_builddir) \
- $(NULL)
-
-AM_CFLAGS = \
- -Wall \
- -fno-strict-aliasing \
- $(LIBOSMOCORE_CFLAGS) \
- $(LIBOSMOGSM_CFLAGS) \
- $(LIBOSMOVTY_CFLAGS) \
- $(LIBOSMOCTRL_CFLAGS) \
- $(LIBOSMOABIS_CFLAGS) \
- $(LIBOSMOGB_CFLAGS) \
- $(LIBOSMOGSUPCLIENT_CFLAGS) \
- $(COVERAGE_CFLAGS) \
- $(LIBGTP_CFLAGS) \
- $(NULL)
-
-bin_PROGRAMS = \
- osmo-gbproxy \
- $(NULL)
-
-osmo_gbproxy_SOURCES = \
- gb_proxy.c \
- gb_proxy_main.c \
- gb_proxy_vty.c \
- gb_proxy_ctrl.c \
- gb_proxy_peer.c \
- $(NULL)
-osmo_gbproxy_LDADD = \
- $(LIBOSMOCORE_LIBS) \
- $(LIBOSMOGSM_LIBS) \
- $(LIBOSMOVTY_LIBS) \
- $(LIBOSMOCTRL_LIBS) \
- $(LIBOSMOGB_LIBS) \
- $(LIBGTP_LIBS) \
- -lrt \
- $(NULL)
diff --git a/src/gbproxy/gb_proxy.c b/src/gbproxy/gb_proxy.c
deleted file mode 100644
index c882eb068..000000000
--- a/src/gbproxy/gb_proxy.c
+++ /dev/null
@@ -1,1549 +0,0 @@
-/* NS-over-IP proxy */
-
-/* (C) 2010-2020 by Harald Welte <laforge@gnumonks.org>
- * (C) 2010-2013 by On-Waves
- * (C) 2013 by Holger Hans Peter Freyther
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <getopt.h>
-#include <errno.h>
-#include <sys/fcntl.h>
-#include <sys/stat.h>
-#include <arpa/inet.h>
-#include <time.h>
-
-#include <osmocom/core/hashtable.h>
-#include <osmocom/core/logging.h>
-#include <osmocom/core/linuxlist.h>
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/select.h>
-#include <osmocom/core/rate_ctr.h>
-#include <osmocom/core/stats.h>
-#include <osmocom/core/utils.h>
-
-#include <osmocom/gprs/gprs_ns2.h>
-#include <osmocom/gprs/gprs_bssgp.h>
-#include <osmocom/gprs/gprs_bssgp2.h>
-#include <osmocom/gprs/gprs_bssgp_bss.h>
-#include <osmocom/gprs/bssgp_bvc_fsm.h>
-
-#include <osmocom/gsm/gsm23236.h>
-#include <osmocom/gsm/gsm_utils.h>
-
-#include <osmocom/sgsn/signal.h>
-#include <osmocom/sgsn/debug.h>
-#include <osmocom/sgsn/gprs_gb_parse.h>
-#include <osmocom/sgsn/gb_proxy.h>
-
-#include <osmocom/sgsn/gprs_llc.h>
-#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
-#include <osmocom/sgsn/gprs_utils.h>
-
-extern void *tall_sgsn_ctx;
-
-static const struct rate_ctr_desc global_ctr_description[] = {
- { "inv-bvci", "Invalid BVC Identifier " },
- { "inv-lai", "Invalid Location Area Identifier" },
- { "inv-rai", "Invalid Routing Area Identifier " },
- { "inv-nsei", "No BVC established for NSEI " },
- { "proto-err:bss", "BSSGP protocol error (BSS )" },
- { "proto-err:sgsn", "BSSGP protocol error (SGSN)" },
- { "not-supp:bss", "Feature not supported (BSS )" },
- { "not-supp:sgsn", "Feature not supported (SGSN)" },
- { "restart:sgsn", "Restarted RESET procedure (SGSN)" },
- { "tx-err:sgsn", "NS Transmission error (SGSN)" },
- { "error", "Other error " },
- { "mod-peer-err", "Patch error: no peer " },
-};
-
-static const struct rate_ctr_group_desc global_ctrg_desc = {
- .group_name_prefix = "gbproxy:global",
- .group_description = "GBProxy Global Statistics",
- .num_ctr = ARRAY_SIZE(global_ctr_description),
- .ctr_desc = global_ctr_description,
- .class_id = OSMO_STATS_CLASS_GLOBAL,
-};
-
-static int gbprox_relay2peer(struct msgb *old_msg, struct gbproxy_bvc *bvc,
- uint16_t ns_bvci);
-
-
-/* generate BVC-STATUS message with cause value derived from TLV-parser error */
-static int tx_status_from_tlvp(enum osmo_tlv_parser_error tlv_p_err, struct msgb *orig_msg)
-{
- uint8_t bssgp_cause;
- switch (tlv_p_err) {
- case OSMO_TLVP_ERR_MAND_IE_MISSING:
- bssgp_cause = BSSGP_CAUSE_MISSING_MAND_IE;
- break;
- default:
- bssgp_cause = BSSGP_CAUSE_PROTO_ERR_UNSPEC;
- }
- return bssgp_tx_status(bssgp_cause, NULL, orig_msg);
-}
-
-/* strip off the NS header */
-static void strip_ns_hdr(struct msgb *msg)
-{
- int strip_len = msgb_bssgph(msg) - msg->data;
- msgb_pull(msg, strip_len);
-}
-
-#if 0
-/* feed a message down the NS-VC associated with the specified bvc */
-static int gbprox_relay2sgsn(struct gbproxy_config *cfg, struct msgb *old_msg,
- uint16_t ns_bvci, uint16_t sgsn_nsei)
-{
- /* create a copy of the message so the old one can
- * be free()d safely when we return from gbprox_rcvmsg() */
- struct gprs_ns2_inst *nsi = cfg->nsi;
- struct osmo_gprs_ns2_prim nsp = {};
- struct msgb *msg = bssgp_msgb_copy(old_msg, "msgb_relay2sgsn");
- int rc;
-
- DEBUGP(DGPRS, "NSE(%05u/BSS)-BVC(%05u) proxying BTS->SGSN NSE(%05u/SGSN)\n",
- msgb_nsei(msg), ns_bvci, sgsn_nsei);
-
- nsp.bvci = ns_bvci;
- nsp.nsei = sgsn_nsei;
-
- strip_ns_hdr(msg);
- osmo_prim_init(&nsp.oph, SAP_NS, PRIM_NS_UNIT_DATA,
- PRIM_OP_REQUEST, msg);
- rc = gprs_ns2_recv_prim(nsi, &nsp.oph);
- if (rc < 0)
- rate_ctr_inc(&cfg->ctrg->ctr[GBPROX_GLOB_CTR_TX_ERR_SGSN]);
- return rc;
-}
-#endif
-
-/*! Determine the TLLI from the given BSSGP message.
- * \param[in] bssgp pointer to start of BSSGP header
- * \param[in] bssgp_len length of BSSGP message in octets
- * \param[out] tlli TLLI (if any) in host byte order
- * \returns 1 if TLLI found; 0 if none found; negative on parse error */
-int gprs_gb_parse_tlli(const uint8_t *bssgp, size_t bssgp_len, uint32_t *tlli)
-{
- const struct bssgp_normal_hdr *bgph;
- uint8_t pdu_type;
-
- if (bssgp_len < sizeof(struct bssgp_normal_hdr))
- return -EINVAL;
-
- bgph = (struct bssgp_normal_hdr *)bssgp;
- pdu_type = bgph->pdu_type;
-
- if (pdu_type == BSSGP_PDUT_UL_UNITDATA ||
- pdu_type == BSSGP_PDUT_DL_UNITDATA) {
- const struct bssgp_ud_hdr *budh = (struct bssgp_ud_hdr *)bssgp;
- if (bssgp_len < sizeof(struct bssgp_ud_hdr))
- return -EINVAL;
- *tlli = osmo_load32be((const uint8_t *)&budh->tlli);
- return 1;
- } else {
- const uint8_t *data = bgph->data;
- size_t data_len = bssgp_len - sizeof(*bgph);
- struct tlv_parsed tp;
-
- if (bssgp_tlv_parse(&tp, data, data_len) < 0)
- return -EINVAL;
-
- if (TLVP_PRESENT(&tp, BSSGP_IE_TLLI)) {
- *tlli = osmo_load32be(TLVP_VAL(&tp, BSSGP_IE_TLLI));
- return 1;
- }
- }
-
- /* No TLLI present in message */
- return 0;
-}
-
-/* feed a message down the NSE */
-static int gbprox_relay2nse(struct msgb *old_msg, struct gbproxy_nse *nse,
- uint16_t ns_bvci)
-{
- OSMO_ASSERT(nse);
- OSMO_ASSERT(nse->cfg);
-
- /* create a copy of the message so the old one can
- * be free()d safely when we return from gbprox_rcvmsg() */
- struct gprs_ns2_inst *nsi = nse->cfg->nsi;
- struct osmo_gprs_ns2_prim nsp = {};
- struct msgb *msg = bssgp_msgb_copy(old_msg, "msgb_relay2nse");
- uint32_t tlli;
- int rc;
-
- DEBUGP(DGPRS, "NSE(%05u/%s)-BVC(%05u/??) proxying to NSE(%05u/%s)\n", msgb_nsei(msg),
- !nse->sgsn_facing ? "SGSN" : "BSS", ns_bvci, nse->nsei, nse->sgsn_facing ? "SGSN" : "BSS");
-
- nsp.bvci = ns_bvci;
- nsp.nsei = nse->nsei;
-
- /* Strip the old NS header, it will be replaced with a new one */
- strip_ns_hdr(msg);
-
- /* TS 48.018 Section 5.4.2: The link selector parameter is
- * defined in 3GPP TS 48.016. At one side of the Gb interface,
- * all BSSGP UNITDATA PDUs related to an MS shall be passed with
- * the same LSP, e.g. the LSP contains the MS's TLLI, to the
- * underlying network service. */
- if (gprs_gb_parse_tlli(msgb_data(msg), msgb_length(msg), &tlli) == 1)
- nsp.u.unitdata.link_selector = tlli;
-
- osmo_prim_init(&nsp.oph, SAP_NS, GPRS_NS2_PRIM_UNIT_DATA,
- PRIM_OP_REQUEST, msg);
- rc = gprs_ns2_recv_prim(nsi, &nsp.oph);
- /* FIXME: We need a counter group for gbproxy_nse */
- //if (rc < 0)
- // rate_ctr_inc(&bvc->ctrg->ctr[GBPROX_PEER_CTR_TX_ERR]);
-
- return rc;
-}
-
-/* feed a message down the NS-VC associated with the specified bvc */
-static int gbprox_relay2peer(struct msgb *old_msg, struct gbproxy_bvc *bvc,
- uint16_t ns_bvci)
-{
- int rc;
- struct gbproxy_nse *nse = bvc->nse;
- OSMO_ASSERT(nse);
-
- rc = gbprox_relay2nse(old_msg, nse, ns_bvci);
- if (rc < 0)
- rate_ctr_inc(&bvc->ctrg->ctr[GBPROX_PEER_CTR_TX_ERR]);
-
- return rc;
-}
-
-int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
-{
- return 0;
-}
-
-
-/***********************************************************************
- * PTP BVC handling
- ***********************************************************************/
-
-/* FIXME: Handle the tlli NULL case correctly,
- * This function should take a generic selector
- * and choose an sgsn based on that
- */
-static struct gbproxy_sgsn *gbproxy_select_sgsn(struct gbproxy_config *cfg, const uint32_t *tlli)
-{
- struct gbproxy_sgsn *sgsn = NULL;
- struct gbproxy_sgsn *sgsn_avoid = NULL;
-
- int tlli_type;
- int16_t nri;
- bool null_nri = false;
-
- if (!tlli) {
- sgsn = llist_first_entry(&cfg->sgsns, struct gbproxy_sgsn, list);
- if (!sgsn) {
- return NULL;
- }
- LOGPSGSN(sgsn, LOGL_INFO, "Could not get TLLI, using first SGSN\n");
- return sgsn;
- }
-
- if (cfg->pool.nri_bitlen == 0) {
- /* Pooling is disabled */
- sgsn = llist_first_entry(&cfg->sgsns, struct gbproxy_sgsn, list);
- if (!sgsn) {
- return NULL;
- }
-
- LOGPSGSN(sgsn, LOGL_INFO, "Pooling disabled, using first configured SGSN\n");
- } else {
- /* Pooling is enabled, try to use the NRI for routing to an SGSN
- * See 3GPP TS 23.236 Ch. 5.3.2 */
- tlli_type = gprs_tlli_type(*tlli);
- if (tlli_type == TLLI_LOCAL || tlli_type == TLLI_FOREIGN) {
- /* Only get/use the NRI if tlli type is local */
- osmo_tmsi_nri_v_get(&nri, *tlli, cfg->pool.nri_bitlen);
- if (nri >= 0) {
- /* Get the SGSN for the NRI */
- sgsn = gbproxy_sgsn_by_nri(cfg, nri, &null_nri);
- if (sgsn && !null_nri)
- return sgsn;
- /* If the NRI is the null NRI, we need to avoid the chosen SGSN */
- if (null_nri && sgsn) {
- sgsn_avoid = sgsn;
- }
- } else {
- /* We couldn't get the NRI from the TLLI */
- LOGP(DGPRS, LOGL_ERROR, "Could not extract NRI from local TLLI %08x\n", *tlli);
- }
- } else {
- LOGP(DGPRS, LOGL_INFO, "TLLI %08x is neither local nor foreign, not routing by NRI\n", *tlli);
- }
- }
-
- /* If we haven't found an SGSN yet we need to choose one, but avoid the one in sgsn_avoid
- * NOTE: This function is not stable if the number of SGSNs or allow_attach changes
- * We could implement TLLI tracking here, but 3GPP TS 23.236 Ch. 5.3.2 (see NOTE) argues that
- * we can just wait for the MS to reattempt the procedure.
- */
- if (!sgsn)
- sgsn = gbproxy_sgsn_by_tlli(cfg, sgsn_avoid, *tlli);
-
- if (!sgsn) {
- LOGP(DGPRS, LOGL_ERROR, "No suitable SGSN found for TLLI %u\n", *tlli);
- return NULL;
- }
-
- return sgsn;
-}
-
-/*! Find the correct gbproxy_bvc given a cell and an SGSN
- * \param[in] cfg The gbproxy configuration
- * \param[in] cell The cell the message belongs to
- * \param[in] tlli An optional TLLI used for tracking
- * \return Returns 0 on success, otherwise a negative value
- */
-static struct gbproxy_bvc *gbproxy_select_sgsn_bvc(struct gbproxy_config *cfg, struct gbproxy_cell *cell, const uint32_t *tlli)
-{
- struct gbproxy_sgsn *sgsn;
- struct gbproxy_bvc *sgsn_bvc = NULL;
- int i;
-
- sgsn = gbproxy_select_sgsn(cfg, tlli);
- if (!sgsn) {
- LOGPCELL(cell, LOGL_ERROR, "Could not find any SGSN, dropping message!\n");
- return NULL;
- }
-
- /* Get the BVC for this SGSN/NSE */
- for (i = 0; i < ARRAY_SIZE(cell->sgsn_bvc); i++) {
- sgsn_bvc = cell->sgsn_bvc[i];
- if (!sgsn_bvc)
- continue;
- if (sgsn->nse != sgsn_bvc->nse)
- continue;
-
- return sgsn_bvc;
- }
-
- /* This shouldn't happen */
- LOGPCELL(cell, LOGL_ERROR, "Could not find matching BVC for SGSN %s, dropping message!\n", sgsn->name);
- return NULL;
-}
-
-/*! Send a message to the next SGSN, possibly ignoring the null SGSN
- * route an uplink message on a PTP-BVC to a SGSN using the TLLI
- * \param[in] cell The cell the message belongs to
- * \param[in] msg The BSSGP message
- * \param[in] null_sgsn If not NULL then avoid this SGSN (because this message contains its null NRI)
- * \param[in] tlli An optional TLLI used for tracking
- * \return Returns 0 on success, otherwise a negative value
- */
-static int gbprox_bss2sgsn_tlli(struct gbproxy_cell *cell, struct msgb *msg, const uint32_t *tlli,
- bool sig_bvci)
-{
- struct gbproxy_config *cfg = cell->cfg;
- struct gbproxy_bvc *sgsn_bvc;
-
- sgsn_bvc = gbproxy_select_sgsn_bvc(cfg, cell, tlli);
- if (!sgsn_bvc) {
- LOGPCELL(cell, LOGL_NOTICE, "Could not find any SGSN for TLLI %u, dropping message!\n", *tlli);
- return -EINVAL;
- }
-
- return gbprox_relay2peer(msg, sgsn_bvc, sig_bvci ? 0 : sgsn_bvc->bvci);
-}
-
-/* Receive an incoming PTP message from a BSS-side NS-VC */
-static int gbprox_rx_ptp_from_bss(struct gbproxy_nse *nse, struct msgb *msg, uint16_t ns_bvci)
-{
- struct bssgp_normal_hdr *bgph = (struct bssgp_normal_hdr *) msgb_bssgph(msg);
- const char *pdut_name = osmo_tlv_prot_msg_name(&osmo_pdef_bssgp, bgph->pdu_type);
- struct gbproxy_bvc *bss_bvc;
- struct tlv_parsed tp;
- char log_pfx[32];
- uint32_t tlli;
- int rc;
-
- snprintf(log_pfx, sizeof(log_pfx), "NSE(%05u/BSS)-BVC(%05u/??)", nse->nsei, ns_bvci);
-
- LOGP(DGPRS, LOGL_DEBUG, "%s Rx %s\n", log_pfx, pdut_name);
-
- if (ns_bvci == 0 || ns_bvci == 1) {
- LOGP(DGPRS, LOGL_NOTICE, "%s BVCI=%05u is not PTP\n", log_pfx, ns_bvci);
- return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg);
- }
-
- if (!(bssgp_pdu_type_flags(bgph->pdu_type) & BSSGP_PDUF_PTP)) {
- LOGP(DGPRS, LOGL_NOTICE, "%s %s not allowed in PTP BVC\n", log_pfx, pdut_name);
- return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg);
- }
-
- if (!(bssgp_pdu_type_flags(bgph->pdu_type) & BSSGP_PDUF_UL)) {
- LOGP(DGPRS, LOGL_NOTICE, "%s %s not allowed in uplink direction\n", log_pfx, pdut_name);
- return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg);
- }
-
- bss_bvc = gbproxy_bvc_by_bvci(nse, ns_bvci);
- if (!bss_bvc) {
- LOGP(DGPRS, LOGL_NOTICE, "%s %s - Didn't find BVC for PTP message, discarding\n",
- log_pfx, pdut_name);
- return bssgp_tx_status(BSSGP_CAUSE_UNKNOWN_BVCI, &ns_bvci, msg);
- }
-
- /* UL_UNITDATA has a different header than all other uplink PDUs */
- if (bgph->pdu_type == BSSGP_PDUT_UL_UNITDATA) {
- const struct bssgp_ud_hdr *budh = (struct bssgp_ud_hdr *) msgb_bssgph(msg);
- if (msgb_bssgp_len(msg) < sizeof(*budh))
- return bssgp_tx_status(BSSGP_CAUSE_INV_MAND_INF, NULL, msg);
- rc = osmo_tlv_prot_parse(&osmo_pdef_bssgp, &tp, 1, bgph->pdu_type, budh->data,
- msgb_bssgp_len(msg) - sizeof(*budh), 0, 0, DGPRS, log_pfx);
- /* populate TLLI from the fixed headser into the TLV-parsed array so later code
- * doesn't have to worry where the TLLI came from */
- tp.lv[BSSGP_IE_TLLI].len = 4;
- tp.lv[BSSGP_IE_TLLI].val = (const uint8_t *) &budh->tlli;
- } else {
- rc = osmo_tlv_prot_parse(&osmo_pdef_bssgp, &tp, 1, bgph->pdu_type, bgph->data,
- msgb_bssgp_len(msg) - sizeof(*bgph), 0, 0, DGPRS, log_pfx);
- }
- if (rc < 0) {
- rate_ctr_inc(&nse->cfg->ctrg->ctr[GBPROX_GLOB_CTR_PROTO_ERR_BSS]);
- return tx_status_from_tlvp(rc, msg);
- }
- /* hack to get both msg + tlv_parsed passed via osmo_fsm_inst_dispatch */
- msgb_bcid(msg) = (void *)&tp;
-
- switch (bgph->pdu_type) {
- case BSSGP_PDUT_UL_UNITDATA:
- case BSSGP_PDUT_RA_CAPA_UPDATE:
- case BSSGP_PDUT_FLOW_CONTROL_MS:
- case BSSGP_PDUT_DOWNLOAD_BSS_PFC:
- case BSSGP_PDUT_CREATE_BSS_PFC_ACK:
- case BSSGP_PDUT_CREATE_BSS_PFC_NACK:
- case BSSGP_PDUT_MODIFY_BSS_PFC_ACK:
- case BSSGP_PDUT_DELETE_BSS_PFC_ACK:
- case BSSGP_PDUT_FLOW_CONTROL_PFC:
- case BSSGP_PDUT_DELETE_BSS_PFC_REQ:
- case BSSGP_PDUT_PS_HO_REQUIRED:
- case BSSGP_PDUT_PS_HO_REQUEST_ACK:
- case BSSGP_PDUT_PS_HO_REQUEST_NACK:
- case BSSGP_PDUT_PS_HO_COMPLETE:
- case BSSGP_PDUT_PS_HO_CANCEL:
- /* We can route based on TLLI-NRI */
- tlli = osmo_load32be(TLVP_VAL(&tp, BSSGP_IE_TLLI));
- rc = gbprox_bss2sgsn_tlli(bss_bvc->cell, msg, &tlli, false);
- break;
- case BSSGP_PDUT_RADIO_STATUS:
- if (TLVP_PRESENT(&tp, BSSGP_IE_TLLI)) {
- tlli = osmo_load32be(TLVP_VAL(&tp, BSSGP_IE_TLLI));
- rc = gbprox_bss2sgsn_tlli(bss_bvc->cell, msg, &tlli, false);
- } else if (TLVP_PRESENT(&tp, BSSGP_IE_TMSI)) {
- /* we treat the TMSI like a TLLI and extract the NRI from it */
- tlli = osmo_load32be(TLVP_VAL(&tp, BSSGP_IE_TMSI));
- /* Convert the TMSI into a FOREIGN TLLI so it is routed appropriately */
- tlli = gprs_tmsi2tlli(tlli, TLLI_FOREIGN);
- rc = gbprox_bss2sgsn_tlli(bss_bvc->cell, msg, &tlli, false);
- } else if (TLVP_PRESENT(&tp, BSSGP_IE_IMSI)) {
- /* FIXME: Use the IMSI as selector? */
- rc = gbprox_bss2sgsn_tlli(bss_bvc->cell, msg, NULL, false);
- /* rc = gbprox_bss2sgsn_hashed(bss_bvc->cell, msg, NULL); */
- } else
- LOGPBVC(bss_bvc, LOGL_ERROR, "Rx RADIO-STATUS without any of the conditional IEs\n");
- break;
- case BSSGP_PDUT_DUMMY_PAGING_PS_RESP:
- case BSSGP_PDUT_PAGING_PS_REJECT:
- {
- /* Route according to IMSI<->NSE cache entry */
- struct osmo_mobile_identity mi;
- const uint8_t *mi_data = TLVP_VAL(&tp, BSSGP_IE_IMSI);
- uint8_t mi_len = TLVP_LEN(&tp, BSSGP_IE_IMSI);
- osmo_mobile_identity_decode(&mi, mi_data, mi_len, false);
- nse = gbproxy_nse_by_imsi(nse->cfg, mi.imsi);
- if (nse) {
- OSMO_ASSERT(nse->sgsn_facing);
- rc = gbprox_relay2nse(msg, nse, ns_bvci);
- } else {
- LOGPBVC(bss_bvc, LOGL_ERROR, "Rx unmatched %s with IMSI %s\n", pdut_name, mi.imsi);
- }
- break;
- }
- case BSSGP_PDUT_FLOW_CONTROL_BVC:
- osmo_fsm_inst_dispatch(bss_bvc->fi, BSSGP_BVCFSM_E_RX_FC_BVC, msg);
- break;
- case BSSGP_PDUT_STATUS:
- /* TODO: Implement by inspecting the contained PDU */
- if (!TLVP_PRESENT(&tp, BSSGP_IE_PDU_IN_ERROR))
- break;
- LOGPBVC(bss_bvc, LOGL_ERROR, "Rx %s: Implementation missing\n", pdut_name);
- break;
- }
-
- return 0;
-}
-
-/* Receive an incoming PTP message from a SGSN-side NS-VC */
-static int gbprox_rx_ptp_from_sgsn(struct gbproxy_nse *nse, struct msgb *msg, uint16_t ns_bvci)
-{
- struct bssgp_normal_hdr *bgph = (struct bssgp_normal_hdr *) msgb_bssgph(msg);
- const char *pdut_name = osmo_tlv_prot_msg_name(&osmo_pdef_bssgp, bgph->pdu_type);
- struct gbproxy_bvc *sgsn_bvc, *bss_bvc;
- struct tlv_parsed tp;
- char log_pfx[32];
- int rc;
-
- snprintf(log_pfx, sizeof(log_pfx), "NSE(%05u/SGSN)-BVC(%05u/??)", nse->nsei, ns_bvci);
-
- LOGP(DGPRS, LOGL_DEBUG, "%s Rx %s\n", log_pfx, pdut_name);
-
- if (ns_bvci == 0 || ns_bvci == 1) {
- LOGP(DGPRS, LOGL_NOTICE, "%s BVCI is not PTP\n", log_pfx);
- return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg);
- }
-
- if (!(bssgp_pdu_type_flags(bgph->pdu_type) & BSSGP_PDUF_PTP)) {
- LOGP(DGPRS, LOGL_NOTICE, "%s %s not allowed in PTP BVC\n", log_pfx, pdut_name);
- return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg);
- }
-
- if (!(bssgp_pdu_type_flags(bgph->pdu_type) & BSSGP_PDUF_DL)) {
- LOGP(DGPRS, LOGL_NOTICE, "%s %s not allowed in downlink direction\n", log_pfx, pdut_name);
- return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg);
- }
-
- sgsn_bvc = gbproxy_bvc_by_bvci(nse, ns_bvci);
- if (!sgsn_bvc) {
- LOGP(DGPRS, LOGL_NOTICE, "%s %s - Didn't find BVC for for PTP message, discarding\n",
- log_pfx, pdut_name);
- rate_ctr_inc(&nse->cfg->ctrg-> ctr[GBPROX_GLOB_CTR_INV_BVCI]);
- return bssgp_tx_status(BSSGP_CAUSE_UNKNOWN_BVCI, &ns_bvci, msg);
- }
-
- if (!bssgp_bvc_fsm_is_unblocked(sgsn_bvc->fi)) {
- LOGPBVC(sgsn_bvc, LOGL_NOTICE, "Rx %s: Dropping on blocked BVC\n", pdut_name);
- rate_ctr_inc(&sgsn_bvc->ctrg->ctr[GBPROX_PEER_CTR_DROPPED]);
- return bssgp_tx_status(BSSGP_CAUSE_BVCI_BLOCKED, &ns_bvci, msg);
- }
-
- /* DL_UNITDATA has a different header than all other uplink PDUs */
- if (bgph->pdu_type == BSSGP_PDUT_DL_UNITDATA) {
- const struct bssgp_ud_hdr *budh = (struct bssgp_ud_hdr *) msgb_bssgph(msg);
- if (msgb_bssgp_len(msg) < sizeof(*budh))
- return bssgp_tx_status(BSSGP_CAUSE_INV_MAND_INF, NULL, msg);
- rc = osmo_tlv_prot_parse(&osmo_pdef_bssgp, &tp, 1, bgph->pdu_type, budh->data,
- msgb_bssgp_len(msg) - sizeof(*budh), 0, 0, DGPRS, log_pfx);
- /* populate TLLI from the fixed headser into the TLV-parsed array so later code
- * doesn't have to worry where the TLLI came from */
- tp.lv[BSSGP_IE_TLLI].len = 4;
- tp.lv[BSSGP_IE_TLLI].val = (const uint8_t *) &budh->tlli;
- } else {
- rc = osmo_tlv_prot_parse(&osmo_pdef_bssgp, &tp, 1, bgph->pdu_type, bgph->data,
- msgb_bssgp_len(msg) - sizeof(*bgph), 0, 0, DGPRS, log_pfx);
- }
- if (rc < 0) {
- rate_ctr_inc(&nse->cfg->ctrg->ctr[GBPROX_GLOB_CTR_PROTO_ERR_BSS]);
- return tx_status_from_tlvp(rc, msg);
- }
- /* hack to get both msg + tlv_parsed passed via osmo_fsm_inst_dispatch */
- msgb_bcid(msg) = (void *)&tp;
-
- OSMO_ASSERT(sgsn_bvc->cell);
- bss_bvc = sgsn_bvc->cell->bss_bvc;
-
- switch (bgph->pdu_type) {
- case BSSGP_PDUT_FLOW_CONTROL_BVC_ACK:
- return osmo_fsm_inst_dispatch(sgsn_bvc->fi, BSSGP_BVCFSM_E_RX_FC_BVC_ACK, msg);
- case BSSGP_PDUT_DUMMY_PAGING_PS:
- case BSSGP_PDUT_PAGING_PS:
- {
- /* Cache the IMSI<->NSE to route PAGING REJECT */
- struct osmo_mobile_identity mi;
- const uint8_t *mi_data = TLVP_VAL(&tp, BSSGP_IE_IMSI);
- uint8_t mi_len = TLVP_LEN(&tp, BSSGP_IE_IMSI);
- osmo_mobile_identity_decode(&mi, mi_data, mi_len, false);
- gbproxy_imsi_cache_update(nse, mi.imsi);
- break;
- }
- default:
- break;
- }
- return gbprox_relay2peer(msg, bss_bvc, bss_bvc->bvci);
-
-}
-
-/***********************************************************************
- * BVC FSM call-backs
- ***********************************************************************/
-
-/* helper function to dispatch a FSM event to all SGSN-side BVC FSMs of a cell */
-static void dispatch_to_all_sgsn_bvc(struct gbproxy_cell *cell, uint32_t event, void *priv)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(cell->sgsn_bvc); i++) {
- struct gbproxy_bvc *sgsn_bvc = cell->sgsn_bvc[i];
- if (!sgsn_bvc)
- continue;
- osmo_fsm_inst_dispatch(sgsn_bvc->fi, event, priv);
- }
-}
-
-/* BVC FSM informs us about a BSS-side reset of the signaling BVC */
-static void bss_sig_bvc_reset_notif(uint16_t nsei, uint16_t bvci, const struct gprs_ra_id *ra_id,
- uint16_t cell_id, uint8_t cause, void *priv)
-{
- struct gbproxy_bvc *sig_bvc = priv;
- struct gbproxy_nse *nse = sig_bvc->nse;
- struct gbproxy_bvc *ptp_bvc;
- unsigned int i;
-
- /* BLOCK all SGSN-side PTP BVC within this NSE */
- hash_for_each(nse->bvcs, i, ptp_bvc, list) {
- if (ptp_bvc == sig_bvc)
- continue;
- OSMO_ASSERT(ptp_bvc->cell);
-
- dispatch_to_all_sgsn_bvc(ptp_bvc->cell, BSSGP_BVCFSM_E_REQ_BLOCK, &cause);
- }
-
- /* Delete all BSS-side PTP BVC within this NSE */
- gbproxy_cleanup_bvcs(nse, 0);
-
- /* TODO: we keep the "CELL" around for now, re-connecting it to
- * any (later) new PTP-BVC for that BVCI. Not sure if that's the
- * best idea ? */
-}
-
-/* forward declaration */
-static const struct bssgp_bvc_fsm_ops sgsn_ptp_bvc_fsm_ops;
-
-static const struct bssgp_bvc_fsm_ops bss_sig_bvc_fsm_ops = {
- .reset_notification = bss_sig_bvc_reset_notif,
-};
-
-/* BVC FSM informs us about a BSS-side reset of a PTP BVC */
-static void bss_ptp_bvc_reset_notif(uint16_t nsei, uint16_t bvci, const struct gprs_ra_id *ra_id,
- uint16_t cell_id, uint8_t cause, void *priv)
-{
- struct gbproxy_bvc *bvc = priv;
- struct gbproxy_config *cfg = bvc->nse->cfg;
- struct gbproxy_nse *sgsn_nse;
- unsigned int i;
-
- OSMO_ASSERT(bvci != 0);
-
- if (!bvc->cell) {
- /* see if we have a CELL dangling around */
- bvc->cell = gbproxy_cell_by_bvci(cfg, bvci);
- if (bvc->cell) {
- /* the CELL already exists. This means either it * was created before at an
- * earlier PTP BVC-RESET, or that there are non-unique BVCIs and hence a
- * malconfiguration */
- if (bvc->cell->bss_bvc) {
- LOGPBVC(bvc, LOGL_NOTICE, "Rx BVC-RESET via this NSE, but CELL already "
- "has BVC on NSEI=%05u\n", bvc->cell->bss_bvc->nse->nsei);
- LOGPBVC(bvc->cell->bss_bvc, LOGL_NOTICE, "Destroying due to conflicting "
- "BVCI configuration (new NSEI=%05u)!\n", bvc->nse->nsei);
- gbproxy_bvc_free(bvc->cell->bss_bvc);
- }
- bvc->cell->bss_bvc = bvc;
- }
- }
-
- if (!bvc->cell) {
- /* if we end up here, it means this is the first time we received a BVC-RESET
- * for this BVC. We need to create the 'cell' data structure and the SGSN-side
- * BVC counterparts */
-
- bvc->cell = gbproxy_cell_alloc(cfg, bvci);
- OSMO_ASSERT(bvc->cell);
- memcpy(bvc->cell->ra, bvc->ra, sizeof(bvc->cell->ra));
-
- /* link us to the cell and vice-versa */
- bvc->cell->bss_bvc = bvc;
- }
-
- /* allocate (any missing) SGSN-side BVCs within the cell, and reset them */
- hash_for_each(cfg->sgsn_nses, i, sgsn_nse, list) {
- struct gbproxy_bvc *sgsn_bvc = gbproxy_bvc_by_bvci(sgsn_nse, bvci);
- if (sgsn_bvc)
- OSMO_ASSERT(sgsn_bvc->cell == bvc->cell || !sgsn_bvc->cell);
-
- if (!sgsn_bvc) {
- sgsn_bvc = gbproxy_bvc_alloc(sgsn_nse, bvci);
- OSMO_ASSERT(sgsn_bvc);
-
- sgsn_bvc->cell = bvc->cell;
- memcpy(sgsn_bvc->ra, bvc->cell->ra, sizeof(sgsn_bvc->ra));
- sgsn_bvc->fi = bssgp_bvc_fsm_alloc_ptp_bss(sgsn_bvc, cfg->nsi, sgsn_nse->nsei,
- bvci, ra_id, cell_id);
- OSMO_ASSERT(sgsn_bvc->fi);
- bssgp_bvc_fsm_set_ops(sgsn_bvc->fi, &sgsn_ptp_bvc_fsm_ops, sgsn_bvc);
-
- gbproxy_cell_add_sgsn_bvc(bvc->cell, sgsn_bvc);
- }
- }
-
- /* Trigger outbound BVC-RESET procedure toward each SGSN */
- dispatch_to_all_sgsn_bvc(bvc->cell, BSSGP_BVCFSM_E_REQ_RESET, &cause);
-}
-
-/* BVC FSM informs us about a BSS-side FSM state change */
-static void bss_ptp_bvc_state_chg_notif(uint16_t nsei, uint16_t bvci, int old_state, int state, void *priv)
-{
- struct gbproxy_bvc *bvc = priv;
- struct gbproxy_cell *cell = bvc->cell;
- uint8_t cause = bssgp_bvc_fsm_get_block_cause(bvc->fi);
-
- /* we have just been created but due to callback ordering the cell is not associated */
- if (!cell)
- return;
-
- switch (state) {
- case BSSGP_BVCFSM_S_BLOCKED:
- /* block the corresponding SGSN-side PTP BVCs */
- dispatch_to_all_sgsn_bvc(cell, BSSGP_BVCFSM_E_REQ_BLOCK, &cause);
- break;
- case BSSGP_BVCFSM_S_UNBLOCKED:
- /* unblock the corresponding SGSN-side PTP BVCs */
- dispatch_to_all_sgsn_bvc(cell, BSSGP_BVCFSM_E_REQ_UNBLOCK, NULL);
- break;
- }
-}
-
-/* BVC FSM informs us about BVC-FC PDU receive */
-static void bss_ptp_bvc_fc_bvc(uint16_t nsei, uint16_t bvci, const struct bssgp2_flow_ctrl *fc, void *priv)
-{
- struct bssgp2_flow_ctrl fc_reduced;
- struct gbproxy_bvc *bss_bvc = priv;
- struct gbproxy_cell *cell;
- struct gbproxy_config *cfg;
-
- OSMO_ASSERT(bss_bvc);
- OSMO_ASSERT(fc);
-
- cell = bss_bvc->cell;
- if (!cell)
- return;
-
- cfg = cell->cfg;
-
- /* reduce / scale according to configuration to make sure we only advertise a fraction
- * of the capacity to each of the SGSNs in the pool */
- fc_reduced = *fc;
- fc_reduced.bucket_size_max = (fc->bucket_size_max * cfg->pool.bvc_fc_ratio) / 100;
- fc_reduced.bucket_leak_rate = (fc->bucket_leak_rate * cfg->pool.bvc_fc_ratio) / 100;
- /* we don't modify the per-MS related values as any single MS is only served by one SGSN */
-
- dispatch_to_all_sgsn_bvc(cell, BSSGP_BVCFSM_E_REQ_FC_BVC, (void *) &fc_reduced);
-}
-
-static const struct bssgp_bvc_fsm_ops bss_ptp_bvc_fsm_ops = {
- .reset_notification = bss_ptp_bvc_reset_notif,
- .state_chg_notification = bss_ptp_bvc_state_chg_notif,
- .rx_fc_bvc = bss_ptp_bvc_fc_bvc,
-};
-
-/* BVC FSM informs us about a SGSN-side reset of a PTP BVC */
-static void sgsn_ptp_bvc_reset_notif(uint16_t nsei, uint16_t bvci, const struct gprs_ra_id *ra_id,
- uint16_t cell_id, uint8_t cause, void *priv)
-{
- struct gbproxy_bvc *bvc = priv;
-
- if (!bvc->cell) {
- LOGPBVC(bvc, LOGL_ERROR, "RESET of PTP BVC on SGSN side for which we have no BSS?\n");
- return;
- }
-
- OSMO_ASSERT(bvc->cell->bss_bvc);
-
- /* request reset of BSS-facing PTP-BVC */
- osmo_fsm_inst_dispatch(bvc->cell->bss_bvc->fi, BSSGP_BVCFSM_E_REQ_RESET, &cause);
-}
-
-static const struct bssgp_bvc_fsm_ops sgsn_ptp_bvc_fsm_ops = {
- .reset_notification = sgsn_ptp_bvc_reset_notif,
-};
-
-/* BVC FSM informs us about a SGSN-side reset of the signaling BVC */
-static void sgsn_sig_bvc_reset_notif(uint16_t nsei, uint16_t bvci, const struct gprs_ra_id *ra_id,
- uint16_t cell_id, uint8_t cause, void *priv)
-{
- struct gbproxy_bvc *bvc = priv;
- struct gbproxy_config *cfg = bvc->nse->cfg;
- struct gbproxy_nse *bss_nse;
- unsigned int i;
-
- /* delete all SGSN-side PTP BVC for this SGSN */
- gbproxy_cleanup_bvcs(bvc->nse, 0);
- /* FIXME: what to do about the cells? */
- /* FIXME: do we really want to RESET all signaling BVC on the BSS and affect all other SGSN? */
-
- /* we need to trigger generating a reset procedure towards each BSS side signaling BVC */
- hash_for_each(cfg->bss_nses, i, bss_nse, list) {
- struct gbproxy_bvc *bss_bvc = gbproxy_bvc_by_bvci(bss_nse, 0);
- if (!bss_bvc) {
- LOGPNSE(bss_nse, LOGL_ERROR, "Doesn't have BVC with BVCI=0 ?!?\n");
- continue;
- }
- osmo_fsm_inst_dispatch(bss_bvc->fi, BSSGP_BVCFSM_E_REQ_RESET, &cause);
- }
-}
-
-const struct bssgp_bvc_fsm_ops sgsn_sig_bvc_fsm_ops = {
- .reset_notification = sgsn_sig_bvc_reset_notif,
-};
-
-/***********************************************************************
- * Signaling BVC handling
- ***********************************************************************/
-
-/* process a BVC-RESET message from the BSS side */
-static int rx_bvc_reset_from_bss(struct gbproxy_nse *nse, struct msgb *msg, struct tlv_parsed *tp)
-{
- struct gbproxy_bvc *from_bvc = NULL;
- uint16_t bvci = ntohs(tlvp_val16_unal(tp, BSSGP_IE_BVCI));
- uint32_t features = 0; // FIXME: make configurable
-
- LOGPNSE(nse, LOGL_INFO, "Rx BVC-RESET (BVCI=%05u)\n", bvci);
-
- if (bvci == 0) {
- /* If we receive a BVC reset on the signalling endpoint, we
- * don't want the SGSN to reset, as the signalling endpoint
- * is common for all point-to-point BVCs (and thus all BTS) */
-
- from_bvc = gbproxy_bvc_by_bvci(nse, 0);
- if (!from_bvc) {
- from_bvc = gbproxy_bvc_alloc(nse, 0);
- OSMO_ASSERT(from_bvc);
- from_bvc->fi = bssgp_bvc_fsm_alloc_sig_sgsn(from_bvc, nse->cfg->nsi, nse->nsei, features);
- if (!from_bvc->fi) {
- LOGPNSE(nse, LOGL_ERROR, "Cannot allocate SIG-BVC FSM\n");
- gbproxy_bvc_free(from_bvc);
- return -ENOMEM;
- }
- bssgp_bvc_fsm_set_ops(from_bvc->fi, &bss_sig_bvc_fsm_ops, from_bvc);
- }
- } else {
- from_bvc = gbproxy_bvc_by_bvci(nse, bvci);
- if (!from_bvc) {
- /* if a PTP-BVC is reset, and we don't know that
- * PTP-BVCI yet, we should allocate a new bvc */
- from_bvc = gbproxy_bvc_alloc(nse, bvci);
- OSMO_ASSERT(from_bvc);
- from_bvc->fi = bssgp_bvc_fsm_alloc_ptp_sgsn(from_bvc, nse->cfg->nsi,
- nse->nsei, bvci);
- if (!from_bvc->fi) {
- LOGPNSE(nse, LOGL_ERROR, "Cannot allocate SIG-BVC FSM\n");
- gbproxy_bvc_free(from_bvc);
- return -ENOMEM;
- }
- bssgp_bvc_fsm_set_ops(from_bvc->fi, &bss_ptp_bvc_fsm_ops, from_bvc);
- }
-#if 0
- /* Could have moved to a different NSE */
- if (!check_bvc_nsei(from_bvc, nsei)) {
- LOGPBVC(from_bvc, LOGL_NOTICE, "moving bvc to NSE(%05u)\n", nsei);
-
- struct gbproxy_nse *nse_new = gbproxy_nse_by_nsei(cfg, nsei, false);
- if (!nse_new) {
- LOGP(DGPRS, LOGL_NOTICE, "NSE(%05u) Got PtP BVC reset before signalling reset for "
- "BVCI=%05u\n", bvci, nsei);
- bssgp_tx_status(BSSGP_CAUSE_PDU_INCOMP_STATE, NULL, msg);
- return 0;
- }
-
- /* Move bvc to different NSE */
- gbproxy_bvc_move(from_bvc, nse_new);
- }
-#endif
- /* FIXME: do we need this, if it happens within FSM? */
- if (TLVP_PRES_LEN(tp, BSSGP_IE_CELL_ID, 8)) {
- struct gprs_ra_id raid;
- /* We have a Cell Identifier present in this
- * PDU, this means we can extend our local
- * state information about this particular cell
- * */
- memcpy(from_bvc->ra, TLVP_VAL(tp, BSSGP_IE_CELL_ID), sizeof(from_bvc->ra));
- gsm48_parse_ra(&raid, from_bvc->ra);
- LOGPBVC(from_bvc, LOGL_INFO, "Cell ID %s\n", osmo_rai_name(&raid));
- }
- }
- /* hand into FSM for further processing */
- osmo_fsm_inst_dispatch(from_bvc->fi, BSSGP_BVCFSM_E_RX_RESET, msg);
- return 0;
-}
-
-/* Receive an incoming signalling message from a BSS-side NS-VC */
-static int gbprox_rx_sig_from_bss(struct gbproxy_nse *nse, struct msgb *msg, uint16_t ns_bvci)
-{
- struct bssgp_normal_hdr *bgph = (struct bssgp_normal_hdr *) msgb_bssgph(msg);
- uint8_t pdu_type = bgph->pdu_type;
- const char *pdut_name = osmo_tlv_prot_msg_name(&osmo_pdef_bssgp, bgph->pdu_type);
- struct tlv_parsed tp;
- int data_len = msgb_bssgp_len(msg) - sizeof(*bgph);
- struct gbproxy_bvc *from_bvc = NULL;
- char log_pfx[32];
- uint16_t ptp_bvci;
- uint32_t tlli;
- int rc;
-
- snprintf(log_pfx, sizeof(log_pfx), "NSE(%05u/BSS)-BVC(%05u/??)", nse->nsei, ns_bvci);
-
- LOGP(DGPRS, LOGL_DEBUG, "%s Rx %s\n", log_pfx, pdut_name);
-
- if (ns_bvci != 0 && ns_bvci != 1) {
- LOGP(DGPRS, LOGL_NOTICE, "%s %s BVCI=%05u is not signalling\n", log_pfx, pdut_name, ns_bvci);
- return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg);
- }
-
- if (!(bssgp_pdu_type_flags(pdu_type) & BSSGP_PDUF_SIG)) {
- LOGP(DGPRS, LOGL_NOTICE, "%s %s not allowed in signalling BVC\n", log_pfx, pdut_name);
- return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg);
- }
-
- if (!(bssgp_pdu_type_flags(pdu_type) & BSSGP_PDUF_UL)) {
- LOGP(DGPRS, LOGL_NOTICE, "%s %s not allowed in uplink direction\n", log_pfx, pdut_name);
- return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg);
- }
-
- rc = osmo_tlv_prot_parse(&osmo_pdef_bssgp, &tp, 1, pdu_type, bgph->data, data_len, 0, 0,
- DGPRS, log_pfx);
- if (rc < 0) {
- rate_ctr_inc(&nse->cfg->ctrg->ctr[GBPROX_GLOB_CTR_PROTO_ERR_BSS]);
- return tx_status_from_tlvp(rc, msg);
- }
- /* hack to get both msg + tlv_parsed passed via osmo_fsm_inst_dispatch */
- msgb_bcid(msg) = (void *)&tp;
-
- /* special case handling for some PDU types */
- switch (pdu_type) {
- case BSSGP_PDUT_BVC_RESET:
- /* resolve or create gbproxy_bvc + handlei n BVC-FSM */
- return rx_bvc_reset_from_bss(nse, msg, &tp);
- case BSSGP_PDUT_BVC_RESET_ACK:
- ptp_bvci = ntohs(tlvp_val16_unal(&tp, BSSGP_IE_BVCI));
- from_bvc = gbproxy_bvc_by_bvci(nse, ptp_bvci);
- if (!from_bvc)
- goto err_no_bvc;
- return osmo_fsm_inst_dispatch(from_bvc->fi, BSSGP_BVCFSM_E_RX_RESET_ACK, msg);
- case BSSGP_PDUT_BVC_BLOCK:
- ptp_bvci = ntohs(tlvp_val16_unal(&tp, BSSGP_IE_BVCI));
- from_bvc = gbproxy_bvc_by_bvci(nse, ptp_bvci);
- if (!from_bvc)
- goto err_no_bvc;
- return osmo_fsm_inst_dispatch(from_bvc->fi, BSSGP_BVCFSM_E_RX_BLOCK, msg);
- case BSSGP_PDUT_BVC_UNBLOCK:
- ptp_bvci = ntohs(tlvp_val16_unal(&tp, BSSGP_IE_BVCI));
- from_bvc = gbproxy_bvc_by_bvci(nse, ptp_bvci);
- if (!from_bvc)
- goto err_no_bvc;
- return osmo_fsm_inst_dispatch(from_bvc->fi, BSSGP_BVCFSM_E_RX_UNBLOCK, msg);
- case BSSGP_PDUT_SUSPEND:
- case BSSGP_PDUT_RESUME:
- {
- struct gbproxy_sgsn *sgsn;
-
- tlli = osmo_load32be(TLVP_VAL(&tp, BSSGP_IE_TLLI));
- sgsn = gbproxy_select_sgsn(nse->cfg, &tlli);
- if (!sgsn) {
- LOGP(DGPRS, LOGL_ERROR, "Could not find any SGSN for TLLI, dropping message!\n");
- rc = -EINVAL;
- break;
- }
-
- gbproxy_tlli_cache_update(nse, tlli);
-
- rc = gbprox_relay2nse(msg, sgsn->nse, 0);
-#if 0
- /* TODO: Validate the RAI for consistency with the RAI
- * we expect for any of the BVC within this BSS side NSE */
- memcpy(ra, TLVP_VAL(&tp, BSSGP_IE_ROUTEING_AREA), sizeof(from_bvc->ra));
- gsm48_parse_ra(&raid, from_bvc->ra);
-#endif
- break;
- }
- case BSSGP_PDUT_STATUS:
- /* FIXME: inspect the erroneous PDU IE (if any) and check
- * if we can extract a TLLI/RNI to route it to the correct SGSN */
- break;
- case BSSGP_PDUT_RAN_INFO:
- case BSSGP_PDUT_RAN_INFO_REQ:
- case BSSGP_PDUT_RAN_INFO_ACK:
- case BSSGP_PDUT_RAN_INFO_ERROR:
- case BSSGP_PDUT_RAN_INFO_APP_ERROR:
- /* FIXME: route based in RIM Routing IE */
- rc = bssgp_tx_status(BSSGP_CAUSE_PDU_INCOMP_FEAT, NULL, msg);
- break;
- case BSSGP_PDUT_LLC_DISCARD:
- case BSSGP_PDUT_FLUSH_LL_ACK:
- /* route based on BVCI + TLLI */
- ptp_bvci = ntohs(tlvp_val16_unal(&tp, BSSGP_IE_BVCI));
- tlli = osmo_load32be(TLVP_VAL(&tp, BSSGP_IE_TLLI));
- from_bvc = gbproxy_bvc_by_bvci(nse, ptp_bvci);
- if (!from_bvc)
- goto err_no_bvc;
- gbprox_bss2sgsn_tlli(from_bvc->cell, msg, &tlli, true);
- break;
- case BSSGP_PDUT_PAGING_PS_REJECT:
- case BSSGP_PDUT_DUMMY_PAGING_PS_RESP:
- {
- /* Route according to IMSI<->NSE cache entry */
- struct osmo_mobile_identity mi;
- const uint8_t *mi_data = TLVP_VAL(&tp, BSSGP_IE_IMSI);
- uint8_t mi_len = TLVP_LEN(&tp, BSSGP_IE_IMSI);
- osmo_mobile_identity_decode(&mi, mi_data, mi_len, false);
- nse = gbproxy_nse_by_imsi(nse->cfg, mi.imsi);
- if (!nse) {
- return bssgp_tx_status(BSSGP_CAUSE_INV_MAND_INF, NULL, msg);
- }
- OSMO_ASSERT(nse->sgsn_facing);
- rc = gbprox_relay2nse(msg, nse, 0);
- break;
- }
- default:
- LOGPNSE(nse, LOGL_ERROR, "Rx %s: Implementation missing\n", pdut_name);
- break;
- }
-
- return rc;
-err_no_bvc:
- LOGPNSE(nse, LOGL_ERROR, "Rx %s: cannot find BVC for BVCI=%05u\n", pdut_name, ptp_bvci);
- rate_ctr_inc(&nse->cfg->ctrg->ctr[GBPROX_GLOB_CTR_INV_NSEI]);
- return bssgp_tx_status(BSSGP_CAUSE_INV_MAND_INF, NULL, msg);
-}
-
-/* Receive paging request from SGSN, we need to relay to proper BSS */
-static int gbprox_rx_paging(struct gbproxy_nse *sgsn_nse, struct msgb *msg, const char *pdut_name,
- struct tlv_parsed *tp, uint16_t ns_bvci, bool broadcast)
-{
- struct gbproxy_config *cfg = sgsn_nse->cfg;
- struct gbproxy_bvc *sgsn_bvc, *bss_bvc;
- struct gbproxy_nse *nse;
- unsigned int n_nses = 0;
- int errctr = GBPROX_GLOB_CTR_PROTO_ERR_SGSN;
- int i, j;
-
- /* FIXME: Handle paging logic to only page each matching NSE */
-
- if (TLVP_PRES_LEN(tp, BSSGP_IE_BVCI, 2)) {
- uint16_t bvci = ntohs(tlvp_val16_unal(tp, BSSGP_IE_BVCI));
- errctr = GBPROX_GLOB_CTR_OTHER_ERR;
- sgsn_bvc = gbproxy_bvc_by_bvci(sgsn_nse, bvci);
- if (!sgsn_bvc) {
- LOGPNSE(sgsn_nse, LOGL_NOTICE, "Rx %s: unable to route: BVCI=%05u unknown\n",
- pdut_name, bvci);
- rate_ctr_inc(&cfg->ctrg->ctr[errctr]);
- return -EINVAL;
- }
- LOGPBVC(sgsn_bvc, LOGL_INFO, "Rx %s: routing by BVCI\n", pdut_name);
- return gbprox_relay2peer(msg, sgsn_bvc->cell->bss_bvc, ns_bvci);
- } else if (TLVP_PRES_LEN(tp, BSSGP_IE_ROUTEING_AREA, 6)) {
- errctr = GBPROX_GLOB_CTR_INV_RAI;
- /* iterate over all bvcs and dispatch the paging to each matching one */
- hash_for_each(cfg->bss_nses, i, nse, list) {
- hash_for_each(nse->bvcs, j, bss_bvc, list) {
- if (!memcmp(bss_bvc->ra, TLVP_VAL(tp, BSSGP_IE_ROUTEING_AREA), 6)) {
- LOGPNSE(nse, LOGL_INFO, "Rx %s: routing to NSE (RAI match)\n",
- pdut_name);
- gbprox_relay2peer(msg, bss_bvc, ns_bvci);
- n_nses++;
- /* Only send it once to each NSE */
- break;
- }
- }
- }
- } else if (TLVP_PRES_LEN(tp, BSSGP_IE_LOCATION_AREA, 5)) {
- errctr = GBPROX_GLOB_CTR_INV_LAI;
- /* iterate over all bvcs and dispatch the paging to each matching one */
- hash_for_each(cfg->bss_nses, i, nse, list) {
- hash_for_each(nse->bvcs, j, bss_bvc, list) {
- if (!memcmp(bss_bvc->ra, TLVP_VAL(tp, BSSGP_IE_LOCATION_AREA), 5)) {
- LOGPNSE(nse, LOGL_INFO, "Rx %s: routing to NSE (LAI match)\n",
- pdut_name);
- gbprox_relay2peer(msg, bss_bvc, ns_bvci);
- n_nses++;
- /* Only send it once to each NSE */
- break;
- }
- }
- }
- } else if (TLVP_PRES_LEN(tp, BSSGP_IE_BSS_AREA_ID, 1) || broadcast) {
- /* iterate over all bvcs and dispatch the paging to each matching one */
- hash_for_each(cfg->bss_nses, i, nse, list) {
- hash_for_each(nse->bvcs, j, bss_bvc, list) {
- LOGPNSE(nse, LOGL_INFO, "Rx %s:routing to NSE (broadcast)\n", pdut_name);
- gbprox_relay2peer(msg, bss_bvc, ns_bvci);
- n_nses++;
- /* Only send it once to each NSE */
- break;
- }
- }
- } else {
- LOGPNSE(sgsn_nse, LOGL_ERROR, "BSSGP PAGING: unable to route, missing IE\n");
- rate_ctr_inc(&cfg->ctrg->ctr[errctr]);
- }
-
- if (n_nses == 0) {
- LOGPNSE(sgsn_nse, LOGL_ERROR, "BSSGP PAGING: unable to route, no destination found\n");
- rate_ctr_inc(&cfg->ctrg->ctr[errctr]);
- return -EINVAL;
- }
- return 0;
-}
-
-/* Receive an incoming BVC-RESET message from the SGSN */
-static int rx_bvc_reset_from_sgsn(struct gbproxy_nse *nse, struct msgb *msg, struct tlv_parsed *tp,
- uint16_t ns_bvci)
-{
- uint16_t ptp_bvci = ntohs(tlvp_val16_unal(tp, BSSGP_IE_BVCI));
- struct gbproxy_bvc *from_bvc;
-
- LOGPNSE(nse, LOGL_INFO, "Rx BVC-RESET (BVCI=%05u)\n", ptp_bvci);
-
- if (ptp_bvci == 0) {
- from_bvc = gbproxy_bvc_by_bvci(nse, 0);
- OSMO_ASSERT(from_bvc);
- osmo_fsm_inst_dispatch(from_bvc->fi, BSSGP_BVCFSM_E_RX_RESET, msg);
- } else {
- from_bvc = gbproxy_bvc_by_bvci(nse, ptp_bvci);
- if (!from_bvc) {
- LOGPNSE(nse, LOGL_ERROR, "Rx BVC-RESET BVCI=%05u: Cannot find BVC\n", ptp_bvci);
- rate_ctr_inc(&nse->cfg->ctrg->ctr[GBPROX_GLOB_CTR_INV_BVCI]);
- return bssgp_tx_status(BSSGP_CAUSE_UNKNOWN_BVCI, &ptp_bvci, msg);
- }
- osmo_fsm_inst_dispatch(from_bvc->fi, BSSGP_BVCFSM_E_RX_RESET, msg);
- }
-
- return 0;
-}
-
-/* Receive an incoming signalling message from the SGSN-side NS-VC */
-static int gbprox_rx_sig_from_sgsn(struct gbproxy_nse *nse, struct msgb *msg, uint16_t ns_bvci)
-{
- struct bssgp_normal_hdr *bgph = (struct bssgp_normal_hdr *) msgb_bssgph(msg);
- uint8_t pdu_type = bgph->pdu_type;
- const char *pdut_name = osmo_tlv_prot_msg_name(&osmo_pdef_bssgp, bgph->pdu_type);
- struct gbproxy_config *cfg = nse->cfg;
- struct gbproxy_bvc *sgsn_bvc;
- struct tlv_parsed tp;
- int data_len;
- uint16_t bvci;
- char log_pfx[32];
- int rc = 0;
- int cause;
- int i;
- bool paging_bc = false;
-
- snprintf(log_pfx, sizeof(log_pfx), "NSE(%05u/SGSN)-BVC(%05u/??)", nse->nsei, ns_bvci);
-
- LOGP(DGPRS, LOGL_DEBUG, "%s Rx %s\n", log_pfx, pdut_name);
-
- if (ns_bvci != 0 && ns_bvci != 1) {
- LOGP(DGPRS, LOGL_NOTICE, "%s BVCI=%05u is not signalling\n", log_pfx, ns_bvci);
- return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg);
- }
-
- if (!(bssgp_pdu_type_flags(pdu_type) & BSSGP_PDUF_SIG)) {
- LOGP(DGPRS, LOGL_NOTICE, "%s %s not allowed in signalling BVC\n", log_pfx, pdut_name);
- return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg);
- }
-
- if (!(bssgp_pdu_type_flags(pdu_type) & BSSGP_PDUF_DL)) {
- LOGP(DGPRS, LOGL_NOTICE, "%s %s not allowed in downlink direction\n", log_pfx, pdut_name);
- return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg);
- }
-
- data_len = msgb_bssgp_len(msg) - sizeof(*bgph);
-
- rc = osmo_tlv_prot_parse(&osmo_pdef_bssgp, &tp, 1, pdu_type, bgph->data, data_len, 0, 0,
- DGPRS, log_pfx);
- if (rc < 0) {
- rc = tx_status_from_tlvp(rc, msg);
- rate_ctr_inc(&cfg->ctrg->ctr[GBPROX_GLOB_CTR_PROTO_ERR_SGSN]);
- return rc;
- }
- /* hack to get both msg + tlv_parsed passed via osmo_fsm_inst_dispatch */
- msgb_bcid(msg) = (void *)&tp;
-
- switch (pdu_type) {
- case BSSGP_PDUT_BVC_RESET:
- /* resolve or create ggbproxy_bvc + handle in BVC-FSM */
- bvci = ntohs(tlvp_val16_unal(&tp, BSSGP_IE_BVCI));
- rc = rx_bvc_reset_from_sgsn(nse, msg, &tp, ns_bvci);
- break;
- case BSSGP_PDUT_BVC_RESET_ACK:
- bvci = ntohs(tlvp_val16_unal(&tp, BSSGP_IE_BVCI));
- sgsn_bvc = gbproxy_bvc_by_bvci(nse, bvci);
- if (!sgsn_bvc)
- goto err_no_bvc;
- rc = osmo_fsm_inst_dispatch(sgsn_bvc->fi, BSSGP_BVCFSM_E_RX_RESET_ACK, msg);
- break;
- case BSSGP_PDUT_BVC_BLOCK_ACK:
- bvci = ntohs(tlvp_val16_unal(&tp, BSSGP_IE_BVCI));
- sgsn_bvc = gbproxy_bvc_by_bvci(nse, bvci);
- if (!sgsn_bvc)
- goto err_no_bvc;
- rc = osmo_fsm_inst_dispatch(sgsn_bvc->fi, BSSGP_BVCFSM_E_RX_BLOCK_ACK, msg);
- break;
- case BSSGP_PDUT_BVC_UNBLOCK_ACK:
- bvci = ntohs(tlvp_val16_unal(&tp, BSSGP_IE_BVCI));
- sgsn_bvc = gbproxy_bvc_by_bvci(nse, bvci);
- if (!sgsn_bvc)
- goto err_no_bvc;
- rc = osmo_fsm_inst_dispatch(sgsn_bvc->fi, BSSGP_BVCFSM_E_RX_UNBLOCK_ACK, msg);
- break;
- case BSSGP_PDUT_FLUSH_LL:
- /* simple case: BVCI IE is mandatory */
- bvci = ntohs(tlvp_val16_unal(&tp, BSSGP_IE_BVCI));
- sgsn_bvc = gbproxy_bvc_by_bvci(nse, bvci);
- if (!sgsn_bvc)
- goto err_no_bvc;
- if (sgsn_bvc->cell && sgsn_bvc->cell->bss_bvc)
- rc = gbprox_relay2peer(msg, sgsn_bvc->cell->bss_bvc, ns_bvci);
- break;
- case BSSGP_PDUT_DUMMY_PAGING_PS:
- /* Routing area is optional in dummy paging and we have nothing else to go by
- * so in case it is missing we need to broadcast the paging */
- paging_bc = true;
- /* fall through */
- case BSSGP_PDUT_PAGING_PS:
- {
- /* Cache the IMSI<->NSE to route PAGING REJECT */
- struct osmo_mobile_identity mi;
- const uint8_t *mi_data = TLVP_VAL(&tp, BSSGP_IE_IMSI);
- uint8_t mi_len = TLVP_LEN(&tp, BSSGP_IE_IMSI);
- osmo_mobile_identity_decode(&mi, mi_data, mi_len, false);
- gbproxy_imsi_cache_update(nse, mi.imsi);
- /* fall through */
- }
- case BSSGP_PDUT_PAGING_CS:
- /* process the paging request (LAI/RAI lookup) */
- rc = gbprox_rx_paging(nse, msg, pdut_name, &tp, ns_bvci, paging_bc);
- break;
- case BSSGP_PDUT_STATUS:
- /* Some exception has occurred */
- cause = *TLVP_VAL(&tp, BSSGP_IE_CAUSE);
- LOGPNSE(nse, LOGL_NOTICE, "Rx STATUS cause=0x%02x(%s) ", cause,
- bssgp_cause_str(cause));
- if (TLVP_PRES_LEN(&tp, BSSGP_IE_BVCI, 2)) {
- bvci = ntohs(tlvp_val16_unal(&tp, BSSGP_IE_BVCI));
- LOGPC(DGPRS, LOGL_NOTICE, "BVCI=%05u\n", bvci);
- sgsn_bvc = gbproxy_bvc_by_bvci(nse, bvci);
- /* don't send STATUS in response to STATUS if !bvc */
- if (sgsn_bvc && sgsn_bvc->cell && sgsn_bvc->cell->bss_bvc)
- rc = gbprox_relay2peer(msg, sgsn_bvc->cell->bss_bvc, ns_bvci);
- } else
- LOGPC(DGPRS, LOGL_NOTICE, "\n");
- break;
- /* those only exist in the SGSN -> BSS direction */
- case BSSGP_PDUT_SUSPEND_ACK:
- case BSSGP_PDUT_SUSPEND_NACK:
- case BSSGP_PDUT_RESUME_ACK:
- case BSSGP_PDUT_RESUME_NACK:
- {
- struct gbproxy_nse *nse_peer;
- uint32_t tlli = osmo_load32be(TLVP_VAL(&tp, BSSGP_IE_TLLI));
-
- nse_peer = gbproxy_nse_by_tlli(cfg, tlli);
- if (!nse_peer) {
- LOGPNSE(nse, LOGL_ERROR, "Rx %s: Cannot find NSE\n", pdut_name);
- /* TODO: Counter */
- return bssgp_tx_status(BSSGP_CAUSE_INV_MAND_INF, NULL, msg);
- }
- /* Delete the entry after we're done */
- gbproxy_tlli_cache_remove(cfg, tlli);
- LOGPNSE(nse_peer, LOGL_DEBUG, "Rx %s: forwarding\n", pdut_name);
- gbprox_relay2nse(msg, nse_peer, ns_bvci);
- break;
- }
- case BSSGP_PDUT_SGSN_INVOKE_TRACE:
- case BSSGP_PDUT_OVERLOAD:
- LOGPNSE(nse, LOGL_DEBUG, "Rx %s: broadcasting\n", pdut_name);
- /* broadcast to all BSS-side bvcs */
- hash_for_each(cfg->bss_nses, i, nse, list) {
- gbprox_relay2nse(msg, nse, 0);
- }
- break;
- case BSSGP_PDUT_RAN_INFO:
- case BSSGP_PDUT_RAN_INFO_REQ:
- case BSSGP_PDUT_RAN_INFO_ACK:
- case BSSGP_PDUT_RAN_INFO_ERROR:
- case BSSGP_PDUT_RAN_INFO_APP_ERROR:
- /* FIXME: route based in RIM Routing IE */
- rc = bssgp_tx_status(BSSGP_CAUSE_PDU_INCOMP_FEAT, NULL, msg);
- break;
- default:
- LOGPNSE(nse, LOGL_NOTICE, "Rx %s: Not supported\n", pdut_name);
- rate_ctr_inc(&cfg->ctrg->ctr[GBPROX_GLOB_CTR_PROTO_ERR_SGSN]);
- rc = bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg);
- break;
- }
-
- return rc;
-
-err_no_bvc:
- LOGPNSE(nse, LOGL_ERROR, "Rx %s: Cannot find BVC\n", pdut_name);
- rate_ctr_inc(&cfg->ctrg-> ctr[GBPROX_GLOB_CTR_INV_RAI]);
- return bssgp_tx_status(BSSGP_CAUSE_INV_MAND_INF, NULL, msg);
-}
-
-
-/***********************************************************************
- * libosmogb NS/BSSGP integration
- ***********************************************************************/
-
-int gbprox_bssgp_send_cb(void *ctx, struct msgb *msg)
-{
- int rc;
- struct gbproxy_config *cfg = (struct gbproxy_config *) ctx;
- struct gprs_ns2_inst *nsi = cfg->nsi;
- struct osmo_gprs_ns2_prim nsp = {};
-
- nsp.bvci = msgb_bvci(msg);
- nsp.nsei = msgb_nsei(msg);
-
- osmo_prim_init(&nsp.oph, SAP_NS, GPRS_NS2_PRIM_UNIT_DATA, PRIM_OP_REQUEST, msg);
- rc = gprs_ns2_recv_prim(nsi, &nsp.oph);
-
- return rc;
-}
-
-/* Main input function for Gb proxy */
-int gbprox_rcvmsg(void *ctx, struct msgb *msg)
-{
- struct gbproxy_config *cfg = (struct gbproxy_config *) ctx;
- uint16_t ns_bvci = msgb_bvci(msg);
- uint16_t nsei = msgb_nsei(msg);
- struct gbproxy_nse *nse;
-
- /* ensure minimum length to decode PCU type */
- if (msgb_bssgp_len(msg) < sizeof(struct bssgp_normal_hdr))
- return bssgp_tx_status(BSSGP_CAUSE_SEM_INCORR_PDU, NULL, msg);
-
- nse = gbproxy_nse_by_nsei(cfg, nsei, NSE_F_SGSN);
- if (nse) {
- if (ns_bvci == 0 || ns_bvci == 1)
- return gbprox_rx_sig_from_sgsn(nse, msg, ns_bvci);
- else
- return gbprox_rx_ptp_from_sgsn(nse, msg, ns_bvci);
- }
-
- nse = gbproxy_nse_by_nsei(cfg, nsei, NSE_F_BSS);
- if (!nse) {
- LOGP(DGPRS, LOGL_NOTICE, "NSE(%05u/BSS) not known -> allocating\n", nsei);
- nse = gbproxy_nse_alloc(cfg, nsei, false);
- }
- if (nse) {
- if (ns_bvci == 0 || ns_bvci == 1)
- return gbprox_rx_sig_from_bss(nse, msg, ns_bvci);
- else
- return gbprox_rx_ptp_from_bss(nse, msg, ns_bvci);
- }
-
- return 0;
-}
-
-/* TODO: What about handling:
- * GPRS_NS2_AFF_CAUSE_VC_FAILURE,
- GPRS_NS2_AFF_CAUSE_VC_RECOVERY,
- GPRS_NS2_AFF_CAUSE_FAILURE,
- GPRS_NS2_AFF_CAUSE_RECOVERY,
- osmocom own causes
- GPRS_NS2_AFF_CAUSE_SNS_CONFIGURED,
- GPRS_NS2_AFF_CAUSE_SNS_FAILURE,
- */
-
-void gprs_ns_prim_status_cb(struct gbproxy_config *cfg, struct osmo_gprs_ns2_prim *nsp)
-{
- /* TODO: bss nsei available/unavailable bssgp_tx_simple_bvci(BSSGP_PDUT_BVC_BLOCK, nsvc->nsei, bvc->bvci, 0);
- * TODO: sgsn nsei available/unavailable
- */
-
- struct gbproxy_bvc *bvc;
- struct gbproxy_nse *sgsn_nse;
-
- switch (nsp->u.status.cause) {
- case GPRS_NS2_AFF_CAUSE_SNS_FAILURE:
- case GPRS_NS2_AFF_CAUSE_SNS_CONFIGURED:
- break;
-
- case GPRS_NS2_AFF_CAUSE_RECOVERY:
- LOGP(DGPRS, LOGL_NOTICE, "NS-NSE %d became available\n", nsp->nsei);
- sgsn_nse = gbproxy_nse_by_nsei(cfg, nsp->nsei, NSE_F_SGSN);
- if (sgsn_nse) {
- uint8_t cause = BSSGP_CAUSE_OML_INTERV;
- bvc = gbproxy_bvc_by_bvci(sgsn_nse, 0);
- if (bvc)
- osmo_fsm_inst_dispatch(bvc->fi, BSSGP_BVCFSM_E_REQ_RESET, &cause);
- }
- break;
- case GPRS_NS2_AFF_CAUSE_FAILURE:
-#if 0
- if (gbproxy_is_sgsn_nsei(cfg, nsp->nsei)) {
- /* sgsn */
- /* TODO: BSVC: block all PtP towards bss */
- rate_ctr_inc(&cfg->ctrg->
- ctr[GBPROX_GLOB_CTR_RESTART_RESET_SGSN]);
- } else {
- /* bss became unavailable
- * TODO: Block all BVC belonging to that NSE */
- bvc = gbproxy_bvc_by_nsei(cfg, nsp->nsei);
- if (!bvc) {
- /* TODO: use primitive name + status cause name */
- LOGP(DGPRS, LOGL_NOTICE, "Received ns2 primitive %d for unknown bvc NSEI=%u\n",
- nsp->u.status.cause, nsp->nsei);
- break;
- }
-
- if (!bvc->blocked)
- break;
- hash_for_each(cfg->sgsn_nses, _sgsn, sgsn_nse, list) {
- bssgp_tx_simple_bvci(BSSGP_PDUT_BVC_BLOCK, sgsn_nse->nsei, bvc->bvci, 0);
- }
- }
-#endif
- LOGP(DGPRS, LOGL_NOTICE, "NS-NSE %d became unavailable\n", nsp->nsei);
- break;
- default:
- LOGP(DGPRS, LOGL_NOTICE, "NS: Unknown NS-STATUS.ind cause=%s from NS\n",
- gprs_ns2_aff_cause_prim_str(nsp->u.status.cause));
- break;
- }
-}
-
-/* called by the ns layer */
-int gprs_ns2_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
-{
- struct osmo_gprs_ns2_prim *nsp;
- struct gbproxy_config *cfg = (struct gbproxy_config *) ctx;
- uintptr_t bvci;
- int rc = 0;
-
- if (oph->sap != SAP_NS)
- return 0;
-
- nsp = container_of(oph, struct osmo_gprs_ns2_prim, oph);
-
- if (oph->operation != PRIM_OP_INDICATION) {
- LOGP(DGPRS, LOGL_NOTICE, "NS: Unexpected primitive operation %s from NS\n",
- get_value_string(osmo_prim_op_names, oph->operation));
- return 0;
- }
-
- switch (oph->primitive) {
- case GPRS_NS2_PRIM_UNIT_DATA:
-
- /* hand the message into the BSSGP implementation */
- msgb_bssgph(oph->msg) = oph->msg->l3h;
- msgb_bvci(oph->msg) = nsp->bvci;
- msgb_nsei(oph->msg) = nsp->nsei;
- bvci = nsp->bvci | BVC_LOG_CTX_FLAG;
-
- log_set_context(LOG_CTX_GB_BVC, (void *)bvci);
- rc = gbprox_rcvmsg(cfg, oph->msg);
- msgb_free(oph->msg);
- break;
- case GPRS_NS2_PRIM_STATUS:
- gprs_ns_prim_status_cb(cfg, nsp);
- break;
- default:
- LOGP(DGPRS, LOGL_NOTICE, "NS: Unknown prim %s %s from NS\n",
- gprs_ns2_prim_str(oph->primitive),
- get_value_string(osmo_prim_op_names, oph->operation));
- break;
- }
-
- return rc;
-}
-
-void gbprox_reset(struct gbproxy_config *cfg)
-{
- struct gbproxy_nse *nse;
- struct hlist_node *ntmp;
- int i, j;
-
- hash_for_each_safe(cfg->bss_nses, i, ntmp, nse, list) {
- struct gbproxy_bvc *bvc;
- struct hlist_node *tmp;
- hash_for_each_safe(nse->bvcs, j, tmp, bvc, list)
- gbproxy_bvc_free(bvc);
-
- gbproxy_nse_free(nse);
- }
- /* FIXME: cells */
- /* FIXME: SGSN side BVCs (except signaling) */
-
- rate_ctr_group_free(cfg->ctrg);
- gbproxy_init_config(cfg);
-}
-
-static void tlli_cache_cleanup(void *data)
-{
- struct gbproxy_config *cfg = data;
- gbproxy_tlli_cache_cleanup(cfg);
-
- /* TODO: Disable timer when cache is empty */
- osmo_timer_schedule(&cfg->tlli_cache.timer, 2, 0);
-}
-
-static void imsi_cache_cleanup(void *data)
-{
- struct gbproxy_config *cfg = data;
- gbproxy_imsi_cache_cleanup(cfg);
-
- /* TODO: Disable timer when cache is empty */
- osmo_timer_schedule(&cfg->imsi_cache.timer, 2, 0);
-}
-
-int gbproxy_init_config(struct gbproxy_config *cfg)
-{
- struct timespec tp;
-
- /* by default we advertise 100% of the BSS-side capacity to _each_ SGSN */
- cfg->pool.bvc_fc_ratio = 100;
- cfg->pool.null_nri_ranges = osmo_nri_ranges_alloc(cfg);
- /* TODO: Make configurable */
- cfg->tlli_cache.timeout = 10;
- cfg->imsi_cache.timeout = 10;
-
- hash_init(cfg->bss_nses);
- hash_init(cfg->sgsn_nses);
- hash_init(cfg->cells);
- hash_init(cfg->tlli_cache.entries);
- INIT_LLIST_HEAD(&cfg->sgsns);
-
- osmo_timer_setup(&cfg->tlli_cache.timer, tlli_cache_cleanup, cfg);
- osmo_timer_schedule(&cfg->tlli_cache.timer, 2, 0);
-
- /* We could also combine both timers */
- osmo_timer_setup(&cfg->imsi_cache.timer, imsi_cache_cleanup, cfg);
- osmo_timer_schedule(&cfg->imsi_cache.timer, 2, 0);
-
- cfg->ctrg = rate_ctr_group_alloc(tall_sgsn_ctx, &global_ctrg_desc, 0);
- if (!cfg->ctrg) {
- LOGP(DGPRS, LOGL_ERROR, "Cannot allocate global counter group!\n");
- return -1;
- }
- osmo_clock_gettime(CLOCK_REALTIME, &tp);
- osmo_fsm_log_timeouts(true);
-
- return 0;
-} \ No newline at end of file
diff --git a/src/gbproxy/gb_proxy_ctrl.c b/src/gbproxy/gb_proxy_ctrl.c
deleted file mode 100644
index 456163466..000000000
--- a/src/gbproxy/gb_proxy_ctrl.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/* Control Interface Implementation for the Gb-proxy */
-/*
- * (C) 2018 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
- * All Rights Reserved
- *
- * Author: Daniel Willmann
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <osmocom/core/talloc.h>
-
-
-#include <osmocom/gprs/gprs_bssgp.h>
-#include <osmocom/gprs/gprs_ns.h>
-
-#include <osmocom/ctrl/control_if.h>
-#include <osmocom/ctrl/control_cmd.h>
-#include <osmocom/sgsn/gb_proxy.h>
-#include <osmocom/sgsn/debug.h>
-
-extern vector ctrl_node_vec;
-
-struct nsvc_cb_data {
- struct ctrl_cmd *cmd;
- uint16_t nsei;
- bool is_sgsn;
-};
-
-static int ctrl_nsvc_state_cb(struct gprs_ns2_vc *nsvc, void *ctx) {
- struct nsvc_cb_data *data = (struct nsvc_cb_data *)ctx;
- struct ctrl_cmd *cmd = (struct ctrl_cmd *)data->cmd;
-
- cmd->reply = talloc_asprintf_append(cmd->reply, "%u,%s,%s,%s\n",
- data->nsei, gprs_ns2_ll_str(nsvc), gprs_ns2_nsvc_state_name(nsvc),
- data->is_sgsn ? "SGSN" : "BSS" );
-
- return 0;
-}
-
-static int get_nsvc_state(struct ctrl_cmd *cmd, void *data)
-{
- struct gbproxy_config *cfg = data;
- struct gprs_ns2_inst *nsi = cfg->nsi;
- struct gprs_ns2_nse *nse;
- struct gbproxy_nse *nse_peer;
- int i;
-
- cmd->reply = talloc_strdup(cmd, "");
-
- /* NS-VCs for SGSN */
- hash_for_each(cfg->sgsn_nses, i, nse_peer, list) {
- nse = gprs_ns2_nse_by_nsei(nsi, nse_peer->nsei);
- if (nse)
- gprs_ns2_nse_foreach_nsvc(nse, &ctrl_nsvc_state_cb, cmd);
- }
-
- /* NS-VCs for BSS peers */
- hash_for_each(cfg->bss_nses, i, nse_peer, list) {
- nse = gprs_ns2_nse_by_nsei(nsi, nse_peer->nsei);
- if (nse)
- gprs_ns2_nse_foreach_nsvc(nse, &ctrl_nsvc_state_cb, cmd);
- }
-
- return CTRL_CMD_REPLY;
-}
-
-CTRL_CMD_DEFINE_RO(nsvc_state, "nsvc-state");
-
-static int get_gbproxy_state(struct ctrl_cmd *cmd, void *data)
-{
- struct gbproxy_config *cfg = data;
- struct gbproxy_nse *nse_peer;
- int i, j;
-
- cmd->reply = talloc_strdup(cmd, "");
-
- hash_for_each(cfg->bss_nses, i, nse_peer, list) {
- struct gbproxy_bvc *bvc;
- hash_for_each(nse_peer->bvcs, j, bvc, list) {
- struct gprs_ra_id raid;
- gsm48_parse_ra(&raid, bvc->ra);
-
- cmd->reply = talloc_asprintf_append(cmd->reply, "%u,%u,%u,%u,%u,%u,%s\n",
- nse_peer->nsei, bvc->bvci,
- raid.mcc, raid.mnc,
- raid.lac, raid.rac,
- osmo_fsm_inst_state_name(bvc->fi));
- }
- }
-
- return CTRL_CMD_REPLY;
-}
-
-CTRL_CMD_DEFINE_RO(gbproxy_state, "gbproxy-state");
-
-static int get_num_peers(struct ctrl_cmd *cmd, void *data)
-{
- struct gbproxy_config *cfg = data;
- struct gbproxy_nse *nse_peer;
- struct gbproxy_bvc *bvc;
- uint32_t count = 0;
- int i, j;
-
- hash_for_each(cfg->bss_nses, i, nse_peer, list) {
- hash_for_each(nse_peer->bvcs, j, bvc, list)
- count++;
- }
-
- cmd->reply = talloc_strdup(cmd, "");
- cmd->reply = talloc_asprintf_append(cmd->reply, "%u", count);
-
- return CTRL_CMD_REPLY;
-}
-CTRL_CMD_DEFINE_RO(num_peers, "number-of-peers");
-
-int gb_ctrl_cmds_install(void)
-{
- int rc = 0;
- rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_nsvc_state);
- rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_gbproxy_state);
- rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_num_peers);
-
- return rc;
-}
diff --git a/src/gbproxy/gb_proxy_main.c b/src/gbproxy/gb_proxy_main.c
deleted file mode 100644
index b76e0fbb6..000000000
--- a/src/gbproxy/gb_proxy_main.c
+++ /dev/null
@@ -1,336 +0,0 @@
-/* NS-over-IP proxy */
-
-/* (C) 2010 by Harald Welte <laforge@gnumonks.org>
- * (C) 2010 by On-Waves
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <getopt.h>
-#include <errno.h>
-#include <signal.h>
-#include <sys/fcntl.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include <osmocom/core/application.h>
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/select.h>
-#include <osmocom/core/rate_ctr.h>
-#include <osmocom/core/stats.h>
-
-#include <osmocom/gprs/gprs_ns2.h>
-#include <osmocom/gprs/gprs_bssgp.h>
-
-#include <osmocom/sgsn/signal.h>
-#include <osmocom/sgsn/debug.h>
-#include <osmocom/sgsn/vty.h>
-#include <osmocom/sgsn/gb_proxy.h>
-
-#include <osmocom/ctrl/control_vty.h>
-#include <osmocom/ctrl/control_if.h>
-#include <osmocom/ctrl/ports.h>
-
-#include <osmocom/vty/command.h>
-#include <osmocom/vty/telnet_interface.h>
-#include <osmocom/vty/logging.h>
-#include <osmocom/vty/stats.h>
-#include <osmocom/vty/ports.h>
-#include <osmocom/vty/misc.h>
-
-#include "../../bscconfig.h"
-
-#define _GNU_SOURCE
-#include <getopt.h>
-
-void *tall_sgsn_ctx;
-
-const char *openbsc_copyright =
- "Copyright (C) 2010 Harald Welte and On-Waves\r\n"
- "License AGPLv3+: GNU AGPL version 3 or later <http://gnu.org/licenses/agpl-3.0.html>\r\n"
- "This is free software: you are free to change and redistribute it.\r\n"
- "There is NO WARRANTY, to the extent permitted by law.\r\n";
-
-#define CONFIG_FILE_DEFAULT "osmo-gbproxy.cfg"
-#define CONFIG_FILE_LEGACY "osmo_gbproxy.cfg"
-
-static char *config_file = NULL;
-struct gbproxy_config *gbcfg;
-static int daemonize = 0;
-
-/* Pointer to the SGSN peer */
-extern struct gbprox_peer *gbprox_peer_sgsn;
-
-static void signal_handler(int signum)
-{
- fprintf(stdout, "signal %u received\n", signum);
-
- switch (signum) {
- case SIGINT:
- case SIGTERM:
- osmo_signal_dispatch(SS_L_GLOBAL, S_L_GLOBAL_SHUTDOWN, NULL);
- sleep(1);
- exit(0);
- break;
- case SIGABRT:
- /* in case of abort, we want to obtain a talloc report and
- * then run default SIGABRT handler, who will generate coredump
- * and abort the process. abort() should do this for us after we
- * return, but program wouldn't exit if an external SIGABRT is
- * received.
- */
- talloc_report(tall_vty_ctx, stderr);
- talloc_report_full(tall_sgsn_ctx, stderr);
- signal(SIGABRT, SIG_DFL);
- raise(SIGABRT);
- break;
- case SIGUSR1:
- talloc_report(tall_vty_ctx, stderr);
- talloc_report_full(tall_sgsn_ctx, stderr);
- break;
- case SIGUSR2:
- talloc_report_full(tall_vty_ctx, stderr);
- break;
- default:
- break;
- }
-}
-
-static void print_usage()
-{
- printf("Usage: bsc_hack\n");
-}
-
-static void print_help()
-{
- printf(" Some useful help...\n");
- printf(" -h --help this text\n");
- printf(" -d option --debug=DNS:DGPRS,0:0 enable debugging\n");
- printf(" -D --daemonize Fork the process into a background daemon\n");
- printf(" -c --config-file filename The config file to use [%s]\n", CONFIG_FILE_DEFAULT);
- printf(" -s --disable-color\n");
- printf(" -T --timestamp Prefix every log line with a timestamp\n");
- printf(" -V --version. Print the version.\n");
- printf(" -e --log-level number. Set a global loglevel.\n");
-}
-
-static void handle_options(int argc, char **argv)
-{
- while (1) {
- int option_index = 0, c;
- static struct option long_options[] = {
- { "help", 0, 0, 'h' },
- { "debug", 1, 0, 'd' },
- { "daemonize", 0, 0, 'D' },
- { "config-file", 1, 0, 'c' },
- { "disable-color", 0, 0, 's' },
- { "timestamp", 0, 0, 'T' },
- { "version", 0, 0, 'V' },
- { "log-level", 1, 0, 'e' },
- { 0, 0, 0, 0 }
- };
-
- c = getopt_long(argc, argv, "hd:Dc:sTVe:",
- long_options, &option_index);
- if (c == -1)
- break;
-
- switch (c) {
- case 'h':
- print_usage();
- print_help();
- exit(0);
- case 's':
- log_set_use_color(osmo_stderr_target, 0);
- break;
- case 'd':
- log_parse_category_mask(osmo_stderr_target, optarg);
- break;
- case 'D':
- daemonize = 1;
- break;
- case 'c':
- config_file = optarg;
- break;
- case 'T':
- log_set_print_timestamp(osmo_stderr_target, 1);
- break;
- case 'e':
- log_set_log_level(osmo_stderr_target, atoi(optarg));
- break;
- case 'V':
- print_version(1);
- exit(0);
- break;
- default:
- break;
- }
- }
-
- if (argc > optind) {
- fprintf(stderr, "Unsupported positional arguments on command line\n");
- exit(2);
- }
-}
-
-static struct vty_app_info vty_info = {
- .name = "OsmoGbProxy",
- .version = PACKAGE_VERSION,
-};
-
-/* default categories */
-static struct log_info_cat gprs_categories[] = {
- [DGPRS] = {
- .name = "DGPRS",
- .description = "GPRS Packet Service",
- .enabled = 1, .loglevel = LOGL_DEBUG,
- },
- [DNS] = {
- .name = "DNS",
- .description = "GPRS Network Service (NS)",
- .enabled = 1, .loglevel = LOGL_INFO,
- },
- [DOBJ] = {
- .name = "DOBJ",
- .description = "GbProxy object allocation/release",
- .enabled = 1,
- .color = "\033[38;5;121m"
- },
-};
-
-static const struct log_info gprs_log_info = {
- .filter_fn = gprs_log_filter_fn,
- .cat = gprs_categories,
- .num_cat = ARRAY_SIZE(gprs_categories),
-};
-
-static bool file_exists(const char *path)
-{
- struct stat sb;
- return stat(path, &sb) ? false : true;
-}
-
-int gbprox_bssgp_send_cb(void *ctx, struct msgb *msg);
-
-int main(int argc, char **argv)
-{
- int rc;
- struct ctrl_handle *ctrl;
-
- tall_sgsn_ctx = talloc_named_const(NULL, 0, "nsip_proxy");
- msgb_talloc_ctx_init(tall_sgsn_ctx, 0);
- vty_info.tall_ctx = tall_sgsn_ctx;
-
- signal(SIGINT, &signal_handler);
- signal(SIGTERM, &signal_handler);
- signal(SIGABRT, &signal_handler);
- signal(SIGUSR1, &signal_handler);
- signal(SIGUSR2, &signal_handler);
- osmo_init_ignore_signals();
-
- osmo_init_logging2(tall_sgsn_ctx, &gprs_log_info);
-
- vty_info.copyright = openbsc_copyright;
- vty_init(&vty_info);
- logging_vty_add_cmds();
- osmo_talloc_vty_add_cmds();
- osmo_stats_vty_add_cmds();
- osmo_fsm_vty_add_cmds();
- gbproxy_vty_init();
-
- handle_options(argc, argv);
-
- /* Backwards compatibility: for years, the default config file name was
- * osmo_gbproxy.cfg. All other Osmocom programs use osmo-*.cfg with a
- * dash. To be able to use the new config file name without breaking
- * previous setups that might rely on the legacy default config file
- * name, we need to look for the old config file if no -c option was
- * passed AND no file exists with the new default file name. */
- if (!config_file) {
- /* No -c option was passed */
- if (file_exists(CONFIG_FILE_LEGACY)
- && !file_exists(CONFIG_FILE_DEFAULT))
- config_file = CONFIG_FILE_LEGACY;
- else
- config_file = CONFIG_FILE_DEFAULT;
- }
-
- rate_ctr_init(tall_sgsn_ctx);
- osmo_stats_init(tall_sgsn_ctx);
-
- gbcfg = talloc_zero(tall_sgsn_ctx, struct gbproxy_config);
- if (!gbcfg) {
- LOGP(DGPRS, LOGL_FATAL, "Unable to allocate config\n");
- exit(1);
- }
- gbproxy_init_config(gbcfg);
- gbcfg->nsi = gprs_ns2_instantiate(tall_sgsn_ctx, gprs_ns2_prim_cb, gbcfg);
- if (!gbcfg->nsi) {
- LOGP(DGPRS, LOGL_ERROR, "Unable to instantiate NS\n");
- exit(1);
- }
- gprs_ns2_vty_init(gbcfg->nsi);
- logging_vty_add_deprecated_subsys(tall_sgsn_ctx, "bssgp");
-
- bssgp_set_bssgp_callback(gbprox_bssgp_send_cb, gbcfg);
-
- rc = gbproxy_parse_config(config_file, gbcfg);
- if (rc < 0) {
- LOGP(DGPRS, LOGL_FATAL, "Cannot parse config file '%s'\n", config_file);
- exit(2);
- }
-
- /* start telnet after reading config for vty_get_bind_addr() */
- rc = telnet_init_dynif(tall_sgsn_ctx, NULL,
- vty_get_bind_addr(), OSMO_VTY_PORT_GBPROXY);
- if (rc < 0)
- exit(1);
-
- /* Start control interface after getting config for
- * ctrl_vty_get_bind_addr() */
- ctrl = ctrl_interface_setup_dynip(gbcfg, ctrl_vty_get_bind_addr(), OSMO_CTRL_PORT_GBPROXY, NULL);
- if (!ctrl) {
- LOGP(DGPRS, LOGL_FATAL, "Failed to create CTRL interface.\n");
- exit(1);
- }
-
- if (gb_ctrl_cmds_install() != 0) {
- LOGP(DGPRS, LOGL_FATAL, "Failed to install CTRL commands.\n");
- exit(1);
- }
-
- if (daemonize) {
- rc = osmo_daemonize();
- if (rc < 0) {
- perror("Error during daemonize");
- exit(1);
- }
- }
-
- while (1) {
- rc = osmo_select_main(0);
- if (rc < 0)
- exit(3);
- }
-
- exit(0);
-}
diff --git a/src/gbproxy/gb_proxy_peer.c b/src/gbproxy/gb_proxy_peer.c
deleted file mode 100644
index 7d6ba864a..000000000
--- a/src/gbproxy/gb_proxy_peer.c
+++ /dev/null
@@ -1,759 +0,0 @@
-/* Gb proxy peer handling */
-
-/* (C) 2010 by Harald Welte <laforge@gnumonks.org>
- * (C) 2010-2013 by On-Waves
- * (C) 2013 by Holger Hans Peter Freyther
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <osmocom/sgsn/gb_proxy.h>
-
-#include <osmocom/sgsn/debug.h>
-
-#include <osmocom/gprs/protocol/gsm_08_18.h>
-#include <osmocom/core/crc16.h>
-#include <osmocom/core/logging.h>
-#include <osmocom/core/linuxlist.h>
-#include <osmocom/core/rate_ctr.h>
-#include <osmocom/core/stats.h>
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/utils.h>
-#include <osmocom/gsm/tlv.h>
-
-#include <string.h>
-
-extern void *tall_sgsn_ctx;
-
-static const struct rate_ctr_desc bvc_ctr_description[] = {
- { "blocked", "BVC Block " },
- { "unblocked", "BVC Unblock " },
- { "dropped", "BVC blocked, dropped packet " },
- { "inv-nsei", "NSEI mismatch " },
- { "tx-err", "NS Transmission error " },
-};
-
-osmo_static_assert(ARRAY_SIZE(bvc_ctr_description) == GBPROX_PEER_CTR_LAST, everything_described);
-
-static const struct rate_ctr_group_desc bvc_ctrg_desc = {
- .group_name_prefix = "gbproxy:peer",
- .group_description = "GBProxy Peer Statistics",
- .num_ctr = ARRAY_SIZE(bvc_ctr_description),
- .ctr_desc = bvc_ctr_description,
- .class_id = OSMO_STATS_CLASS_PEER,
-};
-
-
-/* Find the gbproxy_bvc by its BVCI. There can only be one match */
-struct gbproxy_bvc *gbproxy_bvc_by_bvci(struct gbproxy_nse *nse, uint16_t bvci)
-{
- struct gbproxy_bvc *bvc;
- hash_for_each_possible(nse->bvcs, bvc, list, bvci) {
- if (bvc->bvci == bvci)
- return bvc;
- }
- return NULL;
-}
-
-struct gbproxy_bvc *gbproxy_bvc_alloc(struct gbproxy_nse *nse, uint16_t bvci)
-{
- struct gbproxy_bvc *bvc;
- OSMO_ASSERT(nse);
- struct gbproxy_config *cfg = nse->cfg;
- OSMO_ASSERT(cfg);
-
- bvc = talloc_zero(tall_sgsn_ctx, struct gbproxy_bvc);
- if (!bvc)
- return NULL;
-
- bvc->bvci = bvci;
- bvc->ctrg = rate_ctr_group_alloc(bvc, &bvc_ctrg_desc, (nse->nsei << 16) | bvci);
- if (!bvc->ctrg) {
- talloc_free(bvc);
- return NULL;
- }
- bvc->nse = nse;
-
- hash_add(nse->bvcs, &bvc->list, bvc->bvci);
-
- LOGPBVC_CAT(bvc, DOBJ, LOGL_INFO, "BVC Created\n");
-
- /* We leave allocating the bvc->fi to the caller, as the FSM details depend
- * on the type of BVC (SIG/PTP) and role (SGSN/BSS) */
-
- return bvc;
-}
-
-void gbproxy_bvc_free(struct gbproxy_bvc *bvc)
-{
- struct gbproxy_cell *cell;
-
- if (!bvc)
- return;
-
- LOGPBVC_CAT(bvc, DOBJ, LOGL_INFO, "BVC Destroying\n");
-
- hash_del(&bvc->list);
-
- rate_ctr_group_free(bvc->ctrg);
- bvc->ctrg = NULL;
-
- osmo_fsm_inst_free(bvc->fi);
-
- cell = bvc->cell;
- if (cell) {
- int i;
-
- if (cell->bss_bvc == bvc)
- cell->bss_bvc = NULL;
-
- /* we could also be a SGSN-side BVC */
- for (i = 0; i < ARRAY_SIZE(cell->sgsn_bvc); i++) {
- if (cell->sgsn_bvc[i] == bvc)
- cell->sgsn_bvc[i] = NULL;
- }
- bvc->cell = NULL;
- }
-
- talloc_free(bvc);
-}
-
-/*! remove BVCs on NSE specified by NSEI.
- * \param[in] cfg proxy in which we operate
- * \param[in] nsei NS entity in which we should clean up
- * \param[in] bvci if 0: remove all PTP BVCs; if != 0: BVCI of the single BVC to clean up */
-int gbproxy_cleanup_bvcs(struct gbproxy_nse *nse, uint16_t bvci)
-{
- struct hlist_node *btmp;
- struct gbproxy_bvc *bvc;
- int j, counter = 0;
-
- if (!nse)
- return 0;
-
- hash_for_each_safe(nse->bvcs, j, btmp, bvc, list) {
- if (bvci && bvc->bvci != bvci)
- continue;
- if (bvci == 0 && bvc->bvci == 0)
- continue;
-
- gbproxy_bvc_free(bvc);
- counter += 1;
- }
-
- return counter;
-}
-
-
-/***********************************************************************
- * CELL
- ***********************************************************************/
-
-/* Allocate a new 'cell' object */
-struct gbproxy_cell *gbproxy_cell_alloc(struct gbproxy_config *cfg, uint16_t bvci)
-{
- struct gbproxy_cell *cell;
- OSMO_ASSERT(cfg);
-
- cell = talloc_zero(cfg, struct gbproxy_cell);
- if (!cell)
- return NULL;
-
- cell->cfg = cfg;
- cell->bvci = bvci;
-
- hash_add(cfg->cells, &cell->list, cell->bvci);
-
- LOGPCELL_CAT(cell, DOBJ, LOGL_INFO, "CELL Created\n");
-
- return cell;
-}
-
-/* Find cell by BVCI */
-struct gbproxy_cell *gbproxy_cell_by_bvci(struct gbproxy_config *cfg, uint16_t bvci)
-{
- struct gbproxy_cell *cell;
-
- hash_for_each_possible(cfg->cells, cell, list, bvci) {
- if (cell->bvci == bvci)
- return cell;
- }
- return NULL;
-}
-
-struct gbproxy_cell *gbproxy_cell_by_bvci_or_new(struct gbproxy_config *cfg, uint16_t bvci)
-{
- struct gbproxy_cell *cell;
- OSMO_ASSERT(cfg);
-
- cell = gbproxy_cell_by_bvci(cfg, bvci);
- if (!cell)
- cell = gbproxy_cell_alloc(cfg, bvci);
-
- return cell;
-}
-
-void gbproxy_cell_free(struct gbproxy_cell *cell)
-{
- unsigned int i;
-
- if (!cell)
- return;
-
- LOGPCELL_CAT(cell, DOBJ, LOGL_INFO, "CELL Destroying\n");
-
- /* remove from cfg.cells */
- hash_del(&cell->list);
-
- /* remove back-pointers from the BSS side */
- if (cell->bss_bvc && cell->bss_bvc->cell)
- cell->bss_bvc->cell = NULL;
-
- /* remove back-pointers from the SGSN side */
- for (i = 0; i < ARRAY_SIZE(cell->sgsn_bvc); i++) {
- if (!cell->sgsn_bvc[i])
- continue;
- if (cell->sgsn_bvc[i]->cell)
- cell->sgsn_bvc[i]->cell = NULL;
- }
-
- talloc_free(cell);
-}
-
-bool gbproxy_cell_add_sgsn_bvc(struct gbproxy_cell *cell, struct gbproxy_bvc *bvc)
-{
- unsigned int i;
- for (i = 0; i < ARRAY_SIZE(cell->sgsn_bvc); i++) {
- if (!cell->sgsn_bvc[i]) {
- cell->sgsn_bvc[i] = bvc;
- LOGPCELL_CAT(cell, DOBJ, LOGL_DEBUG, "CELL linked to SGSN\n");
- LOGPBVC_CAT(bvc, DOBJ, LOGL_DEBUG, "BVC linked to CELL\n");
- return true;
- }
- }
- return false;
-}
-
-
-/***********************************************************************
- * TLLI cache
- ***********************************************************************/
-
-static inline struct gbproxy_tlli_cache_entry *_get_tlli_entry(struct gbproxy_config *cfg, uint32_t tlli)
-{
- struct gbproxy_tlli_cache_entry *cache_entry;
-
- hash_for_each_possible(cfg->tlli_cache.entries, cache_entry, list, tlli) {
- if (cache_entry->tlli == tlli)
- return cache_entry;
- }
- return NULL;
-}
-
-void gbproxy_tlli_cache_update(struct gbproxy_nse *nse, uint32_t tlli)
-{
- struct gbproxy_config *cfg = nse->cfg;
- struct timespec now;
- struct gbproxy_tlli_cache_entry *cache_entry = _get_tlli_entry(cfg, tlli);
-
- osmo_clock_gettime(CLOCK_MONOTONIC, &now);
-
- if (cache_entry) {
- /* Update the entry if it already exists */
- cache_entry->nse = nse;
- cache_entry->tstamp = now.tv_sec;
- return;
- }
-
- cache_entry = talloc_zero(cfg, struct gbproxy_tlli_cache_entry);
- cache_entry->tlli = tlli;
- cache_entry->nse = nse;
- cache_entry->tstamp = now.tv_sec;
- hash_add(cfg->tlli_cache.entries, &cache_entry->list, cache_entry->tlli);
-}
-
-static void _tlli_cache_remove_nse(struct gbproxy_nse *nse) {
- uint i;
- struct gbproxy_config *cfg = nse->cfg;
- struct gbproxy_tlli_cache_entry *tlli_cache;
- struct hlist_node *tmp;
-
- hash_for_each_safe(cfg->tlli_cache.entries, i, tmp, tlli_cache, list) {
- if (tlli_cache->nse == nse) {
- hash_del(&tlli_cache->list);
- talloc_free(tlli_cache);
- }
- }
-}
-
-void gbproxy_tlli_cache_remove(struct gbproxy_config *cfg, uint32_t tlli)
-{
- struct gbproxy_tlli_cache_entry *tlli_cache;
- struct hlist_node *tmp;
-
- hash_for_each_possible_safe(cfg->tlli_cache.entries, tlli_cache, tmp, list, tlli) {
- if (tlli_cache->tlli == tlli) {
- hash_del(&tlli_cache->list);
- talloc_free(tlli_cache);
- return;
- }
- }
-}
-
-int gbproxy_tlli_cache_cleanup(struct gbproxy_config *cfg)
-{
- int i, count = 0;
- struct gbproxy_tlli_cache_entry *tlli_cache;
- struct hlist_node *tmp;
- struct timespec now;
- time_t expiry;
-
- osmo_clock_gettime(CLOCK_MONOTONIC, &now);
- expiry = now.tv_sec - cfg->tlli_cache.timeout;
-
- hash_for_each_safe(cfg->tlli_cache.entries, i, tmp, tlli_cache, list) {
- if (tlli_cache->tstamp < expiry) {
- count++;
- LOGP(DGPRS, LOGL_NOTICE, "Cache entry for TLLI %08x expired, removing\n", tlli_cache->tlli);
- hash_del(&tlli_cache->list);
- talloc_free(tlli_cache);
- }
- }
- return count;
-
-}
-/***********************************************************************
- * IMSI cache
- ***********************************************************************/
-static inline uint16_t _checksum_imsi(const char *imsi)
-{
- size_t len = strlen(imsi);
- return osmo_crc16(0, (const uint8_t *)imsi, len);
-}
-
-static inline struct gbproxy_imsi_cache_entry *_get_imsi_entry(struct gbproxy_config *cfg, const char *imsi)
-{
- struct gbproxy_imsi_cache_entry *cache_entry;
- uint16_t imsi_hash = _checksum_imsi(imsi);
-
- hash_for_each_possible(cfg->imsi_cache.entries, cache_entry, list, imsi_hash) {
- if (!strncmp(cache_entry->imsi, imsi, sizeof(cache_entry->imsi)))
- return cache_entry;
- }
- return NULL;
-}
-
-void gbproxy_imsi_cache_update(struct gbproxy_nse *nse, const char *imsi)
-{
- struct gbproxy_config *cfg = nse->cfg;
- struct timespec now;
- struct gbproxy_imsi_cache_entry *cache_entry = _get_imsi_entry(cfg, imsi);
- uint16_t imsi_hash = _checksum_imsi(imsi);
-
- osmo_clock_gettime(CLOCK_MONOTONIC, &now);
-
- if (cache_entry) {
- /* Update the entry if it already exists */
- cache_entry->nse = nse;
- cache_entry->tstamp = now.tv_sec;
- return;
- }
-
- cache_entry = talloc_zero(cfg, struct gbproxy_imsi_cache_entry);
- OSMO_STRLCPY_ARRAY(cache_entry->imsi, imsi);
- cache_entry->nse = nse;
- cache_entry->tstamp = now.tv_sec;
- hash_add(cfg->imsi_cache.entries, &cache_entry->list, imsi_hash);
-}
-
-static void _imsi_cache_remove_nse(struct gbproxy_nse *nse) {
- uint i;
- struct gbproxy_config *cfg = nse->cfg;
- struct gbproxy_imsi_cache_entry *imsi_cache;
- struct hlist_node *tmp;
-
- hash_for_each_safe(cfg->imsi_cache.entries, i, tmp, imsi_cache, list) {
- if (imsi_cache->nse == nse) {
- hash_del(&imsi_cache->list);
- talloc_free(imsi_cache);
- }
- }
-}
-
-void gbproxy_imsi_cache_remove(struct gbproxy_config *cfg, const char *imsi)
-{
- struct gbproxy_imsi_cache_entry *imsi_cache;
- struct hlist_node *tmp;
- uint16_t imsi_hash = _checksum_imsi(imsi);
-
- hash_for_each_possible_safe(cfg->imsi_cache.entries, imsi_cache, tmp, list, imsi_hash) {
- if (!(strncmp(imsi_cache->imsi, imsi, sizeof(imsi_cache->imsi)))) {
- hash_del(&imsi_cache->list);
- talloc_free(imsi_cache);
- return;
- }
- }
-}
-
-int gbproxy_imsi_cache_cleanup(struct gbproxy_config *cfg)
-{
- int i, count = 0;
- struct gbproxy_imsi_cache_entry *imsi_cache;
- struct hlist_node *tmp;
- struct timespec now;
- time_t expiry;
-
- osmo_clock_gettime(CLOCK_MONOTONIC, &now);
- expiry = now.tv_sec - cfg->imsi_cache.timeout;
-
- hash_for_each_safe(cfg->imsi_cache.entries, i, tmp, imsi_cache, list) {
- if (imsi_cache->tstamp < expiry) {
- count++;
- LOGP(DGPRS, LOGL_NOTICE, "Cache entry for IMSI %s expired, removing\n", imsi_cache->imsi);
- hash_del(&imsi_cache->list);
- talloc_free(imsi_cache);
- }
- }
- return count;
-}
-
-/***********************************************************************
- * NSE - NS Entity
- ***********************************************************************/
-
-struct gbproxy_nse *gbproxy_nse_alloc(struct gbproxy_config *cfg, uint16_t nsei, bool sgsn_facing)
-{
- struct gbproxy_nse *nse;
- OSMO_ASSERT(cfg);
-
- nse = talloc_zero(tall_sgsn_ctx, struct gbproxy_nse);
- if (!nse)
- return NULL;
-
- nse->nsei = nsei;
- nse->cfg = cfg;
- nse->sgsn_facing = sgsn_facing;
-
- if (sgsn_facing)
- hash_add(cfg->sgsn_nses, &nse->list, nsei);
- else
- hash_add(cfg->bss_nses, &nse->list, nsei);
-
- hash_init(nse->bvcs);
-
- LOGPNSE_CAT(nse, DOBJ, LOGL_INFO, "NSE Created\n");
-
- return nse;
-}
-
-static void _nse_free(struct gbproxy_nse *nse)
-{
- struct gbproxy_bvc *bvc;
- struct hlist_node *tmp;
- int i;
-
- if (!nse)
- return;
-
- LOGPNSE_CAT(nse, DOBJ, LOGL_INFO, "NSE Destroying\n");
-
- hash_del(&nse->list);
- /* Clear the cache entries of this NSE */
- _tlli_cache_remove_nse(nse);
- _imsi_cache_remove_nse(nse);
-
- hash_for_each_safe(nse->bvcs, i, tmp, bvc, list)
- gbproxy_bvc_free(bvc);
-
- talloc_free(nse);
-}
-static void _sgsn_free(struct gbproxy_sgsn *sgsn);
-
-void gbproxy_nse_free(struct gbproxy_nse *nse)
-{
- if (!nse)
- return;
- OSMO_ASSERT(nse->cfg);
-
- if (nse->sgsn_facing) {
- struct gbproxy_sgsn *sgsn = gbproxy_sgsn_by_nsei(nse->cfg, nse->nsei);
- OSMO_ASSERT(sgsn);
- _sgsn_free(sgsn);
- }
-
- _nse_free(nse);
-}
-
-struct gbproxy_nse *gbproxy_nse_by_nsei(struct gbproxy_config *cfg, uint16_t nsei, uint32_t flags)
-{
- struct gbproxy_nse *nse;
- OSMO_ASSERT(cfg);
-
- if (flags & NSE_F_SGSN) {
- hash_for_each_possible(cfg->sgsn_nses, nse, list, nsei) {
- if (nse->nsei == nsei)
- return nse;
- }
- }
-
- if (flags & NSE_F_BSS) {
- hash_for_each_possible(cfg->bss_nses, nse, list, nsei) {
- if (nse->nsei == nsei)
- return nse;
- }
- }
-
- return NULL;
-}
-
-struct gbproxy_nse *gbproxy_nse_by_nsei_or_new(struct gbproxy_config *cfg, uint16_t nsei, bool sgsn_facing)
-{
- struct gbproxy_nse *nse;
- OSMO_ASSERT(cfg);
-
- nse = gbproxy_nse_by_nsei(cfg, nsei, sgsn_facing ? NSE_F_SGSN : NSE_F_BSS);
- if (!nse)
- nse = gbproxy_nse_alloc(cfg, nsei, sgsn_facing);
-
- return nse;
-}
-
-struct gbproxy_nse *gbproxy_nse_by_tlli(struct gbproxy_config *cfg, uint32_t tlli)
-{
- struct gbproxy_tlli_cache_entry *tlli_cache;
-
- hash_for_each_possible(cfg->tlli_cache.entries, tlli_cache, list, tlli) {
- if (tlli_cache->tlli == tlli)
- return tlli_cache->nse;
- }
- return NULL;
-}
-
-struct gbproxy_nse *gbproxy_nse_by_imsi(struct gbproxy_config *cfg, const char *imsi)
-{
- struct gbproxy_imsi_cache_entry *imsi_cache;
- uint16_t imsi_hash = _checksum_imsi(imsi);
-
- hash_for_each_possible(cfg->imsi_cache.entries, imsi_cache, list, imsi_hash) {
- if (!strncmp(imsi_cache->imsi, imsi, sizeof(imsi_cache->imsi)))
- return imsi_cache->nse;
- }
- return NULL;
-}
-
-/***********************************************************************
- * SGSN - Serving GPRS Support Node
- ***********************************************************************/
-
-/*! Allocate a new SGSN. This ensures the corresponding gbproxy_nse is allocated as well
- * \param[in] cfg The gbproxy configuration
- * \param[in] nsei The nsei where the SGSN can be reached
- * \param[in] name A name to give the SGSN
- * \return The SGSN, NULL if it couldn't be allocated
- */
-struct gbproxy_sgsn *gbproxy_sgsn_alloc(struct gbproxy_config *cfg, uint16_t nsei, const char *name)
-{
- struct gbproxy_sgsn *sgsn;
- OSMO_ASSERT(cfg);
-
- sgsn = talloc_zero(tall_sgsn_ctx, struct gbproxy_sgsn);
- if (!sgsn)
- return NULL;
-
- sgsn->nse = gbproxy_nse_alloc(cfg, nsei, true);
- if (!sgsn->nse) {
- LOGP(DOBJ, LOGL_ERROR, "Could not allocate NSE(%05u) for SGSN(%s)\n",
- nsei, sgsn->name);
- goto free_sgsn;
- }
-
- if (name)
- sgsn->name = talloc_strdup(sgsn, name);
- else
- sgsn->name = talloc_asprintf(sgsn, "NSE(%05u)", sgsn->nse->nsei);
- if (!sgsn->name)
- goto free_sgsn;
-
- sgsn->pool.allow_attach = true;
- sgsn->pool.nri_ranges = osmo_nri_ranges_alloc(sgsn);
-
- llist_add_tail(&sgsn->list, &cfg->sgsns);
- LOGPSGSN_CAT(sgsn, DOBJ, LOGL_INFO, "SGSN Created\n");
- return sgsn;
-
-free_sgsn:
- talloc_free(sgsn);
- return NULL;
-}
-
-/* Only free gbproxy_sgsn, sgsn can't be NULL */
-static void _sgsn_free(struct gbproxy_sgsn *sgsn) {
- struct gbproxy_config *cfg;
-
- OSMO_ASSERT(sgsn->nse);
- cfg = sgsn->nse->cfg;
- OSMO_ASSERT(cfg);
-
- LOGPSGSN_CAT(sgsn, DOBJ, LOGL_INFO, "SGSN Destroying\n");
- llist_del(&sgsn->list);
- /* talloc will free ->name and ->pool.nri_ranges */
- talloc_free(sgsn);
-}
-
-/*! Free the SGSN. This ensures the corresponding gbproxy_nse is freed as well
- * \param[in] sgsn The SGSN
- */
-void gbproxy_sgsn_free(struct gbproxy_sgsn *sgsn)
-{
- if (!sgsn)
- return;
-
- OSMO_ASSERT(sgsn->nse)
-
- _nse_free(sgsn->nse);
- _sgsn_free(sgsn);
-}
-
-/*! Return the SGSN for a given NSEI
- * \param[in] cfg The gbproxy configuration
- * \param[in] nsei The nsei where the SGSN can be reached
- * \return Returns the matching SGSN or NULL if it couldn't be found
- */
-struct gbproxy_sgsn *gbproxy_sgsn_by_name(struct gbproxy_config *cfg, const char *name)
-{
- struct gbproxy_sgsn *sgsn;
- OSMO_ASSERT(cfg);
-
- llist_for_each_entry(sgsn, &cfg->sgsns, list) {
- if (!strcmp(sgsn->name, name))
- return sgsn;
- }
-
- return NULL;
-}
-
-/*! Return the SGSN for a given NSEI
- * \param[in] cfg The gbproxy configuration
- * \param[in] nsei The nsei where the SGSN can be reached
- * \return Returns the matching SGSN or NULL if it couldn't be found
- */
-struct gbproxy_sgsn *gbproxy_sgsn_by_nsei(struct gbproxy_config *cfg, uint16_t nsei)
-{
- struct gbproxy_sgsn *sgsn;
- OSMO_ASSERT(cfg);
-
- llist_for_each_entry(sgsn, &cfg->sgsns, list) {
- if (sgsn->nse->nsei == nsei)
- return sgsn;
- }
-
- return NULL;
-}
-
-/*! Return the SGSN for a given NSEI, creating a new one if none exists
- * \param[in] cfg The gbproxy configuration
- * \param[in] nsei The nsei where the SGSN can be reached
- * \return Returns the SGSN
- */
-struct gbproxy_sgsn *gbproxy_sgsn_by_nsei_or_new(struct gbproxy_config *cfg, uint16_t nsei)
-{
- struct gbproxy_sgsn *sgsn;
- OSMO_ASSERT(cfg);
-
- sgsn = gbproxy_sgsn_by_nsei(cfg, nsei);
- if (!sgsn)
- sgsn = gbproxy_sgsn_alloc(cfg, nsei, NULL);
-
- return sgsn;
-}
-
-/*! Return the gbproxy_sgsn matching that NRI
- * \param[in] cfg proxy in which we operate
- * \param[in] nri NRI to look for
- * \param[out] null_nri If not NULL this indicates whether the NRI is a null NRI
- * \return The SGSN this NRI has been added to, NULL if no matching SGSN could be found
- */
-struct gbproxy_sgsn *gbproxy_sgsn_by_nri(struct gbproxy_config *cfg, uint16_t nri, bool *null_nri)
-{
- struct gbproxy_sgsn *sgsn;
- OSMO_ASSERT(cfg);
-
- llist_for_each_entry(sgsn, &cfg->sgsns, list) {
- if (osmo_nri_v_matches_ranges(nri, sgsn->pool.nri_ranges)) {
- /* Also check if the NRI we're looking for is a NULL NRI */
- if (null_nri) {
- if (osmo_nri_v_matches_ranges(nri, cfg->pool.null_nri_ranges))
- *null_nri = true;
- else
- *null_nri = false;
- }
- return sgsn;
- }
- }
-
- return NULL;
-}
-
-/*! Seleect a pseudo-random SGSN for a given TLLI, ignoring any SGSN that is not accepting connections
- * \param[in] cfg The gbproxy configuration
- * \param[in] sgsn_avoid If not NULL then avoid this SGSN when selecting a new one. Use for load redistribution
- * \param[in] tlli The tlli to choose an SGSN for. The same tlli will map to the same SGSN as long as no SGSN is
- * added/removed or allow_attach changes.
- * \return Returns the sgsn on success, NULL if no SGSN that allows new connections could be found
- */
-struct gbproxy_sgsn *gbproxy_sgsn_by_tlli(struct gbproxy_config *cfg, struct gbproxy_sgsn *sgsn_avoid,
- uint32_t tlli)
-{
- uint32_t i = 0;
- uint32_t index, num_sgsns;
- OSMO_ASSERT(cfg);
-
- struct gbproxy_sgsn *sgsn = cfg->pool.nsf_override;
-
- if (sgsn) {
- LOGPSGSN(sgsn, LOGL_DEBUG, "Node selection function is overridden by config\n");
- return sgsn;
- }
-
- /* TODO: We should keep track of count in cfg */
- num_sgsns = llist_count(&cfg->sgsns);
-
- if (num_sgsns == 0)
- return NULL;
-
- /* FIXME: 256 SGSNs ought to be enough for everyone */
- index = hash_32(tlli, 8) % num_sgsns;
-
- /* Get the first enabled SGSN after index */
- llist_for_each_entry(sgsn, &cfg->sgsns, list) {
- if (i >= index && sgsn->pool.allow_attach) {
- return sgsn;
- }
- i++;
- }
- /* Start again from the beginning */
- i = 0;
- llist_for_each_entry(sgsn, &cfg->sgsns, list) {
- if (i >= index) {
- break;
- } else if (sgsn->pool.allow_attach) {
- return sgsn;
- }
- i++;
- }
-
- return NULL;
-}
diff --git a/src/gbproxy/gb_proxy_vty.c b/src/gbproxy/gb_proxy_vty.c
deleted file mode 100644
index 7ae65d20e..000000000
--- a/src/gbproxy/gb_proxy_vty.c
+++ /dev/null
@@ -1,778 +0,0 @@
-/*
- * (C) 2010 by Harald Welte <laforge@gnumonks.org>
- * (C) 2010 by On-Waves
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <string.h>
-#include <time.h>
-#include <inttypes.h>
-
-#include <osmocom/core/hashtable.h>
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/timer.h>
-#include <osmocom/core/rate_ctr.h>
-#include <osmocom/core/utils.h>
-
-#include <osmocom/gprs/gprs_ns2.h>
-#include <osmocom/gprs/bssgp_bvc_fsm.h>
-
-#include <osmocom/gsm/apn.h>
-#include <osmocom/gsm/gsm23236.h>
-#include <osmocom/gsm/gsm48.h>
-
-#include <osmocom/sgsn/debug.h>
-#include <osmocom/sgsn/gb_proxy.h>
-#include <osmocom/sgsn/gprs_utils.h>
-#include <osmocom/sgsn/vty.h>
-
-#include <osmocom/vty/command.h>
-#include <osmocom/vty/logging.h>
-#include <osmocom/vty/vty.h>
-#include <osmocom/vty/misc.h>
-
-#define GBPROXY_STR "Display information about the Gb proxy\n"
-#define NRI_STR "Mapping of Network Resource Indicators to this SGSN, for SGSN pooling\n"
-#define NULL_NRI_STR "Define NULL-NRI values that cause re-assignment of an MS to a different SGSN, for SGSN pooling.\n"
-#define NRI_FIRST_LAST_STR "First value of the NRI value range, should not surpass the configured 'nri bitlen'.\n" \
- "Last value of the NRI value range, should not surpass the configured 'nri bitlen' and be larger than the" \
- " first value; if omitted, apply only the first value.\n"
-#define NRI_ARGS_TO_STR_FMT "%s%s%s"
-#define NRI_ARGS_TO_STR_ARGS(ARGC, ARGV) ARGV[0], (ARGC>1)? ".." : "", (ARGC>1)? ARGV[1] : ""
-#define NRI_WARN(SGSN, FORMAT, args...) do { \
- vty_out(vty, "%% Warning: NSE(%05d/SGSN): " FORMAT "%s", (SGSN)->nse->nsei, ##args, VTY_NEWLINE); \
- LOGP(DLBSSGP, LOGL_ERROR, "NSE(%05d/SGSN): " FORMAT "\n", (SGSN)->nse->nsei, ##args); \
- } while (0)
-
-static struct gbproxy_config *g_cfg = NULL;
-
-/*
- * vty code for gbproxy below
- */
-static struct cmd_node gbproxy_node = {
- GBPROXY_NODE,
- "%s(config-gbproxy)# ",
- 1,
-};
-
-static void gbprox_vty_print_bvc(struct vty *vty, struct gbproxy_bvc *bvc)
-{
-
- if (bvc->bvci == 0) {
- vty_out(vty, "NSEI %5u, SIG-BVCI %5u [%s]%s", bvc->nse->nsei, bvc->bvci,
- osmo_fsm_inst_state_name(bvc->fi), VTY_NEWLINE);
- } else {
- struct gprs_ra_id raid;
- gsm48_parse_ra(&raid, bvc->ra);
- vty_out(vty, "NSEI %5u, PTP-BVCI %5u, RAI %s [%s]%s", bvc->nse->nsei, bvc->bvci,
- osmo_rai_name(&raid), osmo_fsm_inst_state_name(bvc->fi), VTY_NEWLINE);
- }
-}
-
-static void gbproxy_vty_print_nse(struct vty *vty, struct gbproxy_nse *nse, bool show_stats)
-{
- struct gbproxy_bvc *bvc;
- int j;
-
- hash_for_each(nse->bvcs, j, bvc, list) {
- gbprox_vty_print_bvc(vty, bvc);
-
- if (show_stats)
- vty_out_rate_ctr_group(vty, " ", bvc->ctrg);
- }
-}
-
-static void gbproxy_vty_print_cell(struct vty *vty, struct gbproxy_cell *cell, bool show_stats)
-{
- struct gprs_ra_id raid;
- gsm48_parse_ra(&raid, cell->ra);
- unsigned int num_sgsn_bvc = 0;
- unsigned int i;
-
- vty_out(vty, "BVCI %5u RAI %s: ", cell->bvci, osmo_rai_name(&raid));
- if (cell->bss_bvc)
- vty_out(vty, "BSS NSEI %5u, SGSN NSEI ", cell->bss_bvc->nse->nsei);
- else
- vty_out(vty, "BSS NSEI <none>, SGSN NSEI ");
-
- for (i = 0; i < ARRAY_SIZE(cell->sgsn_bvc); i++) {
- struct gbproxy_bvc *sgsn_bvc = cell->sgsn_bvc[i];
- if (sgsn_bvc) {
- vty_out(vty, "%5u ", sgsn_bvc->nse->nsei);
- num_sgsn_bvc++;
- }
- }
- if (num_sgsn_bvc)
- vty_out(vty, "%s", VTY_NEWLINE);
- else
- vty_out(vty, "<none>%s", VTY_NEWLINE);
-}
-
-static int config_write_gbproxy(struct vty *vty)
-{
- struct osmo_nri_range *r;
-
- vty_out(vty, "gbproxy%s", VTY_NEWLINE);
-
- if (g_cfg->pool.bvc_fc_ratio != 100)
- vty_out(vty, " pool bvc-flow-control-ratio %u%s", g_cfg->pool.bvc_fc_ratio, VTY_NEWLINE);
-
- if (g_cfg->pool.nri_bitlen != OSMO_NRI_BITLEN_DEFAULT)
- vty_out(vty, " nri bitlen %u%s", g_cfg->pool.nri_bitlen, VTY_NEWLINE);
-
- llist_for_each_entry(r, &g_cfg->pool.null_nri_ranges->entries, entry) {
- vty_out(vty, " nri null add %d", r->first);
- if (r->first != r->last)
- vty_out(vty, " %d", r->last);
- vty_out(vty, "%s", VTY_NEWLINE);
- }
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_gbproxy,
- cfg_gbproxy_cmd,
- "gbproxy",
- "Configure the Gb proxy")
-{
- vty->node = GBPROXY_NODE;
- return CMD_SUCCESS;
-}
-
-/* VTY code for SGSN (pool) configuration */
-extern const struct bssgp_bvc_fsm_ops sgsn_sig_bvc_fsm_ops;
-#include <osmocom/gprs/protocol/gsm_08_18.h>
-
-static struct cmd_node sgsn_node = {
- SGSN_NODE,
- "%s(config-sgsn)# ",
- 1,
-};
-
-static void sgsn_write_nri(struct vty *vty, struct gbproxy_sgsn *sgsn, bool verbose)
-{
- struct osmo_nri_range *r;
-
- if (verbose) {
- vty_out(vty, "sgsn nsei %d%s", sgsn->nse->nsei, VTY_NEWLINE);
- if (llist_empty(&sgsn->pool.nri_ranges->entries)) {
- vty_out(vty, " %% no NRI mappings%s", VTY_NEWLINE);
- return;
- }
- }
-
- llist_for_each_entry(r, &sgsn->pool.nri_ranges->entries, entry) {
- if (osmo_nri_range_validate(r, 255))
- vty_out(vty, " %% INVALID RANGE:");
- vty_out(vty, " nri add %d", r->first);
- if (r->first != r->last)
- vty_out(vty, " %d", r->last);
- vty_out(vty, "%s", VTY_NEWLINE);
- }
-}
-
-static void write_sgsn(struct vty *vty, struct gbproxy_sgsn *sgsn)
-{
- vty_out(vty, "sgsn nsei %u%s", sgsn->nse->nsei, VTY_NEWLINE);
- vty_out(vty, " name %s%s", sgsn->name, VTY_NEWLINE);
- vty_out(vty, " %sallow-attach%s", sgsn->pool.allow_attach ? "" : "no ", VTY_NEWLINE);
- sgsn_write_nri(vty, sgsn, false);
-}
-
-static int config_write_sgsn(struct vty *vty)
-{
- struct gbproxy_sgsn *sgsn;
-
- llist_for_each_entry(sgsn, &g_cfg->sgsns, list)
- write_sgsn(vty, sgsn);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_sgsn_nsei,
- cfg_sgsn_nsei_cmd,
- "sgsn nsei <0-65534>",
- "Configure the SGSN\n"
- "NSEI to be used in the connection with the SGSN\n"
- "The NSEI\n")
-{
- uint32_t features = 0; // FIXME: make configurable
- unsigned int nsei = atoi(argv[0]);
- unsigned int num_sgsn = llist_count(&g_cfg->sgsns);
- struct gbproxy_sgsn *sgsn;
- struct gbproxy_nse *nse;
- struct gbproxy_bvc *bvc;
-
- if (num_sgsn >= GBPROXY_MAX_NR_SGSN) {
- vty_out(vty, "%% Too many SGSN NSE defined (%d), increase GBPROXY_MAX_NR_SGSN%s",
- num_sgsn, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- /* This will have created the gbproxy_nse as well */
- sgsn = gbproxy_sgsn_by_nsei_or_new(g_cfg, nsei);
- if (!sgsn)
- goto free_nothing;
- nse = sgsn->nse;
- if (num_sgsn > 1 && g_cfg->pool.nri_bitlen == 0)
- vty_out(vty, "%% Multiple SGSNs defined, but no pooling enabled%s", VTY_NEWLINE);
-
-
- if (!gbproxy_bvc_by_bvci(nse, 0)) {
- uint8_t cause = BSSGP_CAUSE_OML_INTERV;
- bvc = gbproxy_bvc_alloc(nse, 0);
- if (!bvc)
- goto free_sgsn;
- bvc->fi = bssgp_bvc_fsm_alloc_sig_bss(bvc, nse->cfg->nsi, nsei, features);
- if (!bvc->fi)
- goto free_bvc;
- bssgp_bvc_fsm_set_ops(bvc->fi, &sgsn_sig_bvc_fsm_ops, bvc);
- osmo_fsm_inst_dispatch(bvc->fi, BSSGP_BVCFSM_E_REQ_RESET, &cause);
- }
-
- vty->node = SGSN_NODE;
- vty->index = sgsn;
- return CMD_SUCCESS;
-
-free_bvc:
- gbproxy_bvc_free(bvc);
-free_sgsn:
- gbproxy_sgsn_free(sgsn);
-free_nothing:
- vty_out(vty, "%% Unable to create NSE for NSEI=%05u%s", nsei, VTY_NEWLINE);
- return CMD_WARNING;
-}
-
-DEFUN(cfg_sgsn_name,
- cfg_sgsn_name_cmd,
- "name NAME",
- "Configure the SGSN\n"
- "Name the SGSN\n"
- "The name\n")
-{
- struct gbproxy_sgsn *sgsn = vty->index;
- const char *name = argv[0];
-
-
- osmo_talloc_replace_string(sgsn, &sgsn->name, name);
- if (!sgsn->name) {
- vty_out(vty, "%% Unable to set name for SGSN with nsei %05u%s", sgsn->nse->nsei, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- return CMD_SUCCESS;
-}
-
-DEFUN_ATTR(cfg_sgsn_nri_add, cfg_sgsn_nri_add_cmd,
- "nri add <0-32767> [<0-32767>]",
- NRI_STR "Add NRI value or range to the NRI mapping for this MSC\n"
- NRI_FIRST_LAST_STR,
- CMD_ATTR_IMMEDIATE)
-{
- struct gbproxy_sgsn *sgsn = vty->index;
- struct gbproxy_sgsn *other_sgsn;
- bool before;
- int rc;
- const char *message;
- struct osmo_nri_range add_range;
-
- rc = osmo_nri_ranges_vty_add(&message, &add_range, sgsn->pool.nri_ranges, argc, argv, g_cfg->pool.nri_bitlen);
- if (message) {
- NRI_WARN(sgsn, "%s: " NRI_ARGS_TO_STR_FMT, message, NRI_ARGS_TO_STR_ARGS(argc, argv));
- }
- if (rc < 0)
- return CMD_WARNING;
-
- /* Issue a warning about NRI range overlaps (but still allow them).
- * Overlapping ranges will map to whichever SGSN comes fist in the gbproxy_config->sgsns llist,
- * which should be the first one defined in the config */
- before = true;
-
- llist_for_each_entry(other_sgsn, &g_cfg->sgsns, list) {
- if (other_sgsn == sgsn) {
- before = false;
- continue;
- }
- if (osmo_nri_range_overlaps_ranges(&add_range, other_sgsn->pool.nri_ranges)) {
- uint16_t nsei = sgsn->nse->nsei;
- uint16_t other_nsei = other_sgsn->nse->nsei;
- NRI_WARN(sgsn, "NRI range [%d..%d] overlaps between NSE %05d and NSE %05d."
- " For overlaps, NSE %05d has higher priority than NSE %05d",
- add_range.first, add_range.last, nsei, other_nsei,
- before ? other_nsei : nsei, before ? nsei : other_nsei);
- }
- }
- return CMD_SUCCESS;
-}
-
-DEFUN_ATTR(cfg_sgsn_nri_del, cfg_sgsn_nri_del_cmd,
- "nri del <0-32767> [<0-32767>]",
- NRI_STR "Remove NRI value or range from the NRI mapping for this MSC\n"
- NRI_FIRST_LAST_STR,
- CMD_ATTR_IMMEDIATE)
-{
- struct gbproxy_sgsn *sgsn = vty->index;
- int rc;
- const char *message;
-
- rc = osmo_nri_ranges_vty_del(&message, NULL, sgsn->pool.nri_ranges, argc, argv);
- if (message) {
- NRI_WARN(sgsn, "%s: " NRI_ARGS_TO_STR_FMT, message, NRI_ARGS_TO_STR_ARGS(argc, argv));
- }
- if (rc < 0)
- return CMD_WARNING;
- return CMD_SUCCESS;
-}
-
-DEFUN_ATTR(cfg_sgsn_allow_attach, cfg_sgsn_allow_attach_cmd,
- "allow-attach",
- "Allow this SGSN to attach new subscribers (default).\n",
- CMD_ATTR_IMMEDIATE)
-{
- struct gbproxy_sgsn *sgsn = vty->index;
- sgsn->pool.allow_attach = true;
- return CMD_SUCCESS;
-}
-
-DEFUN_ATTR(cfg_sgsn_no_allow_attach, cfg_sgsn_no_allow_attach_cmd,
- "no allow-attach",
- NO_STR
- "Do not assign new subscribers to this MSC."
- " Useful if an MSC in an MSC pool is configured to off-load subscribers."
- " The MSC will still be operational for already IMSI-Attached subscribers,"
- " but the NAS node selection function will skip this MSC for new subscribers\n",
- CMD_ATTR_IMMEDIATE)
-{
- struct gbproxy_sgsn *sgsn = vty->index;
- sgsn->pool.allow_attach = false;
- return CMD_SUCCESS;
-}
-
-DEFUN(sgsn_show_nri_all, show_nri_all_cmd,
- "show nri all",
- SHOW_STR NRI_STR "Show all SGSNs\n")
-{
- struct gbproxy_sgsn *sgsn;
-
- llist_for_each_entry(sgsn, &g_cfg->sgsns, list)
- sgsn_write_nri(vty, sgsn, true);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(show_nri_nsei, show_nri_nsei_cmd,
- "show nri nsei <0-65535>",
- SHOW_STR NRI_STR "Identify SGSN by NSEI\n"
- "NSEI of the SGSN\n")
-{
- struct gbproxy_sgsn *sgsn;
- int nsei = atoi(argv[0]);
-
- sgsn = gbproxy_sgsn_by_nsei(g_cfg, nsei);
- if (!sgsn) {
- vty_out(vty, "%% No SGSN with found for NSEI %05d%s", nsei, VTY_NEWLINE);
- return CMD_SUCCESS;
- }
- sgsn_write_nri(vty, sgsn, true);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_pool_bvc_fc_ratio,
- cfg_pool_bvc_fc_ratio_cmd,
- "pool bvc-flow-control-ratio <1-100>",
- "SGSN Pool related configuration\n"
- "Ratio of BSS-advertised bucket size + leak rate advertised to each SGSN\n"
- "Ratio of BSS-advertised bucket size + leak rate advertised to each SGSN (Percent)\n")
-{
- g_cfg->pool.bvc_fc_ratio = atoi(argv[0]);
- return CMD_SUCCESS;
-}
-DEFUN_ATTR(cfg_gbproxy_nri_bitlen,
- cfg_gbproxy_nri_bitlen_cmd,
- "nri bitlen <0-15>",
- NRI_STR
- "Set number of bits that an NRI has, to extract from TMSI identities (always starting just after the TMSI's most significant octet).\n"
- "bit count (0 disables) pooling)\n",
- CMD_ATTR_IMMEDIATE)
-{
- g_cfg->pool.nri_bitlen = atoi(argv[0]);
-
- if (llist_count(&g_cfg->sgsns) > 1 && g_cfg->pool.nri_bitlen == 0)
- vty_out(vty, "%% Pooling disabled, but multiple SGSNs defined%s", VTY_NEWLINE);
-
- /* TODO: Verify all nri ranges and warn on mismatch */
-
- return CMD_SUCCESS;
-}
-
-DEFUN_ATTR(cfg_gbproxy_nri_null_add,
- cfg_gbproxy_nri_null_add_cmd,
- "nri null add <0-32767> [<0-32767>]",
- NRI_STR NULL_NRI_STR "Add NULL-NRI value (or range)\n"
- NRI_FIRST_LAST_STR,
- CMD_ATTR_IMMEDIATE)
-{
- int rc;
- const char *message;
-
- rc = osmo_nri_ranges_vty_add(&message, NULL, g_cfg->pool.null_nri_ranges, argc, argv,
- g_cfg->pool.nri_bitlen);
- if (message) {
- vty_out(vty, "%% nri null add: %s: " NRI_ARGS_TO_STR_FMT "%s", message, NRI_ARGS_TO_STR_ARGS(argc, argv),
- VTY_NEWLINE);
- vty_out(vty, "%s: \n" NRI_ARGS_TO_STR_FMT, message, NRI_ARGS_TO_STR_ARGS(argc, argv));
- }
- if (rc < 0)
- return CMD_WARNING;
- return CMD_SUCCESS;
-}
-
-DEFUN_ATTR(cfg_gbproxy_nri_null_del,
- cfg_gbproxy_nri_null_del_cmd,
- "nri null del <0-32767> [<0-32767>]",
- NRI_STR NULL_NRI_STR "Remove NRI value or range from the NRI mapping for this MSC\n"
- NRI_FIRST_LAST_STR,
- CMD_ATTR_IMMEDIATE)
-{
- int rc;
- const char *message;
- rc = osmo_nri_ranges_vty_del(&message, NULL, g_cfg->pool.null_nri_ranges, argc, argv);
- if (message) {
- vty_out(vty, "%% %s: " NRI_ARGS_TO_STR_FMT "%s", message, NRI_ARGS_TO_STR_ARGS(argc, argv),
- VTY_NEWLINE);
- }
- if (rc < 0)
- return CMD_WARNING;
- return CMD_SUCCESS;
-}
-
-static void log_set_bvc_filter(struct log_target *target,
- const uint16_t *bvci)
-{
- if (bvci) {
- uintptr_t bvci_filter = *bvci | BVC_LOG_CTX_FLAG;
- target->filter_map |= (1 << LOG_FLT_GB_BVC);
- target->filter_data[LOG_FLT_GB_BVC] = (void *)bvci_filter;
- } else if (target->filter_data[LOG_FLT_GB_BVC]) {
- target->filter_map = ~(1 << LOG_FLT_GB_BVC);
- target->filter_data[LOG_FLT_GB_BVC] = NULL;
- }
-}
-
-DEFUN(logging_fltr_bvc,
- logging_fltr_bvc_cmd,
- "logging filter bvc bvci <0-65535>",
- LOGGING_STR FILTER_STR
- "Filter based on BSSGP VC\n"
- "Identify BVC by BVCI\n"
- "Numeric identifier\n")
-{
- struct log_target *tgt;
- uint16_t id = atoi(argv[0]);
-
- log_tgt_mutex_lock();
- tgt = osmo_log_vty2tgt(vty);
- if (!tgt) {
- log_tgt_mutex_unlock();
- return CMD_WARNING;
- }
-
- log_set_bvc_filter(tgt, &id);
- log_tgt_mutex_unlock();
- return CMD_SUCCESS;
-}
-
-DEFUN(show_gbproxy_bvc, show_gbproxy_bvc_cmd, "show gbproxy bvc (bss|sgsn) [stats]",
- SHOW_STR GBPROXY_STR
- "Show BSSGP Virtual Connections\n"
- "Display BSS-side BVCs\n"
- "Display SGSN-side BVCs\n"
- "Show statistics\n")
-{
- struct gbproxy_nse *nse;
- bool show_stats = argc >= 2;
- int i;
-
- if (show_stats)
- vty_out_rate_ctr_group(vty, "", g_cfg->ctrg);
-
- if (!strcmp(argv[0], "bss")) {
- hash_for_each(g_cfg->bss_nses, i, nse, list)
- gbproxy_vty_print_nse(vty, nse, show_stats);
- } else {
- hash_for_each(g_cfg->sgsn_nses, i, nse, list)
- gbproxy_vty_print_nse(vty, nse, show_stats);
- }
- return CMD_SUCCESS;
-}
-
-DEFUN(show_gbproxy_cell, show_gbproxy_cell_cmd, "show gbproxy cell [stats]",
- SHOW_STR GBPROXY_STR
- "Show GPRS Cell Information\n"
- "Show statistics\n")
-{
- struct gbproxy_cell *cell;
- bool show_stats = argc >= 1;
- int i;
-
- hash_for_each(g_cfg->cells, i, cell, list)
- gbproxy_vty_print_cell(vty, cell, show_stats);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(show_gbproxy_links, show_gbproxy_links_cmd, "show gbproxy links",
- SHOW_STR GBPROXY_STR "Show logical links\n")
-{
- struct gbproxy_nse *nse;
- int i, j;
-
- hash_for_each(g_cfg->bss_nses, i, nse, list) {
- struct gbproxy_bvc *bvc;
- hash_for_each(nse->bvcs, j, bvc, list) {
- gbprox_vty_print_bvc(vty, bvc);
- }
- }
- return CMD_SUCCESS;
-}
-
-DEFUN(show_gbproxy_tlli_cache, show_gbproxy_tlli_cache_cmd,
- "show gbproxy tlli-cache",
- SHOW_STR GBPROXY_STR "Show TLLI cache entries\n")
-{
- struct gbproxy_tlli_cache_entry *entry;
- struct timespec now;
- time_t expiry;
- int i, count = 0;
-
- osmo_clock_gettime(CLOCK_MONOTONIC, &now);
- expiry = now.tv_sec - g_cfg->tlli_cache.timeout;
-
- vty_out(vty, "TLLI cache timeout %us%s", g_cfg->tlli_cache.timeout, VTY_NEWLINE);
- hash_for_each(g_cfg->tlli_cache.entries, i, entry, list) {
- time_t valid = entry->tstamp - expiry;
- struct gbproxy_nse *nse = entry->nse;
-
- vty_out(vty, " TLLI %08x -> NSE(%05u/%s) valid %lds%s", entry->tlli, nse->nsei,
- nse->sgsn_facing ? "SGSN" : "BSS", valid, VTY_NEWLINE);
- count++;
- }
- vty_out(vty, "TLLI cache contains %u entries%s", count, VTY_NEWLINE);
- return CMD_SUCCESS;
-}
-
-DEFUN(show_gbproxy_imsi_cache, show_gbproxy_imsi_cache_cmd,
- "show gbproxy imsi-cache",
- SHOW_STR GBPROXY_STR "Show IMSI cache entries\n")
-{
- struct gbproxy_imsi_cache_entry *entry;
- struct timespec now;
- time_t expiry;
- int i, count = 0;
-
- osmo_clock_gettime(CLOCK_MONOTONIC, &now);
- expiry = now.tv_sec - g_cfg->imsi_cache.timeout;
-
- vty_out(vty, "IMSI cache timeout %us%s", g_cfg->imsi_cache.timeout, VTY_NEWLINE);
- hash_for_each(g_cfg->imsi_cache.entries, i, entry, list) {
- time_t valid = entry->tstamp - expiry;
- struct gbproxy_nse *nse = entry->nse;
- vty_out(vty, " IMSI %s -> NSE(%05u/%s): valid %lds%s", entry->imsi, nse->nsei,
- nse->sgsn_facing ? "SGSN" : "BSS", valid, VTY_NEWLINE);
- count++;
- }
- vty_out(vty, "IMSI cache contains %u entries%s", count, VTY_NEWLINE);
- return CMD_SUCCESS;
-}
-
-DEFUN(delete_gb_bvci, delete_gb_bvci_cmd,
- "delete-gbproxy-peer <0-65534> bvci <2-65534>",
- "Delete a GBProxy bvc by NSEI and optionally BVCI\n"
- "NSEI number\n"
- "Only delete bvc with a matching BVCI\n"
- "BVCI number\n")
-{
- const uint16_t nsei = atoi(argv[0]);
- const uint16_t bvci = atoi(argv[1]);
- struct gbproxy_nse *nse = gbproxy_nse_by_nsei(g_cfg, nsei, NSE_F_BSS);
- int counter;
-
- if (!nse) {
- vty_out(vty, "NSE not found%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- counter = gbproxy_cleanup_bvcs(nse, bvci);
-
- if (counter == 0) {
- vty_out(vty, "BVC not found%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- return CMD_SUCCESS;
-}
-
-DEFUN(delete_gb_nsei, delete_gb_nsei_cmd,
- "delete-gbproxy-peer <0-65534> (only-bvc|only-nsvc|all) [dry-run]",
- "Delete a GBProxy bvc by NSEI and optionally BVCI\n"
- "NSEI number\n"
- "Only delete BSSGP connections (BVC)\n"
- "Only delete dynamic NS connections (NS-VC)\n"
- "Delete BVC and dynamic NS connections\n"
- "Show what would be deleted instead of actually deleting\n"
- )
-{
- const uint16_t nsei = atoi(argv[0]);
- const char *mode = argv[1];
- int dry_run = argc > 2;
- int delete_bvc = 0;
- int delete_nsvc = 0;
- int counter;
-
- if (strcmp(mode, "only-bvc") == 0)
- delete_bvc = 1;
- else if (strcmp(mode, "only-nsvc") == 0)
- delete_nsvc = 1;
- else
- delete_bvc = delete_nsvc = 1;
-
- if (delete_bvc) {
- if (!dry_run) {
- struct gbproxy_nse *nse = gbproxy_nse_by_nsei(g_cfg, nsei, NSE_F_BSS);
- counter = gbproxy_cleanup_bvcs(nse, 0);
- gbproxy_nse_free(nse);
- } else {
- struct gbproxy_nse *nse;
- struct gbproxy_bvc *bvc;
- int i, j;
- counter = 0;
- hash_for_each(g_cfg->bss_nses, i, nse, list) {
- if (nse->nsei != nsei)
- continue;
- hash_for_each(nse->bvcs, j, bvc, list) {
- vty_out(vty, "BVC: ");
- gbprox_vty_print_bvc(vty, bvc);
- counter += 1;
- }
- }
- }
- vty_out(vty, "%sDeleted %d BVC%s",
- dry_run ? "Not " : "", counter, VTY_NEWLINE);
- }
-
- if (delete_nsvc) {
- struct gprs_ns2_inst *nsi = g_cfg->nsi;
- struct gprs_ns2_nse *nse;
-
- nse = gprs_ns2_nse_by_nsei(nsi, nsei);
- if (!nse) {
- vty_out(vty, "NSEI not found%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- /* TODO: We should NOT delete a persistent NSEI/NSVC as soon as we can check for these */
- if (!dry_run)
- gprs_ns2_free_nse(nse);
-
- vty_out(vty, "%sDeleted NS-VCs for NSEI %d%s",
- dry_run ? "Not " : "", nsei, VTY_NEWLINE);
- }
-
- return CMD_SUCCESS;
-}
-
-/* Only for ttcn3 testing */
-DEFUN_HIDDEN(sgsn_pool_nsf_fixed, sgsn_pool_nsf_fixed_cmd,
- "sgsn-pool nsf fixed NAME",
- "SGSN pooling: load balancing across multiple SGSNs.\n"
- "Customize the Network Selection Function.\n"
- "Set a fixed SGSN to use (for testing).\n"
- "The name of the SGSN to use.\n")
-{
- const char *name = argv[0];
- struct gbproxy_sgsn *sgsn = gbproxy_sgsn_by_name(g_cfg, name);
-
- if (!sgsn) {
- vty_out(vty, "%% Could not find SGSN with name %s%s", name, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- g_cfg->pool.nsf_override = sgsn;
- return CMD_SUCCESS;
-}
-
-DEFUN_HIDDEN(sgsn_pool_nsf_normal, sgsn_pool_nsf_normal_cmd,
- "sgsn-pool nsf normal",
- "SGSN pooling: load balancing across multiple SGSNs.\n"
- "Customize the Network Selection Function.\n"
- "Reset the NSF back to regular operation (for testing).\n")
-{
- g_cfg->pool.nsf_override = NULL;
- return CMD_SUCCESS;
-}
-
-int gbproxy_vty_init(void)
-{
- install_element_ve(&show_gbproxy_bvc_cmd);
- install_element_ve(&show_gbproxy_cell_cmd);
- install_element_ve(&show_gbproxy_links_cmd);
- install_element_ve(&show_gbproxy_tlli_cache_cmd);
- install_element_ve(&show_gbproxy_imsi_cache_cmd);
- install_element_ve(&show_nri_all_cmd);
- install_element_ve(&show_nri_nsei_cmd);
- install_element_ve(&logging_fltr_bvc_cmd);
-
- install_element(ENABLE_NODE, &delete_gb_bvci_cmd);
- install_element(ENABLE_NODE, &delete_gb_nsei_cmd);
- install_element(ENABLE_NODE, &sgsn_pool_nsf_fixed_cmd);
- install_element(ENABLE_NODE, &sgsn_pool_nsf_normal_cmd);
-
- install_element(CONFIG_NODE, &cfg_gbproxy_cmd);
- install_node(&gbproxy_node, config_write_gbproxy);
- install_element(GBPROXY_NODE, &cfg_pool_bvc_fc_ratio_cmd);
- install_element(GBPROXY_NODE, &cfg_gbproxy_nri_bitlen_cmd);
- install_element(GBPROXY_NODE, &cfg_gbproxy_nri_null_add_cmd);
- install_element(GBPROXY_NODE, &cfg_gbproxy_nri_null_del_cmd);
-
- install_element(CONFIG_NODE, &cfg_sgsn_nsei_cmd);
- install_node(&sgsn_node, config_write_sgsn);
- install_element(SGSN_NODE, &cfg_sgsn_name_cmd);
- install_element(SGSN_NODE, &cfg_sgsn_allow_attach_cmd);
- install_element(SGSN_NODE, &cfg_sgsn_no_allow_attach_cmd);
- install_element(SGSN_NODE, &cfg_sgsn_nri_add_cmd);
- install_element(SGSN_NODE, &cfg_sgsn_nri_del_cmd);
-
-
- return 0;
-}
-
-int gbproxy_parse_config(const char *config_file, struct gbproxy_config *cfg)
-{
- int rc;
-
- g_cfg = cfg;
- rc = vty_read_config_file(config_file, NULL);
- if (rc < 0) {
- fprintf(stderr, "Failed to parse the config file: '%s'\n", config_file);
- return rc;
- }
-
- return 0;
-}
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 32ed47258..cb6d343b5 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -33,8 +33,6 @@ EXTRA_DIST = \
vty_test_runner.py \
ctrl_test_runner.py \
osmo-sgsn_test-nodes.vty \
- osmo-gbproxy_test-nodes.vty \
- osmo-gbproxy-pool_test-nodes.vty \
$(NULL)
TESTSUITE = $(srcdir)/testsuite
@@ -63,14 +61,6 @@ vty-python-test: $(BUILT_SOURCES)
# make vty-transcript-test U=-u
vty-transcript-test:
osmo_verify_transcript_vty.py -v \
- -n OsmoGbProxy -p 4246 \
- -r "$(top_builddir)/src/gbproxy/osmo-gbproxy -c $(top_srcdir)/doc/examples/osmo-gbproxy/osmo-gbproxy.cfg" \
- $(U) $${T:-$(srcdir)/osmo-gbproxy_test-nodes.vty}
- osmo_verify_transcript_vty.py -v \
- -n OsmoGbProxy -p 4246 \
- -r "$(top_builddir)/src/gbproxy/osmo-gbproxy -c $(top_srcdir)/doc/examples/osmo-gbproxy/osmo-gbproxy-pool.cfg" \
- $(U) $${T:-$(srcdir)/osmo-gbproxy-pool_test-nodes.vty}
- 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" \
$(U) $${T:-$(srcdir)/osmo-sgsn*.vty}
diff --git a/tests/osmo-gbproxy-pool_test-nodes.vty b/tests/osmo-gbproxy-pool_test-nodes.vty
deleted file mode 100644
index a741e483e..000000000
--- a/tests/osmo-gbproxy-pool_test-nodes.vty
+++ /dev/null
@@ -1,35 +0,0 @@
-OsmoGbProxy> enable
-OsmoGbProxy# show nri all
-sgsn nsei 101
- nri add 1
- nri add 11
-sgsn nsei 102
- nri add 2
- nri add 12
-OsmoGbProxy# configure terminal
-OsmoGbProxy(config)# list
-...
- gbproxy
- sgsn nsei <0-65534>
- ns
-...
-
-OsmoGbProxy(config)# sgsn nsei 101
-OsmoGbProxy(config-sgsn)# list
-...
- allow-attach
- no allow-attach
- nri add <0-32767> [<0-32767>]
- nri del <0-32767> [<0-32767>]
-...
-
-OsmoGbProxy(config-sgsn)# exit
-OsmoGbProxy(config)# gbproxy
-
-OsmoGbProxy(config-gbproxy)# list
-...
- pool bvc-flow-control-ratio <1-100>
- nri bitlen <0-15>
- nri null add <0-32767> [<0-32767>]
- nri null del <0-32767> [<0-32767>]
-...
diff --git a/tests/osmo-gbproxy_test-nodes.vty b/tests/osmo-gbproxy_test-nodes.vty
deleted file mode 100644
index 8a47aa075..000000000
--- a/tests/osmo-gbproxy_test-nodes.vty
+++ /dev/null
@@ -1,32 +0,0 @@
-OsmoGbProxy> enable
-OsmoGbProxy# show nri all
-sgsn nsei 101
- % no NRI mappings
-...
-OsmoGbProxy# configure terminal
-OsmoGbProxy(config)# list
-...
- gbproxy
- sgsn nsei <0-65534>
- ns
-...
-
-OsmoGbProxy(config)# sgsn nsei 101
-OsmoGbProxy(config-sgsn)# list
-...
- allow-attach
- no allow-attach
- nri add <0-32767> [<0-32767>]
- nri del <0-32767> [<0-32767>]
-...
-
-OsmoGbProxy(config-sgsn)# exit
-OsmoGbProxy(config)# gbproxy
-
-OsmoGbProxy(config-gbproxy)# list
-...
- pool bvc-flow-control-ratio <1-100>
- nri bitlen <0-15>
- nri null add <0-32767> [<0-32767>]
- nri null del <0-32767> [<0-32767>]
-...
diff --git a/tests/vty_test_runner.py b/tests/vty_test_runner.py
index 92466bb04..0b7df8c89 100755
--- a/tests/vty_test_runner.py
+++ b/tests/vty_test_runner.py
@@ -67,53 +67,6 @@ class TestVTYBase(unittest.TestCase):
self.vty = None
osmoutil.end_proc(self.proc)
-
-class TestVTYGbproxy(TestVTYBase):
-
- def vty_command(self):
- return ["./src/gbproxy/osmo-gbproxy", "-c",
- "doc/examples/osmo-gbproxy/osmo-gbproxy.cfg"]
-
- def vty_app(self):
- return (4246, "./src/gbproxy/osmo-gbproxy", "OsmoGbProxy", "gbproxy")
-
- def testVtyTree(self):
- self.vty.enable()
- self.assertTrue(self.vty.verify('configure terminal', ['']))
- self.assertEqual(self.vty.node(), 'config')
- self.checkForEndAndExit()
- self.assertTrue(self.vty.verify('ns', ['']))
- self.assertEqual(self.vty.node(), 'config-ns')
- self.checkForEndAndExit()
- self.assertTrue(self.vty.verify('exit', ['']))
- self.assertEqual(self.vty.node(), 'config')
- self.assertTrue(self.vty.verify('gbproxy', ['']))
- self.assertEqual(self.vty.node(), 'config-gbproxy')
- self.checkForEndAndExit()
- self.assertTrue(self.vty.verify('exit', ['']))
- self.assertEqual(self.vty.node(), 'config')
-
- def testVtyShow(self):
- res = self.vty.command("show ns")
- self.assertTrue(res.find('UDP bind') >= 0)
-
- res = self.vty.command("show gbproxy bvc bss stats")
- self.assertTrue(res.find('GBProxy Global Statistics') >= 0)
-
- def testVtyDeletePeer(self):
- self.vty.enable()
- self.assertTrue(self.vty.verify('delete-gbproxy-peer 9999 bvci 7777', ['NSE not found']))
- res = self.vty.command("delete-gbproxy-peer 9999 all dry-run")
- self.assertTrue(res.find('Not Deleted 0 BVC') >= 0)
- self.assertTrue(res.find('NSEI not found') >= 0)
- res = self.vty.command("delete-gbproxy-peer 9999 only-bvc dry-run")
- self.assertTrue(res.find('Not Deleted 0 BVC') >= 0)
- res = self.vty.command("delete-gbproxy-peer 9999 only-nsvc dry-run")
- self.assertTrue(res.find('NSEI not found') >= 0)
- res = self.vty.command("delete-gbproxy-peer 9999 all")
- self.assertTrue(res.find('Deleted 0 BVC') >= 0)
- self.assertTrue(res.find('NSEI not found') >= 0)
-
class TestVTYSGSN(TestVTYBase):
def vty_command(self):
@@ -274,13 +227,6 @@ class TestVTYSGSN(TestVTYBase):
for t in [3312, 3322, 3350, 3360, 3370, 3313, 3314, 3316, 3385, 3395, 3397]:
self.assertTrue(self.vty.verify('timer t%d 10' % t, ['']))
-def add_gbproxy_test(suite, workdir):
- if not os.path.isfile(os.path.join(workdir, "src/gbproxy/osmo-gbproxy")):
- print("Skipping the Gb-Proxy test")
- return
- test = unittest.TestLoader().loadTestsFromTestCase(TestVTYGbproxy)
- suite.addTest(test)
-
def add_sgsn_test(suite, workdir):
if not os.path.isfile(os.path.join(workdir, "src/sgsn/osmo-sgsn")):
print("Skipping the SGSN test")
@@ -318,7 +264,6 @@ if __name__ == '__main__':
os.chdir(workdir)
print("Running tests for specific VTY commands")
suite = unittest.TestSuite()
- add_gbproxy_test(suite, workdir)
add_sgsn_test(suite, workdir)
if args.test_name: