#!/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 {
    IP=$1
    MASK=$2
    if ! [ -x "$(command -v sipcalc)" ]; then
        sudo yum -y install sipcalc >/dev/null 2>&1
    fi
    NETWORK=$(sipcalc $IP/$MASK | grep 'Network range' | awk -F "- " '{gsub(" -", ""); print $2}')
    echo $NETWORK
}

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_centos_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_centos_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_centos_manual.sh'
            create_net_config $name $mac
        else
            echo "nic:$name is roce nic,not reconfig it"  | logger -i -t 'bcc_elastic_net_centos_manual.sh'
        fi
    done
    echo -e "  Create/Reset config file \033[32m[OK]\033[0m"  | logger -i -t 'bcc_elastic_net_centos_manual.sh'
}
 
function restart_network(){
    killall dhclient >/dev/null 2>&1
    if [[ "6 7 2" =~ $major_version ]]; then
        which systemctl >/dev/null 2>&1
        if [[ "$?" -eq 0 ]]; then
            systemctl restart network >/dev/null 2>&1
        else
            service network restart >/dev/null 2>&1
        fi
    else
        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_centos_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_centos_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_centos_manual.sh'
            fi
        done
    fi
    if [ "$?" -eq 0 ]; then
        echo -e "  \033[32m[OK]\033[0m"  | logger -i -t 'bcc_elastic_net_centos_manual.sh'
    else
        echo -e "  \033[31m[FAILED]\033[0m"  | logger -i -t 'bcc_elastic_net_centos_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
 
    # write to file
    if  [[ "6 7 2" =~ $major_version ]]; then
        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 "${eip} dev ${name} table ${table_name}" >> /etc/sysconfig/network-scripts/route-"${name}"
                echo "from ${eip} lookup ${table_name}" >> /etc/sysconfig/network-scripts/rule-"${name}" 
            fi   
        else
            if [ $ONLY_CONFIG_IPv4 -eq 0 ]; then
                echo "${eip} dev ${name} table ${table_name}" >> /etc/sysconfig/network-scripts/route6-"${name}"
                echo "from ${eip} lookup ${table_name}" >> /etc/sysconfig/network-scripts/rule6-"${name}"
            fi
        fi
        
        #echo -e "  Add ip ${eip} to route table: ${table_name}"
    else
        if [[ $eip =~ ^[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
        #echo -e "  Add ip ${eip} to route table: ${table_name}"
    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}"
 
    if  [[ "6 7 2" =~ $major_version ]]; then
        prefix=""
        config_script="/etc/sysconfig/network-scripts/route-${DEFAULT_EIP_NIC}"
        if  [[ "7 2" =~ $major_version ]]; then
            sed -i '/DEFROUTE=no/d' /etc/sysconfig/network-scripts/ifcfg-${PRIMARY_NIC}
        else
            sed -i "/^case \${interface} in/,/^esac$/d" /etc/dhcp/dhclient-enter-hooks
        fi
    else
        prefix="ip route add "
        config_script="/etc/NetworkManager/dispatcher.d/config_rt_eip.sh"
    fi
 
    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_centos_manual.sh'
        echo -e "\033[31m  You can run $0 uninstall to uninstall eip direction.\033[0m"  | logger -i -t 'bcc_elastic_net_centos_manual.sh'
 
        if  [[ "6" == $major_version ]]; then
            if [[ ${DEFAULT_EIP_NIC}==${PRIMARY_NIC} ]]; then
                cat >> /etc/dhcp/dhclient-enter-hooks << EOF
case \${interface} in
  $PRIMARY_NIC)
     printf "executing ip route del default\n"
     ip route del default
  ;;
     *)
  ;;
esac
EOF
            fi
        elif [[ "7 2" =~ $major_version ]]; then
            if [[ ${DEFAULT_EIP_NIC}==${PRIMARY_NIC} ]]; then
                echo "DEFROUTE=no" >> /etc/sysconfig/network-scripts/ifcfg-${PRIMARY_NIC}
            fi
        else
            echo "#!/bin/bash" > $config_script
            echo "" >> $config_script
            echo ip route del default >> $config_script
            chmod +x $config_script
        fi
        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_centos_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_centos_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_centos_manual.sh'
	    continue
        fi
        let index=10+${name:3}*10
 
	    if  [[ "6 7 2" =~ $major_version ]]; then
            echo "remove route-${name} and rule-${name}"  | logger -i -t 'bcc_elastic_net_centos_manual.sh'
            rm -f /etc/sysconfig/network-scripts/route-${name}
            rm -f /etc/sysconfig/network-scripts/rule-${name}
            if [ -f /etc/sysconfig/network-scripts/route6-${name} ]; then
                rm /etc/sysconfig/network-scripts/route6-${name}
            fi
            if [ -f /etc/sysconfig/network-scripts/rule6-${name} ]; then
                rm /etc/sysconfig/network-scripts/rule6-${name}
            fi
        else
            echo "remove config_rt_${name}.sh" | logger -i -t 'bcc_elastic_net_centos_manual.sh'
            rm -f /etc/NetworkManager/dispatcher.d/config_rt_${name}.sh
        fi

        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_centos_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_centos_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_centos_manual.sh'
            echo "$index $table_name" >> /etc/iproute2/rt_tables
        fi
        config_script_name="config_$table_name".sh
        if [[ "8 9 3" =~ $major_version ]]; then
            echo "#!/bin/bash" > /etc/NetworkManager/dispatcher.d/$config_script_name
            echo "" >> /etc/NetworkManager/dispatcher.d/$config_script_name
        fi
        
        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

        if [[ "6 7 2" =~ $major_version ]]; then
            echo "default via $gateway dev $name table $table_name" > /etc/sysconfig/network-scripts/route-$name
        else
            echo "ip route add default via $gateway dev $name table $table_name" >> /etc/NetworkManager/dispatcher.d/$config_script_name
        fi
 
        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_centos_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_centos_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
                if  [[ "9" =~ $major_version ]]; then
                    one_ip_network=$(ipcalc -n $one_ip/$netmask_one_cidr| awk -F = '{print $2}')
                else
                    one_ip_network=$(calculate_network "$one_ip" $netmask_one_cidr)
                fi
            fi

            # write to file
            if [[ "6 7 2" =~ $major_version ]]; then
                if [ $version == 4 ]; then
                    if [ $ONLY_CONFIG_IPv6 -eq 0 ]; then
                        echo "$one_ip_network/$netmask_one_cidr dev $name table $table_name" >> /etc/sysconfig/network-scripts/route-$name
                        echo "from $one_ip lookup $table_name" >> /etc/sysconfig/network-scripts/rule-$name
                        if [[ "$one_ip" == "$primary_ip" ]]; then
                            echo "from all oif ${name} lookup $table_name" >> ${CONFIG_PATH}/rule-${name}
                            echo "from all oif ${name} lookup $table_name" >> ${CONFIG_PATH}/rule6-${name}
                        fi
                    fi
                else
                    if [ $ONLY_CONFIG_IPv4 -eq 0 ]; then
                        if [ $first_ipv6 == true ]; then
                            gateway_v6=$(get_meta_value $name $one_ip "gateway")
                            echo "default via $gateway_v6 dev $name table $table_name" > /etc/sysconfig/network-scripts/route6-$name
                            first_ipv6=false
                        fi
                        echo "$one_ip_network/$netmask_one_cidr dev $name table $table_name" >> /etc/sysconfig/network-scripts/route6-$name
                        echo "from $one_ip lookup $table_name" >> /etc/sysconfig/network-scripts/rule6-$name
                    fi
                fi
                echo -e "  Add ip $one_ip to route table: $table_name "  | logger -i -t 'bcc_elastic_net_centos_manual.sh'
            else
                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

                #echo -e "  Add ip $one_ip to route table: $table_name "  | logger -i -t 'bcc_elastic_net_centos_manual.sh'
            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 
        if [[ "8 9 3" =~ $major_version ]]; then
            chmod +x /etc/NetworkManager/dispatcher.d/$config_script_name
        else
            if [ ! -f "/sbin/ifdown-local" ]; then
                # clear ip rule 
                echo "#!/bin/bash" > /sbin/ifdown-local
                echo "" >> /sbin/ifdown-local
                echo "ip rule show | grep rt_eth[1-9] | awk '{print \$NF}' | xargs -r -L1 ip rule del table" >> /sbin/ifdown-local
                chmod +x /sbin/ifdown-local
                echo "[add_route_table]create /sbin/ifdown-local,dev=${name}"  | logger -i -t 'bcc_elastic_net_centos_manual.sh'
            fi
        fi
        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_centos_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_centos_manual.sh'
            NOTCFG_AUXIPEIP=1
            ;;
        onlyipv4)
            echo "only config IPv4"  | logger -i -t 'bcc_elastic_net_centos_manual.sh'
            ONLY_CONFIG_IPv4=1
            ;;
        onlyipv6)
            echo "not config IPv6"  | logger -i -t 'bcc_elastic_net_centos_manual.sh'
            ONLY_CONFIG_IPv6=1
            ;;
        help|*)
            echo "usage:"
            echo "  $0 [install/uninstall/help] [eip]"  | logger -i -t 'bcc_elastic_net_centos_manual.sh'
            return 1
            ;;
    esac
    return 0
}
 
##################################################
for file in centos-release redhat-release
do
    [ ! -f /etc/$file ] && continue
    if grep -i -q "CentOS Stream" /etc/$file; then
        distro="centosstream"
        major_version=$(cat /etc/$file | grep -o '[0-9]\+')
    elif grep -i -q "CentOS" /etc/$file; then
        distro="centos"
        major_version=$(cat /etc/$file | grep -oE '[0-9]+\.[0-9]+' | cut -d '.' -f 1)
        minor_version=$(cat /etc/$file | grep -oE '[0-9]+\.[0-9]+' | cut -d '.' -f 2)
    elif grep -i -q "Rocky" /etc/$file; then
        distro="rocky"
        major_version=$(cat /etc/$file | grep -oE '[0-9]+\.[0-9]+' | cut -d '.' -f 1)
        minor_version=$(cat /etc/$file | grep -oE '[0-9]+\.[0-9]+' | cut -d '.' -f 2)
    elif grep -i -q "Baidu" /etc/$file; then
        distro="baidu"
        major_version=$(cat /etc/$file | grep -oE '[0-9]+\.[0-9]+' | cut -d '.' -f 1)
        minor_version=$(cat /etc/$file | grep -oE '[0-9]+\.[0-9]+' | cut -d '.' -f 2)
    elif grep -i -q "AlmaLinux" /etc/$file; then
        distro="alma"
        major_version=$(cat /etc/$file | grep -oE '[0-9]+\.[0-9]+' | cut -d '.' -f 1)
        minor_version=$(cat /etc/$file | grep -oE '[0-9]+\.[0-9]+' | cut -d '.' -f 2)
    fi
done
 
if ! parse_args "$@"; then
    exit 1
fi
 
if [ "$distro" == "centos" ] || [ "$distro" == "rocky" ] || [ "$distro" == "baidu" ]|| [ "$distro" == "alma" ]|| [ "$distro" == "centosstream" ]; then
    echo "----------------------------------"  | logger -i -t 'bcc_elastic_net_centos_manual.sh'
    if [[ ! "6 7 8 9 2 3" =~ $major_version ]]; then
        echo -e "\033[31m this tool has only been tested on CentOS 6,7,8,centos stream 8 9,rocky 8 9,baidu 2,3.\033[0m"  | logger -i -t 'bcc_elastic_net_centos_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_centos_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_centos_manual.sh'
        exit 3
    else
        echo "curl meta server successfully,network conncection is OK,retry times=$i"  | logger -i -t 'bcc_elastic_net_centos_manual.sh'
    fi
 
    echo -e "\033[32m  tool version: $SCRIPT_VERSION \033[0m"  | logger -i -t 'bcc_elastic_net_centos_manual.sh'
    if [[ "6 7 2" =~ $major_version ]]; then
        echo "  Disable NetworkManager"  | logger -i -t 'bcc_elastic_net_centos_manual.sh'
        if which systemctl >/dev/null 2>&1; then
            systemctl stop NetworkManager >/dev/null 2>&1
            systemctl disable NetworkManager >/dev/null 2>&1
        else
            service NetworkManager stop >/dev/null 2>&1
            chkconfig NetworkManager off >/dev/null 2>&1
        fi
    fi
    echo "----------------------------------" | logger -i -t 'bcc_elastic_net_centos_manual.sh'
    PRIMARY_NIC=$(get_primary_nic)
    echo "  Begin to config elastic NIC" | logger -i -t 'bcc_elastic_net_centos_manual.sh'
    config_elastic_nic
    echo "----------------------------------" | logger -i -t 'bcc_elastic_net_centos_manual.sh'
    if [ $NOTCFG_AUXIPEIP -eq 0 ]; then
        echo "  Begin to config secondary IPs" | logger -i -t 'bcc_elastic_net_centos_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_centos_manual.sh'
            fi
        done
    else 
        rm -f $CONFIG_PATH/ifcfg-${PRIMARY_NIC}:*
    fi
    echo "----------------------------------" | logger -i -t 'bcc_elastic_net_centos_manual.sh'
    echo "  Begin to add routing rules..." | logger -i -t 'bcc_elastic_net_centos_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")
    if  [[ "7 2" =~ $major_version ]]; then
        cur_rtcfgs=$(ls ${CONFIG_PATH}/ |grep -E "^route-")
    else
        cur_rtcfgs=$(ls ${nmdispatcher_path}/ |grep "config_rt_eth")
    fi
    echo "prepare to delete residual config,cur_nics=${cur_nics},cur_ifcfgs=${cur_ifcfgs},cur_rtcfgs=${cur_rtcfgs}" | logger -i -t 'bcc_elastic_net_centos_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_centos_manual.sh'
            rm -f ${CONFIG_PATH}/$ifcfg
        fi
    done
    if  [[ "7 2" =~ $major_version ]]; then
        for rtcfg in ${cur_rtcfgs}
        do
            netdev=$(echo $rtcfg |awk -F'-' '{print $2}')
            [ "$netdev" == "$PRIMARY_NIC" ] && continue
            echo $cur_nics |grep -w $netdev >/dev/null 2>&1
            if [ $? -ne 0 ]; then
                echo "[c7]nic:$netdev not exist,delete its rtcfg:$rtcfg" | logger -i -t 'bcc_elastic_net_centos_manual.sh'
                rm -f ${CONFIG_PATH}/route-${netdev}
                rm -f ${CONFIG_PATH}/rule-${netdev}
                /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
    else
        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 "[c8]nic:$netdev not exist,delete its rtcfg:$rtcfg" | logger -i -t 'bcc_elastic_net_centos_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
    fi

    echo "----------------------------------" | logger -i -t 'bcc_elastic_net_centos_manual.sh'
    echo -n "  Restart network..."  | logger -i -t 'bcc_elastic_net_centos_manual.sh'
    restart_network
    echo "----------------------------------" | logger -i -t 'bcc_elastic_net_centos_manual.sh'
    
else
    echo -e "\033[31mPlease run the script on CentOS system.\033[0m" | logger -i -t 'bcc_elastic_net_centos_manual.sh'
fi
