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 # add the routing entries and rules
135 for i in "${interfaces[@]}"
137 # extract ipv4 address and netmask in cidr format
138 addr=($(/sbin/ip -o -4 addr list $i 2>&- | awk '{print $4}' | cut -d/ -f1))
139 cidrmask=($(/sbin/ip -o -4 addr list $i 2>&- | awk '{print $4}' | cut -d/ -f2))
140 # convert cidr mask to mask in dot format
141 dotmask=$(cidr2mask ${cidrmask[0]})
142 # apply mask to ip addr
143 net=$(netcalc ${addr[0]} $dotmask)
144 # build and execute route commands
145 routecmd=(/sbin/ip route add ${net}/${cidrmask[0]} dev ${i} proto kernel scope link src ${addr[0]} table ${i})
146 ruledelcmd=(/sbin/ip rule del from ${addr[0]} table ${i} '&>/dev/null')
147 ruleaddcmd=(/sbin/ip rule add from ${addr[0]} table ${i})
149 eval ${ruledelcmd[@]}
150 eval ${ruleaddcmd[@]}
151 logcmd1=(logger "${me}: ${routecmd[@]}")
152 logcmd2=(logger "${me}: ${ruledelcmd[@]}")
153 logcmd3=(logger "${me}: ${ruleaddcmd[@]}")
160 for i in "${interfaces[@]}"
162 flushcmd=(/sbin/ip neigh flush dev ${i})