No IPv6 on DietPi with SLAAC

Creating a bug report/issue

Required Information

  • DietPi version | cat /boot/dietpi/.version
G_DIETPI_VERSION_CORE=8
G_DIETPI_VERSION_SUB=19
G_DIETPI_VERSION_RC=1
G_GITBRANCH='master'
G_GITOWNER='MichaIng'
G_LIVE_PATCH_STATUS[0]='applied'
G_LIVE_PATCH_STATUS[1]='applied'
G_LIVE_PATCH_STATUS[2]='applied'
  • Distro version | echo $G_DISTRO_NAME $G_RASPBIAN
bookworm 0
  • Kernel version | uname -a
Linux DietPi 6.1.21-v8+ #1642 SMP PREEMPT Mon Apr  3 17:24:16 BST 2023 aarch64 GNU/Linux
  • Architecture | dpkg --print-architecture
arm64
  • SBC model | echo $G_HW_MODEL_NAME or (EG: RPi3)
RPi 4 Model B (aarch64)
  • Power supply used | (EG: 5V 1A RAVpower)
    2.5A 5V OKDO
  • SD card used | (EG: SanDisk ultra)
    Samsung EVO 32GB

Additional Information (if applicable)

  • Software title | (EG: Nextcloud)
    Running the following software:
OpenSSH Client
Tailscale
WiFi Hotspot
DietPi-RAMlog
Dropbear
NFS Client
Docker Compose
Docker
Portainer
  • Was the software title installed freshly or updated/migrated?
    No updates ran, recently installed DietPi.
  • Can this issue be replicated on a fresh installation of DietPi?
    Unsure, since it's running in production right now I can't have too much downtime to check.
    ← If you sent a ā€œdietpi-bugreportā€, please paste the ID here →
  • Bug report ID | echo $G_HW_UUID
    Might be irrelevant but do get errors regarding isc-dhcp-server
    2f846fe6-b075-4745-89c0-86c6ab380fc1

Steps to reproduce

  1. Have IPv6 enabled in dietpi-config
  2. Restart interfaces

Expected behaviour

  • Have IPv6 with a link-global address.

Actual behaviour

  • Have no link-global address.

Extra details

  • I’m running OpenWRT as a router on a separate Pi
  • All of my other devices, laptops, Xbox, phones, Smart TV, IoT devices, all get IPv6 global addresses except the DietPi hinting that the router config shouldn’t be borked.
  • I have SLAAC running on OpenWRT with no RA flags.

Output of ip a

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether e4:5f:01:0c:8b:b5 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.4/24 brd 192.168.1.255 scope global dynamic eth0
       valid_lft 42805sec preferred_lft 42805sec
    inet6 fe80::e65f:1ff:fe0c:8bb5/64 scope link
       valid_lft forever preferred_lft forever
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether e4:5f:01:0c:8b:b7 brd ff:ff:ff:ff:ff:ff
    inet 192.168.42.1/24 brd 192.168.42.255 scope global wlan0
       valid_lft forever preferred_lft forever
    inet6 fe80::e65f:1ff:fe0c:8bb7/64 scope link
       valid_lft forever preferred_lft forever
4: tailscale0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1280 qdisc pfifo_fast state UNKNOWN group default qlen 500
    link/none
    inet 100.87.207.113/32 scope global tailscale0
       valid_lft forever preferred_lft forever
    inet6 fd7a:115c:a1e0:ab12:4843:cd96:6257:cf71/128 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::4178:f2e5:907c:d1e0/64 scope link stable-privacy
       valid_lft forever preferred_lft forever
5: br-7ae53c7f8e4e: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:e3:0a:5d:ef brd ff:ff:ff:ff:ff:ff
    inet 172.19.0.1/16 brd 172.19.255.255 scope global br-7ae53c7f8e4e
       valid_lft forever preferred_lft forever
    inet6 fe80::42:e3ff:fe0a:5def/64 scope link
       valid_lft forever preferred_lft forever
6: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:c3:e3:27:a1 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:c3ff:fee3:27a1/64 scope link
       valid_lft forever preferred_lft forever
7: br-e64e81805d59: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:c9:a6:d1:fe brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.1/16 brd 172.18.255.255 scope global br-e64e81805d59
       valid_lft forever preferred_lft forever
    inet6 fe80::42:c9ff:fea6:d1fe/64 scope link
       valid_lft forever preferred_lft forever
9: vethaf49004@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-e64e81805d59 state UP group default
    link/ether fe:37:6c:2b:7d:97 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::fc37:6cff:fe2b:7d97/64 scope link
       valid_lft forever preferred_lft forever
11: veth3a9c1bb@if10: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
    link/ether e2:6c:ad:93:cb:5f brd ff:ff:ff:ff:ff:ff link-netnsid 1
    inet6 fe80::e06c:adff:fe93:cb5f/64 scope link
       valid_lft forever preferred_lft forever
13: veth7596823@if12: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-7ae53c7f8e4e state UP group default
    link/ether 5e:62:cc:9a:fe:ca brd ff:ff:ff:ff:ff:ff link-netnsid 2
    inet6 fe80::5c62:ccff:fe9a:feca/64 scope link
       valid_lft forever preferred_lft forever
15: veth8199274@if14: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-e64e81805d59 state UP group default
    link/ether ae:ec:4d:af:c6:d8 brd ff:ff:ff:ff:ff:ff link-netnsid 5
    inet6 fe80::acec:4dff:feaf:c6d8/64 scope link
       valid_lft forever preferred_lft forever
17: vethe09af91@if16: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-e64e81805d59 state UP group default
    link/ether be:ce:db:8c:ca:09 brd ff:ff:ff:ff:ff:ff link-netnsid 4
    inet6 fe80::bcce:dbff:fe8c:ca09/64 scope link
       valid_lft forever preferred_lft forever
19: veth810eae2@if18: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-e64e81805d59 state UP group default
    link/ether c6:1c:ab:d3:34:89 brd ff:ff:ff:ff:ff:ff link-netnsid 3
    inet6 fe80::c41c:abff:fed3:3489/64 scope link
       valid_lft forever preferred_lft forever
21: veth8baea87@if20: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-e64e81805d59 state UP group default
    link/ether de:88:f8:f5:14:59 brd ff:ff:ff:ff:ff:ff link-netnsid 8
    inet6 fe80::dc88:f8ff:fef5:1459/64 scope link
       valid_lft forever preferred_lft forever
23: veth7808f66@if22: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-e64e81805d59 state UP group default
    link/ether 0e:d4:1b:6d:37:6b brd ff:ff:ff:ff:ff:ff link-netnsid 6
    inet6 fe80::cd4:1bff:fe6d:376b/64 scope link
       valid_lft forever preferred_lft forever
25: vethde62429@if24: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-e64e81805d59 state UP group default
    link/ether 82:3c:01:77:9b:13 brd ff:ff:ff:ff:ff:ff link-netnsid 7
    inet6 fe80::803c:1ff:fe77:9b13/64 scope link
       valid_lft forever preferred_lft forever

Maybe @MichaIng or @trendy have an idea what it could be.

Hopefully! I think I’ve seen @trendy on the OpenWRT forums too which is cool!

In the meantime do you know how to force a release and renew of DHCP without having to take down the interface?

Edit: Figured it out how to do with networkd, killed my network because I didn’t do a double command lol but hopefully it’ll get an IPv6 now, enabled DHCPv6 on the router with the RA Other Config flag indicating that there’s general IP information available like DNS.

Edit 2: I renewed the lease, Put DHCPv6 with RA Flag to O and it seems like I still am not receiving IPv6.

2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether e4:5f:01:0c:8b:b5 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.4/24 brd 192.168.1.255 scope global dynamic eth0
       valid_lft 41598sec preferred_lft 41598sec
    inet6 fe80::e65f:1ff:fe0c:8bb5/64 scope link
       valid_lft forever preferred_lft forever

Alright so for those with the same issue the solution was way too simple.

dhclient -6 will request a IPv6 lease. This however only work when there’s a DHCPv6 server running on the server.

Since I have two primary goals for all of this:

  • Run an AdGuard Home server on the DietPi
  • Have SLAAC as a backup method if I decide to use my OpenWRT as Adblocking or SLAAC again.

After reading a couple of hours of documentation I was able to configure /etc/network/interfaces.d with a drop file I named eth0.conf and added accept_ra 2. I think this triggered the system get an IPv6 addressSee below, I’ve since tried to replicate it not working and can’t get the IPv6 address to go away lol. I will investigate further to try and replicate the config. I guess this is what happens when you try a bunch of things and not keep track of everything you do.

In the meantime, is there a way to reset the network config so everything will be as when installed?


Edit:
Removed the config file /etc/network/interfaces.d/eth0.conf and instead of just doing a service networking restart I actually rebooted.
To get the IPv6 back it wasn’t accept_ra 2 but it was iface eth0 inet6 auto.


So to get IPv6 running if you can't get it over SLAAC normally, here's a short guide:

Use sudo if you’re not using the root user:
sudo nano example.conf

  1. Create a config file /etc/network/interfaces.d/eth0.conf:
nano /etc/network/interfaces.d/eth0.conf
  1. Add the following line:
iface eth0 inet6 auto
  1. Save by pressing ctrl+x and confirm with pressing y

  2. Restarting the networking service:

service networking restart
  1. Confirm you have a IPv6 address on the interface:
ip addr show eth0

I’m curious about why DietPi doesn’t have this option by default. Is there a reason for it? I noticed that the documentation suggests it’s a requirement for the function to work.

I would want suggest to add in the DietPi-Config to have more a bit more expanded options for IPv6, maybe a option to change from auto to DHCPv6, for example:

IPv6: [On]/[Off]
IPv6 Config: [Auto]/[DHCPv6]

From what I understand auto uses EUI64 to get the address.

Actually, SLAAC should work OOTB without this entry. It is redundant, at least I am not aware of any other case where this was ever needed. I use IPv6 via SLAAC as well. Basically the kernel driver itself accepts RAs and does SLAAC based on it without the need for any network stack to interfere.

This is indeed needed if the interface is otherwise configured to forward incoming requests as gateway (ip_forward=1). In this case by default it is assuming that the host is a router and should hence not accept RAs from other routers. 2 enforces it however. At least in case of the dietpi-software install options, it is sweet by default in cases where forwarding is needed, like for WiFi hotspot or VPN servers.

But not sure e.g. whether Tailscale can interfere.

Not sure whether there is a way to check what the system does with incoming RAs and why :thinking:.

Ohhh, this does make sense. So because I installed the HotSpot package it must’ve triggered something to not listen to RA’s anymore? I googled and it seems you can possibly listen to RA packages through tcpdump -n -i eth0 icmp6 and ip6[40] == 134, not sure about how the system uses them tho. Maybe Kernel logs will show something?

It does make me wonder however if it is redundant how it was what solved it? Because after I deleted the config and accept_ra 2 from any of the modifications I did and only kept iface eth0 inet6 auto it worked flawlessly. Could it be that the Hostapd package turned of IPv6 in the kernel yet systemd-networkd turns it on, so to speak, ā€œoutsideā€ the kernel?

As for Tailscale, I don’t think it interferes, you can enable Tailscale DNS but it all works very much on the side of system functions afaik.

Do you think uninstalling the WiFi things and the HotSpot package should theoretically be able to make things act as normal again?

Read my whole message: We set accept_ra=2 automatically during hotspot install.

tcpdump can be used to check whether RAs do arrive, but we know that already. What wound be interesting to debug is what/why the system does with them, i.e. whether they are ignored or SLAAC attempted, and for what reason.

The inet6 auto entry is redundant in all other tenth of thousands of DietPi systems, so we need to find out what is different in your case. Probably systemd-networkd. Why are you using it? It is either redundant or conflicting with ifupdown and does not make use of /etc/network/interfaces. I wound disable it before continuing debugging.

I never realised they were different programs. But yes, then I should only be using ifupdown.

service networking status
networking.service - Raise network interfaces
     Loaded: loaded (/lib/systemd/system/networking.service; enabled; preset: enabled)
     Active: active (exited) since Sat 2023-07-22 17:24:25 CEST; 2h 29min ago
       Docs: man:interfaces(5)
   Main PID: 25841 (code=exited, status=1/FAILURE)
      Tasks: 0 (limit: 9352)
     Memory: 12.0K
        CPU: 631ms
     CGroup: /system.slice/networking.service
cat /lib/systemd/system/networking.service
[Unit]
Description=Raise network interfaces
Documentation=man:interfaces(5)
DefaultDependencies=no
Wants=network.target ifupdown-pre.service
After=local-fs.target network-pre.target apparmor.service systemd-sysctl.service systemd-modules-load.service ifupdown-pre.service
Before=network.target shutdown.target network-online.target
Conflicts=shutdown.target

[Install]
WantedBy=multi-user.target
WantedBy=network-online.target

[Service]
Type=oneshot
EnvironmentFile=-/etc/default/networking
ExecStart=/sbin/ifup -a --read-environment
ExecStart=-/bin/sh -c 'if [ -f /run/network/restart-hotplug ]; then /sbin/ifup -a --read-environment --allow=hotplug; fi'
ExecStop=/sbin/ifdown -a --read-environment --exclude=lo
ExecStopPost=/usr/bin/touch /run/network/restart-hotplug
RemainAfterExit=true
TimeoutStartSec=5min

According to this StackExchange thread there seems to have been a lot in terms of what has happened with the network stack. What else I could dig up is that servers or GUI:less installs don’t use NetworkManager either. Damn, networking in Debian seem to have gotten very difficult to wrap ones head around.

For now, I’ve uninstalled Hostapd through DietPi-Software and the WiFi stack through DietPi-Config.

Currently my configs in /etc/network/ look like this:

interfaces
# Location: /etc/network/interfaces
# Please modify network settings via: dietpi-config
# Or create your own drop-ins in: /etc/network/interfaces.d/

# Drop-in configs
source interfaces.d/*

# Ethernet
allow-hotplug eth0
iface eth0 inet static
address 192.168.1.4
netmask 255.255.255.0
gateway 192.168.1.1
#dns-nameservers 9.9.9.9 149.112.112.112

# WiFi
#allow-hotplug wlan0
iface wlan0 inet dhcp
address 192.168.0.101
netmask 255.255.255.0
#gateway 192.168.0.1
#dns-nameservers 192.168.1.1
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
if-down.d/resolved
#!/bin/sh
#
# Script fragment to make ifupdown supply DNS information to resolved
#

case "$ADDRFAM" in
    inet|inet6) : ;;
    *) exit 0 ;;
esac

if systemctl is-enabled systemd-resolved > /dev/null 2>&1; then
    interface=$IFACE
    if [ ! "$interface" ]; then
        return
    fi
    ifindex=$(cat "/sys/class/net/$interface/ifindex")
    if [ ! "$ifindex" ]; then
        return
    fi
    mystatedir=/run/network
    statedir=/run/systemd/resolve/netif
    rm -f "$mystatedir/isc-dhcp-v4-$interface" "$mystatedir/isc-dhcp-v6-$interface" "$mystatedir/ifupdown-inet-$interface" "$mystatedir/ifupdown-inet6-$interface" "$statedir/$ifindex"
    if systemctl --quiet is-active systemd-resolved; then
        resolvectl revert "$ifindex" || true
    fi
fi
if-pre-up.d/ethtool
#!/bin/sh

ETHTOOL=/sbin/ethtool

test -x $ETHTOOL || exit 0

[ "$IFACE" != "lo" ] || exit 0

# Gather together the mixed bag of settings applied with -s/--change
SETTINGS="\
${IF_ETHERNET_PORT:+ port $IF_ETHERNET_PORT}\
${IF_DRIVER_MESSAGE_LEVEL:+ msglvl $IF_DRIVER_MESSAGE_LEVEL}\
"
[ -z "$SETTINGS" ] || $ETHTOOL --change "$IFACE" $SETTINGS
if-up.d/ethtool
#!/bin/sh

ETHTOOL=/sbin/ethtool

test -x $ETHTOOL || exit 0

[ "$IFACE" != "lo" ] || exit 0

# Find settings with a given prefix and print them as they appeared in
# /etc/network/interfaces, only with the prefix removed.
# This actually prints each name and value on a separate line, but that
# doesn't matter to the shell.
gather_settings () {
    set | sed -n "
/^IF_$1[A-Za-z0-9_]*=/ {
    h;                             # hold line
    s/^IF_$1//; s/=.*//; s/_/-/g;  # get name without prefix
    y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/;  # lower-case
    p;
    g;                             # restore line
    s/^[^=]*=//; s/^'\(.*\)'/\1/;  # get value
    p;
}"
}

# Gather together the mixed bag of settings applied with -s/--change
SETTINGS="\
${IF_LINK_SPEED:+ speed $IF_LINK_SPEED}\
${IF_LINK_DUPLEX:+ duplex $IF_LINK_DUPLEX}\
"

# WOL has an optional pass-key
set -- $IF_ETHERNET_WOL
SETTINGS="$SETTINGS${1:+ wol $1}${2:+ sopass $2}"

# Autonegotiation can be on|off or an advertising mask
case "$IF_ETHERNET_AUTONEG" in
'')     ;;
on|off) SETTINGS="$SETTINGS autoneg $IF_ETHERNET_AUTONEG" ;;
*)      SETTINGS="$SETTINGS autoneg on advertise $IF_ETHERNET_AUTONEG" ;;
esac

[ -z "$SETTINGS" ] || $ETHTOOL --change "$IFACE" $SETTINGS

SETTINGS="$(gather_settings ETHERNET_PAUSE_)"
[ -z "$SETTINGS" ] || $ETHTOOL --pause "$IFACE" $SETTINGS

SETTINGS="$(gather_settings HARDWARE_IRQ_COALESCE_)"
[ -z "$SETTINGS" ] || $ETHTOOL --coalesce "$IFACE" $SETTINGS

SETTINGS="$(gather_settings HARDWARE_DMA_RING_)"
[ -z "$SETTINGS" ] || $ETHTOOL --set-ring "$IFACE" $SETTINGS

SETTINGS="$(gather_settings OFFLOAD_)"
[ -z "$SETTINGS" ] || $ETHTOOL --offload "$IFACE" $SETTINGS
if-up.d/resolved
#!/bin/sh
#
# Script fragment to make ifupdown supply DNS information to resolved
#

case "$ADDRFAM" in
    inet|inet6) : ;;
    *) exit 0 ;;
esac

if systemctl is-enabled systemd-resolved > /dev/null 2>&1; then
    interface=$IFACE
    if [ ! "$interface" ]; then
        return
    fi
    # TODO handle lo interface settings
    if [ "$interface" = "lo" ]; then
        return
    fi
    ifindex=$(cat "/sys/class/net/$interface/ifindex")
    if [ ! "$ifindex" ]; then
        return
    fi
    mystatedir=/run/network
    mkdir -p $mystatedir

    statedir=/run/systemd/resolve/netif
    mkdir -p $statedir
    chown systemd-resolve:systemd-resolve $statedir

    oldstate="$(mktemp)"
    # ignore errors due to nonexistent file
    md5sum "$mystatedir/isc-dhcp-v4-$interface" "$mystatedir/isc-dhcp-v6-$interface" "$mystatedir/ifupdown-inet-$interface" "$mystatedir/ifupdown-inet6-$interface" > "$oldstate" 2> /dev/null || true

    NEW_DEFAULT_ROUTE=$IF_DNS_DEFAULT_ROUTE
    NEW_DNS=$(echo $IF_DNS_NAMESERVERS $IF_DNS_NAMESERVER)
    NEW_DOMAINS=$(echo $IF_DNS_DOMAIN $IF_DNS_SEARCH)
    DNS=DNS
    DOMAINS=DOMAINS
    if [ "$ADDRFAM" = "inet6" ]; then
        DNS=DNS6
        DOMAINS=DOMAINS6
    fi
    if  [ -n "$NEW_DNS" ]; then
        cat <<EOF >"$mystatedir/ifupdown-${ADDRFAM}-$interface"
"$DNS"="$NEW_DNS"
EOF
        if  [ -n "$NEW_DOMAINS" ]; then
            cat <<EOF >>"$mystatedir/ifupdown-${ADDRFAM}-$interface"
"$DOMAINS"="$NEW_DOMAINS"
EOF
        fi
    fi
    case "$NEW_DEFAULT_ROUTE" in
        1|yes|true|on) NEW_DEFAULT_ROUTE=yes ;;
        0|no|false|off) NEW_DEFAULT_ROUTE=no ;;
        *) NEW_DEFAULT_ROUTE= ;;
    esac
    if [ -n "$NEW_DEFAULT_ROUTE" ]; then
        cat <<EOF >>"$mystatedir/ifupdown-${ADDRFAM}-$interface"
DEFAULT_ROUTE="$NEW_DEFAULT_ROUTE"
EOF
    fi

    newstate="$(mktemp)"
    # ignore errors due to nonexistent file
    md5sum "$mystatedir/isc-dhcp-v4-$interface" "$mystatedir/isc-dhcp-v6-$interface" "$mystatedir/ifupdown-inet-$interface" "$mystatedir/ifupdown-inet6-$interface" > "$newstate" 2> /dev/null || true
    if ! cmp --silent "$oldstate" "$newstate" 2>/dev/null; then
        DNS DNS6 DOMAINS DOMAINS6 DEFAULT_ROUTE
        # v4 first
        if [ -e "$mystatedir/isc-dhcp-v4-$interface" ]; then
            . "$mystatedir/isc-dhcp-v4-$interface"
        fi
        # v4 manual config overrides
        if [ -e "$mystatedir/ifupdown-inet-$interface" ]; then
            . "$mystatedir/ifupdown-inet-$interface"
        fi
        # v6 preffered
        if [ -e "$mystatedir/isc-dhcp-v6-$interface" ]; then
            . "$mystatedir/isc-dhcp-v6-$interface"
        fi
        # v6 manual config overrides
        if [ -e "$mystatedir/ifupdown-inet6-$interface" ]; then
            . "$mystatedir/ifupdown-inet6-$interface"
        fi
        resolvectl_failed=
        if [ "$DNS" ] || [ "$DNS6" ] ; then
            cat <<EOF >"$statedir/$ifindex"
# This is private data. Do not parse.
LLMNR=yes
MDNS=no
SERVERS=$(echo $DNS6 $DNS)
DOMAINS=$(echo $DOMAINS6 $DOMAINS)
EOF
            if [ -n "$DEFAULT_ROUTE" ]; then
                cat <<EOF >>"$statedir/$ifindex"
DEFAULT_ROUTE=$DEFAULT_ROUTE
EOF
            fi
            chown systemd-resolve:systemd-resolve "$statedir/$ifindex"
            # In addition to creating the state file (needed if we run before
            # resolved is started), also feed the information directly to
            # resolved.
            if systemctl --quiet is-active systemd-resolved; then
                resolvectl llmnr "$ifindex" yes || resolvectl_failed=$?
                resolvectl mdns "$ifindex" no || resolvectl_failed=$?
                if [ "$DOMAINS6" ] || [ "$DOMAINS" ]; then
                    resolvectl domain "$ifindex" $DOMAINS6 $DOMAINS || resolvectl_failed=$?
                else
                    resolvectl domain "$ifindex" "" || resolvectl_failed=$?
                fi
                resolvectl dns "$ifindex" $DNS6 $DNS || resolvectl_failed=$?
                if [ "$DEFAULT_ROUTE" ]; then
                    resolvectl default-route "$ifindex" $DEFAULT_ROUTE || resolvectl_failed=$?
                fi
            fi
        else
            rm -f "$statedir/$ifindex"
            if systemctl --quiet is-active systemd-resolved; then
                resolvectl revert "$ifindex" || resolvectl_failed=$?
            fi
        fi

        # resolved was running, but without dbus, it means state files
        # will not be read & resolvectl commands failed, restart it
        if [ "$resolvectl_failed" ]; then
                systemctl try-restart systemd-resolved
        fi
    fi
    rm -f "$oldstate" "$newstate"
fi

Now after a reboot, this is my current IP info:

ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether e4:5f:01:0c:8b:b5 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.4/24 brd 192.168.1.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::e65f:1ff:fe0c:8bb5/64 scope link
       valid_lft forever preferred_lft forever
3: tailscale0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1280 qdisc pfifo_fast state UNKNOWN group default qlen 500
    link/none
    inet 100.87.207.113/32 scope global tailscale0
       valid_lft forever preferred_lft forever
    inet6 fd7a:115c:a1e0:ab12:4843:cd96:6257:cf71/128 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::359c:31c2:e2c7:c305/64 scope link stable-privacy
       valid_lft forever preferred_lft forever
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:72:14:f7:c5 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:72ff:fe14:f7c5/64 scope link
       valid_lft forever preferred_lft forever
5: br-7ae53c7f8e4e: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:5b:85:a8:51 brd ff:ff:ff:ff:ff:ff
    inet 172.19.0.1/16 brd 172.19.255.255 scope global br-7ae53c7f8e4e
       valid_lft forever preferred_lft forever
    inet6 fe80::42:5bff:fe85:a851/64 scope link
       valid_lft forever preferred_lft forever
6: br-e64e81805d59: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:cc:05:07:3e brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.1/16 brd 172.18.255.255 scope global br-e64e81805d59
       valid_lft forever preferred_lft forever
    inet6 fe80::42:ccff:fe05:73e/64 scope link
       valid_lft forever preferred_lft forever
8: veth95c1985@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-e64e81805d59 state UP group default
    link/ether 4a:92:73:76:a7:2e brd ff:ff:ff:ff:ff:ff link-netnsid 1
    inet6 fe80::4892:73ff:fe76:a72e/64 scope link
       valid_lft forever preferred_lft forever
10: vethbfe65ed@if9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
    link/ether 7a:e4:9c:d7:52:a5 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::78e4:9cff:fed7:52a5/64 scope link
       valid_lft forever preferred_lft forever
12: veth493b221@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-7ae53c7f8e4e state UP group default
    link/ether 2a:9e:5c:52:39:b1 brd ff:ff:ff:ff:ff:ff link-netnsid 2
    inet6 fe80::289e:5cff:fe52:39b1/64 scope link
       valid_lft forever preferred_lft forever
14: veth8424e47@if13: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-e64e81805d59 state UP group default
    link/ether 9e:22:57:79:b3:93 brd ff:ff:ff:ff:ff:ff link-netnsid 5
    inet6 fe80::9c22:57ff:fe79:b393/64 scope link
       valid_lft forever preferred_lft forever
18: veth2c0ebb9@if17: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-e64e81805d59 state UP group default
    link/ether 62:ca:54:10:c0:7f brd ff:ff:ff:ff:ff:ff link-netnsid 4
    inet6 fe80::60ca:54ff:fe10:c07f/64 scope link
       valid_lft forever preferred_lft forever
22: veth0d777c0@if21: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-e64e81805d59 state UP group default
    link/ether 36:b3:f0:5e:55:ba brd ff:ff:ff:ff:ff:ff link-netnsid 3
    inet6 fe80::34b3:f0ff:fe5e:55ba/64 scope link
       valid_lft forever preferred_lft forever

Edit: I tried to uninstall Tailscale too to no avail, same results.

Alright so I went to watch a movie and decided to go back to this afterwards. Didn’t change anything in the config from after I uninstalled hostapd, tailscale and the WiFi stack but now I’m getting IPv6 somehow…

ip addr show eth0

2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether e4:5f:01:0c:8b:b5 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.4/24 brd 192.168.1.255 scope global dynamic eth0
       valid_lft 42877sec preferred_lft 42877sec
    inet6 fd8d:9c44:d6fc:e31b:e65f:1ff:fe0c:8bb5/64 scope global dynamic mngtmpaddr
       valid_lft 1677sec preferred_lft 1677sec
    inet6 2a02:920:41c7:4200:e65f:1ff:fe0c:8bb5/64 scope global dynamic mngtmpaddr
       valid_lft forever preferred_lft forever
    inet6 fe80::e65f:1ff:fe0c:8bb5/64 scope link
       valid_lft forever preferred_lft forever

I see now that instead of using the interfaces to configure it I have mngtmpaddr by the end of the inet6 line. I tried Googling what that is but didn’t find much found some documentation (Wouldn’t this make it a bit of a non–permanent address unlike EUI64?), gonna dig a bit more. For now I’m gonna try and install the programs one by one and restart and see what changes, but I’ll have to get to that tomorrow.

I never had issues with SLAAC, only in some cases I had to add iface eth0 inet6 dhcp in /etc/network/interfaces.d/ipv6.conf to make DHCP6 work.

Yes, ifupdown + isc-dhcp-client is the Debian default network stack/tool. systemd-networkd is the default on Ubuntu, with own config files and embedded simple DHCP client. Debian was discussing whether to switch or not, but did not find a reason to do so, and I do not see one either. NetworkManager is another high level network tool, which brings again its own config files. It adds some features and desktop wrappers used by some desktop panel plugins for WiFi setup, so indeed often found on desktop systems. All of them are capable of more or less complex network setups, and hence naturally they can conflict.

So far so good.

Makes sense, in case DHCPv6 is required for some reason. We could indeed add it as option/alternative to SLAAC, but I do not remember anyone really requiring/requesting it. What was your use case?

Static IP for server. I know it is also possible with SLAAC, but it is preferred to have a GUA or ULA in the form of fddd::2 than the EUI64.

1 Like

Just for my understanding:

  • As far as I understand EUI64, the IPv6 address is derived from the MAC address. I know this from the LLA, but in my case(s) the GUA obtained via SLAAC does not contain the MAC address in any way.
  • As you say GUA and ULA: A GUA is obtained via SLAAC, an ULA only if explicitly enabled in router (usually not recommended or required). I am not sure whether the ULA is formally part of SLAAC, but it is obtained with the exact same RA which also provides the GUA AFAIR.
  • Despite this, you mean the GUA obtained via SLAAC has a different format then the one which can be obtained via DHCPv6?
  • The prefix is fixed anyway, and static or dynamic depending on internet provider only. So the only difference could be after the prefix. Of course via DHCPv6 you can freely choose the address range (after prefix), while I never saw an option to change this for SLAAC. But what is the benefit of using a specific address range?

Let me show you an example from my dietpi:

2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
    inet6 2aaa:aaaa:273:7500:ba27:ebff:febb:8a0e/64 scope global dynamic mngtmpaddr 
       valid_lft 285sec preferred_lft 255sec
    inet6 fd00:bbbb::ba27:ebff:febb:8a0e/64 scope global dynamic mngtmpaddr 
       valid_lft 43189sec preferred_lft 43189sec
    inet6 fd00:bbbb::3/128 scope global dynamic 
       valid_lft 86375sec preferred_lft 105sec
    inet6 2aaa:aaaa:273:7500::3/128 scope global dynamic 
       valid_lft 135sec preferred_lft 105sec
    inet6 fe80::ba27:ebff:febb:8a0e/64 scope link 
       valid_lft forever preferred_lft forever

First is GUA from SLAAC, second is ULA from SLAAC, third is ULA from DHCP, and fourth is GUA from DHCP. Finally the LLA.
Both ULA and GUA can derive from the MAC and the network prefix. This is advertised by the RAs. The RAs can also inform if there is DHCP6 available to get their addresses or other configuration.
The prefix is fixed, either the ISP delegated prefix or the ULA prefix. What can be controlled is the suffix, and can be configured by DHCP6, otherwise the device will create EUI64 or pseudorandom in SLAAC.

1 Like

My SLAAC addresses are definitely EUI64 based, there’s web-tools available to take the IPv6 address and convert it back to a MAC address, feels a bit sketch sometimes and adds to the network fingerprint too sadly.

I’m having an issue where my OpenWRT setup gives out a ULA even with ULA disabled, not sure how to fix lol but it’s also EUI64 based on my devices. But the ULA can also be obtained from SLAAC I think.

Static could be nice in case the setup changes, a config could always change somewhat, I know there’s some way to get a ā€œmore randomā€ IPv6 in a more dynamic way but not sure what the options to change these are and I’m unsure if that’s the case for DietPis sysctl options that are used. You can also make it more fun by using hex numbers that looks like words which will also be more memorisable than a normal IPv6 address.

Either another OpenWrt advertising ULA (seen that in an OpenWrt forum topic) or settings not applied.

Are you sure that this is true for the GUA, i.e. in your case for 2a02:920:41c7:4200:e65f:1ff:fe0c:8bb5/64? For the LLA fe80:* it is normal, but that one is not public and can only be used between directly linked hosts. I also do not find any tool to convert a GUA into a MAC or the other way round.

This was true for my internet provider’s router, when I enabled ULA to test something and disabled it again. A router restart solved it.

This is not in your control for the GUA prefix (the first part of the full global IPv6 address). I just checked, and for the ULA I can define a ā€œsubnet IDā€, whatever this is, probably related to the address range? If you explicitly use IPv6 addresses to communicate within your LAN, than having it static is of course nice. I however do no know any reason why one would use IPv6 addresses instead of the much shorter and simpler IPv4 for this, unless you really have huge LAN which exceeds the number of available IPv4 addresses in one subnet.

The strangest thing about is definitely that the address that it gives exists in none of the UCI configs at all. Doing uci show and looking for prefixes nothing shows up. It’s always with the fd8d:9c44:d6fc:e31b:: prefix too. Super strange. But doesn’t get in the way too much, just a bit of an annoyance.

Currently however I’m trying to install the hotspot again but DietPi-Config doesn’t seem to want to discover wlan0 on my Pi.

WLAN Interface needs to be activated first followed by a reboot to enable it

1 Like

For me it’s mostly that it feels cooler lol. But I do mostly use IPv4 for my local connections except for when I connect through domains on my browser. I do want to switch over to mostly domains on my LAN through the AdGuard Home install and pretty much only use IPv6.

I still haven’t really thought about if I want to use custom/random static address or the EUI64, somehow the EUI64 seems like a nice-have but at the same time I don’t want to add to my fingerprinting. I wish there was a way to tell the DHCP server to generate a random address for each device, AdGuard users Bind and OpenWRT uses dnsmasq so might be able to look into that.

This website works for me and since my global link from SLAAC is the same but with a longer prefix it shows the full MAC as well if I just make it a local address instead.

I think something is just wrong with my OpenWRT config, going to start a thread on the OpenWRT forums later about it. Too off-topic here.

IPv6 Subnet I think is just an IPv4 Subnet but for IPv6 addresses from what I understand of it so while you can set longer prefix there and have another subnet and add routing to it you can also change the DHCPv6 prefix by adding to it, for example, be55:db35:c602:5ab9::/56 suffix for the dedicated range to your local network you can do the delegation address of be55:db35:c602:5ab9:dead:beef::/64.

1 Like