5 # convert number of mask bits to x.x.x.x mask format
8 local full_octets=$(($1/8))
9 local partial_octet=$(($1%8))
11 for ((i=0;i<4;i+=1)); do
12 if [ $i -lt $full_octets ]; then
14 elif [ $i -eq $full_octets ]; then
15 mask+=$((256 - 2**(8-$partial_octet)))
19 test $i -lt 3 && mask+=.
25 # apply netmask (second argument) to ip address (first argument)
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"
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
48 # Extract comma-separated interfaces from the argument
51 for i in $(echo $1 | sed "s/,/ /g")
53 # verify that the interface exists
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
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")
74 # this array will contain the interfaces
75 # already listed in rt_tables
78 # flush cache for every interface
79 for i in "${interfaces[@]}"
83 flushcmd=(/sbin/ip route flush table ${i} ${redirect} )
86 logcmd=(logger "${me}: ${flushcmd[@]}")
90 filename='/etc/iproute2/rt_tables'
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
102 # don't check comments
103 if [[ ${line:0:1} == "#" ]]; then
106 # split using space as separator
108 # check the table number and update the max
109 if [ $max_table_num -lt ${splitline[0]} ]; then
110 max_table_num=${splitline[0]}
112 # check if any of the interfaces are listed
113 for i in "${interfaces[@]}"
115 if [[ " ${splitline[@]} " =~ " ${i} " ]]; then
116 if [[ " ${interfaces[@]} " =~ " ${i} " ]]; then
117 interfaces_listed+=($i)
121 #echo "Line No. $n : $line: $max_table_num"
125 # add entries for unlisted interfaces
126 for i in "${interfaces[@]}"
128 if [[ ! " ${interfaces_listed[@]} " =~ " ${i} " ]]; then
129 max_table_num=$((max_table_num+1))
130 echo "$max_table_num $i" >> $filename
134 # generate list of available default gateways
135 gwsline=$(/sbin/ip route | awk '/default/ { print $3 }')
138 # select a gateway on the same subnet
140 for gw in "${gateways[@]}"; do
141 if [[ "$(netcalc "${1}" "${2}")" == "$(netcalc "${gw}" "${2}")" ]]; then
149 # add the routing entries and rules
150 for i in "${interfaces[@]}"
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})
165 routecmd=(/sbin/ip route add default via ${gw} dev ${i} table ${i})
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}")
181 for i in "${interfaces[@]}"
183 flushcmd=(/sbin/ip neigh flush dev ${i})