#!/bin/sh

#*************************************************************
# Name:        check_ip
# Description: check whether ip is valid
# Input:  ip
# Return: 0 -- success; not 0 -- failure
# Date:    2019-08-08
#*************************************************************
check_ip()
{
    check_ipv4 $1
    if [[ $? == 0 ]];then
          return 0
    fi

    check_ipv6 $1
    if [[ $? == 0 ]];then
          return 0
    fi

    return 1
}

#*************************************************************
# Name:        check_ipv4
# Description: check whether ip is valid
# Input:  ip
# Return: 0 -- success; not 0 -- failure
# Date:    2019-08-08
#*************************************************************
check_ipv4()
{
    g_result=""
    ipaddr=$1
    if [[ x$ipaddr == x ]];then
        echo "The IP value you put ("$1") is illegal!"
        return 1
    fi
    e=`echo ${ipaddr}|awk -F . '{print NF}'`
    a0=`echo ${ipaddr}|awk -F . '{print $1}'`
    b0=`echo ${ipaddr}|awk -F . '{print $2}'`
    c0=`echo ${ipaddr}|awk -F . '{print $3}'`
    d0=`echo ${ipaddr}|awk -F . '{print $4}'`
    a1=`echo $a0`
    b1=`echo $b0`
    c1=`echo $c0`
    d1=`echo $d0`
    a=`echo $a0 | tr -cd "0-9"`
    b=`echo $b0 | tr -cd "0-9"`
    c=`echo $c0 | tr -cd "0-9"`
    d=`echo $d0 | tr -cd "0-9"`

    if [[ $e -ne 4 ]]|| [ -z $b ] ||[ -z $c ] ||[ -z $d ] ||[ -z $a ] || [[ $a1 != $a ]]|| [[  $b1 != $b ]]|| [[  $c1 != $c ]]|| [[  $d1 != $d ]]
       then
            return 1
    fi

    for i in $a $b $c $d
    do
        if [ $i -gt 255 ] || [ $i -lt 0 ]
        then
               return 1
        fi
    done
    check_ip_broad ${ipaddr}
    if [[ $? != 0 ]];then
        return 2
    fi
    g_result=$a.$b.$c.$d
}

#*************************************************************
# Name:        check_ipv6
# Description: check whether ip is valid
# Input:  ip
# Return: 0 -- success; not 0 -- failure
# Date:    2019-08-08
#*************************************************************
check_ipv6()
{
  ipaddr=$1
  matchResult=`echo "$ipaddr" | grep -E "^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$"`

    if [[ "$matchResult" != "$ipaddr" ]];then
        return 1
    fi
    return 0
}

#*************************************************************
# Name:        check_prefix
# Description: check whether prefix is valid
# Input:  mask prefix
# Return: 0 -- success; not 0 -- failure
# Date:    2019-08-08
#*************************************************************
check_prefix()
{
    net_prefix=$1

    if [[ x${net_prefix} == x ]];then
        return 1
    fi
    if [[ ${net_prefix} -gt 32 ]] || [[ ${net_prefix} -lt 0 ]];then
        return 1
    fi

    return 0
}

#*************************************************************
# Name:        check_ip_broad
# Description: check whether ip broad is valid
# Input:  ip
# Return: 0 -- success; not 0 -- failure
# Date:    2019-08-08
#*************************************************************
check_ip_broad()
{
    local ip=$1
    if [[ $ip = "255.255.255.255" ]];then
        echo "The IP address $ip is a broadcast address, which is not allowed."
        return 1
    fi
    ip_part1=${ip%%.*}

    if [[ $ip_part1 -ge 224 ]]&&[[ $ip_part1 -le 239 ]];then
        echo "The IP address $ip is a multicast address, which is not allowed."
        return 1
    fi
}

#*************************************************************
# Name:        check_net_mask
# Description: check whether netmask is valid
# Input:  mask
# Return: 0 -- success; not 0 -- failure
# Date:    2019-08-08
#*************************************************************
check_net_mask()
{
    local netmask=$1
    check_ipv4_net_mask ${netmask}
    if [[ $? == 0 ]];then
        return 0
    fi

    check_ipv6_net_mask ${netmask}
    if [[ $? == 0 ]];then
        return 0
    fi

    return 1
}

#*************************************************************
# Name:        check_ipv4_net_mask
# Description: check whether netmask is valid
# Input:  mask
# Return: 0 -- success; not 0 -- failure
# Date:    2019-08-08
#*************************************************************
check_ipv4_net_mask()
{
    local netmask=$1
    check_ip ${netmask} >/dev/null 2>&1
    if [[ $? -ne 0 ]];then
        return 1
    fi

    if [[ ${netmask} == "0.0.0.0" ]];then
        return 11
    fi

    local a=`echo $netmask | awk -F'.' '{print $1}'`
    local b=`echo $netmask | awk -F'.' '{print $2}'`
    local c=`echo $netmask | awk -F'.' '{print $3}'`
    local d=`echo $netmask | awk -F'.' '{print $4}'`

    local regex1=^1*$
    local regex2=^1+0+$
    local regex3=^0+$

    for i in $a $b $c $d; do
        _tmp2=`echo "obase=2;${i}" |bc`

        if [[ ${i} != "0" ]];then
            if [[ "8" -ne "${#_tmp2}" ]];then
                return 1
            fi
        fi
        if [[ ${_tmp2} =~ ${regex1} ]];then
            continue
        elif [[ ${_tmp2} =~ ${regex2} ]];then
            regex1=^0+$
            regex2=^0+$
            continue
        elif [[ ${_tmp2} =~ ${regex3} ]];then
            regex1=^0+$
            regex2=^0+$
            continue
        else
            return 1
        fi
    done

    return 0
}

#*************************************************************
# Name:        check_ipv6_net_mask
# Description: check whether netmask is valid
# Input:  mask
# Return: 0 -- success; not 0 -- failure
# Date:    2019-08-08
#*************************************************************
check_ipv6_net_mask()
{
    local prefixlen=$1

    if [[ x${prefixlen} == x ]];then
        return 1
    fi
    if [[ ${prefixlen} -gt 128 ]] || [[ ${prefixlen} -lt 0 ]];then
        return 1
    fi
    return 0
}

#*************************************************************
# Name:        prefix_to_mask
# Description: prefix-->mask
# Input:  mask prefix
# Output: mask
# Return: N/A
# Date:    2019-08-08
#*************************************************************
prefix_to_mask()
{
    bin_prefix=""
    prefix_cnt1=${1}
    for i in `seq 1 ${prefix_cnt1}`
    do
        bin_prefix="${bin_prefix}1"
    done
    prefix_cnt2=$((32 - ${prefix_cnt1}))
    for i in `seq 1 ${prefix_cnt2}`
    do
        bin_prefix="${bin_prefix}0"
    done

    internal_mask=""
    for i in `seq 0 8 31`
    do
        val=${bin_prefix:${i}:8}
        tmp_mask=$(echo "obase=10;ibase=2;${val}" | bc)
        if [[ "${internal_mask}" = "" ]];then
            internal_mask="${tmp_mask}"
        else
            internal_mask="${internal_mask}.${tmp_mask}"
        fi
    done
    num_mask=$internal_mask
}

#*************************************************************
# Name:        mask_to_prefix
# Description: mask-->prefix
# Input:  mask
# Output: mask prefix
# Return: N/A
# Date:    2019-08-08
#*************************************************************
mask_to_prefix()
{
    mask=${1}
    prefix_cnt=0
    prefix_temp=""
    local mask_list=($(echo ${mask} | awk -F. '{print $1,$2,$3,$4}'))
    local mask_cnt=${#mask_list[*]}
    mask_cnt=$((${mask_cnt} - 1))
    for i in `seq 0 ${mask_cnt}`
    do
        tmp=$(echo "obase=2;ibase=10;${mask_list[$i]}" | bc)
        prefix_temp="${prefix_temp}${tmp}"
    done
    prefix_cnt=$(echo ${prefix_temp} | grep -o 1 | wc -l)
    return ${prefix_cnt}
}

#*************************************************************
# Name:        check_ip_and_mask
# Description: check the ip and the mask
# Input:  ip and mask
# Output: N/A
# Return: 0 -- success; not 0 -- failure
# Date:    2019-08-08
#*************************************************************
check_ip_and_mask()
{
    check_ip ${ip}
    if [[ $? != 0 ]];then
        echo "Invalid ip ${ip}."
        return 1
    fi

    check_net_mask ${mask}
    if [[ $? != 0 ]];then
        echo "Invalid mask ${mask}."
        return 3
    fi

    check_ipv4 ${ip}
    if [[ $? == 0 ]];then
        check_ipv4_net_mask ${mask}
        if [[ $? == 0 ]];then
            if [[ x$prefix == x ]];then
                mask_to_prefix $mask
                prefix=$?
            fi
            check_prefix ${prefix}
            if [[ $? != 0 ]];then
                echo "Invalid prefix ${prefix}."
                return 2
            fi
        elif [[ x == x ]]; then
            check_ipv6_net_mask ${mask}
            if [[ $? == 0 ]];then
                echo "Ensure that the entered IP address and mask are both in IPv4 or IPv6 format."
                return 4
            fi
        fi
    fi


    check_ipv6 ${ip}
    if [[ $? == 0 ]];then
        check_ipv4_net_mask ${mask}
        if [[ $? == 0 ]];then
            echo "Ensure that the entered IP address and mask are both in IPv4 or IPv6 format."
            return 5
        fi
    fi

    return 0
}

#*************************************************************
# Name:        check_slave
# Description: determine if eth is bound by bond
# Input:  ethX
# Output: N/A
# Return: 0 -- success; not 0 -- failure
# Date:    2019-08-08
#*************************************************************
check_slave()
{
    is_slave=$(cat ${NETWORK_DIR}/ifcfg-$1 | grep SLAVE | awk -F= '{print $2}')
    if [[ "$is_slave" == "yes" ]] || [[ "$is_slave" == "Yes" ]] || [[ "$is_slave" == "YES" ]];then
        bond_master=$(cat ${NETWORK_DIR}/ifcfg-$1 | grep MASTER | awk -F= '{print $2}')
        echo "The secondary network port $1 has been bond by ${bond_master}."
        return 1
    fi
    return 0
}

#*************************************************************
# Name:        add_hosts
# Description: add ip to the hosts file
# Input:  ip
# Output: N/A
# Return: N/A
# Date:    2019-08-08
#*************************************************************
add_hosts()
{
    local ip=$ip

    OLD_IFS="$IFS"
    IFS="/"
    local ip_arr=($ip)
    IFS="$OLD_IFS"
    local ip=${ip_arr[0]}

    local hostname=$(cat /etc/hostname)
    if [[ -f "/etc/hosts" ]];then
        ip_line=$(cat /etc/hosts | grep -w $ip)
        if [[ x$ip_line = x ]];then
            echo -e "${ip}\t${hostname}">>"/etc/hosts"
        fi
    else
        echo "The hosts file does not exist."
    fi
}

#*************************************************************
# Name:        del_hosts
# Description: delete ip in the hosts file
# Input:  ip
# Output: N/A
# Return: N/A
# Date:    2019-08-08
#*************************************************************
del_hosts()
{
    local ip=$1
    OLD_IFS="$IFS"
    IFS="/"
    local ip_arr=($ip)
    IFS="$OLD_IFS"
    local ip=${ip_arr[0]}
    if [[ -f "/etc/hosts" ]];then
        ip_line=$(cat /etc/hosts | grep -w $ip | head -1)
        while [[ x$ip_line != x ]]
        do
            sed "/$ip_line/d" /etc/hosts > /etc/hosts_temp
            mv /etc/hosts_temp /etc/hosts
            chmod 644 /etc/hosts
            ip_line=$(cat /etc/hosts | grep -w $ip | head -1)
        done
    else
        echo "The hosts file does not exist"
    fi
}

#*************************************************************
# Name:        check_eth
# Description: determine whether the network port exists
# Input:  ethX
# Output: N/A
# Return: 0 -- success; not 0 -- failure
# Date:    2019-08-08
#*************************************************************
check_eth()
{
    local eth_name=$1

    eth_val=$(ifconfig -a | grep -w ${eth_name})

    if [[ x != x$eth_val ]];then

        if [[ ! -f "${NETWORK_DIR}/ifcfg-${eth_name}" ]];then

            temp_file_name="ifcfg-temp-"`date "+%Y%m%d%H%M%S"`

            if [[ -f "/root/${temp_file_name}" ]]||[[ -d "/root/${temp_file_name}" ]];then
              rm /root/${temp_file_name}
            fi
            echo "TYPE=Ethernet" >> /root/${temp_file_name}
            echo "DEVICE=$eth_name" >> /root/${temp_file_name}
            echo "NAME=$eth_name" >> /root/${temp_file_name}
            echo "BOOTPROTO=none" >> /root/${temp_file_name}
            echo "STARTMODE=hotplug" >> /root/${temp_file_name}
            chmod 644 /root/${temp_file_name}
            cat /root/${temp_file_name} >${NETWORK_DIR}/"ifcfg-"$eth_name
            chmod 644 ${NETWORK_DIR}/"ifcfg-"$eth_name
            if [[ -f "/root/${temp_file_name}" ]]||[[ -d "/root/${temp_file_name}" ]];then
                rm /root/${temp_file_name}
            fi
        fi
    else
        echo "Network port ${eth_name} does not exist."
        return 1
    fi
    return 0
}

#*************************************************************
# Name:        check_args
# Description: check for illegal parameter names and duplicate parameter names
# Input:  args
# Output: N/A
# Return: 0 -- success; not 0 -- failure
# Date:    2019-08-08
#*************************************************************
check_args()
{
  local num=0
  for i in ${args_name_arr[*]};do
    if [[ ${i:0:1} = "-" ]];then
      args_name_arr[$num]=$i
      num=$((num+1))
    fi
  done

  for i in ${args_name_arr[*]};do
    if [[ ! ${args_list[*]} =~ $i ]];then
      echo "Invalid parameter name exists."
      return 5
    fi
  done

  local origin_num="${#args_name_arr[*]}"
  args_name_arr=($(awk -vRS=' ' '!a[$1]++' <<< ${args_name_arr[@]}))
  local after_num="${#args_name_arr[*]}"
  if [[ $origin_num != $after_num ]];then
    echo "Duplicate parameter names exist."
    return 6
  fi
  return 0
}

#*************************************************************
# Name:        bond_pre_check
# Description: pre_check of create bond
# Input:  bond_name nic_list mode_name bond_ip netmask
# Output: N/A
# Return: 0 -- success; not 0 -- failure
# Date:    2019-08-08
#*************************************************************
bond_pre_check(){
    check_ip_and_mask
    if [[ $? != 0 ]];then
        usage_bond
        logger -t $USER -p local0.info "$FILE_NAME;Failed;${OPERIP:-127.0.0.1};sem_tool $arg"
        return 1
    fi

    #判断bond是否存在
    if [[ -f ${NETWORK_DIR}/ifcfg-${name} ]];then
      echo "The bond $name already exists. To recreate the bond, unbond it and bond it again."
      return 1
    fi

    #分割eth组成数组
    nics_arr=(${nic_list//,/ })
    if [[ ${#nics_arr[@]} != 2 ]];then
      echo "Only two secondary network ports can be bond."
      return 1
    fi
    if [[ ${nics_arr[0]} == 'lo' ]] || [[ ${nics_arr[1]} == 'lo' ]];then
      echo "The lo network port can't be used as the slave of the bond."
      return 1
    fi
    if [[ ${nics_arr[0]} == ${nics_arr[1]} ]];then
      echo "The command contains the same secondary network port."
      return 1
    fi
    for s in ${nics_arr[@]};do
        check_eth $s
        if [[ $? != 0 ]];then
            return 1
        fi
        check_slave $s
        if [[ $? != 0 ]];then
            return 1
        fi
    done

    if [[ $mode_name != "active-backup" ]]&&[[ $mode_name != "802.3ad" ]];then
        echo "Invalid mode value."
        return 1
    fi

    local type_check=""
    #判断BOND IP是否在某张网卡上
    for i in $(ls ${NETWORK_DIR} | grep ifcfg-);do
        ip_in_port=$(cat ${NETWORK_DIR}/$i | grep -w $bond_ip )
        if [[ "$ip_in_port" != "" ]];then
            which_port=${i#*-}
            echo "The IP address $bond_ip has been occupied by $which_port"
            echo "Migrate the IP address $ip from the ${which_port} network adapter to the $name network adapter? y/n"
            read reply
            if [[ ! $reply = "y" ]];then
                return 1
            fi
            #IP已被分配到某张网卡上，删除网卡上的IP，并移动到bond上
            type_check=""
            check_ipv4 $bond_ip
            if [[ $? == 0 ]];then
                type_check="ipv4"
                unifconfig $which_port $type_check "inner_function"
                break
            fi

            check_ipv6 $bond_ip
            if [[ $? == 0 ]];then
                type_check="ipv6"
                unifconfig $which_port $type_check "inner_function"
                break
            fi
        fi
    done

    echo "The network will be restarted during the operation, which may lead to network interruption. Are you sure you want to continue? y/n"
    read reply
    if [[ ! $reply == "y" ]];then
        return 1
    fi

    #修改slave网口的配置文件
    if [[ x$bond_ip != x ]];then
        type_check=""
        check_ipv4 $bond_ip
        if [[ $? == 0 ]];then
            type_check="ipv4"
        fi
        check_ipv6 $bond_ip
        if [[ $? == 0 ]];then
              type_check="ipv6"
        fi
    fi

    count=0
    for eth_name in ${nics_arr[@]};do
        #删除原网卡中信息，并重新写入
        if [[ -f ${NETWORK_DIR}/ifcfg-$eth_name ]];then
            unifconfig $eth_name $type_check "inner_function"
        fi
        sed "/BOOTPROTO/d" ${NETWORK_DIR}/ifcfg-$eth_name > ${NETWORK_DIR}/ifcfg-$eth_name-temp
        mv ${NETWORK_DIR}/ifcfg-$eth_name-temp ${NETWORK_DIR}/ifcfg-$eth_name
        echo "BOOTPROTO=none" >> ${NETWORK_DIR}/ifcfg-$eth_name
        echo "MASTER=$name" >> ${NETWORK_DIR}/ifcfg-$eth_name
        echo "SLAVE=yes" >> ${NETWORK_DIR}/ifcfg-$eth_name
        sed "/ONBOOT/d" ${NETWORK_DIR}/ifcfg-$eth_name > ${NETWORK_DIR}/ifcfg-$eth_name-temp
        mv ${NETWORK_DIR}/ifcfg-$eth_name-temp ${NETWORK_DIR}/ifcfg-$eth_name
        echo "ONBOOT=yes" >> ${NETWORK_DIR}/ifcfg-$eth_name
        chmod 644 ${NETWORK_DIR}/ifcfg-$eth_name
        if [[ $OS_TYPE == "sles" ]];then
            sed "/STARTMODE/d" ${NETWORK_DIR}/ifcfg-$eth_name > ${NETWORK_DIR}/ifcfg-$eth_name-temp
            mv ${NETWORK_DIR}/ifcfg-$eth_name-temp ${NETWORK_DIR}/ifcfg-$eth_name
            echo "STARTMODE=hotplug" >> ${NETWORK_DIR}/ifcfg-$eth_name
            echo "BONDING_SLAVE$count=$eth_name" >> ${NETWORK_DIR}/ifcfg-$name
        fi
        count=$((count+1))
    done

    return 0
}

#*************************************************************
# Name:        bond
# Description: Create bond
# Input:  bond_name nic_list mode_name bond_ip netmask
# Output: N/A
# Return: 0 -- success; not 0 -- failure
# Date:    2019-08-08
#*************************************************************
bond(){
    bond_name=$1
    nic_list=$2
    mode_name=$3
    bond_ip=$4
    net_mask=$5

    bond_pre_check
    if [[ $? == 1 ]];then
        return 1
    fi

    local type_bond=""
    check_ipv4 $bond_ip
    if [[ $? == 0 ]];then
        type_bond="ipv4"
    fi
    check_ipv6 $bond_ip
    if [[ $? == 0 ]];then
        type_bond="ipv6"
    fi
    #创建bond文件
    echo "DEVICE=$bond_name" >> ${NETWORK_DIR}/ifcfg-${bond_name}
    echo "TYPE=Bond" >> ${NETWORK_DIR}/ifcfg-${bond_name}
    echo "BONDING_MASTER=yes" >> ${NETWORK_DIR}/ifcfg-${bond_name}
    echo "NAME=$bond_name" >> ${NETWORK_DIR}/ifcfg-${bond_name}
    echo "ONBOOT=yes" >> ${NETWORK_DIR}/ifcfg-${bond_name}
    echo "BOOTPROTO=static" >> ${NETWORK_DIR}/ifcfg-${bond_name}
    if [[ $OS_TYPE == "sles" ]];then
        sed "/STARTMODE/d" ${NETWORK_DIR}/ifcfg-${name} > ${NETWORK_DIR}/ifcfg-${name}-temp
        mv ${NETWORK_DIR}/ifcfg-${name}-temp ${NETWORK_DIR}/ifcfg-${name}
        echo "STARTMODE=auto" >> ${NETWORK_DIR}/ifcfg-$name
        echo "BONDING_MODULE_OPTS='mode=$mode miimon=100'" >> ${NETWORK_DIR}/ifcfg-${bond_name}
    else
        echo "BONDING_OPTS='mode=$mode miimon=100'" >> ${NETWORK_DIR}/ifcfg-${bond_name}
    fi
    if [[ $type_bond == "ipv4" ]];then
        if [[ $OS_TYPE == "euler" ]];then
            echo "IPADDR=${bond_ip}" >> ${NETWORK_DIR}/ifcfg-${bond_name}
            if [[ x$prefix != x ]];then
                echo "PREFIX=${prefix}" >> ${NETWORK_DIR}/ifcfg-${bond_name}
            fi
        else
            echo "IPADDR=$bond_ip/$prefix" >> ${NETWORK_DIR}/ifcfg-${bond_name}
        fi
    fi
    if [[ $type_bond == "ipv6" ]];then
        if [[ $OS_TYPE == "euler" ]];then
            echo "IPV6ADDR=$bond_ip/$net_mask" >> ${NETWORK_DIR}/ifcfg-${bond_name}
        else
            echo "IPADDR_0=$bond_ip/$net_mask" >> ${NETWORK_DIR}/ifcfg-${bond_name}
        fi
    fi
    chmod 644 ${NETWORK_DIR}/ifcfg-${bond_name}

    if [[ $OS_TYPE == "sles" && -f /sys/class/net/bonding_masters ]];then
        echo +${bond_name} > /sys/class/net/bonding_masters
    fi

    #重启网络
    echo "Restarting the network..."
    service network restart
    if [[ $OS_TYPE == "sles" ]];then
        sleep 2
        cat /sys/class/net/bonding_masters | grep ${bond_name} > /dev/null 2>&1
        if [[ $? -ne 0 ]];then
            echo +${bond_name} > /sys/class/net/bonding_masters
        fi
        service network restart
    fi
    echo "The bond configuration is successful."
}

#*************************************************************
# Name:        unbond
# Description: Delete bond
# Input:  bond_name
# Output: N/A
# Return: 0 -- success; not 0 -- failure
# Date:    2019-08-08
#*************************************************************
unbond(){
    bond_name=$1
    #判断bond是否存在
    if [[ ! -f ${NETWORK_DIR}/ifcfg-${bond_name} ]];then
        echo "The configuration file of $bond_name does not exist."
        return 1
    fi

    #判断是否是bond master
    if [[ $OS_TYPE == "euler" ]];then
        is_bond_master=$(cat ${NETWORK_DIR}/ifcfg-${bond_name} | grep BONDING_OPTS)
    else
        is_bond_master=$(cat ${NETWORK_DIR}/ifcfg-${bond_name} | grep BONDING_MODULE_OPTS)
    fi
    if [[ x${is_bond_master} == x ]];then
        echo "${name} is not bond master"
        return 1
    fi

    echo "The network will be restarted during the operation, which may lead to network interruption. Are you sure you want to continue? y/n"
    read reply
    if [[ ! $reply == "y" ]];then
        return 1
    fi

    #获取slave的设备序号
    cd ${NETWORK_DIR}
    temp_nics=($(grep "^MASTER=" ifcfg-* | grep $bond_name | awk -F: '{print $1}'|awk -F- '{print $2}'))
    if [[ ${#temp_nics[@]} != 2 ]];then
        echo "$bond_name has more than 2 slaves [${temp_nics[@]}], please check the configuration of $bond_name."
        return 1
    fi

    #删除网卡上的bond信息
    for nic_name in ${temp_nics[@]};do
        if [[ -f ${NETWORK_DIR}/ifcfg-${nic_name} ]];then
            sed '/MASTER/d' ${NETWORK_DIR}/ifcfg-${nic_name} > ${NETWORK_DIR}/ifcfg-${nic_name}-temp
            mv ${NETWORK_DIR}/ifcfg-${nic_name}-temp ${NETWORK_DIR}/ifcfg-${nic_name}
            sed '/SLAVE/d' ${NETWORK_DIR}/ifcfg-${nic_name} > ${NETWORK_DIR}/ifcfg-${nic_name}-temp
            mv ${NETWORK_DIR}/ifcfg-${nic_name}-temp ${NETWORK_DIR}/ifcfg-${nic_name}
            chmod 644 ${NETWORK_DIR}/ifcfg-${nic_name}
        fi
    done

    ipv4_addr=$(cat ${NETWORK_DIR}/ifcfg-${bond_name} | grep IPADDR | head -1 | awk -F= '{print $2}' | tr -d '"')
    if [[ x$ipv4_addr != x ]];then
        del_hosts $ipv4_addr
    fi
    ipv6_addr=$(cat ${NETWORK_DIR}/ifcfg-${bond_name} | grep IPV6ADDR | head -1 | awk -F= '{print $2}' | tr -d '"')
    if [[ x$ipv6_addr != x ]];then
        del_hosts $ipv6_addr
    fi

    #删除bond文件
    ifconfig ${bond_name} down
    rm -f ${NETWORK_DIR}/ifcfg-${bond_name}
    if [[ -f ${NETWORK_DIR}/route-${bond_name} ]];then
        rm -f ${NETWORK_DIR}/route-${bond_name}
    fi

    echo -${bond_name} > /sys/class/net/bonding_masters

    #重启网络
    echo "Restarting the network..."
    service network restart
    echo "The bond is deleted successfully."

    return 0
}

#*************************************************************
# Name:        ifconfig_pre_check
# Description: pre_check of ifconfig
# Input:  dev ip mask gateway
# Output: N/A
# Return: 0 -- success; not 0 -- failure
# Date:    2019-08-08
#*************************************************************
ifconfig_pre_check()
{
    check_ip_and_mask
    if [[ $? != 0 ]];then
        usage_ifconfig
        logger -t $USER -p local0.info "$FILE_NAME;Failed;${OPERIP:-127.0.0.1};sem_tool $arg"
        return 1
    fi
    check_eth $name
    if [[ $? != 0 ]];then
        return 1
    fi

    #判断网口是否被bond
    check_slave $name
    if [[ $? == 1 ]];then
        return 1
    fi

    #判断配置的ip是否改变
    ip_line=$(cat ${NETWORK_DIR}/ifcfg-${name} | grep -w $ip )
    if [[ x$ip_line != x ]];then
        echo "The single-port network adapter $name has been configured with the IP address ${ip_line}. Are you sure you want to replace it? (The original IP address of the network adapter will be deleted.) y/n"
        read reply
        if [[ ! $reply == "y" ]];then
            return 1
        fi
    fi

    #判断ip有没有占用
    for i in $(ls ${NETWORK_DIR} | grep ifcfg- | grep -v ${name});do
        ip_in_port=$(cat ${NETWORK_DIR}/$i | grep -w $ip )
        if [[ "$ip_in_port" != "" ]];then
            eth_name=${i#*-}
            echo "The IP address $ip has been occupied by $eth_name"
            echo "Migrate the IP address $ip from the $eth_name network adapter to the $name network adapter? y/n"
            read reply
            if [[ ! $reply = "y" ]];then
                return 1
            fi
            #IP已被分配到某张网卡上，则删除原网卡上的IP，并移动到配置网卡上
            local type_check=""
            check_ipv4 $ip
            if [[ $? == 0 ]];then
                type_check="ipv4"
                unifconfig $eth_name $type_check "inner_function"
                break
            fi
            check_ipv6 $ip
            if [[ $? == 0 ]];then
                type_check="ipv6"
                unifconfig $eth_name $type_check "inner_function"
                break
            fi

        fi
    done

    #是否能重启网络服务
    echo "The network will be restarted during the operation, which may lead to network interruption. Are you sure you want to continue? y/n"
    read reply
    if [[ ! $reply == "y" ]];then
        return 1
    fi

    return 0
}

#*************************************************************
# Name:        ifconfig_cmd
# Description: Configure the IP address and mask of the NIC
# Input:  dev ip mask gateway
# Output: N/A
# Return: 0 -- success; not 0 -- failure
# Date:    2019-08-08
#*************************************************************
ifconfig_cmd()
{
    ifconfig_pre_check
    if [[ $? == 1 ]];then
        return 1
    fi

    #清空本网卡的ip
    local type_ifconfig=""
    check_ipv4 $ip
    if [[ $? == 0 ]];then
        type_ifconfig="ipv4"
    fi
    check_ipv6 $ip
    if [[ $? == 0 ]];then
        type_ifconfig="ipv6"
    fi

    unifconfig $name $type_ifconfig "inner_function"

    sed "/ONBOOT/d" ${NETWORK_DIR}/ifcfg-${name} > ${NETWORK_DIR}/ifcfg-${name}-temp
    mv ${NETWORK_DIR}/ifcfg-${name}-temp ${NETWORK_DIR}/ifcfg-${name}
    echo "ONBOOT=yes" >> ${NETWORK_DIR}/ifcfg-$name
    if [[ $OS_TYPE == "sles" ]];then
        sed "/STARTMODE/d" ${NETWORK_DIR}/ifcfg-${name} > ${NETWORK_DIR}/ifcfg-${name}-temp
        mv ${NETWORK_DIR}/ifcfg-${name}-temp ${NETWORK_DIR}/ifcfg-${name}
        echo "STARTMODE=auto" >> ${NETWORK_DIR}/ifcfg-$name
    fi
    echo "BOOTPROTO=static" >> ${NETWORK_DIR}/ifcfg-$name
    if [[ $type_ifconfig == "ipv4" ]];then
        if [[ $OS_TYPE == "euler" ]];then
            echo "IPADDR=$ip" >> ${NETWORK_DIR}/ifcfg-$name
            echo "PREFIX=${prefix}" >> ${NETWORK_DIR}/ifcfg-$name
        else
            echo "IPADDR=${ip}/${prefix}" >> ${NETWORK_DIR}/ifcfg-$name
        fi
    fi
    if [[ $type_ifconfig == "ipv6" ]];then
        if [[ $OS_TYPE == "euler" ]];then
            echo "IPV6ADDR=$ip/$mask" >> ${NETWORK_DIR}/ifcfg-$name
        else
            echo "IPADDR_0=$ip/$mask" >> ${NETWORK_DIR}/ifcfg-$name
        fi
    fi

    chmod 644 ${NETWORK_DIR}/ifcfg-$name

    #重启网络
    echo "Restarting the network..."
    service network restart
    echo "The IP address is configured successfully."
}

#*************************************************************
# Name:        unifconfig
# Description: Clear the IP address and mask of the NIC
# Input:  dev
# Output: N/A
# Return: 0 -- success; not 0 -- failure
# Date:    2019-08-08
#*************************************************************
unifconfig()
{
    eth_name=$1
    if [[ ! -f ${NETWORK_DIR}/ifcfg-${eth_name} ]];then
        echo "The configuration file of $eth_name does not exist."
        return 1
    fi

    #如果网卡属于某个bond，不操作
    check_slave ${eth_name}
    if [[ $? == 1 ]];then
        return 1
    fi

    if [[ $3 != "inner_function" ]];then
        echo "The network will be restarted during the operation, which may lead to network interruption. Are you sure you want to continue? y/n"
        read reply
        if [[ ! $reply == "y" ]];then
            return 1
        fi
    fi

    if [[ $2 != "ipv4" ]] && [[ $2 != "ipv6" ]];then
        echo $2
        echo "type must be 'ipv4' or 'ipv6'"
        return 1
    fi
    ipv4_addr_list=$(cat ${NETWORK_DIR}/ifcfg-${eth_name} | grep IPADDR | awk -F= '{print $3}' | tr -d '"')
    for ipv4_addr in ${ipv4_addr_list}
    do
        if [[ x$ipv4_addr != x ]];then
            del_hosts $ipv4_addr
        fi
    done
    ipv6_addr_list=$(cat ${NETWORK_DIR}/ifcfg-${eth_name} | grep IPV6ADDR | awk -F= '{print $3}' | tr -d '"')
    for ipv6_addr in ${ipv6_addr_list}
    do
        if [[ x$ipv6_addr != x ]];then
            del_hosts $ipv6_addr
        fi
    done

    if [[ $2 == "ipv4" ]];then
        sed "/IPADDR/d" ${NETWORK_DIR}/ifcfg-${eth_name} > ${NETWORK_DIR}/ifcfg-${eth_name}-temp
        mv ${NETWORK_DIR}/ifcfg-${eth_name}-temp ${NETWORK_DIR}/ifcfg-${eth_name}

        sed "/BOOTPROTO/d" ${NETWORK_DIR}/ifcfg-${eth_name} > ${NETWORK_DIR}/ifcfg-${eth_name}-temp
        mv ${NETWORK_DIR}/ifcfg-${eth_name}-temp ${NETWORK_DIR}/ifcfg-${eth_name}

        sed "/NETMASK=/d" ${NETWORK_DIR}/ifcfg-${eth_name} > ${NETWORK_DIR}/ifcfg-${eth_name}-temp
        mv ${NETWORK_DIR}/ifcfg-${eth_name}-temp ${NETWORK_DIR}/ifcfg-${eth_name}

        sed "/PREFIX/d" ${NETWORK_DIR}/ifcfg-${eth_name} > ${NETWORK_DIR}/ifcfg-${eth_name}-temp
        mv ${NETWORK_DIR}/ifcfg-${eth_name}-temp ${NETWORK_DIR}/ifcfg-${eth_name}

        sed "/GATEWAY/d" ${NETWORK_DIR}/ifcfg-${eth_name} > ${NETWORK_DIR}/ifcfg-${eth_name}-temp
        mv ${NETWORK_DIR}/ifcfg-${eth_name}-temp ${NETWORK_DIR}/ifcfg-${eth_name}

        sed "/DEFROUTE/d" ${NETWORK_DIR}/ifcfg-${eth_name} > ${NETWORK_DIR}/ifcfg-${eth_name}-temp
        mv ${NETWORK_DIR}/ifcfg-${eth_name}-temp ${NETWORK_DIR}/ifcfg-${eth_name}
    elif [[ $2 == "ipv6" ]]; then
        if [[ $OS_TYPE == "euler" ]];then
            sed "/IPV6ADDR/d" ${NETWORK_DIR}/ifcfg-${eth_name} > ${NETWORK_DIR}/ifcfg-${eth_name}-temp
            mv ${NETWORK_DIR}/ifcfg-${eth_name}-temp ${NETWORK_DIR}/ifcfg-${eth_name}

            sed "/BOOTPROTO/d" ${NETWORK_DIR}/ifcfg-${eth_name} > ${NETWORK_DIR}/ifcfg-${eth_name}-temp
            mv ${NETWORK_DIR}/ifcfg-${eth_name}-temp ${NETWORK_DIR}/ifcfg-${eth_name}

            sed "/IPV6_DEFAULTGW/d" ${NETWORK_DIR}/ifcfg-${eth_name} > ${NETWORK_DIR}/ifcfg-${eth_name}-temp
            mv ${NETWORK_DIR}/ifcfg-${eth_name}-temp ${NETWORK_DIR}/ifcfg-${eth_name}
        else
            sed "/IPADDR_0/d" ${NETWORK_DIR}/ifcfg-${eth_name} > ${NETWORK_DIR}/ifcfg-${eth_name}-temp
            mv ${NETWORK_DIR}/ifcfg-${eth_name}-temp ${NETWORK_DIR}/ifcfg-${eth_name}
        fi
    fi

    chmod 644 ${NETWORK_DIR}/ifcfg-${eth_name}

    if [[ $3 != "inner_function" ]];then
        echo "Restarting the network..."
        service network restart
        echo "The IP address is cleared successfully."
    fi

    return 0
}

#*************************************************************
# Name:        hostname_add
# Description: Configure hostname
# Input:  N/A
# Output: N/A
# Return: 0 -- success; not 0 -- failure
# Date:    2019-08-08
#*************************************************************
hostname_add()
{
    pattern="^[0-9A-Za-z]+[0-9A-Za-z-]*[0-9A-Za-z]+$"
    if [[ ! $name =~ $pattern ]];then
        echo "The parameter of \"name\" contains special characters, please modify!"
        logger -t $USER -p local0.info "$FILE_NAME;Failed;${OPERIP:-127.0.0.1};sem_tool $arg"
        return 1
    fi

    new_hostname=$name
    if [[ $new_hostname =~ \-\- ]];then
        echo "The host name cannot contain consecutive hyphens (-)."
        return 1
    fi
    if [[ $new_hostname =~ ^[0-9][0-9]{0,62}$ ]];then
        echo "The host name cannot contain only digits."
        return 1
    fi
    if [[ $new_hostname =~ ^[a-zA-Z0-9][a-zA-Z0-9-]{0,62}$ ]];then
        #修改当前内存中的主机名
        hostname $new_hostname

        #修改/etc/hostname
        hostnamectl set-hostname --static $new_hostname

        #修改/etc/HOSTNAME
        echo "$new_hostname" >/etc/HOSTNAME

        #修改/etc/hosts
        tmp_result=$(ip addr | grep 'scope global' | awk '{print $2}' | cut -f1 -d "/" 2>&1)
        count=0
        for i in $tmp_result
        do
            host_ip=$(cat /etc/hosts | grep -w "$i" | head -1)
            while [[ $host_ip != "" ]]
            do
                sed "/$host_ip/d" /etc/hosts > /etc/hosts-temp
                mv /etc/hosts-temp /etc/hosts
                chmod 644 /etc/hosts
                host_ip=$(cat /etc/hosts | grep -w "$i" | head -1)
            done
            echo "$i $new_hostname" >>/etc/hosts
            count=$((count+1))
        done
    else
        echo "The host name is invalid."
        echo "A host name can contain a maximum of 63 characters, including digits, letters, and hyphens (-). It must start with a digit or letter, and cannot contain consecutive hyphens (-) or only digits."
        return 1
    fi
    echo "The host name is modified successfully."
}

#*************************************************************
# Name:        config_default_gateway
# Description: Configure default route
# Input:  gateway dev
# Output: N/A
# Return: 0 -- success; not 0 -- failure
# Date:    2019-08-08
#*************************************************************
config_default_gateway()
{
    local default_gateway=$defaultgw

    check_ipv4 $default_gateway
    if [[ $? == 0 ]];then
        route add default gw ${default_gateway}
        if [[ $? != 0 ]];then
            return 1
        fi

        local has_default=1
        while [ ${has_default} -eq 1 ]
        do
            route del -net 0.0.0.0 netmask 0.0.0.0 > /dev/null 2>&1
            if [[ $? != 0 ]];then
                has_default=0
            fi
        done
        route add default gw ${default_gateway}

        for i in $(ls ${NETWORK_DIR} | grep ifcfg- | grep -v lo);do
            sed '/DEFROUTE/d' ${NETWORK_DIR}/${i} > ${NETWORK_DIR}/${i}-temp
            mv ${NETWORK_DIR}/${i}-temp ${NETWORK_DIR}/${i}
            sed '/GATEWAY/d' ${NETWORK_DIR}/${i} > ${NETWORK_DIR}/${i}-temp
            mv ${NETWORK_DIR}/${i}-temp ${NETWORK_DIR}/${i}
            chmod 644 ${NETWORK_DIR}/${i}
        done

        if [[ ${OS_TYPE} == "euler" ]];then
            local des_net=0.0.0.0
            local des_mask=0.0.0.0
            for i in $(ls ${NETWORK_DIR} | grep route- | awk -F"-" '{print $2}');do
                delete_static_route ${i} ${des_net} ${des_mask} "inner_function"
            done

            sed '/GATEWAY/d' /etc/sysconfig/network > /etc/sysconfig/network-temp
            mv /etc/sysconfig/network-temp /etc/sysconfig/network
            echo "GATEWAY=${default_gateway}" >> /etc/sysconfig/network

            chmod 644 /etc/sysconfig/network
        else
            if [[ ! -f ${NETWORK_DIR}/routes ]];then
                touch ${NETWORK_DIR}/routes
            fi
            ipv4_default=$(cat ${NETWORK_DIR}/routes | grep default | grep -v ":")
            if [[ x$ipv4_default != x ]];then
                sed "/$ipv4_default/d" ${NETWORK_DIR}/routes > ${NETWORK_DIR}/routes-temp
                mv ${NETWORK_DIR}/routes-temp ${NETWORK_DIR}/routes
            fi
            echo "default ${default_gateway} - -" >> ${NETWORK_DIR}/routes

            chmod 644 ${NETWORK_DIR}/routes
        fi
    fi

    check_ipv6 $default_gateway
    if [[ $? == 0 ]];then
        if [[ ${OS_TYPE} == "euler" ]];then
            ip -6 route add default via ${default_gateway}
            sed '/IPV6_DEFAULTGW/d' /etc/sysconfig/network > /etc/sysconfig/network-temp
            mv /etc/sysconfig/network-temp /etc/sysconfig/network
            echo "IPV6_DEFAULTGW=${default_gateway}" >> /etc/sysconfig/network

            chmod 644 /etc/sysconfig/network
        else
            ip -6 route del default > /dev/null 2>&1
            ip -6 route add default via ${default_gateway}
            if [[ ! -f ${NETWORK_DIR}/routes ]];then
                touch ${NETWORK_DIR}/routes
            fi
            ipv6_default=$(cat ${NETWORK_DIR}/routes | grep default | grep ":")
            if [[ x$ipv6_default != x ]];then
                sed "/$ipv6_default/d" ${NETWORK_DIR}/routes > ${NETWORK_DIR}/routes-temp
                mv ${NETWORK_DIR}/routes-temp ${NETWORK_DIR}/routes
            fi
            echo "default ${default_gateway} - -" >> ${NETWORK_DIR}/routes

            chmod 644 ${NETWORK_DIR}/routes
        fi
    fi

    echo "The default gateway is configured successfully."
}

#*************************************************************
# Name:        config_static_route
# Description: Configure static route
# Input:  dev net mask gateway
# Output: N/A
# Return: 0 -- success; not 0 -- failure
# Date:    2019-08-08
#*************************************************************
config_static_route()
{
    local dev=$name
    local des_net=$net
    local des_net_mask=$mask
    local gateway=$gateway

    local type_route=""
    check_ipv4 $des_net
    if [[ $? == 0 ]];then
        type_route="ipv4"
    fi
    check_ipv6 $des_net
    if [[ $? == 0 ]];then
        type_route="ipv6"
    fi

    check_ip ${des_net}
    if [[ $? != 0 ]];then
        echo "Invalid net ${des_net}."
        return 1
    fi

    if [[ ${des_net_mask} != "255.255.255.255" ]];then
        check_net_mask ${des_net_mask}
        if [[ $? != 0 ]];then
            echo "Invalid mask ${des_net_mask}."
            return 3
        fi
    fi

    if [[ $dev != 'vEth0' ]];then
        check_eth $dev
        if [[ $? != 0 ]];then
            return 1
        fi
    fi

    if [[ $type_route == "ipv4" ]];then
        eth_val=$(ifconfig -a | grep -w vEth0)
        if [[ $dev != 'vEth0' ]] || [[ x != x$eth_val ]];then
            mask_to_prefix $des_net_mask
            prefix=$?
            ip route add ${des_net}/${prefix} via ${gateway} dev ${dev}
            if [[ $? != 0 ]];then
                return 1
            fi
        fi

        if [[ ${OS_TYPE} == "euler" ]];then
            if [[ ! -f ${NETWORK_DIR}/route-$dev ]];then
                touch ${NETWORK_DIR}/route-$dev
            fi

            for i in $(cat ${NETWORK_DIR}/route-$dev | grep -w ${des_net} | awk -F"ADDRESS" '{print $2}' | awk -F"=" '{print $1}')
            do
                local to_be_add_mask=$(cat ${NETWORK_DIR}/route-$dev | grep -w NETMASK${i} | awk -F"NETMASK${i}=" '{print $2}')
                if [[ ${to_be_add_mask} == ${des_net_mask} ]];then
                    echo "The route has been configured on the $dev network port device."
                    return 1
                fi
            done

            route_list=[]
            route_count=0
            for address_line in $(cat ${NETWORK_DIR}/route-$dev | grep "ADDRESS")
            do
                route_list[$route_count]=$(echo ${address_line} | awk -F"ADDRESS" '{print $2}' | awk -F"=" '{print $1}')
                let route_count=route_count+1
            done
            if [[ ${route_count} == 0 ]];then
                cur_line=0
            else
                let route_count=route_count-1
                cur_line=$((route_list[$route_count]+1))
            fi
            echo "ADDRESS${cur_line}=$des_net" >> ${NETWORK_DIR}/route-$dev
            echo "NETMASK${cur_line}=$des_net_mask" >> ${NETWORK_DIR}/route-$dev
            echo "GATEWAY${cur_line}=$gateway" >> ${NETWORK_DIR}/route-$dev

            chmod 644 ${NETWORK_DIR}/route-$dev
        else
            if [[ ! -f ${NETWORK_DIR}/routes ]];then
                touch ${NETWORK_DIR}/routes
            fi
            cat ${NETWORK_DIR}/routes | grep -w ${des_net} | grep -w ${des_net_mask} > /dev/null 2>&1
            if [[ $? -ne 0 ]];then
                echo "${des_net} $gateway ${des_net_mask} $dev" >> ${NETWORK_DIR}/routes
            fi
            chmod 644 ${NETWORK_DIR}/routes
        fi

    elif [[ $type_route == "ipv6" ]];then
        ip route add ${des_net}/${des_net_mask} via ${gateway} dev ${dev}
        if [[ $? != 0 ]];then
            echo "The route has been configured on the $dev network port device."
            return 1
        fi
        if [[ ${OS_TYPE} == "euler" ]];then
            if [[ ! -f ${NETWORK_DIR}/route6-$dev ]];then
                touch ${NETWORK_DIR}/route6-$dev
            fi
            echo "${des_net}/${des_net_mask} via ${gateway} dev ${dev}" >> ${NETWORK_DIR}/route6-$dev

            chmod 644 ${NETWORK_DIR}/route6-$dev
        else
            if [[ ! -f ${NETWORK_DIR}/routes ]];then
                touch ${NETWORK_DIR}/routes
            fi
            echo "${des_net} $gateway ${des_net_mask} $dev" >> ${NETWORK_DIR}/routes
            chmod 644 ${NETWORK_DIR}/routes
        fi

    fi


    echo "The route is configured successfully."
}

#*************************************************************
# Name:        delete_static_route
# Description: Delete static route
# Input:  dev net
# Output: N/A
# Return: 0 -- success; not 0 -- failure
# Date:    2019-08-08
#*************************************************************
delete_static_route()
{
    local dev=$1
    local des_net=$2
    local des_net_mask=$3

    local type_route=""
    check_ipv4 $des_net
    if [[ $? == 0 ]];then
        type_route="ipv4"
    else
        check_ipv6 $des_net
        if [[ $? == 0 ]];then
            type_route="ipv6"
        fi
    fi

    if [[ $4 != "inner_function" ]];then
        check_ip ${des_net}
        if [[ $? != 0 ]];then
            echo "Invalid net ${des_net}."
            return 1
        fi

        if [[ ${des_net_mask} != "255.255.255.255" ]] && [[ ${des_net_mask} != "128" ]];then
            check_net_mask ${des_net_mask}
            if [[ $? != 0 ]];then
                echo "Invalid mask ${des_net_mask}."
                return 3
            fi
        fi

        if [[ $dev != 'vEth0' ]];then
            check_eth $dev
            if [[ $? != 0 ]];then
                return 1
            fi
        fi

        if [[ $type_route == "ipv4" ]];then
            eth_val=$(ifconfig -a | grep -w vEth0)
            if [[ $dev != 'vEth0' ]] || [[ x != x$eth_val ]];then
                mask_to_prefix $des_net_mask
                prefix=$?
                ip route del ${des_net}/${prefix} dev ${dev}
                if [[ $? != 0 ]];then
                    return 1
                fi
            fi
        fi

        if [[ ${OS_TYPE} == "euler" ]];then
            if [[ ! -f ${NETWORK_DIR}/route-$dev ]] && [[ ! -f ${NETWORK_DIR}/route6-$dev ]];then
                echo "No routing file is configured on the $dev network port device."
                return 1
            fi
        fi
    fi

    if [[ $type_route == "ipv4" ]];then
        local contain_flag=0
        if [[ ${OS_TYPE} == "euler" ]];then
            for i in $(cat ${NETWORK_DIR}/route-$dev | sed $'s/\'//g'|grep -w ${des_net} | awk -F"ADDRESS" '{print $2}' | awk -F"=" '{print $1}')
            do
                local to_be_delete_mask=$(cat ${NETWORK_DIR}/route-$dev |sed $'s/\'//g'|grep -w NETMASK${i} | awk -F"NETMASK${i}=" '{print $2}')
                if [[ ${to_be_delete_mask} == ${des_net_mask} ]];then
                    to_be_delete_net_num=${i}
                    contain_flag=1
                    break
                fi
            done
        else
            cat ${NETWORK_DIR}/routes | grep -w ${des_net} | grep -w ${des_net_mask} > /dev/null 2>&1
            if [[ $? -eq 0 ]];then
                contain_flag=1
            fi
        fi

        if [[ ${contain_flag} == 0 ]];then
            if [[ $4 == "inner_function" ]];then
                return 0
            else
                echo "The route to be deleted is not configured on the $dev network port device."
                return 1
            fi
        fi
    fi

    if [[ $type_route == "ipv4" ]];then
        if [[ ${OS_TYPE} == "euler" ]];then
            #删除指定的路由
            local des_file="${NETWORK_DIR}/route-${dev}"
            local des_file_bak="${NETWORK_DIR}/route-${dev}-bak"
            sed "/ADDRESS${to_be_delete_net_num}/d" ${des_file} > ${des_file_bak}
            mv ${des_file_bak} ${des_file}
            sed "/NETMASK${to_be_delete_net_num}/d" ${des_file} > ${des_file_bak}
            mv ${des_file_bak} ${des_file}
            sed "/GATEWAY${to_be_delete_net_num}/d" ${des_file} > ${des_file_bak}
            mv ${des_file_bak} ${des_file}

            #路由文件中的路由编号需要连续，不能中断
            for address_line in $(cat ${des_file} | grep "ADDRESS")
            do
                address_num=$(echo ${address_line} | awk -F"ADDRESS" '{print $2}' | awk -F"=" '{print $1}')
                if [[ ${address_num} > ${to_be_delete_net_num} ]];then
                    address_ip=$(echo ${address_line} | awk -F"=" '{print $2}')
                    address_mask=$(cat ${des_file} | grep -w "NETMASK${address_num}" | awk -F"=" '{print $2}')
                    address_gateway=$(cat ${des_file} | grep -w "GATEWAY${address_num}" | awk -F"=" '{print $2}')
                    sed "/ADDRESS${address_num}/d" ${des_file} > ${des_file_bak}
                    mv ${des_file_bak} ${des_file}
                    sed "/NETMASK${address_num}/d" ${des_file} > ${des_file_bak}
                    mv ${des_file_bak} ${des_file}
                    sed "/GATEWAY${address_num}/d" ${des_file} > ${des_file_bak}
                    mv ${des_file_bak} ${des_file}

                    let address_num=address_num-1
                    echo "ADDRESS${address_num}=${address_ip}" >> ${des_file}
                    echo "NETMASK${address_num}=${address_mask}" >> ${des_file}
                    echo "GATEWAY${address_num}=${address_gateway}" >> ${des_file}
                fi
            done

            chmod 644 ${NETWORK_DIR}/route-$dev
        else
            ipv4_route=$(cat ${NETWORK_DIR}/routes | grep -w ${des_net} | grep -w ${des_net_mask})
            if [[ x$ipv4_route != x ]];then
                sed "/$ipv4_route/d" ${NETWORK_DIR}/routes > ${NETWORK_DIR}/routes-temp
                mv ${NETWORK_DIR}/routes-temp ${NETWORK_DIR}/routes
            fi
            chmod 644 ${NETWORK_DIR}/routes
        fi
    elif [[ $type_route == "ipv6" ]]; then
        ip route del ${des_net}/${des_net_mask} dev ${dev}
        if [[ $? != 0 ]];then
            echo "The route to be deleted is not configured on the $dev network port device."
            return 1
        fi
        if [[ ${OS_TYPE} == "euler" ]];then
            ipv6_route=$(cat "${NETWORK_DIR}route6-$dev" | grep -w ${des_net} | grep -w ${des_net_mask})
            if [[ $ipv6_route == '' ]];then
                echo "The route to be deleted is not configured on the $dev network port device."
                return 1
            fi
            local des_6_file="${NETWORK_DIR}route6-${dev}"
            local des_6_file_bak="${NETWORK_DIR}route6-${dev}-bak"
            sed "/${ipv6_route}/d" ${des_6_file} > ${des_6_file_bak}
            mv ${des_6_file_bak} ${des_6_file}
            chmod 644 ${des_6_file}
        else
            ipv6_route=$(cat ${NETWORK_DIR}/routes | grep -w ${des_net} | grep -w ${des_net_mask})
            if [[ x$ipv6_route != x ]];then
                sed "/$ipv6_route/d" ${NETWORK_DIR}/routes > ${NETWORK_DIR}/routes-temp
                mv ${NETWORK_DIR}/routes-temp ${NETWORK_DIR}/routes
            fi
            chmod 644 ${NETWORK_DIR}/routes
        fi
    fi

    if [[ $4 != "inner_function" ]];then
        echo "The route was deleted successfully."
    fi
}

#*************************************************************
# Name:        show
# Description: Display current network port and route configuration
# Input:  N/A
# Output: N/A
# Return: N/A
# Date:    2019-08-08
#*************************************************************
show()
{
    #print ip and bond
    echo "------------------------------------------------------ Interface ----------------------------------------------------"
    printf "%-20s%-16s%-20s%-16s%-40s%-20s\n" "Iface" "Mode" "IPv4 addr" "Mask" "IPv6 addr" "Protocol State"

    #bond slave
    slave_eth=[]
    slave_count=0
    for eth in $(ifconfig -a | grep -v "^[ ].*$" | grep -v '^$' | awk '{print $1}' | grep -v lo | grep -v vEth)
    do
       eth=$(echo ${eth} | awk -F":" '{printf $1}')
       local eth_cfg="${NETWORK_DIR}/ifcfg-${eth}"
       if [[ ! -f ${eth_cfg} ]];then
           continue
       fi
       master=$(cat ${eth_cfg} | grep "^MASTER" | awk -F"=" '{printf $2}' | sed "s/['|\"]//g")
       if [[ x"$master" != x ]]&&[[ ! ${slave_eth[*]} =~ ${eth} ]];then
            slave_eth[${slave_count}]=${eth}
            let slave_count=slave_count+1
            local master_slave=${eth}
            local master_slave1=${eth}
            for other_eth in $(ifconfig -a | grep -v "^[ ].*$" | grep -v '^$' | awk '{print $1}' | grep -v lo | grep -v ${eth} | grep -v vEth)
            do
                other_eth=$(echo ${other_eth} | awk -F":" '{printf $1}')
                local other_eth_cfg="${NETWORK_DIR}/ifcfg-${other_eth}"
                if [[ ! -f ${other_eth_cfg} ]];then
                    continue
                fi
                other_eth_master=$(cat ${other_eth_cfg} | grep "^MASTER" | awk -F"=" '{printf $2}' | sed "s/['|\"]//g")
                if [[ $other_eth_master == $master ]];then
                    slave_eth[${slave_count}]=${other_eth}
                    let slave_count=slave_count+1
                    master_slave="${master_slave}&${other_eth}"
                    local master_slave2=${other_eth}
                fi
            done
            slave_eth[${slave_count}]=${master}
            let slave_count=slave_count+1
            local master_eth_cfg="${NETWORK_DIR}/ifcfg-${master}"
            if [[ ${OS_TYPE} == "euler" ]];then
                master_ipv4_ipaddr=$(cat ${master_eth_cfg} | grep "^IPADDR" | awk -F"=" '{printf $2}' | sed "s/['|\"]//g")
                master_ipv6_ipaddr=$(cat ${master_eth_cfg} | grep "^IPV6ADDR" | awk -F"=" '{printf $2}' | sed "s/['|\"]//g")
            else
                master_ipv4_ipaddr=$(cat ${master_eth_cfg} | grep -w "IPADDR" | awk -F"=" '{printf $2}' | sed "s/['|\"]//g")
                master_ipv6_ipaddr=$(cat ${master_eth_cfg} | grep -w "IPADDR_0" | awk -F"=" '{printf $2}' | sed "s/['|\"]//g")
            fi
            if [[ x"$master_ipv4_ipaddr" != x ]] || [[ x"$master_ipv6_ipaddr" != x ]];then
                master_slave="("${master_slave}")"
                master_mask=$(cat ${master_eth_cfg} | grep "^NETMASK" | awk -F"=" '{printf $2}' | sed "s/['|\"]//g")
                if [[ x"$master_mask" == x ]];then
                    master_prefix=$(cat ${master_eth_cfg} | grep "^PREFIX" | awk -F"=" '{printf $2}' | sed "s/['|\"]//g")
                    if [[ x"$master_prefix" == x ]];then
                        master_mask="--"
                    else
                        prefix_to_mask ${master_prefix}
                        master_mask=${num_mask}
                    fi
                fi
                if [[ x"$master_ipv4_ipaddr" == x ]];then
                    master_ipv4_ipaddr="--"
                fi
                if [[ x"$master_ipv6_ipaddr" == x ]];then
                    master_ipv6_ipaddr="--"
                fi
                master_state=$(ifconfig $master | grep 'UP' >/dev/null 2>&1; if [[ $? -eq 0 ]];then echo "up"; else echo "down"; fi)
                master_mode=$(cat ${master_eth_cfg} | grep "mode=" | awk -F"mode=" '{printf $2}' | awk -F" miimon=" '{printf $1}')
                master_slave1_state=$(ifconfig ${master_slave1} | grep 'UP' >/dev/null 2>&1; if [[ $? -eq 0 ]];then echo "up"; else echo "down"; fi)
                master_slave2_state=$(ifconfig ${master_slave2} | grep 'UP' >/dev/null 2>&1; if [[ $? -eq 0 ]];then echo "up"; else echo "down"; fi)
                if [[ "${master_mode}" == "active-backup" || "${master_mode}" == "1" ]];then
                    cat /proc/net/bonding/${master} | grep "Currently Active Slave" | grep ${master_slave1} >/dev/null 2>&1
                    if [[ $? -eq 0 ]];then
                        master_slave1_mode="active(${master})"
                    else
                        master_slave1_mode="backup(${master})"
                    fi
                    cat /proc/net/bonding/${master} | grep "Currently Active Slave" | grep ${master_slave2} >/dev/null 2>&1
                    if [[ $? -eq 0 ]];then
                        master_slave2_mode="active(${master})"
                    else
                        master_slave2_mode="backup(${master})"
                    fi
                else
                    master_slave1_mode=${master}
                    master_slave2_mode=${master}
                fi
                printf "%-20s%-16s%-20s%-16s%-40s%-20s\n" "${master}${master_slave}" "${master_mode}" "${master_ipv4_ipaddr}" "${master_mask}" "${master_ipv6_ipaddr}" "${master_state}"
                printf "%-20s%-16s%-20s%-16s%-40s%-20s\n" "${master_slave1}" "${master_slave1_mode}" "--" "--" "--" "${master_slave1_state}"
                printf "%-20s%-16s%-20s%-16s%-40s%-20s\n" "${master_slave2}" "${master_slave2_mode}" "--" "--" "--" "${master_slave2_state}"
            fi
       fi
    done

    showed_eth=[]
    showed_count=0
    for eth in $(ifconfig -a | grep -v "^[ ].*$" | grep -v '^$' | awk '{print $1}' | grep -v lo | grep -v vEth)
    do
        eth=$(echo ${eth} | awk -F":" '{printf $1}')
        if [[ ${showed_eth[*]} =~ ${eth} ]];then
           continue
        fi
        showed_eth[${showed_count}]=${eth}
        let showed_count=showed_count+1
        echo "${slave_eth[*]}" | grep "${eth}" >/dev/null 2>&1
        if [[ $? -eq 0 ]];then
            continue
        fi
        local eth_cfg="${NETWORK_DIR}/ifcfg-${eth}"
        if [[ ! -f ${eth_cfg} ]];then
           continue
        fi
        if [[ ${OS_TYPE} == "euler" ]];then
            eth_ipv4_ipaddr=$(cat ${eth_cfg} | grep "^IPADDR" | awk -F"=" '{printf $2}' | sed "s/['|\"]//g")
            eth_ipv6_ipaddr=$(cat ${eth_cfg} | grep "^IPV6ADDR" | awk -F"=" '{printf $2}' | sed "s/['|\"]//g")
        else
            eth_ipv4_ipaddr=$(cat ${eth_cfg} | grep -w "IPADDR" | awk -F"=" '{printf $2}' | sed "s/['|\"]//g")
            eth_ipv6_ipaddr=$(cat ${eth_cfg} | grep -w "IPADDR_0" | awk -F"=" '{printf $2}' | sed "s/['|\"]//g")
        fi
        if [[ x"$eth_ipv4_ipaddr" != x ]] || [[ x"$eth_ipv6_ipaddr" != x ]];then
            eth_mask=$(cat ${eth_cfg} | grep "^NETMASK" | awk -F"=" '{printf $2}' | sed "s/['|\"]//g")
            if [[ x"$eth_mask" == x ]];then
                eth_prefix=$(cat ${eth_cfg} | grep "^PREFIX" | awk -F"=" '{printf $2}' | sed "s/['|\"]//g")
                if [[ x"$eth_prefix" == x ]];then
                    eth_mask="--"
                else
                    prefix_to_mask ${eth_prefix}
                    eth_mask=${num_mask}
                fi
            fi
            if [[ x"$eth_ipv4_ipaddr" == x ]]; then
                eth_ipv4_ipaddr="--"
            fi
            if [[ x"$eth_ipv6_ipaddr" == x ]]; then
                eth_ipv6_ipaddr="--"
            fi
            eth_state=$(ifconfig $eth | grep 'UP' >/dev/null 2>&1; if [[ $? -eq 0 ]];then echo "up"; else echo "down"; fi)
            eth_mode="--"
            printf "%-20s%-16s%-20s%-16s%-40s%-20s\n" "${eth}" "${eth_mode}" "${eth_ipv4_ipaddr}" "${eth_mask}" "${eth_ipv6_ipaddr}" "${eth_state}"
        fi
    done

    #print route
    echo "-------------------------------- IPv4 Routing table ------------------------------"
    route -n

    echo "-------------------------------- IPv6 Routing table ------------------------------"
    ip -6 route | grep -v error
}

#*************************************************************
# Name:        state
# Description: Display current network port and route configuration
# Input:  N/A
# Output: N/A
# Return: N/A
# Date:    2021-3-26
#*************************************************************
state()
{
  echo "---------------- Server Type ----------------"
  dmidecode -s system-product-name
  echo "------------------ Nic State ------------------"
  printf "%-20s%-20s%-20s\n" "Nic Name" "Link detected" "Speed"
  showed_eth=[]
  showed_count=0
  for eth in $(ifconfig -a | grep -v "^[ ].*$" | grep -v '^$' | awk '{print $1}' | grep -v lo | grep -v vEth)
  do
    eth=$(echo ${eth} | awk -F":" '{printf $1}')
    if [[ ${showed_eth[*]} =~ ${eth} ]];then
        continue
    fi
    showed_eth[${showed_count}]=${eth}
    let showed_count=showed_count+1
    status=$(ethtool $eth | grep 'Link detected' | awk -F ':' '{print $2}')
    speed=$(ethtool $eth | grep 'Speed' | awk -F ':' '{print $2}')
    printf "%-20s%-19s%-19s\n" "${eth}" "${status}" "${speed}"
  done
}

usage()
{
    echo -e "Usage:\n\tsem_tool -cmd <command> [arguments]\n\ncommand:\n\tbond\t\t: Configuring bond\n\tunbond\t\t: unbond configuration\n\thostname\t: Configuring hostname\n\tifconfig\t: Configuring an IP address\n\tunifconfig\t: Clear the IP address and mask of the network port\n\trouteadd\t: Configuring route\n\troutedel\t: Delete route\n\tshow\t\t: Show configuration info\n\tstate\t\t: Show serer and nic status info"
}
usage_bond()
{
    echo -e "Usage:\n\tsem_tool -cmd bond -name <bond name> -nics <nics list> -mode <active-backup|802.3ad> -ip <ip address> -mask <mask address>\nexample:\n\tsem_tool -cmd bond -name bond0 -nics eth0,eth2 -mode active-backup -ip X.X.X.X -mask 255.255.255.0\n"
    echo -e "\tsem_tool -cmd bond -name bond0 -nics eth0,eth2 -mode 802.3ad -ip X.X.X.X -mask 255.255.255.0\n"
}
usage_unbond()
{
    echo -e "Usage:\n\tsem_tool -cmd unbond -name <bond name>\nexample:\n\tsem_tool -cmd unbond -name bond0"
}
usage_hostname()
{
    echo -e "Usage:\n\tsem_tool -cmd hostname -name <hostname>\nexample:\n\tsem_tool -cmd hostname -name Insight-0001"
}
usage_ifconfig()
{
    echo -e "Usage:\n\tsem_tool -cmd ifconfig -name <nic name> -ip <ip address> -mask <mask address>\nexample:\n\tsem_tool -cmd ifconfig -name eth0 -ip X.X.X.X -mask 255.255.255.0\nexample:\n\tsem_tool -cmd ifconfig -name eth0 -ip X:X:X:X:X:X:X:X -mask 64\n"
}
usage_unifconfig()
{
    echo -e "Usage:\n\tsem_tool -cmd unifconfig -name <nic name> -type <ipaddr type>\nexample:\n\tsem_tool -cmd unifconfig -name eth0 -type ipv4"
}
usage_routeadd()
{
    echo -e "Usage:\n\tsem_tool -cmd routeadd -name <nic name> -net <ip address> -mask <mask address> -gateway <gateway address>\n\tsem_tool -cmd routeadd -defaultgw <gateway address>\nexample:\n\tsem_tool -cmd routeadd -name eth0 -net X.X.X.0 -mask 255.255.255.0 -gateway X.X.X.X\n"
    echo -e "\tsem_tool -cmd routeadd -defaultgw X.X.X.X\n"
}
usage_routedel()
{
    echo -e "Usage:\n\tsem_tool -cmd routedel -name <nic name> -net <ip address> -mask <mask address>\nexample:\n\tsem_tool -cmd routedel -name eth0 -net X.X.X.0 -mask 255.255.255.0\n"
}

#*************************************************************
# Name:        get_param
# Description: Get parameters
# Input:  args
# Output: N/A
# Return: 0 -- success; not 0 -- failure
# Date:    2019-08-08
#*************************************************************
get_param()
{
    #获取所有参数，建立数组
    args_name_arr=$arg
    count=0
    for i in $arg;do
        arg_arr[$count]=$i
        count=$((count+1))
    done

    arg_len=${#arg_arr[@]}

    num=0
    while [ $num -lt $arg_len ];do
        if [[ ${arg_arr[$num]} == "-name" ]];then
            name=${arg_arr[$num+1]}
            if [[ ${name} == "lo" ]];then
                echo "Invalid name value."
                logger -t $USER -p local0.info "$FILE_NAME;Failed;${OPERIP:-127.0.0.1};sem_tool $arg"
                return 1
            fi
            if [[ ${arg_arr[1]} != "hostname" ]];then
                pattern="^[0-9A-Za-z]+$"
                if [[ ! ${name} =~ $pattern ]];then
                    echo "The parameter of \"name\" contains special characters, please modify!"
                    logger -t $USER -p local0.info "$FILE_NAME;Failed;${OPERIP:-127.0.0.1};sem_tool $arg"
                    return 1
                fi
            fi
        fi
        if [[ ${arg_arr[$num]} == "-nics" ]];then
            nics=${arg_arr[$num+1]}
            pattern="^[0-9A-Za-z,]+$"
            if [[ ! $nics =~ $pattern ]];then
                echo "The parameter of \"nics\" contains special characters, please modify!"
                logger -t $USER -p local0.info "$FILE_NAME;Failed;${OPERIP:-127.0.0.1};sem_tool $arg"
                return 1
            fi
        fi
        if [[ ${arg_arr[$num]} == "-mode" ]];then
            mode=${arg_arr[$num+1]}
            if [[ $mode != "active-backup" ]]&&[[ $mode != "802.3ad" ]];then
            echo "Invalid mode value."
            return 1
        fi
        fi
        if [[ ${arg_arr[$num]} == "-ip" ]];then
            ip=${arg_arr[$num+1]}
        fi
        if [[ ${arg_arr[$num]} == "-mask" ]];then
            mask=${arg_arr[$num+1]}
        fi
        if [[ ${arg_arr[$num]} == "-gateway" ]];then
            gateway=${arg_arr[$num+1]}
            check_ip $gateway >/dev/null 2>&1
            if [[ $? != 0 ]];then
                echo "gateway $gateway is invalid"
                logger -t $USER -p local0.info "$FILE_NAME;Failed;${OPERIP:-127.0.0.1};sem_tool $arg"
                return 1
            fi
        fi
        if [[ ${arg_arr[$num]} == "-defaultgw" ]];then
            defaultgw=${arg_arr[$num+1]}
            check_ip $defaultgw >/dev/null 2>&1
            if [[ $? != 0 ]];then
                echo "default gateway $defaultgw is invalid"
                logger -t $USER -p local0.info "$FILE_NAME;Failed;${OPERIP:-127.0.0.1};sem_tool $arg"
                return 1
            fi
        fi
        if [[ ${arg_arr[$num]} == "-net" ]];then
            net=${arg_arr[$num+1]}
        fi
        if [[ ${arg_arr[$num]} == "-type" ]];then
            type=${arg_arr[$num+1]}
        fi
        num=$((num+1))
    done
}

#*************************************************************
# Name:        main
# Description: Main interface
# Input:  N/A
# Output: N/A
# Return: 0 -- success; not 0 -- failure
# Date:    2019-08-08
#*************************************************************
main()
{
    cat /etc/os-release | grep -E "EulerOS|Kylin|CTyunOS" >/dev/null 2>&1
    if [[ $? -eq 0 ]];then
        OS_TYPE="euler"
        NETWORK_DIR="/etc/sysconfig/network-scripts/"
    else
        OS_TYPE="sles"
        NETWORK_DIR="/etc/sysconfig/network/"
    fi
    get_param
    if [[ $? != 0 ]];then
        return 1
    fi

    if [[ ${arg_arr[0]} == "-cmd" ]]&&[[ ${arg_arr[1]} == "bond" ]];then
        args_list=("-cmd" "-name" "-nics" "-mode" "-ip" "-mask")
        check_args $args_list $args_name_arr
        if [[ $? != 0 ]];then
            usage_bond
            return 1
        fi
        if [[ $arg_len != "12" ]];then
            echo "The command is invalid."
            usage_bond
            return 1
        fi

        if [[ "${arg_arr[*]}" =~ "-name" ]]&&[[ "${arg_arr[*]}" =~ "-nics" ]]&&[[ "${arg_arr[*]}" =~ "-mode" ]]&&[[ "${arg_arr[*]}" =~ "-ip" ]]&&[[ "${arg_arr[*]}" =~ "-mask" ]]&&[[ x$name != x ]]&&[[ x$nics != x ]]&&[[ x$mode != x ]]&&[[ x$ip != x ]]&&[[ x$mask != x ]];then
            bond $name $nics $mode $ip $mask
        else
            echo "Invalid parameter.The 'bond' command requires at least the following parameters,[-name -nics -mode -ip -mask]"
            usage_bond
        fi
    elif [[ ${arg_arr[0]} == "-cmd" ]]&&[[ ${arg_arr[1]} == "unbond" ]];then
        args_list=("-cmd" "-name")
        check_args $args_list $args_name_arr
        if [[ $? != 0 ]];then
            usage_unbond
            return 1
        fi

        if [[ $arg_len != "4" ]];then
            echo "The command is invalid."
            usage_unbond
            return 1
        fi

        if [[ "${arg_arr[*]}" =~ "-name" ]]&&[[ x$name != x ]];then
            unbond $name
        else
            echo "Invalid parameter."
            usage_unbond
        fi
    elif [[ ${arg_arr[0]} == "-cmd" ]]&&[[ ${arg_arr[1]} == "ifconfig" ]];then
        args_list=("-cmd" "-name" "-ip" "-mask")
        check_args $args_list $args_name_arr
        if [[ $? != 0 ]];then
            usage_ifconfig
            return 1
        fi
        if [[ $arg_len != "8" ]];then
            echo "The command is invalid."
            usage_ifconfig
            return 1
        fi

        if [[ "${arg_arr[*]}" =~ "-name" ]]&&[[ "${arg_arr[*]}" =~ "-ip" ]]&&[[ "${arg_arr[*]}" =~ "-mask" ]]&&[[ x$name != x ]]&&[[ x$ip != x ]]&&[[ x$mask != x ]];then
            ifconfig_cmd $name $ip $mask
        else
            echo "Invalid parameter.The 'ifconfig' command requires at least the following parameters,[-name -ip -mask]"
            usage_ifconfig
        fi
    elif [[ ${arg_arr[0]} == "-cmd" ]]&&[[ ${arg_arr[1]} == "hostname" ]];then
        args_list=("-cmd" "-name")
        check_args $args_list $args_name_arr
        if [[ $? != 0 ]];then
            usage_hostname
            return 1
        fi
        if [[ $arg_len != "4" ]];then
            echo "The command is invalid."
            usage_hostname
            return 1
        fi

        if [[ "${arg_arr[*]}" =~ "-name" ]]&&[[ x$name != x ]];then
            hostname_add
        else
            echo "Invalid parameter."
            usage_hostname
        fi
    elif [[ ${arg_arr[0]} == "-cmd" ]]&&[[ ${arg_arr[1]} == "unifconfig" ]];then
        args_list=("-cmd" "-name" "-type")
        check_args $args_list $args_name_arr
        if [[ $? != 0 ]];then
            usage_unifconfig
            return 1
        fi
        if [[ $arg_len != "6" ]];then
            echo "The command is invalid."
            usage_unifconfig
            return 1
        fi

        if [[ "${arg_arr[*]}" =~ "-name" ]]&&[[ x$name != x ]];then
            unifconfig $name $type
        else
            echo "Invalid parameter."
            usage_unifconfig
        fi
    elif [[ ${arg_arr[0]} == "-cmd" ]]&&[[ ${arg_arr[1]} == "routeadd" ]];then
        if [[ ${arg_arr[*]} =~ "-defaultgw" ]];then
            args_list=("-cmd" "-defaultgw")
            check_args $args_list $args_name_arr
            if [[ $? != 0 ]];then
                usage_routeadd
                return 1
            fi
            if [[ $arg_len != "4" ]];then
                echo "The command is invalid."
                usage_routeadd
                return 1
            fi

            if [[ "${arg_arr[*]}" =~ "-defaultgw" ]]&&[[ x$defaultgw != x ]];then
                config_default_gateway $defaultgw
            else
                echo "Invalid parameter."
                usage_routeadd
            fi
        else
            args_list=("-cmd" "-net" "-mask" "-gateway" "-name")
            check_args $args_list $args_name_arr
            if [[ $? != 0 ]];then
                usage_routeadd
                return 1
            fi
            if [[ $arg_len != "10" ]];then
                echo "The command is invalid."
                usage_routeadd
                return 1
            fi

            if [[ "${arg_arr[*]}" =~ "-net" ]]&&[[ "${arg_arr[*]}" =~ "-name" ]]&&[[ "${arg_arr[*]}" =~ "-gateway" ]]&&[[ "${arg_arr[*]}" =~ "-mask" ]]&&[[ x$net != x ]]&&[[ x$name != x ]]&&[[ x$mask != x ]]&&[[ x$gateway != x ]];then
                config_static_route $name $net $mask $gateway
            else
                echo "Invalid parameter."
                usage_routeadd
            fi
        fi
    elif [[ ${arg_arr[0]} == "-cmd" ]]&&[[ ${arg_arr[1]} == "routedel" ]];then
        args_list=("-cmd" "-net" "-name" "-mask")
        check_args $args_list $args_name_arr
        if [[ $? != 0 ]];then
            usage_routedel
            return 1
        fi
        if [[ $arg_len != "8" ]];then
            echo "The command is invalid."
            usage_routedel
            return 1
        fi

        if [[ "${arg_arr[*]}" =~ "-net" ]]&&[[ "${arg_arr[*]}" =~ "-name" ]]&&[[ "${arg_arr[*]}" =~ "-mask" ]]&&[[ x$net != x ]]&&[[ x$name != x ]]&&[[ x$mask != x ]];then
            delete_static_route $name $net $mask
        else
            echo "Invalid parameter."
            usage_routedel
        fi
    elif [[ ${arg_arr[0]} == "-cmd" ]]&&[[ ${arg_arr[1]} == "show" ]]&&[[ $arg_len = "2" ]];then
        show
    elif [[ ${arg_arr[0]} == "-cmd" ]]&&[[ ${arg_arr[1]} == "state" ]]&&[[ $arg_len = "2" ]];then
        state
    elif [[ ${arg_arr[0]} == "-help" ]];then
        usage
    else
        echo "The command is invalid."
        usage
        return 1
    fi
}

OPERIP=`who am i | awk '{print $NF}' | sed 's/[()]//g'`
FILE_NAME="sem_tool"
if [[ "$(whoami)" != 'root' ]];then
    echo "You do not have the permission to perform the operation. Switch to the root user to perform the operation."
    logger -t $USER -p local0.info "$FILE_NAME;Failed;${OPERIP:-127.0.0.1};sem_tool $arg"
    exit 1
fi

arg="$@"
main
result=$?
if [[ "$result" == "0" ]]
then
    logger -t $USER -p local0.info "$FILE_NAME;Successful;${OPERIP:-127.0.0.1};sem_tool $arg"
else
    logger -t $USER -p local0.info "$FILE_NAME;Failed;${OPERIP:-127.0.0.1};sem_tool $arg"
fi
exit $result
