szaydel
2/25/2014 - 12:16 AM

S99network

#!/usr/bin/ksh

# This is a temporary workaround for aggregates not starting on boot.
DLADM_CMD=/usr/sbin/dladm
IPADM_CMD=/usr/sbin/ipadm
SVCPROP_CMD=/usr/bin/svcprop

typeset fmri=/system/postinst/config
typeset admin_name=$(${SVCPROP_CMD} -p settings/def_admin_int ${fmri})
typeset vnic_config=/etc/admin0.config
typeset vnic_macaddr=""
typeset dladm_config=/etc/dladm/datalink.conf

function get_vnic_mac {

    # In most cases we should have a single line in the $vnic_config
    # file that is the MAC address of the admin interface. We want to
    # keep this address constant, so as to avoid problems with DHCP.
    [[ -f ${vnic_config} ]] \
    && vnic_macaddr=$(cat ${vnic_config}) \
    || vnic_macaddr=$(awk -v var_adm=${admin_name} '$0 ~ var_adm {FS=";"; split($7, arr, ",")} END {print arr[2]}' ${dladm_config})

}

function set_admin_interface {

    get_vnic_mac # If there is already a config, make sure to use same MAC.

    # Default admin interface name is stored as an SMF prop.
    # typeset admin_name=$(${SVCPROP_CMD} -p settings/def_admin_int ${fmri})
    typeset interface=
    typeset link_state="unknown"
    typeset vnic_admin=$(${DLADM_CMD} show-vnic -p -olink ${admin_name} 2>/dev/null)
    typeset expected=("igb0" "e1000g0" "vmxnet3s0")
    typeset delay=10

    # If this is not empty, we already have an admin interface,
    # and we do not want to attempt creating another, possibly
    # clobbering existing setting.
    [[ -z ${vnic_admin} ]] \
        || return 0

    [[ ! -z $(/usr/sbin/ipadm show-if -p -o ifname ${vnic_admin} 2> /dev/null) ]] \
        || return 0

    read -A net_dev_links < <((${DLADM_CMD} show-phys -p -oLINK|xargs))

    for link in ${net_dev_links[@]}; do

        [[ ! -z ${interface} ]] && break

        # Check each interface and see if it matches against
        # one of the expected interface names. If there is a match
        # we assume this is our admin interface.
        for i in ${expected[@]}; do
            [[ ! -z ${interface} ]] \
            && break \
            || { [[ $link == $i ]] && interface=$link; }
        done

    done

    if [[ -z ${vnic_admin} ]]; then

        if [[ ${vnic_macaddr} ]]; then # If we already have a MAC, let's reuse it.

            ${DLADM_CMD} create-vnic -m ${vnic_macaddr} -l ${interface} ${admin_name}
            [[ $? -eq 0 ]] && vnic_state="up"
        else # If this is running for the first time, MAC will be randomly assigned.
            ${DLADM_CMD} create-vnic -l ${interface} ${admin_name}
            [[ $? -eq 0 ]] && vnic_state="up"
            ${DLADM_CMD} show-vnic -p -omacaddress ${admin_name} > ${vnic_config}
        fi

        [[ ${vnic_state} == "up" ]] && ${IPADM_CMD} create-if ${admin_name}
        [[ $? -eq 0 ]] && ${IPADM_CMD} create-addr -T dhcp -w 60 ${admin_name}/v4

    else
        return 0 # We are already done, nothing more needs to happen.

    fi

    return 0

}


interfaces=($(${IPADM_CMD} show-if -p -o ifname|xargs))

for interface in ${interfaces[@]}; do
    if [[ ${interface} =~ "aggr" || ${interface} =~ "admin" ]]; then
        ${IPADM_CMD} enable-if -t ${interface}
        ${IPADM_CMD} enable-addr -t ${interface}/v4
    fi
done

set_admin_interface