1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
|
#!/bin/bash
if [ ${DIB_DEBUG_TRACE:-0} -gt 0 ]; then
set -x
fi
set -eu
set -o pipefail
INTERFACE=${1:-} #optional, if not specified configure all available interfaces
ENI_FILE="/etc/network/interfaces"
PATH=/sbin:$PATH
if [ -d "/etc/network" ]; then
CONF_TYPE="eni"
elif [ -d "/etc/sysconfig/network-scripts/" ]; then
CONF_TYPE="rhel-netscripts"
SCRIPTS_PATH="/etc/sysconfig/network-scripts/"
elif [ -d "/etc/sysconfig/network/" ]; then
# SUSE network scripts location
CONF_TYPE="suse-netscripts"
SCRIPTS_PATH="/etc/sysconfig/network/"
else
echo "Unsupported network configuration type!"
exit 1
fi
ARGS="$0 $@"
function serialize_me() {
if [ "$CONF_TYPE" == "eni" ]; then
# Serialize runs so that we don't miss hot-add interfaces
FLOCKED=${FLOCKED:-}
if [ -z "$FLOCKED" ] ; then
FLOCKED=true exec flock -x $ENI_FILE $ARGS
fi
fi
}
function get_if_link() {
cat /sys/class/net/${1}/carrier || echo 0
}
function get_if_type() {
cat /sys/class/net/${1}/type
}
function interface_is_vlan() {
# Check if this is a vlan interface created on top of an Ethernet interface.
local interface=$1
# When the vlan interface is created, its mac address is copied from the
# underlying address and the address assignment type is set to 2
mac_addr_type=$(cat /sys/class/net/${interface}/addr_assign_type)
if [ "$mac_addr_type" != "2" ]; then
return 1
fi
# Only check for vlan interfaces named <interface>.<vlan>
lower_interface="$(echo $interface | cut -f1 -d'.')"
if [[ ! -z $lower_interface ]]; then
mac_addr_type=$(cat /sys/class/net/${lower_interface}/addr_assign_type)
if [ "$mac_addr_type" == "0" ]; then
return 0 # interface is vlan
fi
fi
return 1
}
function enable_interface() {
local interface=$1
local ipv6_init=$2
local ipv6_AdvManagedFlag=$3
local ipv6_AdvOtherConfigFlag=$4
serialize_me
if [ "$CONF_TYPE" == "eni" ]; then
printf "auto $interface\niface $interface inet dhcp\n\n" >>$ENI_FILE
if [ "$ipv6_init" == "True" ]; then
# Make DUID-UUID Type 4 (RFC 6355)
echo "default-duid \"\\x00\\x04$(sed 's/.\{2\}/\\x&/g' < /etc/machine-id)\";" >"/var/lib/dhcp/dhclient6--$interface.lease"
if [ $ipv6_AdvManagedFlag == "Yes" ]; then
# IPv6 DHCPv6 Stateful address configuration
printf "iface $interface inet6 dhcp\n\n" >>$ENI_FILE
echo "DHCPv6 Stateful Configured."
elif [ $ipv6_AdvOtherConfigFlag == "Yes" ]; then
# IPv6 DHCPv6 Stateless address configursation
printf "iface $interface inet6 auto\n\tdhcp 1\n\n" >>$ENI_FILE
echo "DHCPv6 Stateless Configured."
else
# IPv6 Autoconfiguration (SLAAC)
printf "iface $interface inet6 auto\n\tdhcp 0\n\n" >>$ENI_FILE
echo "IPv6 SLAAC Configured"
fi
fi
printf "\n" >>$ENI_FILE
elif [ "$CONF_TYPE" == "rhel-netscripts" ]; then
if [ "$(get_if_type $interface)" == "32" ]; then
printf "DEVICE=\"$interface\"\nBOOTPROTO=\"dhcp\"\nONBOOT=\"yes\"\nTYPE=\"InfiniBand\"\nCONNECTED_MODE=\"no\"\nDEFROUTE=\"yes\"\nPEERDNS=\"yes\"\nPEERROUTES=\"yes\"\nIPV4_FAILURE_FATAL=\"yes\"\nIPV6INIT=\"no\"" >"${SCRIPTS_PATH}ifcfg-$interface"
else
if interface_is_vlan $interface; then
printf "DEVICE=\"$interface\"\nBOOTPROTO=\"dhcp\"\nONBOOT=\"yes\"\nVLAN=\"yes\"\n" >"${SCRIPTS_PATH}ifcfg-$interface"
else
printf "DEVICE=\"$interface\"\nBOOTPROTO=\"dhcp\"\nONBOOT=\"yes\"\nTYPE=\"Ethernet\"\n" >"${SCRIPTS_PATH}ifcfg-$interface"
fi
if [ "$ipv6_init" == "True" ]; then
# Make DUID-UUID Type 4 (RFC 6355)
echo "default-duid \"\\x00\\x04$(sed 's/.\{2\}/\\x&/g' < /etc/machine-id)\";" >"/var/lib/dhclient/dhclient6--$interface.lease"
printf "IPV6INIT=\"yes\"\n" >>"${SCRIPTS_PATH}ifcfg-$interface"
if [ $ipv6_AdvManagedFlag == "Yes" ]; then
# IPv6 DHCPv6 Stateful address configuration
printf "IPV6_FORCE_ACCEPT_RA=\"yes\"\nDHCPV6C=\"yes\"\n" >>"${SCRIPTS_PATH}ifcfg-$interface"
echo "DHCPv6 Stateful Configured"
elif [ $ipv6_AdvOtherConfigFlag == "Yes" ]; then
# IPv6 DHCPv6 Stateless address configursation
printf "IPV6_AUTOCONF=\"yes\"\nDHCPV6C=\"yes\"\nDHCPV6C_OPTIONS=\"-S\"\n" >>"${SCRIPTS_PATH}ifcfg-$interface"
echo "DHCPv6 Stateless Configured"
else
# IPv6 Autoconfiguration (SLAAC)
printf "IPV6_AUTOCONF=\"yes\"\n" >>"${SCRIPTS_PATH}ifcfg-$interface"
echo "IPv6 SLAAC Configured"
fi
fi
fi
elif [ "$CONF_TYPE" == "suse-netscripts" ]; then
printf "BOOTPROTO=\"dhcp\"\nSTARTMODE=\"auto\"" >"${SCRIPTS_PATH}ifcfg-$interface"
fi
echo "Configured $1"
}
function config_exists() {
local interface=$1
if [[ "$CONF_TYPE" =~ "netscripts" ]]; then
if [ -f "${SCRIPTS_PATH}ifcfg-$interface" ]; then
return 0
fi
else
if ifquery $interface >/dev/null 2>&1; then
if [ -z "$(ifquery $interface 2>&1)" ]; then
return 1
else
return 0
fi
else
return 1
fi
fi
return 1
}
function inspect_interface() {
local interface=$1
local mac_addr_type
mac_addr_type=$(cat /sys/class/net/${interface}/addr_assign_type)
echo -n "Inspecting interface: $interface..."
if config_exists $interface; then
echo "Has config, skipping."
elif interface_is_vlan $interface || [ "$mac_addr_type" == "0" ]; then
local has_link
local tries=DIB_DHCP_TIMEOUT
for ((; tries > 0; tries--)); do
# Need to set the link up on each iteration
ip link set dev $interface up &>/dev/null
has_link=$(get_if_link $interface)
[ "$has_link" == "1" ] && break
sleep 1
done
if [ "$has_link" == "1" ]; then
local ipv6_init=False
local ipv6_AdvManagedFlag=No
local ipv6_AdvOtherConfigFlag=No
if type rdisc6 &>/dev/null; then
# We have rdisc6, let's try to configure IPv6 autoconfig/dhcpv6
tries=DIB_DHCP_TIMEOUT
for ((; tries > 0; tries--)); do
# Need to retry this, link-local-address required for
# Neighbor Discovery, DHCPv6 etc.
set +e # Do not exit on error, capture rdisc6 error codes.
RA=$(rdisc6 --retry 3 --single "$interface" 2>/dev/null)
local return_code=$?
set -e # Re-enable exit on error.
if [ $return_code -eq 0 ]; then
ipv6_init=True
ipv6_AdvManagedFlag=$(echo "$RA" | grep "Stateful address conf." | awk -F: '{ print $2 }')
ipv6_AdvOtherConfigFlag=$(echo "$RA" | grep "Stateful other conf." | awk -F: '{ print $2 }')
break
elif [ $return_code -eq 1 ]; then
sleep 1
elif [ $return_code -eq 2 ]; then
# If rdisc6 does not receive any response after the
# specified number of attempts waiting for wait_ms
# (1000ms by default) milliseconds each time, it will
# exit with code 2.
break
fi
done
else
echo "rdisc6 not available, skipping IPv6 configuration."
fi
enable_interface "$interface" "$ipv6_init" "$ipv6_AdvManagedFlag" "$ipv6_AdvOtherConfigFlag"
else
echo "No link detected, skipping"
fi
else
echo "Device has generated MAC, skipping."
fi
}
if [ -n "$INTERFACE" ]; then
inspect_interface $INTERFACE
else
for iface in $(ls /sys/class/net | grep -v ^lo$); do
inspect_interface $iface
done
fi
|