jablonka.czprosek.czf

czfcentos

Subversion Repositories:
[/] [trunk/] [router/] [usr/] [local/] [bin/] [sedlo] - Blame information for rev 3

 

Line No. Rev Author Line
13czfcentos#!/bin/bash
2# author : Petr Simandl www.simandl.cz
3# release date : 03/06/2007
4# name : sedlo
5# description : dynamic side routing tables tool
6# license : GPL
7 
8sl_version="0.0.4pre11"
9 
10PATH=$PATH:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
11 
12sl_nmcnf="sedlo.conf"
13sl_sedlocnf="/etc/$sl_nmcnf"
14sl_sedlocache="/var/cache/sedlo"
15mkdir -p /var/cache/sedlo
16 
17sl_rttab="/etc/iproute2/rt_tables"
18sl_rtnmin=110
19sl_rtnmax=200
20#all traffic that is handled as internal (CZF traffic)
21sl_ipnodef="10.0.0.0/8"
22#this will specify base priority in rule table
23sl_priobase=10000
24#this will specify base priority in rule table select mask
25sl_priorulesmask="100.."
26#no default traffic will have rule at higher priority
27sl_prionodef=$(($sl_priobase - 1))
28 
29slm_unknown="Nezname parametry : "
30 
31sl_ipcmd=`which ip`
32sl_trcmd=`which tr`
33sl_wgetcmd=`which wget`
34sl_hnmcmd=`which hostname`
35sl_awkcmd=`which awk`
36sl_catcmd=`which cat`
37sl_grepcmd=`which grep`
38sl_diffcmd=`which diff`
39 
40if [ -e $sl_sedlocnf ]
41 then
42 sl_nop=1
43 else
44 echo "$sl_sedlocnf not found"
45 exit 1
46fi
47 
48if [ -e $sl_rttab ]
49 then
50 sl_nop=1
51 else
52 echo "$sl_rttab not found"
53 exit 1
54fi
55 
56sl_murlcfg=`cat $sl_sedlocnf | grep "^mcnf" | uniq | awk '{print $2" "$3" "$4}'`
57 
58######################################################################
59#this will delete all rules at sl_prionodef and sl_priorulesmask priorities
60s_flruall()
61{
62if [ $scm_info -gt 0 ]; then echo "Flushing all rules" ; fi
63 
64sl_rules=`$sl_ipcmd ru ls | $sl_grepcmd "^"$sl_prionodef":" | $sl_trcmd '[:blank:]' '*'`
65for sl_rule in $sl_rules
66do
67 sl_ipgws=`echo $sl_rule | $sl_awkcmd -F '*' '{print $2,$3,$4,$5,$6,$7}'`
68 $sl_ipcmd ru del $sl_ipgws
69 #this should make faster applying of new routing tables
70 $sl_ipcmd ro flush cache
71done
72 
73sl_rules=`$sl_ipcmd ru ls | $sl_grepcmd "^"$sl_priorulesmask":" | $sl_trcmd '[:blank:]' '*'`
74for sl_rule in $sl_rules
75do
76 sl_ipgws=`echo $sl_rule | $sl_awkcmd -F '*' '{print $2,$3,$4,$5,$6,$7}'`
77 $sl_ipcmd ru del $sl_ipgws
78 #this should make faster applying of new routing tables
79 $sl_ipcmd ro flush cache
80done
81 
82} # s_flruall
83 
84######################################################################
85s_checknodefru()
86{
87#checking if we have present nodef rule and if not we create it
88sl_nodefrule=`$sl_ipcmd ru ls | $sl_grepcmd "^"$sl_prionodef":" | $sl_trcmd '[:blank:]' '*'`
89#echo $sl_nodefrule
90if [ "$sl_nodefrule x" == " x" ]
91 then
92 if [ $scm_info -gt 0 ]; then echo "Creating rule for nodef route" ; fi
93 $sl_ipcmd ru add from $sl_ipnodef to $sl_ipnodef lookup main prio $sl_prionodef
94fi
95}
96 
97######################################################################
98# here we get each ip and we create a rule to send this ip to a
99# certain table
100# this routine can be skipped when the number of ips and ip directions
101# are still the same = old and new configs are the same
102s_fillrules()
103{
104 
105#this will check no default rule if exists and if not it will be created
106s_checknodefru
107 
108if [ $scm_info -gt 0 ]; then echo "Checking rules for ips" ; fi
109 
110sl_ips=`$sl_catcmd $sl_sedlocache/$sl_nmcnf | $sl_grepcmd "^ip" | $sl_awkcmd '{print $2"*"$4"*"$5"*"$6}'`
111sl_rules=`$sl_ipcmd ru ls | $sl_grepcmd ^$sl_priorulesmask":" | $sl_trcmd '[:blank:]' '*'`
112 
113#for all IPs we check and leave, change or create rule
114for sl_ip in $sl_ips
115do
116 sl_ipn=`echo $sl_ip | $sl_awkcmd -F '*' '{print $1}'`
117 sl_ipgws=`echo $sl_ip | $sl_awkcmd -F '*' '{print $2,$3,$4}'`
118 sl_ok="no"
119 #for all GWs we check rules
120 for sl_ipgw in $sl_ipgws
121 do
122 sl_tbl=`$sl_ipcmd ro ls ta $sl_ipgw`
123 #check if table exists
124 if [ "$sl_tbl x" != " x" ] && [ "$sl_ok" = "no" ]
125 then
126 #we have IP and GW table
127 #check if the rule alredady exists
128 sl_oldrule=`echo $sl_rules | $sl_trcmd " " "\n" | $sl_grepcmd "\*"$sl_ipn"\*"`
129 sl_exactrule=`echo $sl_oldrule | $sl_trcmd " " "\n" | $sl_grepcmd "\*"$sl_ipgw"\*"`
130 if [ "$sl_exactrule x" == " x" ]
131 then
132 #exact rule doesn't exist so we check if an old rule for this IP is present
133 if [ "$sl_oldrule x" != " x" ]
134 then
135 #some old rule(s) for IP is present so we delete it
136 for sl_rule in $sl_oldrule
137 do
138 sl_ipgws=`echo $sl_rule | $sl_awkcmd -F '*' '{print $2,$3,$4,$5,$6,$7}'`
139 if [ $scm_info -gt 0 ]; then echo "Deleting old rule $sl_ipgws" ; fi
140 $sl_ipcmd ru del $sl_ipgws
141 #this should make faster applying of new routing tables
142 $sl_ipcmd ro flush cache
143 done
144 fi
145 #getting subnet mask if exists
146 sl_subnet=`echo $sl_ip | $sl_awkcmd -F '/' '{print $2}' | $sl_awkcmd -F '*' '{print $1}' `
147 if [ "$sl_subnet x" == " x" ]
148 then
149 #if subnet was not found we set subnet to 32
150 sl_subnet=32
151 else
152 #this is just to be sure to have subnet between 1 and 32
153 if [ $sl_subnet -gt 32 ]; then sl_subnet=32 ; fi
154 if [ $sl_subnet -lt 1 ]; then sl_subnet=1 ; fi
155 fi
156 #bigger subnets have lower priority
157 sl_priorule=$(($sl_priobase + 32))
158 sl_priorule=$(($sl_priorule - $sl_subnet))
159 
160 if [ $scm_info -gt 0 ]; then echo "Creating new rule to send $sl_ipn to table $sl_ipgw" ; fi
161 $sl_ipcmd ru add from $sl_ipn lookup $sl_ipgw prio $sl_priorule
162 
163 else
164 if [ $scm_info -gt 1 ]; then echo "Rule to send $sl_ipn to table $sl_ipgw already exists" ; fi
165 fi
166 sl_ok="yes"
167 else
168 #we have no table
169 if [ "$sl_ok" = "no" ]
170 then
171 if [ $scm_info -gt 1 ]; then echo "For $sl_ipn table $sl_ipgw not used because it is empty" ; fi
172 else
173 if [ $scm_info -gt 1 ]; then echo "For $sl_ipn table $sl_ipgw not used because it has lower priority" ; fi
174 fi
175 fi
176 done
177done
178 
179#finally we check all rules and if there is a rule without IP from config we delete it
180for sl_rule in $sl_rules
181do
182 sl_iprule=`echo $sl_rule | $sl_awkcmd -F '*' '{print $3}'`
183 sl_ipconf=`echo $sl_ips | $sl_trcmd " " "\n" | $sl_grepcmd "^"$sl_iprule"\*"`
184 
185 if [ "$sl_ipconf x" == " x" ]
186 then
187 #we have a rule without an IP in config so we delete this rule
188 sl_ipgws=`echo $sl_rule | $sl_awkcmd -F '*' '{print $2,$3,$4,$5,$6,$7}'`
189 if [ $scm_info -gt 0 ]; then echo "Deleting non config rule $sl_ipgws" ; fi
190 $sl_ipcmd ru del $sl_ipgws
191 #this should make faster applying of new routing tables
192 $sl_ipcmd ro flush cache
193 fi
194done
195 
196} # s_fillrules
197 
198######################################################################
199# here we look into the main routing table for path to our iGWs
200# and we fill these tables with two halves default nets that
201# point to appropriate direction
202# this routine can be skipped when the routing table is the same
203s_filltables()
204{
205if [ $scm_info -gt 0 ]; then echo "Checking main routing table" ; fi
206 
207if [ $scm_info -gt 0 ]; then echo "Filling tables" ; fi
208 
209sl_igws=`$sl_catcmd $sl_sedlocache/$sl_nmcnf | $sl_grepcmd -E "^igw|^myigw" | $sl_awkcmd '{print $3"*"$2"*"$1}'`
210 
211for sl_igw in $sl_igws
212 do
213 sl_igwn=`echo $sl_igw | $sl_awkcmd -F '*' '{print $1}'`
214 sl_igwip=`echo $sl_igw | $sl_awkcmd -F '*' '{print $2}'`
215 sl_igwtype=`echo $sl_igw | $sl_awkcmd -F '*' '{print $3}'`
216 
217#oprava falesneho routovani na lokalni iface - pokud jsme lokalni igw tak se nema najit ip
218#protoze cesta dal neni - jsme totiz uz na lokalnim iface
219#head je tam proto ze se pro prespolni(a bgp) muze objevit vice rout s ruznou metrikou tak vezmem jen prvni (head)
220#s nejmensi metrikou (sort)
221 sl_igwgt=`$sl_ipcmd ro ls | $sl_grepcmd -v "proto kernel" | $sl_grepcmd "^$sl_igwip " | sort | $sl_awkcmd '{print $3}' | head -n 1`
222 
223 # equal cost multipath detection - just first IP is taken as way to igw
224 if [ "$sl_igwgt x" = "zebra x" ]
225 then
226 sl_igwgt=`$sl_ipcmd ro ls | $sl_grepcmd -A 1 "^$sl_igwip " | $sl_grepcmd "nexthop" | $sl_awkcmd '{print $3}'`
227 fi
228 
229 #if myigw then fill table for local gateway with single ip from config
230 if [ "$sl_igwtype x" = "myigw x" ]
231 then
232 sl_igwgt=$sl_igwip
233 fi
234 #testing if the igw has not a route in global routing table
235 if [ "$sl_igwgt x" = " x" ]
236 then
237 if [ $scm_info -gt 1 ]; then echo "Route not found for igw $sl_igwn" ; fi
238 sl_myigw=`cat $sl_sedlocnf | $sl_grepcmd "^myigw" | $sl_grepcmd $sl_igwn | $sl_awkcmd '{print $3}'`
239 #testing if the igw without route is in local config
240 #if not we go to flush its table and set flag to redo rules
241 if [ "$sl_myigw x" = " x" ]
242 then
243 #getting num of routes of igw
244 sl_igwnr=`$sl_ipcmd ro ls ta all | $sl_grepcmd -c "table ${sl_igwn} "`
245 if [ "$sl_igwnr x" = "0 x" ]
246 then
247 if [ $scm_info -gt 1 ]; then echo "Table $sl_igwn is already empty - no action taken" ; fi
248 else
249 if [ $scm_info -gt 1 ]; then echo "Table $sl_igwn will be flushed and rules rearranged" ; fi
250 $sl_ipcmd ro fl ta $sl_igwn
251 #because this igw dissapeared we set a flag for rules recreation
252 sl_diffigw=1
253 fi
254 else
255 if [ $scm_info -gt 1 ]; then echo "Igw $sl_igwn found in local config - leaving table as is" ; fi
256 fi
257 else
258 sl_tbl=`$sl_ipcmd ro ls ta $sl_igwn`
259 #if the table is empty we fill it and we set flag for rules recreation
260 if [ "$sl_tbl x" = " x" ]
261 then
262 sl_diffigw=1
263 $sl_ipcmd ro add 0.0.0.0/1 via $sl_igwgt ta $sl_igwn
264 $sl_ipcmd ro add 128.0.0.0/1 via $sl_igwgt ta $sl_igwn
265 if [ "$sl_igwtype x" = "myigw x" ]
266 then
267 if [ $scm_info -gt 1 ]; then echo "Table $sl_igwn filled with default myigw $sl_igwgt" ; fi
268 else
269 if [ $scm_info -gt 1 ]; then echo "Table $sl_igwn filled with default gw $sl_igwgt" ; fi
270 fi
271 #the table is not empty so we check if routes are the same
272 else
273 #picking default gateway from the table
274 sl_igwogt=`$sl_ipcmd ro ls ta $sl_igwn | $sl_awkcmd '{print $3}' | uniq`
275 #checking if the old default is same as the new one
276 if [ "$sl_igwogt x" = "$sl_igwgt x" ]
277 then
278 if [ $scm_info -gt 1 ]; then echo "Table $sl_igwn will not be changed and default is $sl_igwgt" ; fi
279 else
280 #the new default is different so we will flush the table, fill new default
281 if [ $scm_info -gt 1 ]; then echo "Table $sl_igwn will be rewritten to default $sl_igwgt" ; fi
282 #flushing old default route in the table
283 $sl_ipcmd ro fl ta $sl_igwn
284 #filling new default
285 $sl_ipcmd ro add 0.0.0.0/1 via $sl_igwgt ta $sl_igwn
286 $sl_ipcmd ro add 128.0.0.0/1 via $sl_igwgt ta $sl_igwn
287 fi
288 fi
289 fi
290 done
291 
292} # s_filltables
293 
294######################################################################
295# filling rttab with tables from config
296# only new tables are created with a new uniq number that is not important because
297# usually we handle tables just by their names
298# this routine acts only when a new iGW appears - only adding a table is supported
299# no deleting is implemented because it seems to be not necessary to delete an old table
300# because there is space enough and after reboot table will not be created
301s_mktables()
302{
303if [ $scm_info -gt 0 ]; then echo "Checking tables" ; fi
304 
305sl_igws=`$sl_catcmd $sl_sedlocache/$sl_nmcnf | $sl_grepcmd -E "^igw|^myigw" | $sl_awkcmd '{print $3}'`
306for sl_igw in $sl_igws
307 do
308 sl_igwrttb=`$sl_catcmd $sl_rttab | $sl_awkcmd '{print $2}' | $sl_grepcmd $sl_igw `
309 if [ "$sl_igwrttb x" = " x" ]
310 then
311 if [ $scm_info -gt 1 ]; then echo "Creating table for $sl_igw" ; fi
312 sl_cnt="$sl_rtnmax"
313 sl_ok="no"
314 until [ "$sl_cnt" -eq "$sl_rtnmin" ] || [ "$sl_ok" = "yes" ]
315 do
316 #space is used to recognized two and three digit numbers
317 sl_igwrttb=`cat $sl_rttab | awk '{print $1" "}' | grep "$sl_cnt " `
318 if [ "$sl_igwrttb x" = " x" ]
319 then
320 sl_ok="yes"
321 echo "$sl_cnt $sl_igw" >> $sl_rttab
322 fi
323 sl_cnt=$(($sl_cnt - 1 ))
324 done
325 # a new table was created so we should set a flag for rules creation
326 sl_difftbl=1
327 else
328 if [ $scm_info -gt 1 ]; then echo "Table found for $sl_igw no action taken" ; fi
329 fi
330 done
331} # s_mktables
332 
333######################################################################
334s_getcfg()
335{
336if [ $scm_info -gt 0 ]; then echo "Getting config" ; fi
337if [ $scm_info -gt 1 ]; then echo "Using main config $sl_murlcfg" ; fi
338if [ $scm_info -gt 1 ]; then echo "Using local config $sl_sedlocnf" ; fi
339 
340rm -f "$sl_sedlocache/$sl_nmcnf.main.tmp"
341 
342$sl_wgetcmd -q -t 3 $sl_murlcfg -O "$sl_sedlocache/$sl_nmcnf.main.tmp"
343 
344if [ -s $sl_sedlocache/$sl_nmcnf.main.tmp ]
345 then
346 date > $sl_sedlocache/last_getcnf.txt
347 cp $sl_sedlocache/$sl_nmcnf.main.tmp $sl_sedlocache/$sl_nmcnf.main
348 if [ $scm_info -gt 1 ]; then echo "Main config downloaded and accepted" ; fi
349 else
350 if [ $scm_info -gt 1 ]; then echo "Main config not downloaded - cached config will be used" ; fi
351 echo -n "Main config not downloaded " > $sl_sedlocache/last_getcnf.txt
352 date >> $sl_sedlocache/last_getcnf.txt
353fi
354 
355# before generating a new cached config we store the old one for
356# comparison with the new one
357rm -f "$sl_sedlocache/$sl_nmcnf.old"
358if [ -s $sl_sedlocache/$sl_nmcnf ]
359 then
360 cp $sl_sedlocache/$sl_nmcnf $sl_sedlocache/$sl_nmcnf.old
361 else
362 touch $sl_sedlocache/$sl_nmcnf.old
363fi
364 
365# preparing cached config from local and main
366# the local config should be processed as the first to have
367# higher priority for rules from local config
368echo "# generated file" > $sl_sedlocache/$sl_nmcnf
369for sl_file in `ls $sl_sedlocnf ; ls $sl_sedlocache/$sl_nmcnf.main `
370do
371cat $sl_file | grep "^mcnf" | $sl_trcmd ';' '#' | awk '{print $1"\t"$2}' >> $sl_sedlocache/$sl_nmcnf
372cat $sl_file | grep "^igw" | $sl_trcmd ';' '#' | awk '{print $1"\t"$2"\t"$3}' >> $sl_sedlocache/$sl_nmcnf
373cat $sl_file | grep "^ip" | $sl_trcmd ';' '#' | awk '{print $1"\t"$2"\t"$3"\t"$4"\t"$5"\t"$6}' >> $sl_sedlocache/$sl_nmcnf
374done
375 
376#local gateways taken from local config
377cat $sl_sedlocnf | grep "^myigw" | $sl_trcmd ';' '#' | awk '{print $1"\t"$2"\t"$3}' >> $sl_sedlocache/$sl_nmcnf
378 
379#cat $sl_sedlocache/$sl_nmcnf | sort | uniq > $sl_sedlocache/$sl_nmcnf.uniq
380#mv $sl_sedlocache/$sl_nmcnf.uniq $sl_sedlocache/$sl_nmcnf
381 
382sl_diffcfg=`diff $sl_sedlocache/$sl_nmcnf $sl_sedlocache/$sl_nmcnf.old | grep -c .`
383if [ $sl_diffcfg -gt 0 ]
384 then
385 if [ $scm_info -gt 0 ]; then echo "New config is different than the old one" ; fi
386 else
387 if [ $scm_info -gt 0 ]; then echo "New config is the same as the old one" ; fi
388fi
389 
390# showing number of rules in config and system
391sl_numru=`ip ru ls | grep -c lookup`
392sl_numip=`grep -c ^ip $sl_sedlocache/$sl_nmcnf`
393sl_numru=$(($sl_numru - 3 ))
394if [ $sl_numip -gt $sl_numru ]
395 then
396 if [ $scm_info -gt 0 ]; then echo "We have less rules ($sl_numru) than new config has ips ($sl_numip)" ; fi
397# sl_diffcfg="1"
398 else
399 if [ $scm_info -gt 0 ]; then echo "We have $sl_numru rules and $sl_numip ips" ; fi
400fi
401}
402 
403######################################################################
404s_version()
405{
406 echo sedlo $sl_version
407} # s_version
408 
409######################################################################
410s_report()
411{
412 echo Content-type: text/html
413 echo
414 echo "Sedlo na routeru `hostname`"
415 echo "<pre>"
416 echo "##### SEDLO #####"
417 echo "date : `date`"
418 echo "version : $sl_version"
419 echo "local_config : $sl_sedlocnf"
420 echo "main_config : <a href=\"$sl_murlcfg\">$sl_murlcfg</a>"
421 echo "last update : `cat $sl_sedlocache/last_getcnf.txt`"
422 echo "##### TABLES #####"
423 cat $sl_rttab
424 echo ; echo "##### DEFAULT ROUTES IN TABLES #####"
425 $sl_ipcmd ro ls ta all | $sl_grepcmd table | $sl_grepcmd -v local | $sl_trcmd " " "\t"
426 echo ; echo "##### RULES FOR IPS #####"
427 $sl_ipcmd ru ls | $sl_trcmd " " "\t"
428 echo "</pre>"
429} # s_report
430 
431######################################################################
432s_help()
433{
434 echo Pouziti: sedlo [param]
435 echo param:
436 echo -V vypise verzi
437 echo -help vypise napovedu
438 echo -v malo upovidany
439 echo -vv hodne upovidany
440 echo -nogetcfg zajisti ze se nedude znovu nacitat konfigurace a pouzije se predchozi z cache
441 echo -report vypise prehled pravidel a tabulek
442 echo -flru odstrani vsechny pravidla
443 echo -force bezpodminecne znovu obnovi vsechny pravidla
444} # s_help
445 
446######################################################################
447######################################################################
448 
449sl_unknown=""
450scm_nogetcfg=0
451scm_flru=0
452scm_info=0
453scm_force=0
454sl_diffigw=0
455sl_difftbl=0
456 
457# parsing input parameters
458while [ "a$1" != "a" ]
459do
460 case $1 in
461 -V)
462 s_version
463 exit 0
464 ;;
465 -h)
466 s_help
467 exit 0
468 ;;
469 -report)
470 s_report
471 exit 0
472 ;;
473 -flru)
474 scm_flru=1
475 shift
476 ;;
477 -force)
478 scm_force=1
479 shift
480 ;;
481 -help)
482 s_help
483 exit 0
484 ;;
485 -nogetcfg)
486 scm_nogetcfg=1
487 shift
488 ;;
489 -v)
490 scm_info=1
491 shift
492 ;;
493 -vv)
494 scm_info=2
495 shift
496 ;;
497 *)
498 sl_unknown="$sl_unknown$1 "
499 shift
500 esac
501done
502 
503# printing the list of bad parameters (if there are some)
504if [ "a$sl_unknown" != "a" ]
505then
506 echo "$slm_unknown $sl_unknown"
507 s_help
508 exit 0
509fi
510 
511if [ $scm_flru -eq 1 ]
512then
513 s_flruall
514 exit 0
515fi
516 
517if [ $scm_nogetcfg -eq 0 ]
518then
519 s_getcfg
520fi
521 
522s_mktables
523s_filltables
524#toto je pro ladici ucely
525#echo $sl_difftbl
526#echo $sl_diffcfg
527#echo $sl_diffigw
528#echo $scm_force
529#exit 0
530 
531#flushing and filling rules is done only when
532#new table is created
533#config is changed
534#some igw dissapears or appears
535#-force command line parameter was used
536if [ $sl_difftbl -gt 0 ] || [ $sl_diffcfg -gt 0 ] || [ $sl_diffigw -gt 0 ] || [ $scm_force -gt 0 ]
537then
538 s_fillrules
539fi
540 
541 
542exit 0

Powered by WebSVN 2.2.1