#!/bin/sh
#
# We don't need to check for ip= errors here, that is handled by the
# cmdline parser script
#
PATH=$PATH:/sbin:/usr/sbin

export PS4="ifup.$1.$$ + "

. /lib/dracut-lib.sh

[ "$RDDEBUG" = "yes" ] \
    && [ -e /dev/initlog.pipe ] \
    && exec >>/dev/initlog.pipe 2>>/dev/initlog.pipe

# 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
    #echo "Starting dhcp for interface $netif"
    ip link set $netif up
    wait_for_if_up $netif
    [ -n "$macaddr" ] && ip link set address $macaddr dev $netif
    [ -n "$mtu" ] && ip link set mtu $mtu dev $netif
    dhclient "$@" -1 -q -cf /etc/dhclient.conf -pf /tmp/dhclient.$netif.pid -lf /tmp/dhclient.$netif.lease $netif &

    # increase wait time for DHCP
    echo '[ $(($RDRETRY-$main_loop)) -lt 720 ] && RDRETRY=$(($main_loop+720)); rm -f "$job"' > /initqueue/rd_retry_inc_dhclient.$netif.sh

    #|| echo "dhcp failed"
}

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
	ip link set $netif up 
	wait_for_if_up $netif
        [ -n "$macaddr" ] && ip link set address $macaddr dev $netif
        [ -n "$mtu" ] && ip link set mtu $mtu dev $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

    {
	ip link set $netif up 
	wait_for_if_up $netif
        [ -n "$macaddr" ] && ip link set address $macaddr dev $netif
        [ -n "$mtu" ] && ip link set mtu $mtu dev $netif
	# do not flush addr for ipv6
	#strstr $ip '*:*:*' || \
	#    ip addr flush dev $netif
	ip addr add $ip/$mask brd + 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 
}

get_vid() {
    case "$1" in
        vlan*)
            echo ${1#vlan}
            ;;
        *.*)
            echo ${1##*.}
            ;;
    esac
}

# Huh? No $1?
[ -z "$1" ] && exit 1

# $netif reads easier than $1
netif=$1

# check, if we need VLAN's for this interface
if [ -z "$DO_VLAN_PHY" ] && [ -e /tmp/vlan.${netif}.phy ]; then
    NO_AUTO_DHCP=yes DO_VLAN_PHY=yes ifup "$netif"
    modprobe -b -q 8021q

    for i in /tmp/vlan.*.${netif}; do
        [ -e "$i" ] || continue
        read vlanname < "$i"
        if [ -n "$vlanname" ]; then
            ip link set "$netif" up
            wait_for_if_up "$netif"
            ip link add dev "$vlanname" link "$netif" type vlan id "$(get_vid $vlanname)"
            ifup "$vlanname"
        fi
    done
    exit 0
fi

# enslave this interface to bond?
if [ -e /tmp/bond.info ]; then
    . /tmp/bond.info
    for slave in $bondslaves ; do
        if [ "$netif" = "$slave" ] ; then
            netif=$bondname
        fi
    done
fi

# bridge this interface?
if [ -e /tmp/bridge.info ]; then
    . /tmp/bridge.info
    if [ "$netif" = "$ethname" ]; then
        if [ "$netif" = "$bondname" ] && [ -n "$DO_BOND_SETUP" ] ; then
            : # We need to really setup bond (recursive call)
        else
            netif="$bridgename"
        fi
    fi
fi


# bail immediately if the interface is already up
# or we don't need the network
[ -f "/tmp/net.$netif.up" ] && exit 0
[ -f "/tmp/root.info" ] || exit 0
. /tmp/root.info
[ -z "$netroot" ] && exit 0

# loopback is always handled the same way
if [ "$netif" = "lo" ] ; then
    ip link set lo up
    ip addr add 127.0.0.1/8 dev lo
    >/tmp/net.$netif.up
    exit 0
fi

# start bond if needed
if [ -e /tmp/bond.info ]; then
    . /tmp/bond.info

    if [ "$netif" = "$bondname" ] && [ ! -e /tmp/net.$bondname.up ] ; then # We are master bond device
        modprobe bonding
        echo "+$netif" >  /sys/class/net/bonding_masters
        ip link set $netif down

        # Stolen from ifup-eth
        # add the bits to setup driver parameters here
        for arg in $bondoptions ; do
            key=${arg%%=*};
            value=${arg##*=};
            # %{value:0:1} is replaced with non-bash specific construct
            if [ "${key}" = "arp_ip_target" -a "${#value}" != "0" -a "+${value%%+*}" != "+" ]; then
                OLDIFS=$IFS;
                IFS=',';
                for arp_ip in $value; do
                    echo +$arp_ip > /sys/class/net/${netif}/bonding/$key
                done
                IFS=$OLDIFS;
            else
                echo $value > /sys/class/net/${netif}/bonding/$key
            fi
        done

        ip link set $netif up

        for slave in $bondslaves ; do
            ip link set $slave down
            ifenslave $bondname $slave
            ip link set $slave up
            wait_for_if_up $slave
        done

        # add the bits to setup the needed post enslavement parameters
        for arg in $BONDING_OPTS ; do
            key=${arg%%=*};
            value=${arg##*=};
            if [ "${key}" = "primary" ]; then
                echo $value > /sys/class/net/${netif}/bonding/$key
            fi
        done
    fi
fi


# XXX need error handling like dhclient-script

# start bridge if necessary
if [ "$netif" = "$bridgename" ] && [ ! -e /tmp/net.$bridgename.up ]; then
    if [ "$ethname" = "$bondname" ] ; then
        DO_BOND_SETUP=yes /sbin/ifup $bondname
    else
        ip link set $ethname up
    fi
    wait_for_if_up $ethname
    # Create bridge and add eth to bridge
    brctl addbr $bridgename
    brctl setfd $bridgename 0
    brctl addif $bridgename $ethname
fi


# No ip lines default to dhcp
ip=$(getarg ip)

if [ -z "$NO_AUTO_DHCP" ] && [ -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
for p in $(getargs ip=); do
    ip_to_var $p

    # If this option isn't directed at our interface, skip it
    [ -n "$dev" ] && [ "$dev" != "$netif" ] && continue

    # skip ibft
    if [ "$autoconf" = "ibft" ]; then
        if [ -n "$mtu" ] || mtu=$(getarg "mtu="); then
            ip link set mtu $mtu dev $netif
        fi
        continue
    fi

    # Store config for later use
    for i in ip srv gw mask hostname macaddr mtu; do
	eval '[ "$'$i'" ] && echo '$i'="$'$i'"'
    done > /tmp/net.$netif.override

    OLDIFS="$IFS"
    IFS=,
    set -- $autoconf
    IFS="$OLDIFS"

    for autoconf in "$@"; do
	case $autoconf in
	    dhcp|on|any)
		do_dhcp -4 ;;
	    dhcp6)
		do_dhcp -6 ;;
	    auto6)
		do_ipv6auto ;;
            *)
		do_static ;;
	esac
    done
    break
done

exit 0
