Work In progress

Work in Progress

Introduction 

MAP-T (RFC 7599) is a stateless IPv4/IPv6 transition mechanism that enables IPv4 services over an IPv6-only network using algorithmic translation.

Translation happens at:

  •    MAP Customer Edge (CE): A device functioning as a Customer Edge
                               router in a MAP deployment.  A typical MAP CE
                               adopting MAP Rules will serve a residential
                               site with one WAN-side IPv6-addressed
                               interface and one or more LAN-side interfaces
                               addressed using private IPv4 addressing.
    
       MAP Border Relay (BR):  A MAP-enabled router managed by the service
                               provider at the edge of a MAP domain.  A BR
                               has at least an IPv6-enabled interface and an
                               IPv4 interface connected to the native IPv4
                               network.  A MAP BR may also be referred to as
                               simply a "BR" within the context of MAP.

High-Level Architecture


Block Diagram

Untitled Diagram-1775555063614

Configuration

Border Relay: Setup done in ubuntu machine ( linux kernel 5.15 )
Installation
  1. Create a netplan /etc/netplan/99-mapt-config.yaml

    network:
      version: 2
      ethernets:
        enp1s0:                               # internet side, faces laptop virbr0
          dhcp4: true
          addresses: ["fd00::2/64"]
          routes:
            - to: "::/0"
              via: "fd00::1"
        enp7s0:                               # CE side
          dhcp4: false
          accept-ra: false                    # else the BR eats its own radvd RA
          addresses:
            - 10.42.0.10/24
            - "2001:558:6013:100::1/64"

  2. sudo apt-get install isc-dhcp-server
  3. Open file /etc/dhcp/dhcpd.conf and update as below

    ddns-update-style none;
    default-lease-time 3600;
    max-lease-time 7200;
    authoritative;
    option custom-upstream-rate code 242 = unsigned integer 32;
    option custom-downstream-rate code 243 = unsigned integer 32;

    option domain-name "hsd.pa.crnrstn.comcast.net" ;

    subnet 10.42.0.0 netmask 255.255.255.0 {
        option routers 10.42.0.10;
        option broadcast-address 10.42.0.255;
        option domain-name-servers 1.1.1.1, 8.8.8.8;
        range 10.42.0.3 10.42.0.254;

    }

  4. Open file /etc/radvd.conf

    interface enp7s0 {
        AdvSendAdvert on;
        AdvManagedFlag on;
        AdvOtherConfigFlag on;

        prefix 2001:558:6013:100::/64 {
            AdvOnLink on;
            AdvAutonomous on;
        };

    };

  5. Open file  /etc/dhcp/dhcpd6.conf and update as below 

    ddns-update-style none;
    default-lease-time 3600;
    max-lease-time 7200;
    option dhcp-renewal-time 1800;
    option dhcp-rebinding-time 2880;
    option client-class-information code 97 = string;
    authoritative;
    option dhcp6.map-option code 95 = string;
    subnet6 2001:558:6013:0100::/64 {
        range6 2001:558:6013:0100::1000 2001:558:6013:0100::1fff;
        prefix6 2001:558:6013:0200:: 2001:558:6013:fe00:: /56;
        option dhcp6.map-option 00:59:00:16:00:08:18:c0:a8:14:00:30:20:01:05:58:60:13:00:5d:00:04:08:00:00:00:00:5b:00:09:40:00:64:ff:9b:00:00:00:00;
        option dhcp6.name-servers
        2001:4860:4860::8888,
        2001:4860:4860::8844;
    }

  6. Once all changes are done, restart the dhcpd and radvd service.
    sudo systemctl enable isc-dhcp-server isc-dhcp-server6 radvd
    sudo systemctl restart isc-dhcp-server
    sudo systemctl restart isc-dhcp-server6
    sudo systemctl restart radvd
    isc-dhcp-server status
    ● isc-dhcp-server6.service - ISC DHCP IPv6 server
         Loaded: loaded (/lib/systemd/system/isc-dhcp-server6.service; enabled; vendor preset: enabled)
         Active: active (running) since Thu 2026-10-15 10:12:28 UTC; 16min ago
           Docs: man:dhcpd(8)
       Main PID: 853 (dhcpd)
          Tasks: 4 (limit: 4553)
         Memory: 4.5M
            CPU: 10ms
         CGroup: /system.slice/isc-dhcp-server6.service
                 └─853 dhcpd -user dhcpd -group dhcpd -f -6 -pf /run/dhcp-server/dhcpd6.pid -cf /etc/dhcp/dhcpd6.conf enp7s0
    
    Oct 15 10:12:28 akhil dhcpd[853]: PID file: /run/dhcp-server/dhcpd6.pid
    Oct 15 10:12:28 akhil dhcpd[853]: Wrote 1 NA, 0 TA, 2 PD leases to lease file.
    Oct 15 10:12:28 akhil sh[853]: Wrote 1 NA, 0 TA, 2 PD leases to lease file.
    Oct 15 10:12:28 akhil dhcpd[853]: Bound to *:547
    Oct 15 10:12:28 akhil sh[853]: Bound to *:547
    Oct 15 10:12:28 akhil sh[853]: Listening on Socket/7/enp7s0/2001:558:6013:100::/64
    Oct 15 10:12:28 akhil sh[853]: Sending on   Socket/7/enp7s0/2001:558:6013:100::/64
    Oct 15 10:12:28 akhil dhcpd[853]: Listening on Socket/7/enp7s0/2001:558:6013:100::/64
    Oct 15 10:12:28 akhil dhcpd[853]: Sending on   Socket/7/enp7s0/2001:558:6013:100::/64
    Oct 15 10:12:28 akhil dhcpd[853]: Server starting service.
    
    ● isc-dhcp-server.service - ISC DHCP IPv4 server
         Loaded: loaded (/lib/systemd/system/isc-dhcp-server.service; enabled; vendor preset: enabled)
         Active: active (running) since Thu 2026-10-15 10:12:28 UTC; 16min ago
           Docs: man:dhcpd(8)
       Main PID: 852 (dhcpd)
          Tasks: 4 (limit: 4553)
         Memory: 6.1M
            CPU: 19ms
         CGroup: /system.slice/isc-dhcp-server.service
                 └─852 dhcpd -user dhcpd -group dhcpd -f -4 -pf /run/dhcp-server/dhcpd.pid -cf /etc/dhcp/dhcpd.conf enp7s0
    
    Oct 15 10:12:28 akhil dhcpd[852]: PID file: /run/dhcp-server/dhcpd.pid
    Oct 15 10:12:28 akhil dhcpd[852]: Wrote 2 leases to leases file.
    Oct 15 10:12:28 akhil sh[852]: Wrote 2 leases to leases file.
    Oct 15 10:12:28 akhil dhcpd[852]: Listening on LPF/enp7s0/52:54:00:f2:71:a5/10.42.0.0/24
    Oct 15 10:12:28 akhil sh[852]: Listening on LPF/enp7s0/52:54:00:f2:71:a5/10.42.0.0/24
    Oct 15 10:12:28 akhil sh[852]: Sending on   LPF/enp7s0/52:54:00:f2:71:a5/10.42.0.0/24
    Oct 15 10:12:28 akhil sh[852]: Sending on   Socket/fallback/fallback-net
    Oct 15 10:12:28 akhil dhcpd[852]: Sending on   LPF/enp7s0/52:54:00:f2:71:a5/10.42.0.0/24
    Oct 15 10:12:28 akhil dhcpd[852]: Sending on   Socket/fallback/fallback-net
    Oct 15 10:12:28 akhil dhcpd[852]: Server starting service.● radvd.service - Router advertisement daemon for IPv6
    Loaded: loaded (/lib/systemd/system/radvd.service; enabled; vendor preset: enabled)
    Active: active (running) since Thu 2026-10-15 10:12:25 UTC; 16min ago
    Docs: man:radvd(8)
    Process: 674 ExecStartPre=/usr/sbin/radvd --logmethod stderr_clean --configtest (code=exited, status=0/SUCCESS)
    Process: 684 ExecStart=/usr/sbin/radvd --logmethod stderr_clean (code=exited, status=0/SUCCESS)
    Main PID: 701 (radvd)
    Tasks: 2 (limit: 4553)
    Memory: 596.0K
    CPU: 23ms
    CGroup: /system.slice/radvd.service
    ├─701 /usr/sbin/radvd --logmethod stderr_clean
    └─702 /usr/sbin/radvd --logmethod stderr_clean
    
    Oct 15 10:12:25 akhil systemd[1]: Starting Router advertisement daemon for IPv6...
    Oct 15 10:12:25 akhil radvd[674]: config file, /etc/radvd.conf, syntax ok
    Oct 15 10:12:25 akhil radvd[684]: version 2.18 started
    Oct 15 10:12:25 akhil systemd[1]: Started Router advertisement daemon for IPv6.
  7. Forwarding

    Forwarding (persist with: sudo apt install -y iptables-persistent)

    # /etc/sysctl.d/99-mapt.conf
    net.ipv4.ip_forward=1
    net.ipv6.conf.all.forwarding=1
    sudo sysctl --system

    sudo iptables  -A FORWARD -i enp7s0 -o enp1s0 -j ACCEPT
    sudo iptables  -A FORWARD -i enp1s0 -o enp7s0 -m state --state RELATED,ESTABLISHED -j ACCEPT
    sudo ip6tables -A FORWARD -i enp7s0 -o enp1s0 -j ACCEPT
    sudo ip6tables -A FORWARD -i enp1s0 -o enp7s0 -m state --state RELATED,ESTABLISHED -j ACCEPT
    sudo iptables-save  | sudo tee /etc/iptables/rules.v4
    sudo ip6tables-save | sudo tee /etc/iptables/rules.v6

    DO NOT add a MASQUERADE rule on the BR VM. Jool translates outside conntrack's
    view, so it can never fire on translated packets. NAT goes on the laptop.

Jool Installation
  • Build the jool modules using below build instructions
    Jool Installation
    sudo apt update
    sudo apt upgrade
    sudo apt install build-essential pkg-config
    sudo wget https://github.com/NICMx/Jool/releases/download/v4.2.0-rc2/jool-4.2.0.rc2.tar.gz
    sudo tar -xzf jool-4.2.0.rc2.tar.gz
    sudo /sbin/dkms install jool-4.2.0.rc2/
    cd jool-4.2.0.rc2/
    sudo ./configure
    sudo make
    sudo make install
  • Once build completed, below modules will be generated in respective paths, add those modules to kernel path
    MAPT modules
    ubuntu:~/jool-4.2.0~rc2$ find . -iname jool*ko
    ./src/mod/mapt/jool_mapt.ko
    ./src/mod/common/jool_common.ko
    ./src/mod/nat64/jool.ko
    /src/mod/siit/jool_siit.ko
    Jool configure
    Modeprobe modules
    sudo modprobe jool_common
    sudo modprobe jool_mapt
    
    sudo modprobe nf_defrag_ipv4
    sudo modprobe nf_defrag_ipv6
  • Once all modules are loaded and confirmed via lsmod

    ubuntu:~/ lsmod | grep jool*
    jool_mapt                    20480  0
    jool_common             253952  1 jool_mapt
    nf_defrag_ipv6          24576  3 nf_conntrack,openvswitch,jool_mapt
    nf_defrag_ipv4         16384  2 nf_conntrack,jool_mapt
    x_tables                       53248  9 xt_conntrack,nft_compat,xt_state,xt_tcpudp,xt_addrtype,xt_nat,ip_tables,xt_MASQUERADE,jool_mapt

  • Create an instance BR
    BR instance creation
    sudo jool_mapt instance add "BR" --netfilter --dmr 64:ff9b::/64
    sudo jool_mapt -i "BR" fmrt add 2001:558:6013::/48 192.168.20.0/24 8 8
    sudo jool_mapt -i "BR" global update map-t-type BR
    View the created instance using: (To remove instance sudo jool_mapt instance remove BR )
    View Instances
    akhil@CHTSL00399:~$ sudo jool_mapt -i BR fmrt display
    +---------------------------------------------+--------------------+----------------+----+
    |                                 IPv6 Prefix |        IPv4 Prefix | EA-bits Length |  a |
    +---------------------------------------------+--------------------+----------------+----+
    |                         2001:558:6013::/48  |    192.168.20.0/24 | 8              |  8 |
    +---------------------------------------------+--------------------+----------------+----+
    akhil@CHTSL00399:~$ sudo jool_mapt instance display
    +--------------------+-----------------+-----------+
    |          Namespace |            Name | Framework |
    +--------------------+-----------------+-----------+
    |           89628c00 |              BR | netfilter |
    +--------------------+-----------------+-----------+
    akhil@CHTSL00399:~$
    Enable debugging for jool using sudo jool_mapt -i BR global update logging-debug true
    cat /var/log/syslog
  • Make changes in BR setup to make ping and internet work in mapt mode
    Add host laptop rules
    sudo ip route replace 192.168.20.0/24 via 192.168.122.82
    sudo iptables -t nat -I POSTROUTING -s 192.168.20.0/24 ! -d 192.168.20.0/24 -j MASQUERADE
    sudo iptables -I FORWARD -s 192.168.20.0/24 -j ACCEPT
    sudo iptables -I FORWARD -d 192.168.20.0/24 -j ACCEPT
    sudo sysctl -qw net.ipv4.ip_forward=1
  •  CE gets a prefix but nothing comes back. /usr/local/sbin/mapt-pd-routes.py polls /var/lib/dhcp/dhcpd6.leases every 5 s and installs one route per active ia-pd, deriving the next hop from the DUID-LL in the lease

    # /etc/systemd/system/mapt-pd-routes.service
    [Unit]
    Description=MAP-T: route delegated prefixes to their CE (derived from dhcpd6 leases)
    After=isc-dhcp-server6.service network-online.target
    Wants=isc-dhcp-server6.service

    [Service]
    Type=simple
    ExecStart=/usr/bin/python3 /usr/local/sbin/mapt-pd-routes.py --interval 5
    Restart=always
    RestartSec=5

    [Install]
    WantedBy=multi-user.target

  • Check tcpdump for wan interface and downlink interface which is connected to CE, will be able to see request and reply from upstream.
  • Connectivity test updated below

Customer Edge: Enable/Disable MAPT feature with below distro's from build

DISTRO_FEATURES_append = " feature_mapt"
DISTRO_FEATURES_append = " nat46"

Enable MAPT in BPI using the mapt rfc datatmodel

Enable MAPT
root@Filogic-GW:~# dmcli eRT getv Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.MAP-T.Enable
CR component name is: eRT.com.cisco.spvtg.ccsp.CR
subsystem_prefix eRT.
Execution succeed.
Parameter    1 name: Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.MAP-T.Enable
               type:       bool,    value: true 

Check map0 interface created and erouter0 should have only IPv6 addr

map0
root@Filogic-GW:~# ifconfig map0
map0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
          inet6 addr: fe80::c534:91eb:b45d:b579/64 Scope:Link
          UP POINTOPOINT RUNNING NOARP  MTU:1500  Metric:1
          RX packets:123 errors:0 dropped:0 overruns:0 frame:0
          TX packets:90 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:5161 (5.0 KiB)  TX bytes:0 (0.0 B)
root@Filogic-GW:~# ifconfig erouter0
erouter0  Link encap:Ethernet  HWaddr 02:01:00:39:58:64  
          inet6 addr: 2001:558:6013:100::175f/128 Scope:Global
          inet6 addr: fe80::1:ff:fe39:5864/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:637 errors:0 dropped:0 overruns:0 frame:0
          TX packets:599 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:105610 (103.1 KiB)  TX bytes:105608 (103.1 KiB)

root@Filogic-GW:~# 


Test Results

Ping and Internet should work in CE and connected clients

  • Test result on CE
    ping 8.8.8.8 & ping gmail.com
    root@Filogic-GW:~# ping 8.8.8.8
    PING 8.8.8.8 (8.8.8.8): 56 data bytes
    64 bytes from 8.8.8.8: seq=0 ttl=110 time=322.241 ms
    64 bytes from 8.8.8.8: seq=1 ttl=110 time=357.163 ms
    64 bytes from 8.8.8.8: seq=2 ttl=110 time=145.545 ms
    64 bytes from 8.8.8.8: seq=3 ttl=110 time=163.061 ms
    ^C
    --- 8.8.8.8 ping statistics ---
    root@Filogic-GW:~# ping -4 gmail.com
    PING gmail.com (142.250.207.69): 56 data bytes
    64 bytes from 142.250.207.69: seq=0 ttl=110 time=204.645 ms
    64 bytes from 142.250.207.69: seq=1 ttl=110 time=228.521 ms
    64 bytes from 142.250.207.69: seq=2 ttl=110 time=260.954 ms
    64 bytes from 142.250.207.69: seq=3 ttl=110 time=276.700 ms
    ^C
    --- gmail.com ping statistics ---
    4 packets transmitted, 4 packets received, 0% packet loss
  • iptables & ip6tables in mapt mode
    iptables & ip6tables
    root@Filogic-GW:~# iptables -L -v -n | grep map0
        0     0 ACCEPT     47   --  map0   *       0.0.0.0/0            0.0.0.0/0           
        0     0 DROP       all  --  map0   map0    0.0.0.0/0            0.0.0.0/0           
        0     0 wan2lan    all  --  map0   br106   0.0.0.0/0            0.0.0.0/0           
        0     0 wan2lan    all  --  map0   brlan1  0.0.0.0/0            0.0.0.0/0           
        0     0 lan2wan    all  --  br106  map0    0.0.0.0/0            0.0.0.0/0           
        0     0 lan2wan    all  --  brlan1 map0    0.0.0.0/0            0.0.0.0/0           
        0     0 wan2lan    all  --  map0   br403   0.0.0.0/0            0.0.0.0/0           
      110  9240 wan2lan    all  --  map0   brlan0  0.0.0.0/0            0.0.0.0/0           
        0     0 lan2wan    all  --  br403  map0    0.0.0.0/0            0.0.0.0/0           
      587 52500 lan2wan    all  --  brlan0 map0    0.0.0.0/0            0.0.0.0/0           
    root@Filogic-GW:~# 
    root@Filogic-GW:~# ip6tables -L -v -n | grep map0                                                                                                     
      212 58132 wan2lan    all      erouter0 map0    ::/0                 ::/0                
     1086  216K lan2wan    all      map0   erouter0  ::/0                 ::/0                
    root@Filogic-GW:~# 
  • Test Result on LAN client
    ping test from lan client
    chtspc0041@chtspc0041-OptiPlex-7010:~$ ping 8.8.8.8
    PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
    64 bytes from 8.8.8.8: icmp_seq=1 ttl=248 time=5.26 ms
    64 bytes from 8.8.8.8: icmp_seq=2 ttl=248 time=5.56 ms
    64 bytes from 8.8.8.8: icmp_seq=3 ttl=248 time=7.65 ms
    ^C
    --- 8.8.8.8 ping statistics ---
    3 packets transmitted, 3 received, 0% packet loss, time 2002ms
    rtt min/avg/max/mdev = 5.260/6.160/7.653/1.063 ms
    chtspc0041@chtspc0041-OptiPlex-7010:~$ ping -4 gmail.com
    PING gmail.com (142.250.207.69) 56(84) bytes of data.
    64 bytes from hkg12s32-in-f5.1e100.net (142.250.207.69): icmp_seq=2 ttl=109 time=494 ms
    64 bytes from hkg12s32-in-f5.1e100.net (142.250.207.69): icmp_seq=3 ttl=109 time=312 ms
    64 bytes from hkg12s32-in-f5.1e100.net (142.250.207.69): icmp_seq=4 ttl=109 time=543 ms
    64 bytes from hkg12s32-in-f5.1e100.net (142.250.207.69): icmp_seq=5 ttl=109 time=364 ms
    64 bytes from hkg12s32-in-f5.1e100.net (142.250.207.69): icmp_seq=6 ttl=109 time=182 ms
    64 bytes from hkg12s32-in-f5.1e100.net (142.250.207.69): icmp_seq=7 ttl=109 time=200 ms
    64 bytes from hkg12s32-in-f5.1e100.net (142.250.207.69): icmp_seq=8 ttl=109 time=1006 ms
    64 bytes from hkg12s32-in-f5.1e100.net (142.250.207.69): icmp_seq=9 ttl=109 time=59.2 ms
    64 bytes from hkg12s32-in-f5.1e100.net (142.250.207.69): icmp_seq=10 ttl=109 time=605 ms
    ^C
    --- gmail.com ping statistics ---
    10 packets transmitted, 9 received, 10% packet loss, time 9011ms

Datamodels

root@Filogic-GW:~# dmcli eRT getv Device.DHCPv6.Client.1.X_RDKCENTRAL-COM_RcvOption.
CR component name is: eRT.com.cisco.spvtg.ccsp.CR
subsystem_prefix eRT.
Execution succeed.
Parameter    1 name: Device.DHCPv6.Client.1.X_RDKCENTRAL-COM_RcvOption.MapTransportMode
               type:     string,    value: MAPT 
Parameter    2 name: Device.DHCPv6.Client.1.X_RDKCENTRAL-COM_RcvOption.MapBRPrefix
               type:     string,    value: 64:ff9b::/64 
Parameter    3 name: Device.DHCPv6.Client.1.X_RDKCENTRAL-COM_RcvOption.MapRuleIPv4Prefix
               type:     string,    value: 192.168.20.0 
Parameter    4 name: Device.DHCPv6.Client.1.X_RDKCENTRAL-COM_RcvOption.MapRuleIPv6Prefix
               type:     string,    value: 2001:558:6013::/48 
Parameter    5 name: Device.DHCPv6.Client.1.X_RDKCENTRAL-COM_RcvOption.MapEALen
               type:       uint,    value: 8 
Parameter    6 name: Device.DHCPv6.Client.1.X_RDKCENTRAL-COM_RcvOption.MapPSIDOffset
               type:       uint,    value: 8 
Parameter    7 name: Device.DHCPv6.Client.1.X_RDKCENTRAL-COM_RcvOption.MapPSIDLen
               type:       uint,    value: 8 
Parameter    8 name: Device.DHCPv6.Client.1.X_RDKCENTRAL-COM_RcvOption.MapPSID
               type:       uint,    value: 0 
Parameter    9 name: Device.DHCPv6.Client.1.X_RDKCENTRAL-COM_RcvOption.MapIsFMR
               type:       bool,    value: false 
Parameter   10 name: Device.DHCPv6.Client.1.X_RDKCENTRAL-COM_RcvOption.MapIpv4Address
               type:     string,    value: 192.168.20.254 
Parameter   11 name: Device.DHCPv6.Client.1.X_RDKCENTRAL-COM_RcvOption.MapRatio
               type:       uint,    value: 1 

References

RFC7599: https://www.rfc-editor.org/rfc/rfc7599

Mapt simulation tool: https://map46.cisco.com/

Jool official: https://www.jool.mx/en/map-t.html

Mapt physical setup link: MAP-T Physical setup




1 Comment

  1. Simple and clear documentation.