Commit Graph

65 Commits

Author SHA1 Message Date
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
Harald Welte d46bcd236e IPv6: Implement IPv6 prefix assignment via ICMPv6 router advertisement
The 3GPP specs are quite strange when it comes to how an IPv6 address
or rather prefix is assigned to an IPv6 PDP context.  The designated
method for allocating the IPv6 address via the PDP EUA (End User
Address) Information Element in the GTP signalling plane is *not*
used to allocate the address/prefix.  Instead, the EUA is used to
allocate an "interface identifier" to the MS, which it the uses
to derive its link-local source address to send a router solicitation.

The GGSN subsequently answers witha router advertisement, advertising
a single/64 prefix, whihcthe MS then uses to generate it's real IPv6
source address for subsequent communication.

Change-Id: Icddf7d30e01d76a4784bcef5787b36f52f703a9f
2017-08-11 10:45:56 +02:00
Harald Welte d4d6e09fd2 ippool: Extend pool to work with /64 prefixes
In IPv6 GPRS, we actually don't want to allocate an individual v6
address (like in IPv4), but we want to allocate a prefix.  The
standard prefix lengh is 8 bytes, i.e. a /64 prefix.  This patch
extends the pool to be able to work with such v6 prefixes.

Change-Id: I0cf700b6baf195a2e5fbea000531f801acaaa443
2017-08-09 22:37:57 +02:00
Harald Welte 365f8fa462 in46_addr: Add new function in46a_prefix_equal()
This function is used to compare an IPv6 address against another,
using the smaller of the two prefix lengths.

Change-Id: Ic993d8abdc90897cb55276f01ae3b8a5eadf5a0d
2017-08-09 22:09:34 +02:00
Harald Welte d1bf1e11ba ggsn: Send proper errors in create_context_ind()
When we receive PDP context requests for unknown PDP types or if
we run out of dynamic addresses, we need to inform the SGSN that
PDP context creation failed.

Change-Id: Ibf199c1726130d27c8f80230b30ee51101c93b06
2017-08-09 22:09:34 +02:00
Harald Welte a0d281db1c IPv6 support for user IP
This patch enables the use of IPv6 PDP contexts.  The phone will
have to request an IPv6 End-user-Address, and the GGSN will have
to be configured for an IPv6 pool.

The outer transport-layer IP between SGSN and GGSN must still be
IPv4, it is not modified by this patch

Change-Id: I22c3bf32a98e5daf99d6eaeac8c9f95cc7574774
2017-08-09 22:09:34 +02:00
Harald Welte 53165ede24 ippool_new(): const-ify input arguments
Change-Id: If3e53584e8c9c1f06bba4c183c9fd65fae913904
2017-08-09 22:09:34 +02:00