Project

General

Profile

Actions

Bug #2746

closed

prod env: osmo-ggsn unable to get IPv6 link-local address

Added by pespin over 6 years ago. Updated about 6 years ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
Start date:
12/13/2017
Due date:
% Done:

100%

Spec Reference:

Description

gprs tests are currently failing when trying to create an ipv6 pdp context.

The issue is actually in osmo-ggsn returning an error when sgsn sends a Pdp Activate with IPv4v6. When the modem asks for an ipv4, it still uses a IPv4v6 (see #2713) but when the error is returned it re-tries with a IPv4-only EUA and then it works. However for IPv6 it doesn't and it returns a failure through the dbus interface.

Now the interesting part for this ticket: How osmo-ggsn fails.

When receiving a request for an ipv4v6 ctx, osmo-ggsn tries to get one IP of each type from the pools in the APN. Before looking in the pool, it checks if the APN actually supports this kind of address / has this type of pool. When checking for the IPv6 pool, it fails printing the following + sending a packet back with an error:

20171213174828668 DGGSN <0002> ggsn.c:635 PDP(901700000015252:6): APN doesn't support requested EUA / AF type

That happens because the following path triggers:

            /* does this APN actually have an IPv6 pool? */
            if (!apn_supports_ipv6(apn))
                goto err_wrong_af;

which means the ipv6 pool was not configured successfully at startup. We can actually see it in log file:

20171213174741477 DGGSN <0002> ggsn.c:201 APN(internet): Starting
20171213174741477 DGGSN <0002> ggsn.c:204 APN(internet): Opening TUN device tun4
20171213174741478 DGGSN <0002> ggsn.c:209 APN(internet): Opened TUN device tun4
20171213174741478 DGGSN <0002> ggsn.c:220 APN(internet): Setting tun IP address 176.16.222.1/24
20171213174741480 DGGSN <0002> ggsn.c:283 APN(internet): Creating IPv4 pool 176.16.222.0/24
20171213174741481 DGGSN <0002> ggsn.c:185 APN(internet): Blacklist tun IP 176.16.222.1/24
20171213174741481 DIP <0000> ippool.c:295 addr blacklisted from pool: 176.16.222.1
20171213174741481 DGGSN <0002> ggsn.c:314 APN(internet): Successfully started
20171213174741482 DGGSN <0002> ggsn.c:201 APN(inet6): Starting
20171213174741482 DGGSN <0002> ggsn.c:204 APN(inet6): Opening TUN device tun6
20171213174741482 DGGSN <0002> ggsn.c:209 APN(inet6): Opened TUN device tun6
20171213174741482 DGGSN <0002> ggsn.c:232 APN(inet6): Setting tun IPv6 address fde4:8dba:82e1:2000::/56
20171213174741484 DGGSN <0002> ggsn.c:252 APN(inet6): Cannot obtain IPv6 link-local address of interface: Success
20171213174741484 DGGSN <0002> ggsn.c:115 APN(inet6): Stopping
20171213174741484 DGGSN <0002> ggsn.c:128 APN(inet6): Closing TUN device tun6
20171213174741503 DGGSN <0002> ggsn.c:201 APN(inet46): Starting
20171213174741503 DGGSN <0002> ggsn.c:204 APN(inet46): Opening TUN device tun46
20171213174741504 DGGSN <0002> ggsn.c:209 APN(inet46): Opened TUN device tun46
20171213174741504 DGGSN <0002> ggsn.c:220 APN(inet46): Setting tun IP address 176.16.46.0/24
20171213174741505 DGGSN <0002> ggsn.c:232 APN(inet46): Setting tun IPv6 address fde4:8dba:82e1:2000::/56
20171213174741506 DGGSN <0002> ggsn.c:252 APN(inet46): Cannot obtain IPv6 link-local address of interface: Success
20171213174741506 DGGSN <0002> ggsn.c:115 APN(inet46): Stopping
20171213174741506 DGGSN <0002> ggsn.c:128 APN(inet46): Closing TUN device tun46
20171213174741535 DGGSN <0002> ggsn.c:812 GGSN(ggsn0): Starting GGSN

As you can see, it fails to configure ipv6 pools because it fails to get the IPv6 link-local address from the tun iface:

20171213174741506 DGGSN <0002> ggsn.c:252 APN(inet46): Cannot obtain IPv6 link-local address of interface: Success

Later on it fails with different errno:

20171213174741549 DGGSN <0002> ggsn.c:252 APN(inet6): Cannot obtain IPv6 link-local address of interface: No such file or directory

The only path in tun/netdev_ip_local_get which can return an error and issues a syscall is:

    if (getifaddrs(&ifaddr) == -1) {
        return -1;
    }

This function only receives a pointer and has no context associated with our code. It actually works fine in R&D env (debian9 in R&D vs debian 8 in Prod), which means there's a bug in libc or kernel in debian8.

debian8 (Prod):
- Debian GLIBC 2.19-18+deb8u10
- #1 SMP Debian 3.16.43-2+deb8u2 (2017-06-26)

debian9 (R&D):
- Debian GLIBC 2.24-11+deb9u1
- kernel: 1 SMP Debian 4.9.30-2+deb9u3 (2017-08-06)

"man getifaddrs":

RETURN VALUE
       On success, getifaddrs() returns zero; on error, -1 is returned, and errno is set appropriately.

ERRORS
       getifaddrs() may fail and set errno for any of the errors specified for socket(2), bind(2), getsockname(2), recvmsg(2),  sendto(2),
       malloc(3), or realloc(3).
VERSIONS
       The  getifaddrs()  function  first appeared in glibc 2.3, but before glibc 2.3.3, the implementation supported only IPv4 addresses;
       IPv6 support was added in glibc 2.3.3.  Support of address families other than IPv4 is  available  only  on  kernels  that  support
       netlink.

So regarding glibc version it should support ipv6 addresses (it doesn't mean there aren't bugs in there though), and "kernel that support" netlink it's a big difficult to match to a specific version.

In any case, it seems like another good reason to upgrade production environment to debian 9.


Files

bla bla 52.2 KB pespin, 12/13/2017 07:44 PM
bla-rnd bla-rnd 134 KB pespin, 12/13/2017 07:56 PM
Actions

Also available in: Atom PDF

Add picture from clipboard (Maximum size: 48.8 MB)