network: fix ifup and netroot calling
[platform/upstream/dracut.git] / modules.d / 40network / net-lib.sh
1 #!/bin/sh
2
3 get_ip() {
4     local iface="$1" ip=""
5     ip=$(ip -o -f inet addr show $iface)
6     ip=${ip%%/*}
7     ip=${ip##* }
8 }
9
10 iface_for_remote_addr() {
11     set -- $(ip -o route get to $1)
12     echo $5
13 }
14
15 iface_for_mac() {
16     local interface="" mac="$(echo $1 | tr '[:upper:]' '[:lower:]')"
17     for interface in /sys/class/net/*; do
18         if [ $(cat $interface/address) = "$mac" ]; then
19             echo ${interface##*/}
20         fi
21     done
22 }
23
24 iface_has_link() {
25     local interface="$1" flags=""
26     [ -n "$interface" ] || return 2
27     interface="/sys/class/net/$interface"
28     [ -d "$interface" ] || return 2
29     flags=$(cat $interface/flags)
30     echo $(($flags|0x41)) > $interface/flags # 0x41: IFF_UP|IFF_RUNNING
31     [ "$(cat $interface/carrier)" = 1 ] || return 1
32     # XXX Do we need to reset the flags here? anaconda never bothered..
33 }
34
35 all_ifaces_up() {
36     local iface="" IFACES=""
37     [ -e "/tmp/net.ifaces" ] && read IFACES < /tmp/net.ifaces
38     for iface in $IFACES; do
39         [ -e /tmp/net.$iface.up ] || return 1
40     done
41 }
42
43 get_netroot_ip() {
44     local prefix="" server="" rest=""
45     splitsep "$1" ":" prefix server rest
46     case $server in
47         [0-9]*\.[0-9]*\.[0-9]*\.[0-9]*) echo "$server"; return 0 ;;
48     esac
49     return 1
50 }
51
52 ip_is_local() {
53     strstr "$(ip route get $1 2>/dev/null)" " via "
54 }
55
56 ifdown() {
57     local netif="$1"
58     # ip down/flush ensures that routing info goes away as well
59     ip link set $netif down
60     ip addr flush dev $netif
61     echo "#empty" > /etc/resolv.conf
62     rm -f /tmp/net.$netif.did-setup
63     # TODO: send "offline" uevent?
64 }
65
66 setup_net() {
67     local netif="$1" f="" gw_ip="" netroot_ip="" iface="" IFACES=""
68     [ -e /tmp/net.$netif.did-setup ] && return
69     [ -e "/tmp/net.ifaces" ] && read IFACES < /tmp/net.ifaces
70     [ -z "$IFACES" ] && IFACES="$netif"
71     # run the scripts written by ifup
72     [ -e /tmp/net.$netif.gw ]            && . /tmp/net.$netif.gw
73     [ -e /tmp/net.$netif.hostname ]      && . /tmp/net.$netif.hostname
74     [ -e /tmp/net.$netif.override ]      && . /tmp/net.$netif.override
75     [ -e /tmp/dhclient.$netif.dhcpopts ] && . /tmp/dhclient.$netif.dhcpopts
76     # set up resolv.conf
77     [ -e /tmp/net.$netif.resolv.conf ] && \
78         cp -f /tmp/net.$netif.resolv.conf /etc/resolv.conf
79
80     # Handle STP Timeout: arping the default gateway.
81     # (or the root server, if a) it's local or b) there's no gateway.)
82     # Note: This assumes that if no router is present the
83     # root server is on the same subnet.
84
85     # Get DHCP-provided router IP, or the cmdline-provided "gw=" argument
86     [ -n "$new_routers" ] && gw_ip=${new_routers%%,*}
87     [ -n "$gw" ] && gw_ip=$gw
88
89     # Get the "netroot" IP (if there's an IP address in there)
90     netroot_ip=$(get_netroot_ip $netroot)
91
92     # try netroot if it's local (or there's no gateway)
93     if ip_is_local $netroot_ip || [ -z "$gw_ip" ]; then
94         dest="$netroot_ip"
95     else
96         dest="$gw_ip"
97     fi
98     if [ -n "$dest" ] && ! arping -q -f -w 60 -I $netif $dest ; then
99         info "Resolving $dest via ARP on $netif failed"
100     fi
101     > /tmp/net.$netif.did-setup
102 }
103
104 save_netinfo() {
105     local netif="$1" IFACES="" f="" i=""
106     [ -e /tmp/net.ifaces ] && read IFACES < /tmp/net.ifaces
107     # Add $netif to the front of IFACES (if it's not there already).
108     set -- "$netif"
109     for i in $IFACES; do [ "$i" != "$netif" ] && set -- "$@" "$i"; done
110     IFACES="$*"
111     for i in $IFACES; do
112         for f in /tmp/dhclient.$i.*; do
113             [ -f $f ] && cp -f $f /tmp/net.${f#/tmp/dhclient.}
114         done
115     done
116     echo $IFACES > /tmp/.net.ifaces.new
117     mv /tmp/.net.ifaces.new /tmp/net.ifaces
118 }
119
120 set_ifname() {
121     local name="$1" mac="$2" num=0 n=""
122     # if it's already set, return the existing name
123     for n in $(getargs ifname=); do
124         strstr "$n" "$mac" && echo ${n%%:*} && return
125     done
126     # otherwise, pick a new name and use that
127     while [ -e /sys/class/$name$num ]; do num=$(($num+1)); done
128     echo "ifname=$name$num:$mac" >> /etc/cmdline.d/45-ifname.conf
129     echo "$name$num"
130 }
131
132 ibft_to_cmdline() {
133     local iface="" mac="" dev=""
134     local dhcp="" ip="" gw="" mask="" hostname=""
135     modprobe -q iscsi_ibft
136     (
137         for iface in /sys/firmware/ibft/ethernet*; do
138             [ -e ${iface}/mac ] || continue
139             mac=$(read a < ${iface}/mac; echo $a)
140             [ -z "$ifname_mac" ] && continue
141             dev=$(set_ifname ibft $ifname_mac)
142             dhcp=$(read a < ${iface}/dhcp; echo $a)
143             if [ -n "$dhcp" ]; then
144                 echo "ip=$dev:dhcp"
145             else
146                 ip=$(read a < ${iface}/ip-addr; echo $a)
147                 gw=$(read a < ${iface}/gateway; echo $a)
148                 mask=$(read a < ${iface}/subnet-mask; echo $a)
149                 hostname=$(read a < ${iface}/hostname; echo $a)
150                 echo "ip=$ip::$gw:$mask:$hostname:$dev:none"
151             fi
152         done
153     ) >> /etc/cmdline.d/40-ibft.conf
154     # reread cmdline
155     unset CMDLINE
156 }
157
158 parse_iscsi_root()
159 {
160     local v
161     v=${1#iscsi:}
162
163 # extract authentication info
164     case "$v" in
165         *@*:*:*:*:*)
166             authinfo=${v%%@*}
167             v=${v#*@}
168     # allow empty authinfo to allow having an @ in iscsi_target_name like this:
169     # netroot=iscsi:@192.168.1.100::3260::iqn.2009-01.com.example:testdi@sk
170             if [ -n "$authinfo" ]; then
171                 OLDIFS="$IFS"
172                 IFS=:
173                 set $authinfo
174                 IFS="$OLDIFS"
175                 if [ $# -gt 4 ]; then
176                     warn "Wrong authentication info in iscsi: parameter!"
177                     return 1
178                 fi
179                 iscsi_username=$1
180                 iscsi_password=$2
181                 if [ $# -gt 2 ]; then
182                     iscsi_in_username=$3
183                     iscsi_in_password=$4
184                 fi
185             fi
186             ;;
187     esac
188
189 # extract target ip
190     case "$v" in
191         [[]*[]]:*)
192             iscsi_target_ip=${v#[[]}
193                 iscsi_target_ip=${iscsi_target_ip%%[]]*}
194             v=${v#[[]$iscsi_target_ip[]]:}
195             ;;
196         *)
197             iscsi_target_ip=${v%%[:]*}
198             v=${v#$iscsi_target_ip:}
199             ;;
200     esac
201
202 # extract target name
203     case "$v" in
204         *:iqn.*)
205             iscsi_target_name=iqn.${v##*:iqn.}
206             v=${v%:iqn.*}:
207             ;;
208         *:eui.*)
209             iscsi_target_name=iqn.${v##*:eui.}
210             v=${v%:iqn.*}:
211             ;;
212         *:naa.*)
213             iscsi_target_name=iqn.${v##*:naa.}
214             v=${v%:iqn.*}:
215             ;;
216         *)
217             warn "Invalid iscii target name, should begin with 'iqn.' or 'eui.' or 'naa.'"
218             return 1
219             ;;
220     esac
221
222 # parse the rest
223     OLDIFS="$IFS"
224     IFS=:
225     set $v
226     IFS="$OLDIFS"
227
228     iscsi_protocol=$1; shift # ignored
229     iscsi_target_port=$1; shift
230     if [ $# -eq 3 ]; then
231         iscsi_iface_name=$1; shift
232     fi
233     if [ $# -eq 2 ]; then
234         iscsi_netdev_name=$1; shift
235     fi
236     iscsi_lun=$1; shift
237     if [ $# -ne 0 ]; then
238         warn "Invalid parameter in iscsi: parameter!"
239         return 1
240     fi
241 }
242
243 ip_to_var() {
244     local v=${1}:
245     local i
246     set --
247     while [ -n "$v" ]; do
248         if [ "${v#\[*:*:*\]:}" != "$v" ]; then
249             # handle IPv6 address
250             i="${v%%\]:*}"
251             i="${i##\[}"
252             set -- "$@" "$i"
253             v=${v#\[$i\]:}
254         else
255             set -- "$@" "${v%%:*}"
256             v=${v#*:}
257         fi
258     done
259
260     unset ip srv gw mask hostname dev autoconf macaddr mtu
261     case $# in
262         0)  autoconf="error" ;;
263         1)  autoconf=$1 ;;
264         2)  dev=$1; autoconf=$2 ;;
265         3)  dev=$1; autoconf=$2; mtu=$3 ;;
266         4)  dev=$1; autoconf=$2; mtu=$3; macaddr=$4 ;;
267         *)  ip=$1; srv=$2; gw=$3; mask=$4; hostname=$5; dev=$6; autoconf=$7; mtu=$8; macaddr=$9 ;;
268     esac
269 }