Feature #2418

IPv6 PDP context support

Added by laforge 17 days ago. Updated 6 days ago.

Target version:
Start date:
Due date:
% Done:


Spec Reference:


Even while the transport (outer) layer is still v4-only, it would be great to finally have IPv6 PDP context (inner) layer support.

There is a user-contributed patch at

This patch needs to be tested if it actually works at all (dexter) and the code review related modifications need to be made.

@dexter: I've already done a first round of 12 comments on June 11, so after the testing you could also go through those, address them and re-submit a new version of the patch. I'll do another round after the testing has concluded and the old comments are adressed.

ipv6_pdp_context_reject.pcapng (480 Bytes) dexter, 08/03/2017 12:30 PM

trace_v6pdpctx_act_and_deact_04072017.tar (1.62 MB) dexter, 08/04/2017 05:39 PM

v6.conf Magnifier - OpenGGSN config for v6 prefix (2.41 KB) laforge, 08/09/2017 08:16 AM

trace_v6pdpctx_act_and_deact_09082017.tar (2.36 MB) dexter, 08/09/2017 10:50 AM

trace_ipv6_test_android_10082017.pcapng (14.1 KB) dexter, 08/10/2017 09:36 AM

trace_ipv6_test_nokiaE90_10082017.pcapng (29.4 KB) dexter, 08/10/2017 09:36 AM


#1 Updated by laforge 16 days ago

  • Status changed from New to In Progress
  • Assignee changed from dexter to laforge

the patch is against a >= 10 years old openggsn version, will require lots of manual porting work :/

#2 Updated by laforge 16 days ago

  • % Done changed from 0 to 70
remote: ippool: Add IPv6 support to IP pool implementation
remote: lib/tun.h: Remove non-endian-safe redefinition of IP header
remote: ippool_new(): const-ify input arguments
remote: IPv6 support for user IP
remote: ggsn: Send proper errors in create_context_ind()
remote: Support setting TUN device IPv6 address + prefix

#3 Updated by dexter 15 days ago

I have configured the ggsn as suggested in:


net 2001:780:44:2000:0:0:0:0/120

First I expected a problem with the sgsn, since this is the untested component,
but it may also be a problem with the ggsn as well. The debug output of
openggsn shows:

<0000> ippool.c:454 MS requested unsupported PDP context type
<0002> ggsn.c:202 Cannot allocate IP address in pool

This means that the ggsn is the entity that rejects the pdp context.
The attached trace also confirms that.

The sgsn log also displays the reject:

<000f> gprs_sgsn.c:898 Checking for inactive LLMEs, time = 52892
<0011> gprs_bssgp.c:789 BSSGP BVCI=2 Rx Flow Control BVC
<0010> gprs_ns.c:614 NSEI=101 Timer expired in mode tns-test (30 seconds)
<0010> gprs_ns.c:547 NSEI=101 Tx NS ALIVE (NSVCI=101)
<0010> gprs_ns.c:586 NSEI=101 Starting timer in mode tns-alive (3 seconds)
<0010> gprs_ns.c:586 NSEI=101 Starting timer in mode tns-test (30 seconds)
<0010> gprs_ns.c:560 NSEI=101 Tx NS ALIVE_ACK (NSVCI=101)
<0011> gprs_bssgp.c:789 BSSGP BVCI=2 Rx Flow Control BVC
<0011> gprs_bssgp.c:379 BSSGP TLLI=0xa1df35c3 Rx UPLINK-UNITDATA
<0012> gprs_llc.c:522 LLC RX: unknown TLLI 0xa1df35c3, creating LLME on the fly
<0012> gprs_llc_parse.c:82 LLC SAPI=1 C   U GEA0 IOV-UI=0x000000 FCS=0xb9e3eb CMD=UI DATA 
<0002> gprs_gmm.c:1241 MM(---/ffffffff) -> GMM ATTACH REQUEST MI(3789501891) type="GPRS attach" 
<0002> gprs_sgsn.c:231 MM(/00000000) Allocated with GEA0 cipher.
<0002> gprs_gmm.c:546 MM(/c6babf03) <- GPRS IDENTITY REQUEST: mi_type=IMEI
<0011> gprs_bssgp.c:379 BSSGP TLLI=0xa1df35c3 Rx UPLINK-UNITDATA
<0012> gprs_llc_parse.c:82 LLC SAPI=1 C   U GEA0 IOV-UI=0x000000 FCS=0x41d70b CMD=UI DATA 
<0002> gprs_gmm.c:1180 MM(/c6babf03) -> GMM IDENTITY RESPONSE: MI(IMEI)=354391077046600
<0002> gprs_gmm.c:546 MM(/c6babf03) <- GPRS IDENTITY REQUEST: mi_type=IMSI
<0011> gprs_bssgp.c:379 BSSGP TLLI=0xa1df35c3 Rx UPLINK-UNITDATA
<0012> gprs_llc_parse.c:82 LLC SAPI=1 C   U GEA0 IOV-UI=0x000000 FCS=0x00e248 CMD=UI DATA 
<0002> gprs_gmm.c:1180 MM(/c6babf03) -> GMM IDENTITY RESPONSE: MI(IMSI)=001010000000102
<0002> sgsn_auth.c:160 MM(001010000000102/c6babf03) Requesting authorization
<0002> sgsn_auth.c:219 MM(001010000000102/c6babf03) Updating authorization (unknown -> accepted)
<0002> sgsn_auth.c:248 MM(001010000000102/c6babf03) Got authorization update: state unknown -> accepted
<0002> gprs_gmm.c:1104 MM(001010000000102/c6babf03) Authorized, continuing procedure, IMSI=001010000000102
<0002> gprs_gmm.c:427 MM(001010000000102/c6babf03) <- GPRS ATTACH ACCEPT (new P-TMSI=0xc6babf03)
<0011> gprs_bssgp.c:379 BSSGP TLLI=0xc6babf03 Rx UPLINK-UNITDATA
<0012> gprs_llc_parse.c:82 LLC SAPI=1 C   U GEA0 IOV-UI=0x000000 FCS=0xea1c55 CMD=UI DATA 
<0002> gprs_gmm.c:1998 MM(001010000000102/c6babf03) -> ATTACH COMPLETE
<0002> gprs_gmm.c:170 MM(001010000000102/c6babf03) Changing MM state from MM IDLE to MM READY
<0011> gprs_bssgp.c:379 BSSGP TLLI=0xc6babf03 Rx UPLINK-UNITDATA
<0012> gprs_llc_parse.c:82 LLC SAPI=1 C   U GEA0 IOV-UI=0x000000 FCS=0x1a0d86 CMD=UI DATA 
<0002> gprs_gmm.c:2442 MM(001010000000102/c6babf03) -> ACTIVATE PDP CONTEXT REQ: SAPI=3 NSAPI=5 IETF IPv6 
<0002> gprs_sgsn.c:862 MM(001010000000102/c6babf03) Found GGSN 0 for APN 'internet' (requested 'internet')
<0002> gprs_gmm.c:2329 MM(001010000000102/c6babf03) Using GGSN 0
<000f> sgsn_libgtp.c:148 Create PDP Context
<0025> pdp.c:215 Begin pdp_tidset tid = 5201000000010100
<0025> pdp.c:224 End pdp_tidset
<000f> sgsn_libgtp.c:594 libgtp cb_conf(type=16, cause=220, pdp=0x7f6616bfe320, cbp=0x55fde5d3dcd0)
<000f> sgsn_libgtp.c:369 PDP(001010000000102/0) Received CREATE PDP CTX CONF, cause=220(Unknown PDP address or PDP type)
<0025> pdp.c:233 Begin pdp_tiddel tid = 5201000000010100
<0025> pdp.c:240 End pdp_tiddel: PDP found
<0002> gprs_gmm.c:2255 MM(001010000000102/c6babf03) <- ACTIVATE PDP CONTEXT REJ(cause=28)
<0011> gprs_bssgp.c:789 BSSGP BVCI=2 Rx Flow Control BVC

I wonder what could be wrong here. I have tried the sgsn emulator, but I can
only get it to a point where it requests an IPV4 pdp context (which also
gets rejected, which is expected with the current configuration). I start
sgsnemu as follows:

./sgsnemu --l -r

Maybe there is commandline argument missing. commandline argument?

I suspect either a problem with my ggsn configuration. It might also be that
the pdp context request that the sgsn generates might have some issues.

#4 Updated by laforge 15 days ago

It was working once but I broke it later in some cleanup :/

I've just (force-)pushed a fix to laforge/ipv6, please retry using the new version.

The v6 activation has now been tested against my brand-new TTCN-3 testcase for
PDP context activation, which supports both v4 and v6 contexts. I'll expand on this
and hopefully we can integrate this with Jenkins soon.


#5 Updated by dexter 14 days ago

I gave it another try. I have tested it with IPV4 and IPV6. For IPV4 everything
is fine so far. But IPV6 seems not to work.

The IPV6 pdpd context is successfully established, but it is not possible to
transfer any data. I would have expected that at least pinging the phone is
possible. There is data flowing between the phone and the network, but as
I can see so far by the log its only Rx UPLINK-UNITDATA. There is no TX data.

On the tun0 interface, as well as on the GTP link, the only messages that
appear are Router Solicitation and Neighbor Solicitation. When I look at
the GB interface I see the messages there as well, so these messages seem
to be mobile originated. However, I do not understand why source and
destination address is does not fall in the assigned range. When I look
at the pdp context ack. I can see the expected address is assigned.

The bahviour is cyclic, the phone establishes a pdp context, for a short time,
data is transfered. Then the pdp context is deactivated. After some time the
same happens again.

I have also checked with the communicator again. The communicator now shows
also the same behaviour. I also tried with a qualcomm modem. The same there

Trades, logs and configs can be found in:


#6 Updated by laforge 13 days ago

It's good to see that the signaling plane seems to work end-to-end, i.e.
the v6 PDP context is established successfully and a dynamic IPv6 address
is allocated.

The only odd part I can see on the signaling/control plane is the fact that
the PCO contain as DNS server IP adresses. This is odd in two ways:

a) if there are no DNS servers, why report instead of simply not
sending any DNS Server PCO back to the MS
b) if the PDP context is IPv6, the DNS Server addresses inherently also must
be IPv6. The MS has no way to talk to an IPv4 DNS server if it has an
IPv6 (only) PDP context

The MS then subsequently sends router and neighbor discovery requests which are
unanswered. The big question is how that is supposed to work on a point-to-point
interface anyway. In IPv4 there is no broadcast/ARP involved on such interfaces.

I'll read up with the relevant specs and will extend the TTCN-3 tests to transmit
the exact same router and neighbor discovery reqests to be able to develop
and test without having to set up the entire cellular network + phone for each

#7 Updated by laforge 13 days ago

Ok, I found Section of 3GPP TS 29.061 which details the process. For some
strange reason, they decided to make it significantly more complex than in the IPv4
case, while at the same time making it not entirely compatible/compliant with what
IETF IPv6 usually does.

Other apparently related documents: RFC3314, RFC7066, RFC6459, TS 23.060 9.2.1

My understanding at this point:

  • the IPv6 address sent in the EUA IE of the PDP CTX ACT ACK from the GGSN
    is not used for actual traffic, but is only used for allocating an
    "interface identifier" to the MS/UE. This "interface identifier" is
    formed from the lower 64 bits of the prefix, while the upper 64 bits
    are being discarded.
  • the MS/UE uses RFC2373 Section 2.5.8 to construct a link-local unicast
    address from this "interface identifier". This means: * lower 64 bits are the "interface identifier" * upper 64 bits are fe80:0000:0000:0000
  • the MS may send a "router solicitation" icmpv6 message to trigger the GGSN
    to send a router advertisement to the MS (optional!)
  • The GGSN sends a Router Advertisement message. The Router
    Advertisement messages shall contain the same prefix as the one
    provided in the PDP CTX ACT ACK. A given prefix shall not be
    advertised on more than one PDP context on a given APN, or set of
    APNs, within the same addressing scope. The GGSN shall be configured
    to advertise only one prefix per PDP context.
  • After the MS has received the Router Advertisement message, it
    constructs its full IPv6 address by concatenating the interface
    identifier received in PDP CTX ACT ACK, or a locally generated interface
    identifier, and the prefix received in the Router Advertisement. If
    the Router Advertisement contains more than one prefix option, the MS
    shall only consider the first one and silently discard the others.
  • Because any prefix that the GGSN advertises in a PDP context is unique
    within the scope of the prefix (i.e. site- local or global), there is
    no need for the MS to perform Duplicate Address Detection for this
    IPv6 address. Therefore, the GGSN shall silently discard Neighbor
    Solicitation messages that the MS may send to perform Duplicate
    Address Detection.
  • It is possible for the MS to perform Neighbor Unreachability Detection
    towards the GGSN, as defined in RFC 246171; therefore if the GGSN
    receives a Neighbor Solicitation as part of this procedure, the GGSN
    shall provide a Neighbor Advertisement as described in RFC 2461.

So now we know we need to implement router advertisements inside the
GGSN before we can proceed...

#8 Updated by laforge 9 days ago

  • File v6.confMagnifier added
  • Assignee changed from laforge to dexter

Hi Philipp,

it should be working now, at least more than before. In my test case, I can now see a seemingly-valid router advertiement in response to the routeer solicitation. Could you give current laforge/ipv6 another [quick] try, please?

My ggsn config file is attached. The important part is to have a pool with a prefix shorter than 64 bits, i.e. something like /56, so you have 256 prefixes that can be allocated to individual MSs.

#9 Updated by dexter 9 days ago

Hello Harald,

I have tried it again. I can see the router advertisements going up the gb interface. However, the pdp context still closes after a few seconds. I have attached the archive with the logs and the config files.


#10 Updated by laforge 9 days ago

Hi Philipp,

On Wed, Aug 09, 2017 at 10:53:24AM +0000, dexter [REDMINE] wrote:

I have tried it again. I can see the router advertisements going up the gb interface. However, the pdp context still closes after a few seconds. I have attached the archive with the logs and the config files.

Ok, it seems the MS needs to do neighbor solicitation after the router advertisement.
I'll investigate. Meanwhile I've also found+charged some phones using which I should
hopefully be able to test myself.

#11 Updated by laforge 9 days ago

  • % Done changed from 70 to 80

So, finally progress. I could make the current "laforge/ipv6" brnach work with my Fairpohne2: It establishes the v6 PDP context successfully, gets through PDP context activation and router solicitation/advertisement and then succcessfully establishes bi-directional TCP traffic to the public IPv6 internet.

Chagnes compared to yesterday's version were:
  • implement PCO for IPv6 DNS server address assignment
  • fix some bits in router advertisement message that were not in-line with 3GPP requirements (L/A bit)
  • make sure that the upper 64bit of the EUA in the PDP Context Establishment matches the /64 prefix of the router advertisement that follows

Philip: Please reproduce locally with your phone(s) and confirm it works for you, too

#12 Updated by dexter 8 days ago

Attached the traces of the recent tests.

  • Android: PDP context still closes immediately, but rest looks good. We suspect that the pdp context is closed because the DNS server is unreachable from the test host.
  • nokiaE90: PDP context stays open until it is manually closed by the user.

#13 Updated by laforge 6 days ago

  • Status changed from In Progress to Closed
  • % Done changed from 80 to 100

merged to master.

Also available in: Atom PDF