Commit Graph

71 Commits

Author SHA1 Message Date
Pau Espin 1ef2621d3f gtp-kernel.c: Fix wrong use of in46a_from_eua, print IPv6 euas
in46a_from_eua() API documentation clearly states an array of 2 items
should be passed as pointer, but show_one_pdp() was passing only one,
which would end up in out-of-bounds writes on v4v6 EUAs.

Let's better use ippool to print allocated ip addresses instead of
parsing EUAs we sent some point in the past.

Change-Id: I7e164f40f50de43027bcd4464aa879450d2fb10e
2019-08-28 11:14:57 +02:00
Pau Espin f612ffea82 Move pdp_get_peer_ipv() to lib/util.*
Preparation for next commit, where this function will be needed inside
libmisc (lib/*).

Change-Id: Ibab4f6c09d1e5f0e9cfaea28ae1e7ab5b5c219b5
2019-08-28 11:14:57 +02:00
Pau Espin 95cd897c3f in46_addr: Improve in46a_ntop documentation
Change-Id: I27238c330f9b805ac9e734e735d2c7ae158fe524
2019-08-28 11:14:51 +02:00
Pau Espin 60ee0dbfa4 Introduce in46a_is_v{4,6}() helpers
It's clearer having size-related checks in one place for a data structure
in46_addr, instead of spread around the code.

Change-Id: Idc94bf0c8c01bb5a30e36d3c284b99f66b972abb
2019-08-28 11:13:32 +02:00
Stefan Sperling b0b9c28284 properly store IPv6 addresses in struct tun_t
All addresses in struct tun_t were stored as an in_addr.
But IPv6 addresses need an in6_addr, so switch tun_t addresses
to the in64_addr wrapper struct.

This is an ABI break, as documented in TODO-RELEASE.

Fixes an out of bounds memcpy() identified by Coverity.

Change-Id: Idd2431ad25d7fa182e52e2bd5231ceb04d427c34
Related: CID#174278
2018-11-22 14:12:40 +00:00
Stefan Sperling cc8181fefe fix format string error in ippool_printaddr()
The variable this->listsize is an unsigned int, but the format
string assumed ptrdiff_t. Found by Coverity.

Change-Id: Ib2a55907adae98f8aa7b079f1c9a3b4fc5f67fc5
Related: CID#188879
2018-11-22 13:17:01 +00:00
Stefan Sperling 7327360d10 initialize local variable addr in ippool_new()
Coverity points out that addr.len was potentially being used
uninitialized, via calls to in46a_inc(&addr).

Change-Id: Idb67394e5f4c2072380a33f46c848d92c4317245
Related: CID#174189
2018-11-22 13:16:50 +00:00
Stefan Sperling e405c2f196 replace bogus memcpy() call in ippool_newip()
When copying an address to a reused static hash table member
with memcpy(), this code mistakenly passed the size of a
pointer as the amount of bytes to be copied, rather than
the actual size of the address.

This means the IP pool could contain bogus IP addresses because
only addr->len (a uint8_t) and 3 further bytes of the address
were actually copied on 32 bit platforms. On 64 bit platforms,
a sufficient amount of bytes were copied for IPv4 to work
correctly, but too few bytes were copied for IPv6.

This problem was found by Coverity.

Replace the bogus memcpy() call with direct assignments to the
appropriate struct in64addr union members, and assert that the
length recorded for the address actually corresponds to the
length used by the address family (IP4, IPv6).

Change-Id: Ic21560f7519e776107485a8779702fb1279d065c
Related: CID#57921
2018-11-22 13:16:29 +00:00
Stefan Sperling 411ff3b984 fix allocation of ippool's hash table
The calloc() call in ippool_new() had two problems.

The first problem is benign: The order of arguments were reversed.
Pass the number of elements in the array first, then the size of
each element, as calloc() expects.
This problem was found by me. There are more instances of this
problem in this file, which I'll address in follow-up patches.

The second problem is that the requested allocation was larger than
necessary: The hash table is an array of pointers to ippoolm_t, not
an array of struct ippoolm_t. Fix the required size passed to calloc().
This problem was found by Coverity.

Change-Id: I93fa5bc539771ca19714f6a665558c9140e2ce07
Related: CID#57920
2018-11-22 07:00:54 +00:00
Stefan Sperling aee905b790 check ioctl() call return value in tun_new()
Coverity complains about a missing ioctl() return value check.
Check for failure of the TUNSETNOCSUM ioctl and log a warning
if it fails.

Change-Id: I88da2164d975d7a232619b8d31c5eadeef0f3a80
Related: CID#57661
2018-11-21 14:14:10 +01:00
Harald Welte fb75adfeda ippool.c: Use "%td" format string for ptrdiff_t
Change-Id: Iacafa0919baebac6b5a799deb41a673c022c6743
Fixes: Coverity CID#135225
2018-10-21 13:30:07 +02:00
Harald Welte f2286395e9 Move kernel GTP support from ggsn/ to lib/
This way, the IP address / route handling between TUN devices and kernel
GTP can be shared, which will provide not only a unified codebase but
also a more consistent behavior.

This also paves the road for to use kernel GTP from sgsnemu in the future.

Related: OS#3214
Change-Id: Ic53a971136edd0d8871fbd6746d7b0090ce3a188
2018-04-25 21:44:46 +02:00
Harald Welte 9eebe15cd1 lib/tun: Remove tun_setaddr() API, as everyone is using tun_addaddr() now
Change-Id: I02e057d30b6773c17ea6bc31094e53587971e9e7
2018-04-25 21:41:43 +02:00
Harald Welte 47adad0817 lib/netdev.c: Cosmetic changes (coding style / cleanups)
Change-Id: I60cbca616a4f727e2374c52715f9286a0f4c5e4b
2018-04-25 21:41:43 +02:00
Harald Welte c5efb5bccb lib/tun: split generic network device related stuff to lib/netdev
Change-Id: Ib021e392637a43d5cf1b40e0d50621fe7e854ba5
2018-04-25 21:41:41 +02:00
Harald Welte 9a6da455b9 lib/tun.c: Generalize tun_{set,add}addr*() functions
There's nothing really tun-specific about the adding and removing of
addresses to network devices.  Let's generalize the related code.

Change-Id: I139a950dd81a4b1199953be1608cd109a060f562
2018-04-25 21:40:30 +02:00
Harald Welte b4c0828039 lib/tun.c: generalize tun_*route() to netdev_*route()
There's nothing specific to tun devices in adding a route to the kernel.

Change-Id: Ib077934aa5f3c9bed06e2cf16a980c965a7a046d
2018-04-25 20:46:05 +02:00
Harald Welte df3dcac439 lib/tun.c: Generalize tun_sifflags() to netdev_sifflags
There's nothing "tun" specific about that function, let's clarify that.

Change-Id: Iae7ced700245d6c1ac7e9807ab80d12fde8da116
2018-04-25 20:46:05 +02:00
Pau Espin f5e40b7011 Set tun_addaddr ipv agnostic and add support for ipv6
sgsnemu (the only user of this API so far) has been modified to use the
new API with in46_addr.

FreeBSD code for IPv6 has not been tested.

Change-Id: Ie36afe6eaf393855a4a708000ef4ad0192bf4767
2017-12-14 14:49:12 +00:00
Pau Espin 02e21af657 tun.c: tun_addaddr: Fix segfault and wrong usage of tun_nlattr
First of all, dstaddr can be NULL, avoid copying it in that case.
Second, we want to copy the addr data, not the pointer. I tested it and
the IP was not added (not shown in ip addr) until I copied the content
instead of the address.

Change-Id: I8da637b155f0e913cab6c5b0dde355c9f33375b5
2017-12-14 14:49:12 +00:00
Pau Espin 2d6a69e69a Add support for IPv4v6 End User Addresses
Before this commit, when an MS requested an ipv4v6 context osmo-ggsn
returned an error stating the type was unknown, and this text was
printed in the log:
Processing create PDP context request for APN 'ims'
Cannot decode EUA from MS/SGSN: f1 8d

This patch has been tested with an MS running the 3 types of addresses:
- IPv4 and IPv6: no regressions observed, the context is activated and
packets are sent to the ggsn.
- IPv4v6: Wireshark correctly parses request and reponse, and then
ICMPv6 traffic from both sides. Finally I see the MS using the IPv4 and
IPv6 DNS addresses advertised and TCP traffic over IPv4 (because
probably my IPv6 network setup is not correct). I also checked I can
disable/enable data (pdp ctx delete and activate) several times without
any issue.

Change-Id: Ic820759167fd3bdf329cb11d4b942e903fe50af5
2017-12-11 11:39:18 +01:00
Pau Espin b9ace14717 cosmetic: Reorder tun_addaddr to get rid of decl of tun_setaddr4
In any case, if we add support for ipv6 in tun_addaddr we will need
tun_setaddr (and also change the API of tun_addaddr to use in46_addr).

Change-Id: Iadf51379455174a642b477040ec96f28022c24c7
2017-12-01 15:40:32 +01:00
Pau Espin d9fff0c543 tun_setaddr6: Fix log typo
Change-Id: Id7f7d33a33730d57c5ecf7ebf5612f4744cf5163
2017-12-01 15:39:28 +01:00
Harald Welte 4c7d29107f factor out netdev_ip_local_get() from tun_ip_local_get()
netdev_ip_local_get() is a generalized version of tun_ip_local_get()
which supports the net device as argument, rather than a tun_t.

Change-Id: I072aa1a55e7bf110706e9207021b776d9b977fb6
2017-11-13 23:57:58 +09:00
Harald Welte fc6676c4a0 ippool: Correctly compute size of static pool
* we have to use stataddr, not addr (dynamic)
* we have to multiply the length of the address by 8 to get its bit length
* we can simplify the -1 +1 logic (like dynamic)

Change-Id: I174102051bef95f7df34b7d7c480a00ae408be7d
Fixes: Coverity CID#174189
2017-11-06 03:38:54 +09:00
Harald Welte 1af543f44c tun: Don't copy 16byte IPv6 address to 'struct in_addr'
The 'struct tun' curently only has an in_addr (v4-only) member to
store the address of the tun device, so let's not attempt to store
an IPv6 address in it.

FIXME: This entire code needs an overhaul. The assumption that there's
only one address, and only either v6 or v4 is broken to begin with.

Change-Id: If0b626d688841d6e0a3867834f4cb1b70084050e
Fixes: Coverity CID#174278
2017-11-06 03:32:52 +09:00
Pau Espin 859f9b0752 ippool: Implement and use blacklist instead of blindly using IPPOOL_NOGATEWAY
Commit dda21ed7d4 modified previous calls
to ippool_new() removing the pass of flags to avoid allocating certain
problematic IPs from the pool to MS, such as the network, gateway and
broadcast IPs.

Today I did some unsucessful tests with osmo-ggsn with a pool "ip prefix
dynamic 176.16.222.0/24", and thus IP 176.16.222.0 was being assigned to
the MS. De-capsulated DNS packets were received in the tun interface,
but the Linux system in there was unable to correctly forward the
packets to the gateway interface connected to the Internet. However,
adding a second MS which got 176.16.222.1 had its packets forwarded
correctly.

However, previous implementation relies on flag IPPOOL_NOGATEWAY flag to
blindly blacklist first IP after the network ip (ie, .0 and .1 are
removed), which limits the IP reserved for the tun device to be .1. If a
different IP in the range is assigned, it may cause issues. As a result,
a blacklist is introduced in this commit to dynamically fetch the tun IP
address and exlucde it from the pool of available IPs.

Change-Id: I8e91f7280d60490c858a769dd578c1c8e54e9243
2017-10-17 19:10:24 +02:00
Pau Espin a037e5908a tun: Convert tun_ipv6_linklocal_get to be more generic
Add support for IPv4 and IPv6 global IPs. Also return the prefix length
of the IP address by using a in46_prefix.

Change-Id: I277af191dc611b6bbcb83479f4ae338083740322
2017-10-16 17:45:48 +02:00
Pau Espin 2e7b9ff891 lib/in46a: Introduce in46a_netmasklen API
Change-Id: I06e3e038afd8f7afaec2a3fa67b1616500c8db80
2017-10-16 17:45:40 +02:00
Pau Espin 361cb9e910 lib/ippool: Fix listsize calculated 1 elem too small
Take the chance this commit is changing test output to also remove use
of IPPOOL_NOGATEWAY which is going to be removed soon, and instead test
IPPOOL_NOBROADCAST.

Change-Id: I95c24bc690490155bec9e3933d678e4668d7745f
2017-10-16 11:59:43 +02:00
Harald Welte 34a7416ec0 in46a_to_sas(): Return AF_INET6 in case of IPv6 address
Change-Id: Ia2f9ac60f08823d5f7c1a76c0b7cbd65ac615e26
2017-10-13 16:28:01 +02:00
Pau Espin fdd732b130 Remove trailing whitespace
Change-Id: I8e24f95a88bef3a59006a89c219871e6156963d7
2017-10-13 16:28:01 +02:00
Pau Espin 58c0da7833 lib/tun.c: tun_ipv6_linklocal_get(): fix memory leak with getifaddrs()
From getifaddrs(3) man:
"The data returned by getifaddrs() is dynamically allocated and should
be freed using freeifaddrs() when no longer needed"

Change-Id: If6300d1c8d36fcafef294a4c11bbda31a158bb9c
2017-10-12 18:00:16 +02:00
Harald Welte cee7546f15 Replace EUA magic numbers for IETF, IPv4 and IPv6 with #defines
Change-Id: I33f65e404217e717bd795e5229c8d9456a7b3739
2017-10-01 18:19:07 +08:00
Harald Welte f85fe9720b ICMPv6: Send router advertisement from own link-local address
I'm not quite sure how I ended up doing this, but for some strange
reason the code before this commit is sending the ICMPv6 Router
Advertisements from some weird non-standard source address.  This is
a violation of RFC4861 which clearly states that the source address
of router advertisements "MUST be the link-local address assigned to the
interface from which this message is sent."

Change-Id: Ib444af70fc8f0b433d371281601fd5a37b29039e
2017-09-24 20:51:47 +08:00
Harald Welte dda21ed7d4 Introduce a VTY, factually turning OpenGGSN into an Osmocom program
Change-Id: I9613ca3436e77ea132c47f0096df7c5050d7e826
2017-09-06 09:17:11 +02:00
Harald Welte 2778ae2b8f lib/tun: Mark internal helper functions 'static'
Change-Id: I53a8a89abb0080a39a153e9d3864c17b29aa193c
2017-09-05 23:13:14 +02:00
Harald Welte 1b6e8e7b5e Remove __sun__ code that is unmaintained
We haven nobody maintaining this platform, let's remove it.

In fact, only Linux and FreeBSD are part of the jenkins build tests,
so even Apple/MacOS is up for disposal.  However, as it's more
popular, let's keep the code.

Change-Id: Id6b8179259bacade52c39f96e688f828eff164ac
2017-09-05 23:13:14 +02:00
Harald Welte 9e6dfa0558 lib/tun.c: Proper cleanup during tun_new() error paths
Change-Id: I285be20df76774ac7258b6edb3d4f2d28703757d
2017-09-05 22:42:18 +02:00
Harald Welte 4857f3c2f3 lib/ippool: Move ippool_aton() out of ippool_new()
we rather pass the in46_prefix directly into ippool_new()

Change-Id: Iadf6274e881a9bfc75eb41f9380f5ae2d8c92a0f
2017-09-05 22:42:18 +02:00
Harald Welte b513b951bd lib/ippool: Add back-pointer from pool member to pool
This allows us to remove pool members without having to keep
a pointer to the pool around.

Change-Id: I9042eb85989c5451d7894678eca110dd19e78002
2017-09-05 22:42:17 +02:00
Harald Welte 33520b43ec lib/in46_addr: Avoid ASSERT() when in46a_ntop() is called on uninitialized address
Change-Id: I42d41ec1370b9cc15d372b649d8e1bc78e76af9b
2017-09-05 22:42:17 +02:00
Harald Welte 7fc8694b97 lib/in46_addr: Add 'struct in46_prefix' to represent addr + prefix
Change-Id: I797d105117e81951732bcfc2cc26a8d00fd69443
2017-09-05 22:42:17 +02:00
Harald Welte b62983d3c3 lib/in46_addr: Add in46a_ntoa() function, similar to inet_ntoa()
Change-Id: I752b7033a106a74dc219047da5c3a7ad3cd3602e
2017-09-05 22:42:17 +02:00
Harald Welte 881e97ed00 lib/tun: Add 'void *priv' pointer to tun_t
This allows the application to attach some private state to the tun
device, such as the context from which it was created/allocated

Change-Id: Ief43b9b5fab5830fa8e28362c795f88f0b4d353b
2017-09-05 22:42:17 +02:00
Harald Welte c55ece8d91 lib/tun: Add missing #include to net/if.h for IFNAMSIZ
Change-Id: I979867d643c9fa912884fe55105333dbad39ab97
2017-09-05 22:42:17 +02:00
Harald Welte 81bc2aea53 tun_new(): Fix array overflow in FreeBSD related code
Change-Id: I096e3b614e82e402886163274cfcf9355bd57580
2017-08-11 13:12:09 +02:00
Harald Welte ab6d189f8f replace hand-coded tun_gifindex() with standard POSIX if_nametoindex()
Change-Id: I738472765ab09f530dcf071455e1bb4e6fb3f6e5
2017-08-11 13:12:09 +02:00
Harald Welte 2e48a44952 Support setting TUN device IPv6 address + prefix
As we can now have PDP contexts with IPv6 user IP payload,
it is useful to extend the TUN related code to be able to
configure the tun device IPv6 address + prefix length

Change-Id: I899d21e52d02e0b8384af29ddd489ff19c8f2cf6
2017-08-11 13:12:04 +02:00
Harald Welte 72a38b55e3 IPv6: in46_addr: OSMO_ASSERT() in case of unsupported calls
There's a bit of trickery with the ip_pool and it's "lengty=8" IPv6
prefix handling, let's make sure we don't accidentially call any
support functions with addresses of wrong length.

Change-Id: I444c190bdcd18780344e1f0dad4faf3bcf9da5a5
2017-08-11 10:46:00 +02:00