jablonka.czprosek.czf

sedlo

Subversion Repositories:
[/] [trunk/] [sedlo] - Blame information for rev 4

 

Line No. Rev Author Line
12simandl#!/bin/bash
2# author : Petr Simandl www.simandl.cz
34simandl# release date : 07/09/2004
42simandl# name : sedlo
5# description : dynamic side routing tables tool
6# license : GPL
7 
84simandlsl_version="0.0.3pre1-wsh-4"
92simandl 
104simandlPATH=$PATH:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
112simandl 
12sl_nmcnf="sedlo.conf"
13sl_sedlocnf="/etc/$sl_nmcnf"
14sl_sedlocache="/var/cache/sedlo"
15 
16sl_rttab="/etc/iproute2/rt_tables"
17sl_rtnmin=110
183simandlsl_rtnmax=200
194simandl 
20# sl_rule_prio_min - The lowest priority for rules created by
21# sedlo. Each configured user has one or more dynamic rules for
22# internet routing as specified in the config file.
23 
24sl_rule_prio_min=2000
25 
263simandlsl_ipnodef="10.0.0.0/8"
272simandl 
283simandlslm_unknown="Nezname parametry : "
29 
30sl_ipcmd=`which ip`
31sl_trcmd=`which tr`
32sl_wgetcmd=`which wget`
332simandlsl_hnmcmd=`which hostname`
34sl_awkcmd=`which awk`
353simandlsl_catcmd=`which cat`
36sl_grepcmd=`which grep`
372simandl 
384simandlif [ -r $sl_sedlocnf ]
392simandl then
40 sl_nop=1
41 else
424simandl echo "$sl_sedlocnf not found or is not readable"
432simandl exit 1
44fi
45 
464simandlif [ -w $sl_rttab ]
47 then
482simandl sl_nop=1
49 else
504simandl echo "Can't write to $sl_rttab"
512simandl exit 1
52fi
53 
544simandl# Read local configuration file
55sl_local_conf_murlcfg=`cat $sl_sedlocnf | grep "^mcnf" | head -n 1 | awk '{print $2}'`
56sl_local_conf_blackhole=`cat $sl_sedlocnf | grep "^blackhole" | head -n 1 | awk '{print $2}'`
57sl_local_conf_me2igw=`awk '/^me2igw/ { print $2 "*" $3 "*" $4 }' < $sl_sedlocnf`
58sl_local_conf_myigws=`awk '/^myigw/ { print $2; }' < $sl_sedlocnf`
592simandl 
60######################################################################
614simandls_flru()
62{
63 # Existing rules which were created by sedlo (priority
64 # sl_rule_prio_min and above) are deleted. All other rules are
65 # preserved.
66 
67 [ $scm_info -gt 0 ] && echo "Flushing all rules created by sedlo"
68 ip rule ls \
69 | awk -F ':' -v PRIO=$sl_rule_prio_min '{ if ($1 == PRIO) { print $2, " prio ", PRIO; PRIO=PRIO+1;} }' \
70 | sed -e 's!all!0/0!' \
71 | while read RULE; do
72 [ $scm_info -gt 1 ] && echo -n '#'
73 ip rule del $RULE;
74 done
75 
76 [ $scm_info -gt 1 ] && echo # new line after ###s
77 
78} # s_flru
79######################################################################
803simandls_fillrules()
812simandl{
824simandls_flru # Flush all rules
83 
843simandlif [ $scm_info -gt 0 ]; then echo "Creating rules" ; fi
852simandl 
864simandlsl_rule_prio=$sl_rule_prio_min # rules should have unique prio - see the iproute manual
872simandl 
884simandl# Insert rule for internal traffic
89ip ru add from 0/0 to $sl_ipnodef table main prio $sl_rule_prio
90sl_rule_prio=$((sl_rule_prio + 1))
91 
92# Prepare rules for later processing. Delete comments and format them
93# for better parsing.
94 
95sl_ips=`awk '/^ip/ {gsub("#.*$", ""); print $2"*"$4"*"$5"*"$6}' < $sl_sedlocache/$sl_nmcnf`
96 
97# $sl_ips format: ip_range*igw1*igw2*igw3
98 
99default_rule=""
100default_igws=`awk '/^default/ { print $2"*"$3"*"$4; }' < $sl_sedlocache/$sl_nmcnf`
101[ "x$default_igws" != "x" ] && default_rule="DEFAULT*$default_igws"
102 
103# $default_rule format: DEFAULT*igw1name*igw2name*igw3name
104 
105this_router="ME2IGW*$sl_local_conf_me2igw"
106 
107# $this_router format: THIS_ROUTER*igw1name*igw2name*igw3name
108 
109for sl_ip in $this_router $sl_ips $default_rule
1103simandldo
1114simandl sl_ipn=`echo $sl_ip | awk -F '*' '{print $1}'` # Client IP
112 sl_ipgws=`echo $sl_ip | awk -F '*' '{print $2,$3,$4}'` # iGW names
113 sl_attempt=1 # Which iGW is assigned (1st, 2nd or 3rd)
114 sl_rule_ok=no # whether there is a functional iGW for this rule
1153simandl for sl_ipgw in $sl_ipgws
1162simandl do
1174simandl sl_tbl=`ip ro ls ta $sl_ipgw`
118 if [ "$sl_tbl x" != " x" ]
1192simandl then
1204simandl [ $scm_info -gt 1 ] && echo "Creating new rules to send $sl_ipn to table $sl_ipgw (attempt $sl_attempt)";
121 case "$sl_ipn" in
122 "DEFAULT")
123 ip ru add table $sl_ipgw prio $sl_rule_prio ;;
124 "ME2IGW")
125 ip ru add iif lo table $sl_ipgw prio $sl_rule_prio ;;
126 *)
127 ip ru add from $sl_ipn table $sl_ipgw prio $sl_rule_prio ;;
128 esac
129 sl_rule_prio=$((sl_rule_prio + 1))
130 sl_rule_ok=yes
131 break
1323simandl else
1334simandl sl_attempt=$((sl_attempt + 1))
1343simandl fi
135 done
1364simandl if [ "x$sl_rule_ok" = "xno" ]; then
137 case "$sl_ipn" in
138 "DEFAULT")
139 # Despite of there is no default iGW accessible, create
140 # a rule for a default iGW. This prevents Internet
141 # packets to enter the main table.
142 
143 first_igw=`echo $sl_ip|awk -F '*' '{ print $2 }'`
144 [ $scm_info -gt 1 ] && echo "Creating new rule to send $sl_ipn to table $first_igw (the last attempt)";
145 ip ru add table $first_igw prio $sl_rule_prio
146 sl_rule_prio=$((sl_rule_prio + 1))
147 ;;
148 esac
149 fi
150 
1513simandldone
1522simandl 
1534simandl# Flushing the cache is necessary in order to new rules become
154# efective.
155 
156ip route flush cache
157 
1583simandl} # s_fillrules
159######################################################################
160s_filltables()
161{
162if [ $scm_info -gt 0 ]; then echo "Filling tables" ; fi
163 
1644simandlsl_igws=`awk '/^igw/ {print $3"*"$2}' < $sl_sedlocache/$sl_nmcnf`
165# $sl_igws format: "name*ip_addr" for each iGW
1663simandl 
167for sl_igw in $sl_igws
168 do
1694simandl # iGW name
170 sl_igwn=`echo $sl_igw | awk -F '*' '{print $1}'`
171 if echo $sl_local_conf_myigws|grep --word-regexp --fixed-strings --quiet $sl_igwn; then
172 
173 # This iGW name is listed in local config as myigw. Setup
174 # fixed route table.
175 
176 myigw_ip=`awk "/^myigw[[:space:]]+$sl_igwn/ { print \\$3; }" < $sl_sedlocnf`
177 ip ro replace default via $myigw_ip table $sl_igwn
178 else
179 
180 # Normal iGW - create a default route based on the main route
181 # table state.
182 
183 # iGW IP with slash is escaped with a backslash 10.51.0.0/16 -> 10.21.0.0\/16
184 sl_igwip=`echo $sl_igw | awk -F '*' '{gsub( "/", "\\\\/", $2); print $2}'`
185 # Where to send packets for this iGW (can be "via <ip-addres>" or "dev <dev-name>")
186 sl_igwgt=`ip ro ls | awk "/^$sl_igwip/ {print \\$2, \\$3}"`
187 
188 # TODO: Try to find IGW IP in a IP subnet. It allows an iGW to
189 # publish their settings, becouse it will be the same
190 # regardless # of router's cloud.
191 
192 sl_tbl=`ip ro ls ta $sl_igwn`
193 if [ "$sl_igwgt x" = " x" ] # route to igw not found
194 then
195 if [ $scm_info -gt 1 ]; then echo "Route not found for igw $sl_igwn - leaving table empty" ; fi
196 if [ "$sl_tbl x" != " x" ] # if table is not empty, flush it
197 then
198 ip ro fl ta $sl_igwn
199 fi
200 else
201 sl_no_default_routes_count=`ip ro ls ta $sl_igwn|grep -c -v '^default'`
202 if [ $sl_no_default_routes_count -gt 0 ] # if the table contains other than default routes, flush it
203 then
204 ip ro fl ta $sl_igwn
205 fi
206 ip ro replace default $sl_igwgt table $sl_igwn
207 if [ $scm_info -gt 1 ]; then echo "Table filled for igw $sl_igwn" ; fi
208 fi
209 sl_tbl_new=`ip ro ls ta $sl_igwn`
210 
211 # If an iGW state changes from reachable to unreachable or
212 # vice versa, rules needs to be rebuilt.
213 
214 if [ "x$sl_tbl" = "x" -a "x$sl_tbl_new" != "x" -o \
215 "x$sl_tbl" != "x" -a "x$sl_tbl_new" = "x" ]; then
216 sl_rules_update_needed=yes
217 fi
2182simandl fi
2193simandl done
2202simandl 
2213simandl} # s_filltables
222######################################################################
223s_mktables()
224{
225if [ $scm_info -gt 0 ]; then echo "Creating tables " ; fi
2264simandlsl_igws=`awk '/^igw/ {print $3}' < $sl_sedlocache/$sl_nmcnf`
227sl_cnt="$sl_rtnmax"
2283simandlfor sl_igw in $sl_igws
229 do
2304simandl sl_igwrttb=`awk "/$sl_igw/ {print \\$2}" < $sl_rttab`
231 if [ "$sl_igwrttb x" = " x" ] # Table is not present in rttab
2323simandl then
2334simandl [ $scm_info -gt 1 ] && echo "Creating table for $sl_igw"
2343simandl sl_ok="no"
235 until [ "$sl_cnt" -eq "$sl_rtnmin" ] || [ "$sl_ok" = "yes" ]
236 do
2374simandl sl_igwrttb=`awk "/^[^#]*$sl_cnt/ {print \\$1}" < $sl_rttab`
238 if [ "$sl_igwrttb x" = " x" ] # This number is free
2393simandl then
240 sl_ok="yes"
241 echo "$sl_cnt $sl_igw" >> $sl_rttab
242 fi
243 sl_cnt=$(($sl_cnt - 1 ))
244 done
245 else
2464simandl [ $scm_info -gt 1 ] && echo "Table found for $sl_igw no action taken"
2473simandl fi
248 
2492simandl done
2503simandl} # s_mktables
2512simandl######################################################################
252s_getcfg()
253{
2543simandlif [ $scm_info -gt 0 ]; then echo "Getting config" ; fi
2554simandlif [ $scm_info -gt 1 ]; then echo "Using main config $sl_local_conf_murlcfg" ; fi
2563simandlif [ $scm_info -gt 1 ]; then echo "Using local config $sl_sedlocnf" ; fi
2574simandl 
258wget --timeout=10 --tries 1 $sl_local_conf_murlcfg -O "$sl_sedlocache/$sl_nmcnf.main.tmp" -q
259 
260if [ -s $sl_sedlocache/$sl_nmcnf.main.tmp ]
2613simandl then
2624simandl date > $sl_sedlocache/last_getcnf.txt
263 cp $sl_sedlocache/$sl_nmcnf.main.tmp $sl_sedlocache/$sl_nmcnf.main
264 if [ $scm_info -gt 1 ]; then echo "Main config accepted" ; fi
265 else
266 
267 # Test if there is an old cached config file. This happens when
268 # wget is not installed when run first.
269 
270 if [ ! -r $sl_sedlocache/$sl_nmcnf.main ]; then
271 echo "No cached main config file found ($sl_sedlocache/${sl_nmcnf}.main)"
272 exit 1;
273 fi
274 
275 if [ $scm_info -gt 1 ]; then echo "Main config not accepted - using cached config" ; fi
276 echo -n "Main config not found " > $sl_sedlocache/last_getcnf.txt || exit 1
277 date >> $sl_sedlocache/last_getcnf.txt
2783simandlfi
2792simandl 
2804simandl# Preparing cached config from local and main one. The ^ip lines form
281# local config should have higher priority than the same lines in the
282# main config. For ^igw lines, the oposite is true. The default iGW
283# (first iGW in the config) should be the same for whole cloud.
284 
285echo "# generated file" > $sl_sedlocache/$sl_nmcnf || exit 1
286sl_conf_main_first=`ls $sl_sedlocache/$sl_nmcnf.main $sl_sedlocnf`
287sl_conf_local_first=`ls $sl_sedlocnf $sl_sedlocache/$sl_nmcnf.main`
288 
289#cat $sl_file | grep "^mcnf" | tr ';' '#' | awk '{print $1"\t"$2}' >> $sl_sedlocache/$sl_nmcnf || exit
290grep --no-filename --extended-regexp "^(igw|default)" $sl_conf_main_first| tr ';' '#' | awk '{print $1"\t"$2"\t"$3}' >> $sl_sedlocache/$sl_nmcnf || exit 1
291grep --no-filename "^ip" $sl_conf_local_first| tr ';' '#' | awk '{print $1"\t"$2"\t"$3"\t"$4"\t"$5"\t"$6}' >> $sl_sedlocache/$sl_nmcnf || exit 1
292 
293#cat $sl_sedlocache/$sl_nmcnf | sort | uniq > $sl_sedlocache/$sl_nmcnf.uniq
294#mv $sl_sedlocache/$sl_nmcnf.uniq $sl_sedlocache/$sl_nmcnf
2952simandl}
296######################################################################
297s_version()
298{
299 echo sedlo $sl_version
3003simandl} # s_version
3012simandl######################################################################
3023simandls_report()
303{
304 echo "##### SEDLO #####"
3054simandl echo "date : `date`"
3063simandl echo "version : $sl_version"
307 echo "local_config : $sl_sedlocnf"
3084simandl echo "main_config : $sl_local_conf_murlcfg"
309 echo "last update : `cat $sl_sedlocache/last_getcnf.txt`"
3103simandl echo "##### TABLES #####"
3114simandl tables=`awk "/^[^#]/ { if (\\\$1 >= $sl_rtnmin && \\\$1 <= $sl_rtnmax) print \\\$2; }" < $sl_rttab`
312 for table in $tables; do
313 echo "${table}:"
314 ip ro ls table ${table}|awk '{ print " " $0; }'
315 done
3163simandl echo "##### RULES #####"
3174simandl ip ru ls
3183simandl} # s_report
319######################################################################
3204simandlsl_lock_filename="/tmp/sedlo.lock"
321sl_tmp_lock_filename="/tmp/sedlo.$$"
322 
323sl_try_lock()
324{
325 echo $$ > $sl_tmp_lock_filename 2>/dev/null || {
326 echo >&2 "You don't have permission to access `dirname $TEMPFILE`"
327 return 1
328 }
329 ln $sl_tmp_lock_filename $sl_lock_filename 2>/dev/null && {
330 rm -f $sl_tmp_lock_filename
331 return 0
332 }
333 rm -f $sl_tmp_lock_filename
334 return 1
335}
336 
337# sl_invalid_lock: returns 0 (success) if the lock file doesn't
338# contain valid PID of sedlo process.
339 
340sl_invalid_lock()
341{
342 local pid
343 local proc_name
344 [ -f $sl_lock_filename ] || return 1 # lock doesn't exist so it
345 # can't be invalid
346 pid=$(< $sl_lock_filename)
347 proc_name=$(ps --pid $pid -o comm --no-headers)
348 if [ "$proc_name" = "sedlo" ]; then return 1 # the lock is valid
349 else return 0 # the lock is invalid
350 fi;
351}
352 
353sl_lock()
354{
355 trap sl_unlock EXIT
356 
357 timeout=10
358 while [ $timeout -gt 0 ]; do
359 sl_try_lock && break
360 [ $timeout -eq 10 -a $scm_info -gt 0 ] && echo "Trying to lock sedlo..."
361 sleep 1
362 timeout=$((timeout - 1))
363 done
364 
365 if [ $timeout -eq 0 ]; then
366 sl_invalid_lock && rm -f $sl_lock_filename && sl_try_lock && return 0
367 echo >&2 "Can't lock $sl_lock_filename."
368 echo >&2 "Probably sedlo is already running with PID `< $sl_lock_filename`."
369 exit 2
370 fi
371}
372 
373sl_unlock()
374{
375 if [ -f $sl_lock_filename ]; then
376 [ "`< $sl_lock_filename`" = "$$" ] && rm -f $sl_lock_filename
377 fi
378 [ -f $sl_tmp_lock_filename ] && rm -f $sl_tmp_lock_filename
379}
380 
381######################################################################
3822simandls_help()
383{
3844simandlcat <<EOF
385Pouziti: sedlo [param]
386param:
387-V vypise verzi
388-help vypise napovedu
389-v malo upovidany
390-vv hodne upovidany
391-quick Pouze nastavi routovaci tabuly. Necte config a nemeni
392 pravidla. Urceno pro caste spousteni z cronu.
393-nogetcfg zajisti ze se nedude znovu nacitat konfigurace a pouzije se
394 predchozi z cache
395-report vypise prehled pravidel a tabulek
396-flru odstrani vsechny pravidla
397EOF
3983simandl} # s_help
3992simandl######################################################################
400######################################################################
401 
4023simandlsl_unknown=""
403scm_nogetcfg=0
4044simandlscm_quick=0
405scm_flru=0
4063simandlscm_info=0
4072simandl 
4083simandl# parsing input parameters
409while [ "a$1" != "a" ]
410do
411 case $1 in
4124simandl -V)
413 s_version
414 exit 0
4153simandl ;;
416 -h)
4174simandl s_help
418 exit 0
4193simandl ;;
420 -report)
4214simandl s_report
422 exit 0
4233simandl ;;
4244simandl -flru)
425 scm_flru=1
426 shift
427 ;;
4283simandl -help)
4294simandl s_help
430 exit 0
4313simandl ;;
432 -nogetcfg)
433 scm_nogetcfg=1
434 shift
435 ;;
4364simandl -quick)
437 scm_quick=1
438 scm_nogetcfg=1
439 shift
440 ;;
441 -v)
4423simandl scm_info=1
443 shift
444 ;;
4454simandl -vv)
4463simandl scm_info=2
447 shift
448 ;;
449 *)
450 sl_unknown="$sl_unknown$1 "
451 shift
452 esac
453done
454 
455# printing the list of bad parameters (if there are some)
456if [ "a$sl_unknown" != "a" ]
457then
458 echo "$slm_unknown $sl_unknown"
459 s_help
4604simandl exit 0
4613simandlfi
462 
4634simandlsl_lock
464 
465if [ $scm_flru -eq 1 ]
466then
467 s_flru
468 exit
469fi
470 
4713simandlif [ $scm_nogetcfg -eq 0 ]
472then
473 s_getcfg
474fi
475 
4764simandl# Test if there is a cached config file (if called with -nogetcfg)
477if [ ! -r $sl_sedlocache/$sl_nmcnf ]; then
478 echo "No cached config file found ($sl_sedlocache/$sl_nmcnf)"
479 exit 1
480fi
481 
482if [ $scm_quick -eq 1 ]
483then
484 sl_rules_update_needed=no
485 s_filltables
486 [ $sl_rules_update_needed = yes ] && s_fillrules
487 exit
488fi
489 
490[ $sl_local_conf_blackhole = "yes" ] && ip route replace blackhole $sl_ipnodef
491 
4922simandls_mktables
4933simandls_filltables
494s_fillrules
495 
4962simandlexit 0

Powered by WebSVN 2.2.1