Jio 5G - IPv6 only on transport

Last month I got access to Jio 5G like everyone else around in Haryana. They are running a beta program with uncapped data for now. Overall it works fine for usual stuff (web surfing on popular sites, YouTube videos, music streaming etc) but 464XLAT seems to be a little buggy in IPv4 hardcoded destinations. Initially it was giving quite a few issues but many of them seem to be fixed in last few days.


Jio 5G - IPv6 only on transport

Since I got enrolled with Jio’s 5G, I see both wireguard tunnels misbehaving i.e tunnelling IPv4 packets inside IPv4 transport & tunnelling IPv4 packets inside IPv6 transport. I looked at my phone’s interfaces using Hurricane Electric’s Network tools app and it shows 192.0.0.2/32 on the PDP_IP0 interface.

This is a special pool and not just another private pool. This is called “IPv4 Service Continuity Prefix” and is defined in RFC 7335. It was originally for DS-Lite but its usage was extended to 464XLAT.

It seems like Jio 5G (and even Jio LTE after 5G is enabled once) is a 464XLAT-based network.

Let’s tether my computer to my phone & look at the traffic:

wlp5s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.20.10.8  netmask 255.255.255.240  broadcast 172.20.10.15
        inet6 2409:40d6:d:8b8a:b61f:7b9f:5f21:bc7c  prefixlen 64  scopeid 0x0<global>
        inet6 fe80::f14a:f5ac:3b82:c073  prefixlen 64  scopeid 0x20<link>
        inet6 2409:40d6:d:8b8a:cb1f:a2ea:8aa4:13c  prefixlen 64  scopeid 0x0<global>
        ether <masked>  txqueuelen 1000  (Ethernet)
        RX packets 88540  bytes 104397410 (104.3 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 22968  bytes 4004457 (4.0 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

The IPv4 network here is native. Basically, my computer <-> phone is a dual-stack network. But the phone’s WAN side is IPv6 only. This briefly explains these methods comparing IPv6 only Vs IPv6 + NAT64 & DNS64 Vs IPv6 with 464XLAT.


Let’s look at three kinds of possible traffic - 1) Where the destination is on IPv6, 2) the Destination is IPv4 only with DNS and 3) the Destination is hardcoded IPv4

1. IPv6 to IPv6 flow

anurag@desktop ~> mtr anuragbhatia.com -6 -wr
Start: 2023-02-11T02:56:07+0530
HOST: desktop.rtk                          Loss%   Snt   Last   Avg  Best  Wrst StDev
  1.|-- 2409:40d6:d:8b8a:b0b6:aecb:682b:d3ee  0.0%    10    1.8   1.8   1.8   1.9   0.1
  2.|-- ???                                  100.0    10    0.0   0.0   0.0   0.0   0.0
  3.|-- 2405:200:5209:20:3925::1              0.0%    10   47.7  39.3  30.4  62.1  11.2
  4.|-- 2405:200:801:1900::5be                0.0%    10   27.0  40.0  27.0  57.1  10.7
  5.|-- 2405:200:801:1900::5bf                0.0%    10   65.3  43.2  30.5  65.3  13.0
  6.|-- 2405:203:10:8200:130:26:30:99         0.0%    10   56.9  57.4  44.6  81.4  12.5
  7.|-- 2405:200:1605:600:49:44:220:b3        0.0%    10   70.4  44.2  33.1  70.4  12.2
  8.|-- 2405:200:1605:600:49:44:220:b3        0.0%    10   38.8  46.4  35.3  61.0   9.6
  9.|-- 2620:0:890::100                       0.0%    10   42.6  47.9  36.0  67.3   8.1
anurag@desktop ~>

2. IPv6 to IPv4 only with DNS

To date, github.com is on IPv4 only. Let’s look at the mtr over IPv6:

anurag@desktop ~> mtr github.com -6 -wr
Start: 2023-02-11T03:01:28+0530
HOST: desktop.rtk                             Loss%   Snt   Last   Avg  Best  Wrst StDev
  1.|-- 2409:40d6:d:8b8a:b0b6:aecb:682b:d3ee     0.0%    10    1.8   5.5   1.6  38.4  11.5
  2.|-- ???                                     100.0    10    0.0   0.0   0.0   0.0   0.0
  3.|-- 2405:200:5209:20:3925::1                 0.0%    10   30.3  51.2  30.3 157.4  37.7
  4.|-- 2405:200:871:3631:61::7                  0.0%    10   33.9  54.2  23.0 126.0  37.3
  5.|-- 64:ff9b::ac11:b642                       0.0%    10   28.8  64.2  28.8 233.0  61.3
  6.|-- 64:ff9b::c0a8:7e32                       0.0%    10   43.4  62.9  29.6 197.2  50.3
        64:ff9b::c0a8:7e30                     
  7.|-- 64:ff9b::c0a8:7e31                       0.0%    10   58.3  59.1  33.9 161.4  37.5
  8.|-- 64:ff9b::ac10:1221                       0.0%    10   62.9  54.7  36.3 125.6  27.0
  9.|-- 64:ff9b::ac10:1221                       0.0%    10   67.8  64.6  35.4 232.9  60.0
 10.|-- reliancejio.del01-96cbe-1b.ntwk.msn.net  0.0%    10   35.6  68.4  35.6 197.2  54.7
 11.|-- ae20-0.del01-96cbe-1a.ntwk.msn.net       0.0%    10   38.6  68.8  37.3 165.1  50.2
 12.|-- ae32-0.ear01.bom02.ntwk.msn.net          0.0%    10   61.8  74.6  48.7 142.2  32.2
 13.|-- be-23-0.ibr03.bom02.ntwk.msn.net         0.0%    10   61.0  87.7  61.0 218.1  47.9
 14.|-- be-5-0.ibr01.pnq21.ntwk.msn.net          0.0%    10   66.5  96.0  57.6 182.5  44.4
 15.|-- ae106-0.rwa04.pnq21.ntwk.msn.net         0.0%    10   60.5  77.6  58.8 146.7  25.4
 16.|-- ???                                     100.0    10    0.0   0.0   0.0   0.0   0.0
anurag@desktop ~> 

So this shows the use of DNS64. The DNS server on my system is my cell phone which acts as a forwarder and forwards packets to the DNS node of Jio.

anurag@desktop ~> dig github.com aaaa +short
64:ff9b::14cf:4952
anurag@desktop ~> 

For comparison here’s a reply at the same time from say Google’s 8.8.8.8:

anurag@desktop ~> dig github.com aaaa @8.8.8.8 +short
anurag@desktop ~> 

(i.e no IPv6 AAAA DNS record)


3. IPv6 to IPv4 only with hardcoded IPv4, no DNS

For anyone familiar with NAT64 - this specific case used to be a drawback of NAT64+DNS64. For cases with no DNS, the system could not give the “fake” AAAA reply and hence connection would not be established. Let’s look at the trace here:

anurag@desktop ~> mtr -wr 1.1.1.1
Start: 2023-02-11T03:06:49+0530
HOST: desktop.rtk     Loss%   Snt   Last   Avg  Best  Wrst StDev
  1.|-- _gateway         0.0%    10    1.8  19.6   1.7  87.4  32.5
  2.|-- ???             100.0    10    0.0   0.0   0.0   0.0   0.0
  3.|-- ???             100.0    10    0.0   0.0   0.0   0.0   0.0
  4.|-- ???             100.0    10    0.0   0.0   0.0   0.0   0.0
  5.|-- ???             100.0    10    0.0   0.0   0.0   0.0   0.0
  6.|-- ???             100.0    10    0.0   0.0   0.0   0.0   0.0
  7.|-- ???             100.0    10    0.0   0.0   0.0   0.0   0.0
  8.|-- ???             100.0    10    0.0   0.0   0.0   0.0   0.0
  9.|-- ???             100.0    10    0.0   0.0   0.0   0.0   0.0
 10.|-- ???             100.0    10    0.0   0.0   0.0   0.0   0.0
 11.|-- ???             100.0    10    0.0   0.0   0.0   0.0   0.0
 12.|-- ???             100.0    10    0.0   0.0   0.0   0.0   0.0
 13.|-- ???             100.0    10    0.0   0.0   0.0   0.0   0.0
 14.|-- ???             100.0    10    0.0   0.0   0.0   0.0   0.0
 15.|-- one.one.one.one  0.0%    10   59.1 114.8  57.8 344.2  95.7
anurag@desktop ~> 

For all random IPv4, I see the same result. mtr completes but no middle hops. Hop 1 is visible (which is my cell phone) because LAN has native IPv4. A possible reason (my guess which I need to validate with some friends) is that there is no IPv4 on transport, and the “TTL time exceeded” ICMP message cannot be sent over an IPv6-only network. We see the last hop here possibly because ICMP packets with destination are part of CGNAT translation and hence ICMP message was carried inside IPv6 packets.

I can send packets to 1.1.1.1 directly.

anurag@desktop ~> ping -c 5 1.1.1.1
PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data.
64 bytes from 1.1.1.1: icmp_seq=1 ttl=53 time=82.2 ms
64 bytes from 1.1.1.1: icmp_seq=2 ttl=53 time=78.5 ms
64 bytes from 1.1.1.1: icmp_seq=3 ttl=53 time=77.6 ms
64 bytes from 1.1.1.1: icmp_seq=4 ttl=53 time=71.4 ms
64 bytes from 1.1.1.1: icmp_seq=5 ttl=53 time=86.1 ms

--- 1.1.1.1 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4006ms
rtt min/avg/max/mdev = 71.395/79.149/86.063/4.897 ms
anurag@desktop ~> 

Thus https://1.1.1.1 on my browser works as well as one would expect.


Ending this post with a 5G speed test! 😄