#!/usr/bin/env bash
#global varials
CONFIG_PATH="/etc/sysconfig/network-scripts"
nmdispatcher_path="/etc/NetworkManager/dispatcher.d"
MAC_URL="169.254.169.254/2009-04-04/meta-data/network/interfaces/macs"
PRIMARY_NIC=
DEFAULT_EIP_NIC=
DEFAULT_EIP=
DEFAULT_EIP_GATEWAY=
EIP_OPT=
SCRIPT_VERSION="3.0.20260323"
NOTCFG_AUXIPEIP=0
count=0
declare -A nametotype
declare -A nametoprimaryip
declare -A nametomac
mac_address_cache=
nic_type_cache=
primary_ip_cahce=
ONLY_CONFIG_IPv4=0
ONLY_CONFIG_IPv6=0

function calculate_network {
    local ip=$1
    local cidr=$2

    # Use sipcalc if available
    if [ -x "$(command -v sipcalc)" ]; then
        NETWORK=$(sipcalc $ip/$cidr | grep 'Network range' | awk -F "- " '{gsub("-", ""); print $2}')
        echo "$NETWORK"
        return
    fi

    # Fallback to pure Bash implementation
    local network_addr=""

    # Normalize IPv6 address by expanding :: and removing leading zeros
    # Replace :: with appropriate number of zero blocks
    if [[ "$ip" =~ :: ]]; then
        local blocks_before=0
        local blocks_after=0
        [[ ! "${ip%%::*}" == "$ip" ]] && blocks_before=$(echo ${ip%%::*} | tr ':' '\n' | grep -c .)
        [[ ! "${ip##*::}" == "$ip" ]] && blocks_after=$(echo ${ip##*::} | tr ':' '\n' | grep -c .)
        local zero_blocks=$((8 - blocks_before - blocks_after))
        ip=$(echo "$ip" | sed "s/::/$(printf ':0%.0s' $(seq 1 $zero_blocks))/")
    fi

    # Split into octets, pad with leading zeros
    local IFS=':'
    local -a octets=($ip)
    for i in "${!octets[@]}"; do
        octets[$i]=$(printf '%04x' "0x${octets[$i]}")
    done

    # Convert to binary string (128 bits)
    local bin_str=""
    for octet in "${octets[@]}"; do
        bin_str+="$(printf '%04s' "$(echo "obase=2; ibase=16; ${octet^^}" | bc 2>/dev/null)" | tr ' ' '0')"
    done

    # Apply CIDR mask - keep first cidr bits, set rest to 0
    if [[ $cidr -lt 128 ]]; then
        bin_str="${bin_str:0:$cidr}$(printf '0%.0s' $(seq 1 $((128 - cidr))))"
    fi

    # Convert back to hex octets
    local result_octets=()
    for ((i=0; i<8; i++)); do
        local hex_octet="${bin_str:$((i*16)):16}"
        local decimal=$((2#$hex_octet))
        result_octets+=($(printf '%x' $decimal))
    done

    # Format output, remove leading zeros but keep :: for consecutive zeros
    network_addr=""
    for ((i=0; i<8; i++)); do
        # Remove leading zeros from each block
        octet_str=$(echo ${result_octets[$i]} | sed 's/^0*//')
        # Keep at least one zero if block is all zeros
        [ -z "$octet_str" ] && octet_str="0"
        if [ $i -eq 0 ]; then
            network_addr="$octet_str"
        else
            network_addr="$network_addr:$octet_str"
        fi
    done

    # Compress longest sequence of zero blocks to ::
    # This is a simplified compression - may not handle all edge cases
    for ((zeros=7; zeros>=2; zeros--)); do
        pattern=":"
        for ((i=0; i<zeros; i++)); do
            pattern="${pattern}0"
        done
        pattern="${pattern}:"
        if [[ "$network_addr" =~ $pattern ]]; then
            network_addr="${network_addr/$pattern/::}"
            break
        fi
    done

    echo "$network_addr"
}

function ip_version() {
    local ip=$1
    local IFS=.
    local -a octets=($ip)
    if [[ $ip =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
        return 4
    else
        return 6
    fi
}

function get_MTU(){
    name=$1
    get_mac_address $name
    mac=$mac_address_cache
    mtu=$(curl -s "$MAC_URL/$mac/mtu")
    echo $mtu
}

function get_mac_address(){
    name=$1
    if [[ -z ${nametomac[$name]} ]]; then
        mac_address_tmp=$(cat /sys/class/net/$name/address)
        mac_address=$(curl -s "$MAC_URL" | grep -iE "$mac_address_tmp" | sed 's/\///g')
        nametomac[$name]=$mac_address
        mac_address_cache=$mac_address
    else
        mac_address_cache=${nametomac[$name]}
    fi
}

function get_nic_type() {
    name=$1
    if [[ -z ${nametotype[$name]} ]]; then
      get_mac_address $name
      mac=$mac_address_cache
      nic_type=$(curl -s "$MAC_URL/$mac/vif_features")
      count=$((count + 1))
      nametotype[$name]=$nic_type
      nic_type_cache=$nic_type
    else
      nic_type_cache=${nametotype[$name]}
    fi
}

function config_secondary_ips_v6(){
    name=$1
    index=$2
    get_mac_address $name
    mac=$mac_address_cache
    ips_v6=$(curl -s "$MAC_URL/$mac/fixed_ips" |grep -vP '^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/')
    for ip in ${ips_v6[*]}
    do
	    #netmask=$(curl -s "$MAC_URL/$mac/fixed_ips/$ip/mask")
        #netmask_length=$(netmask2cidr $netmask)
		echo -n "$ip""128 " >> $CONFIG_PATH/ifcfg-$name
	echo -e "config_secondary_ips for $name:$index \033[32;40m[OK]\033[0m"  | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
	if is_eip_direct_enabled "${mac}" "${ip}"; then
	    config_eip_direct_v6 "${name}" "${mac}" "${ip}" "${index}" #"${netmask_length}"
    fi
    done
}

function config_eip_direct_v6() {
    local name=$1
    local mac=$2
    local ip=$3
    local index=$4
    local eip
    eip=$(curl -s "${MAC_URL}/${mac}/fixed_ips/${ip}/eip")
    local eip_gateway=$(curl -s "${MAC_URL}/${mac}/fixed_ips/${ip}/gateway")
    echo -n "$eip/128 " >> $CONFIG_PATH/ifcfg-$name
    if [[ "${EIP_OPT}" = "install" ]]; then
        echo "${DEFAULT_EIP:=${eip}}" > /dev/null
        if [[ "${DEFAULT_EIP}" = "${eip}" ]]; then
            DEFAULT_EIP_NIC="${name}"
            DEFAULT_EIP_GATEWAY="${eip_gateway}"
        fi
    elif [[ "${EIP_OPT}" = "uninstall" ]]; then
        DEFAULT_EIP=""
        DEFAULT_EIP_NIC=""
        DEFAULT_EIP_GATEWAY=""
    fi
}

function get_primary_ip(){
    name=$1
    if [[ -z ${nametoprimaryip[$name]} ]]; then
        get_mac_address $name
        mac=$mac_address_cache
        primary_ip=$(curl -s "$MAC_URL/$mac/primary_ipv4_addr")
        nametoprimaryip[$name]=$primary_ip
        primary_ip_cahce=$primary_ip
    else
        primary_ip_cahce=${nametoprimaryip[$name]}
    fi
}

function netmask2cidr() {
    local mask=$1
    if [[ $mask =~ ":" ]]; then
        local bin_mask=$(echo $mask | tr -d ':' | xxd -r -p | xxd -b -c 16 | tr -d ' \n')
        local count_segment=0
        for ((i=0; i<${#bin_mask}; i++)); do
            if [[ "${bin_mask:$i:1}" == "1" ]]; then
                ((count_segment++))
            fi
        done
        echo $count_segment
    else
        awk -F. '{
        split($0, arrSep)
        for (i in arrSep) {
            mask += int(8 - log(2^8 - arrSep[i])/log(2));
        }
        print mask
        }' <<< $mask
    fi
}

function get_primary_nic(){
    nics=$(ls /sys/class/net/ | grep "^eth")
    for name in ${nics[*]}
    do
        address=$(cat /sys/class/net/$name/address)
        eni_type=$(curl -s "$MAC_URL/$address/eni_type")
        count=$((count + 1))
        if [[ "$eni_type" == "primary" ]]; then
            echo $name
            break
        fi
    sleep 1
    done
}

function get_meta_value(){
    name=$1
    ip=$2
    item=$3
    get_mac_address $name
    mac=$mac_address_cache
    ret=0
    for ((i=1; i<=3; i++)); do
        value=$(curl -f -s $MAC_URL/$mac/fixed_ips/$ip/$item)
        count=$((count + 1))
        ret="$?"
        if [[ "$ret" -eq 0 ]]; then
            break
        fi
        sleep 1
    done
    echo $value
}


function create_net_config(){
    name=$1
    mac=$2
    local primary
    get_primary_ip "${name}"
    primary=$primary_ip_cahce
    local mask
    mask=$(get_meta_value $name $primary "mask")
    cat  > "$CONFIG_PATH/ifcfg-$name" << EOF
DEVICE=$name
BOOTPROTO=static
ONBOOT=yes
TYPE=Ethernet
USERCTL=yes
PEERDNS=no
IPV6_PEERDNS="no"
DHCPV6C="no"
DHCPV6C_OPTIONS=-nw
IPV6_DEFROUTE="no"
IPV6_PEERROUTES="yes"
PERSISTENT_DHCLIENT=yes
#HWADDR=$mac
DEFROUTE=no
IPADDR=$primary
NETMASK=$mask
NAME=$name
MTU=$(get_MTU $name)
EOF
    if [ $ONLY_CONFIG_IPv4 -eq 1 ]; then
        echo "IPV6INIT=no" >> "$CONFIG_PATH/ifcfg-$name"
    else
        echo "IPV6INIT=yes" >> "$CONFIG_PATH/ifcfg-$name"
    fi
}

function is_eip_direct_enabled() {
    local mac=$1
    local ip=$2
    eip_direct=$(curl -s "${MAC_URL}/${mac}/fixed_ips/${ip}/eip_direct")
    if [ "$eip_direct"x = "true"x ]; then
        return 0
    fi
    return 1
}
function config_eip_direct() {
    local name=$1
    local mac=$2
    local ip=$3
    local index=$4
    local eip
    eip=$(curl -s "${MAC_URL}/${mac}/fixed_ips/${ip}/eip")
    local eip_gateway=$(curl -s "${MAC_URL}/${mac}/fixed_ips/${ip}/gateway")
    count=$((count + 2))
    cat > "${CONFIG_PATH}/ifcfg-${name}:${index}" << EOF
DEVICE="${name}:${index}"
NAME="${name}:${index}"
BOOTPROTO="none"
ONBOOT=yes
IPV6INIT=no
ARPCHECK=no
IPADDR="${eip}"
NETMASK=255.255.255.255
EOF

    if [[ "${EIP_OPT}" = "install" ]]; then
        echo "${DEFAULT_EIP:=${eip}}" > /dev/null
        if [[ "${DEFAULT_EIP}" = "${eip}" ]]; then
            DEFAULT_EIP_NIC="${name}"
            DEFAULT_EIP_GATEWAY="${eip_gateway}"
        fi
    elif [[ "${EIP_OPT}" = "uninstall" ]]; then
        DEFAULT_EIP=""
        DEFAULT_EIP_NIC=""
        DEFAULT_EIP_GATEWAY=""
    fi
}


function config_secondary_ips(){
    name=$1
    get_mac_address $name
    mac=$mac_address_cache
    if [ $ONLY_CONFIG_IPv6 -eq 0 ]; then
        ips=$(curl -s "$MAC_URL/$mac/fixed_ips" | grep -v ":" | sed 's/\///g')
        count=$((count + 1))
        get_primary_ip "${name}"
        primary_ip=$primary_ip_cahce
        index=1
        for ip in ${ips[*]}
        do
            if is_eip_direct_enabled "${mac}" "${ip}"; then
                config_eip_direct "${name}" "${mac}" "${ip}" "${index}"
                let index++
            fi
            if [ "$ip" != "$primary_ip" ]; then
                netmask=$(curl -s "$MAC_URL/$mac/fixed_ips/$ip/mask")
                cat > $CONFIG_PATH/ifcfg-$name:$index << EOF
DEVICE="$name:$index"
NAME="$name:$index"
BOOTPROTO="none"
ONBOOT=yes
IPV6INIT=no
IPADDR=$ip
NETMASK=$netmask
NAME=$name
NO_ALIASROUTING=yes
EOF
                echo -e "config_secondary_ips for $name:$index \033[32;40m[OK]\033[0m"  | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
                let index++
            fi
        done
    fi
    if [ $ONLY_CONFIG_IPv4 -eq 0 ]; then
        echo -n "IPV6ADDR_SECONDARIES=\"" >> $CONFIG_PATH/ifcfg-$name
        config_secondary_ips_v6 $name $index
        echo '"' >> $CONFIG_PATH/ifcfg-$name
    fi
}

function config_elastic_nic(){
    elastic_nics=$(ls /sys/class/net/ | grep "^eth" | grep -v "$PRIMARY_NIC")
    for name in ${elastic_nics[*]}
    do
        get_nic_type $name
        nictype=$nic_type_cache
        if [ "$nictype"x != "rdma_roce"x ]; then
            rm -f $CONFIG_PATH/ifcfg-${name}*
            get_mac_address $name
            mac=$mac_address_cache
            echo "[config_elastic_nic]rm old ifcfg and create config for nic:$name,mac:$mac"  | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
            create_net_config $name $mac
        else
            echo "nic:$name is roce nic,not reconfig it"  | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
        fi
    done
    echo -e "  Create/Reset config file \033[32m[OK]\033[0m"  | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
}

function restart_network(){
    killall dhclient >/dev/null 2>&1
    if [[ -f /etc/sysconfig/network-scripts/ifcfg-"$PRIMARY_NIC":1 ]]; then
        elastic_nics=$(ls /sys/class/net/ | grep "^eth")
        grep -qx "NAME=$PRIMARY_NIC" /etc/sysconfig/network-scripts/ifcfg-"$PRIMARY_NIC"
        if [ "$?" -ne 0 ]; then
            echo "NAME=$PRIMARY_NIC" >> /etc/sysconfig/network-scripts/ifcfg-"$PRIMARY_NIC"
        fi
    else
        elastic_nics=$(ls /sys/class/net/ | grep "^eth")
    fi
    for name in ${elastic_nics[*]}
    do
        get_nic_type $name
        nictype=$nic_type_cache
        if [ "$nictype"x != "rdma_roce"x ]; then
            echo "delete nic:$name ip rules"  | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
            ip rule show | grep "rt_${name}" | awk '{print $NF}' | xargs -r -L1 ip rule del table
            echo "nmcli reload and up nic:$name"  | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
            nmcli c reload "$CONFIG_PATH/ifcfg-$name"
            sleep 1
            nmcli c up $name >/dev/null 2>&1
            sleep 1
        else
            echo "nic:$name is roce nic,not restart it"  | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
        fi
    done
    if [ "$?" -eq 0 ]; then
        echo -e "  \033[32m[OK]\033[0m"  | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
    else
        echo -e "  \033[31m[FAILED]\033[0m"  | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
    fi
}

function config_eip_route() {
    local name=$1
    local mac=$2
    local ip=$3
    local table_name=$4
    local eip
    eip=$(curl -s "${MAC_URL}/${mac}/fixed_ips/${ip}/eip")
    count=$((count + 1))
    echo ${eip:?"Get eip failed!"} > /dev/null

    if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
        if [ $ONLY_CONFIG_IPv6 -eq 0 ]; then
            echo "ip route add ${eip} dev ${name} table ${table_name}" >> /etc/NetworkManager/dispatcher.d/"config_rt_${name}.sh"
            echo "ip rule add from ${eip} lookup ${table_name}" >> /etc/NetworkManager/dispatcher.d/"config_rt_${name}.sh"
        fi
    else
        if [ $ONLY_CONFIG_IPv4 -eq 0 ]; then
            echo "ip -6 route add ${eip} dev ${name} table ${table_name}" >> /etc/NetworkManager/dispatcher.d/"config_rt_${name}.sh"
            echo "ip -6 rule add from ${eip} lookup ${table_name}" >> /etc/NetworkManager/dispatcher.d/"config_rt_${name}.sh"
        fi
    fi
}

function config_eip_default_route() {
    local default_gateway
    primary_default_gateway=$(route  -n |awk '{if($1=="0.0.0.0")print $2}')
    default_gateway="${DEFAULT_EIP_GATEWAY}"

    prefix="ip route add "
    config_script="/etc/NetworkManager/dispatcher.d/config_rt_eip.sh"

    if [[ -n "${DEFAULT_EIP_NIC}" && -n "${DEFAULT_EIP}" && -n "${default_gateway}" ]]; then
        echo -e "\033[31m  Default Route is setting to ${DEFAULT_EIP_NIC}....\033[0m"  | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
        echo -e "\033[31m  You can run $0 uninstall to uninstall eip direction.\033[0m"  | logger -i -t 'bcc_elastic_net_kylin_manual.sh'

        echo "#!/bin/bash" > $config_script
        echo "" >> $config_script
        echo ip route del default >> $config_script
        chmod +x $config_script

        echo "$prefix"10.0.0.0/8 dev "${DEFAULT_EIP_NIC}" via "${default_gateway}" >> $config_script
        echo "$prefix"100.64.0.0/10 dev "${DEFAULT_EIP_NIC}" via "${default_gateway}" >> $config_script
        echo "$prefix"172.16.0.0/12 dev "${DEFAULT_EIP_NIC}" via "${default_gateway}" >> $config_script
        echo "$prefix"192.168.0.0/16 dev "${DEFAULT_EIP_NIC}" via "${default_gateway}" >> $config_script
        echo "$prefix"169.254.0.0/16 dev "${DEFAULT_EIP_NIC}" via "${default_gateway}" >> $config_script
        echo "$prefix"255.255.255.255 dev "${DEFAULT_EIP_NIC}" via "${default_gateway}" >> $config_script
        echo "$prefix"default via "${default_gateway}" dev "${DEFAULT_EIP_NIC}" src "${DEFAULT_EIP}" >> $config_script

    elif [[ -z "${DEFAULT_EIP_NIC}" && -n "${DEFAULT_EIP}" ]]; then
        echo -e "\033[31m  Default Route set failed!!, No NIC for ${DEFAULT_EIP}\033[0m"  | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
    elif [[ "${EIP_OPT}" = "uninstall" ]]; then
        ip route del 10.0.0.0/8
        ip route del 100.64.0.0/10
        ip route del 172.16.0.0/12
        ip route del 192.168.0.0/16
        ip route del 169.254.0.0/16
        ip route del 255.255.255.255
        ip route del default
        ip route add default via "${primary_default_gateway}" dev "${PRIMARY_NIC}"
    fi
}

function add_route_table(){
    secondary_nics=$(ls /sys/class/net/ | grep "^eth" | grep -v "$PRIMARY_NIC")
    if command -v wc >/dev/null 2>&1 && command -v tail >/dev/null 2>&1 ; then
        if [ $(tail -c 1 /etc/iproute2/rt_tables | wc -l) -eq 0 ]; then
            echo "Unexpected end of rt_tables" | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
            echo >> /etc/iproute2/rt_tables
        fi
    fi
    for name in $secondary_nics
    do
        get_nic_type $name
        nictype=$nic_type_cache
        if [ "$nictype"x = "rdma_roce"x ]; then
            echo "nic:$name is roce nic,not config route,continue"  | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
	    continue
        fi
        let index=10+${name:3}*10

        echo "remove config_rt_${name}.sh" | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
        rm -f /etc/NetworkManager/dispatcher.d/config_rt_${name}.sh

        get_primary_ip "${name}"
        primary_ip=$primary_ip_cahce
        netmask=$(get_meta_value $name $primary_ip "mask")
        if [[ -z $netmask ]]; then
            echo "  can't get the netmask for $primary_ip from the metadata server."  | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
            exit
        fi

        gateway=$(get_meta_value $name $primary_ip "gateway")
        if [[ -z $gateway ]]; then
            echo "  can't get the gateway for $primary_ip from the metadata server."  | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
            exit
        fi

        table_name="rt_$name"

        grep -q "^$index $table_name" /etc/iproute2/rt_tables >/dev/null 2>&1
        if [ "$?" -ne 0 ]; then
            echo "write $index $table_name to /etc/iproute2/rt_tables"  | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
            echo "$index $table_name" >> /etc/iproute2/rt_tables
        fi
        config_script_name="config_$table_name".sh
        echo "#!/bin/bash" > /etc/NetworkManager/dispatcher.d/$config_script_name
        echo "" >> /etc/NetworkManager/dispatcher.d/$config_script_name

        ip route flush table $table_name >/dev/null 2>&1
        #ip -6 route flush table $table_name >/dev/null 2>&1
        ip rule show | grep "${table_name}" | awk '{print $NF}' | xargs -r -L1 ip rule del table
        #ip -6 rule show | grep "${table_name}" | awk '{print $NF}' | xargs -r -L1 ip -6 rule del table

        echo "ip route add default via $gateway dev $name table $table_name" >> /etc/NetworkManager/dispatcher.d/$config_script_name

        get_mac_address $name
        mac=$mac_address_cache
        for ((i=1; i<=3; i++)); do
            #all_ips=$(curl -f -s $MAC_URL/$mac/fixed_ips | grep -v ":" | sed 's/\///g')
            all_ips=$(curl -f -s $MAC_URL/$mac/fixed_ips | sed 's/\///g')
            if [[ "$?" -eq 0 ]]; then
                break
            fi
            sleep 1
        done
        if [[ -z "$all_ips" ]]; then
            echo "  can't get the fixed_ip list of $name from metadata server."  | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
            exit
        fi
        if [ $NOTCFG_AUXIPEIP -eq 1 ]; then
            echo "not config auxip and eip,set all_ips to primary ip:$primary_ip"  | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
            all_ips=$primary_ip
        fi
        version=
        first_ipv6=true
        for one_ip in $all_ips
        do
            netmask_one=$(get_meta_value ${name} $one_ip "mask")
            netmask_one_cidr=$(netmask2cidr $netmask_one)
            ip_version "$one_ip"
            if [ $? -eq 4 ]; then
                #echo "IPv4"
                version=4
                one_ip_network=$(ipcalc -n $one_ip $netmask_one | awk -F = '{print $2}')
            else
                #echo "IPv6"
                version=6
                one_ip_network=$(calculate_network "$one_ip" $netmask_one_cidr)
            fi

            if [ $version == 4 ]; then
                if [ $ONLY_CONFIG_IPv6 -eq 0 ]; then
                    echo "ip route add $one_ip_network/$netmask_one_cidr dev $name table $table_name" >> /etc/NetworkManager/dispatcher.d/$config_script_name
                    grep -q "ip rule del table" /etc/NetworkManager/dispatcher.d/$config_script_name
                    if [ $? -ne 0 ]; then
                        echo "ip rule show | grep "$table_name" | awk '{print \$NF}' | xargs -r -L1 ip rule del table" >> /etc/NetworkManager/dispatcher.d/$config_script_name
                    fi
                    echo "ip rule add from $one_ip lookup $table_name" >> /etc/NetworkManager/dispatcher.d/$config_script_name
                fi
            else
                if [ $ONLY_CONFIG_IPv4 -eq 0 ]; then
                    grep -q "ip -6 rule del table" /etc/NetworkManager/dispatcher.d/$config_script_name
                    if [ $? -ne 0 ]; then
                        echo "ip -6 rule show | grep "$table_name" | awk '{print \$NF}' | xargs -r -L1 ip -6 rule del table" >> /etc/NetworkManager/dispatcher.d/$config_script_name
                    fi
                    if [ $first_ipv6 == true ]; then
                        gateway_v6=$(get_meta_value $name $one_ip "gateway")
                        echo "ip -6 route add default via $gateway_v6 dev $name table $table_name" >> /etc/NetworkManager/dispatcher.d/$config_script_name
                        first_ipv6=false
                    fi
                    echo "ip -6 route add $one_ip_network/$netmask_one_cidr dev $name table $table_name" >> /etc/NetworkManager/dispatcher.d/$config_script_name
                    echo "ip -6 rule add from $one_ip lookup $table_name" >> /etc/NetworkManager/dispatcher.d/$config_script_name
                fi
            fi

	    if [ $NOTCFG_AUXIPEIP -eq 0 ]; then
                #config eip direct rule
                if is_eip_direct_enabled "${mac}" "${one_ip}"; then
                    config_eip_route "${name}" "${mac}" "${one_ip}" "${table_name}"
                fi
            fi
        done
        #add executable
        chmod +x /etc/NetworkManager/dispatcher.d/$config_script_name
        let index+=10
    done
    if [ $NOTCFG_AUXIPEIP -eq 0 ]; then
        config_eip_default_route
    fi
}

function parse_args() {
    if [[ "$#" = 0 ]]; then
        return 0
    elif [[ "$#" -gt 2 ]]; then
        echo "Error Parameter!!"  | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
        return 1
    fi

    case "$1" in
        install)
            EIP_OPT="install"
            if [[ "$#" = 2 ]]; then
                DEFAULT_EIP=$2
            fi
            ;;
        uninstall)
            EIP_OPT="uninstall"
            ;;
        noauxipeip)
            echo "not config auxiliary ip and EIP"  | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
            NOTCFG_AUXIPEIP=1
            ;;
        onlyipv4)
            echo "only config IPv4"  | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
            ONLY_CONFIG_IPv4=1
            ;;
        onlyipv6)
            echo "not config IPv6"  | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
            ONLY_CONFIG_IPv6=1
            ;;
        help|*)
            echo "usage:"
            echo "  $0 [install/uninstall/help] [eip]"  | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
            return 1
            ;;
    esac
    return 0
}

##################################################
if [ -f /etc/os-release ]; then
    . /etc/os-release
    if [[ "$NAME" == *"Kylin"* && "$NAME" == *"Server"* ]]; then
        distro="kylin"
        # VERSION_ID format: V10, V10SP1, etc.
        major_version="${VERSION_ID}"
    fi
fi

if ! parse_args "$@"; then
    exit 1
fi

if [ "$distro" == "kylin" ]; then
    echo "----------------------------------"  | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
    if [[ ! "$major_version" =~ ^V10 ]]; then
        echo -e "\033[31m this tool has only been tested on Kylin V10.\033[0m"  | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
        exit 1
    fi
    if [[ $EUID -ne 0 ]]; then
        echo -e "\033[31m please run this tool as root. \033[0m"  | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
        exit 0
    fi
    for((i=0;i<30;i++))
    do
        curl -f -s http://169.254.169.254/2009-04-04/meta-data/create-time >/dev/null 2>&1

        if [[ $? -ne 0 ]]; then
            sleep 1
        else
            break
        fi
    done
    if [ $i -ge 30 ]; then
        echo -e "\033[31m error occured when curl meta server. Please check network conncection.  \033[0m"  | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
        exit 3
    else
        echo "curl meta server successfully,network conncection is OK,retry times=$i"  | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
    fi

    echo -e "\033[32m  tool version: $SCRIPT_VERSION \033[0m"  | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
    echo "----------------------------------" | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
    PRIMARY_NIC=$(get_primary_nic)
    echo "  Begin to config elastic NIC" | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
    config_elastic_nic
    echo "----------------------------------" | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
    if [ $NOTCFG_AUXIPEIP -eq 0 ]; then
        echo "  Begin to config secondary IPs" | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
        names=$(ls /sys/class/net/ | grep "^eth" )
        #names=$(ls /sys/class/net/ | grep "^eth" | grep -v "$PRIMARY_NIC")
        for name in ${names[*]}
        do
            get_nic_type $name
            nictype=$nic_type_cache
            if [ "$nictype"x != "rdma_roce"x ]; then
                rm -f $CONFIG_PATH/ifcfg-$name:*
                if [ $name = $PRIMARY_NIC ]; then
                    sed -i '/^IPV6ADDR_SECONDARIES=".*"/d' $CONFIG_PATH/ifcfg-$name
                fi
                config_secondary_ips $name
            else
                echo "nic:$name is roce nic,don't config secondary ips" | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
            fi
        done
    else
        rm -f $CONFIG_PATH/ifcfg-${PRIMARY_NIC}:*
    fi
    echo "----------------------------------" | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
    echo "  Begin to add routing rules..." | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
    # clean old route_table
    #sed -i '/rt_eth/d' /etc/iproute2/rt_tables
    add_route_table

    cur_nics=$(ls /sys/class/net/ | grep "^eth" | grep -v "$PRIMARY_NIC")
    cur_ifcfgs=$(ls ${CONFIG_PATH}/ |grep "ifcfg-eth")
    cur_rtcfgs=$(ls ${nmdispatcher_path}/ |grep "config_rt_eth")
    echo "prepare to delete residual config,cur_nics=${cur_nics},cur_ifcfgs=${cur_ifcfgs},cur_rtcfgs=${cur_rtcfgs}" | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
    for ifcfg in ${cur_ifcfgs}
    do
        netdev=$(echo $ifcfg | awk -F'-' '{print $2}' | awk -F':' '{print $1}')
        [ "$netdev" == "$PRIMARY_NIC" ] && continue
        echo $cur_nics |grep -w $netdev >/dev/null 2>&1
        if [ $? -ne 0 ]; then
            echo "nic:$netdev not exist,delete its ifcfg:$ifcfg" | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
            rm -f ${CONFIG_PATH}/$ifcfg
        fi
    done
    for rtcfg in ${cur_rtcfgs}
    do
        netdev=$(echo $rtcfg |awk -F. '{print $1}' |cut -d'_' -f 3)
        [ "$netdev" == "$PRIMARY_NIC" ] && continue
        echo $cur_nics |grep -w $netdev >/dev/null 2>&1
        if [ $? -ne 0 ]; then
            echo "[kylin]nic:$netdev not exist,delete its rtcfg:$rtcfg" | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
            rm -f ${nmdispatcher_path}/$rtcfg
            /usr/sbin/ip rule show | grep "rt_${netdev}" | awk '{print $NF}' | xargs -r -L1 /usr/sbin/ip rule del table
            sed -i "/rt_${netdev}/d" /etc/iproute2/rt_tables
        fi
    done

    echo "----------------------------------" | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
    echo -n "  Restart network..."  | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
    restart_network
    echo "----------------------------------" | logger -i -t 'bcc_elastic_net_kylin_manual.sh'

else
    echo -e "\033[31mPlease run the script on Kylin system.\033[0m" | logger -i -t 'bcc_elastic_net_kylin_manual.sh'
fi