#627164 klibc-utils: ipconfig does not support for ipv6

Package:
klibc-utils
Source:
klibc
Description:
small utilities built with klibc for early boot
Submitter:
Michal Suchanek
Date:
2024-01-02 01:51:06 UTC
Severity:
important
Tags:
#627164#5
Date:
2011-05-18 11:03:37 UTC
From:
To:
IPv6 is the current IP standard.

ipconfig does not support it.

#627164#14
Date:
2024-01-02 01:46:57 UTC
From:
To:
Dixi quod…

I did it!

Extract the following shar archive into /etc/initramfs-tools/ first…

# This is a shell archive.  Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file".  Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
#	hooks/ipv6
#	scripts/init-top/ipv6
#	scripts/init-bottom/ipv6
#
echo x - hooks/ipv6
sed 's/^X//' >hooks/ipv6 << 'END-of-hooks/ipv6'
X#!/bin/sh
X
XPREREQ="dropbear klibc-utils zz-busybox"
Xprereqs() {
X	echo "$PREREQ"
X}
X
Xcase $1 in
X(prereqs)
X	prereqs
X	exit 0
X	;;
Xesac
X
X. /usr/share/initramfs-tools/hook-functions
X
Xset -e
X
Xtest -x "$DESTDIR/bin/ipconfig" || {
X	echo >&2 "E: klibc ipconfig not found"
X	exit 1
X}
Xtest -x "$DESTDIR/bin/ip" || test -x "$DESTDIR/sbin/ip" || {
X	echo >&2 "E: ip(8), busybox or normal, not found"
X	exit 1
X}
X
Xmv "$DESTDIR/bin/ipconfig" "$DESTDIR/bin/ipconfig.klibc-dist"
Xcat >"$DESTDIR/bin/ipconfig" <<\EOSCRIPT
X#!/bin/sh
Xcase ${1}${3}${4} in
X(-t-dipv6:*)
X	;;
X(*)
X	echo >&2 "I: configuring something other than IPv6"
X	exec /bin/ipconfig.klibc-dist "$@"
X	exit 126
X	;;
Xesac
Xset -e
Xecho >&2 "I: configuring IPv6"
X. /conf/param.conf
Xcase $ipv6_ra:$ipv6_if in
X([01]:?*)
X	;;
X(*)
X	echo >&2 "E: cannot find IPv6 configuration"
X	exit 1
X	;;
Xesac
Xtest -e "/proc/sys/net/ipv6/conf/$ipv6_if/accept_ra" || {
X	echo >&2 "E: cannot find interface for IPv6 configuration: $ipv6_if"
X	( ( ip a | sed 's/^/N: /' >&3) 2>&1 | sed 's/^/E: /') >&2 3>&2
X	exit 1
X}
X
Xcat >"/run/net-$ipv6_if.conf" <<EOF
X${ipv6_hn:+HOSTNAME=$ipv6_hn
X}DEVICE=$ipv6_if
XEOF
X
Xipv6_restore_ra=$(cat "/proc/sys/net/ipv6/conf/$ipv6_if/accept_ra")
Xcase $ipv6_restore_ra in
X(0|1) ;;
X(*) ipv6_restore_ra=1 ;;
Xesac
Xecho ipv6_restore_ra=$ipv6_restore_ra >>/conf/param.conf
Xecho $ipv6_ra >"/proc/sys/net/ipv6/conf/$ipv6_if/accept_ra"
X
Xip link set dev "$ipv6_if" up || {
X	echo >&2 E: could not enable interface
X	exit 1
X}
Xmaxwait=
Xwhile test x"$(cat "/sys/class/net/$ipv6_if/operstate")" != x"up"; do
X	if test x"$maxwait" = x"111111111111111"; then
X		echo >&2
X		echo >&2 'W: link still not up? continuing anyway :/'
X		maxwait=
X		break
X	else
X		test -n "$maxwait" || echo -n >&2 \
X		    'I: waiting until link comes up or 15 seconds '
X		maxwait=1$maxwait
X		sleep 1
X		echo -n >&2 .
X	fi
Xdone
Xtest -z "$maxwait" || echo >&2 ' done'
Xif test -n "$ipv6_na"; then
X	ip -6 addr add "$ipv6_na" dev "$ipv6_if" || {
X		echo >&2 E: could not set up IP
X		exit 1
X	}
X	if ip -6 addr show dev "$ipv6_if" to "$ipv6_na" dadfailed >/dev/null 2>&1; then
X		maxwait=
X		while test -n "$(ip -6 addr show dev "$ipv6_if" to "$ipv6_na" tentative)"; do
X			if test x"$maxwait" = x"1111111"; then
X				echo -n >&2 'timeout'
X				break
X			else
X				test -n "$maxwait" || echo -n >&2 \
X				    'I: waiting for duplicate address detection '
X				maxwait=1$maxwait
X				sleep 1
X				echo -n >&2 .
X			fi
X		done
X		if test -z "$(ip -6 addr show dev "$ipv6_if" to "$ipv6_na" dadfailed)"; then
X			test -z "$maxwait" || echo >&2 ' done'
X		elif test -z "$maxwait"; then
X			echo >&2 'E: duplicate address detection FAILED!'
X		else
X			echo >&2 ' FAILED!'
X		fi
X	else
X		echo >&2 'W: busybox ip(8) cannot handle duplicate address detection'
X		sleep 1 # justin case
X	fi
Xfi
Xif test -n "$ipv6_gw"; then
X	ip -6 route replace default via "$ipv6_gw" dev "$ipv6_if" onlink || {
X		echo >&2 E: could not set up default route
X		exit 1
X	}
Xfi
Xtest -z "$ipv6_hn" || echo "$ipv6_hn" >/proc/sys/kernel/hostname
Xip addr show dev "$ipv6_if" | sed 's/^/N: /' >&2
Xip -6 route list | sed 's/^/N: /' >&2
Xecho >&2 I: IPv6 set up successfully
XEOSCRIPT
Xchmod 555 "$DESTDIR/bin/ipconfig"
END-of-hooks/ipv6
echo x - scripts/init-top/ipv6
sed 's/^X//' >scripts/init-top/ipv6 << 'END-of-scripts/init-top/ipv6'
X#!/bin/sh
X
XPREREQ=""
Xprereqs() {
X	echo "$PREREQ"
X}
X
Xcase $1 in
X(prereqs)
X	prereqs
X	exit 0
X	;;
Xesac
X
X. /scripts/functions
X
Xcase $IP in
X(6,[01],*[!0-9a-zA-Z/:.,-]*)
X	log_failure_msg "init-top/ipv6: IPv6 \$ip contains invalid characters"
X	exit 0
X	;;
X(6,[01],?*)
X	;;
X(*)
X	exit 0
X	;;
Xesac
X
X# incoming syntax (ra is 0 or 1, keepup is 1 or absent=0):
X#	ip=6,ra,iface[,[hostname][,[ip/netmask][,[gw][,keepup]]]]
X# examples:
X#	ip=6,1,eth0
X#	ip=6,0,enx78e7d1ea46dc,0,,2001:db8::1/64
X#	ip=6,0,wlan0,0,meow.example.org,2001:db8::1/64,fe80::1,1
X# but mind IFDOWN in /etc/dropbear-initramfs/config
X# do also note that klibc/initramfs cannot do NFS over IPv6 either in 2024(!)
X
Xset -o noglob
XsaveIFS=$IFS
XIFS=,
Xset -- $IP
XIFS=$saveIFS
Xset +o noglob
X
Xip_ra=$2
Xip_if=$3
Xip_hn=$4
Xip_na=$5
Xip_gw=$6
Xip_up=$7
X
Xcase $ip_if in
X(*/*)
X	log_failure_msg "init-top/ipv6: IPv6 \$ip device contains a slash"
X	exit 0
X	;;
Xesac
X
Xcase x$ip_up in
X(x|x0)	ip_up=0 ;;
X(*)	ip_up=1 ;;
Xesac
X
X# ip=<client-ip>:<server-ip>:<gw-ip>:<netmask>:<hostname>:<device>:<autoconf>:<dns0-ip>:<dns1-ip>:<ntp0-ip>
Xfakex=ipv6::::$ip_hn:$ip_if
X
Xmsg="Preparing on $ip_if to"
Xcase $ip_ra in
X(0)
X	msg="$msg not"
X	;;
X(1)
X	;;
X(*)
X	log_failure_msg "init-top/ipv6: bogus ra? cannot happen!"
X	exit 0
X	;;
Xesac
Xmsg="$msg accept router advertisements"
Xtest -z "$ip_na" || msg="$msg, IP $ip_na"
Xtest -z "$ip_gw" || msg="$msg, default route $ip_gw"
Xtest -z "$ip_hn" || msg="$msg, hostname $ip_hn"
X
Xcat >>/conf/param.conf <<EOF
Xipv6_if=$ip_if
Xipv6_hn=$ip_hn
Xipv6_na=$ip_na
Xipv6_gw=$ip_gw
XIP=$fakex
Xipv6_restore_ra=NO
Xipv6_keepup=$ip_up
Xipv6_ra=$ip_ra
XEOF
X
Xlog_success_msg "init-top/ipv6: $msg"
END-of-scripts/init-top/ipv6
echo x - scripts/init-bottom/ipv6
sed 's/^X//' >scripts/init-bottom/ipv6 << 'END-of-scripts/init-bottom/ipv6'
X#!/bin/sh
X
XPREREQ="dropbear"
Xprereqs() {
X	echo "$PREREQ"
X}
X
Xcase $1 in
X(prereqs)
X	prereqs
X	exit 0
X	;;
Xesac
X
X. /scripts/functions
X. /conf/param.conf
X
Xcase x$ipv6_keepup in
X(x)
X	exit 0
X	;;
X(x1)
X	log_success_msg "init-bottom/ipv6: keeping interface $ipv6_if up"
X	exit 0
X	;;
Xesac
X
Xlog_begin_msg "init-bottom/ipv6: bringing interface $ipv6_if down"
Xtest x"$ipv6_restore_ra" = x"NO" || \
X    echo "$ipv6_restore_ra" >"/proc/sys/net/ipv6/conf/$ipv6_if/accept_ra" || \
X    log_failure_msg "could not restore accept_ra flag to $ipv6_restore_ra"
Xip link set dev "$ipv6_if" down
Xip addr flush dev "$ipv6_if"
Xip route flush dev "$ipv6_if"
Xlog_end_msg
END-of-scripts/init-bottom/ipv6
exit

… then put something like (with net.ifnames=0 of course)…

	ip=6,0,eth0,debian.example.org,2001:db8::1/128,fe80::1

… in GRUB_CMDLINE_LINUX in /etc/default/grub then regenerate the
initramfs and update-grub and you’ll be set for some use cases,
namely “remotely unlock full disc encryption with dropbear”.

NFS over IPv6 still relies on klibc’s nfsmount utility (which is
also insistent on using Legacy IP).

But this is a start ☻

Enjoy,
//mirabilos

#627164#17
Date:
2024-01-02 01:46:57 UTC
From:
To:
Dixi quod…

I did it!

Extract the following shar archive into /etc/initramfs-tools/ first…

# This is a shell archive.  Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file".  Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
#	hooks/ipv6
#	scripts/init-top/ipv6
#	scripts/init-bottom/ipv6
#
echo x - hooks/ipv6
sed 's/^X//' >hooks/ipv6 << 'END-of-hooks/ipv6'
X#!/bin/sh
X
XPREREQ="dropbear klibc-utils zz-busybox"
Xprereqs() {
X	echo "$PREREQ"
X}
X
Xcase $1 in
X(prereqs)
X	prereqs
X	exit 0
X	;;
Xesac
X
X. /usr/share/initramfs-tools/hook-functions
X
Xset -e
X
Xtest -x "$DESTDIR/bin/ipconfig" || {
X	echo >&2 "E: klibc ipconfig not found"
X	exit 1
X}
Xtest -x "$DESTDIR/bin/ip" || test -x "$DESTDIR/sbin/ip" || {
X	echo >&2 "E: ip(8), busybox or normal, not found"
X	exit 1
X}
X
Xmv "$DESTDIR/bin/ipconfig" "$DESTDIR/bin/ipconfig.klibc-dist"
Xcat >"$DESTDIR/bin/ipconfig" <<\EOSCRIPT
X#!/bin/sh
Xcase ${1}${3}${4} in
X(-t-dipv6:*)
X	;;
X(*)
X	echo >&2 "I: configuring something other than IPv6"
X	exec /bin/ipconfig.klibc-dist "$@"
X	exit 126
X	;;
Xesac
Xset -e
Xecho >&2 "I: configuring IPv6"
X. /conf/param.conf
Xcase $ipv6_ra:$ipv6_if in
X([01]:?*)
X	;;
X(*)
X	echo >&2 "E: cannot find IPv6 configuration"
X	exit 1
X	;;
Xesac
Xtest -e "/proc/sys/net/ipv6/conf/$ipv6_if/accept_ra" || {
X	echo >&2 "E: cannot find interface for IPv6 configuration: $ipv6_if"
X	( ( ip a | sed 's/^/N: /' >&3) 2>&1 | sed 's/^/E: /') >&2 3>&2
X	exit 1
X}
X
Xcat >"/run/net-$ipv6_if.conf" <<EOF
X${ipv6_hn:+HOSTNAME=$ipv6_hn
X}DEVICE=$ipv6_if
XEOF
X
Xipv6_restore_ra=$(cat "/proc/sys/net/ipv6/conf/$ipv6_if/accept_ra")
Xcase $ipv6_restore_ra in
X(0|1) ;;
X(*) ipv6_restore_ra=1 ;;
Xesac
Xecho ipv6_restore_ra=$ipv6_restore_ra >>/conf/param.conf
Xecho $ipv6_ra >"/proc/sys/net/ipv6/conf/$ipv6_if/accept_ra"
X
Xip link set dev "$ipv6_if" up || {
X	echo >&2 E: could not enable interface
X	exit 1
X}
Xmaxwait=
Xwhile test x"$(cat "/sys/class/net/$ipv6_if/operstate")" != x"up"; do
X	if test x"$maxwait" = x"111111111111111"; then
X		echo >&2
X		echo >&2 'W: link still not up? continuing anyway :/'
X		maxwait=
X		break
X	else
X		test -n "$maxwait" || echo -n >&2 \
X		    'I: waiting until link comes up or 15 seconds '
X		maxwait=1$maxwait
X		sleep 1
X		echo -n >&2 .
X	fi
Xdone
Xtest -z "$maxwait" || echo >&2 ' done'
Xif test -n "$ipv6_na"; then
X	ip -6 addr add "$ipv6_na" dev "$ipv6_if" || {
X		echo >&2 E: could not set up IP
X		exit 1
X	}
X	if ip -6 addr show dev "$ipv6_if" to "$ipv6_na" dadfailed >/dev/null 2>&1; then
X		maxwait=
X		while test -n "$(ip -6 addr show dev "$ipv6_if" to "$ipv6_na" tentative)"; do
X			if test x"$maxwait" = x"1111111"; then
X				echo -n >&2 'timeout'
X				break
X			else
X				test -n "$maxwait" || echo -n >&2 \
X				    'I: waiting for duplicate address detection '
X				maxwait=1$maxwait
X				sleep 1
X				echo -n >&2 .
X			fi
X		done
X		if test -z "$(ip -6 addr show dev "$ipv6_if" to "$ipv6_na" dadfailed)"; then
X			test -z "$maxwait" || echo >&2 ' done'
X		elif test -z "$maxwait"; then
X			echo >&2 'E: duplicate address detection FAILED!'
X		else
X			echo >&2 ' FAILED!'
X		fi
X	else
X		echo >&2 'W: busybox ip(8) cannot handle duplicate address detection'
X		sleep 1 # justin case
X	fi
Xfi
Xif test -n "$ipv6_gw"; then
X	ip -6 route replace default via "$ipv6_gw" dev "$ipv6_if" onlink || {
X		echo >&2 E: could not set up default route
X		exit 1
X	}
Xfi
Xtest -z "$ipv6_hn" || echo "$ipv6_hn" >/proc/sys/kernel/hostname
Xip addr show dev "$ipv6_if" | sed 's/^/N: /' >&2
Xip -6 route list | sed 's/^/N: /' >&2
Xecho >&2 I: IPv6 set up successfully
XEOSCRIPT
Xchmod 555 "$DESTDIR/bin/ipconfig"
END-of-hooks/ipv6
echo x - scripts/init-top/ipv6
sed 's/^X//' >scripts/init-top/ipv6 << 'END-of-scripts/init-top/ipv6'
X#!/bin/sh
X
XPREREQ=""
Xprereqs() {
X	echo "$PREREQ"
X}
X
Xcase $1 in
X(prereqs)
X	prereqs
X	exit 0
X	;;
Xesac
X
X. /scripts/functions
X
Xcase $IP in
X(6,[01],*[!0-9a-zA-Z/:.,-]*)
X	log_failure_msg "init-top/ipv6: IPv6 \$ip contains invalid characters"
X	exit 0
X	;;
X(6,[01],?*)
X	;;
X(*)
X	exit 0
X	;;
Xesac
X
X# incoming syntax (ra is 0 or 1, keepup is 1 or absent=0):
X#	ip=6,ra,iface[,[hostname][,[ip/netmask][,[gw][,keepup]]]]
X# examples:
X#	ip=6,1,eth0
X#	ip=6,0,enx78e7d1ea46dc,0,,2001:db8::1/64
X#	ip=6,0,wlan0,0,meow.example.org,2001:db8::1/64,fe80::1,1
X# but mind IFDOWN in /etc/dropbear-initramfs/config
X# do also note that klibc/initramfs cannot do NFS over IPv6 either in 2024(!)
X
Xset -o noglob
XsaveIFS=$IFS
XIFS=,
Xset -- $IP
XIFS=$saveIFS
Xset +o noglob
X
Xip_ra=$2
Xip_if=$3
Xip_hn=$4
Xip_na=$5
Xip_gw=$6
Xip_up=$7
X
Xcase $ip_if in
X(*/*)
X	log_failure_msg "init-top/ipv6: IPv6 \$ip device contains a slash"
X	exit 0
X	;;
Xesac
X
Xcase x$ip_up in
X(x|x0)	ip_up=0 ;;
X(*)	ip_up=1 ;;
Xesac
X
X# ip=<client-ip>:<server-ip>:<gw-ip>:<netmask>:<hostname>:<device>:<autoconf>:<dns0-ip>:<dns1-ip>:<ntp0-ip>
Xfakex=ipv6::::$ip_hn:$ip_if
X
Xmsg="Preparing on $ip_if to"
Xcase $ip_ra in
X(0)
X	msg="$msg not"
X	;;
X(1)
X	;;
X(*)
X	log_failure_msg "init-top/ipv6: bogus ra? cannot happen!"
X	exit 0
X	;;
Xesac
Xmsg="$msg accept router advertisements"
Xtest -z "$ip_na" || msg="$msg, IP $ip_na"
Xtest -z "$ip_gw" || msg="$msg, default route $ip_gw"
Xtest -z "$ip_hn" || msg="$msg, hostname $ip_hn"
X
Xcat >>/conf/param.conf <<EOF
Xipv6_if=$ip_if
Xipv6_hn=$ip_hn
Xipv6_na=$ip_na
Xipv6_gw=$ip_gw
XIP=$fakex
Xipv6_restore_ra=NO
Xipv6_keepup=$ip_up
Xipv6_ra=$ip_ra
XEOF
X
Xlog_success_msg "init-top/ipv6: $msg"
END-of-scripts/init-top/ipv6
echo x - scripts/init-bottom/ipv6
sed 's/^X//' >scripts/init-bottom/ipv6 << 'END-of-scripts/init-bottom/ipv6'
X#!/bin/sh
X
XPREREQ="dropbear"
Xprereqs() {
X	echo "$PREREQ"
X}
X
Xcase $1 in
X(prereqs)
X	prereqs
X	exit 0
X	;;
Xesac
X
X. /scripts/functions
X. /conf/param.conf
X
Xcase x$ipv6_keepup in
X(x)
X	exit 0
X	;;
X(x1)
X	log_success_msg "init-bottom/ipv6: keeping interface $ipv6_if up"
X	exit 0
X	;;
Xesac
X
Xlog_begin_msg "init-bottom/ipv6: bringing interface $ipv6_if down"
Xtest x"$ipv6_restore_ra" = x"NO" || \
X    echo "$ipv6_restore_ra" >"/proc/sys/net/ipv6/conf/$ipv6_if/accept_ra" || \
X    log_failure_msg "could not restore accept_ra flag to $ipv6_restore_ra"
Xip link set dev "$ipv6_if" down
Xip addr flush dev "$ipv6_if"
Xip route flush dev "$ipv6_if"
Xlog_end_msg
END-of-scripts/init-bottom/ipv6
exit

… then put something like (with net.ifnames=0 of course)…

	ip=6,0,eth0,debian.example.org,2001:db8::1/128,fe80::1

… in GRUB_CMDLINE_LINUX in /etc/default/grub then regenerate the
initramfs and update-grub and you’ll be set for some use cases,
namely “remotely unlock full disc encryption with dropbear”.

NFS over IPv6 still relies on klibc’s nfsmount utility (which is
also insistent on using Legacy IP).

But this is a start ☻

Enjoy,
//mirabilos