-
Notifications
You must be signed in to change notification settings - Fork 0
/
route.py
executable file
·141 lines (125 loc) · 4.33 KB
/
route.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#!/usr/bin/python
import os
import sys
from subprocess import PIPE, Popen
import StringIO
import ConfigParser
import re
import fcntl
import netifaces
from pyroute2 import IPRoute
from pyroute2 import iproute
from IPy import IP as IPS
def read_rttables(file_path):
strinfo = re.compile('[\t|" "]+')
with open(file_path) as f:
config = StringIO.StringIO()
config.write('[dummy_section]\n')
config.write(strinfo.sub('=', f.read()))
config.seek(0, os.SEEK_SET)
cp = ConfigParser.SafeConfigParser()
cp.readfp(config)
conf = dict(cp.items('dummy_section'))
dic = {}
max = 100
for key in conf:
dic[conf[key]] = key
if key > max and key < 253:
max = key
return dic,max
def run():
#nics = {}
#count = 100
nics, count = read_rttables("/etc/iproute2/rt_tables")
ipr = IPRoute()
cmd = "echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore"
p = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE)
p.wait()
while True:
for interface in netifaces.interfaces():
if interface == "lo":
continue
try:
ip = netifaces.ifaddresses(interface)[netifaces.AF_INET][0]['addr']
mask = netifaces.ifaddresses(interface)[netifaces.AF_INET][0]['netmask']
except KeyError:
ip = ""
mask = ""
continue
if nics.has_key(interface):
state = ipr.get_links(ipr.link_lookup(ifname=interface))[0].get_attr('IFLA_OPERSTATE')
#rule operation
table_id = int(nics[interface])
ipret = ipr.get_rules(table=table_id)
if ipret:
iprlist = {}
if ipret:
for i in ipret[0]['attrs']:
iprlist[i[0]] = i[1]
#current ip is NULL
if not ip or state == "DOWN":
print interface, " ", table_id, " ", state, " del ", ip, " ", " ", mask, "\n"
ipr.rule("del", table=table_id, priority=iprlist['FRA_PRIORITY'])
else:
if ip != iprlist['FRA_SRC']:
print interface, " neq del ", ip, " ", " ", mask, "\n"
ipr.rule("del", table=table_id, priority=iprlist['FRA_PRIORITY'])
ipr.rule("add", table=table_id, src=ip)
else:
if ip:
#add rule
if state != "DOWN":
ipr.rule("add", table=table_id, src=ip)
#route operation
if state == "DOWN":
continue
routelist = ipr.get_routes(table=table_id)
if routelist:
pass
else:
idx = ipr.link_lookup(ifname=interface)[0]
ipss = IPS(ip).make_net(mask)
ipr.route('add', dst=str(ipss), oif=idx, prefsrc=ip, table=table_id)
else:
#only once
count += 1
cmd = "echo \"%d %s\" >> /etc/iproute2/rt_tables" % (count, interface)
p = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE)
p.wait()
#update table id
nics[interface] = count
def checkonce():
try:
pidfile = open("/tmp/mintu.pid", "r")
try:
fcntl.flock(pidfile, fcntl.LOCK_EX | fcntl.LOCK_NB)
except:
print "another process is running..."
sys.exit(1)
except IOError:
pid = str(os.getpid())
f = open('/tmp/mintu.pid', 'w')
f.write(pid)
f.close()
def main():
checkonce()
try:
pid = os.fork()
if pid > 0:
sys.exit(0)
except OSError, e:
print >> sys.stderr,"fork failed:%d (%s)" % (e.errno, e.strerror)
sys.exit(1)
os.chdir("/")
os.setsid()
os.umask(0)
try:
pid = os.fork()
if pid > 0:
sys.exit(0)
except OSError, e:
print >> sys.stderr, "fork failed:%d (%s)" % (e.errno, e.strerror)
sys.exit(1)
run()
if __name__ == '__main__':
main()