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

> One post from jmrp.io, published as its own document. Index: https://jmrp.io/llms-full.txt

Canonical: https://jmrp.io/blog/008-mikrotik-pppoe-dualstack-digi/
Language: en
Alternate: https://jmrp.io/es/blog/008-mikrotik-pppoe-dualstack-digi/index.md
License: https://creativecommons.org/licenses/by/4.0/
Type: TechArticle
Published: 2026-02-15
Updated: 2026-09-02
Instructions re-tested: 2026-08-01 · RouterOS 7.23.2 · RB5009UG+S+
Author: José Manuel Requena Plens
Summary: Configure PPPoE with DHCPv6 Prefix Delegation on MikroTik RouterOS for DIGI Spain. VLAN tagging, SLAAC, prefix change handling, and firewall rules.
Tags: MikroTik, IPv6, Networking
Topics: Point-to-Point Protocol over Ethernet (Q866392), MikroTik (Q913580), IPv6 (Q2551624), DHCPv6 (Q11170), IEEE 802.1Q (Q1535269), Stateless Address Autoconfiguration (Q117198154)
Build-Date: 2026-10-09

Questions answered:

**What VLAN does DIGI Spain use for PPPoE?**

DIGI Spain requires 802.1Q VLAN 20 tagging for PPPoE internet traffic. If you connect directly without VLAN tagging, PPPoE authentication will fail.

**What IPv6 prefix does DIGI delegate via DHCPv6-PD?**

DIGI delegates a dynamic /56 prefix through DHCPv6 Prefix Delegation, giving you 256 /64 subnets to use for your main LAN, IoT, guest network, and more. The prefix can change on each reconnection.

**How do I handle DIGI's IPv6 prefix changing on reconnection?**

Add a script to the DHCPv6 client that waits 5 seconds for the pool to populate, removes the old advertised address on the bridge, and adds a new one from the updated pool6. Because the address uses advertise=yes, RouterOS automatically creates the ND prefix for SLAAC.

**Why is the PPPoE MTU 1480 when I set max-mtu to 1500?**

The max-mtu parameter is only the upper limit the client will accept, not the actual link MTU. The PPPoE server determines the real MTU during LCP negotiation, and DIGI negotiates it down to 1480 regardless of your max-mtu value.

**Why won't my PPPoE connection authenticate with DIGI?**

Check that the VLAN ID is 20, the username uses the identifier@digi format, the ONT is in bridge mode, and the physical cable is connected. The DHCPv6 client must also be on the PPPoE interface, not the VLAN.

**Does this MikroTik configuration work with other ISPs besides DIGI?**

Yes. It works with any PPPoE-based ISP that provides IPv6 via DHCPv6-PD. The per-ISP differences are usually the VLAN ID (or no VLAN), the negotiated MTU (typically 1480–1492), the username format, and the delegated prefix size (/48, /56, or /64).


Steps (Configure MikroTik PPPoE + DHCPv6-PD dual-stack for DIGI Spain):
1. Configure the physical interface
2. Create the VLAN interface
3. Configure the PPPoE client
4. Add interfaces to the WAN list
5. Configure the DHCPv6 client for prefix delegation
6. Configure Neighbor Discovery for SLAAC
7. Configure IPv4 NAT (masquerade)
8. Verify the connection

---

[DIGI Spain](https://www.digimobil.es/) is one of the few ISPs in Spain that provides native IPv6 connectivity to residential customers. Their fiber network uses [PPPoE](https://datatracker.ietf.org/doc/html/rfc2516) authentication with VLAN tagging and delivers both a dynamic IPv4 address and a dynamic /56 IPv6 prefix via [DHCPv6 Prefix Delegation (DHCPv6-PD)](https://datatracker.ietf.org/doc/html/rfc3633).

This guide covers the complete configuration of a [MikroTik](https://mikrotik.com/) 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.

## TL;DR — DIGI Spain dual-stack on RouterOS

- **DIGI delivers the PPPoE session on VLAN 20.** Put the PPPoE client on a VLAN interface over the WAN port, not on the port itself, or authentication fails with no useful error — this is the single most common reason these setups do not come up.
- **The username format is `identifier@digi`**, and IPv4 arrives dynamically with the default route and peer DNS from the session.
- **IPv6 is a delegated `/56`, not a `/64`.** Request the prefix with DHCPv6-PD and carve a `/64` out of it per LAN; pointing the `/56` straight at a bridge does not work.
- **The link MTU negotiates down to 1480 via LCP no matter what.** `max-mtu=1500` is only the client's upper limit, not the resulting MTU, so clamp MSS or half the web loads and the other half hangs.
- **The delegated prefix changes on reconnection**, so a DHCPv6 script has to rewrite the LAN addresses; without it IPv6 dies silently after an outage while IPv4 keeps working.
- **Tested on RouterOS 7.23.2 on an RB5009**, and applicable to any MikroTik router.

**Important — DIGI-Specific vs Generic Values**

This guide is written for **DIGI Spain**, but the PPPoE + DHCPv6-PD setup applies to many ISPs. Values specific to DIGI are clearly marked:

- **VLAN 20** — DIGI-specific. Other ISPs may use different VLAN IDs or no VLAN at all
- **`your_number@digi`** — DIGI username format (a numeric identifier assigned by DIGI). Replace with your ISP's credentials
- **`max-mtu=1500`** — Upper limit the client will accept. DIGI negotiates the actual MTU to **1480** via LCP
- **`ether1`** — Physical port connected to ONT. Use whichever port you prefer

- **`pool6`** — DHCPv6 pool name. Can be any name you choose

If your ISP doesn't use VLAN tagging, skip Step 2 and set the PPPoE client interface directly to the physical port.

---

## How I run this on my own infrastructure

This isn't theoretical: my own RB5009UG+S+ runs exactly this PPPoE + DHCPv6-PD setup against DIGI, with the WAN VLAN tagged `vlan-id=20` (`VLAN_DIGI`) just as described above. The RouterOS version it was last checked against is stamped at the top of this page.

The prefix-change handling in Step 5 isn't defensive programming for an edge case — it's the normal case. Every time I restart the PPPoE interface, or the router itself, DIGI hands me a new /56 prefix. Not occasionally: every single time. That's exactly why the LAN addressing can't hardcode a prefix and has to re-derive it on reconnection; anything that assumes a static prefix breaks on the very first reboot. The trade-off is a few seconds of dropped sessions while the interface renegotiates — the same brief interruption you'd see from any external disconnection.

The negotiated MTU of 1480 isn't a guess either. I've confirmed it three separate ways: DIGI's own published documentation, the configuration shipped on DIGI's stock router, and by directly testing different MTU values on my own connection. All three agree on 1480, not the 1500 that `max-mtu` merely allows as an upper limit.

---

## How does PPPoE carry both IPv4 and IPv6?

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**

| 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 |

**Info — About the /56 Prefix**

DIGI delegates a /56 prefix, which gives you 256 /64 subnets to work with. This is generous compared to some ISPs that only provide a single /64. You can use different /64 subnets for your main LAN, IoT network, guest network, etc.

---

## Prerequisites

**Before You Start**

- **MikroTik router** with RouterOS 7.x or later
- **DIGI fiber connection** with ONT in bridge mode (or your ISP's equivalent)
- **PPPoE credentials** from your ISP (DIGI format: `identifier@digi`)
- **Physical ethernet cable** between ONT and router
- **Administrative access** to your MikroTik router (WinBox, WebFig, or SSH)
- **Interface lists** `WAN` and `LAN` with your bridge already in the `LAN` list (default in most MikroTik configurations)

**Tip — Other ISPs Using PPPoE**

This configuration works with any PPPoE-based ISP that provides IPv6 via DHCPv6-PD. The key differences per ISP are usually: VLAN ID (or no VLAN), negotiated MTU (typically 1480–1492, determined by the server via LCP), username format, and the delegated prefix size (/48, /56, or /64). Adjust the DIGI-specific values for your ISP.

---

## Step 1: configure the physical interface

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

**Physical Interface Configuration**

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

**Tip — Which Port to Use**

Choose any available ethernet port. In this example, we use `ether1`, but you can use any port not assigned to your LAN bridge. Using a dedicated port for WAN improves security and simplifies firewall rules.

---

## Step 2: create the VLAN interface

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

**VLAN Configuration**

```routeros
/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](https://datatracker.ietf.org/doc/html/rfc3069) 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.

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:

```routeros
/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:

**PPPoE Client Configuration**

```routeros
/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"
```

**Warning — Replace Credentials**

You **must** replace `your_number@digi` and `your_password` with the credentials provided by your ISP. For DIGI Spain, the username is a numeric identifier assigned by DIGI followed by `@digi`.

**PPPoE Configuration Parameters**

| 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 |

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`.

**Info — MTU Considerations**

The `max-mtu` parameter is the **upper limit** the client is willing to accept—it is not the actual MTU used on the link. The real MTU is determined by the PPPoE server during [LCP negotiation](https://datatracker.ietf.org/doc/html/rfc1661#section-6.1). DIGI's server negotiates MTU to **1480** regardless of the `max-mtu` value you set. Using `max-mtu=1500` is safe and gives the server room to negotiate higher if it ever supports it.

**Important**: Changing `max-mtu` on a live PPPoE client causes RouterOS to **restart the session**, resulting in a brief disconnection (~3–5 seconds) while it renegotiates with the server.

---

## 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.

**Interface Lists**

```routeros
# 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"
```

**Info — Why Three WAN Interfaces?**

The WAN list includes all three layers because firewall rules may need to match traffic at different stages:

- **Physical port** (`ether1`): Raw ethernet frames
- **VLAN** (`VLAN_DIGI`): Tagged traffic before PPPoE
- **PPPoE** (`PPPoE_DIGI`): Authenticated tunnel (most firewall rules match here)

Adding all three ensures your firewall rules work regardless of which interface the traffic arrives on.

---

## Step 5: configure DHCPv6 client for prefix delegation

This is where IPv6 gets interesting. DIGI provides a /56 prefix via [DHCPv6-PD (Prefix Delegation)](https://datatracker.ietf.org/doc/html/rfc3633). 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](https://datatracker.ietf.org/doc/html/rfc4862)

**DHCPv6 Client with Script**

```routeros
/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.

**Info — Why Remove and Re-add?**

When the ISP prefix changes (PPPoE reconnection, lease renewal), the old address becomes invalid. The script ensures the bridge always has a valid address from the current pool. The `advertise=yes` flag triggers RouterOS to automatically announce the correct `/64` prefix to LAN devices via Router Advertisements (SLAAC).

---

## Step 6: assign IPv6 address to LAN

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

**LAN IPv6 Address**

```routeros
/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)](https://datatracker.ietf.org/doc/html/rfc4862), configure Neighbor Discovery:

**IPv6 Neighbor Discovery**

```routeros
# 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**

| 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:

**IPv4 Masquerade**

```routeros
/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

**Terminal session — PPPoE Client Status**

```routeros
/interface pppoe-client print detail
```

**Output — Connected PPPoE**

```text
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
```

**Tip — What to Look For**

- **status=connected** — The PPPoE session is active
- **local-address** — Your public IPv4 address assigned by the ISP
- **max-mtu** — Upper limit the client accepts (1500). The actual MTU is negotiated by the server via LCP (DIGI: 1480)
- If `status=connecting` or `status=disconnected`, check your credentials and VLAN configuration

### Check negotiated PPPoE values

**Terminal session — PPPoE Monitor Output**

```routeros
/interface pppoe-client monitor PPPoE_DIGI once
```

**Output — Negotiated Values**

```text
               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
```

**Tip — Monitor vs Print**

The `monitor` command shows **live negotiated values**—the actual MTU (1480), MRU (1492), service name (`ftth`), and access concentrator name. Use this to verify what the server actually provides, as opposed to `print detail` which shows your configured parameters.

### Check IPv6 prefix delegation

**Terminal session — IPv6 Prefix Delegation**

```routeros
/ipv6 pool print
```

**Output — Delegated Prefix**

```text
Flags: D - dynamic
 0 D name="pool6" prefix=2001:db8:abcd:ef00::/56 prefix-length=64
```

**Info — Example Prefix**

The prefix shown above (`2001:db8:...`) is a documentation example. Your ISP will assign a real prefix from their allocation.
DIGI Spain typically delegates a `/56` prefix, giving you 256 possible `/64` subnets.

### Check IPv6 addresses

```routeros
/ipv6 address print where interface=bridge
```

**Output — LAN IPv6 Address**

```text
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

**Test IPv6**

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

---

## Complete configuration summary

**File: `pppoe-digi-complete.rsc` — Complete DIGI PPPoE Configuration**

```routeros
# ═══════════════════════════════════════════════════════════════════════════════
# 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

**Info — When Do You Need This?**

Only required if you expose services to the internet over IPv6 (e.g., a web server). If you only need outbound IPv6 connectivity for LAN devices, skip this section.

If you use this script, add `/system script run update-ipv6-nat;` as the last line of the DHCPv6 client script from Step 5 so it runs automatically on each prefix change.

#### 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 Port Forwarding — Web Server**

```routeros
/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"
```

**Tip — Rule Identification by Comment**

The `comment` field is how the update script identifies which rules to modify. Use a **descriptive and unique** comment for each service you expose. If you have additional services, add more rules with different comments (e.g., `"Mail Server"`, `"Game 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:

**IPv6 NAT Update Script**

```routeros
/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);
}
```

**Important — Customize Before Use**

Replace `1111:2222:3333:4444` with your server's static IPv6 host portion (see tip below). Replace `"Web Server"` with the exact comment on your NAT rule. If you have multiple rules, add a `set [find comment="..."]` line for each one.

#### How the script works

**IPv6 Address Construction**

```mermaid
flowchart LR
    subgraph Prefix["ISP Delegated Prefix"]
        P1["2001:db8:abcd:ef00"]:::info
    end
    
    subgraph Host["Static Host Suffix"]
        H1["1111:2222:3333:4444"]:::highlight
    end
    
    subgraph Full["Complete IPv6 Address"]
        F1["2001:db8:abcd:ef00:1111:2222:3333:4444"]:::success
    end
    
    P1 --> F1
    H1 --> F1
```

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

**Tip — Static Host Portion**

Use your server's [EUI-64 address](https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.1) (derived from its MAC address) or assign a [static suffix](https://datatracker.ietf.org/doc/html/rfc8064). The host portion remains constant across prefix changes, making automatic updates reliable.

**Note — Alternative: Address List**

If you manage multiple services pointing to the same server, consider maintaining a **firewall address list** with the server's current IPv6. The script updates a single entry in `/ipv6 firewall address-list`, and firewall **filter** rules can reference it via `dst-address-list` — simplifying rule management. Note that dstnat rules require an explicit `to-address`, so those still need individual updates in the script.

### Basic firewall rules

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

**File: `firewall-basic.rsc` — Basic Firewall Configuration**

```routeros
# ═══════════════════════════════════════════════════════════════════════════════
# 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:

**PPPoE Logging**

```routeros
/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](https://www.digimobil.es/) 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."

