#!/bin/sh
############################################################
# <bsn.cl fy=2013 v=onl>
#
#        Copyright 2013, 2014 BigSwitch Networks, Inc.
#
# Licensed under the Eclipse Public License, Version 1.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
#        http://www.eclipse.org/legal/epl-v10.html
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
# either express or implied. See the License for the specific
# language governing permissions and limitations under the
# License.
#
# </bsn.cl>
############################################################
#
# ifup
#
# Configure a network interface from settings in /etc/onl/NET
# NETDEV: device name
# NETAUTO: autoconfiguration method ("dhcp" or empty)
# NETRETRIES: autoconfiguration timeout
# NETIP: IP address (/prefix optional for v4)
# NETMASK: netmask (if NETIP has no prefix)
# NETGW: default gateway IP address (optional)
# NETDOMAIN: DNS default domain (optional)
# NETDNS: DNS server IP address (optional)
# NETHW: hardware (MAC) address (optional)
#
############################################################

unset NETDEV NETAUTO NETIP NETMASK NETGW NETDOMAIN NETDNS NETHW
. /etc/onl/NET

[ "${NETDEV}" ] || exit

if [ "${NETHW}" ]; then
    ip link set dev ${NETDEV} addr ${NETHW}
fi

# Default DHCP timeout is 10 requests in 10 seconds.
NETRETRIES_DEFAULT=10
NETRETRIES=${NETRETRIES:-$NETRETRIES_DEFAULT}
if [ "$NETRETRIES" = "infinite" ]; then
    NETRETRIES=
elif [ $(echo "$NETRETRIES" | tr -d '[:digit:]') ] || [ "$NETRETRIES" -lt 0 ]; then
    echo "Warning: the NETRETRIES setting is currently '$NETRETRIES'. This is invalid and the default value of $NETRETRIES_DEFAULT will be used instead."
    NETRETRIES=$NETRETRIES_DEFAULT
fi
case "${NETAUTO}" in
    dhcp|auto)
        echo 1 >/proc/sys/net/ipv6/conf/${NETDEV}/autoconf
        if [ -n "${NETRETRIES}" ]; then
            if ! udhcpc --retries $NETRETRIES --now -i ${NETDEV}; then
                echo "**********************************************************************"
                echo "DHCP failed after $NETRETRIES attempts."
                echo "**********************************************************************"
            fi
        else
            while true; do
                if udhcpc --retries $NETRETRIES_DEFAULT --now -i ${NETDEV}; then
                    break
                fi
                echo
                echo "**********************************************************************"
                echo "DHCP failed after $NETRETRIES_DEFAULT attempts."
                echo ""
                echo "No timeout is configured so DHCP requests will continue until successful."
                echo "    Press Ctrl-C to terminate and configure manually."
                echo ""
                echo "**********************************************************************"
            done
        fi
        ;;
    up)
        ifconfig "${NETDEV}" up
        ;;
    *)
        if [ "${NETIP}" ] && [ "${NETMASK}" ] && [ "${NETIP#*/}" = "${NETIP}" ]; then
            NETIP=${NETIP}/$(ipcalc -p -s ${NETIP} ${NETMASK} | sed -n 's/PREFIX=//p')
        fi
        echo 0 >/proc/sys/net/ipv6/conf/${NETDEV}/autoconf
        ip addr  flush dev ${NETDEV}
        ip route flush dev ${NETDEV}

        if [ "${NETIP}" ]; then
            ip addr add ${NETIP} dev ${NETDEV}
        fi
        ip link set ${NETDEV} up
        if [ "${NETGW}" ]; then
            ip route add default via ${NETGW}
        fi
        >/etc/resolv.conf
        if [ "${NETDOMAIN}" ]; then
            echo "search ${NETDOMAIN}" >>/etc/resolv.conf
        fi
        if [ "${NETDNS}" ]; then
            echo "nameserver ${NETDNS}" >>/etc/resolv.conf
        fi
        ;;
esac

#
# If no network settings were applied, bring the interface up for link-local usage.
#
grep -q down "/sys/class/net/${NETDEV}/operstate" || ifconfig "${NETDEV}" up

for i in $(seq 30); do
    (ip -o -6 addr list dev ${NETDEV} | grep tentative >/dev/null) || break
    if [ $i = 5 ]; then
        echo "Waiting for IPv6 duplicate address detection to complete..."
    fi
    sleep 1
done
wait_link_up()
{
    local intf=$1
    local count=$2

    local operstate="/sys/class/net/${intf}/operstate"

    echo "Waiting for link on ${intf}..."
    local i=0
    [ -r $operstate ] && while [ $i -lt $count ] ; do
        intf_operstate="$(cat $operstate)"
        if [ "$intf_operstate" = "up" -o "$intf_operstate" = "unknown" ] ; then
            echo "${intf}: up"
            return 0
        fi
        usleep 100000
        i=$(( $i + 1 ))
    done

    echo "${intf}: down."
    return 1
}

if [ -n "${NETAUTO}" ]; then
    wait_link_up $NETDEV 100
fi
return 0
