Re: Prefix delegation for /60
Neal P. Murphy
Tue Sep 05 18:36:34 2017
On Tue, 5 Sep 2017 21:09:15 +1000
Scott Leggett <scott@xxxxxxxx> wrote:
> Hi,
>
> My ISP provides a /60 and I'm having trouble delegating it correctly to
> the other interfaces on my router using dhcpcd.
>
> This is on current master/HEAD (dhcpcd-7.0.0-rc1-55-g5da607b5).
>
> /etc/dhcpcd.conf:
>
> noipv6rs
> allowinterfaces enp1s0
> interface enp1s0
> ipv6rs
> ia_pd 1 enp2s0/1 wlxc412f52e39d2/2 wlxc412f52ebb7b/3 enp3s0/4
>
> log snippet:
>
> systemd[1]: Started DHCP Client Daemon.
> dhcpcd[248]: enp1s0: soliciting a DHCPv6 lease
> dhcpcd[248]: enp1s0: ADV 2401:a400:2704:1750::/60 from fe80::d6ca:6dff:fe74:72f8
> dhcpcd[248]: enp1s0: REPLY6 received from fe80::d6ca:6dff:fe74:72f8
> dhcpcd[248]: 2401:a400:2704:1750::/60 262
> dhcpcd[248]: 2401:a400:2704:1750::/60 258
> dhcpcd[248]: enp1s0: adding address 2401:a400:2704:1750::/60
> dhcpcd[248]: enp1s0: renew in 302400, rebind in 483840, expire in 604800 seconds
> dhcpcd[248]: lo: adding reject route to 2401:a400:2704:1700::/60
> dhcpcd[248]: enp2s0: adding address 2401:a400:2704:1701::1/64
> dhcpcd[248]: enp3s0: adding address 2401:a400:2704:1704::1/64
> dhcpcd[248]: wlxc412f52ebb7b: adding address 2401:a400:2704:1703::1/64
> dhcpcd[248]: wlxc412f52e39d2: adding address 2401:a400:2704:1702::1/64
> dhcpcd[248]: enp2s0: adding route to 2401:a400:2704:1701::/64
> dhcpcd[248]: enp3s0: adding route to 2401:a400:2704:1704::/64
> dhcpcd[248]: wlxc412f52ebb7b: adding route to 2401:a400:2704:1703::/64
> dhcpcd[248]: wlxc412f52e39d2: adding route to 2401:a400:2704:1702::/64
>
> Notice that the prefix received from the upstream router
> (2401:a400:2704:1750::/60), appears to be incorrectly interpreted later
> as a /56 (2401:a400:2704:1700::/60), which is then delegated incorrectly
> to the interfaces. E.g. the delegation to enp2s0 should be
> 2401:a400:2704:1751::1/64, but instead it is 2401:a400:2704:1701::1/64.
>
> Have I misconfigured dhcpcd, misunderstood prefix delegation, or hit a
> bug?
>
The following works for me. It gets a /60 from Comcrash and assigns a /64 to each of the four interfaces. It does only IPv6 to keep it from interfering with IPv4 (which is handled automatically on the Smoothie; I haven't finished IPv6 work for Express). I last tested on 6.10 or 6.11.
This is the .conf I use on my Smoothwall Express v3.1 system (for testing).
-------------------------------------------------------------------------
#
# A sample configuration for dhcpcd.
# See dhcpcd.conf(5) for details.
# Allow users of this group to interact with dhcpcd via the control socket.
#controlgroup wheel
# Inform the DHCP server of our hostname for DDNS.
# Use the hardware address of the interface for the Client ID.
#clientid
# or
# Use the same DUID + IAID as set in DHCPv6 for DHCPv4 ClientID as per RFC4361.
# Some non-RFC compliant DHCP servers do not reply with this set.
# In this case, comment out duid and enable clientid above.
duid
# Persist interface configuration when dhcpcd exits.
persistent
# Rapid commit support.
# Safe to enable by default because it requires the equivalent option set
# on the server to actually work.
option rapid_commit
# A list of options to request from the DHCP server.
option domain_name_servers, domain_name, domain_search, host_name
option classless_static_routes
# Most distributions have NTP support.
option ntp_servers
# Respect the network MTU.
# Some interface drivers reset when changing the MTU so disabled by default.
#option interface_mtu
# A ServerID is required by RFC2131.
require dhcp_server_identifier
# Generate Stable Private IPv6 Addresses instead of hardware based ones
slaac private
# A hook script is provided to lookup the hostname if not set by the DHCP
# server, but it should not be run by default.
nohook lookup-hostname, hostname, resolv.conf, ntp.conf, timezone, wpa_supplicant
# Use smoothie's script
script /etc/rc.d/rc.update6red
allowinterfaces eth0 eth1 eth2 eth3
denyinterfaces lo ipsec0 ipsec1
debug
ipv6only
ipv6ra_own
ipv6ra_own_default
leasetime 31622400
nodhcp
nodhcp6
noipv6rs
#logfile /var/log/dhcpcd6.log
interface eth0
iaid 4b:17:f2:7a
interface eth1
iaid 4b:17:f2:7b
interface eth2
iaid 4b:17:f2:7c
interface eth3
dhcp6
ipv6rs
iaid 4b:17:f2:7d
ia_na 4b:17:f2:7d
ia_pd 4b:17:f2:7a/::/60 eth0/1/64 eth1/2/64 eth2/3/64
-------------------------------------------------------------------------
This is the rc.update6red script. There are more than several Express-specific things in here; but it should yield at least a few clues.
-------------------------------------------------------------------------
#!/bin/bash
# Like nearly everything in SWE, the file is covered by the project's
# umbrella GPL license.
# Tweaks to handle DHCP changes by Neal Murphy and Stan Prescott, 4/2013
# Re-arranged a little and ip-up merged in; Neal Murphy, 7/2013
# Console output expanded to dump to console, syslog (smoothwall) and/or
# syslog (dhcpcd debugging); Murphy/Jones, 2015
# In addition to execution trace debugging, it is possible to dump this script's
# environment as passed from dhcpcd.
#
# To enable dhcpcd environment logging, create the debug_dhcpcdenv flag file:
# touch "/var/run/debug-dhcpcdenv"
# To disable this logging, delete the file:
# rm -f "/var/run/debug-dhcpcdenv"
# A bit of shorthand
ethDIR="/var/smoothwall/ethernet"
pppDIR="/var/smoothwall/ppp"
redDIR="/var/smoothwall/red"
. /etc/rc.d/inc.rc-functions
dns1ENV=$DNS1
dns2ENV=$DNS2
. ${ethDIR}/settings
# readRED6: read the data files in .../red/*
function readRED6 {
case $RED_TYPE in
DHCP)
RED6_INTERFACE=`cat $redDIR/iface6`
RED6_ADDRESS=`cat $redDIR/local6-ipaddress`
RED6_GATEWAY=`cat $redDIR/remote6-ipaddress`
RED6_NETMASK=`cat $redDIR/dhcp6-netmask`
RED6_DNS1=`cat $redDIR/dns61`
RED6_DNS2=`cat $redDIR/dns62`
RED_DNS1=`cat $redDIR/dns1`
RED_DNS2=`cat $redDIR/dns2`
;;
*)
echolog "" "s" "$DEBUG_DHCPCD" "..readRED6 called for invalid red type '$RED_TYPE'"
exit 0
;;
esac
}
# writeRED: write the data files in .../red/*
function writeRED6 {
echo -n $1 >$redDIR/iface6
echo -n $2 >$redDIR/local6-ipaddress
echo -n $3 >$redDIR/remote6-ipaddress
echo -n $4 >$redDIR/dhcp6-netmask
echo -n $5 >$redDIR/dns61
echo -n $6 >$redDIR/dns62
> $redDIR/active6
chown nobody:nobody $redDIR/*
}
if [ "$reason" != "ROUTERADVERT" ]; then
echolog "$crDEBUG" "" "$DEBUG_DHCPCD" "..enter rc.update6red ($reason) [`date`]"
# Drop a trace
echolog "$crDEBUG" "s" "$crDEBUG_DHCPCD" "..Update6 RED"
fi
if [ "$RED_TYPE" == "DHCP" ]; then
# First up; when RED is DHCP
# We only care about BOUND, REBOOT, RENEW, STOPPED and STOP; we ignore the rest:
# EXPIRE*|EXPIRE6*|NAK*|FAIL*|CARRIER*|NOCARRIER*|PREINIT*|DEPARTED*|TIMEOUT*
# If new reasons appear, we'll see them in the log.
if [ "$reason" != "ROUTERADVERT" ]; then
echolog "$crDEBUG" "s" "$DEBUG_DHCPCD" "..RED6 is DHCP"
fi
# Special dhcpcd debug: maybe dump the environment to syslog (debug.log)
if [ -e "/var/run/debug-dhcpcd6env" ]; then
(
echo -e "\n======\nAs of `date`"
echo "Second Param: " $2
echo "env reason: " $reason
echo
echo "Positional params"
for i in "$@"; do echo " '$i'";done
echo "environment"
set
) |& logger -t dhcpcd6env -p local6.debug
fi
# end dhcpcd environment debug logging block
# Why did you call me?
case $reason in
STOPPED)
# Nothing to do; either the system is going down or networking is
# being stopped for restart. *Technically*, it might be more correct
# to stop the various services; but since they are re-started soon
# enough or the system halts, it might not matter.
echolog "" "s" "" "..DHCP6 stopped on $interface"
echolog "$crDEBUG" "" \
"$DEBUG_DHCPCD" "..DHCP6 stopped on $interface; rc.update6red RED_TYPE [$RED_TYPE] ($reason) [`date`]"
#echo -e "\n$reason" >> /var/log/dhcpcdtmp.log
#set | egrep "^[a-z]" >> /var/log/dhcpcdtmp.log
for i in $old_dhcp6_name_servers; do
sed -i -e "/$i/d" /etc/resolv.conf
done
# This might could get annoying if the lease changes often
[ "$interface" == "$RED_DEV" ] && /usr/bin/sounds/offlinesound
echolog "$crDEBUG" "" "$DEBUG_DHCPCD" \
"..DHCP6 stopped; exit rc.update6red RED_TYPE [$RED_TYPE] ($reason) [`date`]"
echolog "" "s" "" "..DHCP6 stopped, reason: ($reason)"
# Clear the v6 files and mark IPv6 not active on RED
writeRED6
rm /var/smoothwall/red/active6
echolog "$crDEBUG" "" "$DEBUG_DHCPCD" \
"..exit rc.update6red RED_TYPE [$RED_TYPE] ($reason) [`date`]"
exit 0
;;
BOUND6|REBOOT6)
# New lease bound; all new.
# Log some stuff
#echo -e "\n$reason" >> /var/log/dhcpcdtmp.log
#set | egrep "^[a-z]" >> /var/log/dhcpcdtmp.log
# Clear the old DNS server addresses in resolv.conf, if any
for i in $old_dhcp6_name_servers; do
sed -i -e '/$i/d' /etc/resolv.conf
done >> /etc/resolv.conf
# Put the new IPv6 DNS addresses in resolv.conf
for i in $new_dhcp6_name_servers; do
sed -i -e '/$i/d' /etc/resolv.conf
echo "nameserver $i" >> /etc/resolv.conf
done
# Log lease received and address bound
echolog "E" "s" "" "..DHCP6 lease bound ($reason) and prefix delegated; update RED6 info"
echolog "$crDEBUG" "" "$DEBUG_DHCPCD" "..DHCP6 new lease bound ($reason) and prefix delegated; update RED6 info. rc.update6red RED_TYPE [$RED_TYPE] ($reason) [`date`]"
# Log some environment
#echo $reason >> /var/log/dhcpcdtmp.log
#set | egrep "^[a-z]" >> /var/log/dhcpcdtmp.log
# Save the address
sed -i -e '/^IP6_ADDRESS/d' /var/lib/dhcpcd/dhcpcd6-$interface.info
echo "IP6_ADDRESS=$new_dhcp6_ia_na1_ia_addr1/128" >> /var/lib/dhcpcd/dhcpcd6-$interface.info
echolog "$crDEBUG" "" "$DEBUG_DHCPCD" "..DHCP6 new address: $new_dhcp6_ia_na1_ia_addr1/128 [$RED_TYPE] ($reason) [`date`]"
# Did we get a prefix?
if [ ! -z "$new_dhcp6_ia_pd1_prefix1" ]; then
# Save the delegated net
echo "IP6_NET=$new_dhcp6_ia_pd1_prefix1/$new_dhcp6_ia_pd1_prefix1_length" > /var/lib/dhcpcd/dhcpcd6-delegated.info
echolog "$crDEBUG" "" "$DEBUG_DHCPCD" "..DHCP6 delegated prefix: $new_dhcp6_ia_pd1_prefix1/$new_dhcp6_ia_pd1_prefix1_length [$RED_TYPE] ($reason) [`date`]"
# Clear the old prefix address, if any, from RED
if [ ! -z "$old_dhcp6_ia_pd1_prefix1" ]; then
ip -6 addr del ${old_dhcp6_ia_pd1_prefix1}1/64 dev $RED_DEV #>/dev/null 2>&1
fi
# And assign 'subnet 0'::1 to RED
RED6_IP="${new_dhcp6_ia_pd1_prefix1}1"
ip -6 addr add ${new_dhcp6_ia_pd1_prefix1}1/64 dev $RED_DEV
# dhcpcd assigns 'subnet 1', 'subnet 2' and 'subnet 3' to GREEN, ORANGE and PURPLE, respectively.
fi
# Save the available RED info
readRED6
writeRED6 "$interface" "$new_dhcp6_ia_na1_ia_addr1" "$RED6_GATEWAY" \
"/128" $new_dhcp6_name_servers
# We may want to restart daemons &cet, so don't exit.
;;
RELEASE6)
# Log some stuff
#echo -e "\n$reason" >> /var/log/dhcpcdtmp.log
#set | egrep "^[a-z]" >> /var/log/dhcpcdtmp.log
# Remove IPv6 from resolv.conf
for i in $old_dhcp6_name_servers; do
sed -i -e "/$i/d" /etc/resolv.conf
done
# Clear the RED6 files
writeRED6
rm -f $redDIR/active6
echolog "$crDEBUG" "" "$DEBUG_DHCPCD" \
"..exit rc.update6red RED_TYPE [$RED_TYPE] ($reason) [`date`]"
exit 0
;;
EXPIRE6)
# Lease expired; clean up.
#echo -e "\n$reason" >> /var/log/dhcpcdtmp.log
#set | egrep "^[a-z]" >> /var/log/dhcpcdtmp.log
writeRED6
rm -f $redDIR/active6
echolog "$crDEBUG" "" "$DEBUG_DHCPCD" \
"..DHCP6 lease expired ($old_dhcp6_ia_na1_ia_addr1; old_dhcp6_ia_pd1_prefix1) $interface [$RED_TYPE] ($reason) [`date`]"
echolog "$crDEBUG" "" "$DEBUG_DHCPCD" \
"..exit rc.update6red RED_TYPE [$RED_TYPE] ($reason) [`date`]"
exit 0
;;
DELEGATED6)
# IP addrs have been fetched and delegated to internal IFs. Record them.
# Eventually, rewrite dhcp.conf and/or restart dhcpd (the server daemon)
# so that correct addresses will be fed to internal hosts.
#echo -e "\n$reason" >> /var/log/dhcpcdtmp.log
#set | egrep "^[a-z]" >> /var/log/dhcpcdtmp.log
sed -i -e '/^IP6_ADDRESS/d' /var/lib/dhcpcd/dhcpcd6-$interface.info
echo "IP6_ADDRESS=$new_delegated_dhcp6_prefix" >> /var/lib/dhcpcd/dhcpcd6-$interface.info
echolog "$crDEBUG" "" "$DEBUG_DHCPCD" \
"..DHCP6 $new_delegated_dhcp6_prefix delegated to $interface [$RED_TYPE] ($reason) [`date`]"
echolog "$crDEBUG" "" "$DEBUG_DHCPCD" \
"..exit rc.update6red RED_TYPE [$RED_TYPE] ($reason) [`date`]"
exit 0
;;
ROUTERADVERT)
# Our default gateway. These arrive 'forever', so minimize logging.
# Log some stuff
#echo -e "\n$reason" >> /var/log/dhcpcdtmp.log
#set | egrep "^[a-z]" >> /var/log/dhcpcdtmp.log
# Get current RED params, store and log if changed.
readRED6
if [ "$RED6_GATEWAY" != "$nd1_from" ]; then
echolog "$crDEBUG" "" "$DEBUG_DHCPCD" "..enter rc.update6red ($reason) [`date`]"
echolog "$crDEBUG" "s" "$crDEBUG_DHCPCD" "..Update6 RED"
writeRED6 "$interface" "$RED6_ADDRESS" "$nd1_from" \
"$RED6_NETMASK" "$RED6_DNS1" "$RED6_DNS2"
echolog "$crDEBUG" "" "$DEBUG_DHCPCD" \
"..DHCP6 $nd1_from assigned as default gateway [$RED_TYPE] ($reason) [`date`]"
echolog "$crDEBUG" "" "$DEBUG_DHCPCD" \
"..exit rc.updatered RED_TYPE [$RED_TYPE] ($reason) [`date`]"
fi
exit 0
;;
*)
# Ignore all other reasons, known or not. If important, we'll code it up.
echolog "$crDEBUG" "s" "$DEBUG_DHCPCD" \
"..Ignore DHCPCD6 unknown callback reason '$reason'"
echolog "$crDEBUG" "" "$DEBUG_DHCPCD" \
"..exit rc.update6red RED_TYPE [$RED_TYPE] ($reason) [`date`]"
#echo -e "\nUNKNOWN $reason" >> /var/log/dhcpcdtmp.log
#set | egrep "^[a-z]" >> /var/log/dhcpcdtmp.log
exit 0
;;
esac
fi
#####################
# For now, do nothing when IPv6 changes
#####################
exit 0
# Restart/reset everything that depends on RED
#
echolog "E" "s" "" "..DNSMasq (DNS1: $DNSMASQ_DNS1; DNS2: $DNSMASQ_DNS2)"
#echolog "E" "s" "" "..RED6 filtering"
# For now, there is minimal filtering; until IPv6 is fully integrated, the IPv6
# firewall is static: NEW-to-RED is allowed, REL/EST-from-RED is allowed,
# and all traffic among internal LANs is allowed. Not ideal, but good enough
# for testing and development.
#/usr/bin/smoothcom setincoming
#/usr/bin/smoothcom setoutgoing
# Part of Roadster's integrated TOFC
#if [ -f /var/smoothwall/outgoing/configErrors.log ]; then
# tput smso;
# sed -e 's/^/.. /' /var/smoothwall/outgoing/configErrors.log
# tput rmso
#fi
#echolog "E" "s" "" "..external access rules"
#/usr/bin/smoothcom setxtaccess
echolog "E" "s" "$DEBUG_DHCPCD" "..snort, squid, upnpd, TC, DDNS, VPN (as enabled)"
/usr/bin/smoothcom snortrestart
echolog "$crDEBUG" "" "$DEBUG_DHCPCD" "....smoothcom: squidrestart [`date`]"
/usr/bin/smoothcom squidrestart
echolog "$crDEBUG" "" "$DEBUG_DHCPCD" "....smoothcom: upnpdrestart [`date`]"
/usr/bin/smoothcom upnpdrestart
echolog "$crDEBUG" "" "$DEBUG_DHCPCD" "....smoothcom: trafficrestart [`date`]"
/usr/bin/smoothcom trafficrestart
/usr/bin/smoothwall/setddns.pl
/etc/rc.d/rc.vpn.up
# Adapted from Steve McNeill's ModInstall
echolog "E" "s" "" "..run mods' 'on RED6 up' scripts"
# if any; limited to .../mods/*/etc/rc.d
shopt -s nullglob
for i in /var/smoothwall/mods/*/etc/rc.d/00rc.update6red; do
$i
done
shopt -u nullglob
# exit rc.updatered:
echolog "$crDEBUG" "" "$DEBUG_DHCPCD" "..exit rc.updatered RED_TYPE [$RED_TYPE] ($reason) [`date`]"
-------------------------------------------------------------------------
Archive administrator: postmaster@marples.name