mirror of
https://github.com/xcat2/xcat-core.git
synced 2026-10-16 16:50:35 +00:00
1e11b6e80f
Add a MTU column to the networks table. If set, this will configure the MTU in DHCP so that nodes will have the correct MTU during provisioning. This is important for large systems to enable jumbo frames to reduce CPU usage when copying diskless images over the network (before the confignics postscript can run to set the desired MTU).
1397 lines
40 KiB
Bash
Executable File
1397 lines
40 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
#This is network lib for confignetwork to configure bond/vlan/bridge
|
|
|
|
awk="awk"
|
|
sed="sed"
|
|
cut="cut"
|
|
sleep="sleep"
|
|
sort="sort"
|
|
ps="ps"
|
|
head="head"
|
|
readlink="readlink"
|
|
basename="basename"
|
|
udevadm="udevadm"
|
|
touch="touch"
|
|
tail="tail"
|
|
dmesg="dmesg"
|
|
grep="grep"
|
|
lspci="lspci"
|
|
ifup="ifup"
|
|
ifdown="ifdown"
|
|
nmcli="nmcli"
|
|
dirname="dirname"
|
|
ip="ip"
|
|
ifconfig="ifconfig"
|
|
brctl="brctl"
|
|
uniq="uniq"
|
|
xargs="xargs"
|
|
modprobe="modprobe"
|
|
|
|
######################################################
|
|
#
|
|
# log lines
|
|
#
|
|
# input : info or warn or error or status
|
|
#
|
|
# output : multiple lines of string
|
|
#
|
|
######################################################
|
|
function log_lines {
|
|
local pcnt=$#
|
|
local __level=$1
|
|
shift
|
|
local cmd=log_${__level}
|
|
|
|
local hit=0
|
|
local OIFS=$IFS
|
|
local NIFS=$'\n'
|
|
IFS=$NIFS
|
|
local __msg
|
|
for __msg in $*
|
|
do
|
|
IFS=$OIFS
|
|
$cmd "$__msg"
|
|
hit=1
|
|
IFS=$NIFS
|
|
done
|
|
IFS=$OIFS
|
|
|
|
[ $hit -eq 0 -a $pcnt -le 1 ] && \
|
|
while read __msg;
|
|
do
|
|
$cmd "$__msg"
|
|
done
|
|
}
|
|
|
|
######################################################
|
|
#
|
|
# error information
|
|
#
|
|
# input : string
|
|
#
|
|
# output : [E]: message
|
|
# return : 0
|
|
#
|
|
######################################################
|
|
function log_error {
|
|
local __msg="$*"
|
|
$log_print_cmd $log_print_arg "[E]: $__msg"
|
|
return 0
|
|
}
|
|
|
|
######################################################
|
|
#
|
|
# warning information
|
|
#
|
|
# input : string
|
|
#
|
|
# output : [W]: message
|
|
# return : 0
|
|
#
|
|
######################################################
|
|
function log_warn {
|
|
local __msg="$*"
|
|
$log_print_cmd $log_print_arg "[W]: $__msg"
|
|
return 0
|
|
}
|
|
|
|
######################################################
|
|
#
|
|
# log information
|
|
#
|
|
# input : string
|
|
#
|
|
# output : [I]: message
|
|
# return : 0
|
|
#
|
|
######################################################
|
|
function log_info {
|
|
local __msg="$*"
|
|
$log_print_cmd $log_print_arg "[I]: $__msg"
|
|
return 0
|
|
}
|
|
|
|
####################################################
|
|
#
|
|
# print command status
|
|
#
|
|
# input : message
|
|
#
|
|
# output : [S]: message
|
|
#
|
|
###################################################
|
|
__my_log_status=
|
|
function log_status {
|
|
local __msg="$*"
|
|
$log_print_cmd $log_print_arg "[S]: $__msg"
|
|
|
|
# call my_log_status hook to triger more processing for status messages.
|
|
if [ -n "$__my_log_status" ]; then
|
|
$__my_log_status "$__msg"
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
####################################################
|
|
#
|
|
# print output
|
|
#
|
|
###################################################
|
|
function log_print_default {
|
|
printf "%s\n" "$*"
|
|
}
|
|
|
|
####################################################
|
|
#
|
|
# handle command
|
|
#
|
|
###################################################
|
|
function set_log_print {
|
|
local cmd="$1"
|
|
if [ -z "$cmd" ]; then
|
|
return 1
|
|
fi
|
|
shift
|
|
local args="$*"
|
|
|
|
eval "log_print_cmd=\"$cmd\""
|
|
eval "log_print_arg=\"$args\""
|
|
}
|
|
|
|
# let log work
|
|
[ -z "$log_print" ] && set_log_print "log_print_default"
|
|
|
|
#####################################################
|
|
#
|
|
# uniq line in cfg files
|
|
#
|
|
# input : -t"str_for_FS" -k"num"
|
|
#
|
|
# output : text have no duplicate linkes
|
|
#
|
|
#####################################################
|
|
function uniq_per_key {
|
|
local fs=""
|
|
local keyno=0
|
|
|
|
local opt
|
|
while getopts "t:k:" opt;
|
|
do
|
|
case $opt in
|
|
t) fs="$OPTARG";;
|
|
k) keyno="$OPTARG";;
|
|
esac
|
|
done
|
|
shift $(($OPTIND - 1))
|
|
|
|
$awk ${fs:+"-F"}"$fs" -v keyno=$keyno '
|
|
BEGIN { cnt=0; }
|
|
{
|
|
if(!($keyno in keya)) {
|
|
keya[$keyno]=cnt;
|
|
cnt+=1;
|
|
};
|
|
idx=keya[$keyno];
|
|
vala[idx]=$0;
|
|
}
|
|
END {
|
|
for(i = 0; i < cnt; i++) {
|
|
print vala[i];
|
|
};
|
|
}'
|
|
}
|
|
|
|
##################################################################################
|
|
#
|
|
# load kernel module
|
|
#
|
|
# input : module=<type> retry=<retry_times> interval=<time> -- <module_parameters>
|
|
#
|
|
################################################################################
|
|
function load_kmod {
|
|
local lines=""
|
|
|
|
local retry=0
|
|
local interval=0
|
|
local module=""
|
|
local module_parameters=""
|
|
|
|
# parser input arguments
|
|
while [ -n "$1" ];
|
|
do
|
|
key=`echo "$1" | cut -s -d= -f1`
|
|
if [ "$key" = "retry" ] || \
|
|
[ "$key" = "interval" ] || \
|
|
[ "$key" = "module" ]; then
|
|
eval "$1"
|
|
elif [ "$1" = "--" ]; then
|
|
shift
|
|
module_parameters="$*"
|
|
break
|
|
fi
|
|
shift
|
|
done
|
|
|
|
if [ -z "$module" ]; then
|
|
log_error "Empty kernel module name to be loaded!"
|
|
fi
|
|
|
|
# load the module
|
|
((i=0))
|
|
while [ ! -d /sys/module/$module ];
|
|
do
|
|
[ $i -eq 0 ] && lines=`$modprobe $module $module_parameters 2>&1`
|
|
$sleep $interval
|
|
((i+=1))
|
|
[ $i -ge $retry ] && break
|
|
done
|
|
if [ $i -ge $retry ]; then
|
|
log_error "Fail to load kernel module \"$module\""
|
|
echo "$lines" \
|
|
| $sed -e 's/^/>> /g' \
|
|
| log_lines info
|
|
$false
|
|
fi
|
|
}
|
|
|
|
#################################################################
|
|
#
|
|
# query attribute from networks table
|
|
#
|
|
# input : fkey=<number> vkey=<attribute> fval=<number>
|
|
#
|
|
# output : found attribute value
|
|
#
|
|
###############################################################
|
|
function query_nicnetworks {
|
|
local fkey=2
|
|
local vkey=$1
|
|
local fval=1
|
|
|
|
# parser input arguments
|
|
while [ -n "$1" ];
|
|
do
|
|
key=`echo "$1" | cut -s -d= -f1`
|
|
if [ "$key" = "fkey" ] || \
|
|
[ "$key" = "vkey" ] || \
|
|
[ "$key" = "fval" ]; then
|
|
eval "$1"
|
|
fi
|
|
shift
|
|
done
|
|
|
|
local vval=`echo "$NICNETWORKS" | $sed -e 's/,/\n/g' \
|
|
| $awk -v fkey=$fkey -v vkey=$vkey -v fval=$fval -F'!' \
|
|
'$fkey == vkey {r=$fval;} END{print r;}'`
|
|
[ -n "$vval" ] && echo "$vval"
|
|
}
|
|
|
|
###############################################################
|
|
#
|
|
# query networks nic from networks table
|
|
#
|
|
# input : netname, such as 30_0_0_0-255_0_0_0
|
|
#
|
|
# output : nic
|
|
#
|
|
###########################################################
|
|
function query_nicnetworks_nic {
|
|
query_nicnetworks fkey=2 vkey=$1 fval=1
|
|
}
|
|
|
|
#############################################################
|
|
#
|
|
# query netname from networks table
|
|
#
|
|
# input : nic
|
|
#
|
|
# output : netname
|
|
#
|
|
#############################################################
|
|
function query_nicnetworks_net {
|
|
query_nicnetworks fkey=1 vkey=$1 fval=2
|
|
}
|
|
#######################################################################################
|
|
#
|
|
# get network attribute from NETWORKS_LINEX
|
|
#
|
|
# NETWORKS_LINES=2
|
|
# NETWORKS_LINE1='netname=10_0_0_0-255_255_255_0||net=10.0.0.0||mask=255.255.255.0||mgtifname=eth2||gateway=<xcatmaster>||dhcpserver=||tftpserver=10.0.0.153||nameservers=||ntpservers=||logservers=||dynamicrange=10.0.0.1-10.0.0.254||staticrange=||staticrangeincrement=||nodehostname=||ddnsdomain=||vlanid=||domain=||mtu=||disable=||comments=__BEAT_IPRANGE_10.0.0.1-10.0.0.254'
|
|
# NETWORKS_LINE2='netname=10_9_10_0-255_255_255_0||net=10.9.10.0||mask=255.255.255.0||mgtifname=eth1:1||gateway=<xcatmaster>||dhcpserver=||tftpserver=10.9.10.1||nameservers=||ntpservers=||logservers=||dynamicrange=||staticrange=10.9.10.11-10.9.10.30||staticrangeincrement=1||nodehostname=||ddnsdomain=||vlanid=||domain=||mtu=||disable=||comments=__BEAT_IPRANGE_10.9.10.11-10.9.10.30'
|
|
#
|
|
# input : network_name attribute_name
|
|
#
|
|
# output : attribute value
|
|
#
|
|
########################################################################################
|
|
function get_network_attr {
|
|
local netname=$1
|
|
local attrname=$2
|
|
|
|
local netline=""
|
|
local index=1
|
|
while [ $index -le $NETWORKS_LINES ]
|
|
do
|
|
eval netline=\$NETWORKS_LINE$index
|
|
echo "$netline" | grep -sq ".*netname=$netname" && break;
|
|
((index+=1))
|
|
done
|
|
|
|
if [ $index -le $NETWORKS_LINES ]; then
|
|
echo "$netline" | $sed -e 's/||/\n/g' | $awk -F'=' '$1 == "'$attrname'" {print $2}'
|
|
else
|
|
log_error "Fail to get \"$attrname\" for network \"$netname\""
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
#######################################################################
|
|
#
|
|
# get mac
|
|
#
|
|
# input : nic name
|
|
#
|
|
# output : its mac
|
|
#
|
|
######################################################################
|
|
function get_mac {
|
|
declare ifname=$1
|
|
# if bond slave interface, get its real mac
|
|
if [ -L /sys/class/net/$ifname/master ]; then
|
|
declare ifmaster=`ls -l /sys/class/net/$ifname/master | $sed -e 's/^.*virtual\/net\///g'`
|
|
grep -E "^Slave Interface:|^Permanent HW addr:" /proc/net/bonding/$ifmaster \
|
|
| grep -A1 ": $ifname" | $tail -n1 | $awk '{print $4}'
|
|
|
|
# confirm the interface does exist before running "ip link show" command
|
|
elif [ -L /sys/class/net/$ifname ]; then
|
|
$ip link show $ifname | grep "link\/ether" | $awk '{print $2}'
|
|
fi
|
|
}
|
|
|
|
####################################################################
|
|
#
|
|
# wait for nic state
|
|
#
|
|
# input : <nic> <expect_state> <try_count> <sleep_time>
|
|
#
|
|
####################################################################
|
|
function wait_for_ifstate {
|
|
local ifname=$1
|
|
local ifstate=$2
|
|
local tryCnt=$3
|
|
local tryInt=$4
|
|
local state=""
|
|
local i
|
|
((i=0))
|
|
while [ $i -lt $tryCnt ]
|
|
do
|
|
lines=`$ip link show $ifname`
|
|
echo "$lines" | grep -sq "state $ifstate"
|
|
rc=$?
|
|
[ $rc -eq 0 ] && break
|
|
|
|
if [ $tryInt -ne 0 ]; then
|
|
state=`echo "$lines" | grep "state" | $sed -e 's/^.*state \([a-zA-Z]\+\) .*$/\1/g'`
|
|
log_info "State of \"$ifname\" was \"$state\" instead of expected \"$ifstate\". Wait $i of $tryCnt with interval $tryInt."
|
|
fi
|
|
$sleep $tryInt
|
|
((i+=1))
|
|
done
|
|
test $i -lt $tryCnt
|
|
}
|
|
|
|
##################################################################
|
|
#
|
|
# create ifcfg-* files
|
|
#
|
|
# input : ifname=<ifname> nwdir="cfg_file_dir" xcatnet=<xcatnet> _ipaddr=<ip> _netmask=<mask> inattrs=<attrs>
|
|
#
|
|
# return : 0 success
|
|
#
|
|
#################################################################
|
|
function create_persistent_ifcfg {
|
|
log_info "create_persistent_ifcfg $@"
|
|
|
|
local nwdir="/etc/sysconfig/network-scripts"
|
|
|
|
local ifname=""
|
|
local xcatnet=""
|
|
local _ipaddr=""
|
|
local _netmask=""
|
|
local inattrs=""
|
|
|
|
# parser input arguments
|
|
while [ -n "$1" ];
|
|
do
|
|
key=`echo "$1" | cut -s -d= -f1`
|
|
if [ "$key" = "ifname" ] || \
|
|
[ "$key" = "nwdir" ] || \
|
|
[ "$key" = "xcatnet" ] || \
|
|
[ "$key" = "_ipaddr" ] || \
|
|
[ "$key" = "_netmask" ] || \
|
|
[ "$key" = "inattrs" ]; then
|
|
eval "$1"
|
|
fi
|
|
shift
|
|
done
|
|
|
|
local fcfg=$nwdir/ifcfg-$ifname
|
|
# if no ip addr/mask specified explicitely, search in xCAT environment.
|
|
if [ -n "$xcatnet" ]; then
|
|
if [ -z "$_ipaddr" ]; then
|
|
ifname_exp=`query_nicnetworks_nic $xcatnet`
|
|
# search NICIPS for static config
|
|
if [ x"$ifname_exp" == x ]; then
|
|
ifname_exp=$ifname
|
|
fi
|
|
_ipaddr=`echo "$NICIPS" | $sed -e 's/,/\n/g' \
|
|
| $awk -vifname=$ifname_exp -F'!' '$1 == ifname{print $2}' \
|
|
| $awk -F'|' '{print $1}'`
|
|
fi
|
|
if [ -z "$_netmask" ]; then
|
|
_netmask=`get_network_attr $xcatnet mask`
|
|
fi
|
|
fi
|
|
local attrs=""
|
|
attrs=${attrs}${attrs:+,}"DEVICE=$ifname"
|
|
attrs=${attrs}${attrs:+,}"BOOTPROTO=static"
|
|
[ -n "$_ipaddr" ] && \
|
|
attrs=${attrs}${attrs:+,}"IPADDR=$_ipaddr"
|
|
[ -n "$_netmask" ] && \
|
|
attrs=${attrs}${attrs:+,}"NETMASK=$_netmask"
|
|
|
|
# NetworkManager attributes
|
|
attrs=${attrs}${attrs:+,}"NAME=$ifname"
|
|
|
|
# some auto-detected attributes
|
|
# - mark vlan interfac3
|
|
if [ -f /proc/net/vlan/$ifname ]; then
|
|
attrs=${attrs}${attrs:+,}"VLAN=yes"
|
|
fi
|
|
|
|
# - mark bond interfac3
|
|
# https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Networking_Guide/sec-Network_Bonding_Using_the_Command_Line_Interface.html#sec-Create_a_Channel_Bonding_Interface
|
|
if [ -f /proc/net/bonding/$ifname ]; then
|
|
attrs=${attrs}${attrs:+,}"BONDING_MASTER=yes"
|
|
fi
|
|
|
|
# - mark mac address for non-virtual interface.
|
|
# Note: ignore HWADDR attribute if it's a bond slave.
|
|
if ! echo "$inattrs" | grep -sq 'SLAVE="\?yes"\?'; then
|
|
mac=`get_mac $ifname`
|
|
if [ -n "$mac" -a ! -d /sys/devices/virtual/net/$ifname ]; then
|
|
attrs=${attrs}${attrs:+,}"HWADDR=$mac"
|
|
fi
|
|
fi
|
|
|
|
# record manual and auto attributes first
|
|
# since input attributes might overwrite them.
|
|
#
|
|
# record input attributes later. They will overwrite
|
|
# previous generated attributes if duplicate.
|
|
[ -f $fcfg ] && mv -f $fcfg `dirname $fcfg`/.`basename $fcfg`.bak
|
|
echo "$attrs,$inattrs" \ | $sed -e 's/,/\n/g' | grep -v "^$" \
|
|
| $sed -e 's/=/="/' -e 's/ *$/"/' \
|
|
| uniq_per_key -t'=' -k1 >$fcfg
|
|
local rc=$?
|
|
|
|
# log for debug
|
|
echo "['ifcfg-${ifname}']" >&2
|
|
cat $fcfg | $sed -e 's/^/ >> /g' | log_lines info
|
|
return $rc
|
|
}
|
|
|
|
################################################################################
|
|
#
|
|
# get all physical network devices
|
|
# remove duplicate entries while keep their order.
|
|
#
|
|
# input : <cat1>=<filter1_params>,<cat2>=<filter2_params>
|
|
#
|
|
###############################################################################
|
|
function expand_ports {
|
|
log_info "expand_ports $@"
|
|
|
|
local i
|
|
local ports=`echo "$1" | $sed -e 's/,/ /g'`
|
|
|
|
# get all interfaces
|
|
local allifs=""
|
|
|
|
# get all physical network devices
|
|
local alldevs=""
|
|
|
|
local rports=""
|
|
local p
|
|
for p in $ports
|
|
do
|
|
if echo "$p" | grep -sq ".*="; then
|
|
key=`echo "$p" | cut -s -d= -f1`
|
|
val=`echo "$p" | cut -s -d= -f2-`
|
|
|
|
# include direct non-virtual interface
|
|
elif [ -L /sys/class/net/$p -a ! -d /sys/devices/virtual/net/$p ]; then
|
|
rports=${rports}${rports:+,}$p
|
|
|
|
# warn other direct interface, such as virtual
|
|
else
|
|
log_warn "Invalid member port \"$p\". Ignore it!"
|
|
fi
|
|
done
|
|
|
|
# remove duplicate entries while keep their order.
|
|
[ -n "$rports" ] && echo "$rports" | \
|
|
$sed -e 's/,\+/,/g' -e 's/^,//' -e 's/,/\n/g' \
|
|
| uniq_per_key -t" " -k0 \
|
|
| $xargs | $sed -e 's/ /,/g'
|
|
}
|
|
|
|
###########################################################################
|
|
#
|
|
# migrate ip from sports to ifname
|
|
#
|
|
# input : ifname=<current_nic> sports=<pre_ports>
|
|
#
|
|
#########################################################################
|
|
function migrate_ip {
|
|
log_info "migrate_ip $@"
|
|
|
|
local ifname=""
|
|
local sports=""
|
|
|
|
# parser input arguments
|
|
while [ -n "$1" ];
|
|
do
|
|
key=`echo "$1" | $cut -s -d= -f1`
|
|
if [ "$key" = "ifname" ] || \
|
|
[ "$key" = "sports" ]; then
|
|
eval "$1"
|
|
fi
|
|
shift
|
|
done
|
|
|
|
[ -n "$sports" ] && sports=`echo "$sports" | $sed -e 's/,/ /g'`
|
|
|
|
|
|
# loop for every source port and migrate ips and routes
|
|
local p=""
|
|
for p in $sports
|
|
do
|
|
[ -L /sys/class/net/$p ] || continue
|
|
|
|
|
|
#route for now
|
|
saveroutes=`$ip route | grep default | grep "dev $p"| grep via | $sed -e 's/dev .*//'`
|
|
|
|
saveips=`$ip addr show dev $p scope global | grep inet | $sed -e 's/inet.//' | $sed -e 's/[^ ]*$//'`
|
|
if [ -n "$saveips" ]; then
|
|
# Migrate ip address from source ports to target port
|
|
OIFS=$IFS
|
|
IFS=$'\n'
|
|
for line in $saveips
|
|
do
|
|
newline=`echo $line|sed 's/dynamic//g'`
|
|
eval "$ip addr del dev $p $newline"
|
|
log_info "$ip addr del dev $p $newline"
|
|
eval "$ip addr add dev $ifname $newline"
|
|
log_info "$ip addr add dev $ifname $newline"
|
|
done
|
|
IFS=$OIFS
|
|
fi
|
|
|
|
# restore saved routes which assume to be applied to the target interface
|
|
if [ -n "$saveroutes" ]; then
|
|
eval "$ip route add $saveroutes"
|
|
log_info "$ip route add $saveroutes"
|
|
fi
|
|
done
|
|
|
|
}
|
|
|
|
|
|
|
|
###############################################################################
|
|
#
|
|
# create bridge
|
|
#
|
|
# input : bridge name
|
|
#
|
|
##############################################################################
|
|
function add_br() {
|
|
|
|
BNAME=$1
|
|
BRIDGE=$2
|
|
|
|
if [[ $BRIDGE == "bridge_ovs" ]]; then
|
|
type brctl >/dev/null 2>/dev/null || echo "There is no ovs-vsctl" >&2 && exit 1
|
|
log_info "ovs-vsctl add-br $BNAME"
|
|
ovs-vsctl add-br $BNAME
|
|
elif [[ $BRIDGE == "bridge" ]]; then
|
|
type brctl >/dev/null 2>/dev/null || echo "There is no brctl" >&2 && exit 1
|
|
log_info "brctl addbr $BNAME"
|
|
brctl addbr $BNAME
|
|
log_info "brctl stp $BNAME on"
|
|
brctl stp $BNAME on
|
|
fi
|
|
}
|
|
|
|
###############################################################################
|
|
#
|
|
# create add port for bridge
|
|
#
|
|
# input : bridge name
|
|
# port name
|
|
#
|
|
##############################################################################
|
|
function add_if() {
|
|
BNAME=$1
|
|
PORT=$2
|
|
BRIDGE=$3
|
|
|
|
if [[ $BRIDGE == "bridge_ovs" ]]; then
|
|
log_info "ovs-vsctl add-br $BNAME"
|
|
ovs-vsctl add-br $BNAME
|
|
|
|
log_info "ovs-vsctl add-port $BNAME $PORT"
|
|
ovs-vsctl add-port $BNAME $PORT
|
|
elif [[ $BRIDGE == "bridge" ]]; then
|
|
log_info "brctl addif $BNAME $PORT"
|
|
brctl addif $BNAME $PORT
|
|
fi
|
|
|
|
|
|
}
|
|
|
|
###############################################################################
|
|
#
|
|
# create raw vlan for bridge
|
|
#
|
|
# input : ifname=<ifname> _mtu=<mtu> _bridge=<bridge_name>
|
|
#
|
|
###############################################################################
|
|
function create_raw_vlan_for_br {
|
|
|
|
log_info "create_raw_vlan_interface $@"
|
|
local lines=""
|
|
|
|
local ifname=""
|
|
local _mtu=""
|
|
local _bridge=""
|
|
|
|
# parser input arguments
|
|
while [ -n "$1" ];
|
|
do
|
|
key=`echo "$1" | $cut -s -d= -f1`
|
|
if [ "$key" = "ifname" ] || \
|
|
[ "$key" = "_mtu" ] || \
|
|
[ "$key" = "_bridge" ]; then
|
|
eval "$1"
|
|
fi
|
|
shift
|
|
done
|
|
|
|
#handle vlanid
|
|
local vlanid=""
|
|
if echo "$ifname" | grep -sq ".*\.[0-9]\+"; then
|
|
vlanid=`echo "$ifname" | $cut -s -d. -f2-`
|
|
ifname=`echo "$ifname" | $cut -s -d. -f1`
|
|
elif echo "$ifname" | grep -sq ".*vla\?n\?[0-9]\+"; then
|
|
vlanid=`echo "$ifname" | $sed -e 's/^\(.*\)vla\?n\?\([0-9]\+\)$/\2/'`
|
|
ifname=`echo "$ifname" | $sed -e 's/^\(.*\)vla\?n\?\([0-9]\+\)$/\1/'`
|
|
fi
|
|
|
|
# generate raw vlan interface definition
|
|
cfg=""
|
|
cfg="${cfg}${cfg:+,}ONBOOT=yes"
|
|
|
|
if grep -q -i "release 6" /etc/redhat-release ; then
|
|
cfg="${cfg}${cfg:+,}NM_CONTROLLED=no"
|
|
fi
|
|
|
|
cfg="${cfg}${cfg:+,}USERCTL=no"
|
|
cfg="${cfg}${cfg:+,}TYPE=Ethernet"
|
|
cfg="${cfg}${cfg:+,}VLAN=yes"
|
|
cfg="${cfg}${cfg:+,}BRIDGE=$_bridge"
|
|
[ -n "$_mtu" ] && \
|
|
cfg="${cfg}${cfg:+,}MTU=$_mtu"
|
|
create_persistent_ifcfg \
|
|
ifname=$ifname.$vlanid \
|
|
inattrs="$cfg"
|
|
|
|
}
|
|
|
|
###############################################################################
|
|
#
|
|
# create raw bond for bridge
|
|
#
|
|
# input : ifname=<ifname> _mtu=<mtu> _bonding_opts=<string> _bridge=<bridge_name>
|
|
#
|
|
###############################################################################
|
|
function create_raw_bond_for_br {
|
|
|
|
log_info "create_raw_bond_interface $@"
|
|
local lines=""
|
|
local ifname=""
|
|
local _mtu=""
|
|
local _bridge=""
|
|
local _bonding_opts=""
|
|
# parser input arguments
|
|
while [ -n "$1" ];
|
|
do
|
|
key=`echo "$1" | $cut -s -d= -f1`
|
|
if [ "$key" = "ifname" ] || \
|
|
[ "$key" = "_mtu" ] || \
|
|
[ "$key" = "_bonding_opts" ] || \
|
|
[ "$key" = "_bridge" ]; then
|
|
eval "$1"
|
|
fi
|
|
shift
|
|
done
|
|
|
|
# migrate bond ports ip and route to bridge
|
|
#migrate_ip ifname=$ifname sports="$_bridge"
|
|
|
|
# define and bring up raw bond interface
|
|
cfg=""
|
|
cfg="${cfg}${cfg:+,}ONBOOT=yes"
|
|
|
|
if grep -q -i "release 6" /etc/redhat-release ; then
|
|
cfg="${cfg}${cfg:+,}NM_CONTROLLED=no"
|
|
fi
|
|
|
|
cfg="${cfg}${cfg:+,}USERCTL=no"
|
|
cfg="${cfg}${cfg:+,}TYPE=Bond"
|
|
cfg="${cfg}${cfg:+,}BONDING_MASTER=yes"
|
|
cfg="${cfg}${cfg:+,}BONDING_OPTS='$_bonding_opts'"
|
|
cfg="${cfg}${cfg:+,}BOOTPROTO=none"
|
|
cfg="${cfg}${cfg:+,}DHCLIENTARGS='-timeout 200'"
|
|
cfg="${cfg}${cfg:+,}BRIDGE=$_bridge"
|
|
[ -n "$_mtu" ] && \
|
|
cfg="${cfg}${cfg:+,}MTU=$_mtu"
|
|
create_persistent_ifcfg \
|
|
ifname=$ifname \
|
|
inattrs="$cfg"
|
|
}
|
|
|
|
###############################################################################
|
|
#
|
|
# create bridge
|
|
#
|
|
# input : ifname=<ifname> xcatnet=<xcat_network> _ipaddr=<ip> _netmask=<netmask> _port=<port> _pretype=<nic_type> _brtype=<bridge|bridge_ovs> _mtu=<mtu> _bridge=<bridge_name>
|
|
#
|
|
###############################################################################
|
|
function create_bridge_interface {
|
|
|
|
log_info "create_bridge_interface $@"
|
|
local lines=""
|
|
local ifname="" #current bridge
|
|
local xcatnet=""
|
|
local _ipaddr=""
|
|
local _netmask=""
|
|
local _brtype=""
|
|
local _pretype=""
|
|
local _port="" #pre nic
|
|
local _mtu=""
|
|
|
|
# parser input arguments
|
|
while [ -n "$1" ];
|
|
do
|
|
key=`echo "$1" | $cut -s -d= -f1`
|
|
if [ "$key" = "ifname" ] || \
|
|
[ "$key" = "xcatnet" ] || \
|
|
[ "$key" = "_ipaddr" ] || \
|
|
[ "$key" = "_netmask" ] || \
|
|
[ "$key" = "_brtype" ] || \
|
|
[ "$key" = "_pretype" ] || \
|
|
[ "$key" = "_port" ] || \
|
|
[ "$key" = "_mtu" ]; then
|
|
eval "$1"
|
|
fi
|
|
shift
|
|
done
|
|
|
|
# let's query "nicnetworks" table about its target "xcatnet"
|
|
if [ -n "$ifname" -a -z "$xcatnet" -a -z "$_ipaddr" ]; then
|
|
xcatnet=`query_nicnetworks_net $ifname`
|
|
log_info "Pickup xcatnet, \"$xcatnet\", from NICNETWORKS for interface \"$ifname\"."
|
|
fi
|
|
|
|
if [ x$_pretype == "xethernet" ]; then
|
|
create_raw_ethernet_for_br \
|
|
ifname=$_port \
|
|
_bridge=$ifname \
|
|
_mtu=$_mtu
|
|
elif [ x$_pretype == "xvlan" ]; then
|
|
create_raw_vlan_for_br \
|
|
ifname=$_port \
|
|
_bridge=$ifname \
|
|
_mtu=$_mtu
|
|
|
|
elif [ x$_pretype == "xbond" ]; then
|
|
create_raw_bond_for_br \
|
|
ifname=$_port \
|
|
_bridge=$ifname \
|
|
_mtu=$_mtu \
|
|
_bonding_opts="mode=802.3ad miimon=100"
|
|
fi
|
|
|
|
add_br $ifname $_brtype
|
|
add_if $ifname $_port $_brtype
|
|
# setup interface on the fly
|
|
[ -n "$_mtu" ] && $ip link set $ifname mtu $_mtu
|
|
|
|
# log for debug
|
|
|
|
migrate_ip ifname=$ifname sports="$_port"
|
|
|
|
# define and bring up bridge interface, if required.
|
|
# generate bridge interface definition
|
|
cfg=""
|
|
cfg="${cfg}${cfg:+,}ONBOOT=yes"
|
|
cfg="${cfg}${cfg:+,}STP=on"
|
|
if grep -q -i "release 6" /etc/redhat-release ; then
|
|
cfg="${cfg}${cfg:+,}NM_CONTROLLED=no"
|
|
fi
|
|
|
|
if [ x$_brtype == x"bridge" ]; then
|
|
|
|
cfg="${cfg}${cfg:+,}TYPE=Bridge"
|
|
elif [ x$_brtype == x"bridge_ovs" ]; then
|
|
|
|
cfg="${cfg}${cfg:+,}TYPE=OVSBridge"
|
|
|
|
fi
|
|
[ -n "$_mtu" ] && \
|
|
cfg="${cfg}${cfg:+,}MTU=$_mtu"
|
|
create_persistent_ifcfg \
|
|
ifname=$ifname \
|
|
xcatnet=$xcatnet \
|
|
inattrs="$cfg"
|
|
|
|
# bring up interface formally
|
|
lines=`$ifdown $ifname; $ifup $ifname`
|
|
rc=$?
|
|
if [ $rc -ne 0 ]; then
|
|
log_warn "ifup $ifname failed with return code equals to $rc"
|
|
echo "$lines" \
|
|
| $sed -e 's/^/>> /g' \
|
|
| log_lines info
|
|
fi
|
|
return $rc
|
|
|
|
}
|
|
###############################################################################
|
|
#
|
|
# create ethernet
|
|
#
|
|
# input : ifname=<ifname> slave_ports=<ports> xcatnet=<xcatnetwork> _ipaddr=<ip> _netmask=<netmask> _mtu=<mtu> _bridge=<bridge_name> vlanid=<vlanid>
|
|
#
|
|
###############################################################################
|
|
function create_ethernet_interface {
|
|
log_info "create_ethernet_interface $@"
|
|
|
|
local lines=""
|
|
local ifname=""
|
|
local mport=""
|
|
local xcatnet=""
|
|
local _ipaddr=""
|
|
local _netmask=""
|
|
local _mtu=""
|
|
|
|
# parser input arguments
|
|
while [ -n "$1" ];
|
|
do
|
|
key=`echo "$1" | $cut -s -d= -f1`
|
|
if [ "$key" = "ifname" ] || \
|
|
[ "$key" = "mport" ] || \
|
|
[ "$key" = "xcatnet" ] || \
|
|
[ "$key" = "_ipaddr" ] || \
|
|
[ "$key" = "_netmask" ] || \
|
|
[ "$key" = "_mtu" ]; then
|
|
eval "$1"
|
|
fi
|
|
shift
|
|
done
|
|
if [ -z "$ifname" -a -z "$mport" ]; then
|
|
log_error "No valid \"ifname\" or \"mport\". Abort!"
|
|
return 1
|
|
|
|
# if caller only knows the real "mport", assume it is the defined "ifname".
|
|
elif [ -z "$ifname" ]; then
|
|
log_info "Assume defined nic is the member nic \"$mport\"."
|
|
ifname=$mport
|
|
fi
|
|
# let's query "nicnetworks" table about its target "xcatnet"
|
|
if [ -n "$ifname" -a -z "$xcatnet" ]; then
|
|
xcatnet=`query_nicnetworks_net $ifname`
|
|
fi
|
|
|
|
# Verify if there could be valid ipaddr/netmask
|
|
if [ -z "$xcatnet" -a -z "$_ipaddr" ]; then
|
|
log_error "No valid \"xcatnet\" or explicite \"_ipaddr/_netmask\". Abort!"
|
|
return 1
|
|
fi
|
|
|
|
# define and bring up interface
|
|
cfg=""
|
|
cfg="${cfg}${cfg:+,}ONBOOT=yes"
|
|
|
|
if grep -q -i "release 6" /etc/redhat-release ; then
|
|
cfg="${cfg}${cfg:+,}NM_CONTROLLED=no"
|
|
fi
|
|
|
|
cfg="${cfg}${cfg:+,}USERCTL=no"
|
|
cfg="${cfg}${cfg:+,}TYPE=Ethernet"
|
|
[ -n "$_mtu" ] && \
|
|
cfg="${cfg}${cfg:+,}MTU=$_mtu"
|
|
create_persistent_ifcfg \
|
|
ifname=$ifname \
|
|
xcatnet=$xcatnet \
|
|
_ipaddr=$_ipaddr \
|
|
_netmask=$_netmask \
|
|
inattrs="$cfg"
|
|
|
|
# bring up interface formally
|
|
true || lines=`$ifdown $ifname; $ifup $ifname`
|
|
rc=$?
|
|
if [ $rc -ne 0 ]; then
|
|
log_warn "ifup $ifname failed with return code equals to $rc"
|
|
echo "$lines" \
|
|
| $sed -e 's/^/>> /g' \
|
|
| log_lines info
|
|
fi
|
|
|
|
return $rc
|
|
}
|
|
|
|
###############################################################################
|
|
#
|
|
# create vlan
|
|
#
|
|
# input : ifname=<ifname> slave_ports=<ports> xcatnet=<xcatnetwork> _ipaddr=<ip> _netmask=<netmask> _mtu=<mtu> _bridge=<bridge_name> vlanid=<vlanid>
|
|
# return : 0 success
|
|
#
|
|
###############################################################################
|
|
function create_vlan_interface {
|
|
log_info "create_vlan_interface $@"
|
|
|
|
local lines=""
|
|
local ifname=""
|
|
local vlanid=""
|
|
local xcatnet=""
|
|
local _ipaddr=""
|
|
local _netmask=""
|
|
local _mtu=""
|
|
local _bridge=""
|
|
# in case it's on top of bond, we need to migrate ip from its
|
|
# member vlan ports.
|
|
local slave_ports=""
|
|
# parser input arguments
|
|
while [ -n "$1" ];
|
|
do
|
|
key=`echo "$1" | $cut -s -d= -f1`
|
|
if [ "$key" = "ifname" ] || \
|
|
[ "$key" = "slave_ports" ] || \
|
|
[ "$key" = "xcatnet" ] || \
|
|
[ "$key" = "_ipaddr" ] || \
|
|
[ "$key" = "_netmask" ] || \
|
|
[ "$key" = "_mtu" ] || \
|
|
[ "$key" = "_bridge" ] || \
|
|
[ "$key" = "vlanid" ]; then
|
|
eval "$1"
|
|
fi
|
|
shift
|
|
done
|
|
|
|
if [ -z "$vlanid" ]; then
|
|
log_error "No \"vlanid\" specificd for vlan interface. Abort!"
|
|
return 1
|
|
fi
|
|
|
|
# let's query "nicnetworks" table about its target "xcatnet"
|
|
if [ -n "$ifname" -a -z "$xcatnet" -a -z "$_ipaddr" -a -n "$vlanid" ]; then
|
|
xcatnet=`query_nicnetworks_net $ifname.$vlanid`
|
|
log_info "Pickup xcatnet, \"$xcatnet\", from NICNETWORKS for interface \"$ifname\"."
|
|
fi
|
|
|
|
|
|
#load the 8021q module if not loaded.
|
|
load_kmod module=8021q retry=10 interval=0.5
|
|
|
|
# create vlan on top of target interface if that's required.
|
|
((i=0))
|
|
while [ ! -f /proc/net/vlan/$ifname.$vlanid ];
|
|
do
|
|
if [ $i -eq 0 ]; then
|
|
# alternative cmd to "vconfig add $ifname $vlanid"
|
|
$ip link add link $ifname name $ifname.$vlanid type vlan id $(( 10#$vlanid ))
|
|
log_info "$ip link add link $ifname name $ifname.$vlanid type vlan id $(( 10#$vlanid ))"
|
|
fi
|
|
$sleep 0.5
|
|
((i+=1))
|
|
[ $i -ge 10 ] && break
|
|
done
|
|
if [ $i -ge 10 ]; then
|
|
log_error "Fail to create vlan interface \"$ifname.$vlanid\""
|
|
return 1
|
|
fi
|
|
|
|
# setup interface
|
|
[ -n "$_mtu" ] && $ip link set $ifname.$vlanid mtu $_mtu
|
|
$ip link set $ifname.$vlanid up
|
|
log_info "$ip link set $ifname.$vlanid up"
|
|
wait_for_ifstate $ifname.$vlanid UP 200 1
|
|
rc=$?
|
|
|
|
_g_migrate_ip=1
|
|
|
|
|
|
[ $_g_migrate_ip -eq 1 ] && \
|
|
[ -n "$slave_ports" ] && \
|
|
migrate_ip ifname=$ifname.$vlanid sports="$slave_ports"
|
|
|
|
# define and bring up vlan interface on top of raw bond interface, if required.
|
|
# generate vlan interface definition
|
|
cfg=""
|
|
cfg="${cfg}${cfg:+,}ONBOOT=yes"
|
|
|
|
if grep -q -i "release 6" /etc/redhat-release ; then
|
|
cfg="${cfg}${cfg:+,}NM_CONTROLLED=no"
|
|
fi
|
|
|
|
cfg="${cfg}${cfg:+,}USERCTL=no"
|
|
cfg="${cfg}${cfg:+,}TYPE=Ethernet"
|
|
cfg="${cfg}${cfg:+,}VLAN=yes"
|
|
[ -n "$_mtu" ] && \
|
|
cfg="${cfg}${cfg:+,}MTU=$_mtu"
|
|
create_persistent_ifcfg \
|
|
ifname=$ifname.$vlanid \
|
|
xcatnet=$xcatnet \
|
|
inattrs="$cfg"
|
|
|
|
# bring up interface formally
|
|
lines=`$ifdown $ifname.$vlanid; $ifup $ifname.$vlanid`
|
|
rc=$?
|
|
if [ $rc -ne 0 ]; then
|
|
log_warn "ifup $ifname.$vlanid failed with return code equals to $rc"
|
|
echo "$lines" \
|
|
| $sed -e 's/^/>> /g' \
|
|
| log_lines info
|
|
fi
|
|
|
|
return $rc
|
|
}
|
|
|
|
###############################################################################
|
|
#
|
|
# create raw ethernet cfg file for bridge
|
|
# This is for eth-> br
|
|
#
|
|
# input : ifname=<ifname> _mtu=<mtu> _bridge=<bridge_name>
|
|
#
|
|
###############################################################################
|
|
function create_raw_ethernet_for_br {
|
|
|
|
log_info "create_raw_eth_interface_for_br $@"
|
|
|
|
local lines=""
|
|
local ifname=""
|
|
local _bridge=""
|
|
local _mtu=""
|
|
while [ -n "$1" ];
|
|
do
|
|
key=`echo "$1" | $cut -s -d= -f1`
|
|
if [ "$key" = "ifname" ] || \
|
|
[ "$key" = "_mtu" ] || \
|
|
[ "$key" = "_bridge" ]; then
|
|
eval "$1"
|
|
fi
|
|
shift
|
|
done
|
|
|
|
# create raw ethnet ifcfg file for bridge.
|
|
cfg=""
|
|
cfg="${cfg}${cfg:+,}ONBOOT=yes"
|
|
|
|
if grep -q -i "release 6" /etc/redhat-release ; then
|
|
cfg="${cfg}${cfg:+,}NM_CONTROLLED=no"
|
|
fi
|
|
|
|
cfg="${cfg}${cfg:+,}TYPE=Ethernet"
|
|
cfg="${cfg}${cfg:+,}BRIDGE=$_bridge"
|
|
cfg="${cfg}${cfg:+,}BOOTPROTO=none"
|
|
[ -n "$_mtu" ] && \
|
|
cfg="${cfg}${cfg:+,}MTU=$_mtu"
|
|
create_persistent_ifcfg \
|
|
ifname=$ifname \
|
|
inattrs="$cfg"
|
|
|
|
}
|
|
|
|
#############################################################################################################################
|
|
#
|
|
# create bond or bond->vlan interface
|
|
# https://www.kernel.org/doc/Documentation/networking/bonding.txt
|
|
# https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Networking_Guide/sec-Using_Channel_Bonding.html
|
|
#
|
|
# input : ifname=<nic> xcatnet=<xcatnetwork> _ipaddr=<ip> _netmask=<netmask> _bonding_opts=<bonding_opts> _mtu=<mtu> slave_ports=<port1,port2>
|
|
#
|
|
############################################################################################################################
|
|
function create_bond_interface {
|
|
log_info "create_bond_interface $@"
|
|
|
|
local lines=""
|
|
local ifname=""
|
|
local xcatnet=""
|
|
local _ipaddr=""
|
|
local _netmask=""
|
|
# note:
|
|
# - "miimon" requires drivers for each slave nic support MII tool.
|
|
# $ ethtool <interface_name> | grep "Link detected:"
|
|
# - "802.3ad" mode requires a switch that is 802.3ad compliant.
|
|
local _bonding_opts="mode=802.3ad miimon=100"
|
|
local _mtu=""
|
|
local slave_ports=""
|
|
# parser input arguments
|
|
while [ -n "$1" ];
|
|
do
|
|
key=`echo "$1" | $cut -s -d= -f1`
|
|
if [ "$key" = "ifname" ] || \
|
|
[ "$key" = "xcatnet" ] || \
|
|
[ "$key" = "_ipaddr" ] || \
|
|
[ "$key" = "_netmask" ] || \
|
|
[ "$key" = "_bonding_opts" ] || \
|
|
[ "$key" = "_mtu" ] || \
|
|
[ "$key" = "slave_ports" ]; then
|
|
eval "$1"
|
|
fi
|
|
shift
|
|
done
|
|
_g_migrate_ip=1
|
|
if [ -z "$slave_ports" ]; then
|
|
log_error "No valid slave_ports defined. Abort!"
|
|
return 1
|
|
fi
|
|
|
|
# let's query "nicnetworks" table about its target "xcatnet"
|
|
if [ -n "$ifname" -a -z "$xcatnet" -a -z "$_ipaddr" ]; then
|
|
xcatnet=`query_nicnetworks_net $ifname`
|
|
log_info "Pickup xcatnet, \"$xcatnet\", from NICNETWORKS for interface \"$ifname\"."
|
|
fi
|
|
|
|
local cnt
|
|
|
|
# convert the delimitor of _bonding_opts from comma to blank
|
|
if [ -n "$_bonding_opts" ]; then
|
|
_bonding_opts=`echo "$_bonding_opts" | $sed -e 's/,/ /g'`
|
|
fi
|
|
|
|
##############################
|
|
# Create target bond interface
|
|
# if target bond device was already exists, assume succ.
|
|
# stage 0: create interface
|
|
# stage 1: setup bond options which need to bring down bond first
|
|
# stage 2: setup bond slaves, apply other options on the fly and bring interface up
|
|
# stage 3: check target interface up
|
|
cnt=0
|
|
while [ $cnt -lt 4 ];
|
|
do
|
|
# Stage 0:
|
|
# create raw bond device on the fly, if not created yet.
|
|
if [ $cnt -eq 0 -a ! -f /proc/net/bonding/$ifname ]; then
|
|
# load the bonding module if not loaded.
|
|
load_kmod module=bonding retry=10 interval=0.5
|
|
|
|
# create required bond device
|
|
((i=0))
|
|
while ! grep -sq "^$ifname$" /sys/class/net/bonding_masters;
|
|
do
|
|
[ $i -eq 0 ] && echo "+$ifname" >/sys/class/net/bonding_masters
|
|
$sleep 0.5
|
|
((i+=1))
|
|
[ $i -ge 10 ] && break
|
|
done
|
|
if [ $i -ge 10 -o ! -f /proc/net/bonding/$ifname ]; then
|
|
log_error "stage 0: Fail to create bond device \"$ifname\""
|
|
break
|
|
fi
|
|
|
|
# Stage 1:
|
|
# setup bond options
|
|
elif [ $cnt -eq 1 -a -n "$_bonding_opts" ]; then
|
|
# 1.1) bring down bond interface before setup its attributes
|
|
$ip link set $ifname down
|
|
log_info "$ip link set $ifname down"
|
|
$ip link show $ifname | $sed -e 's/^/[bond.down] >> /g' | log_lines info
|
|
|
|
# 1.2) remove current slaves first
|
|
local saved_slaves=$(</sys/class/net/$ifname/bonding/slaves)
|
|
for ifslave in $saved_slaves
|
|
do
|
|
echo "-$ifslave" >/sys/class/net/$ifname/bonding/slaves
|
|
done
|
|
lines=`$(</sys/class/net/$ifname/bonding/slaves)`
|
|
if [ -n "$lines" ]; then
|
|
log_warn "stage 1: Cannot clean up bond slaves before setting up its attributes."
|
|
echo "$lines" \
|
|
| $sed -e 's/[failed.slaves] >> /g' \
|
|
| log_lines info
|
|
fi
|
|
|
|
# 1.3) apply bond options
|
|
local option
|
|
for option in $_bonding_opts
|
|
do
|
|
key=`echo "$option" | $cut -s -d= -f1`
|
|
val=`echo "$option" | $cut -s -d= -f2-`
|
|
echo "$val" >/sys/class/net/$ifname/bonding/$key
|
|
rc=$?
|
|
if [ $rc -ne 0 ]; then
|
|
log_warn "stage 1: Fail to set bonding option \"$key\" to \"$val\" in device \"$ifname\""
|
|
cat /sys/class/net/$ifname/bonding/$key \
|
|
| $sed -e 's/^/[bond.'$key'] >>/g' \
|
|
| log_lines info
|
|
fi
|
|
done
|
|
|
|
# 1.4) restore saved bond slaves
|
|
for ifslave in $saved_slaves
|
|
do
|
|
echo "+$ifslave" >/sys/class/net/$ifname/bonding/slaves
|
|
done
|
|
log_info "[bond.slavesAft] >> $(</sys/class/net/$ifname/bonding/slaves)"
|
|
|
|
# Stage 2:
|
|
# add slave ports
|
|
elif [ $cnt -eq 2 ]; then
|
|
# 2.1) add new slaves
|
|
for ifslave in `echo "$slave_ports" | $sed -e 's/,/ /g'`
|
|
do
|
|
# if the interface was not bonded as slave of master, do it now.
|
|
if ! grep -sq "Slave Interface: *$ifslave *$" /proc/net/bonding/$ifname; then
|
|
# bring it down before adding it to the master, or the operation will fail
|
|
# the slave interface will be brought up implicitely after bonded to master.
|
|
$ip link set $ifslave down
|
|
log_info "$ip link set $ifslave down"
|
|
|
|
# log for debug
|
|
$ip link show $ifslave | $sed -e 's/^/[slave]: >> /g' \
|
|
| log_lines info >&2
|
|
|
|
echo "+$ifslave" >/sys/class/net/$ifname/bonding/slaves
|
|
fi
|
|
|
|
# define and bring up slave interfaces.
|
|
cfg=""
|
|
cfg="${cfg}${cfg:+,}ONBOOT=yes"
|
|
|
|
if grep -q -i "release 6" /etc/redhat-release ; then
|
|
cfg="${cfg}${cfg:+,}NM_CONTROLLED=no"
|
|
fi
|
|
|
|
cfg="${cfg}${cfg:+,}USERCTL=no"
|
|
cfg="${cfg}${cfg:+,}TYPE=Ethernet"
|
|
cfg="${cfg}${cfg:+,}SLAVE=yes"
|
|
cfg="${cfg}${cfg:+,}MASTER=$ifname"
|
|
cfg="${cfg}${cfg:+,}BOOTPROTO=none"
|
|
[ -n "$_mtu" ] && \
|
|
cfg="${cfg}${cfg:+,}MTU=$_mtu"
|
|
create_persistent_ifcfg \
|
|
ifname=$ifslave \
|
|
inattrs="$cfg"
|
|
done
|
|
# log for debug
|
|
log_info "[bond.slavesNew] >> $(</sys/class/net/$ifname/bonding/slaves)"
|
|
|
|
# 2.2) apply other bond interface options on the fly
|
|
[ -n "$_mtu" ] && $ip link set $ifname mtu $_mtu
|
|
|
|
# 2.3) bring interface up
|
|
$ip link set $ifname up
|
|
log_info "$ip link set $ifname up"
|
|
|
|
elif [ $cnt -eq 3 ]; then
|
|
# 3.1) Check bond interface status
|
|
wait_for_ifstate $ifname UP 200 1
|
|
rc=$?
|
|
|
|
# log for debug
|
|
$ip link show $ifname | $sed -e 's/^/[ip.link] >> /g' | log_lines info
|
|
|
|
if [ $rc -ne 0 ]; then
|
|
log_warn "stage 3: Fail to bring up bond interface \"$ifname\""
|
|
break
|
|
fi
|
|
fi
|
|
|
|
((cnt+=1))
|
|
done
|
|
test $cnt -eq 4
|
|
rc=$?
|
|
|
|
# migrate slave ports ip and route to bond master
|
|
#[ $_g_migrate_ip -eq 1 ] && \
|
|
#migrate_ip ifname=$ifname sports="$slave_ports"
|
|
|
|
# define and bring up raw bond interface
|
|
# DHCLIENTARGS is optional, but default to have.
|
|
cfg=""
|
|
cfg="${cfg}${cfg:+,}ONBOOT=yes"
|
|
|
|
if grep -q -i "release 6" /etc/redhat-release ; then
|
|
cfg="${cfg}${cfg:+,}NM_CONTROLLED=no"
|
|
fi
|
|
|
|
cfg="${cfg}${cfg:+,}USERCTL=no"
|
|
cfg="${cfg}${cfg:+,}TYPE=Bond"
|
|
cfg="${cfg}${cfg:+,}BONDING_MASTER=yes"
|
|
cfg="${cfg}${cfg:+,}BONDING_OPTS='$_bonding_opts'"
|
|
cfg="${cfg}${cfg:+,}BOOTPROTO=none"
|
|
cfg="${cfg}${cfg:+,}DHCLIENTARGS='-timeout 200'"
|
|
[ -n "$_mtu" ] && \
|
|
cfg="${cfg}${cfg:+,}MTU=$_mtu"
|
|
create_persistent_ifcfg \
|
|
ifname=$ifname \
|
|
xcatnet=$xcatnet \
|
|
inattrs="$cfg"
|
|
lines=`$ifdown $ifname; $ifup $ifname 2>&1`
|
|
rc=$?
|
|
if [ $rc -ne 0 ]; then
|
|
log_warn "ifup $ifname failed with return code equals to $rc"
|
|
echo "$lines" \
|
|
| $sed -e 's/^/'$ifname' ifup out >> /g' \
|
|
| log_lines info
|
|
fi
|
|
|
|
wait_for_ifstate $ifname UP 200 1
|
|
rc=$?
|
|
if [ $rc -ne 0 ]; then
|
|
log_error "Error! Interface \"$ifname\" was NOT in \"UP\" state eventually."
|
|
$ip link show $ifname \
|
|
| $sed -e 's/^/['$ifname' ip out >> /g' \
|
|
| log_lines info
|
|
fi
|
|
|
|
return $rc
|
|
}
|
|
|
|
#############################################################################
|
|
#
|
|
# base64 encoded, decode first
|
|
#
|
|
# input : string
|
|
#
|
|
############################################################################
|
|
function decode_arguments {
|
|
local rc=1
|
|
local line=`echo "$1" | $base64 -d 2>/dev/null`
|
|
if echo "$line" | grep -sq "^{BASE64}:"; then
|
|
line=`echo "$line" | $sed -e 's/^{BASE64}:[ ]*//'`
|
|
rc=0
|
|
fi
|
|
echo "$line"
|
|
return $rc
|
|
}
|
|
|