Haiyang Zhang | 178cd55 | 2016-07-11 17:06:42 -0700 | [diff] [blame] | 1 | #!/bin/bash |
| 2 | |
| 3 | # This example script creates bonding network devices based on synthetic NIC |
| 4 | # (the virtual network adapter usually provided by Hyper-V) and the matching |
| 5 | # VF NIC (SRIOV virtual function). So the synthetic NIC and VF NIC can |
| 6 | # function as one network device, and fail over to the synthetic NIC if VF is |
| 7 | # down. |
| 8 | # |
| 9 | # Usage: |
| 10 | # - After configured vSwitch and vNIC with SRIOV, start Linux virtual |
| 11 | # machine (VM) |
| 12 | # - Run this scripts on the VM. It will create configuration files in |
| 13 | # distro specific directory. |
| 14 | # - Reboot the VM, so that the bonding config are enabled. |
| 15 | # |
| 16 | # The config files are DHCP by default. You may edit them if you need to change |
| 17 | # to Static IP or change other settings. |
| 18 | # |
| 19 | |
| 20 | sysdir=/sys/class/net |
| 21 | netvsc_cls={f8615163-df3e-46c5-913f-f2d2f965ed0e} |
| 22 | bondcnt=0 |
| 23 | |
| 24 | # Detect Distro |
| 25 | if [ -f /etc/redhat-release ]; |
| 26 | then |
| 27 | cfgdir=/etc/sysconfig/network-scripts |
| 28 | distro=redhat |
| 29 | elif grep -q 'Ubuntu' /etc/issue |
| 30 | then |
| 31 | cfgdir=/etc/network |
| 32 | distro=ubuntu |
| 33 | elif grep -q 'SUSE' /etc/issue |
| 34 | then |
| 35 | cfgdir=/etc/sysconfig/network |
| 36 | distro=suse |
| 37 | else |
| 38 | echo "Unsupported Distro" |
| 39 | exit 1 |
| 40 | fi |
| 41 | |
| 42 | echo Detected Distro: $distro, or compatible |
| 43 | |
| 44 | # Get a list of ethernet names |
| 45 | list_eth=(`cd $sysdir && ls -d */ | cut -d/ -f1 | grep -v bond`) |
| 46 | eth_cnt=${#list_eth[@]} |
| 47 | |
| 48 | echo List of net devices: |
| 49 | |
| 50 | # Get the MAC addresses |
| 51 | for (( i=0; i < $eth_cnt; i++ )) |
| 52 | do |
| 53 | list_mac[$i]=`cat $sysdir/${list_eth[$i]}/address` |
| 54 | echo ${list_eth[$i]}, ${list_mac[$i]} |
| 55 | done |
| 56 | |
| 57 | # Find NIC with matching MAC |
| 58 | for (( i=0; i < $eth_cnt-1; i++ )) |
| 59 | do |
| 60 | for (( j=i+1; j < $eth_cnt; j++ )) |
| 61 | do |
| 62 | if [ "${list_mac[$i]}" = "${list_mac[$j]}" ] |
| 63 | then |
| 64 | list_match[$i]=${list_eth[$j]} |
| 65 | break |
| 66 | fi |
| 67 | done |
| 68 | done |
| 69 | |
| 70 | function create_eth_cfg_redhat { |
| 71 | local fn=$cfgdir/ifcfg-$1 |
| 72 | |
| 73 | rm -f $fn |
| 74 | echo DEVICE=$1 >>$fn |
| 75 | echo TYPE=Ethernet >>$fn |
| 76 | echo BOOTPROTO=none >>$fn |
Haiyang Zhang | fd7aabb | 2016-12-02 15:55:38 -0800 | [diff] [blame] | 77 | echo UUID=`uuidgen` >>$fn |
Haiyang Zhang | 178cd55 | 2016-07-11 17:06:42 -0700 | [diff] [blame] | 78 | echo ONBOOT=yes >>$fn |
Haiyang Zhang | 178cd55 | 2016-07-11 17:06:42 -0700 | [diff] [blame] | 79 | echo PEERDNS=yes >>$fn |
| 80 | echo IPV6INIT=yes >>$fn |
| 81 | echo MASTER=$2 >>$fn |
| 82 | echo SLAVE=yes >>$fn |
| 83 | } |
| 84 | |
| 85 | function create_eth_cfg_pri_redhat { |
| 86 | create_eth_cfg_redhat $1 $2 |
| 87 | } |
| 88 | |
| 89 | function create_bond_cfg_redhat { |
| 90 | local fn=$cfgdir/ifcfg-$1 |
| 91 | |
| 92 | rm -f $fn |
| 93 | echo DEVICE=$1 >>$fn |
| 94 | echo TYPE=Bond >>$fn |
| 95 | echo BOOTPROTO=dhcp >>$fn |
Haiyang Zhang | fd7aabb | 2016-12-02 15:55:38 -0800 | [diff] [blame] | 96 | echo UUID=`uuidgen` >>$fn |
Haiyang Zhang | 178cd55 | 2016-07-11 17:06:42 -0700 | [diff] [blame] | 97 | echo ONBOOT=yes >>$fn |
Haiyang Zhang | 178cd55 | 2016-07-11 17:06:42 -0700 | [diff] [blame] | 98 | echo PEERDNS=yes >>$fn |
| 99 | echo IPV6INIT=yes >>$fn |
| 100 | echo BONDING_MASTER=yes >>$fn |
| 101 | echo BONDING_OPTS=\"mode=active-backup miimon=100 primary=$2\" >>$fn |
| 102 | } |
| 103 | |
Haiyang Zhang | 1a4691b | 2017-02-24 17:30:32 +0000 | [diff] [blame] | 104 | function del_eth_cfg_ubuntu { |
| 105 | local fn=$cfgdir/interfaces |
| 106 | local tmpfl=$(mktemp) |
| 107 | |
| 108 | local nic_start='^[ \t]*(auto|iface|mapping|allow-.*)[ \t]+'$1 |
| 109 | local nic_end='^[ \t]*(auto|iface|mapping|allow-.*|source)' |
| 110 | |
| 111 | awk "/$nic_end/{x=0} x{next} /$nic_start/{x=1;next} 1" $fn >$tmpfl |
| 112 | |
| 113 | cp $tmpfl $fn |
| 114 | |
| 115 | rm $tmpfl |
| 116 | } |
| 117 | |
Haiyang Zhang | 178cd55 | 2016-07-11 17:06:42 -0700 | [diff] [blame] | 118 | function create_eth_cfg_ubuntu { |
| 119 | local fn=$cfgdir/interfaces |
| 120 | |
Haiyang Zhang | 1a4691b | 2017-02-24 17:30:32 +0000 | [diff] [blame] | 121 | del_eth_cfg_ubuntu $1 |
| 122 | |
Haiyang Zhang | 178cd55 | 2016-07-11 17:06:42 -0700 | [diff] [blame] | 123 | echo $'\n'auto $1 >>$fn |
| 124 | echo iface $1 inet manual >>$fn |
| 125 | echo bond-master $2 >>$fn |
| 126 | } |
| 127 | |
| 128 | function create_eth_cfg_pri_ubuntu { |
| 129 | local fn=$cfgdir/interfaces |
| 130 | |
| 131 | create_eth_cfg_ubuntu $1 $2 |
| 132 | echo bond-primary $1 >>$fn |
| 133 | } |
| 134 | |
| 135 | function create_bond_cfg_ubuntu { |
| 136 | local fn=$cfgdir/interfaces |
| 137 | |
Haiyang Zhang | 1a4691b | 2017-02-24 17:30:32 +0000 | [diff] [blame] | 138 | del_eth_cfg_ubuntu $1 |
| 139 | |
Haiyang Zhang | 178cd55 | 2016-07-11 17:06:42 -0700 | [diff] [blame] | 140 | echo $'\n'auto $1 >>$fn |
| 141 | echo iface $1 inet dhcp >>$fn |
| 142 | echo bond-mode active-backup >>$fn |
| 143 | echo bond-miimon 100 >>$fn |
| 144 | echo bond-slaves none >>$fn |
| 145 | } |
| 146 | |
| 147 | function create_eth_cfg_suse { |
| 148 | local fn=$cfgdir/ifcfg-$1 |
| 149 | |
| 150 | rm -f $fn |
| 151 | echo BOOTPROTO=none >>$fn |
| 152 | echo STARTMODE=auto >>$fn |
| 153 | } |
| 154 | |
| 155 | function create_eth_cfg_pri_suse { |
| 156 | create_eth_cfg_suse $1 |
| 157 | } |
| 158 | |
| 159 | function create_bond_cfg_suse { |
| 160 | local fn=$cfgdir/ifcfg-$1 |
| 161 | |
| 162 | rm -f $fn |
| 163 | echo BOOTPROTO=dhcp >>$fn |
| 164 | echo STARTMODE=auto >>$fn |
| 165 | echo BONDING_MASTER=yes >>$fn |
| 166 | echo BONDING_SLAVE_0=$2 >>$fn |
| 167 | echo BONDING_SLAVE_1=$3 >>$fn |
| 168 | echo BONDING_MODULE_OPTS=\'mode=active-backup miimon=100 primary=$2\' >>$fn |
| 169 | } |
| 170 | |
| 171 | function create_bond { |
| 172 | local bondname=bond$bondcnt |
| 173 | local primary |
| 174 | local secondary |
| 175 | |
| 176 | local class_id1=`cat $sysdir/$1/device/class_id 2>/dev/null` |
| 177 | local class_id2=`cat $sysdir/$2/device/class_id 2>/dev/null` |
| 178 | |
| 179 | if [ "$class_id1" = "$netvsc_cls" ] |
| 180 | then |
| 181 | primary=$2 |
| 182 | secondary=$1 |
| 183 | elif [ "$class_id2" = "$netvsc_cls" ] |
| 184 | then |
| 185 | primary=$1 |
| 186 | secondary=$2 |
| 187 | else |
| 188 | return 0 |
| 189 | fi |
| 190 | |
| 191 | echo $'\nBond name:' $bondname |
| 192 | |
| 193 | echo configuring $primary |
| 194 | create_eth_cfg_pri_$distro $primary $bondname |
| 195 | |
| 196 | echo configuring $secondary |
| 197 | create_eth_cfg_$distro $secondary $bondname |
| 198 | |
| 199 | echo creating: $bondname with primary slave: $primary |
| 200 | create_bond_cfg_$distro $bondname $primary $secondary |
| 201 | |
| 202 | let bondcnt=bondcnt+1 |
| 203 | } |
| 204 | |
| 205 | for (( i=0; i < $eth_cnt-1; i++ )) |
| 206 | do |
| 207 | if [ -n "${list_match[$i]}" ] |
| 208 | then |
| 209 | create_bond ${list_eth[$i]} ${list_match[$i]} |
| 210 | fi |
| 211 | done |