summaryrefslogtreecommitdiff
path: root/scripts/boot/networking.sh
blob: 268770e6a40ea9be9fa95927423cac94a8b68410 (plain)
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
#!/bin/sh

do_netsetup ()
{
	modprobe -q af_packet # For DHCP

	udevadm trigger
	udevadm settle

	[ -n "$ETHDEV_TIMEOUT" ] || ETHDEV_TIMEOUT=15
	echo "Using timeout of $ETHDEV_TIMEOUT seconds for network configuration."

	if [ -z "${NETBOOT}" ] && [ -z "${FETCH}" ] && \
	   [ -z "${HTTPFS}" ] && [ -z "${FTPFS}" ]
	then


	# support for Syslinux IPAPPEND parameter
	# it sets the BOOTIF variable on the kernel parameter

	if [ -n "${BOOTIF}" ]
	then
		# pxelinux sets BOOTIF to a value based on the mac address of the
		# network card used to PXE boot, so use this value for DEVICE rather
		# than a hard-coded device name from initramfs.conf. this facilitates
		# network booting when machines may have multiple network cards.
		# pxelinux sets BOOTIF to 01-$mac_address

		# strip off the leading "01-", which isn't part of the mac
		# address
		temp_mac=${BOOTIF#*-}

		# convert to typical mac address format by replacing "-" with ":"
		bootif_mac=""
		IFS='-'
		for x in $temp_mac
		do
			if [ -z "$bootif_mac" ]
			then
				bootif_mac="$x"
			else
				bootif_mac="$bootif_mac:$x"
			fi
		done
		unset IFS

		# look for devices with matching mac address, and set DEVICE to
		# appropriate value if match is found.

		for device in /sys/class/net/*
		do
			if [ -f "$device/address" ]
			then
				current_mac=$(cat "$device/address")

				if [ "$bootif_mac" = "$current_mac" ]
				then
					DEVICE=${device##*/}
					break
				fi
			fi
		done
	fi

	# if ethdevice was not specified on the kernel command line
	# make sure we try to get a working network configuration
	# for *every* present network device (except for loopback of course)
	if [ -z "$ETHDEVICE" ] ; then
		echo "If you want to boot from a specific device use bootoption ethdevice=..."
		for device in /sys/class/net/*; do
			dev=${device##*/} ;
			if [ "$dev" != "lo" ] ; then
				ETHDEVICE="$ETHDEVICE $dev"
			fi
		done
	fi

	# split args of ethdevice=eth0,eth1 into "eth0 eth1"
	for device in $(echo $ETHDEVICE | sed 's/,/ /g') ; do
		devlist="$devlist $device"
	done

	# this is tricky (and ugly) because ipconfig sometimes just hangs/runs into
	# an endless loop; if execution fails give it two further tries, that's
	# why we use '$devlist $devlist $devlist' for the other for loop
	for dev in $devlist $devlist $devlist ; do
		echo "Executing ipconfig -t $ETHDEV_TIMEOUT $dev"
		ipconfig -t "$ETHDEV_TIMEOUT" $dev | tee -a /netboot.config &
		jobid=$!
		sleep "$ETHDEV_TIMEOUT" ; sleep 1
		if [ -r /proc/"$jobid"/status ] ; then
			echo "Killing job $jobid for device $dev as ipconfig ran into recursion..."
			kill -9 $jobid
		fi

		# if configuration of device worked we should have an assigned
		# IP address, if so let's use the device as $DEVICE for later usage.
		# simple and primitive approach which seems to work fine
		if ifconfig $dev | grep -q 'inet.*addr:' ; then
			export DEVICE="$dev"
			break
		fi
	done

	else
		for interface in ${DEVICE}; do
			ipconfig -t "$ETHDEV_TIMEOUT" ${interface} | tee /netboot-${interface}.config
			[ -e /tmp/net-${interface}.conf ] && . /tmp/net-${interface}.conf
			if [ "$IPV4ADDR" != "0.0.0.0" ]
			then
				break
			fi
		done
	fi

	for interface in ${DEVICE}; do
		# source relevant ipconfig output
		OLDHOSTNAME=${HOSTNAME}
		[ -e /tmp/net-${interface}.conf ] && . /tmp/net-${interface}.conf
		[ -z ${HOSTNAME} ] && HOSTNAME=${OLDHOSTNAME}
		export HOSTNAME

		if [ -n "${interface}" ]
		then
			HWADDR="$(cat /sys/class/net/${interface}/address)"
		fi

		if [ ! -e "/etc/resolv.conf" ]
		then
			echo "Creating /etc/resolv.conf"

			if [ -n "${DNSDOMAIN}" ]
			then
				echo "domain ${DNSDOMAIN}" > /etc/resolv.conf
				echo "search ${DNSDOMAIN}" >> /etc/resolv.conf
			fi

			for i in ${IPV4DNS0} ${IPV4DNS1} ${IPV4DNS1}
			do
				if [ -n "$i" ] && [ "$i" != 0.0.0.0 ]
				then
					echo "nameserver $i" >> /etc/resolv.conf
				fi
			done
		fi

		# Check if we have a network device at all
		if ! ls /sys/class/net/"$interface" > /dev/null 2>&1 && \
		   ! ls /sys/class/net/eth0 > /dev/null 2>&1 && \
		   ! ls /sys/class/net/wlan0 > /dev/null 2>&1 && \
		   ! ls /sys/class/net/ath0 > /dev/null 2>&1 && \
		   ! ls /sys/class/net/ra0 > /dev/null 2>&1
		then
			panic "No supported network device found, maybe a non-mainline driver is required."
		fi
	done
}