Compare commits

...

30 Commits

Author SHA1 Message Date
Keith
33680054c3 Implement ICMP response for inactive IP address.
Send ICMP Host Unreachable packets back on the tun device
in reponse to a packet received for an IP address that is
not active in our pool (No active pdp context)

Only IPv4 implemented.

Change-Id: Ia2c708feab14bb4cada00b0a90e0cb56d680d1aa
2021-05-17 01:32:47 +02:00
Pau Espin Pedrol
f32c6a9095 gtp: Support tx/rx RAN Information Relay message
See 3GPP TS 29.060 sec 7.5.14.1 RAN Information Relay.

Related: SYS#5314
Change-Id: Iea3eb032ccd4aed5187baca7f7719349d76039d4
2021-05-06 18:57:12 +02:00
Pau Espin Pedrol
2eed6ec5ec gtp: constify pointer arg
Change-Id: Ib5b5a8b64247202a2538c2ff8f8601981ccda822
2021-05-05 17:51:34 +02:00
Pau Espin Pedrol
641206ad5e cosmetic: gtpie.c: Fix trailing whitespace
Change-Id: I552e3b5f694e1b49fe5e21fa4023e4a24ffc2784
2021-05-03 17:24:30 +02:00
Pau Espin Pedrol
bfd3119ae4 gtp: Improve logging of failing pdp ctx resolution from TEI/TID
Change-Id: I4f2084ec7e3a830e0224dd998ff0fe6654cc23bd
2021-04-22 16:24:55 +02:00
Pau Espin Pedrol
4b9b19e998 ggsn: Improve logging on incoming DL data packets
Change-Id: I3617c8f68d8f18617871c070e28cc6ae5c6a925b
2021-04-22 16:24:55 +02:00
Pau Espin Pedrol
00e0559e17 gtp: Rework parsing logic of UpdatePdpCtxResponse
The previous order of parsing lead to non-optimal information gathering
when pushing events to upper layers.

This patch rearranges parsing of packet data to always gather as much
info as possible for the benefit of the upper layer. This way it can
gather information such as the cause, which is important in the case of
"Non-existent", since user should then drop the context.

First we want to parse the recovery state, but delay cb to upper layers
until we tried to gather the pdp ctx (meaning all except that pdp ctx
should be freed).
Second, we want to parse the cause, in order to know if there's an
associated pdp ctx we can gather from TEID.
Third, once we know if we should expect a meaningul TEID, parse it.

Related: SYS#5435
Change-Id: Idd10b494e8fbac8703c49ecd8f9bbe4246e51c57
2021-04-22 16:24:48 +02:00
Pau Espin Pedrol
0b1d9dbc40 gtp: Update teic_confirmed only on resp success
Change-Id: I54c54cbb51bfa5d1520855f448fa27511037b396
2021-04-21 19:45:23 +02:00
Harald Welte
5379273ea3 vty: Inform user that static IP addresses are not supported
Currently, osmo-ggsn doesn't implement PDP contexts with static IP
addresses.  The code for specifying ranges that can be used for
static IPs was always present even from OpenGGSN days, but we never
really treated them.  Let's not raise the impression we do by
warning accordingly if the user configures them.

Change-Id: I7787dae037c46c0c5052aa6dd000be330984f144
Related: OS#5097
2021-03-27 19:03:30 +01:00
Harald Welte
ecef920b8f ggsn: Reject PDP CTX ACT for static IP addresses
We don't implement handling of static IP addresses for now,
let's properly reject those rather than allocating a dynamic address
anyway.

Change-Id: Iac8868438655fe4e5e07d167d7dbd6273dbb7678
Related: OS#5097
2021-03-27 19:00:34 +01:00
Harald Welte
eb9267b15e Don't install sgsnemu.conf to /etc/osmocom/
This is an auxiliary example config file, which should not be installed
to /etc/ and hence not be in OSMOCONF_FILES

This fixes the following rpm packaging error:
[  149s] error: Installed (but unpackaged) file(s) found:
[  149s]    /etc/osmocom/sgsnemu.conf

Change-Id: Id31f6542590405531ff61a9434041c15e779865b
Fixes: Icd6f3efcf5a9ef50237a3d0a76d4cce55051f447
2021-03-03 08:10:56 +01:00
Harald Welte
1efb2bcd90 Don't install osmo-ggsn-kernel-gtp.cfg to /etc/osmocom/
This is an auxiliary example config file, which should not be installed
to /etc/ and hence not be in OSMOCONF_FILES

This fixes the following rpm packaging error:
[  149s] error: Installed (but unpackaged) file(s) found:
[  149s]    /etc/osmocom/osmo-ggsn-kernel-gtp.cfg

Change-Id: If118ed26491a1edda83eda7f95479e165ca4c150
Fixes: I6fbe8a8e55bad41532e9aed3cf71ebebffdcee52
2021-03-03 08:10:23 +01:00
Oliver Smith
878593f205 gitignore: add ggsn_vty_reference.xml
Change-Id: I39bd36e4bde457b7c7a62ca6aa6d5dadea4051fc
2021-03-02 09:03:20 +01:00
Oliver Smith
1596463985 doc/manuals: describe GTP-U kernel module
Related: OS#3209
Change-Id: Ib45cbfe03077960f216a83cf500ab3203d02cb3b
2021-03-02 09:03:09 +01:00
Oliver Smith
9d82492e49 doc/examples/osmo-ggsn-kernel-gtp.cfg: new file
Add a copy of osmo-ggsn.cfg, with gtpu-mode set to kernel-gtp and apn
inet6 and inet46 removed (as the kernel module only supports ipv4).

Related: OS#3209
Change-Id: I6fbe8a8e55bad41532e9aed3cf71ebebffdcee52
2021-03-01 15:37:39 +01:00
Oliver Smith
303aeea8a8 doc/examples/Makefile.am: add sgsnemu.conf
Related: OS#3209
Change-Id: Icd6f3efcf5a9ef50237a3d0a76d4cce55051f447
2021-03-01 15:03:10 +01:00
Pau Espin Pedrol
18898b4a9f Bump version: 1.7.0.2-17ce → 1.7.1
Change-Id: Ideca49e0762eb20799375a33a04469673dfeb168
2021-02-23 17:31:24 +01:00
Harald Welte
17cee2056c manuals: generate vty reference xml at build time
Remove ggsn_vty_reference from the source tree.

In manuals/Makefile.am use the new BUILT_REFERENCE_XML feature recently added
to osmo-gsm-manuals, and add a build target to generate the XML using the new
osmo-ggsn --vty-ref-xml cmdline switch.

Change-Id: I772293cc78a6c95e07565a7048c1c8dadf87d2fc
Depends: I613d692328050a036d05b49a436ab495fc2087ba
Related: OS#5041
2021-02-23 17:08:14 +01:00
Harald Welte
67a3c833af main: add --vty-ref-mode, use vty_dump_xml_ref_mode()
Change-Id: I966715ab2a430497bbccf26c50aef72d0901997f
Depends: Ie2022a7f9e167e5ceacf15350c037dd43768ff40
Related: OS#5041
2021-02-23 17:08:06 +01:00
Pau Espin Pedrol
b1f641b5b7 Bump version: 1.6.0.22-f01c-dirty → 1.7.0
Change-Id: I05d9bee0791cec5aebbeb1602be6697ecc2e2b74
2021-02-23 13:34:40 +01:00
Harald Welte
f01ce65f5b gtp-kernel: don't #include libmnl headers
* we don't check for libmnl via pkg-config in configure.ac
* we don't add libmnl include path to CFLAGS

As a result, we cannot #include related files.

libmnl is completely encapsulated by libgtpnl.  It even
includes a forward-declaration of 'struct mnl_socket'.

Change-Id: I0af869cc3c8e30b69d73a4985c56ef7743565e95
2021-02-20 11:28:59 +01:00
Harald Welte
be1cf99e9a gtp-kernel: Remove duplicate #include section
This was probably a wrong patch merge at some point.

Change-Id: I54191aca8fd55de84d86591035fe9785d379205f
2021-02-20 11:05:53 +01:00
Oliver Smith
7710080ffd deb/rpm: build with --enable-gtp-linux
Allow optional use of the GTP kernel module.

Related: OS#3208
Change-Id: Ic001ec6c5ec9887706a5b27f2a48cd61942ab4ee
2021-02-19 18:28:04 +01:00
Oliver Smith
798a81d48d .gitignore: ignore debian/libgtp*
Change-Id: I41fa611917defeab13f01a59dcc3f95961f10bda
2021-02-19 18:25:58 +01:00
Pau Espin Pedrol
51930f7b63 tests: Replace deprecated API log_set_print_filename
Change-Id: I35eb879d82e1030ea8be56ce9039277c021bb6fa
2021-02-19 13:23:00 +01:00
Pau Espin Pedrol
00ef1b0d6e tests: Explicitly drop category from log
Let's disable category here since we don't care about its formatting here.

In any case, every test relying on logging output validation should
always explicitly state the config to avoid issues in the future if
default values change.

Change-Id: Icce09882ef3ed07328679594ff84902383d16c72
Related: OS#5034
2021-02-19 13:22:28 +01:00
Oliver Smith
02a82c3c9b apn_start: avoid segfault if missing tun-device
Check if tun-device is defined and give the user a hint that it is
missing instead of segfaulting with gtpu-mode kernel-gtp:
  20210205141701206 DGGSN <0002> ggsn.c:186 APN(internet): Starting
  20210205141701206 DGGSN <0002> ggsn.c:204 APN(internet): Opening Kernel GTP device (null)
  Segmentation fault

With gtpu-mode tun it didn't segfault, but still tried to open the NULL
device:
  20210205141557598 DGGSN <0002> ggsn.c:186 APN(internet): Starting
  20210205141557599 DGGSN <0002> ggsn.c:189 APN(internet): Opening TUN device (null)
  20210205141557599 DTUN <0001> tun.c:195 errno=1/Operation not permitted ioctl() failed

Related: OS#3208
Change-Id: I9f71af65cc0eed71728c04b774e5c08352947913
2021-02-05 16:37:02 +01:00
Oliver Smith
349cbfcf50 configure.ac: set -std=gnu11
Change-Id: I7fed7d43242f804e6d2b005277c5b2b1bd197aa8
2021-01-28 09:28:56 +00:00
Oliver Smith
51f99ae250 contrib/jenkins: don't build osmo-gsm-manuals
Related: OS#4912
Change-Id: Ie77a81d3bd7cdb739fa082d9e1b5ddeba433a9db
2021-01-13 13:05:20 +01:00
Pau Espin Pedrol
12304c0e5a ggsn: generate coredump and exit upon SIGABRT received
Previous code relied on abort() switching sigaction to SIG_FDL +
retriggering SIGABRT in case the signal handler returns, which would
then generate the coredump + terminate the process.
However, if a SIGABRT is received from somewhere else (kill -SIGABRT),
then the process would print the talloc report and continue running,
which is not desired.

Change-Id: I7acfdfe5020320d853cba98b5add7479f8aaaf39
Fixes: OS#4865
2020-11-25 18:49:16 +01:00
26 changed files with 493 additions and 1736 deletions

3
.gitignore vendored
View File

@@ -27,7 +27,7 @@ osmo-ggsn-*.tar*
# debian
debian/osmo-ggsn/
debian/*.debhelper
debian/libgtp1
debian/libgtp*/
debian/osmo-ggsn-dbg
debian/*.log
debian/autoreconf.*
@@ -79,5 +79,6 @@ doc/manuals/generated/
doc/manuals/osmomsc-usermanual.xml
doc/manuals/common
doc/manuals/build
doc/manuals/vty/ggsn_vty_reference.xml
contrib/osmo-ggsn.spec

View File

@@ -7,4 +7,4 @@
# 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
osmo-ggsn update osmo-gsm-manuals dependency to > 0.3.0 for vty_cpu_sched.adoc include
libgtp ADD gtp_ran_info_relay_req, gtp_set_cb_ran_info_relay_ind

View File

@@ -9,6 +9,8 @@ AC_CONFIG_AUX_DIR([.])
AC_CONFIG_TESTDIR(tests)
AC_CANONICAL_HOST
CFLAGS="$CFLAGS -std=gnu11"
dnl kernel style compile messages
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
@@ -152,9 +154,9 @@ adl_FUNC_GETOPT_LONG
AM_INIT_AUTOMAKE([foreign])
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.4.0)
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.4.0)
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.4.0)
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.5.0)
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.5.0)
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.5.0)
AC_ARG_ENABLE(sanitize,
[AS_HELP_STRING(

View File

@@ -38,7 +38,6 @@ export PATH="$inst/bin:$PATH"
# Additional configure options and depends
CONFIG=""
if [ "$WITH_MANUALS" = "1" ]; then
osmo-build-dep.sh osmo-gsm-manuals
CONFIG="--enable-manuals"
fi

View File

@@ -29,11 +29,10 @@ BuildRequires: pkgconfig >= 0.20
%if 0%{?suse_version}
BuildRequires: systemd-rpm-macros
%endif
BuildRequires: pkgconfig(libgtpnl) >= 1.0.0
BuildRequires: pkgconfig(libmnl) >= 1.0.3
BuildRequires: pkgconfig(libosmocore) >= 1.1.0
BuildRequires: pkgconfig(libosmoctrl) >= 1.1.0
BuildRequires: pkgconfig(libosmovty) >= 1.1.0
BuildRequires: pkgconfig(libgtpnl) >= 1.2.0
BuildRequires: pkgconfig(libosmocore) >= 1.5.0
BuildRequires: pkgconfig(libosmoctrl) >= 1.5.0
BuildRequires: pkgconfig(libosmovty) >= 1.5.0
Obsoletes: openggsn
%{?systemd_requires}
@@ -69,6 +68,7 @@ applications that want to make use of libgtp.
echo "%{version}" >.tarball-version
autoreconf -fi
%configure \
--enable-gtp-linux \
--disable-static \
--docdir="%{_docdir}/%{name}" \
--with-systemdsystemunitdir=%{_unitdir} \
@@ -108,7 +108,9 @@ make %{?_smp_mflags} check || (find . -name testsuite.log -exec cat {} +)
%{_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

44
debian/changelog vendored
View File

@@ -1,3 +1,47 @@
osmo-ggsn (1.7.1) unstable; urgency=medium
[ Harald Welte ]
* main: add --vty-ref-mode, use vty_dump_xml_ref_mode()
* manuals: generate vty reference xml at build time
-- Pau Espin Pedrol <pespin@sysmocom.de> Tue, 23 Feb 2021 17:31:24 +0100
osmo-ggsn (1.7.0) unstable; urgency=medium
[ Vadim Yanitskiy ]
* debian/control: change maintainer to the Osmocom team / mailing list
[ Pau Espin Pedrol ]
* configure.ac: Fix trailing whitespace
* doc: Update VTY reference xml file
* Support setting rt-prio and cpu-affinity mask through VTY
* contrib/jenkins: Enable parallel make in make distcheck
* ggsn: generate coredump and exit upon SIGABRT received
* tests: Explicitly drop category from log
* tests: Replace deprecated API log_set_print_filename
[ Keith ]
* Fix vty PDP lookups by IMSI
* Prevent Crash in show pdp-context from vty
* Minor: remove code duplication
* Use imsi_str2gtp() in sgsnemu
* sgsnemu: relax check on length of IMSI cmdline arg.
* GTP: Replace recently introduced imsi_str2gtp()
[ Harald Welte ]
* Use OSMO_FD_* instead of deprecated BSC_FD_*
* gtp-kernel: Remove duplicate #include section
* gtp-kernel: don't #include libmnl headers
[ Oliver Smith ]
* contrib/jenkins: don't build osmo-gsm-manuals
* configure.ac: set -std=gnu11
* apn_start: avoid segfault if missing tun-device
* .gitignore: ignore debian/libgtp*
* deb/rpm: build with --enable-gtp-linux
-- Pau Espin Pedrol <pespin@espeweb.net> Tue, 23 Feb 2021 13:34:39 +0100
osmo-ggsn (1.6.0) unstable; urgency=medium
[ Pau Espin Pedrol ]

5
debian/control vendored
View File

@@ -7,8 +7,9 @@ Build-Depends: debhelper (>= 9),
pkg-config,
libdpkg-perl, git,
dh-autoreconf,
libosmocore-dev (>= 1.4.0),
osmo-gsm-manuals-dev
libosmocore-dev (>= 1.5.0),
osmo-gsm-manuals-dev,
libgtpnl-dev (>= 1.2.0)
Standards-Version: 3.9.6
Vcs-Browser: http://git.osmocom.org/osmo-ggsn/
Vcs-Git: git://git.osmocom.org/osmo-ggsn

View File

@@ -1,2 +1,3 @@
doc/examples/osmo-ggsn.cfg
doc/examples/osmo-ggsn-kernel-gtp.cfg
doc/examples/sgsnemu.conf

5
debian/rules vendored
View File

@@ -19,7 +19,10 @@ override_dh_strip:
dh_strip -plibgtp6 --dbg-package=libgtp-dbg
override_dh_auto_configure:
dh_auto_configure -- --with-systemdsystemunitdir=/lib/systemd/system --enable-manuals
dh_auto_configure -- \
--enable-gtp-linux \
--with-systemdsystemunitdir=/lib/systemd/system \
--enable-manuals
# Don't create .pdf.gz files (barely saves space and they can't be opened directly by most pdf readers)
override_dh_compress:

View File

@@ -1,9 +1,13 @@
OSMOCONF_FILES = \
osmo-ggsn.cfg \
$(NULL)
osmoconfdir = $(sysconfdir)/osmocom
osmoconf_DATA = osmo-ggsn.cfg
osmoconf_DATA = $(OSMOCONF_FILES)
EXTRA_DIST = osmo-ggsn.cfg
EXTRA_DIST = $(OSMOCONF_FILES)
CFG_FILES = find $(srcdir) -name '*.cfg*' | sed -e 's,^$(srcdir),,'
CFG_FILES = find $(srcdir) -name '*.cfg' -o -name '*.conf' | sed -e 's,^$(srcdir),,'
dist-hook:
for f in $$($(CFG_FILES)); do \

View File

@@ -0,0 +1,51 @@
!
! OpenGGSN (0.94.1-adac) configuration saved from vty
!!
!
log stderr
logging filter all 1
logging color 1
logging print category 0
logging timestamp 0
logging level ip info
logging level tun info
logging level ggsn info
logging level sgsn notice
logging level icmp6 notice
logging level lglobal notice
logging level llapd notice
logging level linp notice
logging level lmux notice
logging level lmi notice
logging level lmib notice
logging level lsms notice
logging level lctrl notice
logging level lgtp info
logging level lstats notice
logging level lgsup notice
logging level loap notice
logging level lss7 notice
logging level lsccp notice
logging level lsua notice
logging level lm3ua notice
logging level lmgcp notice
!
stats interval 5
!
line vty
no login
!
ggsn ggsn0
gtp state-dir /tmp
gtp bind-ip 127.0.0.2
apn internet
gtpu-mode kernel-gtp
tun-device tun4
type-support v4
ip prefix dynamic 172.16.222.0/24
ip dns 0 8.8.8.8
ip dns 1 8.8.4.4
ip ifconfig 172.16.222.0/24
no shutdown
default-apn internet
no shutdown ggsn

View File

@@ -11,6 +11,12 @@ if BUILD_MANUALS
include $(OSMO_GSM_MANUALS_DIR)/build/Makefile.asciidoc.inc
VTY_REFERENCE = osmoggsn-vty-reference.xml
BUILT_REFERENCE_XML = $(builddir)/vty/ggsn_vty_reference.xml
$(builddir)/vty/ggsn_vty_reference.xml: $(top_builddir)/ggsn/osmo-ggsn
mkdir -p $(builddir)/vty
$(top_builddir)/ggsn/osmo-ggsn --vty-ref-xml > $@
include $(OSMO_GSM_MANUALS_DIR)/build/Makefile.vty-reference.inc
OSMO_REPOSITORY=osmo-ggsn

View File

@@ -80,3 +80,47 @@ possible to pick differing ports on the same IP address), like:
ggsn ggsn0
gtp bind-ip 127.0.0.2
----
=== GTP-U kernel module
WARNING: As of writing, the kernel module does not support IPv6.
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
userspace in OsmoGGSN. The kernel module is included in Linux 4.7.0 and higher.
Notably the Debian GNU/Linux distribution has it enabled by default.
In order to use this feature, make sure that your Linux kernel was configured
to support it (`CONFIG_GTP=m` or `=y`). Furthermore, `osmo-ggsn` must have been
built with `./configure` argument `--enable-gtp-linux` (which requires libgtpnl
to be installed).
Load the kernel module with:
----
$ sudo modprobe gtp
----
Then start OsmoGGSN with a configuration file that uses `gtpu-mode kernel-gtp`.
A full example configuration is in `osmo-ggsn-kernel-gtp.cfg`.
----
$ sudo osmo-ggsn -c /usr/share/doc/osmo-ggsn/examples/osmo-ggsn-kernel-gtp.cfg
----
.Example: APN with kernel-gtp
----
ggsn ggsn0
gtp state-dir /tmp
gtp bind-ip 127.0.0.2
apn internet
gtpu-mode kernel-gtp
tun-device tun4
type-support v4
ip prefix dynamic 172.16.222.0/24
ip dns 0 8.8.8.8
ip dns 1 8.8.4.4
ip ifconfig 172.16.222.0/24
no shutdown
----

File diff suppressed because it is too large Load Diff

View File

@@ -40,6 +40,7 @@
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <netinet/ip6.h>
#include <osmocom/core/timer.h>
@@ -467,9 +468,13 @@ int create_context_ind(struct pdp_t *pdp)
return 0;
}
/* FIXME: we manually force all context requests to dynamic here! */
if (pdp->eua.l > 2)
pdp->eua.l = 2;
/* FIXME: implement context request for static IP addresses! */
if (pdp->eua.l > 2) {
LOGPPDP(LOGL_ERROR, pdp, "Static IP addresses not supported: %s\n",
osmo_hexdump(pdp->eua.v, pdp->eua.l));
gtp_create_context_resp(gsn, pdp, GTPCAUSE_NOT_SUPPORTED);
return 0;
}
memcpy(pdp->qos_neg0, pdp->qos_req0, sizeof(pdp->qos_req0));
@@ -580,6 +585,72 @@ err_wrong_af:
return 0;
}
static uint16_t inet_checksum(void *data, int len) {
int nleft = len;
int sum = 0;
unsigned short *w = data;
unsigned short answer = 0;
while (nleft > 1)
{
sum += *w++;
nleft -= 2;
}
if (nleft == 1)
{
*(unsigned char *)(&answer) = *(unsigned char *)w;
sum += answer;
}
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
answer = ~sum;
return (answer);
}
/* Generate and send an ICMP HOST UNREACHABLE Packet */
static void ipv4_host_unreach(struct tun_t *tun, void *pack, unsigned len) {
char send_buf[sizeof(struct ip) + sizeof(struct icmp) + len];
/* What are these 20 bytes on the end of pack? */
len = len - 20;
struct iphdr *iph = (struct iphdr *)pack;
memset(send_buf, 0, sizeof(send_buf));
struct ip *ip = (struct ip *)send_buf;
struct icmp *icmp = (struct icmp *)(ip + 1);
ip->ip_v = 4;
ip->ip_hl = 5;
ip->ip_tos = 0;
ip->ip_len = htons(sizeof(send_buf));
ip->ip_id = rand();
ip->ip_off = 0;
ip->ip_ttl = 64;
ip->ip_sum = 0;
ip->ip_p = IPPROTO_ICMP;
ip->ip_src.s_addr = iph->daddr;
//inet_pton(AF_INET, "10.20.0.4", &(ip->ip_src));
ip->ip_dst.s_addr = iph->saddr;
ip->ip_sum = inet_checksum(ip, sizeof(send_buf));
icmp->icmp_type = ICMP_DEST_UNREACH;
icmp->icmp_code = ICMP_HOST_UNREACH;
icmp->icmp_id = 0;
icmp->icmp_seq = 0;
icmp->icmp_cksum = 0;
memcpy(send_buf + sizeof(ip) + sizeof(icmp) + 12, pack, len);
icmp->icmp_cksum = inet_checksum(icmp, sizeof(icmp) + 12 + len);
tun_encaps(tun, send_buf, sizeof(send_buf));
}
/* Internet-originated IP packet, needs to be sent via GTP towards MS */
static int cb_tun_ind(struct tun_t *tun, void *pack, unsigned len)
{
@@ -589,7 +660,7 @@ static int cb_tun_ind(struct tun_t *tun, void *pack, unsigned len)
struct iphdr *iph = (struct iphdr *)pack;
struct ip6_hdr *ip6h = (struct ip6_hdr *)pack;
struct ippool_t *pool;
char straddr[INET6_ADDRSTRLEN];
char straddr[2][INET6_ADDRSTRLEN];
uint8_t pref_offset;
switch (iph->version) {
@@ -622,17 +693,45 @@ static int cb_tun_ind(struct tun_t *tun, void *pack, unsigned len)
return 0;
if (ippool_getip(pool, &ipm, &dst)) {
LOGTUN(LOGL_DEBUG, tun, "Received packet for APN(%s) with no PDP contex! (%s)\n",
apn->cfg.name,
iph->version == 4 ?
inet_ntop(AF_INET, &iph->saddr, straddr, sizeof(straddr)) :
inet_ntop(AF_INET6, &ip6h->ip6_src, straddr, sizeof(straddr)));
LOGTUN(LOGL_DEBUG, tun, "APN(%s) Rx DL data packet for IP address outside "
"pool of managed addresses: %s <- %s\n",
apn->cfg.name,
iph->version == 4 ?
inet_ntop(AF_INET, &iph->daddr, straddr[0], sizeof(straddr[0])) :
inet_ntop(AF_INET6, &ip6h->ip6_dst, straddr[0], sizeof(straddr[0])),
iph->version == 4 ?
inet_ntop(AF_INET, &iph->saddr, straddr[1], sizeof(straddr[1])) :
inet_ntop(AF_INET6, &ip6h->ip6_src, straddr[1], sizeof(straddr[1])));
return 0;
}
LOGTUN(LOGL_DEBUG, tun, "Received packet for APN(%s)\n", apn->cfg.name);
if (ipm->peer) /* Check if a peer protocol is defined */
gtp_data_req(apn->ggsn->gsn, (struct pdp_t *)ipm->peer, pack, len);
if (ipm->peer) { /* Check if a peer protocol is defined */
struct pdp_t *pdp = (struct pdp_t *)ipm->peer;
LOGTUN(LOGL_DEBUG, tun, "APN(%s) Rx DL data packet for PDP(%s:%u): %s <- %s\n",
apn->cfg.name,
imsi_gtp2str(&(pdp)->imsi), (pdp)->nsapi,
iph->version == 4 ?
inet_ntop(AF_INET, &iph->daddr, straddr[0], sizeof(straddr[0])) :
inet_ntop(AF_INET6, &ip6h->ip6_dst, straddr[0], sizeof(straddr[0])),
iph->version == 4 ?
inet_ntop(AF_INET, &iph->saddr, straddr[1], sizeof(straddr[1])) :
inet_ntop(AF_INET6, &ip6h->ip6_src, straddr[1], sizeof(straddr[1])));
gtp_data_req(apn->ggsn->gsn, pdp, pack, len);
} else {
LOGTUN(LOGL_DEBUG, tun, "APN(%s) Rx DL data packet for IP address with no "
"associated PDP Ctx: %s <- %s\n",
apn->cfg.name,
iph->version == 4 ?
inet_ntop(AF_INET, &iph->daddr, straddr[0], sizeof(straddr[0])) :
inet_ntop(AF_INET6, &ip6h->ip6_dst, straddr[0], sizeof(straddr[0])),
iph->version == 4 ?
inet_ntop(AF_INET, &iph->saddr, straddr[1], sizeof(straddr[1])) :
inet_ntop(AF_INET6, &ip6h->ip6_src, straddr[1], sizeof(straddr[1])));
if (iph->version != 4)
return 0;
LOGTUN(LOGL_DEBUG, tun, "No PDP Context for Destination Address, send host unreach.\n");
ipv4_host_unreach(tun, pack, len);
}
return 0;
}

View File

@@ -71,6 +71,17 @@ static void signal_handler(int s)
end = 1;
break;
case SIGABRT:
/* in case of abort, we want to obtain a talloc report and
* then run default SIGABRT handler, who will generate coredump
* and abort the process. abort() should do this for us after we
* return, but program wouldn't exit if an external SIGABRT is
* received.
*/
talloc_report(tall_vty_ctx, stderr);
talloc_report_full(tall_ggsn_ctx, stderr);
signal(SIGABRT, SIG_DFL);
raise(SIGABRT);
break;
case SIGUSR1:
talloc_report(tall_vty_ctx, stderr);
talloc_report_full(tall_ggsn_ctx, stderr);
@@ -96,17 +107,49 @@ static void print_help()
" -c --config-file filename The config file to use\n"
" -V --version Print the version of OsmoGGSN\n"
);
printf("\nVTY reference generation:\n");
printf(" --vty-ref-mode MODE VTY reference generation mode (e.g. 'expert').\n");
printf(" --vty-ref-xml Generate the VTY reference XML output and exit.\n");
}
static void handle_long_options(const char *prog_name, const int long_option)
{
static int vty_ref_mode = VTY_REF_GEN_MODE_DEFAULT;
switch (long_option) {
case 1:
vty_ref_mode = get_string_value(vty_ref_gen_mode_names, optarg);
if (vty_ref_mode < 0) {
fprintf(stderr, "%s: Unknown VTY reference generation "
"mode '%s'\n", prog_name, optarg);
exit(2);
}
break;
case 2:
fprintf(stderr, "Generating the VTY reference in mode '%s' (%s)\n",
get_value_string(vty_ref_gen_mode_names, vty_ref_mode),
get_value_string(vty_ref_gen_mode_desc, vty_ref_mode));
vty_dump_xml_ref_mode(stdout, (enum vty_ref_gen_mode) vty_ref_mode);
exit(0);
default:
fprintf(stderr, "%s: error parsing cmdline options\n", prog_name);
exit(2);
}
}
static void handle_options(int argc, char **argv)
{
while (1) {
int option_index = 0, c;
static int long_option = 0;
static struct option long_options[] = {
{ "help", 0, 0, 'h' },
{ "daemonize", 0, 0, 'D' },
{ "config-file", 1, 0, 'c' },
{ "version", 0, 0, 'V' },
{ "vty-ref-mode", 1, &long_option, 1 },
{ "vty-ref-xml", 0, &long_option, 2 },
{ 0, 0, 0, 0 }
};
@@ -115,6 +158,9 @@ static void handle_options(int argc, char **argv)
break;
switch (c) {
case 0:
handle_long_options(argv[0], long_option);
break;
case 'h':
print_usage();
print_help();

View File

@@ -533,9 +533,11 @@ DEFUN(cfg_apn_ip_prefix, cfg_apn_ip_prefix_cmd,
struct in46_prefix *pfx;
/* first update our parsed prefix */
if (!strcmp(argv[0], "static"))
if (!strcmp(argv[0], "static")) {
pfx = &apn->v4.cfg.static_prefix;
else
vty_out(vty, "%% static IP addresses currently not yet supported%s", VTY_NEWLINE);
return CMD_WARNING;
} else
pfx = &apn->v4.cfg.dynamic_prefix;
str2prefix(pfx, argv[1]);
@@ -567,9 +569,11 @@ DEFUN(cfg_apn_ipv6_prefix, cfg_apn_ipv6_prefix_cmd,
struct apn_ctx *apn = (struct apn_ctx *) vty->index;
struct in46_prefix *pfx;
if (!strcmp(argv[0], "static"))
if (!strcmp(argv[0], "static")) {
pfx = &apn->v6.cfg.static_prefix;
else
vty_out(vty, "%% static IP addresses currently not yet supported%s", VTY_NEWLINE);
return CMD_WARNING;
} else
pfx = &apn->v6.cfg.dynamic_prefix;
str2prefix(pfx, argv[1]);
return CMD_SUCCESS;
@@ -699,6 +703,10 @@ DEFUN(cfg_apn_no_shutdown, cfg_apn_no_shutdown_cmd,
struct apn_ctx *apn = (struct apn_ctx *) vty->index;
if (apn->cfg.shutdown) {
if (!apn->tun.cfg.dev_name) {
vty_out(vty, "%% Failed to start APN, tun-device is not configured%s", VTY_NEWLINE);
return CMD_WARNING;
}
if (apn_start(apn) < 0) {
vty_out(vty, "%% Failed to start APN, check log for details%s", VTY_NEWLINE);
return CMD_WARNING;

View File

@@ -2,7 +2,7 @@
# 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=6:0:0
LIBVERSION=7:0:1
lib_LTLIBRARIES = libgtp.la

175
gtp/gtp.c
View File

@@ -196,6 +196,13 @@ int gtp_set_cb_extheader_ind(struct gsn_t *gsn,
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))
@@ -773,7 +780,7 @@ static int gtp_resp(uint8_t version, struct gsn_t *gsn, struct pdp_t *pdp,
static int gtp_notification(struct gsn_t *gsn, uint8_t version,
union gtp_packet *packet, int len,
struct sockaddr_in *peer, int fd, uint16_t seq)
const struct sockaddr_in *peer, int fd, uint16_t seq)
{
uint8_t ver = GTPHDR_F_GET_VER(packet->flags);
@@ -1200,6 +1207,57 @@ static int gtp_extheader_ind(struct gsn_t *gsn, struct sockaddr_in *peer,
return 0;
}
/* Handle a RAN Information Relay message */
static int gtp_ran_info_relay_ind(struct gsn_t *gsn, int version, struct sockaddr_in *peer,
void *pack, unsigned len)
{
union gtpie_member *ie[GTPIE_SIZE];
if (version != 1) {
LOGP(DLGTP, LOGL_NOTICE,
"RAN Information Relay expected only on GTPCv1: %u\n", version);
return -EINVAL;
}
int hlen = get_hlen(pack);
/* Decode information elements */
if (gtpie_decaps(ie, version, pack + hlen, len - hlen)) {
gsn->invalid++;
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Invalid message format (AN Information Relay)\n");
return -EINVAL;
}
if (gsn->cb_ran_info_relay_ind)
gsn->cb_ran_info_relay_ind(peer, ie);
return 0;
}
/* Send off a RAN Information Relay message */
int gtp_ran_info_relay_req(struct gsn_t *gsn, const struct sockaddr_in *peer,
const uint8_t *ran_container, size_t ran_container_len,
const uint8_t *rim_route_addr, size_t rim_route_addr_len,
uint8_t rim_route_addr_discr)
{
union gtp_packet packet;
/* GTP 1 is the highest supported protocol */
unsigned int length = get_default_gtp(1, GTP_RAN_INFO_RELAY, &packet);
gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_RAN_T_CONTAIN, ran_container_len,
ran_container);
if (rim_route_addr) {
gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_RIM_ROUT_ADDR,
rim_route_addr_len, rim_route_addr);
gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_RIM_RA_DISCR, 1,
&rim_route_addr_discr);
}
return gtp_notification(gsn, 1, &packet, length, peer, gsn->fd1c, 0);
}
/* ***********************************************************
* Session management messages
* Messages: create, update and delete PDP context
@@ -1792,9 +1850,6 @@ int gtp_create_pdp_conf(struct gsn_t *gsn, int version,
return EOF;
}
/* Register that we have received a valid teic from GGSN */
pdp->teic_confirmed = 1;
/* Decode information elements */
if (gtpie_decaps(ie, version, pack + hlen, len - hlen)) {
gsn->invalid++;
@@ -1894,6 +1949,8 @@ int gtp_create_pdp_conf(struct gsn_t *gsn, int version,
gsn->cb_conf(type, EOF, pdp, cbp);
return EOF;
}
/* Register that we have received a valid teic from GGSN */
pdp->teic_confirmed = 1;
}
if (gtpie_gettv4(ie, GTPIE_CHARGING_ID, 0, &pdp->cid)) {
@@ -2137,8 +2194,9 @@ static int gtp_update_pdp_ind(struct gsn_t *gsn, uint8_t version,
/* Find the context in question */
if (gtp_pdp_tidget(gsn, &pdp, get_tid(pack))) {
gsn->err_unknownpdp++;
GTP_LOGPKG(LOGL_ERROR, peer, pack,
len, "Unknown PDP context\n");
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Unknown PDP context: TID=0x%" PRIx64 "\n",
get_tid(pack));
return gtp_update_pdp_resp(gsn, version, peer, fd, pack,
len, NULL,
GTPCAUSE_NON_EXIST);
@@ -2162,9 +2220,9 @@ static int gtp_update_pdp_ind(struct gsn_t *gsn, uint8_t version,
/* Find the context in question */
if (gtp_pdp_getgtp1(gsn, &pdp, get_tei(pack))) {
gsn->err_unknownpdp++;
GTP_LOGPKG(LOGL_ERROR, peer,
pack, len, "Unknown PDP context: %u\n",
get_tei(pack));
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Unknown PDP context: TEI=0x%" PRIx32 "\n",
get_tei(pack));
return gtp_update_pdp_resp(gsn, version, peer,
fd, pack, len, NULL,
GTPCAUSE_NON_EXIST);
@@ -2173,8 +2231,9 @@ static int gtp_update_pdp_ind(struct gsn_t *gsn, uint8_t version,
/* Find the context in question */
if (gtp_pdp_getimsi(gsn, &pdp, imsi, nsapi)) {
gsn->err_unknownpdp++;
GTP_LOGPKG(LOGL_ERROR, peer,
pack, len, "Unknown PDP context\n");
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Unknown PDP context: IMSI=0x%" PRIx64
" NSAPI=%" PRIu8 "\n", imsi, nsapi);
return gtp_update_pdp_resp(gsn, version, peer,
fd, pack, len, NULL,
GTPCAUSE_NON_EXIST);
@@ -2325,29 +2384,20 @@ static int gtp_update_pdp_ind(struct gsn_t *gsn, uint8_t version,
static int gtp_update_pdp_conf(struct gsn_t *gsn, uint8_t version,
struct sockaddr_in *peer, void *pack, unsigned len)
{
struct pdp_t *pdp;
struct pdp_t *pdp = NULL;
union gtpie_member *ie[GTPIE_SIZE];
uint8_t cause, recovery;
uint8_t cause = EOF;
uint8_t recovery;
int rc = 0;
void *cbp = NULL;
uint8_t type = 0;
bool trigger_recovery = false;
int hlen = get_hlen(pack);
/* Remove packet from queue */
if (gtp_conf(gsn, 0, peer, pack, len, &type, &cbp))
return EOF;
/* Find the context in question */
if (gtp_pdp_getgtp1(gsn, &pdp, get_tei(pack))) {
gsn->err_unknownpdp++;
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Unknown PDP context: %u\n", get_tei(pack));
pdp = NULL;
goto err_out;
}
/* Register that we have received a valid teic from GGSN */
pdp->teic_confirmed = 1;
/* Decode information elements */
if (gtpie_decaps(ie, version, pack + hlen, len - hlen)) {
gsn->invalid++;
@@ -2356,19 +2406,34 @@ static int gtp_update_pdp_conf(struct gsn_t *gsn, uint8_t version,
goto err_out;
}
/* Extract recovery (optional) */
if (!gtpie_gettv1(ie, GTPIE_RECOVERY, 0, &recovery))
trigger_recovery = true;
/* Extract cause value (mandatory) */
if (gtpie_gettv1(ie, GTPIE_CAUSE, 0, &cause)) {
goto err_missing;
}
/* Extract recovery (optional) */
if (!gtpie_gettv1(ie, GTPIE_RECOVERY, 0, &recovery)) {
emit_cb_recovery(gsn, peer, pdp, recovery);
/* 3GPP TS 29.060 sec 8.2: "Receiving node shall send back to the source
* of the message, a response with the appropriate cause value (either
* "Non-existent" or "Context not found"). The Tunnel Endpoint
* Identifier used in the response message shall be set to all zeroes."
* Hence, TEID=0 in this scenario, it makes no sense to infer PDP ctx
* from it. User is responsible to infer it from cbp */
if (cause != GTPCAUSE_NON_EXIST && cause != GTPCAUSE_CONTEXT_NOT_FOUND) {
/* Find the context in question */
if (gtp_pdp_getgtp1(gsn, &pdp, get_tei(pack))) {
gsn->err_unknownpdp++;
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Unknown PDP context: TEI=0x%" PRIx32 "\n", get_tei(pack));
goto err_out;
}
}
/* Check all conditional information elements */
/* TODO: This does not handle GGSN-initiated update responses */
if (GTPCAUSE_ACC_REQ == cause) {
if (cause == GTPCAUSE_ACC_REQ) {
if (version == 0) {
if (gtpie_gettv0(ie, GTPIE_QOS_PROFILE0, 0,
&pdp->qos_neg0,
@@ -2393,6 +2458,8 @@ static int gtp_update_pdp_conf(struct gsn_t *gsn, uint8_t version,
if (gtpie_gettv4(ie, GTPIE_TEI_C, 0, &pdp->teic_gn)) {
goto err_missing;
}
/* Register that we have received a valid teic from GGSN */
pdp->teic_confirmed = 1;
}
if (gtpie_gettv4(ie, GTPIE_CHARGING_ID, 0, &pdp->cid)) {
@@ -2418,18 +2485,20 @@ static int gtp_update_pdp_conf(struct gsn_t *gsn, uint8_t version,
}
}
generic_ret:
if (trigger_recovery)
emit_cb_recovery(gsn, peer, pdp, recovery);
if (gsn->cb_conf)
gsn->cb_conf(type, cause, pdp, cbp);
return 0; /* Succes */
return rc; /* Succes */
err_missing:
gsn->missing++;
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Missing information field\n");
err_out:
if (gsn->cb_conf)
gsn->cb_conf(type, EOF, pdp, cbp);
return EOF;
rc = EOF;
goto generic_ret;
}
/* API: Deprecated. Send Delete PDP Context Request And free pdp ctx. */
@@ -2594,7 +2663,7 @@ int gtp_delete_pdp_ind(struct gsn_t *gsn, int version,
if (gtp_pdp_getgtp1(gsn, &linked_pdp, get_tei(pack))) {
gsn->err_unknownpdp++;
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Unknown PDP context: %u\n", get_tei(pack));
"Unknown PDP context: TEI=0x%" PRIx32 "\n", get_tei(pack));
return gtp_delete_pdp_resp(gsn, version, peer, fd, pack, len,
NULL, NULL, GTPCAUSE_NON_EXIST,
teardown);
@@ -2623,7 +2692,7 @@ int gtp_delete_pdp_ind(struct gsn_t *gsn, int version,
if (gtpie_gettv1(ie, GTPIE_NSAPI, 0, &nsapi)) {
gsn->missing++;
GTP_LOGPKG(LOGL_ERROR, peer, pack,
len, "Missing mandatory information field\n");
len, "Missing mandatory information field\n");
return gtp_delete_pdp_resp(gsn, version, peer, fd, pack,
len, NULL, NULL,
GTPCAUSE_MAN_IE_MISSING,
@@ -2633,8 +2702,9 @@ int gtp_delete_pdp_ind(struct gsn_t *gsn, int version,
/* Find the context in question */
if (gtp_pdp_getgtp1(gsn, &pdp, linked_pdp->secondary_tei[nsapi & 0x0f])) {
gsn->err_unknownpdp++;
GTP_LOGPKG(LOGL_ERROR, peer, pack,
len, "Unknown PDP context\n");
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Unknown PDP context: Secondary TEI=0x%" PRIx32 "\n",
linked_pdp->secondary_tei[nsapi & 0x0f]);
return gtp_delete_pdp_resp(gsn, version, peer, fd, pack,
len, NULL, NULL,
GTPCAUSE_NON_EXIST,
@@ -2687,8 +2757,9 @@ int gtp_delete_pdp_conf(struct gsn_t *gsn, int version,
if (gtp_pdp_getgtp1(gsn, &pdp, get_tei(pack))) {
gsn->err_unknownpdp++;
GTP_LOGPKG(LOGL_NOTICE, peer, pack, len,
"Unknown PDP context: %u (expected if gtp_delete_context_req is used or pdp ctx was freed manually before response)\n",
get_tei(pack));
"Unknown PDP context: TEI=0x%" PRIx32 " (expected if "
"gtp_delete_context_req is used or pdp ctx was freed "
"manually before response)\n", get_tei(pack));
if (gsn->cb_conf)
gsn->cb_conf(type, EOF, NULL, cbp);
return EOF;
@@ -2765,7 +2836,8 @@ static int gtp_error_ind_conf(struct gsn_t *gsn, uint8_t version,
if (gtp_pdp_tidget(gsn, &pdp, get_tid(pack))) {
gsn->err_unknownpdp++;
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Unknown PDP context\n");
"Unknown PDP context: TID=0x%" PRIx64 "\n",
get_tid(pack));
return EOF;
}
} else if (version == 1) {
@@ -2790,7 +2862,9 @@ static int gtp_error_ind_conf(struct gsn_t *gsn, uint8_t version,
if (gtp_pdp_getgtp1_peer_d(gsn, &pdp, peer, teid_gn)) {
gsn->err_unknownpdp++;
GTP_LOGPKG(LOGL_ERROR, peer, pack, len, "Unknown PDP context\n");
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Unknown PDP context: Peer TEID=0x%" PRIx32 "\n",
teid_gn);
return EOF;
}
} else {
@@ -2821,22 +2895,22 @@ static int gtp_gpdu_ind(struct gsn_t *gsn, uint8_t version,
switch (version) {
case 0:
if (gtp_pdp_getgtp0(gsn, &pdp,
ntoh16(((union gtp_packet *)pack)->gtp0.h.flow))) {
if (gtp_pdp_getgtp0(gsn, &pdp, get_tei(pack))) {
gsn->err_unknownpdp++;
GTP_LOGPKG(LOGL_ERROR, peer, pack,
len, "Unknown PDP context, GTPv0\n");
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Unknown PDP context: TEI=0x%" PRIx32 "\n",
get_tei(pack));
return gtp_error_ind_resp(gsn, version, peer, fd, pack,
len);
}
hlen = GTP0_HEADER_SIZE;
break;
case 1:
if (gtp_pdp_getgtp1(gsn, &pdp,
ntoh32(((union gtp_packet *)pack)->gtp1l.h.tei))) {
if (gtp_pdp_getgtp1(gsn, &pdp, get_tei(pack))) {
gsn->err_unknownpdp++;
GTP_LOGPKG(LOGL_ERROR, peer, pack,
len, "Unknown PDP context, GTPv1\n");
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Unknown PDP context: TEI=0x%" PRIx32 "\n",
get_tei(pack));
return gtp_error_ind_resp(gsn, version, peer, fd, pack,
len);
}
@@ -3186,6 +3260,9 @@ int gtp_decaps1c(struct gsn_t *gsn)
case GTP_ERROR:
gtp_error_ind_conf(gsn, version, &peer, buffer, status);
break;
case GTP_RAN_INFO_RELAY:
gtp_ran_info_relay_ind(gsn, version, &peer, buffer, status);
break;
default:
gsn->unknown++;
GTP_LOGPKG(LOGL_ERROR, &peer, buffer, status,

View File

@@ -16,6 +16,7 @@
#include <osmocom/core/defs.h>
#include <osmocom/core/timer.h>
#include "gtpie.h"
#include "pdp.h"
#define GTP_MODE_GGSN 1
@@ -85,6 +86,7 @@
#define GTP_FWD_SRNS 58 /* Forward SRNS Context */
#define GTP_FWD_RELOC_ACK 59 /* Forward Relocation Complete Acknowledge */
#define GTP_FWD_SRNS_ACK 60 /* Forward SRNS Context Acknowledge */
#define GTP_RAN_INFO_RELAY 70 /* RAN Information Relay */
/* 61-239 For future use. */
#define GTP_DATA_TRAN_REQ 240 /* Data Record Transfer Request */
#define GTP_DATA_TRAN_RSP 241 /* Data Record Transfer Response */
@@ -276,6 +278,7 @@ struct gsn_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);
@@ -343,6 +346,11 @@ extern int gtp_delete_context_req2(struct gsn_t *gsn, struct pdp_t *pdp,
extern int gtp_data_req(struct gsn_t *gsn, struct pdp_t *pdp,
void *pack, unsigned len);
extern int gtp_ran_info_relay_req(struct gsn_t *gsn, const struct sockaddr_in *peer,
const uint8_t *ran_container, size_t ran_container_len,
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));
@@ -366,6 +374,9 @@ extern int gtp_set_cb_unsup_ind(struct gsn_t *gsn,
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));

View File

@@ -1,17 +1,17 @@
/*
/*
* OsmoGGSN - Gateway GPRS Support Node
* Copyright (C) 2002 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.
*
*
*/
/*
* gtpie.c: Contains functions to encapsulate and decapsulate GTP
* information elements
* gtpie.c: Contains functions to encapsulate and decapsulate GTP
* information elements
*
*
* Encapsulation

View File

@@ -18,7 +18,6 @@
#include <libgtpnl/gtp.h>
#include <libgtpnl/gtpnl.h>
#include <libmnl/libmnl.h>
#include <errno.h>
@@ -31,10 +30,6 @@
#include "../gtp/pdp.h"
#include "../gtp/gtp.h"
#include <libgtpnl/gtp.h>
#include <libgtpnl/gtpnl.h>
#include <libmnl/libmnl.h>
#include "gtp-kernel.h"
static void pdp_debug(const char *prefix, const char *devname, struct pdp_t *pdp)

View File

@@ -113,7 +113,7 @@ int main(int argc, char **argv)
msgb_talloc_ctx_init(tall_ctx, 0);
osmo_init_logging2(tall_ctx, &log_info);
log_set_use_color(osmo_stderr_target, 0);
log_set_print_filename(osmo_stderr_target, 0);
log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE);
srand(time(NULL));

View File

@@ -223,7 +223,7 @@ int main(int argc, char **argv)
msgb_talloc_ctx_init(tall_ctx, 0);
osmo_init_logging2(tall_ctx, &log_info);
log_set_use_color(osmo_stderr_target, 0);
log_set_print_filename(osmo_stderr_target, 0);
log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE);
test_queue_empty();
test_queue_one();

View File

@@ -431,7 +431,7 @@ int main(int argc, char **argv)
msgb_talloc_ctx_init(tall_ctx, 0);
osmo_init_logging2(tall_ctx, &log_info);
log_set_use_color(osmo_stderr_target, 0);
log_set_print_filename(osmo_stderr_target, 0);
log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE);
srand(time(NULL));

View File

@@ -131,7 +131,9 @@ int main(int argc, char **argv)
msgb_talloc_ctx_init(tall_ctx, 0);
osmo_init_logging2(tall_ctx, &log_info);
log_set_use_color(osmo_stderr_target, 0);
log_set_print_filename(osmo_stderr_target, 0);
log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE);
log_set_print_category(osmo_stderr_target, 0);
log_set_print_category_hex(osmo_stderr_target, 0);
srand(time(NULL));