Back to Blog
José Manuel Requena Plens

MikroTik PPPoE + DHCPv6-PD: Dual-Stack for DIGI Spain

Configure PPPoE with dynamic IPv4 and DHCPv6 Prefix Delegation on MikroTik RouterOS for DIGI Spain ISP. Includes VLAN tagging, SLAAC, automatic prefix change handling, and production-ready firewall rules.

Cover image for MikroTik PPPoE + DHCPv6-PD: Dual-Stack for DIGI Spain

DIGI Spain is one of the few ISPs in Spain that provides native IPv6 connectivity to residential customers. Their fiber network uses PPPoE authentication with VLAN tagging and delivers both a dynamic IPv4 address and a dynamic /56 IPv6 prefix via DHCPv6 Prefix Delegation (DHCPv6-PD).

This guide covers the complete configuration of a MikroTik router for DIGI’s network, including automatic handling of prefix changes—a challenge when your ISP assigns dynamic prefixes that can change on each reconnection.

What You'll Configure
  • PPPoE over VLAN 20 for DIGI Spain fiber authentication
  • Dynamic IPv4 with automatic default route and peer DNS
  • DHCPv6 Prefix Delegation (/56 prefix) for native IPv6 connectivity
  • SLAAC for automatic IPv6 address assignment on LAN devices
  • Automatic prefix change handling with DHCPv6 script that updates addresses on reconnection
  • Production-ready firewall with input, forward chains for both IPv4 and IPv6
  • Tested on RouterOS 7.x with RB5009, but applicable to any MikroTik router

Network architecture overview

DIGI’s network requires a specific setup: ONT in bridge mode → VLAN 20 → PPPoE authentication → dual-stack IPv4 + IPv6 (DHCPv6-PD) → firewall/NAT → LAN with SLAAC.

What you receive from DIGI

DIGI Connection Parameters
ParameterValueNotes
Connection TypePPPoE over VLAN 20VLAN tagging required
IPv4 AddressDynamic (CGNAT or Public)Assigned via PPPoE
IPv6 PrefixDynamic /56Via DHCPv6-PD, can change on reconnect
MTU1480 (negotiated)Standard PPPoE, negotiated via LCP
MRU1492 (negotiated)Maximum Receive Unit, negotiated via LCP
Service NameftthPPPoE service identifier reported by DIGI
DNSISP-provided or customCan use peer DNS or configure your own

Prerequisites


Step 1: configure the physical interface

First, configure the ethernet port connected to the DIGI ONT:

ROUTEROSPhysical Interface Configuration
/interface ethernet set [ find default-name=ether1 ] \
    comment="DIGI ONT" \
    rx-flow-control=auto \
    tx-flow-control=auto

Step 2: create the VLAN interface

DIGI requires VLAN 20 tagging for PPPoE traffic. Create the VLAN interface:

ROUTEROSVLAN Configuration
/interface vlan add \
    name=VLAN_DIGI \
    vlan-id=20 \
    interface=ether1 \
    comment="VLAN for ISP connection"

Why VLAN 20?

DIGI uses 802.1Q VLAN tagging to separate different services on their network. VLAN 20 is specifically for internet service. If you connect directly without VLAN tagging, PPPoE authentication will fail.

What If My ISP Doesn't Use VLANs?

If your ISP doesn’t require VLAN tagging, skip this step entirely. In Step 3, set the PPPoE client interface directly to the physical port:

/interface pppoe-client add \
    interface=ether1 \
    ...

Common ISP VLAN configurations:

  • DIGI Spain: VLAN 20
  • Movistar Spain: VLAN 6 (internet) + VLAN 2 (VoIP) + VLAN 3 (IPTV)
  • Orange Spain: VLAN 832
  • No VLAN: Many ISPs (especially cable/DOCSIS providers)

Step 3: configure the PPPoE client

Now create the PPPoE client that will authenticate with DIGI:

ROUTEROSPPPoE Client Configuration
/interface pppoe-client add \
    name=PPPoE_DIGI \
    interface=VLAN_DIGI \
    user="your_number@digi" \
    password="your_password" \
    add-default-route=yes \
    use-peer-dns=yes \
    max-mtu=1500 \
    profile=default-encryption \
    disabled=no \
    comment="PPPoE client for ISP DIGI"
PPPoE Configuration Parameters
ParameterValuePurpose
interfaceVLAN_DIGIPPPoE runs over the VLAN interface, not the physical port
add-default-routeyesAutomatically adds default route when connected
use-peer-dnsyesUses DIGI’s DNS servers (can disable for custom DNS)
max-mtu1500Maximum MTU the client accepts. DIGI negotiates down to 1480 via LCP
profiledefault-encryptionStandard PPP profile with MPPE encryption support
About the PPP Profile

The default-encryption profile enables MPPE (Microsoft Point-to-Point Encryption) negotiation during PPP authentication. This is the standard choice for most ISPs.

MikroTik includes two built-in profiles:

  • default — No encryption requirement
  • default-encryption — Requires encryption (recommended)

Most ISPs, including DIGI, work fine with either profile. Use default-encryption unless your ISP specifically requires otherwise. You can check available profiles with /ppp profile print.


Step 4: add interfaces to WAN list

For firewall rules to work correctly, add all WAN-related interfaces to an interface list. This is essential—without it, firewall rules referencing the WAN list won’t match traffic correctly.

ROUTEROSInterface Lists
# Create WAN interface list (skip if it already exists in your config)
/interface list add name=WAN comment="ISP Interfaces Group"

# Add WAN interfaces — all three layers of the ISP connection
/interface list member add \
    interface=ether1 \
    list=WAN \
    comment="ISP Physical port"                                    # ← CUSTOMIZE port

/interface list member add \
    interface=VLAN_DIGI \
    list=WAN \
    comment="ISP VLAN"                                             # Skip if no VLAN

/interface list member add \
    interface=PPPoE_DIGI \
    list=WAN \
    comment="ISP PPPoE Client"

Step 5: configure DHCPv6 client for prefix delegation

This is where IPv6 gets interesting. DIGI provides a /56 prefix via DHCPv6-PD (Prefix Delegation). We need to:

  1. Request the prefix from DIGI
  2. Store it in a local pool
  3. Assign addresses to our LAN from that pool
  4. Configure Router Advertisements for SLAAC
ROUTEROSDHCPv6 Client with Script
/ipv6 dhcp-client add \
    interface=PPPoE_DIGI \
    pool-name=pool6 \
    request=prefix \
    add-default-route=yes \
    use-peer-dns=yes \
    allow-reconfigure=yes \
    rapid-commit=no \
    comment="DHCPv6 client for ISP DIGI" \
    script=":delay 5s;
/ipv6 address remove [find advertise=yes];
/ipv6 address add interface=bridge address=::1/64 from-pool=pool6 advertise=yes;"

The script waits 5 seconds for the pool to be populated, removes any old advertised IPv6 address on the bridge, and adds a new one from the updated pool. Because the address uses advertise=yes, RouterOS automatically creates a dynamic ND prefix for SLAAC—no manual ND prefix management is needed.


Step 6: assign IPv6 address to LAN

The router’s LAN interface needs an IPv6 address from the delegated pool:

ROUTEROSLAN IPv6 Address
/ipv6 address add \
    interface=bridge \
    address=::1/64 \
    from-pool=pool6 \
    advertise=yes

This creates an address like 2a0c:5a84:xxxx:xx00::1/64 where the prefix comes from DIGI’s delegation.


Step 7: configure Neighbor Discovery (SLAAC)

For LAN devices to automatically configure their IPv6 addresses via SLAAC (Stateless Address Autoconfiguration), configure Neighbor Discovery:

ROUTEROSIPv6 Neighbor Discovery
# Configure ND defaults
/ipv6 nd set [ find default=yes ] \
    hop-limit=64 \
    mtu=1500 \
    other-configuration=yes \
    reachable-time=30s \
    retransmit-interval=1s

# Configure ND for LAN bridge
/ipv6 nd add \
    interface=bridge \
    ra-preference=high \
    hop-limit=64 \
    mtu=1500 \
    dns=fe80::1 \
    reachable-time=30s \
    retransmit-interval=1s
Neighbor Discovery Parameters
ParameterValuePurpose
ra-preferencehighClients prefer this router over others
hop-limit64TTL for outgoing packets (standard value)
dnsfe80::1Router’s link-local address as DNS (RDNSS)
other-configurationyesTells clients to use DHCPv6 for other options

Step 8: configure IPv4 NAT (Masquerade)

For outbound IPv4 connectivity:

ROUTEROSIPv4 Masquerade
/ip firewall nat add \
    chain=srcnat \
    action=masquerade \
    out-interface-list=WAN \
    ipsec-policy=out,none \
    comment="Masquerade for internet access"

Step 9: verify the connection

Check PPPoE status

/interface pppoe-client print detail
Flags: X - disabled; R - running 0 R name="PPPoE_DIGI" max-mtu=1500 max-mru=auto mrru=disabled interface=VLAN_DIGI user="your_number@digi" password="****" profile=default-encryption keepalive-timeout=10 service-name="" ac-name="" add-default-route=yes default-route-distance=1 dial-on-demand=no use-peer-dns=yes allow=pap,chap,mschap1,mschap2 status=connected uptime=3d14h22m45s encoding="" local-address=79.117.xxx.xxx remote-address=10.0.0.1

Check negotiated PPPoE values

/interface pppoe-client monitor PPPoE_DIGI once
status: connected service-name: ftth ac-name: ftth mtu: 1480 mru: 1492 local-address: 79.117.xxx.xxx remote-address: 10.0.x.x local-ipv6-address: fe80::xxxx:xxxx:x:xx remote-ipv6-address: fe80::1

Check IPv6 prefix delegation

/ipv6 pool print
Flags: D - dynamic 0 D name="pool6" prefix=2001:db8:abcd:ef00::/56 prefix-length=64

Check IPv6 addresses

/ipv6 address print where interface=bridge
Flags: X - disabled, I - invalid, D - dynamic, G - global, L - link-local 0 DG address=2001:db8:abcd:ef00::1/64 from-pool=pool6 interface=bridge advertise=yes

Test IPv6 connectivity

/ping 2001:4860:4860::8888 count=4

Complete configuration summary

pppoe-digi-complete.rsc
# ═══════════════════════════════════════════════════════════════════════════════
# MIKROTIK PPPoE CONFIGURATION FOR DIGI SPAIN
# ═══════════════════════════════════════════════════════════════════════════════
# Dual-Stack IPv4 + IPv6 with DHCPv6 Prefix Delegation
# ═══════════════════════════════════════════════════════════════════════════════

# ───────────────────────────────────────────────────────────────────────────────
# PHYSICAL INTERFACE
# ───────────────────────────────────────────────────────────────────────────────

/interface ethernet set [ find default-name=ether1 ] \          # ← CUSTOMIZE port
    comment="DIGI ONT" \
    rx-flow-control=auto \
    tx-flow-control=auto

# ───────────────────────────────────────────────────────────────────────────────
# VLAN CONFIGURATION (skip if your ISP doesn't use VLANs)
# ───────────────────────────────────────────────────────────────────────────────

/interface vlan add \
    name=VLAN_DIGI \
    vlan-id=20 \                                                   # ← CUSTOMIZE VLAN ID
    interface=ether1 \                                              # ← CUSTOMIZE port
    comment="VLAN for ISP connection"

# ───────────────────────────────────────────────────────────────────────────────
# PPPoE CLIENT
# ───────────────────────────────────────────────────────────────────────────────

/interface pppoe-client add \
    name=PPPoE_DIGI \
    interface=VLAN_DIGI \                                           # ← Use ether port if no VLAN
    user="your_number@digi" \                                       # ← CUSTOMIZE credentials
    password="your_password" \                                      # ← CUSTOMIZE credentials
    add-default-route=yes \
    use-peer-dns=yes \
    max-mtu=1500 \                                                  # Upper limit; server negotiates actual MTU via LCP
    profile=default-encryption \
    disabled=no \
    comment="PPPoE client for ISP DIGI"

# ───────────────────────────────────────────────────────────────────────────────
# INTERFACE LISTS
# ───────────────────────────────────────────────────────────────────────────────

/interface list add name=WAN comment="ISP Interfaces Group"    # Skip if it already exists

/interface list member add interface=ether1 list=WAN comment="ISP Physical port"         # ← CUSTOMIZE port
/interface list member add interface=VLAN_DIGI list=WAN comment="ISP VLAN"                # Skip if no VLAN
/interface list member add interface=PPPoE_DIGI list=WAN comment="ISP PPPoE Client"

# ───────────────────────────────────────────────────────────────────────────────
# DHCPv6 CLIENT (PREFIX DELEGATION)
# ───────────────────────────────────────────────────────────────────────────────

/ipv6 dhcp-client add \
    interface=PPPoE_DIGI \
    pool-name=pool6 \
    request=prefix \
    add-default-route=yes \
    use-peer-dns=yes \
    allow-reconfigure=yes \
    rapid-commit=no \
    comment="DHCPv6 client for ISP DIGI" \
    script=":delay 5s;
/ipv6 address remove [find advertise=yes];
/ipv6 address add interface=bridge address=::1/64 from-pool=pool6 advertise=yes;"

# ───────────────────────────────────────────────────────────────────────────────
# IPv6 ADDRESS FOR LAN
# ───────────────────────────────────────────────────────────────────────────────

/ipv6 address add \
    interface=bridge \
    address=::1/64 \
    from-pool=pool6 \
    advertise=yes

# ───────────────────────────────────────────────────────────────────────────────
# NEIGHBOR DISCOVERY (SLAAC)
# ───────────────────────────────────────────────────────────────────────────────

/ipv6 nd set [ find default=yes ] \
    hop-limit=64 \
    mtu=1500 \
    other-configuration=yes \
    reachable-time=30s \
    retransmit-interval=1s

/ipv6 nd add \
    interface=bridge \
    ra-preference=high \
    hop-limit=64 \
    mtu=1500 \
    dns=fe80::1 \
    reachable-time=30s \
    retransmit-interval=1s

# ───────────────────────────────────────────────────────────────────────────────
# IPv4 NAT (MASQUERADE)
# ───────────────────────────────────────────────────────────────────────────────

/ip firewall nat add \
    chain=srcnat \
    action=masquerade \
    out-interface-list=WAN \
    ipsec-policy=out,none \
    comment="Masquerade for internet access"

Optional enhancements

The core PPPoE + DHCPv6-PD configuration is complete. The following sections cover additional features you can add depending on your needs.

IPv6 port forwarding with automatic NAT update

Create a port forwarding rule

You need at least one IPv6 dstnat rule. This example forwards HTTP and HTTPS traffic from the WAN to an internal web server:

ROUTEROSIPv6 Port Forwarding — Web Server
/ipv6 firewall nat add \
    chain=dstnat \
    action=dst-nat \
    protocol=tcp \
    dst-port=80,443 \
    in-interface=PPPoE_DIGI \
    to-address=2001:db8:abcd:ef00:1111:2222:3333:4444 \
    comment="Web Server"

Create the update script

Since the delegated prefix changes on each PPPoE reconnection, the to-address in your dstnat rules becomes stale. This script automatically reconstructs the full IPv6 address from the new prefix and updates all matching rules:

ROUTEROSIPv6 NAT Update Script
/system script add \
    name=update-ipv6-nat \
    comment="Auto-update IPv6 NAT when pool6 changes" \
    policy=read,write,policy,test \
    source={
:local serverHost "1111:2222:3333:4444";  # ← CUSTOMIZE: your server's host portion
:local poolprefix [/ipv6/pool get [find name=pool6] prefix];
:local slashPos [:find $poolprefix "/"];
:local prefix [:pick $poolprefix 0 $slashPos];
:local prefixLen [:len $prefix];
:if ([:pick $prefix ($prefixLen - 2) $prefixLen] = "::") do={
    :set prefix [:pick $prefix 0 ($prefixLen - 1)];
}
:local serverIPv6 ($prefix . $serverHost);
/ipv6/firewall/nat set [find comment="Web Server"] to-address=$serverIPv6;
:log info ("IPv6 NAT updated: " . $serverIPv6);
}

How the script works

Complete IPv6 Address

Static Host Suffix

ISP Delegated Prefix

2001:db8:abcd:ef00

1111:2222:3333:4444

2001:db8:abcd:ef00:1111:2222:3333:4444

IPv6 Address Construction

The script:

  1. Gets the current prefix from pool6 (e.g., 2001:db8:abcd:ef00::/56)
  2. Strips the length notation (/56) and trailing :: to isolate the network prefix
  3. Appends the static host portion to form the complete IPv6 address
  4. Updates all matching dstnat rules identified by their comment field

Basic firewall rules

Secure your connection with essential firewall rules for both IPv4 and IPv6:

firewall-basic.rsc
# ═══════════════════════════════════════════════════════════════════════════════
# IPv4 FIREWALL - INPUT CHAIN
# ═══════════════════════════════════════════════════════════════════════════════

/ip firewall filter

# Accept established and related connections
add chain=input action=accept \
    connection-state=established,related \
    comment="Accept established/related"

# Drop invalid connections
add chain=input action=drop \
    connection-state=invalid \
    comment="Drop invalid"

# Accept ICMP (ping)
add chain=input action=accept \
    protocol=icmp \
    comment="Accept ICMP"

# Accept from LAN
add chain=input action=accept \
    in-interface-list=LAN \
    comment="Accept from LAN"

# Drop everything else from WAN
add chain=input action=drop \
    in-interface-list=WAN \
    comment="Drop all from WAN"

# ═══════════════════════════════════════════════════════════════════════════════
# IPv4 FIREWALL - FORWARD CHAIN
# ═══════════════════════════════════════════════════════════════════════════════

# FastTrack established connections
add chain=forward action=fasttrack-connection \
    connection-state=established,related \
    hw-offload=yes \
    comment="FastTrack"

add chain=forward action=accept \
    connection-state=established,related \
    comment="Accept established/related"

# Drop invalid
add chain=forward action=drop \
    connection-state=invalid \
    comment="Drop invalid"

# Accept from LAN to WAN
add chain=forward action=accept \
    in-interface-list=LAN \
    out-interface-list=WAN \
    comment="LAN to WAN"

# Drop everything else
add chain=forward action=drop \
    comment="Drop all other forward"


# ═══════════════════════════════════════════════════════════════════════════════
# IPv6 FIREWALL - INPUT CHAIN
# ═══════════════════════════════════════════════════════════════════════════════

/ipv6 firewall filter

# Accept established and related
add chain=input action=accept \
    connection-state=established,related \
    comment="Accept established/related"

# Drop invalid
add chain=input action=drop \
    connection-state=invalid \
    comment="Drop invalid"

# Accept ICMPv6
add chain=input action=accept \
    protocol=icmpv6 \
    comment="Accept ICMPv6"

# Accept DHCPv6 client replies
add chain=input action=accept \
    protocol=udp \
    dst-port=546 \
    src-address=fe80::/10 \
    comment="Accept DHCPv6-Client prefix delegation"

# Accept from LAN
add chain=input action=accept \
    in-interface-list=LAN \
    comment="Accept from LAN"

# Drop from WAN
add chain=input action=drop \
    in-interface-list=WAN \
    comment="Drop all from WAN"


# ═══════════════════════════════════════════════════════════════════════════════
# IPv6 FIREWALL - FORWARD CHAIN
# ═══════════════════════════════════════════════════════════════════════════════

# Accept established and related
add chain=forward action=accept \
    connection-state=established,related \
    comment="Accept established/related"

# Drop invalid
add chain=forward action=drop \
    connection-state=invalid \
    comment="Drop invalid"

# Accept ICMPv6 for path MTU discovery
add chain=forward action=accept \
    protocol=icmpv6 \
    comment="Accept ICMPv6"

# Accept outbound from LAN
add chain=forward action=accept \
    in-interface-list=LAN \
    out-interface-list=WAN \
    comment="LAN to WAN"

# Drop all other forward
add chain=forward action=drop \
    comment="Drop all other forward"

PPPoE logging

Optionally enable PPPoE event logging for troubleshooting:

ROUTEROSPPPoE Logging
/system logging add \
    topics=pppoe \
    prefix="[PPPoE]" \
    action=memory

Troubleshooting

PPPoE won’t connect

  • Verify VLAN ID is 20
  • Check username format: identifier@digi
  • Ensure ONT is in bridge mode
  • Check physical cable connection

No IPv6 prefix received

  • DHCPv6 client must be on PPPoE interface, not VLAN
  • Request type should be prefix not address
  • Check firewall allows DHCPv6 (UDP 546)

LAN devices don’t get IPv6

  • Verify ND is configured for bridge interface
  • Check advertise=yes on bridge IPv6 address
  • Ensure pool6 has a valid prefix

Conclusion

You now have a complete dual-stack configuration for DIGI Spain with:

  • PPPoE authentication over VLAN 20
  • Dynamic IPv4 with automatic default route
  • DHCPv6 Prefix Delegation for native IPv6
  • Automatic handling of prefix changes
  • SLAAC for effortless LAN device configuration

This setup ensures your network maintains full IPv4 and IPv6 connectivity even when the ISP changes your assigned prefixes. The DHCPv6 script handles the complexity of prefix changes, making the configuration truly “set and forget.”