Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
CenturyLink PPPoE and 6rd on an OpenBSD router

Replacing the CenturyLink provided ethernet router with OpenBSD

Unfortunately CenturyLink provisions their fiber to the home with a PPPoE authentication over vlan 201, this makes replacing the router more difficult than it should be. I also had to call CenturyLink support to get the password for the PPPoE connection.

cnmac0 is the egress interface on my EdgeRouter Lite.

You also need to add match on pppoe0 scrub (max-mss 1440) to your pf.conf because otherwise many things don't work. (Thanks Bryan)

If you're doing ipsec over this link, you also need to scrub the enc0 max-mss to 64 smaller than the max-mss on the pppoe interface. match on enc0 scrub (max-mss 1376).

Overall it ends up being fairly forward, the PPPoE config is copied directly from the man page with the minor change that CenturyLink uses chap instead of pap.

The IPv6 setup was based on these resources from some searches

# Put this in root's crontab with -s:
# * * * * * -ns /usr/local/sbin/
# CenturyLink
while [ -z "$v4ip" -o "$v4ip" = "" ]; do
v4ip=$( ifconfig pppoe0 |
sed -ne 's/[[:space:]]*inet[[:space:]]\([^[:space:]]*\).*/\1/p' )
sleep 1
if [ "$v4ip" = "" ]; then
echo "No IP on pppoe0" >&2
exit 1
v6ip=$( ifconfig $if |
sed -ne "s/[[:space:]]*inet6[[:space:]]\($rdprefix[^[:space:]]*\).*prefixlen[[:space:]]*\([[:digit:]]*\)/\1\/\2/p" )
v6prefix=$( printf ${v6format} $( echo $v4ip | tr '.' ' ' ) )
v6dest=$( printf ${v6format}00::1 $( echo $v4dest | tr '.' ' ' ) )
# The prefix I get to use is the rdmask + the 32 bits of the v4 address
v6internal=${v6prefix}7f::1/$(( rdmask + 32 + 1 ))
v6guest=${v6prefix}ff::1/$(( rdmask + 32 + 1 ))
# We're already configured, don't try again
[ "$v6ip" = "$v6external" ] && exit
# add "include: /var/unbound/etc/6rd.conf" to the end of unbound.conf
cat <<EOL >/var/unbound/etc/6rd.conf
interface: ${v6internal%/*}
access-control: $v6internal allow
interface: ${v6guest%/*}
access-control: $v6guest allow
# I have this already configured, you might have to uncomment
# local-zone: "$search_domain." static
local-data: "$( hostname ). IN AAAA ${v6external%/*}"
local-data: "ns1.$search_domain. IN AAAA ${v6internal%/*}"
local-data: "ns2.$search_domain. IN AAAA ${v6guest%/*}"
cat <<EOL >/etc/rad.conf
mtu $mtu
dns { search $search_domain }
interface $internalif { dns { nameserver ${v6internal%/*} } }
interface $guestif { dns { nameserver ${v6guest%/*} } }
ifconfig $if mtu $mtu
ifconfig $if tunnel $v4ip $v4dest
# reset any old v6 addresses
/sbin/route -qn delete -inet6 default
ifconfig $if -inet6
ifconfig $internalif -inet6
ifconfig $guestif -inet6
set -x # because I want to know the new IPs
# and add them back in
ifconfig $guestif inet6 $v6guest
ifconfig $internalif inet6 $v6internal
ifconfig $if inet6 $v6external
/sbin/route -qn add -inet6 default $v6dest
#rcctl start rad
rcctl reload rad unbound
inet NONE \
pppoedev vlan201 authproto chap \
authname '' authkey 'mypassword' up
!/sbin/route add default -ifp \$if
vnetid 201 parent cnmac0

This comment has been minimized.

Copy link

@dgwynne dgwynne commented Jul 13, 2017

hostname.vlan201 should read:

vnetid 201 parent cnmac0

EDIT (Andrew): I fixed it, was using the olde timey vlandev cnmac0


This comment has been minimized.

Copy link

@garnoth garnoth commented Feb 12, 2021

I'm looking to adapt this to my setup. What's with publicif=vlan41 ? shouldn't the public side be on vlan201 which is connected to cnmac0 in your situation? Or is this something specific to your setup?


This comment has been minimized.

Copy link
Owner Author

@afresh1 afresh1 commented Feb 12, 2021

@garnoth: I should improve that. By "public" I mean "guest network for the public to use" as opposed to the "internal network for me to use". It's specifically the open SSID on my wifi network that visitors use.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment