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.

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
| Parameter | Value | Notes |
|---|---|---|
| Connection Type | PPPoE over VLAN 20 | VLAN tagging required |
| IPv4 Address | Dynamic (CGNAT or Public) | Assigned via PPPoE |
| IPv6 Prefix | Dynamic /56 | Via DHCPv6-PD, can change on reconnect |
| MTU | 1480 (negotiated) | Standard PPPoE, negotiated via LCP |
| MRU | 1492 (negotiated) | Maximum Receive Unit, negotiated via LCP |
| Service Name | ftth | PPPoE service identifier reported by DIGI |
| DNS | ISP-provided or custom | Can use peer DNS or configure your own |
Prerequisites
Step 1: configure the physical interface
First, configure the ethernet port connected to the DIGI ONT:
/interface ethernet set [ find default-name=ether1 ] \
comment="DIGI ONT" \
rx-flow-control=auto \
tx-flow-control=autoStep 2: create the VLAN interface
DIGI requires VLAN 20 tagging for PPPoE traffic. Create the VLAN interface:
/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:
/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"| Parameter | Value | Purpose |
|---|---|---|
interface | VLAN_DIGI | PPPoE runs over the VLAN interface, not the physical port |
add-default-route | yes | Automatically adds default route when connected |
use-peer-dns | yes | Uses DIGI’s DNS servers (can disable for custom DNS) |
max-mtu | 1500 | Maximum MTU the client accepts. DIGI negotiates down to 1480 via LCP |
profile | default-encryption | Standard 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 requirementdefault-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.
# 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:
- Request the prefix from DIGI
- Store it in a local pool
- Assign addresses to our LAN from that pool
- Configure Router Advertisements for SLAAC
/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:
/ipv6 address add \
interface=bridge \
address=::1/64 \
from-pool=pool6 \
advertise=yesThis 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:
# 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| Parameter | Value | Purpose |
|---|---|---|
ra-preference | high | Clients prefer this router over others |
hop-limit | 64 | TTL for outgoing packets (standard value) |
dns | fe80::1 | Router’s link-local address as DNS (RDNSS) |
other-configuration | yes | Tells clients to use DHCPv6 for other options |
Step 8: configure IPv4 NAT (Masquerade)
For outbound IPv4 connectivity:
/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
Check negotiated PPPoE values
Check IPv6 prefix delegation
Check IPv6 addresses
Test IPv6 connectivity
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:
/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:
/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
The script:
- Gets the current prefix from
pool6(e.g.,2001:db8:abcd:ef00::/56) - Strips the length notation (
/56) and trailing::to isolate the network prefix - Appends the static host portion to form the complete IPv6 address
- Updates all matching dstnat rules identified by their
commentfield
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:
/system logging add \
topics=pppoe \
prefix="[PPPoE]" \
action=memoryTroubleshooting
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
prefixnotaddress - Check firewall allows DHCPv6 (UDP 546)
LAN devices don’t get IPv6
- Verify ND is configured for bridge interface
- Check
advertise=yeson 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.”