add preliminary IPv6 support
authorHarald Hoyer <harald@redhat.com>
Thu, 4 Feb 2010 15:05:19 +0000 (16:05 +0100)
committerHarald Hoyer <harald@redhat.com>
Thu, 4 Feb 2010 15:05:19 +0000 (16:05 +0100)
13 files changed:
dracut.8
modules.d/40network/dhcp-root.sh
modules.d/40network/ifup
modules.d/40network/install
modules.d/40network/installkernel
modules.d/40network/netroot
modules.d/40network/parse-ip-opts.sh
modules.d/45ifcfg/write-ifcfg.sh
modules.d/95debug/install
modules.d/95iscsi/iscsiroot
modules.d/95nfs/nfsroot
modules.d/95nfs/parse-nfsroot.sh
modules.d/99base/dracut-lib.sh

index 1abc690..d82e437 100644 (file)
--- a/dracut.8
+++ b/dracut.8
@@ -236,22 +236,22 @@ only activate the raid sets with the given UUID
 
 .SS Network
 .TP
-.BR ip= {dhcp|on|any|auto6}
+.BR ip= {dhcp|on|any|dhcp6|auto6}
 dhcp|on|any: get ip from dhcp server from all interfaces. If root=dhcp, 
 loop sequentially through all interfaces (eth0, eth1, ...) and use the first 
 with a valid DHCP root-path.
 
-auto6: do ipv6 autoconfiguration
+auto6: do IPv6 autoconfiguration
 .TP
-.BR ip= <interface>:{dhcp|on|any|auto6}
-dhcp|on|any: get ip from dhcp server on a specific interface
+.BR ip= <interface>:{dhcp|on|any|dhcp6|auto6}
+dhcp|on|any|dhcp6: get ip from dhcp server on a specific interface
 
-auto6: do ipv6 autoconfiguration
+auto6: do IPv6 autoconfiguration
 .TP
 .ad l
 .BR ip= "\%<client-IP>\::[<server-id>]\::<gateway-IP>\::<netmask>\::<client\%hostname>\::<interface>\::{none|off}"
 .ad
-explicit network configuration
+explicit network configuration. If you want do define a IPv6 address, put it in brackets (e.g. [2001:DB8::1]).
 .TP
 .BR ifname= <interface>:<MAC>
 Assign network device name <interface> (ie eth0) to the NIC with MAC <MAC>.
@@ -277,7 +277,7 @@ NFS options can be appended with the prefix ":" or "," and are seperated by ",".
 .TP
 .BR root= "nfs4:[<server-ip>:]<root-dir>[:<nfs-options>]"
 .TP
-.BR root= dhcp 
+.BR root= dhcp|dhcp6 
 root=dhcp alone directs initrd to look at the DHCP root-path where NFS 
 options can be specified.
     root-path=<server-ip>:<root-dir>[,<nfs-options>]
index 8e51ed8..644b5ef 100755 (executable)
@@ -7,13 +7,15 @@
 [ -z "$root" ] && root=$(getarg root=)
 [ -z "$netroot" ] && netroot=$(getarg netroot=)
 
-if [ "$root" = "dhcp" ] || [ "$netroot" = "dhcp" ] ; then
+if [ "$root" = "dhcp" ] || [ "$root" = "dhcp6" ] || [ "$netroot" = "dhcp" ] ; then
     # Tell ip= checker that we need dhcp
     NEEDDHCP="1"
 
     # Done, all good!
     rootok=1
-    netroot=dhcp
+    if [ "$netroot" != "dhcp" ] ; then
+       netroot=$root
+    fi
 
     # Shut up init error check
     [ -z "$root" ] && root="dhcp"
index 419c2ca..e2237ef 100755 (executable)
@@ -3,45 +3,75 @@
 # We don't need to check for ip= errors here, that is handled by the
 # cmdline parser script
 #
+PATH=$PATH:/sbin:/usr/sbin
 
-# Sadly there's no easy way to split ':' separated lines into variables
-ip_to_var() {
-    local v=${1}:
-    set --
-    while [ -n "$v" ]; do
-       set -- "$@" "${v%%:*}"
-       v=${v#*:}
-    done
-
-    unset ip srv gw mask hostname dev autoconf
-    case $# in
-    0) autoconf="error" ;;
-    1) autoconf=$1 ;;
-    2) dev=$1; autoconf=$2 ;;
-    *) ip=$1; srv=$2; gw=$3; mask=$4; hostname=$5; dev=$6; autoconf=$7 ;;
-    esac
-}
+. /lib/dracut-lib.sh
 
 # Run dhclient
 do_dhcp() {
     # /sbin/dhclient-script will mark the netif up and generate the online
     # event for nfsroot
     # XXX add -V vendor class and option parsing per kernel
-    dhclient -1 -q -cf /etc/dhclient.conf -pf /tmp/dhclient.$netif.pid -lf /tmp/dhclient.$netif.lease $netif
+    dhclient "$@" -1 -q -cf /etc/dhclient.conf -pf /tmp/dhclient.$netif.pid -lf /tmp/dhclient.$netif.lease $netif
+}
+
+load_ipv6() {
+    modprobe ipv6
+    i=0
+    while [ ! -d /proc/sys/net/ipv6 ]; do
+       i=$(($i+1))
+       [ $i -gt 10 ] && break
+       sleep 0.1
+    done
+}
+
+do_ipv6auto() {
+    load_ipv6
+    {
+        echo 0 > /proc/sys/net/ipv6/conf/$netif/forwarding 
+        echo 1 > /proc/sys/net/ipv6/conf/$netif/accept_ra
+        echo 1 > /proc/sys/net/ipv6/conf/$netif/accept_redirects
+       echo ip link set $netif up 
+       echo wait_for_if_up $netif
+    } > /tmp/net.$netif.up
+
+    [ -n "$hostname" ] && echo "echo $hostname > /proc/sys/kernel/hostname" > /tmp/net.$netif.hostname
+
+    namesrv=$(getargs nameserver)
+    if  [ -n "$namesrv" ] ; then
+       for s in $namesrv; do
+           echo nameserver $s 
+       done
+    fi >> /tmp/net.$netif.resolv.conf
+
+
+    echo online > /sys/class/net/$netif/uevent
+    /sbin/initqueue --onetime --name netroot-$netif  /sbin/netroot $netif 
 }
 
 # Handle static ip configuration
 do_static() {
+    strstr $ip '*:*:*' && load_ipv6
+
     {
        echo ip link set $netif up 
        echo wait_for_if_up $netif
-       echo ip addr flush dev $netif
+       # do not flush addr for ipv6
+       strstr $ip '*:*:*' || \
+           echo ip addr flush dev $netif
        echo ip addr add $ip/$mask dev $netif
     } > /tmp/net.$netif.up
 
     [ -n "$gw" ] && echo ip route add default via $gw dev $netif > /tmp/net.$netif.gw
     [ -n "$hostname" ] && echo "echo $hostname > /proc/sys/kernel/hostname" > /tmp/net.$netif.hostname
 
+    namesrv=$(getargs nameserver)
+    if  [ -n "$namesrv" ] ; then
+       for s in $namesrv; do
+           echo nameserver $s 
+       done
+    fi >> /tmp/net.$netif.resolv.conf
+
     echo online > /sys/class/net/$netif/uevent
     /sbin/initqueue --onetime --name netroot-$netif  /sbin/netroot $netif 
 }
@@ -99,7 +129,14 @@ fi
 
 # No ip lines default to dhcp
 ip=$(getarg ip)
-[ -z "$ip" ] && do_dhcp;
+
+if [ -z "$ip" ]; then
+    if [ "$netroot" = "dhcp6" ]; then
+       do_dhcp -6
+    else
+       do_dhcp -4
+    fi
+fi
 
 # Specific configuration, spin through the kernel command line
 # looking for ip= lines
@@ -115,9 +152,16 @@ for p in $(getargs ip=); do
     done > /tmp/net.$netif.override
 
     case $autoconf in
-       dhcp|on|any)     do_dhcp ;;
-        *) do_static ;;
+       dhcp|on|any)
+           do_dhcp -4 ;;
+       dhcp6)
+           do_dhcp -6 ;;
+       auto6)
+           do_ipv6auto ;;
+        *) 
+           do_static ;;
     esac
     break
 done
+
 exit 0
index 8421af9..398d4e4 100755 (executable)
@@ -11,3 +11,18 @@ inst_hook cmdline 99 "$moddir/parse-ip-opts.sh"
 inst_hook cmdline 98 "$moddir/parse-bridge.sh"
 inst_hook cmdline 99 "$moddir/parse-ifname.sh"
 inst_hook pre-pivot 10 "$moddir/kill-dhclient.sh"
+
+if ldd $(which sh) | grep -q lib64; then
+    LIBDIR="/lib64"
+else
+    LIBDIR="/lib"
+fi
+
+ARCH=$(uname -m)
+
+for dir in /usr/$LIBDIR/tls/$ARCH/ /usr/$LIBDIR/tls/ /usr/$LIBDIR/$ARCH/ /usr/$LIBDIR/ /$LIBDIR/; do
+    for i in $(ls $dir/libnss_dns.so.* $dir/libnss_mdns4_minimal.so.* 2>/dev/null); do
+       dracut_install $i
+    done
+done
+
index eb88ecd..514902d 100755 (executable)
@@ -14,3 +14,4 @@ instmods $(filter_kernel_modules net_module_test)
 instmods ecb arc4
 # bridge modules
 instmods bridge stp llc
+instmods ipv6
index f1a98df..6a24d41 100755 (executable)
@@ -31,7 +31,7 @@ netif=$1
 
 # Figure out the handler for root=dhcp by recalling all netroot cmdline 
 # handlers
-if [ "$netroot" = "dhcp" ] ; then
+if [ "$netroot" = "dhcp" ] || [ "$netroot" = "dhcp6" ] ; then
     # Unset root so we can check later
     unset root
 
index 8db9fb5..327ba5e 100755 (executable)
 # routing,dns,dhcp-options,etc.
 #
 
-# Sadly there's no easy way to split ':' separated lines into variables
-ip_to_var() {
-    local v=${1}:
-    set --
-    while [ -n "$v" ]; do
-       set -- "$@" "${v%%:*}"
-       v=${v#*:}
-    done
-
-    unset ip srv gw mask hostname dev autoconf
-    case $# in
-    0) autoconf="error" ;;
-    1) autoconf=$1 ;;
-    2) dev=$1; autoconf=$2 ;;
-    *) ip=$1; srv=$2; gw=$3; mask=$4; hostname=$5; dev=$6; autoconf=$7 ;;
-    esac
-}
+. /lib/dracut-lib.sh
 
 # Check if ip= lines should be used
 if getarg ip= >/dev/null ; then
index f75c94f..f5989ef 100644 (file)
@@ -15,39 +15,49 @@ for netif in $IFACES ; do
         bridge=yes
     fi
     cat /sys/class/net/$netif/address > /tmp/net.$netif.hwaddr
-    echo "# Generated by dracut initrd" > /tmp/ifcfg/ifcfg-$netif
-    echo "DEVICE=$netif" >> /tmp/ifcfg/ifcfg-$netif
-    echo "ONBOOT=yes" >> /tmp/ifcfg/ifcfg-$netif
-    echo "NETBOOT=yes" >> /tmp/ifcfg/ifcfg-$netif
-    if [ -f /tmp/net.$netif.lease ]; then
-       echo "BOOTPROTO=dhcp" >> /tmp/ifcfg/ifcfg-$netif
-    else
-       echo "BOOTPROTO=none" >> /tmp/ifcfg/ifcfg-$netif
+    {
+       echo "# Generated by dracut initrd" 
+       echo "DEVICE=$netif"
+       echo "ONBOOT=yes"
+       echo "NETBOOT=yes"
+       if [ -f /tmp/net.$netif.lease ]; then
+           strstr "$ip" '*:*:*' &&
+           echo "DHCPV6C=yes" 
+           echo "BOOTPROTO=dhcp" 
+       else
+           echo "BOOTPROTO=none" 
         # If we've booted with static ip= lines, the override file is there
-       . /tmp/net.$netif.override 
-       echo "IPADDR=$ip" >> /tmp/ifcfg/ifcfg-$netif
-       echo "NETMASK=$mask" >> /tmp/ifcfg/ifcfg-$netif
-       [ -n "$gw" ] && echo "GATEWAY=$gw" >> /tmp/ifcfg/ifcfg-$netif
-    fi
+           . /tmp/net.$netif.override 
+           echo "IPADDR=$ip"
+           echo "NETMASK=$mask"
+           [ -n "$gw" ] && echo "GATEWAY=$gw"
+       fi
+    } > /tmp/ifcfg/ifcfg-$netif
 
     # bridge needs different things written to ifcfg
     if [ -z "$bridge" ]; then
         # standard interface
-        echo "HWADDR=$(cat /sys/class/net/$netif/address)" >> /tmp/ifcfg/ifcfg-$netif
-        echo "TYPE=Ethernet" >> /tmp/ifcfg/ifcfg-$netif
-        echo "NAME=\"Boot Disk\"" >> /tmp/ifcfg/ifcfg-$netif
+       {
+            echo "HWADDR=$(cat /sys/class/net/$netif/address)"
+            echo "TYPE=Ethernet"
+            echo "NAME=\"Boot Disk\"" 
+       } >> /tmp/ifcfg/ifcfg-$netif
     else
         # bridge
-       echo "TYPE=Bridge" >> /tmp/ifcfg/ifcfg-$netif
-        echo "NAME=\"Boot Disk\"" >> /tmp/ifcfg/ifcfg-$netif
+       {
+           echo "TYPE=Bridge"
+            echo "NAME=\"Boot Disk\"" 
+       } >> /tmp/ifcfg/ifcfg-$netif
         # write separate ifcfg file for the raw eth interface
-        echo "DEVICE=$ethname" >> /tmp/ifcfg/ifcfg-$ethname
-        echo "TYPE=Ethernet" >> /tmp/ifcfg/ifcfg-$ethname
-        echo "ONBOOT=yes" >> /tmp/ifcfg/ifcfg-$ethname
-        echo "NETBOOT=yes" >> /tmp/ifcfg/ifcfg-$ethname
-        echo "HWADDR=$(cat /sys/class/net/$ethname/address)" >> /tmp/ifcfg/ifcfg-$ethname
-        echo "BRIDGE=$netif" >> /tmp/ifcfg/ifcfg-$ethname
-        echo "NAME=$ethname" >> /tmp/ifcfg/ifcfg-$ethname
+       {
+            echo "DEVICE=$ethname"
+            echo "TYPE=Ethernet"
+            echo "ONBOOT=yes"
+            echo "NETBOOT=yes"
+            echo "HWADDR=$(cat /sys/class/net/$ethname/address)"
+            echo "BRIDGE=$netif"
+            echo "NAME=$ethname" 
+       } >> /tmp/ifcfg/ifcfg-$ethname
     fi
 done
 
index cd8c48c..b9ddee4 100755 (executable)
@@ -1,3 +1,3 @@
 #!/bin/bash
 dracut_install -o ps grep more cat rm strace free showmount 
-dracut_install -o ping netstat rpcinfo vi scp
+dracut_install -o ping netstat rpcinfo vi scp ping6 ssh
index 7679a15..308faa4 100755 (executable)
@@ -88,15 +88,31 @@ if [ $# -gt 1 ]; then
         fi
     fi
 fi  
-IFS=:
-set $iroot
+
+IFS="$OLDIFS"
+
+local v=${iroot}:
+local i
+set -- 
+while [ -n "$v" ]; do
+    if [ "${v#\[*:*:*\]:}" != "$v" ]; then
+       # handle IPv6 address
+       i="${v%%\]:*}"
+       i="${i##\[}"
+       set -- "$@" "$i"
+       v=${v#\[$i\]:}
+    else                   
+       set -- "$@" "${v%%:*}"
+       v=${v#*:}
+    fi
+done
 iscsi_target_ip=$1; shift
 iscsi_protocol=$1; shift # ignored
 iscsi_target_port=$1; shift
 iscsi_lun=$1; shift
+IFS=:
 iscsi_target_name=$*
-IFS="$OLDIFS"
-
+IFS=$OLDIFS
 # XXX is this needed?
 getarg ro && iscsirw=ro
 getarg rw && iscsirw=rw
index 4d86bc8..39d5b0c 100755 (executable)
@@ -1,43 +1,5 @@
 #!/bin/sh
 
-# Copy from parse-nfsroot.sh
-root_to_var() {
-    local v=${1}:
-    set --
-    while [ -n "$v" ]; do
-       set -- "$@" "${v%%:*}"
-       v=${v#*:}
-    done
-
-    unset nfs server path options
-
-    # Ugly: Can't -z test $path after the case, since it might be allowed
-    # to be empty for root=nfs
-    nfs=$1
-    case $# in
-    0|1);;
-    2) path=$2;;
-    3)
-    # This is ultra ugly. But we can't decide in which position path
-    # sits without checking if the string starts with '/'
-    case $2 in
-       /*) path=$2; options=$3;;
-       *) server=$2; path=$3;;
-    esac
-    ;;
-    *) server=$2; path=$3; options=$4;
-    esac
-    
-    # Does it really start with '/'?
-    [ -n "${path%%/*}" ] && path="error";
-    
-    #Fix kernel legacy style separating path and options with ','
-    if [ "$path" != "${path#*,}" ] ; then
-       options=${path#*,}
-       path=${path%%,*}
-    fi
-}
-
 . /lib/dracut-lib.sh
 
 PATH=$PATH:/sbin:/usr/sbin
@@ -63,7 +25,7 @@ case "${root%%:*}" in
     *) return;;
 esac
 
-root_to_var $root
+nfsroot_to_var $root
 
 #Load other data that might provide info
 [ -f /tmp/net.$netif.override ] && . /tmp/net.$netif.override
@@ -71,7 +33,7 @@ root_to_var $root
 
 #Empty path means try dhcp root-path, this is ok here since parse-nfsroot.sh
 #already takes care of nfs:... formatted root-path
-[ -z "$path" ] && root_to_var $nfs:$new_root_path
+[ -z "$path" ] && nfsroot_to_var $nfs:$new_root_path
 
 #Empty path defaults to "/tftpboot/%s" only in nfsroot.txt legacy mode
 [ -z "$path" ] && [ "$(getarg root=)" = "/dev/nfs" ] && path="/tftpboot/%s"
index 6300351..bcf3465 100755 (executable)
 # NFSv3 is used.
 #
 
-# Sadly there's no easy way to split ':' separated lines into variables
-netroot_to_var() {
-    local v=${1}:
-    set --
-    while [ -n "$v" ]; do
-       set -- "$@" "${v%%:*}"
-       v=${v#*:}
-    done
-
-    unset nfs server path options
-
-    nfs=$1
-    # Ugly: Can't -z test #path after the case, since it might be allowed
-    # to be empty for root=nfs
-    case $# in
-    0|1);;
-    2) path=${2:-error};;
-    3)
-    # This is ultra ugly. But we can't decide in which position path
-    # sits without checking if the string starts with '/'
-    case $2 in
-       /*) path=$2; options=$3;;
-       *) server=$2; path=${3:-error};;
-    esac
-    ;;
-    *) server=$2; path=${3:-error}; options=$4;
-    esac
-    
-    # Does it really start with '/'?
-    [ -n "${path%%/*}" ] && path="error";
-    
-    #Fix kernel legacy style separating path and options with ','
-    if [ "$path" != "${path#*,}" ] ; then
-       options=${path#*,}
-       path=${path%%,*}
-    fi
-}
+. /lib/dracut-lib.sh
 
 #Don't continue if root is ok
 [ -n "$rootok" ] && return
@@ -105,7 +69,7 @@ case "${netroot%%:*}" in
 esac
 
 # Check required arguments
-netroot_to_var $netroot
+nfsroot_to_var $netroot
 [ "$path" = "error" ] && die "Argument nfsroot must contain a valid path!"
 
 # Set fstype, might help somewhere
index 5b2b2c1..100219e 100644 (file)
@@ -1,3 +1,9 @@
+
+# returns OK if $1 contains $2
+strstr() {
+  [ "${1#*$2*}" != "$1" ]
+}
+
 getarg() {
     local o line
     if [ -z "$CMDLINE" ]; then
@@ -50,6 +56,7 @@ setdebug() {
     [ "$RDDEBUG" = "yes" ] && set -x 
 }
 
+setdebug
 
 source_all() {
     local f
@@ -171,3 +178,65 @@ wait_for_if_up() {
     done 
     return 1
 }
+
+# root=nfs:[<server-ip>:]<root-dir>[:<nfs-options>] 
+# root=nfs4:[<server-ip>:]<root-dir>[:<nfs-options>]
+nfsroot_to_var() {
+    # strip nfs[4]:
+    local arg="$@:"
+    nfs="${arg%%:*}"
+    arg="${arg##$nfs:}"
+    # check for server
+    local OLDIFS="$IFS"
+
+    # check if we have a server
+    if strstr "$arg" ':/*' ; then
+       server="${arg%%:/*}"
+       arg="/${arg##*:/}"
+    fi
+
+    path="${arg%%:*}"
+
+    # rest are options
+    options="${arg##$path}"
+    # strip leading ":"
+    options="${options##:}"
+    # strip  ":"
+    options="${options%%:}"
+    
+    # Does it really start with '/'?
+    [ -n "${path%%/*}" ] && path="error";
+    
+    #Fix kernel legacy style separating path and options with ','
+    if [ "$path" != "${path#*,}" ] ; then
+       options=${path#*,}
+       path=${path%%,*}
+    fi
+}
+
+ip_to_var() {
+    local v=${1}:
+    local i
+    set -- 
+    while [ -n "$v" ]; do
+       if [ "${v#\[*:*:*\]:}" != "$v" ]; then
+           # handle IPv6 address
+           i="${v%%\]:*}"
+           i="${i##\[}"
+           set -- "$@" "$i"
+           v=${v#\[$i\]:}
+       else                
+           set -- "$@" "${v%%:*}"
+           v=${v#*:}
+       fi
+    done
+
+    unset ip srv gw mask hostname dev autoconf
+    case $# in
+    0) autoconf="error" ;;
+    1) autoconf=$1 ;;
+    2) dev=$1; autoconf=$2 ;;
+    *) ip=$1; srv=$2; gw=$3; mask=$4; hostname=$5; dev=$6; autoconf=$7 ;;
+    esac
+}
+