Skip to content

fakemanhk/openwrt-jp-ipoe

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

33 Commits
 
 
 
 

Repository files navigation

Configuring OpenWrt to work with Japan NTT IPv6 (MAP-E) service

The problem:

ISPs with NTT mostly support both IPv4 & IPv6 implementations, while former one usually by using PPPoE which can introduce higher latency, during peak hours it can be also very slow in some busy districts. IPv6 is their newly promoted way to connect to internet which doesn't require PPPoE (note there is no PPPoE for 10G plan, IPoE is the only option),  they also claim this is a much faster option, with IPv4 over IPv6 together users should retain traditional IPv4 connectivity. Unfortunately if you subscribe the internet service without using Hikari Denwa (ひかり電話) residential phone service, you will end up getting /64 prefix address as well as without router advertisement (RA), if you don't use vendor provided router it would be extremely difficult to set up your IPv6 network with IPv4 over IPv6 connectivity.

There exist a few different implementations (DS-LITE/Transix/MAP-E)  in Japan, so not all providers can do the same way, here I am only referring to my own provider NTT ぷらら (plala), which is MAP-E implementation.

Setup:

The whole setup was first tested with GL-INET MT1300 (beryl, v22.03.3) and verified with NanoPi R4S (4GB, v22.03.3) as well as Linksys WRT3200ACM (rango, v22.03.2) and Jetway NF9HG-N2930 (x86, v22.03.3) on 1G plan.

In October 2023 I have verified this setup is also working with Netgear WAX206 (v23.05.0) on upgraded 10G plan.

Note: I didn't notice that my upgraded 10G plan is slightly different from the original 1G plan, the old one comes with /64 prefix without prefix delegation (PD), while the 10G plan already give you /56 prefix with PD even you don't pay for the Hikari phone service! Here is a discussion about it.

  • System > Software: Install the required add-on package map for MAP-E/MAP-T support, you will need to reboot before you can use it.
  • Enable WAN6 with DHCPv6, firewall setting you probably need to add this to WAN Zone (same as IPv4 WAN) for protection.

Under DHCP Server > IPv6 Setting, follow these settings:

  • Designated master ON
  • RA-Service: relay mode
  • DHCPv6-Service: relay mode
  • NDP-Proxy: relay mode
  • Learn routes: ON

Save & Apply setting, you should see a public IPv6 address being assigned to your WAN6 interface (usually starting with 2400)

  • WAN6 interface also needs to add Routed Prefix Information due to missing RA on WAN6 side (note: If your service plan comes with prefix delegation, like having Hikari phone service, or using some of the 10G internet plan, it could be coming with a shorter prefix like /60 or /56 together with PD, then this step can be ommited):

  • Use SSH to login router, edit /etc/config/network, add the line marked in Italics under WAN6 interface section, note the 2400:aaaa:bbbb:cccc is your WAN IP prefix (first 64 bit), this will give the WAN6 interface proper IPv6-PD:

config interface 'wan6'

            option device 'eth1'

            option proto 'dhcpv6'

            option reqaddress 'try'

            option reqprefix 'auto'

            option ip6prefix '2400:aaaa:bbbb:cccc::/64'

Note: Previously I had failed my setup because of missing this step, it wasn't mentioned in most resources I found on web, and I eventually got a MAP rule invalid error.

  • Next, configure LAN interface, under DHCP Server > IPv6 settings, basically very similar to WAN6 but Designated master OFF

You clients can probably get public IPv6 addresses (*) from router now! But this will be IPv6 access only and you are still missing the IPv4 connectivity, another MAP-E interface is required to fill the gap.

(*) Some clients might not work with DHCPv6, and you'll need SLAAC, please refer to the discussion here to change the settings.

  • Before we create the MAP-E interface, the parameter calculation for MAP-E is needed, in reference section I have attached the IETF information but someone has created a page to calculate, you can copy the public IPv6 address from WAN6 interface and use this online MAP-E rule calculator:

Note: Before I ran the above calculator, I used the Buffalo router that came with ISP to connect the internet service, logged into that router and from status page I can see that at least the IPv4 address and port numbers are the same as above, so I believe the parameters I get from the calculator should be correct, you might want to do this as a verification.

  • Next will be setting up new MAP-E interface, create a new interface and name it (e.g. WAN6MAPE), and fill the parameters using above generated parameters:
    • Protocol: MAP/LW4over6
    • Type: MAP-E
    • BR/DMR/AFTR: [peeraddr]
    • IPv4 prefix: [ipaddr]
    • IPv4 prefix length: [ip4prefixlen]
    • IPv6 prefix: [ip6prefix]
    • IPv6 prefix length: [ip6prefixlen]
    • EA-bit length: [ealen]
    • PSID-bits length: [psidlen]
    • PSID offset: [offset]
    • From advanced settings, make sure it has WAN6 as Tunnel Link, and check the box Use legacy MAP:

Note: Don't forget to add this WAN6MAPE interface to same firewall zone as WAN/WAN6 since this is also part of WAN.

ADVANCED CUSTOM CONFIGURATION

MAP-E with IPv4 sharing from ISP is designed to share same IPv4 address with many customers, with different ports being assigned based on IETF rules, the above linked parameter calculator already shown the assigned ports, usually it's divided into groups of 16 ports, according to this discussion JPNE assigns 15 groups (240 ports), while OCN/plala assign 63 groups (1008 ports). In most cases this should be enough for most home uses (since only IPv4 connections will use them), however a recent test with well known IPv4 based website that uses many sessions showing a significant lagging while loading. After investigation the OpenWrt firewall statistics indicating only first group of assigned ports (i.e. only 16 ports) being used and this is the reason of lagging when a large number of simultaneous IPv4 sessions opening, also IPv4 PING is not working. Not sure if it's because Japan ISP MAP-E configuration has something MAP package can't deal with, as a result a system change is required for /lib/netifd/proto/map.sh. Below is the diff of original vs new map.sh:

root@OpenWrt# diff -c map.sh.old map.sh.new
*** map.sh.old  Sat Mar  4 03:57:30 2023
--- map.sh.new     Tue Mar  7 00:09:22 2023
***************
*** 13,18 ****
--- 13,40 ----
  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  # GNU General Public License for more details.
  
+ #------------------------------------
+ #     Modifications by 'cmspam'
+ #------------------------------------
+ # These modifications are made to ensure that the multiple port ranges
+ # used with Japan's MAP-E implementation are actually SNAT-ed to correctly.
+ 
+ #------------------------------------
+ #     Setting to not SNAT to certain ports
+ #------------------------------------
+ # This is a space-delimited list of ports to not SNAT to.
+ # If, for example, you use some ports for servers, it's best to
+ # include them here, so that they are not used with SNAT.
+ # Port ranges are not supported, so please list each port individually
+ # separated with a space.
+ # 
+ # Example, if you want to not SNAT to 2938, 7088, and 10233
+ #
+ #DONT_SNAT_TO="2938 7088 10233"
+ 
+ DONT_SNAT_TO="0"
+ 
+ 
  [ -n "$INCLUDE_ONLY" ] || {
        . /lib/functions.sh
        . /lib/functions/network.sh
***************
*** 140,158 ****
              json_add_string snat_ip $(eval "echo \$RULE_${k}_IPV4ADDR")
            json_close_object
          else
            for portset in $(eval "echo \$RULE_${k}_PORTSETS"); do
!               for proto in icmp tcp udp; do
!               json_add_object ""
!                 json_add_string type nat
!                 json_add_string target SNAT
!                 json_add_string family inet
!                 json_add_string proto "$proto"
!                   json_add_boolean connlimit_ports 1
!                   json_add_string snat_ip $(eval "echo \$RULE_${k}_IPV4ADDR")
!                   json_add_string snat_port "$portset"
!               json_close_object
!               done
            done
          fi
          if [ "$maptype" = "map-t" ]; then
                [ -z "$zone" ] && zone=$(fw3 -q network $iface 2>/dev/null)
--- 162,233 ----
              json_add_string snat_ip $(eval "echo \$RULE_${k}_IPV4ADDR")
            json_close_object
          else
+ 
+ #------------------------------------
+           #MODIFICATION 1: Get all ports, and full port count.
+           #                Don't include ports in DONT_SNAT_TO
+ #------------------------------------
+           local portcount=0
+           local allports=""
            for portset in $(eval "echo \$RULE_${k}_PORTSETS"); do
!               local startport=$(echo $portset | cut -d'-' -f1)
!               local endport=$(echo $portset | cut -d'-' -f2)
!               for x in $(seq $startport $endport); do
!                       if ! echo "$DONT_SNAT_TO" | tr ' ' '\n' | grep -qw $x; then                        
!                               allports="$allports $portcount : $x , "
!                               portcount=`expr $portcount + 1`
!                       fi
!               done
            done
+           allports=${allports%??}
+ #------------------------------------
+           #END MODIFICATION 1
+ #------------------------------------
+           
+ #------------------------------------
+             #MODIFICATION 2: Create mape table
+ #------------------------------------
+             nft add table inet mape
+             nft add chain inet mape srcnat {type nat hook postrouting priority 0\; policy accept\; }
+ #------------------------------------
+           #END MODIFICATION 2
+ #------------------------------------
+ 
+ 
+ #------------------------------------
+           #MODIFICATION 3: Create the rules to snat to all the ports
+ #------------------------------------
+           local counter=0
+           
+             for proto in icmp tcp udp; do
+                 nft add rule inet mape srcnat ip protocol $proto oifname "map-$cfg" snat ip to $(eval "echo \$RULE_${k}_IPV4ADDR") : numgen inc mod $portcount map { $allports }
+             done
+           #END MODIFICATION 3
+           
+ #------------------------------------
+           #MODIFICATION 4: Comment out original SNAT implementation.
+ #------------------------------------
+ #            for portset in $(eval "echo \$RULE_${k}_PORTSETS"); do
+ #              for proto in icmp tcp udp; do
+ #                json_add_object ""
+ #                  json_add_string type nat
+ #                  json_add_string target SNAT
+ #                  json_add_string family inet
+ #                  json_add_string proto "$proto"
+ #                  json_add_boolean connlimit_ports 1
+ #                  json_add_string snat_ip $(eval "echo \$RULE_${k}_IPV4ADDR")
+ #                  json_add_string snat_port "$portset"
+ #                json_close_object
+ #              done
+ #            done
+ #------------------------------------
+           #END MODIFICATION 4
+ #-------------------------------------
+ #------------------------------------
+           #ALL MODIFICATIONS FINISHED
+ #------------------------------------
+ 
+ 
          fi
          if [ "$maptype" = "map-t" ]; then
                [ -z "$zone" ] && zone=$(fw3 -q network $iface 2>/dev/null)

You can also download the whole file here, don't forget to turn on the execute bit of the file after replacement.

After editing, please restart IPv6 interface, or simply reboot router, you'll see that IPv4 PING is working as well as observing more port groups passing traffic now.

Eventually you should see the following screen under Network > Interfaces, WAN6MAPE should get the IPv4 exactly the same as using the ISP provided router, there is also a Virtual dynamic interface automatically created when MAP-E interface started correctly.

From Status > Overview you'll see both IPv4 Upstream and IPv6 Upstream information:

(Note: If your plan comes with prefix delegation, your IPv6 Upstream might not show you any address, only a prefix will be shown, this is NORMAL)

Testing with my Linux laptop by visiting the OCN connectivity verification page, both IPv4/IPv6 addresses should be the same as above upstream informations:

SUCCESS!!

Some speed test results

From time to time, you might observe ip6_tunnel: map-MAPE xmit: Local address not yet configured! in kernel log, this can be ignored and you don't need to worry about it.

Reference materials:

https://datatracker.ietf.org/doc/html/draft-ietf-softwire-map-03#page-6

https://www.labohyt.net/blog/lan/post-6760/

https://zenn.dev/yakumo/articles/19cbc6309d8143cc9349b2fb0d29771e

https://blog.hinaloe.net/2020/03/14/openwrt-mape-ocn/

First draft: 17 Jan 2023

Last Edit: 07 Feb 2024

About

Configure OpenWRT to work with Japan NTT IPv6 service

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages