Index | Thread | Search

From:
Bjorn Ketelaars <bket@openbsd.org>
Subject:
Fwd: Re: PPPoE assigns link local fe80::200:0:0:1 instead of fe80::1
To:
tech@openbsd.org
Cc:
stsp@openbsd.org
Date:
Mon, 20 Jul 2026 21:26:01 +0200

Download raw body.

Thread
----- Forwarded message from Martin Crossley <admin@crossleys.biz> -----

> From: Martin Crossley <admin@crossleys.biz>
> To: Bjorn Ketelaars <bket@openbsd.org>
> Cc: misc@openbsd.org
> Date: Sat, 18 Jul 2026 18:28:41 +0100
> Subject: Re: PPPoE assigns link local fe80::200:0:0:1 instead of fe80::1
> 
> > On 18 Jul 2026, at 15:21, Bjorn Ketelaars <bket@openbsd.org> wrote:
> > 
> > On Sat 18/07/2026 11:44, Martin Crossley wrote:
> >> Clean build of OpenBSD 7.9 generic.mp#449 amd64.
> >> 
> >> During PPPoE negotiation the peer gives us fe80::1 and we accept it.
> >> So why does pppoe set our link local address to fe80::200:0:0:1 ?
> >> 
> >> fe80::200:0:0:1 looks like the EUI64 conversion for a MAC address of
> >> 00:00:00:00:00:01, so could it be that the offered IFID is being
> >> Interpreted as a MAC?
> >> 
> >> (1) hostname.pppoe0 (NB: same result if we explicitly set inet6 fe80::1)
> >> 
> >> inet 0.0.0.0 255.255.255.255 NONE \
> >>    pppoedev bge0 authproto chap \
> >>    authname ‘xxxxx' authkey ‘xxxxx’ up
> >> dest 0.0.0.1
> >> inet6 eui64
> >> !/sbin/route add default -ifp pppoe0 0.0.0.1
> >> !/sbin/route add -inet6 default -ifp pppoe0 fe80::%pppoe0
> >> 
> >> (2) Ifconfig pppoe0 after negotiation
> >> 
> >> pppoe0: flags=8855<UP,DEBUG,POINTOPOINT,RUNNING,SIMPLEX,MULTICAST> mtu 1492
> >> index 5 priority 0 llprio 3
> >> dev: bge0 state: session
> >> sid: 0xca5 PADI retries: 0 PADR retries: 0 time: 00:04:27
> >> sppp: phase network authproto chap authname “xxxxx" 
> >> dns: 212.23.3.100 212.23.6.100
> >> groups: pppoe egress
> >> status: active
> >> inet6 fe80::200:0:0:1%pppoe0 -->  prefixlen 64 scopeid 0x5
> >> inet 217.155.184.174 --> 51.148.77.132 netmask 0xffffffff
> >> 
> >> 
> >> (3) Packet capture on the ethernet (our mac address is 00:9c:02:ab:d9:44)
> >> 
> >> 21:17:19.111881 00:9c:02:ab:d9:44 80:7f:f8:74:01:4b 8864 36: PPPoE-Session
> >>        code Session, version 1, type 1, id 0x07e4, length 16
> >>        IPV6CP Configure-Request Id=0x03: IPv6-Interface-Id=029c:02ff:feab:d944
> >> 21:17:19.117305 80:7f:f8:74:01:4b 00:9c:02:ab:d9:44 8864 60: PPPoE-Session
> >>        code Session, version 1, type 1, id 0x07e4, length 12
> >>        IPCP Configure-Request Id=0x30: IP-Address=51.148.77.133
> >> 21:17:19.117307 80:7f:f8:74:01:4b 00:9c:02:ab:d9:44 8864 60: PPPoE-Session
> >>        code Session, version 1, type 1, id 0x07e4, length 24
> >>        IPCP Configure-Nak Id=0x02: IP-Address=217.155.184.174 Primary-DNS-Server=212.23.3.100 Secondary-DNS-Server=212.23.6.100
> >> 21:17:19.117308 80:7f:f8:74:01:4b 00:9c:02:ab:d9:44 8864 60: PPPoE-Session
> >>        code Session, version 1, type 1, id 0x07e4, length 16
> >>        IPV6CP Configure-Request Id=0x62: IPv6-Interface-Id=827f:f8ff:fe74:014b
> >> 21:17:19.117779 00:9c:02:ab:d9:44 80:7f:f8:74:01:4b 8864 32: PPPoE-Session
> >>        code Session, version 1, type 1, id 0x07e4, length 12
> >>        IPCP Configure-Ack Id=0x30: IP-Address=51.148.77.133
> >> 21:17:19.117780 00:9c:02:ab:d9:44 80:7f:f8:74:01:4b 8864 44: PPPoE-Session
> >>        code Session, version 1, type 1, id 0x07e4, length 24
> >>        IPCP Configure-Request Id=0x04: IP-Address=217.155.184.174 Primary-DNS-Server=212.23.3.100 Secondary-DNS-Server=212.23.6.100
> >> 21:17:19.117781 00:9c:02:ab:d9:44 80:7f:f8:74:01:4b 8864 36: PPPoE-Session
> >>        code Session, version 1, type 1, id 0x07e4, length 16
> >>        IPV6CP Configure-Ack Id=0x62: IPv6-Interface-Id=827f:f8ff:fe74:014b
> >> 21:17:19.117895 80:7f:f8:74:01:4b 00:9c:02:ab:d9:44 8864 60: PPPoE-Session
> >>        code Session, version 1, type 1, id 0x07e4, length 16
> >>        IPV6CP Configure-Nak Id=0x03: IPv6-Interface-Id=0000:0000:0000:0001
> >> 21:17:19.118149 00:9c:02:ab:d9:44 80:7f:f8:74:01:4b 8864 36: PPPoE-Session
> >>        code Session, version 1, type 1, id 0x07e4, length 16
> >>        IPV6CP Configure-Request Id=0x05: IPv6-Interface-Id=0000:0000:0000:0001
> >> 21:17:19.118595 00:9c:02:ab:d9:44 80:7f:f8:74:01:4b 8864 94: PPPoE-Session
> >>        code Session, version 1, type 1, id 0x07e4, length 74
> >>        IPv6 fe80::29c:2ff:feab:d944 > ff02::2: HBH icmp6: multicast listener done max resp delay: 0 addr: ff02::2 [hlim 1]
> >> 21:17:19.118597 00:9c:02:ab:d9:44 80:7f:f8:74:01:4b 8864 94: PPPoE-Session
> >>        code Session, version 1, type 1, id 0x07e4, length 74
> >>        IPv6 fe80::200:0:0:1 > ff02::1:ff00:1: HBH icmp6: multicast listener report max resp delay: 0 addr: ff02::1:ff00:1 [hlim 1]
> >> 21:17:19.226019 80:7f:f8:74:01:4b 00:9c:02:ab:d9:44 8864 60: PPPoE-Session
> >>        code Session, version 1, type 1, id 0x07e4, length 24
> >>        IPCP Configure-Ack Id=0x04: IP-Address=217.155.184.174 Primary-DNS-Server=212.23.3.100 Secondary-DNS-Server=212.23.6.100
> >> 21:17:19.226621 80:7f:f8:74:01:4b 00:9c:02:ab:d9:44 8864 60: PPPoE-Session
> >>        code Session, version 1, type 1, id 0x07e4, length 16
> >>        IPV6CP Configure-Ack Id=0x05: IPv6-Interface-Id=0000:0000:0000:0001
> >> 21:17:19.402414 80:7f:f8:74:01:4b 00:9c:02:ab:d9:44 8864 110: PPPoE-Session
> >>        code Session, version 1, type 1, id 0x07e4, length 90
> >>        IPv6 fe80::827f:f8ff:fe74:14b > ff02::1: icmp6: router advertisement [class 0xc0]
> >> 
> > 
> > I think your diagnosis is correct. The peer NAKs your initial interface
> > ID and suggests 0000:0000:0000:0001. The sppp state machine accepts it
> > and schedules installation of fe80::1. The problem is in
> > in6_ifattach_linklocal(), which then unconditionally applies an EUI-64
> > U/L bit transformation to the provided interface ID:
> > 
> > ifra.ifra_addr.sin6_addr.s6_addr[8] &= ~EUI64_GBIT;
> > ifra.ifra_addr.sin6_addr.s6_addr[8] |=  EUI64_UBIT; /* 0x00 → 0x02 */
> > 
> > That turns fe80::1 into fe80::200:0:0:1. This transformation is
> > appropriate when deriving an interface ID from a MAC address, but RFC
> > 5072 requires PPP-negotiated interface IDs to be used verbatim — they
> > carry no EUI-64 semantics.
> > 
> > The fix is to remove those two lines, see diff below.
> > 
> > There are three call sites for in6_ifattach_linklocal(). Only
> > sys/net/if_spppsubr.c reaches this branch. The other two — in
> > sys/netinet/ip_carp.c and sys/netinet6/in6_ifattach.c itself — both pass
> > NULL as the ifid argument and never reach this branch, so there is no
> > impact on any other interface type.
> > 
> > The lines were introduced by r1.66 of sys/netinet6/in6_ifattach.c
> > (stsp@, January 2014), which added the ifid parameter to allow sppp to
> > install peer-suggested interface IDs — a correct change overall. The
> > EUI-64 bit manipulation was apparently carried over by analogy with the
> > MAC-to-EUI-64 code nearby, but does not belong in the PPP context.
> > 
> > Could you test this against your setup?
> > 
> > 
> > diff --git sys/netinet6/in6_ifattach.c sys/netinet6/in6_ifattach.c
> > index 975ccbf5056..c8c7033c058 100644
> > --- sys/netinet6/in6_ifattach.c
> > +++ sys/netinet6/in6_ifattach.c
> > @@ -244,8 +244,6 @@ in6_ifattach_linklocal(struct ifnet *ifp, struct in6_addr *ifid)
> > 		ifra.ifra_addr.sin6_addr.s6_addr16[0] = htons(0xfe80);
> > 		ifra.ifra_addr.sin6_addr.s6_addr16[1] = htons(ifp->if_index);
> > 		ifra.ifra_addr.sin6_addr.s6_addr32[1] = 0;
> > -		ifra.ifra_addr.sin6_addr.s6_addr[8] &= ~EUI64_GBIT;
> > -		ifra.ifra_addr.sin6_addr.s6_addr[8] |= EUI64_UBIT;
> > 	} else
> > 		in6_get_ifid(ifp, &ifra.ifra_addr.sin6_addr);
> > 
> 
> Happy to confirm that works for me - many thanks for the very quick response
> 
> (1) hostname.pppoe0 (same as before)
> 
> inet 0.0.0.0 255.255.255.255 NONE \
>    pppoedev bge0 authproto chap \
>    authname ‘xxxxx' authkey ‘xxxxx’ up
> dest 0.0.0.1
> inet6 eui64
> !/sbin/route add default -ifp pppoe0 0.0.0.1
> !/sbin/route add -inet6 default -ifp pppoe0 fe80::%pppoe0
> 
> (2) ifconfig pppoe0 after negotiation
> 
> pppoe0: flags=8855<UP,DEBUG,POINTOPOINT,RUNNING,SIMPLEX,MULTICAST> mtu 1492
> 	index 5 priority 0 llprio 3
> 	dev: bge0 state: session
> 	sid: 0x6bd PADI retries: 0 PADR retries: 0 time: 00:01:04
> 	sppp: phase network authproto chap authname "zen103022@zen" 
> 	dns: 212.23.3.100 212.23.6.100
> 	groups: pppoe egress
> 	status: active
> 	inet6 fe80::1%pppoe0 -->  prefixlen 64 scopeid 0x5
> 	inet 217.155.184.174 --> 51.148.77.133 netmask 0xffffffff
> 
> (3) packet capture on the ethernet (our mac address is 00:9c:02:ab:d9:44)
> 
> 18:01:09.142927 00:9c:02:ab:d9:44 80:7f:f8:74:01:3b 8864 44: PPPoE-Session
>         code Session, version 1, type 1, id 0x06bd, length 24
>         IPCP Configure-Request Id=0x02: IP-Address=0.0.0.0 Primary-DNS-Server=0.0.0.0 Secondary-DNS-Server=0.0.0.0
> 18:01:09.142928 00:9c:02:ab:d9:44 80:7f:f8:74:01:3b 8864 36: PPPoE-Session
>         code Session, version 1, type 1, id 0x06bd, length 16
>         IPV6CP Configure-Request Id=0x03: IPv6-Interface-Id=029c:02ff:feab:d944
> 18:01:09.148350 80:7f:f8:74:01:3b 00:9c:02:ab:d9:44 8864 60: PPPoE-Session
>         code Session, version 1, type 1, id 0x06bd, length 12
>         IPCP Configure-Request Id=0xe9: IP-Address=51.148.77.133
> 18:01:09.148352 80:7f:f8:74:01:3b 00:9c:02:ab:d9:44 8864 60: PPPoE-Session
>         code Session, version 1, type 1, id 0x06bd, length 24
>         IPCP Configure-Nak Id=0x02: IP-Address=217.155.184.174 Primary-DNS-Server=212.23.3.100 Secondary-DNS-Server=212.23.6.100
> 18:01:09.148353 80:7f:f8:74:01:3b 00:9c:02:ab:d9:44 8864 60: PPPoE-Session
>         code Session, version 1, type 1, id 0x06bd, length 16
>         IPV6CP Configure-Request Id=0x2a: IPv6-Interface-Id=827f:f8ff:fe74:013b
> 18:01:09.158496 80:7f:f8:74:01:3b 00:9c:02:ab:d9:44 8864 60: PPPoE-Session
>         code Session, version 1, type 1, id 0x06bd, length 16
>         IPV6CP Configure-Nak Id=0x03: IPv6-Interface-Id=0000:0000:0000:0001
> 18:01:09.177925 00:9c:02:ab:d9:44 80:7f:f8:74:01:3b 8864 32: PPPoE-Session
>         code Session, version 1, type 1, id 0x06bd, length 12
>         IPCP Configure-Ack Id=0xe9: IP-Address=51.148.77.133
> 18:01:09.177927 00:9c:02:ab:d9:44 80:7f:f8:74:01:3b 8864 44: PPPoE-Session
>         code Session, version 1, type 1, id 0x06bd, length 24
>         IPCP Configure-Request Id=0x04: IP-Address=217.155.184.174 Primary-DNS-Server=212.23.3.100 Secondary-DNS-Server=212.23.6.100
> 18:01:09.177928 00:9c:02:ab:d9:44 80:7f:f8:74:01:3b 8864 36: PPPoE-Session
>         code Session, version 1, type 1, id 0x06bd, length 16
>         IPV6CP Configure-Ack Id=0x2a: IPv6-Interface-Id=827f:f8ff:fe74:013b
> 18:01:09.187336 00:9c:02:ab:d9:44 80:7f:f8:74:01:3b 8864 36: PPPoE-Session
>         code Session, version 1, type 1, id 0x06bd, length 16
>         IPV6CP Configure-Request Id=0x05: IPv6-Interface-Id=0000:0000:0000:0001
> 18:01:09.205733 00:9c:02:ab:d9:44 80:7f:f8:74:01:3b 8864 94: PPPoE-Session
>         code Session, version 1, type 1, id 0x06bd, length 74
>         IPv6 fe80::29c:2ff:feab:d944 > ff02::2: HBH icmp6: multicast listener done max resp delay: 0 addr: ff02::2 [hlim 1]
> 18:01:09.205735 00:9c:02:ab:d9:44 80:7f:f8:74:01:3b 8864 94: PPPoE-Session
>         code Session, version 1, type 1, id 0x06bd, length 74
>         IPv6 fe80::1 > ff02::1:ff00:1: HBH icmp6: multicast listener report max resp delay: 0 addr: ff02::1:ff00:1 [hlim 1]
> 18:01:09.239512 80:7f:f8:74:01:3b 00:9c:02:ab:d9:44 8864 60: PPPoE-Session
>         code Session, version 1, type 1, id 0x06bd, length 24
>         IPCP Configure-Ack Id=0x04: IP-Address=217.155.184.174 Primary-DNS-Server=212.23.3.100 Secondary-DNS-Server=212.23.6.100
> 18:01:09.239515 80:7f:f8:74:01:3b 00:9c:02:ab:d9:44 8864 60: PPPoE-Session
>         code Session, version 1, type 1, id 0x06bd, length 16
>         IPV6CP Configure-Ack Id=0x05: IPv6-Interface-Id=0000:0000:0000:0001
> 18:01:09.426405 80:7f:f8:74:01:3b 00:9c:02:ab:d9:44 8864 110: PPPoE-Session
>         code Session, version 1, type 1, id 0x06bd, length 90
>         IPv6 fe80::827f:f8ff:fe74:13b > ff02::1: icmp6: router advertisement [class 0xc0]

----- End forwarded message -----

Bringing this from misc@ to tech@ as I'm looking for comments/OK.


netinet6: keep negotiated IPv6CP IFID unchanged for link-local address

When sppp/PPPoE installs a peer-suggested IPv6CP interface identifier,
in6_ifattach_linklocal() forced EUI64 G/U bit adjustments on the
provided IFID. This incorrectly rewrote a valid negotiated IFID such as
::1 into ::200:0:0:1, yielding fe80::200:0:0:1 instead of fe80::1.

Do not apply EUI64 bit mangling when an explicit IFID is supplied; use
the negotiated value as-is (RFC 5072). Other callers are unaffected
since they pass NULL and continue using in6_get_ifid().

Reported and tested by Martin Crossley <admin AT crossleys DOT biz>.
Tested by me on a connection that allows an explicit IFID.


diff --git sys/netinet6/in6_ifattach.c sys/netinet6/in6_ifattach.c
index 975ccbf5056..c8c7033c058 100644
--- sys/netinet6/in6_ifattach.c
+++ sys/netinet6/in6_ifattach.c
@@ -244,8 +244,6 @@ in6_ifattach_linklocal(struct ifnet *ifp, struct in6_addr *ifid)
 		ifra.ifra_addr.sin6_addr.s6_addr16[0] = htons(0xfe80);
 		ifra.ifra_addr.sin6_addr.s6_addr16[1] = htons(ifp->if_index);
 		ifra.ifra_addr.sin6_addr.s6_addr32[1] = 0;
-		ifra.ifra_addr.sin6_addr.s6_addr[8] &= ~EUI64_GBIT;
-		ifra.ifra_addr.sin6_addr.s6_addr[8] |= EUI64_UBIT;
 	} else
 		in6_get_ifid(ifp, &ifra.ifra_addr.sin6_addr);