#!/bin/sh
# vim: set tabstop=4 shiftwidth=4 expandtab:
#
# $Id$
#

# PROVIDE: ya-netif
# REQUIRE: atm1 cleanvar FILESYSTEMS serial sppp sysctl
# REQUIRE: ipfilter ipfs
# REQUIRE: netif
# KEYWORD: nojail
# BEFORE: NETWORKING

. /etc/ya.subr
_init_variables

name="ya-netif"
start_cmd="ya_network_start"
stop_cmd="ya_network_stop"
reload_cmd="ya_network_reload"
extra_commands="reload"

: ${ya_bridge_enable="NO"}

#
#  Global variables used:
#    ipaddr --- address list for this host
#

#
# XXX: Add _common function to remove code duplication
#

ya_network_start()
{
    local _br _detected_interfaces _failed_interfaces _main_interface _opt _ret
    echo -n "Starting network: "
    _ret=0

    _detected_interfaces="$(ya_interface_manage list)"
    _ya_detect_active_interface _failed_interfaces _main_interface $_detected_interfaces

    #
    # Display interfaces configured by this script
    #
    ya_log "Following interfaces were not configured: $_failed_interfaces."
    ya_log "Main interface: $_main_interface."

    #
    # Set MTU
    #
    ya_interface_manage set-mtu $_main_interface $(ya_interface_manage detect-safe-mtu $_main_interface)

    #
    # Set up bridge if needed
    #
    if ya_checkyesno ya_bridge_enable; then
        if _br=$(ya_br_manage start ${_main_interface}); then
            _main_interface="${_br}"
            ya_log "Bridge \"${_br}\" is up"
        else
            ya_warn "[ ya_br_manage start ${_main_interface} ] failed"
        fi
    fi

    #
    # Finally it's time to configure selected interface
    #
    if ! ya_ip_manage populate $_main_interface ${ipaddr}; then
        ya_warn "[ ya_ip_manage populate ${_main_interface} ${ipaddr} ] failed"
        _ret=1
    fi

    for _opt in ${adapter_options}; do
        if ! ya_interface_manage $_opt $_main_interface; then
            ya_warn "[ ya_interface_manage $_opt $_main_interface ] failed"
        fi
    done

    #
    # Wait some time for gateway
    #
    ya_wait_gw 60

    echo .

    return $_ret
}

ya_network_stop()
{
    local _ret _interface
    echo -n "Stopping network: "
    _ret=0

    for _interface in $(ya_interface_manage list); do
        ya_check_real_interface $_interface || continue
        # Flushing IPs on all real interfaces
        if ! ya_ip_manage flush $_interface; then
            ya_warn "[ ya_ip_manage flush ${_interface} ] failed"
            _ret=1
        fi
        # Bringing it down 
        if ! ya_interface_manage down $_interface; then
            ya_warn "[ ya_interface_manage down ${_interface} ] failed"
            _ret=1
        fi
        if ya_checkyesno ya_bridge_enable; then
            ya_br_manage stop ${_interface}
        fi
    done

    echo .

    return $_ret
}

ya_network_reload()
{
    local _if

    echo -n "Reloading network: "

    _if=$(ya_interface_get_active)
    ya_ip_manage populate ${_if} $ipaddr

    echo "."

    return 0
}

_ya_detect_active_interface()
{
    local _ifn _interface_list _first_if _if_exists

    _failed_ifaces=$1
    shift
    _main_iface=$1
    shift

    _interface_list="$@"
    eval $_failed_ifaces=""

    # put all interfaces up
    for _ifn in ${_interface_list}; do
        ya_check_real_interface $_ifn || continue
        ya_interface_manage up ${_ifn}
    done

    #
    # probe for carrier
    #
    local _active_if _sleeped_seconds
    _active_if=""
    _sleeped_seconds=0

    # sleep some seconds and probe interfaces for carrier

    while [ -z $_active_if ]; do
        sleep 2
        _sleeped_seconds=$(($_sleeped_seconds+2))
        if [ $_sleeped_seconds -gt 60 ]; then
            ya_warn "_detect_active_interface(): failed to probe for active interface in 60 seconds."
            break;
        fi
        for _ifn in ${_interface_list}; do
            # skip virtual interfaces
            ya_check_real_interface $_ifn || continue

            if ya_check_interface_carrier ${_ifn}; then
                _active_if=${_ifn}
            fi
        done
    done

    if [ -z $_active_if ]; then
        ya_warn "_detect_active_interface(): No active interface found. \
             We'll use first of existing interfaces."
        for _ifn in $_interface_list; do
            ya_check_real_interface $_ifn || continue
            _active_if=$_ifn
            break
        done
        if [ -z $_active_if ]; then
            ya_err 1 "_detect_active_interface(): Failed selecting first interface. Candidates were [ $_interface_list ]."
        fi
    fi

    # bring unselected interfaces down
    for _ifn in $_interface_list; do
        if [ $_ifn != $_active_if ]; then
            if ya_check_real_interface $_ifn; then
                ya_interface_manage down $_ifn
            fi
            eval eval ${_failed_ifaces}=\""'${_ifn} \$${_failed_ifaces}'"\"
        fi
    done

    #return selected interface
    eval eval \$_main_iface="${_active_if}"
}

ya_load_config_files $name
ya_run_rc_command $@
