commit:     d3b5d78c5f3696aaf841d7900e69a37de29cfc25
Author:     Daniel Solano Gómez <daniel <AT> solanogomez <DOT> org>
AuthorDate: Sat Apr  6 00:13:12 2013 +0000
Commit:     Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Tue Jun  2 21:24:24 2020 +0000
URL:        https://gitweb.gentoo.org/proj/netifrc.git/commit/?id=d3b5d78c

dhclientv6: Add DHCPv6 support via dhclient

This adds DHCPv6 support to OpenRC in Linux using dhclient as outlined
by Stuart Longland at 
<http://stuartl.longlandclan.yi.org/blog/2011/02/15/gentoo-and-dhcpv6/>.
The main place where the new support is added is via a modified copy of
the dhclient.sh script that:

- Renames functions using a 'v6' suffix
- Uses a different pid file
- Uses the '-6' argument when invoking dhclient
- Recognizes new DHCPv6-specific configuration variables with a fallback
  to the DHCP configuration variables.

Additionally:

1. The iproute2 and Linux ifconfig scripts have been ammended to be able
to return IPv6 addresses using new '_get_inet6_address' and
'_get_inet6_addresses' functions.

2. The 'net.lo' init script now has a '_show_address6' function.

3. The documentation in the Linux net.example now contains some DHCPv6
information.

Reported-by: Dustin C. Hatch <admiralnemo <AT> gmail.com>
X-Gentoo-Bug: 150908
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=150908
Signed-off-by: Robin H. Johnson <robbat2 <AT> gentoo.org>
(cherry picked from commit bd7bd3a513c8ddc554e211316c990b5f98110982)
Closes: https://bugs.gentoo.org/450326
Signed-off-by: Robin H. Johnson <robbat2 <AT> gentoo.org>

 doc/net.example.Linux.in | 35 +++++++++++++++++++++
 init.d/net.lo.in         |  4 +++
 net/Makefile             |  2 +-
 net/dhclientv6.sh        | 82 ++++++++++++++++++++++++++++++++++++++++++++++++
 net/ifconfig.sh.Linux.in | 26 +++++++++++++--
 net/iproute2.sh          | 19 +++++++++--
 6 files changed, 162 insertions(+), 6 deletions(-)

diff --git a/doc/net.example.Linux.in b/doc/net.example.Linux.in
index a2993c0..53d9e84 100644
--- a/doc/net.example.Linux.in
+++ b/doc/net.example.Linux.in
@@ -518,6 +518,41 @@
 # You can use any combination of the above options - the default is not to
 # use any of them.
 
+#-----------------------------------------------------------------------------
+# DHCPv6
+# DHCPv6 can be provided by dhclient
+#
+# dhclient: emerge net-misc/dhcp
+#
+# If you have more than one DHCP client installed, you should probably
+# explicitly use 'dhclient' to use dhclient for both DHCP and DHCPv6,
+# otherwise the default DHCP client will be used.  dhcpcd has some stateless
+# IPv6 autoconfiguration support which may clash with DHCPv6.
+#modules="dhclient" # to select dhclient over dhcpcd
+
+# Regardless of which DHCP client you prefer, you configure them the
+# same way using one of following depending on which interface modules
+# you're using.
+#config_eth0="dhcpv6"
+
+# You can also use both DHCP and DHCPv6 on a dual-stack network:
+#config_eth0="dhcp
+#dhcpv6"
+
+# To pass runtime arguments to dhclient for DHCPv6, you do it similarly to
+# setting runtime arguments for DHCP.  Note that you can set options for
+# DHCPv6 separately or in addition the dhclient arguments for DHCP.
+#dhclientv6_eth0="..." # options for DHCPv6 only
+#dhclient_eth0='..."   # options for DHCP (also for DHCPv6 when no
+#                      # dhclientv6_eth0 is defined)
+
+# GENERIC DHCPv6 OPTIONS
+# Set generic DHCPv6 options just as with generic DHCP options.
+#dhcpv6_eth0="release nodns nontp nonis nogateway nosendhost"
+
+# If no generic DHCPv6 options are set, the default is to fall back to the
+# DHCP generic options.
+
 #-----------------------------------------------------------------------------
 # For APIPA support, emerge net-misc/iputils or net-analyzer/arping
 

diff --git a/init.d/net.lo.in b/init.d/net.lo.in
index a5ac0fe..3ab83b2 100644
--- a/init.d/net.lo.in
+++ b/init.d/net.lo.in
@@ -295,6 +295,10 @@ _get_errorhandler_behavior() {
                        echo "$value" && break
                fi
        done
+
+_show_address6()
+{
+       einfo "received address $(_get_inet6_address "${IFACE}")"
 }
 
 # Basically sorts our modules into order and saves the list

diff --git a/net/Makefile b/net/Makefile
index dab94f9..ee48294 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -14,7 +14,7 @@ INC-Linux=    adsl.sh apipa.sh arping.sh bonding.sh 
br2684ctl.sh bridge.sh \
                ccwgroup.sh clip.sh ethtool.sh iproute2.sh ifplugd.sh ip6to4.sh 
\
                ipppd.sh iwconfig.sh netplugd.sh pppd.sh pump.sh tuntap.sh 
udhcpc.sh \
                vlan.sh macvlan.sh ip6rd.sh firewalld.sh dummy.sh hsr.sh 
l2tp.sh \
-               iw.sh wireguard.sh veth.sh
+               iw.sh wireguard.sh veth.sh dhclientv6.sh
 
 SRCS-NetBSD= ifwatchd.sh.in
 INC-NetBSD=    ifwatchd.sh

diff --git a/net/dhclientv6.sh b/net/dhclientv6.sh
new file mode 100644
index 0000000..f87ed4d
--- /dev/null
+++ b/net/dhclientv6.sh
@@ -0,0 +1,82 @@
+# Copyright (c) 2007-2008 Roy Marples <r...@marples.name>
+# Released under the 2-clause BSD license.
+
+dhclientv6_depend()
+{
+       after interface
+       program start /sbin/dhclient
+       provide dhcpv6
+}
+
+_config_vars="$_config_vars dhcp dhclient dhcpv6 dhclientv6"
+
+dhclientv6_start()
+{
+       local args= opt= opts= pidfile="/var/run/dhclientv6-${IFACE}.pid"
+       local sendhost=true dconf=
+
+       # Get our options
+       # These options only work in Gentoo, and maybe RedHat
+       eval args=\$dhclientv6_${IFVAR}
+       [ -z "${args}" ] && eval args=\$dhclient_${IFVAR}
+       eval opts=\$dhcpv6_${IFVAR}
+       [ -z "${opts}" ] && opts=${dhcpv6}
+       [ -z "${opts}" ] && eval opts=\$dhcp_${IFVAR}
+       [ -z "${opts}" ] && opts=${dhcp}
+
+       for opt in ${opts}; do
+               case "${opt}" in
+                       nodns) args="${args} -e PEER_DNS=no";;
+                       nontp) args="${args} -e PEER_NTP=no";;
+                       nogateway) args="${args} -e PEER_ROUTERS=no";;
+                       nosendhost) sendhost=false;;
+               esac
+       done
+
+       # Add our route metric
+       [ "${metric:-0}" != "0" ] && args="${args} -e IF_METRIC=${metric}"
+
+       if ${sendhost}; then
+               local hname="$(hostname)"
+               if [ "${hname}" != "(none)" -a "${hname}" != "localhost" ]; then
+                       dhconf="${dhconf} interface \"${IFACE}\" {"
+                       dhconf="${dhconf} send fqdn.fqdn \"${hname}\";"
+                       dhconf="${dhconf} send fqdn.encoded on;"
+                       dhconf="${dhconf} send fqdn.server-update on;"
+                       dhconf="${dhconf} send fqdn.no-client-update on;"
+                       dhconf="${dhconf}}"
+               fi
+       fi
+
+       # Bring up DHCP for this interface
+       ebegin "Running dhclient -6"
+       echo "${dhconf}" | start-stop-daemon --start --exec /sbin/dhclient \
+               --pidfile "${pidfile}" \
+               -- -6 ${args} -q -1 -pf "${pidfile}" "${IFACE}"
+       eend $? || return 1
+
+       _show_address6
+       return 0
+}
+
+dhclientv6_stop()
+{
+       local pidfile="/var/run/dhclientv6-${IFACE}.pid" opts=
+       [ ! -f "${pidfile}" ] && return 0
+
+       # Get our options
+       if [ -x /sbin/dhclient ]; then
+               eval opts=\$dhcp_${IFVAR}
+               [ -z "${opts}" ] && opts=${dhcp}
+       fi
+
+       ebegin "Stopping dhclient -6 on ${IFACE}"
+       case " ${opts} " in
+               *" release "*) dhclient -6 -q -r -pf "${pidfile}" "${IFACE}";;
+               *)
+                       start-stop-daemon --stop --quiet \
+                               --exec /sbin/dhclient --pidfile "${pidfile}"
+                       ;;
+       esac
+       eend $?
+}

diff --git a/net/ifconfig.sh.Linux.in b/net/ifconfig.sh.Linux.in
index 09708a9..960b239 100644
--- a/net/ifconfig.sh.Linux.in
+++ b/net/ifconfig.sh.Linux.in
@@ -87,21 +87,41 @@ _get_inet_address()
        echo "/$(_netmask2cidr "$1")"
 }
 
-_get_inet_addresses()
+_get_inet6_address()
+{
+       set -- $(LC_ALL=C ifconfig "${IFACE}" |
+       sed -n -e 's/.*\(inet6 addr:\|inet6\) \([^ /]*\)\(\/\| *prefixlen 
\)\([^ ]*\).*/\2\/\4/p')
+       [ -z "$1" ] && return 1
+
+       echo -n "$1"
+}
+
+_get_addresses_fn()
 {
+       local fn="$1"
        local iface=${IFACE} i=0
-       local addrs="$(_get_inet_address)"
+       local addrs="$($fn)"
 
        while true; do
                local IFACE="${iface}:${i}"
                _exists || break
-               local addr="$(_get_inet_address)"
+               local addr="$($fn)"
                [ -n "${addr}" ] && addrs="${addrs}${addrs:+ }${addr}"
                : $(( i += 1 ))
        done
        echo "${addrs}"
 }
 
+_get_inet_addresses()
+{
+       _get_addresses_fn _get_inet_address
+}
+
+_get_inet6_addresses()
+{
+       _get_addresses_fn _get_inet6_address
+}
+
 _cidr2netmask()
 {
        local cidr="$1" netmask="" done=0 i=0 sum=0 cur=128

diff --git a/net/iproute2.sh b/net/iproute2.sh
index ca6c0f8..d19f79d 100644
--- a/net/iproute2.sh
+++ b/net/iproute2.sh
@@ -92,8 +92,16 @@ _set_mac_address()
 
 _get_inet_addresses()
 {
-       LC_ALL=C ip -family inet addr show "${IFACE}" | \
-       sed -n -e 's/.*inet \([^ ]*\).*/\1/p'
+       local family="$1";
+       if [ -z "$family" ]; then
+               family="inet"
+       fi
+       LC_ALL=C ip -family $family addr show "${IFACE}" | \
+       sed -n -e 's/.*inet6\? \([^ ]*\).*/\1/p'
+}
+
+_get_inet6_addresses() {
+       _get_inet_addresses "inet6"
 }
 
 _get_inet_address()
@@ -103,6 +111,13 @@ _get_inet_address()
        echo "$1"
 }
 
+_get_inet6_address()
+{
+       set -- $(_get_inet6_addresses)
+       [ $# = "0" ] && return 1
+       echo "$1"
+}
+
 _add_address()
 {
        if [ "$1" = "127.0.0.1/8" -a "${IFACE}" = "lo" ]; then

Reply via email to