Whamcloud - gitweb
LU-17744 ldiskfs: mballoc stats fixes
[fs/lustre-release.git] / lustre / scripts / ksocklnd-config
1 #!/bin/bash
2
3 me="${0##*/}"
4
5 # convert number of mask bits to x.x.x.x mask format
6 cidr2mask() {
7         local i mask=""
8         local full_octets=$(($1/8))
9         local partial_octet=$(($1%8))
10
11         for ((i=0;i<4;i+=1)); do
12                 if [ $i -lt $full_octets ]; then
13                         mask+=255
14                 elif [ $i -eq $full_octets ]; then
15                         mask+=$((256 - 2**(8-$partial_octet)))
16                 else
17                         mask+=0
18                 fi
19                 test $i -lt 3 && mask+=.
20         done
21
22         echo $mask
23 }
24
25 # apply netmask (second argument) to ip address (first argument)
26 netcalc() {
27         local ipa=$(echo ${1} | awk -F. '{ print $1 }')
28         local ipb=$(echo ${1} | awk -F. '{ print $2 }')
29         local ipc=$(echo ${1} | awk -F. '{ print $3 }')
30         local ipd=$(echo ${1} | awk -F. '{ print $4 }')
31         local mka=$(echo ${2} | awk -F. '{ print $1 }')
32         local mkb=$(echo ${2} | awk -F. '{ print $2 }')
33         local mkc=$(echo ${2} | awk -F. '{ print $3 }')
34         local mkd=$(echo ${2} | awk -F. '{ print $4 }')
35         local nta="$(( $ipa & $mka ))"
36         local ntb="$(( $ipb & $mkb ))"
37         local ntc="$(( $ipc & $mkc ))"
38         local ntd="$(( $ipd & $mkd ))"
39         echo "$nta.$ntb.$ntc.$ntd"
40 }
41
42 # Check if the user wants to skip setting the routes
43 checkskipcmd=$(cat /sys/module/ksocklnd/parameters/skip_mr_route_setup 2>&-)
44 if [ "$checkskipcmd" == "1" ]; then
45         exit 0
46 fi
47
48 # Extract comma-separated interfaces from the argument
49 j=0
50 declare -a interfaces
51 for i in $(echo $1 | sed "s/,/ /g")
52 do
53         # verify that the interface exists
54         #echo "$i"
55         addr=$(/sbin/ip -o -4 addr list $i 2>&- | awk '{print $4}' | cut -d/ -f1)
56         linelen=$(echo -n $addr | wc -m)
57         if [[ $linelen -eq 0 ]]; then
58                 # there's a problem with this interface, skip it
59                 #echo 'bad!'
60                 continue
61         fi
62         # check if route is already set up for this interface
63         intfroute=$(/sbin/ip route show table $i 2>&-)
64         if [[ ! -z $intfroute ]]; then
65                 # route exists so skip this interface
66                 logcmd=(logger "${me}: skip setting up route for ${i}: don\'t overwrite existing route")
67                 eval "${logcmd[@]}"
68                 continue
69         fi
70         interfaces[$j]=$i
71         j=$((j+1))
72 done
73
74 # this array will contain the interfaces
75 # already listed in rt_tables
76 interfaces_listed=()
77
78 # flush cache for every interface
79 for i in "${interfaces[@]}"
80 do
81         # build command
82         redirect="2>&-"
83         flushcmd=(/sbin/ip route flush table ${i} ${redirect} )
84         # execute command
85         eval "${flushcmd[@]}"
86         logcmd=(logger "${me}: ${flushcmd[@]}")
87         eval "${logcmd[@]}"
88 done
89
90 filename='/etc/iproute2/rt_tables'
91 n=1
92 max_table_num=0
93 while read line; do
94         # reading each line
95         # trim leading and trailing spaces
96         line=`echo $line | sed -e 's/^[[:space:]]*//'`
97         linelen=$(echo -n $line | wc -m)
98         # don't check empty lines
99         if [ $linelen -lt 1 ]; then
100                 continue
101         fi
102         # don't check comments
103         if [[ ${line:0:1} == "#" ]]; then
104                 continue
105         fi
106         # split using space as separator
107         splitline=( $line )
108         # check the table number and update the max
109         if [ $max_table_num -lt ${splitline[0]} ]; then
110                 max_table_num=${splitline[0]}
111         fi
112         # check if any of the interfaces are listed
113         for i in "${interfaces[@]}"
114         do
115                 if [[ " ${splitline[@]} " =~ " ${i} " ]]; then
116                         if [[ " ${interfaces[@]} " =~ " ${i} " ]]; then
117                                 interfaces_listed+=($i)
118                         fi
119                 fi
120         done
121         #echo "Line No. $n : $line: $max_table_num"
122         n=$((n+1))
123 done < $filename
124
125 # add entries for unlisted interfaces
126 for i in "${interfaces[@]}"
127 do
128         if [[ ! " ${interfaces_listed[@]} " =~ " ${i} " ]]; then
129                 max_table_num=$((max_table_num+1))
130                 echo "$max_table_num $i" >> $filename
131         fi
132 done
133
134 # generate list of available default gateways
135 gwsline=$(/sbin/ip route | awk '/default/ { print $3 }')
136 gateways=($gwsline)
137
138 # select a gateway on the same subnet
139 selectgw() {
140         for gw in "${gateways[@]}"; do
141                 if [[ "$(netcalc "${1}" "${2}")" == "$(netcalc "${gw}" "${2}")" ]]; then
142                         echo $gw
143                         return
144                 fi
145         done
146         echo "0.0.0.0"
147 }
148
149 # add the routing entries and rules
150 for i in "${interfaces[@]}"
151 do
152         # extract ipv4 address and netmask in cidr format
153         addr=($(/sbin/ip -o -4 addr list $i 2>&- | awk '{print $4}' | cut -d/ -f1))
154         cidrmask=($(/sbin/ip -o -4 addr list $i 2>&- | awk '{print $4}' | cut -d/ -f2))
155         # convert cidr mask to mask in dot format
156         dotmask=$(cidr2mask ${cidrmask[0]})
157         # find a gateway on the same subnet
158         gw=$(selectgw ${addr[0]} $dotmask)
159         # build and execute route commands
160         if [[ $gw == "0.0.0.0" ]]; then
161                 # gateway not found, assume local destinations
162                 net=$(netcalc ${addr[0]} $dotmask)
163                 routecmd=(/sbin/ip route add ${net}/${cidrmask[0]} dev ${i} proto kernel scope link src ${addr[0]} table ${i})
164         else
165                 routecmd=(/sbin/ip route add default via ${gw} dev ${i} table ${i})
166         fi
167         ruledelcmd=(/sbin/ip rule del from ${addr[0]} table ${i} '&>/dev/null')
168         ruleaddcmd=(/sbin/ip rule add from ${addr[0]} table ${i})
169         routeerr=$(eval ${routecmd[@]} 2>&1 >/dev/null)
170         ruledelerr=$(eval ${ruledelcmd[@]} 2>&1 >/dev/null)
171         ruleaddcmd=$(eval ${ruleaddcmd[@]} 2>&1 >/dev/null)
172         logcmd1=(logger "${me}: ${routecmd[@]} ${routeerr}")
173         logcmd2=(logger "${me}: ${ruledelcmd[@]} ${ruledelerr}")
174         logcmd3=(logger "${me}: ${ruleaddcmd[@]} ${ruleaddcmd}")
175         eval "${logcmd1[@]}"
176         eval "${logcmd2[@]}"
177         eval "${logcmd3[@]}"
178 done
179
180 # flush arp tables
181 for i in "${interfaces[@]}"
182 do
183         flushcmd=(/sbin/ip neigh flush dev ${i})
184         eval ${flushcmd[@]}
185 done
186