Compare commits

...

58 Commits

Author SHA1 Message Date
Oliver Smith 57585767dc {contrib,debian}/osmo-ggsn.init: remove
Remove SysV init scripts. These are not really maintained anymore and
this makes it consistent with other Osmocom projects.

Avoids synchronizing with SysV scripts on debian:
  # systemctl enable osmo-ggsn
  Synchronizing state of osmo-ggsn.service with SysV service script with /lib/systemd/systemd-sysv-install.
  Executing: /lib/systemd/systemd-sysv-install enable osmo-ggsn

Change-Id: I11bfb5122344b54970b7f742470cb74b95fa37e0
2024-05-16 09:00:21 +00:00
Oliver Smith 488972b442 Use uniform log format for default config files
Related: OS#6272
Change-Id: I272767e029e95b64f2525d4f19efdfa1f0e29ca2
2024-05-16 09:00:21 +00:00
Oliver Smith 08239ccac3 contrib/systemd: run as osmocom user
Related: OS#4107
Change-Id: I915f2fc12d0bd905d24636aacb2760a6b72a55e3
2024-05-16 09:00:21 +00:00
Oliver Smith fbc56063c5 doc: set state-dir to /var/lib/osmocom/osmo-ggsn
Prepare to run osmo-ggsn as user with the systemd service. As with other
Osmocom service files, we will set StateDirectory= and WorkingDirectory=
options. This results in osmo-ggsn only being able to write to
/var/lib/osmocom, therefore let's change the state-dir from /tmp to
/var/lib/osmocom/osmo-ggsn to avoid:

  gsn.c:411 fopen(path=/tmp/gsn_restart, mode=w) failed: Error = Permission denied

Having the state in /var/lib/osmocom also makes more sense, because then
it doesn't get deleted on reboot.

Change-Id: I5b51529b4f8bd2462e54f58a1ce2e2d7c76ff46a
2024-05-16 09:00:21 +00:00
Oliver Smith c1598e0eb4 ggsn/ggsn_vty: create state-dir
Prepare to change the state-dir in the default config in a follow-up
commit. Create the directory if it does not exist.

Change-Id: I91349fb284336a9de6af41475f1b824eb0e021b0
2024-05-16 09:00:21 +00:00
Oliver Smith 519a2e401d gtp/gtp_internal.h: new file
While at it, move internal functions of gtp.h to a separate file too.
Make all functions that are only used inside gtp.c static.

The following APIs are unexpectedly public:
* imsi_gtp2str gets used by pdp.h
* gsna2in_addr, gtp_echo_req gets used by osmo-sgsn

Change-Id: I72c40cbdec33449ca8104fb3cad8df1a9e07dfd7
2024-05-14 11:13:45 +02:00
Oliver Smith fbef527222 gtp: move conversion functions up
Move the conversion functions above the first user, so we can make
in_addr2gsna static in a follow-up commit and remove the extra
declaration.

Change-Id: I51e6a7c1161320fc54b0e8197ae57e4327976eb1
2024-05-14 11:13:45 +02:00
Oliver Smith 68f5b086ad gtp: remove unused conversion functions
Remove ipv42eua and eua2ipv4, which are in the "internal functions"
section of gtp.h, but are not used anywhere in the code anymore. This is
in preparation of moving the internal functions that are used in
multiple .c files into a separate header file, and to make the other
internal functions static. (Compiler complains about unused static
functions.)

Change-Id: I90e2750f6a6e3e6122e9c562103fda77d7326932
2024-05-14 11:13:41 +02:00
Oliver Smith 3cb3423a59 gtp/gtp.c: move gtp_create_context_resp down
Move gtp_create_context_resp below gtp_create_pdp_resp, which it calls.
In a follow-up commit, we can make gtp_create_pdp_resp static and
remove the additional declaration.

Change-Id: I34efe7592013a8423f4f280758272d81f24b65fa
2024-05-13 15:16:58 +02:00
Oliver Smith bad5eeba0f gtp/gsn_internal.h: new file
Change-Id: I999462e39411fc4ec7e50bd0212e870006fbc4f1
2024-05-13 15:16:58 +02:00
Oliver Smith 1dd16fa12f libgtp: move includes to osmocom/include/gtp
Move all includes from /usr/include/….h to
/usr/include/osmocom/gtp/….h to be more consistent with other Osmocom
projects, and to not "pollute" the top include directory if we add more
header files.

Also the new directory structure makes more obvious, which headers are
public and which ones aren't.

Adjust libgtp.pc.in so both #include <gtp.h> (legacy)
and #include <osmocom/gtp/gtp.h> can be used.

Related: OS#6373
Change-Id: If7e01c61168819bf7120667344e40c857da5490b
2024-05-13 15:16:58 +02:00
Oliver Smith 3372625ad9 contrib: remove rpm spec file
Related: https://osmocom.org/news/255
Related: OS#6446
Change-Id: I7cfe55fa2fda43da4eaa1e1b8d40b31d1c8aaf30
2024-05-08 14:40:58 +02:00
Harald Welte 1f9cc2674f README.md: Major overhaul
A lot of the existing contents was still from the old openggsn days, and
predated osmo-ggsn.

Change-Id: I6ec92260da0f55e9493a15db2e8178e5436143a0
2024-03-23 16:32:45 +01:00
Harald Welte 4abe361f33 README.md: Add Forum + Issue Tracker sections
Change-Id: I7b03a78178de77ebf733587ed178fd48c019663c
2024-03-23 16:15:42 +01:00
Harald Welte bb0655d5aa README.md: Improve markdown formatting
Change-Id: I4e5d99384978d22e6ba0310e97e93d87b610a174
2024-03-23 16:11:50 +01:00
Harald Welte 4e6fe42731 Add funding link to github mirror
see https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/displaying-a-sponsor-button-in-your-repository

Change-Id: I75ba8c4f8635d5a2d36d5bb97566d737e27bcec9
2024-03-23 16:06:28 +01:00
Oliver Smith 19a506b705 Add clear error for kernel not supporting IPv6
Make it clear to the user, that if adding a tunnel fails with kernel GTP
and IPv6: the reason is that the kernel doesn't support IPv6 yet.

Related: OS#6096
Change-Id: I1d3c8cbb51212c91136292347dad9529a5c58a31
2024-03-04 11:15:07 +01:00
Oliver Smith ea6c02ac1f doc: fix typo ndoe -> node
Change-Id: Ib78b5de45b93a7534163de2cd91211e9be75445d
2024-03-01 08:08:43 +00:00
Oliver Smith ec357c5377 lib/gtp-kernel.c: check rc of in46a_from_eua
Fixes: b17fe7bf ("kernel-gtp: support IPv6 on inner layer")
Change-Id: I40e4de1517de8871224a45c173208810b42312ff
2024-02-27 16:04:42 +01:00
Oliver Smith 768d6d5be9 lib/gtp-kernel.c: initialize ret with 0
Fix -Werror=maybe-uninitialize found in Pau's build env:

/home/pespin/dev/sysmocom/git/osmo-ggsn/lib/gtp-kernel.c: In function ‘gtp_kernel_tunnel_add’:
/home/pespin/dev/sysmocom/git/osmo-ggsn/lib/gtp-kernel.c:111:13: error: ‘ret’ may be used uninitialized [-Werror=maybe-uninitialize]
  111 |         int ret;
      |             ^~~
/home/pespin/dev/sysmocom/git/osmo-ggsn/lib/gtp-kernel.c: In function ‘gtp_kernel_tunnel_del’:
/home/pespin/dev/sysmocom/git/osmo-ggsn/lib/gtp-kernel.c:167:13: error: ‘ret’ may be used uninitialized [-Werror=maybe-uninitialize]
  167 |         int ret;
      |             ^~~

Fixes: b17fe7bf ("kernel-gtp: support IPv6 on inner layer")
Change-Id: I19067ebe561d4c067b9ace7f5b201e15af6b342e
2024-02-27 15:00:59 +01:00
Oliver Smith fa91a10498 Cosmetic: {lib,gtp}/Makefile.am: diff friendly
Change-Id: Ib1956794edc6e82cfa6c5419b2609565674d98a4
2024-02-23 13:25:32 +01:00
Oliver Smith 6929391ecf Cosmetic: AM_CFLAGS: make diff friendly
Change-Id: I3303cd8ba8c8b21ff267608833d9fb4833ffc471
2024-02-23 12:08:48 +01:00
Oliver Smith 9baac03927 Cosmetic: Makefile.am: make SUBDIRS diff friendly
Change-Id: I49e1b08e48dc324f313228e8c69679c37aa774f4
2024-02-23 12:08:48 +01:00
Oliver Smith 9bd2711f39 Revert "kernel-gtp: support IPv6 on outer layer"
This reverts commit 0917ce4e22,
as it breaks building osmo-sgsn. This needs to be reworked to be
backwards compatible.

Related: OS#6373
Change-Id: I2c2b2ff0875217e041d94c8e2cef030d2a86c2d8
2024-02-22 16:06:33 +01:00
Oliver Smith b17fe7bfe9 kernel-gtp: support IPv6 on inner layer
Related: OS#6096
Change-Id: I3df47b6c209f1e2f8254ba139581d6e622c6b35f
2024-02-21 16:22:24 +01:00
Oliver Smith 0917ce4e22 kernel-gtp: support IPv6 on outer layer
Related: OS#1953, OS#6096
Change-Id: I257fff1dcd9d030a7f9ea936b2693a3f13208230
2024-02-21 16:22:21 +01:00
Oliver Smith 2a0d37cb1d gtp_new: deduplicate create_and_bind_socket code
Change-Id: Iff3cfdfb0c08033d869c51499754b3416c71732b
2024-02-21 13:06:04 +01:00
Oliver Smith f3d541e353 Fix a typo
Change-Id: I508274a1a466651025c488ad897aeed739e4b799
2024-02-21 13:05:56 +01:00
Pau Espin 8d976444b8 pco: Improve IPCP spec reference documentation
Change-Id: I1dd4a41bae491c61197e8e307efcfc8c63945a71
2024-01-26 16:12:08 +01:00
Daniel Willmann 77734ac81b libgtp: Remove defines for reserved causes in gtp.h
As discussed in Gerrit change I9c3bf64537ef2223e29f8082861fa32fde26bf68
remove defines that don't serve any purpose. These are defines for
reserved values and changing them later if a newer spec defined them
would break API.

Keep the comments to explain the missing values.

Change-Id: I8db0aa0ade59785443a407b51dea326144406dcf
2023-11-29 16:40:49 +01:00
Oliver Smith 848ec697e2 Bump version: 1.10.2.1-a625 → 1.11.0
Change-Id: I1f116e1cded135f231f22ebc9b817aebf3736fc2
2023-11-28 13:07:17 +00:00
Daniel Willmann 6a2e82542d libgtp: Use gtp_cause_successful() instead of GTPCAUSE_ACC_REQ
In some cases the phone requests a PDP context type that isn't available
no the PGW/GGSN, e.g. phone requests a combined IPv4/v6 context, but
only IPv4 is supported.

In that case the GGSN can send a Create PDP Context Response with cause
"New PDP type due to network preference" or "New PDP type due to single
address bearer only". libgtp should continue handling these cause values
like the "Request Accepted" cause. Use the new gtp_cause_successful()
function for that.

Related: OS#6268
Change-Id: I7dd1e0aa185530e1e2d0402742df833c61a787a7
2023-11-24 09:48:22 +01:00
Daniel Willmann a625bdd136 gtp: Add net GTP cause values and a function to check for success
According to the spec the upf/pgw can accept a modified pdp context from
the request e.g. if an ipv4/6 context was requested, but only ipv4 is
availiable. Introduce a function that checks all cause values that are
considered successful.

See also: 3GPP TS 29.060 Ch 7.3.2

Related: OS#6268
Change-Id: I9c3bf64537ef2223e29f8082861fa32fde26bf68
2023-11-22 12:36:49 +01:00
Pau Espin 08bb5182a4 Bump version: 1.10.1.8-4963-dirty → 1.10.2
Change-Id: I148375902975aba0a374e4507c97f1ff67d687bc
2023-09-12 14:36:11 +02:00
Oliver Smith 4963d1c2ea lib/in46_addr: add in46a_from_gsna
Prepare to use it in gtp-kernel.c in a future patch.

Related: OS#6096
Change-Id: I3e76eb7ee89ba338f085c617662d15cffa2a62d5
2023-07-24 15:06:03 +02:00
Oliver Smith 37daa5d003 doc: running: update kernel-gtp limitations
Related: OS#6096
Change-Id: Ie4f1452ecefbe0db0e4093caa8177f1c87bd3950
2023-07-21 12:59:41 +02:00
Oliver Smith c4c4d90b85 README: update documentation section
Change-Id: I3320dc5eb3d183a18c2bd2fe3139f729978ea2a1
2023-07-21 11:19:14 +02:00
Oliver Smith 59f1539ece systemd: depend on networking-online.target
Related: SYS#6400
Change-Id: I29e547242b2ed1cfc4750c7d7e5f8636c2e8f3dc
2023-05-26 14:10:45 +02:00
Oliver Smith eff88c08e7 debian: set compat level to 10
Related: OS#5958
Change-Id: I4b2988fffba12cc84ff0834bb9ef0f3d9de2bcda
2023-04-25 16:48:22 +02:00
Oliver Smith 92ac7249f9 doc/manuals/chapters/configuration: fix typo
Change-Id: I0e9d2c77200c7c8b49aec669bc39ca91d5d4cf1f
2023-04-11 17:18:34 +02:00
Vadim Yanitskiy 5cf6b75dc9 tests: use -no-install libtool flag to avoid ./lt-* scripts
This option should be used for any executables which are used only
for testing, or for generating other files and are consequently never
installed.  By specifying this option, we are telling Libtool that
the executable it links will only ever be executed from where it is
built in the build tree.  Libtool is usually able to considerably
speed up the link process for such executables.

Change-Id: I2ca675e93dc5b34bb08d3b841adc115e93558137
2023-03-11 04:36:59 +07:00
Vadim Yanitskiy 4aa2e417c9 Do not hard-code -g and -O2 in CFLAGS
Let the user decide on the optimization level and debugging info.

Change-Id: I4b0b523b7dac4d67413bda37b546964262e5ea0d
2023-03-09 17:17:03 +07:00
Vadim Yanitskiy f14c056310 Bump version: 1.10.0.4-bf69 → 1.10.1
Change-Id: Ibde9f259bccce29638d35efbd597669f5584e295
2023-02-27 22:35:47 +07:00
Vadim Yanitskiy bf69ddbfef gtp: use OSMO_ASSERT() in gtp_new()
When using built-in static_assert() [1], gcc v12.2.1 fails:

In file included from gsn.c:27:
gsn.c: In function 'gtp_new':
gsn.c:444:54: error: expression in static assertion is not constant
  444 |         osmo_static_assert(gtp_T_defs[0].default_val != 0, first_default_val_not_zero);
      |                                                      ^

The reason is likely that gtp_T_defs[] is not const, so it cannot
be assert()ed statically.  With the current osmo_static_assert()
implementation, this assert does nothing.  One can change the
gtp_T_defs[0].default_val to 0 and the code will still compile.

Change-Id: Ia8af1736b63d501661046fe70befe5bbabc1045a
Related: [1] libosmocore.git I5ca34bc14c05e8c38c721d7df33feb1c6c41c76e
2023-02-27 17:07:26 +07:00
Vadim Yanitskiy 70a4e2e6f8 gtp/gsn.c: fix 'No newline at end of file'
git complains if it's missing, vim adds it automatically.

Change-Id: I3b4808a76da89e65b934d818e7ca280bc0651483
2023-02-27 17:07:26 +07:00
Vadim Yanitskiy 99afe979ef lib/icmpv6.h: fix struct icmpv6_{radv_hdr,opt_prefix}
Fix wrong field order in the big-endian variants.

Change-Id: Ifaa63bb5496e056805bd13b964c8b430fb11c24c
2023-02-27 17:07:05 +07:00
Oliver Smith 35066fb0b0 debian/libgtp6.shlibs: new file
List the most recent library version where new symbols where added, so
debian properly upgrades libgtp6 when upgrading osmo-sgsn from the
version that is currently in Debian to a version from the Osmocom
repositories.

Closes: OS#5318
Change-Id: Ida5dae4655c0acaeb377bc9d556a2ac333bca10a
2023-02-08 18:11:54 +01:00
Pau Espin 55fe62f634 Bump version: 1.9.0.10-4fac-dirty → 1.10.0
Change-Id: I553fb72c577181c32005093eaf4fa986ae0e6ca8
2023-02-07 14:29:49 +01:00
Pau Espin 4fac842826 Fix typos in comments and VTY descriptions
Change-Id: I359425152dc18d29c57047f1b10942480b7a61e5
2023-01-17 14:17:18 +01:00
arehbein 97f60e3dca osmo-ggsn: Transition to use of 'telnet_init_default'
Related: OS#5809
Change-Id: I51b7c175192759e26d1791723540841e72879b02
2022-12-23 11:13:31 +00:00
Max a727e6ed38 ctrl: take both address and port from vty config
Change-Id: Ib31d67591657e308eebd1e6b7e23f79e6a3656e9
2022-12-17 21:14:57 +03:00
Pau Espin 3a55b89777 gtp: Introduce VTY configurable GTP timer X3
This timer controls the amount of time a resp message transmitted by the
local gsn is to be stored in the resp queue. This is used in order to
detect duplicate requests received, since GTP states the exact same
response should be answered if a duplicate request is received.

Prior to this patch, this timer was hardcoded to 60 seconds.
This patch actually should be set, in general, to a value
equal than (T3-RESPONSE * N3-REQUESTS) values configured at
the peer, since that is the maximum period during which the local gsn
expects to receive req retransmissions from the peer.
Hence, this value must be user configurable to adapt it to the peers
connected to the GSN.

The 60 seconds hardcoded value is therefore changed to default to our
local (T3-RESPONSE * N3-REQUESTS), since the most common scenario for
osmo-ggsn/osmo-sgsn is to run it against a peer osmo-sgsn/osmo-ggsn,
which will have the same values by default.
This way we avoid by default caching response messages for way too long,
potentially filling the queue.

Related: OS#5485
Change-Id: Ia15c1cfd201d7c43e9a1d6ceb6725ddf392d2c65
2022-11-04 11:21:25 +01:00
Pau Espin 9f1f747d8e ggsn: Introduce tdef and make it configurable over VTY
Related: OS#5485
Change-Id: I10bc8e2e197c0e8753b23b684b5ae41025672bf7
2022-11-02 20:33:39 +01:00
Pau Espin b9036af7ca Use rate_ctr for gsn_t available_counters
This way they can be inspected with regular osmocom means.

Change-Id: I529305b4f824600c6e733a3c0d2c2c6673f99faf
2022-11-02 18:41:38 +01:00
Pau Espin 724ecc6680 Split gsn_t related APIs out of gtp.{c,h}
This way we split the gsn_t object API/logic from the protocol (message
handling) code.

Change-Id: I47cebb51bf08b9fcf7f115fc8dbea5f3493d4388
2022-11-02 18:41:34 +01:00
Pau Espin 0d3bd3435f cosmetic: gtp: Fix typo in comment
Change-Id: I54b80bba3126cb3ae534938e253721961d4e08c4
2022-11-02 13:22:17 +01:00
Max 3ed252b58e Ignore .deb build byproducts
Change-Id: Iec63ef5ea0acfc5e6621054926be15ae4754d65d
2022-08-30 19:24:48 +07:00
Max ac802e63d7 Set working directory in systemd service file
By default systemd will execute service with root directory (or home directory for user instance) which might result in
attempts to create files in unexpected place. Let's set it to 'osmocom' subdir of state directory (/var/lib for system
instance) instead.

Related: OS#4821
Change-Id: Idffc115c21cac77f6f43356333de538ba549fc6a
2022-08-30 19:24:48 +07:00
58 changed files with 1484 additions and 1506 deletions

1
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1 @@
open_collective: osmocom

4
.gitignore vendored
View File

@ -82,3 +82,7 @@ doc/manuals/build
doc/manuals/vty/ggsn_vty_reference.xml
contrib/osmo-ggsn.spec
/debian/gtp-echo-responder-dbg/
/debian/gtp-echo-responder/
/debian/osmo-ggsn-doc/
/utils/gtp-echo-responder

View File

@ -1,5 +1,15 @@
## Process this file with automake to produce Makefile.in
SUBDIRS = lib gtp ggsn sgsnemu doc contrib utils tests
SUBDIRS = \
include \
lib \
gtp \
ggsn \
sgsnemu \
doc \
contrib \
utils \
tests \
$(NULL)
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libgtp.pc
@ -15,7 +25,6 @@ EXTRA_DIST = \
README.FreeBSD \
README.MacOSX \
README.md \
contrib/osmo-ggsn.spec.in \
debian \
git-version-gen \
$(NULL)

163
README.md
View File

@ -5,15 +5,14 @@ This repository contains a C-language implementation of a GGSN (Gateway
GPRS Support Node), a core network element of ETSI/3GPP cellular
networks such as GPRS, EDGE, UMTS or HSPA.
OsmoGGSN is part of the [Osmocom](https://osmocom.org/) Open Source
Mobile Communications projects and the successor to OpenGGSN.
OpenGGSN was developed until 2004 by Mondru AB.
**OsmoGGSN** is part of the [Osmocom](https://osmocom.org/) Open Source
Mobile Communications projects and the successor to OpenGGSN (which was
developed until 2004 by Mondru AB).
Homepage
--------
The official homepage of the project is
https://osmocom.org/projects/openggsn/wiki
The official homepage of the project is <https://osmocom.org/projects/openggsn/wiki>.
GIT Repository
--------------
@ -27,35 +26,50 @@ There is a web interface at <https://gitea.osmocom.org/cellular-infrastructure/o
Documentation
-------------
There currently is no other documentation other than the wiki on the
homepage. It would be great if somebody would work towards a user
manual that can become part of the osmo-gsm-manuals project.
The user manual and VTY reference are optionally built in PDF form
as part of the build process. Pre-rendered versions are available here:
* [osmo-ggsn user manual](https://ftp.osmocom.org/docs/osmo-ggsn/master/osmoggsn-usermanual.pdf)
* [osmo-ggsn VTY reference](https://ftp.osmocom.org/docs/osmo-ggsn/master/osmoggsn-vty-reference.pdf)
Forum
-----
We welcome any pySim related discussions in the
[Cellular Network Infrastructure -> 2G/3G Core Network](https://discourse.osmocom.org/c/cni/2g-3g-cn/)
section of the osmocom discourse (web based Forum).
Mailing List
------------
Discussions related to OsmoGGSN are happening on the
osmocom-net-gprs@lists.osmocom.org mailing list, please see
https://lists.osmocom.org/mailman/listinfo/osmocom-net-gprs for
<https://lists.osmocom.org/mailman/listinfo/osmocom-net-gprs> for
subscription options and the list archive.
Please observe the [Osmocom Mailing List
Rules](https://osmocom.org/projects/cellular-infrastructure/wiki/Mailing_List_Rules)
Please observe the [Osmocom Mailing List Rules](https://osmocom.org/projects/cellular-infrastructure/wiki/Mailing_List_Rules)
when posting.
Issue Tracker
-------------
We use the [issue tracker of the osmo-ggsn project on osmocom.org](https://osmocom.org/projects/openggsn/issues) for
tracking the state of bug reports and feature requests. Feel free to submit any issues you may find, or help
us out by resolving existing issues.
Contributing
------------
Our coding standards are described at
https://osmocom.org/projects/cellular-infrastructure/wiki/Coding_standards
<https://osmocom.org/projects/cellular-infrastructure/wiki/Coding_standards>
We us a gerrit based patch submission/review process for managing
contributions. Please see
https://osmocom.org/projects/cellular-infrastructure/wiki/Gerrit for
<https://osmocom.org/projects/cellular-infrastructure/wiki/Gerrit> for
more details
The current patch queue for OsmoGGSN can be seen at
https://gerrit.osmocom.org/#/q/project:osmo-ggsn+status:open
<https://gerrit.osmocom.org/#/q/project:osmo-ggsn+status:open>
QuickStart
@ -75,61 +89,33 @@ The tun driver is required for proper operation of openggsn. For Linux
kernels later than 2.4.7 the driver is typically included, but might
need to be configured for automatic loading:
1. Add the following line to /etc/modules.conf: alias char-major-10-200 tun
2. depmod -a
1. Add the following line to `/etc/modules.conf`: `alias char-major-10-200 tun`
2. `depmod -a`
Installation from binary
------------------------
OsmoGGSN is built for common versions of Debian and Ubuntu as part of
OsmoGGSN is built for common versions of Debian, Ubuntu and other distributions part of
the [Osmocom Nightly Builds](https://osmocom.org/projects/cellular-infrastructure/wiki/Nightly_Builds)
project. If you don't want to do development, it is suggested to simply
use those binary packages, rather than building yourself from source.
and [Osmocom Latest Builds](https://osmocom.org/projects/cellular-infrastructure/wiki/Latest_Builds).
If you don't want to do development, it is suggested to simply use those binary packages, rather than building
yourself from source.
Installation from source
------------------------
1. ./configure
2. make
3. make install
```
./configure
make
make install
```
You need to be root in order to install the package, but not in order
to compile.
Running
-------
*sgsnemu*
Start the emulator as root using the command:
sgsnemu -l 10.0.0.50 -r 10.0.0.40 --createif --defaultroute
This will cause the sgsn emulator to bind to local address 10.0.0.50
and connect to the ggsn found at 10.0.0.40. It will first send off an
ECHO_REQUEST message. After this it will attempt to establish a pdp
context. If successful it will create a local interface and set up
routing. Now you should be able to ping through the connection. Use a
network analysator such as ethereal to monitor the traffic.
sgsnemu -h will show a list of available options.
sgsnemu -c sgsnemu.conf will use sgsnemu.conf as a configuration
file. A sample file is provided in examples/sgsnemu.conf.
*ggsn*
Edit the configuration file ggsn.conf found under openggsn/examples.
Start the ggsn as root using the command:
ggsn --fg -c examples/ggsn.conf -l 10.0.0.40 --statedir ./
This will run the ggsn in foreground using the local interface
10.0.0.40. If you don't have a GSM network available for testing you
can use sgsnemu to test the GGSN.
Support
-------
@ -144,9 +130,10 @@ OsmoGGSN is an open source implementation of GPRS Support Nodes
version 1.
OsmoGGSN provides 3 components:
* gtplib
* osmo-ggsn
* sgsnemu
* *libgtp*, a shared library for the GTPv1C protocol
* *osmo-ggsn*, the GGSN itself
* *sgsnemu*, a SGSN emulator
*gtplib*
This library contains all functionality relating to the GTP
@ -182,10 +169,10 @@ Both osmo-ggsn and sgsnemu uses the tun package. You need at least tun
version 1.1. With Linux tun is normally included from kernel version
2.4.7. To configure automatic loading:
1. Add the following line to /etc/modules.conf: alias char-major-10-200 tun
2. depmod -a
1. Add the following line to `/etc/modules.conf`: `alias char-major-10-200 tun`
2. `depmod -a`
Alternatively you can execute "modprobe tun" on the commandline.
Alternatively you can execute `modprobe tun` on the commandline.
Gengetopt
---------
@ -195,11 +182,13 @@ cmdline.ggo source file. You need at least gengetopt version 2.8. If
you are just going to compile the programs you don't need gengetopt.
To use gengetopt for the sgsnemu do the following:
```
cd sgsnemu
gengetopt < cmdline.ggo --conf-parser
```
For more information about gengetopt see
http://www.gnu.org/software/gengetopt/gengetopt.html
<http://www.gnu.org/software/gengetopt/gengetopt.html>
Compilation and Installation
@ -213,27 +202,21 @@ Running osmo-ggsn
Use osmo-ggsn -h for a list of available options. All options available on
the command line can also be given in a configuration file. See
examples/osmo-ggsn.cfg for the format of this file.
`doc/examples/osmo-ggsn.cfg` for the format of this file.
Start osmo-ggsn as root using the command:
osmo-ggsn -c examples/osmo-ggsn.cfg
`osmo-ggsn -c doc/examples/osmo-ggsn.cfg`
First a tun network interface will be created. In the above example
the network interface address is 192.168.0.0 and the mask is
255.255.255.0. You can check that this interface is up by using
ifconfig.
First, a tun network interface will be created for each configured apn.
After tun has been successfully established the ggsn will wait for GTP
create PDP context requests on the local interface
10.0.0.40. Currently all requests are accepted, and no password,
username or APN validation is performed.
create PDP context requests on the configured `gtp bind-ip` address.
Currently all requests are accepted, and no password, username validation is performed.
When receiving a create PDP context request a dynamic IP address will
be allocated from the address pool determined by --dynip. In the above
example the first allocated address will be 192.168.0.1, followed by
192.168.0.2 and so on. The request is confirmed by sending a create
PDP context response message to the peer (SGSN).
When receiving a create PDP context request for a given APN, a dynamic IP address will
be allocated from the address pool defined in the config file section for that apn.
The request is confirmed by sending a create PDP context response message to the peer (SGSN).
Now IP packets will be forwarded between the tun network interface and
the established GTP tunnel. In order to allow users to access the
@ -241,22 +224,22 @@ external network routing needs to be set up. If private addresses are
used you need to configure network address translation. See the Linux
Networking HOWTO for details.
Remember to enable routing:
Remember to enable routing:
echo 1 > /proc/sys/net/ipv4/ip_forward
`echo 1 > /proc/sys/net/ipv4/ip_forward`
If you installed using a binary RPM package it is possible to start
osmo-ggsn by using the Sys 5 script:
If you're using systemd and did `make install` or installed from a bianry package,
you can start osmo-ggsn by using the included systemd service/unit file:
/etc/init.d/osmo-ggsn start
`systemctl start osmo-ggsn`
Running sgsnemu
===============
Use sgsnemu -h for a list of available options. All options available
Use `sgsnemu -h` for a list of available options. All options available
on the command line can also be given in a configuration file. See
examples/sgsnemu.conf for the format of this file.
`doc/examples/sgsnemu.conf` for the format of this file.
If you want to test a GRX roaming connection you will need to do the
following:
@ -269,11 +252,11 @@ subnet mask and default route. See the Linux Networking HOWTO for
details.
4. Launch sgsnemu with something like:
sgsnemu --listen 10.0.0.50 --remote 10.0.0.40 --dns 10.20.38.51 --timelimit 10 --contexts 0
`sgsnemu --listen 10.0.0.50 --remote 10.0.0.40 --dns 10.20.38.51 --timelimit 10 --contexts 0`
sgsnemu will print something like the following on the screen:
```
Using DNS server: 10.20.38.51 (10.20.38.51)
Local IP address is: 10.0.0.50 (10.0.0.50)
Remote IP address is: 10.0.0.40 (10.0.0.40)
@ -289,6 +272,7 @@ sgsnemu will print something like the following on the screen:
Waiting for response from ggsn........
Received echo response. Cause value: 0
```
This is quite good. It means that you managed to send off an echo
request to a remote GGSN, and it was friendly enough to answer you. If
@ -306,10 +290,11 @@ testing. Also note that you are establishing a connection to the Gi
network, so please be carefull not to route internet traffic onto the
GPRS core network! Assuming you know what you are doing:
sgsnemu --listen 10.0.0.50 --remote 10.0.0.40 --dns 10.20.38.51 --timelimit 10 --contexts 1 --apn internet --imsi 240011234567890 --msisdn 46702123456 --createif --defaultroute
`sgsnemu --listen 10.0.0.50 --remote 10.0.0.40 --dns 10.20.38.51 --timelimit 10 --contexts 1 --apn internet --imsi 240011234567890 --msisdn 46702123456 --createif --defaultroute`
sgsnemu will print something like the following on the screen:
```
Using DNS server: 10.20.38.51 (10.20.38.51)
Local IP address is: 10.0.0.50 (10.0.0.50)
Remote IP address is: 10.0.0.40 (10.0.0.40)
@ -330,7 +315,7 @@ sgsnemu will print something like the following on the screen:
Setting up interface and routing
/sbin/ifconfig tun0 192.168.0.1
/sbin/route add -net 192.168.0.0 netmask 255.255.255.0 gw 192.168.0.1
```
Now a context is established to the remote GGSN. The IP address of the
context is 192.168.0.1. You should be able to ping a known address on
@ -344,13 +329,13 @@ do this is to use policy routing. Also note that you are effectively
connecting the same computer to both the Gn and Gi network, so please
be carefull not to route internet traffic onto the GPRS core network
and please protect yourself against hackers! For this reason it is
advised to always use --contexts 0 when testing a live network.
advised to always use `--contexts 0` when testing a live network.
After --timelimit seconds the PDP context is disconnected with the
After `--timelimit seconds` the PDP context is disconnected with the
following messages from sgsnemu:
```
Disconnecting PDP context #0
Received delete PDP context response. Cause value: 128
Deleting tun interface
```

View File

@ -7,3 +7,6 @@
# If any interfaces have been added since the last public release: c:r:a + 1.
# If any interfaces have been removed or changed since the last public release: c:r:0.
#library what description / commit summary line
libgtp REMOVE remove GTP cause defines of reserved values
libgtp REMOVE ABI change (removed API: ipv42eua, eua2ipv4)
libgtpnl > 1.2.5 gtp_tunnel_set_family()

View File

@ -154,9 +154,9 @@ adl_FUNC_GETOPT_LONG
AM_INIT_AUTOMAKE([foreign])
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.7.0)
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.7.0)
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.7.0)
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.9.0)
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.9.0)
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.9.0)
AC_ARG_ENABLE(sanitize,
[AS_HELP_STRING(
@ -262,10 +262,12 @@ AC_CONFIG_FILES([Makefile
doc/manuals/Makefile
contrib/Makefile
contrib/systemd/Makefile
contrib/osmo-ggsn.spec
tests/Makefile
tests/lib/Makefile
tests/gtp/Makefile
include/Makefile
include/osmocom/Makefile
include/osmocom/gtp/Makefile
libgtp.pc])
AC_OUTPUT

View File

@ -1,97 +0,0 @@
#!/bin/sh
#
# osmo-ggsn This shell script takes care of starting and stopping
# osmo-ggsn.
#
# chkconfig: - 65 35
# description: osmo-ggsn is a Gateway GPRS Support Node.
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
if [ -f /etc/sysconfig/osmo-ggsn ]; then
. /etc/sysconfig/osmo-ggsn
fi
# Check that networking is up.
[ ${NETWORKING} = "no" ] && exit 0
[ -f /usr/bin/osmo-ggsn ] || exit 0
[ -f /etc/osmo-ggsn.cfg ] || exit 0
RETVAL=0
prog="osmo-ggsn"
start() {
# Start daemons.
echo -n $"Starting $prog: "
# Load tun module
/sbin/modprobe tun >/dev/null 2>&1
# Enable routing of packets: WARNING!!!
# Users should enable this explicitly
# echo 1 > /proc/sys/net/ipv4/ip_forward
# Check for runtime directory of nonvolatile data
if [ ! -d /var/lib/osmo-ggsn ]; then
mkdir /var/lib/osmo-ggsn
fi
# Check for GTP restart counter
if [ ! -d /var/lib/osmo-ggsn/gsn_restart ]; then
echo 0 > /var/lib/osmo-ggsn/gsn_restart
fi
daemon /usr/bin/osmo-ggsn
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/osmo-ggsn
return $RETVAL
}
stop() {
# Stop daemons.
echo -n $"Shutting down $prog: "
killproc osmo-ggsn
RETVAL=$?
echo
[ $RETVAL = 0 ] && rm -f /var/lock/subsys/osmo-ggsn /var/run/osmo-ggsn.pid
return $RETVAL
}
# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
restart|reload)
stop
start
RETVAL=$?
;;
condrestart)
if [ -f /var/lock/subsys/osmo-ggsn ] ; then
stop
start
RETVAL=$?
fi
;;
status)
status osmo-ggsn
RETVAL=$?
;;
*)
echo $"Usage: $0 {start|stop|restart|condrestart|status}"
exit 1
esac
exit $RETVAL

View File

@ -1,137 +0,0 @@
#
# spec file for package osmo-ggsn
#
# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
# upon. The license for this file, and modifications and additions to the
# file, is the same license as for the pristine package itself (unless the
# license for the pristine package is not an Open Source License, in which
# case the license is the MIT License). An "Open Source License" is a
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.
## Disable LTO for now since it breaks compilation of the tests
## https://osmocom.org/issues/4114
%define _lto_cflags %{nil}
Name: osmo-ggsn
Version: @VERSION@
Release: 0
Summary: GPRS Support Node
License: GPL-2.0-only AND LGPL-2.1-or-later
Group: Productivity/Telephony/Servers
URL: https://osmocom.org/projects/openggsn
Source: %{name}-%{version}.tar.xz
BuildRequires: libtool >= 2
BuildRequires: pkgconfig >= 0.20
%if 0%{?suse_version}
BuildRequires: systemd-rpm-macros
%endif
BuildRequires: pkgconfig(libgtpnl) >= 1.2.0
BuildRequires: pkgconfig(libosmocore) >= 1.7.0
BuildRequires: pkgconfig(libosmoctrl) >= 1.7.0
BuildRequires: pkgconfig(libosmovty) >= 1.7.0
Obsoletes: openggsn
%{?systemd_requires}
%description
Osmo-GGSN is a C-language implementation of a GGSN (Gateway GPRS
Support Node), a core network element of ETSI/3GPP cellular networks
such as GPRS, EDGE, UMTS or HSPA.
%package -n libgtp6
Summary: Library implementing GTP between SGSN and GGSN
License: GPL-2.0-only
Group: System/Libraries
%description -n libgtp6
libgtp implements the GPRS Tunneling Protocol between SGSN and GGSN.
%package -n libgtp-devel
Summary: Development files for the GTP library
License: GPL-2.0-only
Group: Development/Libraries/C and C++
Requires: libgtp6 = %{version}
%description -n libgtp-devel
libgtp implements the GPRS Tunneling Protocol between SGSN and GGSN.
This subpackage contains libraries and header files for developing
applications that want to make use of libgtp.
%package -n gtp-echo-responder
Summary: Small program answering GTP ECHO Request with GTP ECHO Response
License: MIT
Group: System/Libraries
%description -n gtp-echo-responder
Small program answering GTP ECHO Request with GTP ECHO Response for both GTPCv1
and GTPCv2.
%prep
%setup -q
%build
echo "%{version}" >.tarball-version
autoreconf -fi
%configure \
--enable-gtp-linux \
--disable-static \
--docdir="%{_docdir}/%{name}" \
--with-systemdsystemunitdir=%{_unitdir} \
--includedir="%{_includedir}/%{name}"
make %{?_smp_mflags} V=1
%install
%make_install
find %{buildroot} -type f -name "*.la" -delete -print
%check
make %{?_smp_mflags} check || (find . -name testsuite.log -exec cat {} +)
%if 0%{?suse_version}
%pre
%service_add_pre %{name}.service
%post
%service_add_post %{name}.service
%preun
%service_del_preun %{name}.service
%postun
%service_del_postun %{name}.service
%endif
%post -n libgtp6 -p /sbin/ldconfig
%postun -n libgtp6 -p /sbin/ldconfig
%files
%license COPYING
%doc AUTHORS README.md
%{_bindir}/osmo-ggsn
%{_bindir}/sgsnemu
%{_mandir}/man8/osmo-ggsn.8%{?ext_man}
%{_mandir}/man8/sgsnemu.8%{?ext_man}
%{_unitdir}/%{name}.service
%dir %{_docdir}/%{name}/examples
%{_docdir}/%{name}/examples/osmo-ggsn-kernel-gtp.cfg
%{_docdir}/%{name}/examples/osmo-ggsn.cfg
%{_docdir}/%{name}/examples/sgsnemu.conf
%dir %{_sysconfdir}/osmocom
%config(noreplace) %{_sysconfdir}/osmocom/osmo-ggsn.cfg
%files -n libgtp6
%{_libdir}/libgtp.so.6*
%files -n libgtp-devel
%{_includedir}/%{name}/
%{_libdir}/libgtp.so
%{_libdir}/pkgconfig/libgtp.pc
%files -n gtp-echo-responder
%{_bindir}/gtp-echo-responder
%changelog

View File

@ -1,13 +1,20 @@
[Unit]
Description=OsmoGGSN
After=networking.service
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
Restart=always
StateDirectory=osmocom
WorkingDirectory=%S/osmocom
ExecStart=/usr/bin/osmo-ggsn -c /etc/osmocom/osmo-ggsn.cfg
RestartSec=2
RestartPreventExitStatus=1
User=osmocom
Group=osmocom
# For setting up the gtp0/tun0 devices
AmbientCapabilities=CAP_NET_ADMIN
[Install]
WantedBy=multi-user.target

55
debian/changelog vendored
View File

@ -1,3 +1,58 @@
osmo-ggsn (1.11.0) unstable; urgency=medium
[ Daniel Willmann ]
* gtp: Add net GTP cause values and a function to check for success
-- Oliver Smith <osmith@sysmocom.de> Tue, 28 Nov 2023 13:38:29 +0100
osmo-ggsn (1.10.2) unstable; urgency=medium
[ Vadim Yanitskiy ]
* Do not hard-code -g and -O2 in CFLAGS
* tests: use -no-install libtool flag to avoid ./lt-* scripts
[ Oliver Smith ]
* doc/manuals/chapters/configuration: fix typo
* debian: set compat level to 10
* systemd: depend on networking-online.target
* README: update documentation section
* doc: running: update kernel-gtp limitations
* lib/in46_addr: add in46a_from_gsna
-- Pau Espin Pedrol <pespin@sysmocom.de> Tue, 12 Sep 2023 14:36:10 +0200
osmo-ggsn (1.10.1) unstable; urgency=medium
[ Oliver Smith ]
* debian/libgtp6.shlibs: new file
[ Vadim Yanitskiy ]
* lib/icmpv6.h: fix struct icmpv6_{radv_hdr,opt_prefix}
* gtp/gsn.c: fix 'No newline at end of file'
* gtp: use OSMO_ASSERT() in gtp_new()
-- Vadim Yanitskiy <vyanitskiy@sysmocom.de> Mon, 27 Feb 2023 22:35:47 +0700
osmo-ggsn (1.10.0) unstable; urgency=medium
[ Max ]
* Set working directory in systemd service file
* Ignore .deb build byproducts
* ctrl: take both address and port from vty config
[ Pau Espin Pedrol ]
* cosmetic: gtp: Fix typo in comment
* Split gsn_t related APIs out of gtp.{c,h}
* Use rate_ctr for gsn_t available_counters
* ggsn: Introduce tdef and make it configurable over VTY
* gtp: Introduce VTY configurable GTP timer X3
* Fix typos in comments and VTY descriptions
[ arehbein ]
* osmo-ggsn: Transition to use of 'telnet_init_default'
-- Pau Espin Pedrol <pespin@sysmocom.de> Tue, 07 Feb 2023 14:29:48 +0100
osmo-ggsn (1.9.0) unstable; urgency=medium
[ Pau Espin Pedrol ]

2
debian/compat vendored
View File

@ -1 +1 @@
9
10

4
debian/control vendored
View File

@ -2,12 +2,12 @@ Source: osmo-ggsn
Maintainer: Osmocom team <openbsc@lists.osmocom.org>
Section: net
Priority: optional
Build-Depends: debhelper (>= 9),
Build-Depends: debhelper (>= 10),
autotools-dev,
pkg-config,
libdpkg-perl, git,
dh-autoreconf,
libosmocore-dev (>= 1.7.0),
libosmocore-dev (>= 1.9.0),
osmo-gsm-manuals-dev,
libgtpnl-dev (>= 1.2.0)
Standards-Version: 3.9.6

2
debian/libgtp6.shlibs vendored Normal file
View File

@ -0,0 +1,2 @@
# Most recent version of the package that added new symbols (OS#5318)
libgtp 6 libgtp6 (>= 1.8.0)

163
debian/osmo-ggsn.init vendored
View File

@ -1,163 +0,0 @@
#!/bin/sh
### BEGIN INIT INFO
# Provides: osmo-ggsn
# Required-Start: $network $local_fs $remote_fs
# Required-Stop: $network $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Gateway GPRS Support Node
# Description: Gateway GPRS Support Node
### 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
DESC="OsmoGGSN Gateway GPRS Support Node"
NAME=ggsn
DAEMON=/usr/bin/osmo-ggsn
DAEMON_ARGS="" # Arguments to run the daemon with
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/osmo-ggsn
# Exit if the package is not installed
[ -x $DAEMON ] || exit 0
# Read configuration variable file if it is present
[ -r /etc/default/osmo-ggsn ] && . /etc/default/osmo-ggsn
# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions
DAEMON_ARGS="$DAEMON_ARGS"
#
# 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 --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
|| return 1
# Check for runtime directory of nonvolatile data
if [ ! -d /var/lib/osmo-ggsn ]; then
mkdir /var/lib/osmo-ggsn
fi
# Check for GTP restart counter
if [ ! -f /var/lib/osmo-ggsn/gsn_restart ]; then
echo 0 > /var/lib/osmo-ggsn/gsn_restart
fi
start-stop-daemon --start --quiet --pidfile $PIDFILE --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 --pidfile $PIDFILE --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
# Many daemons don't delete their pidfiles when they exit.
rm -f $PIDFILE
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 $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
:

39
debian/postinst vendored Executable file
View File

@ -0,0 +1,39 @@
#!/bin/sh -e
case "$1" in
configure)
# Create the osmocom group and user (if it doesn't exist yet)
if ! getent group osmocom >/dev/null; then
groupadd --system osmocom
fi
if ! getent passwd osmocom >/dev/null; then
useradd \
--system \
--gid osmocom \
--home-dir /var/lib/osmocom \
--shell /sbin/nologin \
--comment "Open Source Mobile Communications" \
osmocom
fi
# Fix permissions of previous (root-owned) install (OS#4107)
if dpkg --compare-versions "$2" le "1.13.0"; then
if [ -e /etc/osmocom/osmo-ggsn.cfg ]; then
chown -v osmocom:osmocom /etc/osmocom/osmo-ggsn.cfg
chmod -v 0660 /etc/osmocom/osmo-ggsn.cfg
fi
if [ -d /etc/osmocom ]; then
chown -v root:osmocom /etc/osmocom
chmod -v 2775 /etc/osmocom
fi
mkdir -p /var/lib/osmocom
chown -R -v osmocom:osmocom /var/lib/osmocom
fi
;;
esac
# dh_installdeb(1) will replace this with shell code automatically
# generated by other debhelper scripts.
#DEBHELPER#

View File

@ -3,10 +3,12 @@
!!
!
log stderr
logging filter all 1
logging color 1
logging print category 0
logging print category-hex 0
logging print category 1
logging timestamp 0
logging print file basename last
logging print level 1
logging level ip info
logging level tun info
logging level ggsn info
@ -36,7 +38,7 @@ line vty
no login
!
ggsn ggsn0
gtp state-dir /tmp
gtp state-dir /var/lib/osmocom/osmo-ggsn
gtp bind-ip 127.0.0.2
apn internet
gtpu-mode kernel-gtp

View File

@ -3,10 +3,12 @@
!!
!
log stderr
logging filter all 1
logging color 1
logging print category 0
logging print category-hex 0
logging print category 1
logging timestamp 0
logging print file basename last
logging print level 1
logging level ip info
logging level tun info
logging level ggsn info
@ -36,7 +38,7 @@ line vty
no login
!
ggsn ggsn0
gtp state-dir /tmp
gtp state-dir /var/lib/osmocom/osmo-ggsn
gtp bind-ip 127.0.0.2
apn internet
gtpu-mode tun

View File

@ -16,7 +16,7 @@ your configuration file, like in below example:
.Example: Single GGSN configuration section
----
ggsn ggsn0
gtp state-dir /tmp
gtp state-dir /var/lib/osmocom/osmo-ggsn
gtp bind-ip 127.0.0.6
apn internet
gtpu-mode tun
@ -58,7 +58,7 @@ The following two mandatory configuration statements have to be given
for every GGSN instance:
----
OsmoGGSN(config-ggsn)# gtp state-dir /var/lib/ggsn/ggsn0 <1>
OsmoGGSN(config-ggsn)# gtp state-dir /var/lib/osmocom/osmo-ggsn <1>
OsmoGGSN(config-ggsn)# gtp bind-ip 127.0.0.6 <2>
----
<1> Store the GSN restart state in the specified directory
@ -101,7 +101,7 @@ OsmoGGSN(config-ggsn)# no shutdown ggsn <4>
----
<1> Change into privileged mode
<2> Enter the interactive configuration mode
<3> Enter the config ndoe of the GGSN instance `ggsn0`
<3> Enter the config node of the GGSN instance `ggsn0`
<4> Take the GGSN instance out of shutdown
@ -121,7 +121,7 @@ OsmoGGSN(config-ggsn)# shutdown ggsn <4>
----
<1> Change into privileged mode
<2> Enter the interactive configuration mode
<3> Enter the config ndoe of the GGSN instance `ggsn0`
<3> Enter the config node of the GGSN instance `ggsn0`
<4> Shut down the GGSN instance
@ -215,8 +215,8 @@ OsmoGGSN(config-ggsn-apn)# no shutdown <5>
----
<1> Change into privileged mode
<2> Enter the interactive configuration mode
<3> Enter the config ndoe of the GGSN instance `ggsn0`
<4> Enter the config ndoe of the APN `internet`
<3> Enter the config node of the GGSN instance `ggsn0`
<4> Enter the config node of the APN `internet`
<5> Take the APN out of shutdown
@ -237,8 +237,8 @@ OsmoGGSN(config-ggsn-apn)# shutdown <5>
----
<1> Change into privileged mode
<2> Enter the interactive configuration mode
<3> Enter the config ndoe of the GGSN instance `ggsn0`
<4> Enter the config ndoe of the APN `internet`
<3> Enter the config node of the GGSN instance `ggsn0`
<4> Enter the config node of the APN `internet`
<5> Shut down the APN
[[ggsn_no_root]]
@ -302,7 +302,7 @@ Name=apn0 <1>
Address=192.168.7.1/24 <2>
IPMasquerade=yes <3>
----
<1> The netowrk device name, which must match the one in the apn0.netdev unit file above
<1> The network device name, which must match the one in the apn0.netdev unit file above
<2> The local IP address configured on the device
<3> Requesting systemd to configure IP masquerading for this interface. Depending on your needs,
You may not want this if you have proper end-to-end routing set up, and want to have transparent

View File

@ -83,7 +83,12 @@ ggsn ggsn0
=== GTP-U kernel module
WARNING: As of writing, the kernel module does not support IPv6.
WARNING: As of writing, IPv6 support for the kernel module has not been
upstreamed yet (OS#1952).
WARNING: As of writing, it is not possible to configure multiple APNs with
gtpu-mode kernel-gpt. This is a limitation in OsmoGGSN, not in the
kernel module (OS#6106).
OsmoGGSN has support to use the Linux kernel GTP-U tunnel driver to accelerate
the data/user plane while still implementing the control plane (GTP-C) in

View File

@ -2,7 +2,16 @@ bin_PROGRAMS = osmo-ggsn
AM_LDFLAGS = @EXEC_LDFLAGS@
AM_CFLAGS = -O2 -D_GNU_SOURCE -fno-builtin -Wall -DSBINDIR='"$(sbindir)"' -ggdb $(LIBOSMOCORE_CFLAGS) $(LIBOSMOCTRL_CFLAGS) $(LIBOSMOVTY_CFLAGS)
AM_CFLAGS = \
-D_GNU_SOURCE \
-fno-builtin \
-Wall \
-DSBINDIR='"$(sbindir)"' \
-I$(top_srcdir)/include \
$(LIBOSMOCORE_CFLAGS) \
$(LIBOSMOCTRL_CFLAGS) \
$(LIBOSMOVTY_CFLAGS) \
$(NULL)
osmo_ggsn_LDADD = @EXEC_LDADD@ -lgtp -L../gtp ../lib/libmisc.a $(LIBOSMOCORE_LIBS) $(LIBOSMOCTRL_LIBS) $(LIBOSMOVTY_LIBS)

View File

@ -46,17 +46,19 @@
#include <osmocom/ctrl/control_if.h>
#include <osmocom/gsm/apn.h>
#include <osmocom/gtp/pdp.h>
#include <osmocom/gtp/gtp.h>
#include "../lib/tun.h"
#include "../lib/ippool.h"
#include "../lib/syserr.h"
#include "../lib/in46_addr.h"
#include "../lib/gtp-kernel.h"
#include "../lib/util.h"
#include "../gtp/pdp.h"
#include "../gtp/gtp.h"
#include "../lib/icmpv6.h"
#include "pco.h"
#include "ggsn.h"
#include "../gtp/gtp_internal.h"
static int ggsn_tun_fd_cb(struct osmo_fd *fd, unsigned int what);
static int cb_tun_ind(struct tun_t *tun, void *pack, unsigned len);
@ -193,7 +195,7 @@ int apn_start(struct apn_ctx *apn)
}
LOGPAPN(LOGL_INFO, apn, "Opened TUN device %s\n", apn->tun.tun->devname);
/* Register with libosmcoore */
/* Register with libosmocore */
osmo_fd_setup(&apn->tun.fd, apn->tun.tun->fd, OSMO_FD_READ, ggsn_tun_fd_cb, apn, 0);
osmo_fd_register(&apn->tun.fd);
@ -202,11 +204,6 @@ int apn_start(struct apn_ctx *apn)
break;
case APN_GTPU_MODE_KERNEL_GTP:
LOGPAPN(LOGL_INFO, apn, "Opening Kernel GTP device %s\n", apn->tun.cfg.dev_name);
if (apn->cfg.apn_type_mask & (APN_TYPE_IPv6|APN_TYPE_IPv4v6)) {
LOGPAPN(LOGL_ERROR, apn, "Kernel GTP currently supports only IPv4\n");
apn_stop(apn);
return -1;
}
if (gsn == NULL) {
/* skip bringing up the APN now if the GSN is not initialized yet.
* This happens during initial load of the config file, as the
@ -536,10 +533,11 @@ int create_context_ind(struct pdp_t *pdp)
in46a_to_eua(addr, num_addr, &pdp->eua);
if (apn->cfg.gtpu_mode == APN_GTPU_MODE_KERNEL_GTP && apn_supports_ipv4(apn)) {
/* TODO: In IPv6, EUA doesn't contain the actual IP addr/prefix! */
if (apn->cfg.gtpu_mode == APN_GTPU_MODE_KERNEL_GTP) {
if (gtp_kernel_tunnel_add(pdp, apn->tun.cfg.dev_name) < 0) {
LOGPPDP(LOGL_ERROR, pdp, "Cannot add tunnel to kernel: %s\n", strerror(errno));
if (addrv6 && errno == EINVAL)
LOGPPDP(LOGL_ERROR, pdp, "Maybe your kernel does not support GTP-U with IPv6 yet?\n");
gtp_create_context_resp(gsn, pdp, GTPCAUSE_SYS_FAIL);
return 0;
}

View File

@ -6,13 +6,14 @@
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/select.h>
#include <osmocom/core/timer.h>
#include <osmocom/core/tdef.h>
#include <osmocom/ctrl/control_if.h>
#include <osmocom/gtp/gtp.h>
#include "../lib/tun.h"
#include "../lib/ippool.h"
#include "../lib/syserr.h"
#include "../lib/in46_addr.h"
#include "../gtp/gtp.h"
#include "sgsn.h"
@ -65,9 +66,9 @@ struct apn_ctx {
uint32_t apn_type_mask;
/* GTP-U via TUN device or in Linux kernel */
enum apn_gtpu_mode gtpu_mode;
/* administratively shut-down (true) or not (false) */
/* administratively shut down (true) or not (false) */
bool shutdown;
/* transmit G-PDU sequeence numbers (true) or not (false) */
/* transmit G-PDU sequence numbers (true) or not (false) */
bool tx_gpdu_seq;
} cfg;
@ -127,7 +128,7 @@ struct ggsn_ctx {
char *state_dir;
/* Time between Echo requests on each SGSN */
unsigned int echo_interval;
/* administratively shut-down (true) or not (false) */
/* administratively shut down (true) or not (false) */
bool shutdown;
} cfg;
@ -152,6 +153,7 @@ struct apn_ctx *ggsn_find_or_create_apn(struct ggsn_ctx *ggsn, const char *name)
/* ggsn_main.c */
extern struct ctrl_handle *g_ctrlh;
extern void *tall_ggsn_ctx;
extern struct osmo_tdef_group ggsn_tdef_group[];
/* ggsn.c */
extern int ggsn_start(struct ggsn_ctx *ggsn);

View File

@ -34,6 +34,7 @@
#include <osmocom/core/stats.h>
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/timer.h>
#include <osmocom/core/tdef.h>
#include <osmocom/core/utils.h>
#include <osmocom/ctrl/control_if.h>
#include <osmocom/ctrl/control_cmd.h>
@ -60,6 +61,11 @@ struct ul255_t apn;
static char *config_file = "osmo-ggsn.cfg";
struct osmo_tdef_group ggsn_tdef_group[] = {
{.name = "gtp", .tdefs = gtp_T_defs, .desc = "GTP (libgtp) timers" },
{ }
};
/* To exit gracefully. Used with GCC compilation flag -pg and gprof */
static void signal_handler(int s)
{
@ -217,12 +223,11 @@ int main(int argc, char **argv)
exit(2);
}
rc = telnet_init_dynif(tall_ggsn_ctx, NULL, vty_get_bind_addr(), OSMO_VTY_PORT_GGSN);
rc = telnet_init_default(tall_ggsn_ctx, NULL, OSMO_VTY_PORT_GGSN);
if (rc < 0)
exit(1);
g_ctrlh = ctrl_interface_setup_dynip(NULL, ctrl_vty_get_bind_addr(),
OSMO_CTRL_PORT_GGSN, NULL);
g_ctrlh = ctrl_interface_setup(NULL, OSMO_CTRL_PORT_GGSN, NULL);
if (!g_ctrlh) {
LOGP(DGGSN, LOGL_ERROR, "Failed to create CTRL interface.\n");
exit(1);

View File

@ -22,6 +22,8 @@
#include <inttypes.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <osmocom/core/talloc.h>
#include <osmocom/core/utils.h>
@ -33,14 +35,16 @@
#include <osmocom/vty/command.h>
#include <osmocom/vty/vty.h>
#include <osmocom/vty/misc.h>
#include <osmocom/vty/tdef_vty.h>
#include "../gtp/gtp.h"
#include "../gtp/pdp.h"
#include <osmocom/gtp/gtp.h>
#include <osmocom/gtp/pdp.h>
#include "../lib/util.h"
#include "ggsn.h"
#include "sgsn.h"
#include "../gtp/gtp_internal.h"
#define PREFIX_STR "Prefix (Network/Netmask)\n"
#define IFCONFIG_STR "GGSN-based interface configuration\n"
@ -222,6 +226,11 @@ DEFUN(cfg_ggsn_state_dir, cfg_ggsn_state_dir_cmd,
{
struct ggsn_ctx *ggsn = (struct ggsn_ctx *) vty->index;
if (mkdir(argv[0], 0755) == -1 && errno != EEXIST) {
vty_out(vty, "%% Failed to create state-dir: %s%s", argv[0], VTY_NEWLINE);
return CMD_WARNING;
}
osmo_talloc_replace_string(ggsn, &ggsn->cfg.state_dir, argv[0]);
return CMD_SUCCESS;
@ -298,7 +307,7 @@ DEFUN(cfg_ggsn_no_default_apn, cfg_ggsn_no_default_apn_cmd,
DEFUN(cfg_ggsn_shutdown, cfg_ggsn_shutdown_cmd,
"shutdown ggsn",
"Put the GGSN in administrative shut-down\n" GGSN_STR)
"Put the GGSN in administrative shutdown\n" GGSN_STR)
{
struct ggsn_ctx *ggsn = (struct ggsn_ctx *) vty->index;
@ -315,7 +324,7 @@ DEFUN(cfg_ggsn_shutdown, cfg_ggsn_shutdown_cmd,
DEFUN(cfg_ggsn_no_shutdown, cfg_ggsn_no_shutdown_cmd,
"no shutdown ggsn",
NO_STR GGSN_STR "Remove the GGSN from administrative shut-down\n")
NO_STR GGSN_STR "Remove the GGSN from administrative shutdown\n")
{
struct ggsn_ctx *ggsn = (struct ggsn_ctx *) vty->index;
@ -343,7 +352,7 @@ static void show_one_sgsn(struct vty *vty, const struct sgsn_peer *sgsn, const c
DEFUN(cfg_ggsn_show_sgsn, cfg_ggsn_show_sgsn_cmd,
"show sgsn",
NO_STR GGSN_STR "Remove the GGSN from administrative shut-down\n")
NO_STR GGSN_STR "Remove the GGSN from administrative shutdown\n")
{
struct ggsn_ctx *ggsn = (struct ggsn_ctx *) vty->index;
struct sgsn_peer *sgsn;
@ -680,7 +689,7 @@ DEFUN(cfg_apn_no_gpdu_seq, cfg_apn_no_gpdu_seq_cmd,
DEFUN(cfg_apn_shutdown, cfg_apn_shutdown_cmd,
"shutdown",
"Put the APN in administrative shut-down\n")
"Put the APN in administrative shutdown\n")
{
struct apn_ctx *apn = (struct apn_ctx *) vty->index;
@ -697,7 +706,7 @@ DEFUN(cfg_apn_shutdown, cfg_apn_shutdown_cmd,
DEFUN(cfg_apn_no_shutdown, cfg_apn_no_shutdown_cmd,
"no shutdown",
NO_STR "Remove the APN from administrative shut-down\n")
NO_STR "Remove the APN from administrative shutdown\n")
{
struct apn_ctx *apn = (struct apn_ctx *) vty->index;
@ -795,6 +804,7 @@ static int config_write_ggsn(struct vty *vty)
vty_out(vty, " gtp control-ip %s%s", in46a_ntoa(&ggsn->cfg.gtpc_addr), VTY_NEWLINE);
if (ggsn->cfg.gtpu_addr.v4.s_addr)
vty_out(vty, " gtp user-ip %s%s", in46a_ntoa(&ggsn->cfg.gtpu_addr), VTY_NEWLINE);
osmo_tdef_vty_groups_write(vty, " ");
llist_for_each_entry(apn, &ggsn->apn_list, list)
config_write_apn(vty, apn);
if (ggsn->cfg.default_apn)
@ -812,10 +822,7 @@ static const char *print_gsnaddr(const struct ul16_t *in)
{
struct in46_addr in46;
in46.len = in->l;
OSMO_ASSERT(in->l <= sizeof(in46.v6));
memcpy(&in46.v6, in->v, in->l);
in46a_from_gsna(in, &in46);
return in46a_ntoa(&in46);
}
@ -1113,6 +1120,8 @@ int ggsn_vty_init(void)
install_element(GGSN_NODE, &cfg_ggsn_echo_interval_cmd);
install_element(GGSN_NODE, &cfg_ggsn_no_echo_interval_cmd);
osmo_tdef_vty_groups_init(GGSN_NODE, ggsn_tdef_group);
install_node(&apn_node, NULL);
install_element(APN_NODE, &cfg_description_cmd);
install_element(APN_NODE, &cfg_no_description_cmd);

View File

@ -110,6 +110,7 @@ ret_broken:
osmo_hexdump_nospc((const uint8_t *)pco_in, pco_in->length));
}
/* Handle IP Control Protocol, RFC 1332, extensions in RFC 1877 */
static void process_pco_element_ipcp(const struct pco_element *pco_elem, struct msgb *resp,
const struct apn_ctx *apn, struct pdp_t *pdp)
{

View File

@ -2,7 +2,7 @@
#include <stdint.h>
#include "../gtp/pdp.h"
#include <osmocom/gtp/pdp.h>
/* 3GPP TS 24.008 10.5.6.3 */
enum pco_protocols {
@ -42,12 +42,11 @@ struct pco_element {
uint8_t data[0];
} __attribute__((packed));
/* RFC 1332 */
/* RFC 1332 IP Control Protocol options, extensions in RFC 1877 */
enum ipcp_options {
IPCP_OPT_IPADDR = 3,
IPCP_OPT_PRIMARY_DNS = 129,
IPCP_OPT_SECONDARY_DNS = 131,
IPCP_OPT_IPADDR = 3, /* RFC 1332 3.3 */
IPCP_OPT_PRIMARY_DNS = 129, /* RFC 1877 1.1 */
IPCP_OPT_SECONDARY_DNS = 131, /* RFC 1877 1.2 */
};
struct ipcp_option_hdr {

View File

@ -1,6 +1,6 @@
#include "sgsn.h"
#include "ggsn.h"
#include "../gtp/gtp_internal.h"
static bool sgsn_peer_attempt_free(struct sgsn_peer *sgsn)
{

View File

@ -8,7 +8,7 @@
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/timer.h>
#include "../gtp/pdp.h"
#include <osmocom/gtp/pdp.h>
struct ggsn_ctx;
struct pdp_priv_t;

View File

@ -2,14 +2,30 @@
# Please read chapter "Library interface versions" of the libtool documentation
# before making any modifications: https://www.gnu.org/software/libtool/manual/html_node/Versioning.html
# If major=current-age is increased, remember to update the dh_strip line in debian/rules!
LIBVERSION=8:1:2
LIBVERSION=9:1:3
lib_LTLIBRARIES = libgtp.la
include_HEADERS = gtp.h pdp.h gtpie.h
AM_CFLAGS = \
-fno-builtin \
-Wall \
-DSBINDIR='"$(sbindir)"' \
-I$(top_srcdir)/include \
$(LIBOSMOCORE_CFLAGS) \
$(NULL)
AM_CFLAGS = -O2 -fno-builtin -Wall -DSBINDIR='"$(sbindir)"' -ggdb $(LIBOSMOCORE_CFLAGS)
libgtp_la_SOURCES = \
gsn.c \
gsn_internal.h \
gtp.c \
gtp_internal.h \
gtpie.c \
lookupa.c \
lookupa.h \
pdp.c \
queue.c \
queue.h \
$(NULL)
libgtp_la_SOURCES = gtp.c gtp.h gtpie.c gtpie.h pdp.c pdp.h lookupa.c lookupa.h queue.c queue.h
libgtp_la_LDFLAGS = -version-info $(LIBVERSION) -no-undefined
libgtp_la_LIBADD = $(LIBOSMOCORE_LIBS)

578
gtp/gsn.c Normal file
View File

@ -0,0 +1,578 @@
/*
* OsmoGGSN - Gateway GPRS Support Node
* Copyright (C) 2002, 2003, 2004 Mondru AB.
* Copyright (C) 2010-2011, 2016-2017 Harald Welte <laforge@gnumonks.org>
* Copyright (C) 2015-2017 sysmocom - s.f.m.c. GmbH
*
* The contents of this file may be used under the terms of the GNU
* General Public License Version 2, provided that the above copyright
* notice and this permission notice is included in all copies or
* substantial portions of the software.
*
*/
/*
* gtp.c: Contains all GTP functionality. Should be able to handle multiple
* tunnels in the same program.
*
* TODO:
* - Do we need to handle fragmentation?
*/
#ifdef __linux__
#define _GNU_SOURCE 1
#endif
#include <osmocom/core/logging.h>
#include <osmocom/core/utils.h>
#include <osmocom/core/stats.h>
#include <osmocom/core/rate_ctr.h>
#if defined(__FreeBSD__)
#include <sys/endian.h>
#endif
#include "../config.h"
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <arpa/inet.h>
/* #include <stdint.h> ISO C99 types */
#include <osmocom/gtp/pdp.h>
#include <osmocom/gtp/gtp.h>
#include <osmocom/gtp/gtpie.h>
#include "queue.h"
#include "gsn_internal.h"
/* Error reporting functions */
#define LOGP_WITH_ADDR(ss, level, addr, fmt, args...) \
LOGP(ss, level, "addr(%s:%d) " fmt, \
inet_ntoa((addr).sin_addr), htons((addr).sin_port), \
##args)
static const struct rate_ctr_desc gsn_ctr_description[] = {
[GSN_CTR_ERR_SOCKET] = { "err:socket", "Socket error" },
[GSN_CTR_ERR_READFROM] = { "err:readfrom", "readfrom() errors" },
[GSN_CTR_ERR_SENDTO] = { "err:sendto", "sendto() errors" },
[GSN_CTR_ERR_QUEUEFULL] = { "err:queuefull", "Failed to queue message because queue is full" },
[GSN_CTR_ERR_SEQ] = { "err:seq", "Sequence number out of range" },
[GSN_CTR_ERR_ADDRESS] = { "err:address", "GSN address conversion failed" },
[GSN_CTR_ERR_UNKNOWN_PDP] = { "err:unknown_pdp", "Failed looking up PDP context" },
[GSN_CTR_ERR_UNEXPECTED_CAUSE] = { "err:unexpected_cause", "Unexpected cause value received" },
[GSN_CTR_ERR_OUT_OF_PDP] = { "err:out_of_pdp", "Out of storage for PDP contexts" },
[GSN_CTR_PKT_EMPTY] = { "pkt:empty", "Empty packet received" },
[GSN_CTR_PKT_UNSUP] = { "pkt:unsupported", "Unsupported GTP version received" },
[GSN_CTR_PKT_TOOSHORT] = { "pkt:too_short", "Packet too short received" },
[GSN_CTR_PKT_UNKNOWN] = { "pkt:unknown", "Unknown packet type received" },
[GSN_CTR_PKT_UNEXPECT] = { "pkt:unexpected", "Unexpected packet type received" },
[GSN_CTR_PKT_DUPLICATE] = { "pkt:duplicate", "Duplicate or unsolicited packet received" },
[GSN_CTR_PKT_MISSING] = { "pkt:missing", "Missing IE in packet received" },
[GSN_CTR_PKT_INCORRECT] = { "pkt:incorrect", "Incorrect IE in packet received" },
[GSN_CTR_PKT_INVALID] = { "pkt:invalid", "Invalid format in packet received" },
};
static const struct rate_ctr_group_desc gsn_ctrg_desc = {
"gsn",
"GSN Statistics",
OSMO_STATS_CLASS_PEER,
ARRAY_SIZE(gsn_ctr_description),
gsn_ctr_description,
};
static unsigned int gsn_ctr_next_idx = 0;
/* Global timer definitions for GTP operation, provided for convenience. To make these user configurable, it is convenient to add
* gtp_gsn_tdefs as one of your program's osmo_tdef_group entries and call osmo_tdef_vty_init(). */
struct osmo_tdef gtp_T_defs[] = {
{ .T = GTP_GSN_TIMER_T3_RESPONSE, .default_val = 5, .unit = OSMO_TDEF_S,
.desc = "Timer T3-RESPONSE holds the maximum wait time for a response of a request message"
},
{ .T = GTP_GSN_TIMER_N3_REQUESTS, .default_val = 3, .unit = OSMO_TDEF_CUSTOM,
.desc = "Counter N3-REQUESTS holds the maximum number of attempts made by GTP to send a request message"
},
{ .T = GTP_GSN_TIMER_T3_HOLD_RESPONSE, .default_val = 5 * 3 /* (GTP_GSN_TIMER_T3_RESPONSE * GTP_GSN_TIMER_N3_REQUESTS) */, .unit = OSMO_TDEF_S,
.desc = "Time a GTP respoonse message is kept cached to re-transmit it when a duplicate request is received. Value is generally equal to (T3-RESPONSE * N3-REQUESTS) set at the peer"
},
{}
};
/* API Functions */
/* Deprecated, use gtp_pdp_newpdp() instead */
int gtp_newpdp(struct gsn_t *gsn, struct pdp_t **pdp,
uint64_t imsi, uint8_t nsapi)
{
int rc;
rc = gtp_pdp_newpdp(gsn, pdp, imsi, nsapi, NULL);
return rc;
}
int gtp_freepdp(struct gsn_t *gsn, struct pdp_t *pdp)
{
if (gsn->cb_delete_context)
gsn->cb_delete_context(pdp);
return pdp_freepdp(pdp);
}
/* Free pdp and all its secondary PDP contexts. Must be called on the primary PDP context. */
int gtp_freepdp_teardown(struct gsn_t *gsn, struct pdp_t *pdp)
{
int n;
struct pdp_t *secondary_pdp;
OSMO_ASSERT(!pdp->secondary);
for (n = 0; n < PDP_MAXNSAPI; n++) {
if (pdp->secondary_tei[n]) {
if (gtp_pdp_getgtp1(gsn, &secondary_pdp,
pdp->secondary_tei[n])) {
LOGP(DLGTP, LOGL_ERROR,
"Unknown secondary PDP context\n");
continue;
}
if (pdp != secondary_pdp) {
gtp_freepdp(gsn, secondary_pdp);
}
}
}
return gtp_freepdp(gsn, pdp);
}
/* gtp_gpdu */
extern int gtp_fd(struct gsn_t *gsn)
{
return gsn->fd0;
}
int gtp_set_cb_unsup_ind(struct gsn_t *gsn,
int (*cb) (struct sockaddr_in * peer))
{
gsn->cb_unsup_ind = cb;
return 0;
}
int gtp_set_cb_extheader_ind(struct gsn_t *gsn,
int (*cb) (struct sockaddr_in * peer))
{
gsn->cb_extheader_ind = cb;
return 0;
}
int gtp_set_cb_ran_info_relay_ind(struct gsn_t *gsn,
int (*cb) (struct sockaddr_in * peer, union gtpie_member **ie))
{
gsn->cb_ran_info_relay_ind = cb;
return 0;
}
/* API: Initialise delete context callback */
/* Called whenever a pdp context is deleted for any reason */
int gtp_set_cb_delete_context(struct gsn_t *gsn, int (*cb) (struct pdp_t * pdp))
{
gsn->cb_delete_context = cb;
return 0;
}
int gtp_set_cb_conf(struct gsn_t *gsn,
int (*cb) (int type, int cause,
struct pdp_t * pdp, void *cbp))
{
gsn->cb_conf = cb;
return 0;
}
int gtp_set_cb_recovery(struct gsn_t *gsn,
int (*cb) (struct sockaddr_in * peer, uint8_t recovery))
{
gsn->cb_recovery = cb;
return 0;
}
/* cb_recovery()
* pdp may be NULL if Recovery IE was received from a message independent
* of any PDP ctx (such as Echo Response), or because pdp ctx is unknown to the
* local setup. In case pdp is known, caller may want to keep that pdp alive to
* handle subsequent msg cb as this specific pdp ctx is still valid according to
* specs.
*/
int gtp_set_cb_recovery2(struct gsn_t *gsn,
int (*cb_recovery2) (struct sockaddr_in * peer, struct pdp_t * pdp, uint8_t recovery))
{
gsn->cb_recovery2 = cb_recovery2;
return 0;
}
/* cb_recovery()
* pdp may be NULL if Recovery IE was received from a message independent
* of any PDP ctx (such as Echo Response), or because pdp ctx is unknown to the
* local setup. In case pdp is known, caller may want to keep that pdp alive to
* handle subsequent msg cb as this specific pdp ctx is still valid according to
* specs.
*/
int gtp_set_cb_recovery3(struct gsn_t *gsn,
int (*cb_recovery3) (struct gsn_t *gsn, struct sockaddr_in *peer,
struct pdp_t *pdp, uint8_t recovery))
{
gsn->cb_recovery3 = cb_recovery3;
return 0;
}
int gtp_set_cb_data_ind(struct gsn_t *gsn,
int (*cb_data_ind) (struct pdp_t * pdp,
void *pack, unsigned len))
{
gsn->cb_data_ind = cb_data_ind;
return 0;
}
static int queue_timer_retrans(struct gsn_t *gsn)
{
/* Retransmit any outstanding packets */
/* Remove from queue if maxretrans exceeded */
time_t now;
struct qmsg_t *qmsg;
unsigned int t3_response, n3_requests;
now = time(NULL);
t3_response = osmo_tdef_get(gsn->tdef, GTP_GSN_TIMER_T3_RESPONSE, OSMO_TDEF_S, -1);
n3_requests = osmo_tdef_get(gsn->tdef, GTP_GSN_TIMER_N3_REQUESTS, OSMO_TDEF_CUSTOM, -1);
/* get first element in queue, as long as the timeout of that
* element has expired */
while ((!queue_getfirst(gsn->queue_req, &qmsg)) &&
(qmsg->timeout <= now)) {
if (qmsg->retrans > n3_requests) { /* Too many retrans */
LOGP(DLGTP, LOGL_NOTICE, "Retransmit req queue timeout of seq %" PRIu16 "\n",
qmsg->seq);
if (gsn->cb_conf)
gsn->cb_conf(qmsg->type, EOF, NULL, qmsg->cbp);
queue_freemsg(gsn->queue_req, qmsg);
} else {
LOGP(DLGTP, LOGL_INFO, "Retransmit (%d) of seq %" PRIu16 "\n",
qmsg->retrans, qmsg->seq);
if (sendto(qmsg->fd, &qmsg->p, qmsg->l, 0,
(struct sockaddr *)&qmsg->peer,
sizeof(struct sockaddr_in)) < 0) {
rate_ctr_inc2(gsn->ctrg, GSN_CTR_ERR_SENDTO);
LOGP(DLGTP, LOGL_ERROR,
"Sendto(fd0=%d, msg=%lx, len=%d) failed: Error = %s\n",
gsn->fd0, (unsigned long)&qmsg->p,
qmsg->l, strerror(errno));
}
queue_back(gsn->queue_req, qmsg);
qmsg->timeout = now + t3_response;
qmsg->retrans++;
}
}
/* Also clean up reply timeouts */
while ((!queue_getfirst(gsn->queue_resp, &qmsg)) &&
(qmsg->timeout < now)) {
LOGP(DLGTP, LOGL_DEBUG, "Retransmit resp queue seq %"
PRIu16 " expired, removing from queue\n", qmsg->seq);
queue_freemsg(gsn->queue_resp, qmsg);
}
return 0;
}
static int queue_timer_retranstimeout(struct gsn_t *gsn, struct timeval *timeout)
{
time_t now, later, diff;
struct qmsg_t *qmsg;
timeout->tv_usec = 0;
if (queue_getfirst(gsn->queue_req, &qmsg)) {
timeout->tv_sec = 10;
} else {
now = time(NULL);
later = qmsg->timeout;
timeout->tv_sec = later - now;
if (timeout->tv_sec < 0)
timeout->tv_sec = 0; /* No negative allowed */
if (timeout->tv_sec > 10)
timeout->tv_sec = 10; /* Max sleep for 10 sec */
}
if (queue_getfirst(gsn->queue_resp, &qmsg)) {
/* already set by queue_req, do nothing */
} else { /* trigger faster if earlier timeout exists in queue_resp */
now = time(NULL);
later = qmsg->timeout;
diff = later - now;
if (diff < 0)
diff = 0;
if (diff < timeout->tv_sec)
timeout->tv_sec = diff;
}
return 0;
}
void gtp_queue_timer_start(struct gsn_t *gsn)
{
struct timeval next;
/* Retrieve next retransmission as timeval */
queue_timer_retranstimeout(gsn, &next);
/* re-schedule the timer */
osmo_timer_schedule(&gsn->queue_timer, next.tv_sec, next.tv_usec/1000);
}
/* timer callback for libgtp retransmission and ping */
static void queue_timer_cb(void *data)
{
struct gsn_t *gsn = data;
/* do all the retransmissions as needed */
queue_timer_retrans(gsn);
gtp_queue_timer_start(gsn);
}
/**
* @brief clear the request and response queue. Useful for debugging to reset "some" state.
* @param gsn The GGSN instance
*/
void gtp_clear_queues(struct gsn_t *gsn)
{
struct qmsg_t *qmsg;
LOGP(DLGTP, LOGL_INFO, "Clearing req & resp retransmit queues\n");
while (!queue_getfirst(gsn->queue_req, &qmsg)) {
queue_freemsg(gsn->queue_req, qmsg);
}
while (!queue_getfirst(gsn->queue_resp, &qmsg)) {
queue_freemsg(gsn->queue_resp, qmsg);
}
}
/* Perform restoration and recovery error handling as described in 29.060 */
static void log_restart(struct gsn_t *gsn)
{
FILE *f;
int i, rc;
int counter = 0;
char *filename;
filename = talloc_asprintf(NULL, "%s/%s", gsn->statedir, RESTART_FILE);
OSMO_ASSERT(filename);
/* We try to open file. On failure we will later try to create file */
if (!(f = fopen(filename, "r"))) {
LOGP(DLGTP, LOGL_NOTICE,
"State information file (%s) not found. Creating new file.\n",
filename);
} else {
rc = fscanf(f, "%d", &counter);
if (rc != 1) {
LOGP(DLGTP, LOGL_ERROR,
"fscanf failed to read counter value\n");
goto close_file;
}
if (fclose(f)) {
LOGP(DLGTP, LOGL_ERROR,
"fclose failed: Error = %s\n", strerror(errno));
}
}
gsn->restart_counter = (unsigned char)counter;
gsn->restart_counter++;
/* Keep the umask closely wrapped around our fopen() call in case the
* log outputs cause file creation. */
i = umask(022);
f = fopen(filename, "w");
umask(i);
if (!f) {
LOGP(DLGTP, LOGL_ERROR,
"fopen(path=%s, mode=%s) failed: Error = %s\n", filename,
"w", strerror(errno));
goto free_filename;
}
fprintf(f, "%d\n", gsn->restart_counter);
close_file:
if (fclose(f))
LOGP(DLGTP, LOGL_ERROR,
"fclose failed: Error = %s\n", strerror(errno));
free_filename:
talloc_free(filename);
}
static int create_and_bind_socket(const char *name, struct gsn_t *gsn, int *fd, int domain,
const struct in_addr *listen, int port)
{
struct sockaddr_in addr;
int type = SOCK_DGRAM;
int protocol = 0;
*fd = socket(domain, type, protocol);
if (*fd < 0) {
rate_ctr_inc2(gsn->ctrg, GSN_CTR_ERR_SOCKET);
LOGP(DLGTP, LOGL_ERROR,
"%s socket(domain=%d, type=%d, protocol=%d) failed: Error = %s\n",
name, domain, type, protocol, strerror(errno));
return -errno;
}
memset(&addr, 0, sizeof(addr));
addr.sin_family = domain;
addr.sin_addr = *listen;
addr.sin_port = htons(port);
#if defined(__FreeBSD__) || defined(__APPLE__)
addr.sin_len = sizeof(addr);
#endif
if (bind(*fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
rate_ctr_inc2(gsn->ctrg, GSN_CTR_ERR_SOCKET);
LOGP_WITH_ADDR(DLGTP, LOGL_ERROR, addr,
"%s bind(fd=%d) failed: Error = %s\n",
name, *fd, strerror(errno));
return -errno;
}
return 0;
}
int gtp_new(struct gsn_t **gsn, char *statedir, struct in_addr *listen,
int mode)
{
LOGP(DLGTP, LOGL_NOTICE, "GTP: gtp_newgsn() started at %s\n", inet_ntoa(*listen));
*gsn = calloc(sizeof(struct gsn_t), 1); /* TODO */
(*gsn)->statedir = statedir;
log_restart(*gsn);
/* Initialise sequence number */
(*gsn)->seq_next = (*gsn)->restart_counter * 1024;
/* Initialize timers: */
(*gsn)->tdef = gtp_T_defs;
/* Small hack to properly reset tdef for old clients not using the tdef_group: */
OSMO_ASSERT(gtp_T_defs[0].default_val != 0);
if (gtp_T_defs[0].val == 0)
osmo_tdefs_reset((*gsn)->tdef);
/* Initialise request retransmit queue */
queue_new(&(*gsn)->queue_req);
queue_new(&(*gsn)->queue_resp);
/* Initialise pdp table */
pdp_init(*gsn);
/* Initialize internal queue timer */
osmo_timer_setup(&(*gsn)->queue_timer, queue_timer_cb, *gsn);
/* Initialize counter group: */
(*gsn)->ctrg = rate_ctr_group_alloc(NULL, &gsn_ctrg_desc, gsn_ctr_next_idx++);
/* Initialise call back functions */
(*gsn)->cb_create_context_ind = 0;
(*gsn)->cb_delete_context = 0;
(*gsn)->cb_unsup_ind = 0;
(*gsn)->cb_conf = 0;
(*gsn)->cb_data_ind = 0;
/* Store function parameters */
/* Same IP for user traffic and signalling */
(*gsn)->gsnc = *listen;
(*gsn)->gsnu = *listen;
(*gsn)->mode = mode;
(*gsn)->fd0 = -1;
(*gsn)->fd1c = -1;
(*gsn)->fd1u = -1;
/* Create GTP version 0 socket */
if (create_and_bind_socket("GTPv0", *gsn, &(*gsn)->fd0, AF_INET, listen, GTP0_PORT) < 0)
goto error;
/* Create GTP version 1 control plane socket */
if (create_and_bind_socket("GTPv1 control plane", *gsn, &(*gsn)->fd1c, AF_INET, listen, GTP1C_PORT) < 0)
goto error;
/* Create GTP version 1 user plane socket */
if (create_and_bind_socket("GTPv1 user plane", *gsn, &(*gsn)->fd1u, AF_INET, listen, GTP1U_PORT) < 0)
goto error;
/* Start internal queue timer */
gtp_queue_timer_start(*gsn);
return 0;
error:
gtp_free(*gsn);
*gsn = NULL;
return -1;
}
int gtp_free(struct gsn_t *gsn)
{
/* Cleanup internal queue timer */
osmo_timer_del(&gsn->queue_timer);
/* Clean up retransmit queues */
queue_free(gsn->queue_req);
queue_free(gsn->queue_resp);
close(gsn->fd0);
close(gsn->fd1c);
close(gsn->fd1u);
rate_ctr_group_free(gsn->ctrg);
free(gsn);
return 0;
}
/* API: Register create context indication callback */
int gtp_set_cb_create_context_ind(struct gsn_t *gsn,
int (*cb_create_context_ind) (struct pdp_t *
pdp))
{
gsn->cb_create_context_ind = cb_create_context_ind;
return 0;
}
int gtp_retrans(struct gsn_t *gsn)
{
/* dummy API, deprecated. */
return 0;
}
int gtp_retranstimeout(struct gsn_t *gsn, struct timeval *timeout)
{
timeout->tv_sec = 24*60*60;
timeout->tv_usec = 0;
/* dummy API, deprecated. Return a huge timer to do nothing */
return 0;
}

3
gtp/gsn_internal.h Normal file
View File

@ -0,0 +1,3 @@
#pragma once
void gtp_queue_timer_start(struct gsn_t *gsn);

880
gtp/gtp.c

File diff suppressed because it is too large Load Diff

3
gtp/gtp_internal.h Normal file
View File

@ -0,0 +1,3 @@
#pragma once
uint64_t gtp_imsi_str2gtp(const char *str);

View File

@ -37,7 +37,7 @@
#include <netinet/in.h>
#include <string.h>
#include "gtpie.h"
#include <osmocom/gtp/gtpie.h>
/*! Encode a TLV type Information Element.
* \param[inout] p Pointer to output packet to which IE is appended

View File

@ -28,8 +28,10 @@
#include <netinet/in.h>
#include <string.h>
#include <inttypes.h>
#include "pdp.h"
#include "gtp.h"
#include <osmocom/gtp/pdp.h>
#include <osmocom/gtp/gtp.h>
#include "lookupa.h"
#include "queue.h"

View File

@ -27,8 +27,10 @@
#include <sys/time.h>
#include <netinet/in.h>
#include <string.h>
#include "pdp.h"
#include "gtp.h"
#include <osmocom/gtp/pdp.h>
#include <osmocom/gtp/gtp.h>
#include "queue.h"
/*! \brief dump a queue_t to stdout */

View File

@ -19,7 +19,7 @@
#include <osmocom/core/linuxlist.h>
#include "gtp.h"
#include <osmocom/gtp/gtp.h>
#define QUEUE_DEBUG 0 /* Print debug information */

3
include/Makefile.am Normal file
View File

@ -0,0 +1,3 @@
SUBDIRS = \
osmocom \
$(NULL)

View File

@ -0,0 +1,3 @@
SUBDIRS = \
gtp \
$(NULL)

View File

@ -0,0 +1,8 @@
libgtp_HEADERS = \
gsn.h \
gtp.h \
gtpie.h \
pdp.h \
$(NULL)
libgtpdir = $(includedir)/osmocom/gtp

178
include/osmocom/gtp/gsn.h Normal file
View File

@ -0,0 +1,178 @@
/*
* OsmoGGSN - Gateway GPRS Support Node
* Copyright (C) 2002, 2003, 2004 Mondru AB.
*
* The contents of this file may be used under the terms of the GNU
* General Public License Version 2, provided that the above copyright
* notice and this permission notice is included in all copies or
* substantial portions of the software.
*
*/
#ifndef _GSN_H
#define _GSN_H
#include <osmocom/core/utils.h>
#include <osmocom/core/defs.h>
#include <osmocom/core/timer.h>
#include <osmocom/core/tdef.h>
#include <osmocom/core/rate_ctr.h>
#include "pdp.h"
#define GTP_MODE_GGSN 1
#define GTP_MODE_SGSN 2
#define RESTART_FILE "gsn_restart"
extern struct osmo_tdef gtp_T_defs[];
/* ***********************************************************
* Information storage for each gsn instance
*
* Normally each instance of the application corresponds to
* one instance of a gsn.
*
* In order to avoid global variables in the application, and
* also in order to allow several instances of a gsn in the same
* application this struct is provided in order to store all
* relevant information related to the gsn.
*
* Note that this does not include information storage for '
* each pdp context. This is stored in another struct.
*************************************************************/
enum gsn_rate_ctr_keys {
GSN_CTR_ERR_SOCKET,
GSN_CTR_ERR_READFROM, /* Number of readfrom errors */
GSN_CTR_ERR_SENDTO, /* Number of sendto errors */
GSN_CTR_ERR_QUEUEFULL, /* Number of times queue was full */
GSN_CTR_ERR_SEQ, /* Number of seq out of range */
GSN_CTR_ERR_ADDRESS, /* GSN address conversion failed */
GSN_CTR_ERR_UNKNOWN_PDP, /* GSN address conversion failed */
GSN_CTR_ERR_UNEXPECTED_CAUSE, /* Unexpected cause value received */
GSN_CTR_ERR_OUT_OF_PDP, /* Out of storage for PDP contexts */
GSN_CTR_PKT_EMPTY, /* Number of empty packets */
GSN_CTR_PKT_UNSUP, /* Number of unsupported version 29.60 11.1.1 */
GSN_CTR_PKT_TOOSHORT, /* Number of too short headers 29.60 11.1.2 */
GSN_CTR_PKT_UNKNOWN, /* Number of unknown messages 29.60 11.1.3 */
GSN_CTR_PKT_UNEXPECT, /* Number of unexpected messages 29.60 11.1.4 */
GSN_CTR_PKT_DUPLICATE, /* Number of duplicate or unsolicited replies */
GSN_CTR_PKT_MISSING, /* Number of missing information field messages */
GSN_CTR_PKT_INCORRECT, /* Number of incorrect information field messages */
GSN_CTR_PKT_INVALID, /* Number of invalid message format messages */
};
/* 3GPP TS 29.006 14.1, 14,2 */
enum gtp_gsn_timers {
GTP_GSN_TIMER_T3_RESPONSE = 3,
GTP_GSN_TIMER_N3_REQUESTS = 1003,
GTP_GSN_TIMER_T3_HOLD_RESPONSE = -3,
};
struct gsn_t {
/* Parameters related to the network interface */
int fd0; /* GTP0 file descriptor */
int fd1c; /* GTP1 control plane file descriptor */
int fd1u; /* GTP0 user plane file descriptor */
int mode; /* Mode of operation: GGSN or SGSN */
struct in_addr gsnc; /* IP address of this gsn for signalling */
struct in_addr gsnu; /* IP address of this gsn for user traffic */
/* Parameters related to signalling messages */
uint16_t seq_next; /* Next sequence number to use */
int seq_first; /* First packet in queue (oldest timeout) */
int seq_last; /* Last packet in queue (youngest timeout) */
unsigned char restart_counter; /* Increment on restart. Stored on disk */
char *statedir; /* Disk location for permanent storage */
void *priv; /* used by libgtp users to attach their own state) */
struct queue_t *queue_req; /* Request queue */
struct queue_t *queue_resp; /* Response queue */
struct pdp_t pdpa[PDP_MAX]; /* PDP storage */
struct pdp_t *hashtid[PDP_MAX]; /* Hash table for IMSI + NSAPI */
struct osmo_timer_list queue_timer; /* internal queue_{req,resp} timer */
/* Call back functions */
int (*cb_delete_context) (struct pdp_t *);
int (*cb_create_context_ind) (struct pdp_t *);
int (*cb_unsup_ind) (struct sockaddr_in * peer);
int (*cb_extheader_ind) (struct sockaddr_in * peer);
int (*cb_ran_info_relay_ind) (struct sockaddr_in *peer, union gtpie_member **ie);
int (*cb_conf) (int type, int cause, struct pdp_t * pdp, void *cbp);
int (*cb_data_ind) (struct pdp_t * pdp, void *pack, unsigned len);
int (*cb_recovery) (struct sockaddr_in * peer, uint8_t recovery);
int (*cb_recovery2) (struct sockaddr_in * peer, struct pdp_t * pdp, uint8_t recovery);
int (*cb_recovery3) (struct gsn_t *gsn, struct sockaddr_in *peer, struct pdp_t *pdp, uint8_t recovery);
/* Counters */
struct rate_ctr_group *ctrg;
/* Timers: */
struct osmo_tdef *tdef;
};
/* External API functions */
extern int gtp_new(struct gsn_t **gsn, char *statedir, struct in_addr *listen,
int mode);
extern int gtp_free(struct gsn_t *gsn);
extern int gtp_newpdp(struct gsn_t *gsn, struct pdp_t **pdp,
uint64_t imsi, uint8_t nsapi) OSMO_DEPRECATED("Use gtp_pdp_newpdp() instead");
extern int gtp_freepdp(struct gsn_t *gsn, struct pdp_t *pdp);
extern int gtp_freepdp_teardown(struct gsn_t *gsn, struct pdp_t *pdp);
extern int gtp_create_context_req(struct gsn_t *gsn, struct pdp_t *pdp,
void *cbp);
extern int gtp_set_cb_create_context_ind(struct gsn_t *gsn,
int (*cb_create_context_ind) (struct
pdp_t *
pdp));
extern int gtp_set_cb_data_ind(struct gsn_t *gsn,
int (*cb_data_ind) (struct pdp_t * pdp,
void *pack, unsigned len));
extern int gtp_set_cb_delete_context(struct gsn_t *gsn,
int (*cb_delete_context) (struct pdp_t *
pdp));
/*extern int gtp_set_cb_create_context(struct gsn_t *gsn,
int (*cb_create_context) (struct pdp_t* pdp)); */
extern int gtp_set_cb_unsup_ind(struct gsn_t *gsn,
int (*cb) (struct sockaddr_in * peer));
extern int gtp_set_cb_extheader_ind(struct gsn_t *gsn,
int (*cb) (struct sockaddr_in * peer));
extern int gtp_set_cb_ran_info_relay_ind(struct gsn_t *gsn,
int (*cb) (struct sockaddr_in * peer, union gtpie_member **ie));
extern int gtp_set_cb_conf(struct gsn_t *gsn,
int (*cb) (int type, int cause, struct pdp_t * pdp,
void *cbp));
int gtp_set_cb_recovery(struct gsn_t *gsn,
int (*cb) (struct sockaddr_in * peer,
uint8_t recovery))
OSMO_DEPRECATED("Use gtp_set_cb_recovery2() instead, to obtain pdp ctx originating the recovery");
int gtp_set_cb_recovery2(struct gsn_t *gsn,
int (*cb) (struct sockaddr_in * peer,
struct pdp_t * pdp,
uint8_t recovery))
OSMO_DEPRECATED("Use gtp_set_cb_recovery3() instead, to obtain gsn handling the recovery");
int gtp_set_cb_recovery3(struct gsn_t *gsn,
int (*cb) (struct gsn_t * gsn, struct sockaddr_in * peer,
struct pdp_t * pdp,
uint8_t recovery));
void gtp_clear_queues(struct gsn_t *gsn);
extern int gtp_fd(struct gsn_t *gsn);
extern int gtp_retrans(struct gsn_t *gsn) OSMO_DEPRECATED("This API is a no-op, libgtp already does the job internally");
extern int gtp_retranstimeout(struct gsn_t *gsn, struct timeval *timeout) OSMO_DEPRECATED("This API is a no-op and will return a 1 day timeout");
#endif /* !_GSN_H */

View File

@ -13,14 +13,10 @@
#define _GTP_H
#include <osmocom/core/utils.h>
#include <osmocom/core/defs.h>
#include <osmocom/core/timer.h>
#include "gtpie.h"
#include "pdp.h"
#define GTP_MODE_GGSN 1
#define GTP_MODE_SGSN 2
#include "gsn.h"
#define GTP0_PORT 3386
#define GTP1C_PORT 2123
@ -32,12 +28,10 @@
#define GTP1_HEADER_SIZE_SHORT 8
#define GTP1_HEADER_SIZE_LONG 12
#define NAMESIZE 1024
#define SYSLOG_PRINTSIZE 255
#define ERRMSG_SIZE 255
#define RESTART_FILE "gsn_restart"
#define NAMESIZE 1024
/* GTP version 1 extension header type definitions. */
#define GTP_EXT_PDCP_PDU 0xC0 /* PDCP PDU Number */
@ -59,7 +53,7 @@
#define GTP_UPDATE_PDP_RSP 19 /* Update PDP Context Response */
#define GTP_DELETE_PDP_REQ 20 /* Delete PDP Context Request */
#define GTP_DELETE_PDP_RSP 21 /* Delete PDP Context Response */
/* 22-25 For future use. *//* In version GTP 1 anonomous PDP context */
/* 22-25 For future use. *//* In version GTP 1 anonomous PDP context */
#define GTP_ERROR 26 /* Error Indication */
#define GTP_PDU_NOT_REQ 27 /* PDU Notification Request */
#define GTP_PDU_NOT_RSP 28 /* PDU Notification Response */
@ -105,19 +99,21 @@ static inline const char *gtp_type_name(uint8_t val)
#define GTPCAUSE_NO_ID_NEEDED 3 /* No identity needed */
#define GTPCAUSE_MS_REFUSES_X 4 /* MS refuses */
#define GTPCAUSE_MS_NOT_RESP_X 5 /* MS is not GPRS responding */
#define GTPCAUSE_006 6 /* For future use 6-48 */
#define GTPCAUSE_049 49 /* Cause values reserved for GPRS charging protocol use (See GTP' in GSM 12.15) 49-63 */
#define GTPCAUSE_064 64 /* For future use 64-127 */
/* 6-48 For future use */
/* 49-63 Cause values reserved for GPRS charging protocol use (See GTP' in GSM 12.15) */
/* 64-127 For future use */
#define GTPCAUSE_ACC_REQ 128 /* Request accepted */
#define GTPCAUSE_129 129 /* For future use 129-176 */
#define GTPCAUSE_177 177 /* Cause values reserved for GPRS charging protocol use (See GTP' In GSM 12.15) 177-191 */
#define GTPCAUSE_NEW_PDP_NET_PREF 129 /* New PDP type due to network preference */
#define GTPCAUSE_NEW_PDP_ADDR_BEAR 130 /* New PDP type due to single address bearer only */
/* 131-176 For future use */
/* 177-191 Cause values reserved for GPRS charging protocol use (See GTP' In GSM 12.15) */
#define GTPCAUSE_NON_EXIST 192 /* Non-existent */
#define GTPCAUSE_INVALID_MESSAGE 193 /* Invalid message format */
#define GTPCAUSE_IMSI_NOT_KNOWN 194 /* IMSI not known */
#define GTPCAUSE_MS_DETACHED 195 /* MS is GPRS detached */
#define GTPCAUSE_MS_NOT_RESP 196 /* MS is not GPRS responding */
#define GTPCAUSE_MS_REFUSES 197 /* MS refuses */
#define GTPCAUSE_198 198 /* For future use */
/* 198 For future use */
#define GTPCAUSE_NO_RESOURCES 199 /* No resources available */
#define GTPCAUSE_NOT_SUPPORTED 200 /* Service not supported */
#define GTPCAUSE_MAN_IE_INCORRECT 201 /* Mandatory IE incorrect */
@ -140,8 +136,15 @@ static inline const char *gtp_type_name(uint8_t val)
#define GTPCAUSE_SYN_ERR_FILTER 218 /* Syntactic errors in packet filter(s) */
#define GTPCAUSE_MISSING_APN 219 /* Missing or unknown APN */
#define GTPCAUSE_UNKNOWN_PDP 220 /* Unknown PDP address or PDP type */
#define GTPCAUSE_221 221 /* For Future Use 221-240 */
#define GTPCAUSE_241 241 /* Cause Values Reserved For Gprs Charging Protocol Use (See Gtp' In Gsm 12.15) 241-255 */
/* 221-240 For future use */
/* 241-255 Cause Values Reserved For Gprs Charging Protocol Use (See Gtp' In Gsm 12.15) */
static inline bool gtp_cause_successful(uint8_t cause)
{
return cause == GTPCAUSE_ACC_REQ ||
cause == GTPCAUSE_NEW_PDP_NET_PREF ||
cause == GTPCAUSE_NEW_PDP_ADDR_BEAR;
}
struct ul66_t;
struct ul16_t;
@ -232,105 +235,13 @@ union gtp_packet {
struct gtp1_packet_long gtp1l;
} __attribute__ ((packed));
/* ***********************************************************
* Information storage for each gsn instance
*
* Normally each instance of the application corresponds to
* one instance of a gsn.
*
* In order to avoid global variables in the application, and
* also in order to allow several instances of a gsn in the same
* application this struct is provided in order to store all
* relevant information related to the gsn.
*
* Note that this does not include information storage for '
* each pdp context. This is stored in another struct.
*************************************************************/
struct gsn_t {
/* Parameters related to the network interface */
int fd0; /* GTP0 file descriptor */
int fd1c; /* GTP1 control plane file descriptor */
int fd1u; /* GTP0 user plane file descriptor */
int mode; /* Mode of operation: GGSN or SGSN */
struct in_addr gsnc; /* IP address of this gsn for signalling */
struct in_addr gsnu; /* IP address of this gsn for user traffic */
/* Parameters related to signalling messages */
uint16_t seq_next; /* Next sequence number to use */
int seq_first; /* First packet in queue (oldest timeout) */
int seq_last; /* Last packet in queue (youngest timeout) */
unsigned char restart_counter; /* Increment on restart. Stored on disk */
char *statedir; /* Disk location for permanent storage */
void *priv; /* used by libgtp users to attach their own state) */
struct queue_t *queue_req; /* Request queue */
struct queue_t *queue_resp; /* Response queue */
struct pdp_t pdpa[PDP_MAX]; /* PDP storage */
struct pdp_t *hashtid[PDP_MAX]; /* Hash table for IMSI + NSAPI */
struct osmo_timer_list queue_timer; /* internal queue_{req,resp} timer */
/* Call back functions */
int (*cb_delete_context) (struct pdp_t *);
int (*cb_create_context_ind) (struct pdp_t *);
int (*cb_unsup_ind) (struct sockaddr_in * peer);
int (*cb_extheader_ind) (struct sockaddr_in * peer);
int (*cb_ran_info_relay_ind) (struct sockaddr_in *peer, union gtpie_member **ie);
int (*cb_conf) (int type, int cause, struct pdp_t * pdp, void *cbp);
int (*cb_data_ind) (struct pdp_t * pdp, void *pack, unsigned len);
int (*cb_recovery) (struct sockaddr_in * peer, uint8_t recovery);
int (*cb_recovery2) (struct sockaddr_in * peer, struct pdp_t * pdp, uint8_t recovery);
int (*cb_recovery3) (struct gsn_t *gsn, struct sockaddr_in *peer, struct pdp_t *pdp, uint8_t recovery);
/* Counters */
uint64_t err_socket; /* Number of socket errors */
uint64_t err_readfrom; /* Number of readfrom errors */
uint64_t err_sendto; /* Number of sendto errors */
uint64_t err_memcpy; /* Number of memcpy */
uint64_t err_queuefull; /* Number of times queue was full */
uint64_t err_seq; /* Number of seq out of range */
uint64_t err_address; /* GSN address conversion failed */
uint64_t err_unknownpdp; /* GSN address conversion failed */
uint64_t err_unknowntid; /* Application supplied unknown imsi+nsapi */
uint64_t err_cause; /* Unexpected cause value received */
uint64_t err_outofpdp; /* Out of storage for PDP contexts */
uint64_t empty; /* Number of empty packets */
uint64_t unsup; /* Number of unsupported version 29.60 11.1.1 */
uint64_t tooshort; /* Number of too short headers 29.60 11.1.2 */
uint64_t unknown; /* Number of unknown messages 29.60 11.1.3 */
uint64_t unexpect; /* Number of unexpected messages 29.60 11.1.4 */
uint64_t duplicate; /* Number of duplicate or unsolicited replies */
uint64_t missing; /* Number of missing information field messages */
uint64_t incorrect; /* Number of incorrect information field messages */
uint64_t invalid; /* Number of invalid message format messages */
};
/* External API functions */
extern const char *gtp_version();
extern int gtp_new(struct gsn_t **gsn, char *statedir, struct in_addr *listen,
int mode);
extern int gtp_free(struct gsn_t *gsn);
extern int gtp_newpdp(struct gsn_t *gsn, struct pdp_t **pdp,
uint64_t imsi, uint8_t nsapi) OSMO_DEPRECATED("Use gtp_pdp_newpdp() instead");
extern int gtp_freepdp(struct gsn_t *gsn, struct pdp_t *pdp);
extern int gtp_freepdp_teardown(struct gsn_t *gsn, struct pdp_t *pdp);
extern int gtp_create_context_req(struct gsn_t *gsn, struct pdp_t *pdp,
void *cbp);
extern int gtp_set_cb_create_context_ind(struct gsn_t *gsn,
int (*cb_create_context_ind) (struct
pdp_t *
pdp));
extern int gtp_create_context_resp(struct gsn_t *gsn, struct pdp_t *pdp,
int cause);
@ -351,107 +262,15 @@ extern int gtp_ran_info_relay_req(struct gsn_t *gsn, const struct sockaddr_in *p
const uint8_t *rim_route_addr, size_t rim_route_addr_len,
uint8_t rim_route_addr_discr);
extern int gtp_set_cb_data_ind(struct gsn_t *gsn,
int (*cb_data_ind) (struct pdp_t * pdp,
void *pack, unsigned len));
extern int gtp_fd(struct gsn_t *gsn);
extern int gtp_decaps0(struct gsn_t *gsn);
extern int gtp_decaps1c(struct gsn_t *gsn);
extern int gtp_decaps1u(struct gsn_t *gsn);
extern int gtp_retrans(struct gsn_t *gsn) OSMO_DEPRECATED("This API is a no-op, libgtp already does the job internally");
extern int gtp_retranstimeout(struct gsn_t *gsn, struct timeval *timeout) OSMO_DEPRECATED("This API is a no-op and will return a 1 day timeout");
extern int gtp_set_cb_delete_context(struct gsn_t *gsn,
int (*cb_delete_context) (struct pdp_t *
pdp));
/*extern int gtp_set_cb_create_context(struct gsn_t *gsn,
int (*cb_create_context) (struct pdp_t* pdp)); */
extern int gtp_set_cb_unsup_ind(struct gsn_t *gsn,
int (*cb) (struct sockaddr_in * peer));
extern int gtp_set_cb_extheader_ind(struct gsn_t *gsn,
int (*cb) (struct sockaddr_in * peer));
extern int gtp_set_cb_ran_info_relay_ind(struct gsn_t *gsn,
int (*cb) (struct sockaddr_in * peer, union gtpie_member **ie));
extern int gtp_set_cb_conf(struct gsn_t *gsn,
int (*cb) (int type, int cause, struct pdp_t * pdp,
void *cbp));
int gtp_set_cb_recovery(struct gsn_t *gsn,
int (*cb) (struct sockaddr_in * peer,
uint8_t recovery))
OSMO_DEPRECATED("Use gtp_set_cb_recovery2() instead, to obtain pdp ctx originating the recovery");
int gtp_set_cb_recovery2(struct gsn_t *gsn,
int (*cb) (struct sockaddr_in * peer,
struct pdp_t * pdp,
uint8_t recovery))
OSMO_DEPRECATED("Use gtp_set_cb_recovery3() instead, to obtain gsn handling the recovery");;
int gtp_set_cb_recovery3(struct gsn_t *gsn,
int (*cb) (struct gsn_t * gsn, struct sockaddr_in * peer,
struct pdp_t * pdp,
uint8_t recovery));
void gtp_clear_queues(struct gsn_t *gsn);
/* Internal functions (not part of the API */
extern int gtp_echo_req(struct gsn_t *gsn, int version, void *cbp,
struct in_addr *inetaddrs);
extern int gtp_echo_resp(struct gsn_t *gsn, int version,
struct sockaddr_in *peer, int fd,
void *pack, unsigned len);
extern int gtp_echo_ind(struct gsn_t *gsn, int version,
struct sockaddr_in *peer, int fd,
void *pack, unsigned len);
extern int gtp_echo_conf(struct gsn_t *gsn, int version,
struct sockaddr_in *peer, void *pack, unsigned len);
extern int gtp_unsup_req(struct gsn_t *gsn, int version,
struct sockaddr_in *peer,
int fd, void *pack, unsigned len);
extern int gtp_unsup_ind(struct gsn_t *gsn, struct sockaddr_in *peer,
void *pack, unsigned len);
extern int gtp_create_pdp_resp(struct gsn_t *gsn, int version,
struct pdp_t *pdp, uint8_t cause);
extern int gtp_create_pdp_ind(struct gsn_t *gsn, int version,
struct sockaddr_in *peer, int fd,
void *pack, unsigned len);
extern int gtp_create_pdp_conf(struct gsn_t *gsn, int version,
struct sockaddr_in *peer,
void *pack, unsigned len);
extern int gtp_update_pdp_req(struct gsn_t *gsn, int version, void *cbp,
struct in_addr *inetaddr, struct pdp_t *pdp);
extern int gtp_delete_pdp_req(struct gsn_t *gsn, int version, void *cbp,
struct pdp_t *pdp);
extern int gtp_delete_pdp_resp(struct gsn_t *gsn, int version,
struct sockaddr_in *peer, int fd,
void *pack, unsigned len,
struct pdp_t *pdp, struct pdp_t *linked_pdp,
uint8_t cause, int teardown);
extern int gtp_delete_pdp_ind(struct gsn_t *gsn, int version,
struct sockaddr_in *peer, int fd,
void *pack, unsigned len);
extern int gtp_delete_pdp_conf(struct gsn_t *gsn, int version,
struct sockaddr_in *peer,
void *pack, unsigned len);
extern int ipv42eua(struct ul66_t *eua, struct in_addr *src);
extern int eua2ipv4(struct in_addr *dst, struct ul66_t *eua);
extern int gsna2in_addr(struct in_addr *dst, struct ul16_t *gsna);
extern int in_addr2gsna(struct ul16_t *gsna, struct in_addr *src);
extern const char *imsi_gtp2str(const uint64_t *imsi);
extern uint64_t gtp_imsi_str2gtp(const char *str);
#endif /* !_GTP_H */

View File

@ -1,10 +1,42 @@
noinst_LIBRARIES = libmisc.a
noinst_HEADERS = gnugetopt.h ippool.h lookup.h syserr.h tun.h in46_addr.h netdev.h gtp-kernel.h netns.h util.h icmpv6.h checksum.h
noinst_HEADERS = \
checksum.h \
gnugetopt.h \
gtp-kernel.h \
icmpv6.h \
in46_addr.h \
ippool.h \
lookup.h \
netdev.h \
netns.h \
syserr.h \
tun.h \
util.h \
$(NULL)
AM_CFLAGS = -O2 -fno-builtin -Wall -DSBINDIR='"$(sbindir)"' -ggdb $(LIBOSMOCORE_CFLAGS)
AM_CFLAGS = \
-fno-builtin \
-Wall \
-DSBINDIR='"$(sbindir)"' \
-I$(top_srcdir)/include \
$(LIBOSMOCORE_CFLAGS) \
$(NULL)
libmisc_a_SOURCES = getopt1.c getopt.c ippool.c lookup.c tun.c debug.c in46_addr.c netdev.c netns.c util.c icmpv6.c checksum.c
libmisc_a_SOURCES = \
checksum.c \
debug.c \
getopt.c \
getopt1.c \
icmpv6.c \
in46_addr.c \
ippool.c \
lookup.c \
netdev.c \
netns.c \
tun.c \
util.c \
$(NULL)
if ENABLE_GTP_KERNEL
AM_CFLAGS += -DGTP_KERNEL $(LIBGTPNL_CFLAGS)

View File

@ -23,12 +23,13 @@
#include <time.h>
#include <osmocom/gtp/pdp.h>
#include <osmocom/gtp/gtp.h>
#include "../lib/tun.h"
#include "../lib/syserr.h"
#include "../lib/util.h"
#include "../lib/ippool.h"
#include "../gtp/pdp.h"
#include "../gtp/gtp.h"
#include "gtp-kernel.h"
@ -104,61 +105,97 @@ void gtp_kernel_stop(const char *devname)
int gtp_kernel_tunnel_add(struct pdp_t *pdp, const char *devname)
{
struct in_addr ms, sgsn;
int ms_addr_count;
struct in46_addr ms[2];
struct in46_addr sgsn;
struct gtp_tunnel *t;
int ret;
int ret = 0;
pdp_debug(__func__, devname, pdp);
t = gtp_tunnel_alloc();
if (t == NULL)
in46a_from_gsna(&pdp->gsnrc, &sgsn);
ms_addr_count = in46a_from_eua(&pdp->eua, ms);
if (ms_addr_count < 0)
return -1;
memcpy(&ms, &pdp->eua.v[2], sizeof(struct in_addr));
memcpy(&sgsn, &pdp->gsnrc.v[0], sizeof(struct in_addr));
for (int i = 0; i < ms_addr_count; i++) {
t = gtp_tunnel_alloc();
if (t == NULL)
return -1;
gtp_tunnel_set_ifidx(t, if_nametoindex(devname));
gtp_tunnel_set_version(t, pdp->version);
gtp_tunnel_set_ms_ip4(t, &ms);
gtp_tunnel_set_sgsn_ip4(t, &sgsn);
if (pdp->version == 0) {
gtp_tunnel_set_tid(t, pdp_gettid(pdp->imsi, pdp->nsapi));
gtp_tunnel_set_flowid(t, pdp->flru);
} else {
gtp_tunnel_set_i_tei(t, pdp->teid_own);
/* use the TEI advertised by SGSN when sending packets
* towards the SGSN */
gtp_tunnel_set_o_tei(t, pdp->teid_gn);
gtp_tunnel_set_ifidx(t, if_nametoindex(devname));
gtp_tunnel_set_version(t, pdp->version);
if (in46a_to_af(&ms[i]) == AF_INET)
gtp_tunnel_set_ms_ip4(t, &ms[i].v4);
else {
/* In IPv6, EUA doesn't contain the actual IP
* addr/prefix. Set higher bits to 0 to get the 64 bit
* netmask. */
memset(((void *)&ms[i].v6) + 8, 0, 8);
gtp_tunnel_set_ms_ip6(t, &ms[i].v6);
}
if (in46a_to_af(&sgsn) == AF_INET)
gtp_tunnel_set_sgsn_ip4(t, &sgsn.v4);
else
gtp_tunnel_set_sgsn_ip6(t, &sgsn.v6);
if (pdp->version == 0) {
gtp_tunnel_set_tid(t, pdp_gettid(pdp->imsi, pdp->nsapi));
gtp_tunnel_set_flowid(t, pdp->flru);
} else {
gtp_tunnel_set_i_tei(t, pdp->teid_own);
/* use the TEI advertised by SGSN when sending packets
* towards the SGSN */
gtp_tunnel_set_o_tei(t, pdp->teid_gn);
}
ret = gtp_add_tunnel(gtp_nl.genl_id, gtp_nl.nl, t);
gtp_tunnel_free(t);
if (ret != 0)
break;
}
ret = gtp_add_tunnel(gtp_nl.genl_id, gtp_nl.nl, t);
gtp_tunnel_free(t);
return ret;
}
int gtp_kernel_tunnel_del(struct pdp_t *pdp, const char *devname)
{
int ms_addr_count;
struct in46_addr ms[2];
struct gtp_tunnel *t;
int ret;
int ret = 0;
pdp_debug(__func__, devname, pdp);
t = gtp_tunnel_alloc();
if (t == NULL)
ms_addr_count = in46a_from_eua(&pdp->eua, ms);
if (ms_addr_count < 0)
return -1;
gtp_tunnel_set_ifidx(t, if_nametoindex(devname));
gtp_tunnel_set_version(t, pdp->version);
if (pdp->version == 0) {
gtp_tunnel_set_tid(t, pdp_gettid(pdp->imsi, pdp->nsapi));
gtp_tunnel_set_flowid(t, pdp->flru);
} else {
gtp_tunnel_set_i_tei(t, pdp->teid_own);
}
for (int i = 0; i < ms_addr_count; i++) {
t = gtp_tunnel_alloc();
if (t == NULL)
return -1;
ret = gtp_del_tunnel(gtp_nl.genl_id, gtp_nl.nl, t);
gtp_tunnel_free(t);
gtp_tunnel_set_ifidx(t, if_nametoindex(devname));
gtp_tunnel_set_family(t, in46a_to_af(&ms[i]));
gtp_tunnel_set_version(t, pdp->version);
if (pdp->version == 0) {
gtp_tunnel_set_tid(t, pdp_gettid(pdp->imsi, pdp->nsapi));
gtp_tunnel_set_flowid(t, pdp->flru);
} else {
gtp_tunnel_set_i_tei(t, pdp->teid_own);
}
ret = gtp_del_tunnel(gtp_nl.genl_id, gtp_nl.nl, t);
gtp_tunnel_free(t);
if (ret != 0)
break;
}
return ret;
}

View File

@ -21,10 +21,11 @@
#include <osmocom/core/msgb.h>
#include <osmocom/core/utils.h>
#include "checksum.h"
#include "../gtp/gtp.h"
#include "../gtp/pdp.h"
#include <osmocom/gtp/gtp.h>
#include <osmocom/gtp/pdp.h>
#include "checksum.h"
#include "ippool.h"
#include "syserr.h"
#include "icmpv6.h"

View File

@ -5,8 +5,8 @@
#include <osmocom/core/msgb.h>
#include <osmocom/core/endian.h>
#include "../gtp/gtp.h"
#include "../gtp/pdp.h"
#include <osmocom/gtp/gtp.h>
#include <osmocom/gtp/pdp.h>
#define ICMPv6_OPT_TYPE_PREFIX_INFO 0x03
@ -44,10 +44,9 @@ struct icmpv6_radv_hdr {
uint8_t res:6,
m:1,
o:1;
#else
uint8_t m:1,
o:1,
res:6;
#elif OSMO_IS_BIG_ENDIAN
/* auto-generated from the little endian part above (libosmocore/contrib/struct_endianness.py) */
uint8_t o:1, m:1, res:6;
#endif
uint16_t router_lifetime;
uint32_t reachable_time;
@ -72,10 +71,9 @@ struct icmpv6_opt_prefix {
uint8_t res:6,
a:1,
l:1;
#else
uint8_t l:1,
a:1,
res:6;
#elif OSMO_IS_BIG_ENDIAN
/* auto-generated from the little endian part above (libosmocore/contrib/struct_endianness.py) */
uint8_t l:1, a:1, res:6;
#endif
uint32_t valid_lifetime;
uint32_t preferred_lifetime;

View File

@ -10,7 +10,7 @@
*/
#include "../lib/in46_addr.h"
#include "../gtp/pdp.h"
#include <osmocom/gtp/pdp.h>
#include <osmocom/core/utils.h>
@ -375,3 +375,10 @@ default_to_dyn_v4:
dst->v4.s_addr = 0;
return 1;
}
void in46a_from_gsna(const struct ul16_t *in, struct in46_addr *dst)
{
dst->len = in->l;
OSMO_ASSERT(in->l <= sizeof(dst->v6));
memcpy(&dst->v6, in->v, in->l);
}

View File

@ -2,7 +2,7 @@
#include <stdint.h>
#include <netinet/in.h>
#include "../gtp/pdp.h"
#include <osmocom/gtp/pdp.h>
/* a simple wrapper around an in6_addr to also contain the length of the address,
* thereby implicitly indicating the address family of the address */
@ -39,3 +39,5 @@ static inline bool in46a_is_v6(const struct in46_addr *addr) {
static inline bool in46a_is_v4(const struct in46_addr *addr) {
return addr->len == sizeof(struct in_addr);
}
void in46a_from_gsna(const struct ul16_t *in, struct in46_addr *dst);

View File

@ -13,7 +13,7 @@
#define _IPPOOL_H
#include "../lib/in46_addr.h"
#include "../gtp/gtp.h"
#include <osmocom/gtp/gtp.h>
/* Assuming that the address space is fragmented we need a hash table
in order to return the addresses.

View File

@ -9,7 +9,7 @@
*
*/
#include "../gtp/pdp.h"
#include <osmocom/gtp/pdp.h>
#include "ippool.h"
#include "in46_addr.h"

View File

@ -7,5 +7,8 @@ Name: OsmoGGSN GTP Library
Description: C Utility Library
Version: @VERSION@
Libs: -L${libdir} -lgtp
Cflags: -I${includedir}/
# Add two include paths to support:
# * #include <osmocom/gtp/gtp.h> (like other Osmocom headers)
# * #include <gtp.h> (legacy compat)
Cflags: -I${includedir}/osmocom/gtp/ -I${includedir}/

View File

@ -2,12 +2,22 @@ bin_PROGRAMS = sgsnemu
AM_LDFLAGS = @EXEC_LDFLAGS@
AM_CFLAGS = -O2 -D_GNU_SOURCE -fno-builtin -Wall -DSBINDIR='"$(sbindir)"' -ggdb $(LIBOSMOCORE_CFLAGS)
AM_CFLAGS = \
-D_GNU_SOURCE \
-fno-builtin \
-Wall \
-DSBINDIR='"$(sbindir)"' \
-I$(top_srcdir)/include \
$(LIBOSMOCORE_CFLAGS) \
$(NULL)
sgsnemu_LDADD = @EXEC_LDADD@ -lgtp -L../gtp ../lib/libmisc.a $(LIBOSMOCORE_LIBS)
if ENABLE_GTP_KERNEL
AM_CFLAGS += -DGTP_KERNEL $(LIBGTPNL_CFLAGS)
AM_CFLAGS += \
-DGTP_KERNEL \
$(LIBGTPNL_CFLAGS) \
$(NULL)
sgsnemu_LDADD += $(LIBGTPNL_LIBS)
endif

View File

@ -54,13 +54,15 @@
#endif // HAVE_IN6_ADDR_GEN_MODE_NONE
#endif
#include <osmocom/gtp/pdp.h>
#include <osmocom/gtp/gtp.h>
#include "../lib/tun.h"
#include "../lib/ippool.h"
#include "../lib/syserr.h"
#include "../lib/netns.h"
#include "../lib/icmpv6.h"
#include "../gtp/pdp.h"
#include "../gtp/gtp.h"
#include "../gtp/gtp_internal.h"
#include "cmdline.h"
#define IPADDRLEN 256 /* Character length of addresses */

View File

@ -1,4 +1,9 @@
AM_CFLAGS = -Wall -I$(top_srcdir)/include $(LIBOSMOCORE_CFLAGS) -g
AM_CFLAGS = \
-Wall \
-I$(top_srcdir)/include \
$(LIBOSMOCORE_CFLAGS) \
$(NULL)
AM_LDFLAGS = -no-install
EXTRA_DIST = \
gtpie_test.ok \

View File

@ -10,8 +10,9 @@
#include <osmocom/core/msgb.h>
#include <osmocom/core/bits.h>
#include <osmocom/gtp/gtpie.h>
#include "../../lib/syserr.h"
#include "../../gtp/gtpie.h"
static const uint8_t in[] = { 1,2,3,4,5,6 };
static uint8_t buf[256];

View File

@ -1,4 +1,9 @@
AM_CFLAGS = -Wall -I$(top_srcdir)/include $(LIBOSMOCORE_CFLAGS) -g
AM_CFLAGS = \
-Wall \
-I$(top_srcdir)/include \
$(LIBOSMOCORE_CFLAGS) \
$(NULL)
AM_LDFLAGS = -no-install
EXTRA_DIST = ippool_test.ok \
ippool_test.err \