moving
[sfa.git] / sfa / util / vlink.py
1 # Taken from bwlimit.py
2 #
3 # See tc_util.c and http://physics.nist.gov/cuu/Units/binary.html. Be
4 # warned that older versions of tc interpret "kbps", "mbps", "mbit",
5 # and "kbit" to mean (in this system) "kibps", "mibps", "mibit", and
6 # "kibit" and that if an older version is installed, all rates will
7 # be off by a small fraction.
8 suffixes = {
9     "":         1,
10     "bit":  1,
11     "kibit":    1024,
12     "kbit": 1000,
13     "mibit":    1024*1024,
14     "mbit": 1000000,
15     "gibit":    1024*1024*1024,
16     "gbit": 1000000000,
17     "tibit":    1024*1024*1024*1024,
18     "tbit": 1000000000000,
19     "bps":  8,
20     "kibps":    8*1024,
21     "kbps": 8000,
22     "mibps":    8*1024*1024,
23     "mbps": 8000000,
24     "gibps":    8*1024*1024*1024,
25     "gbps": 8000000000,
26     "tibps":    8*1024*1024*1024*1024,
27     "tbps": 8000000000000
28 }
29
30 def get_tc_rate(s):
31     """
32     Parses an integer or a tc rate string (e.g., 1.5mbit) into bits/second
33     """
34
35     if type(s) == int:
36         return s
37     m = re.match(r"([0-9.]+)(\D*)", s)
38     if m is None:
39         return -1
40     suffix = m.group(2).lower()
41     if suffixes.has_key(suffix):
42         return int(float(m.group(1)) * suffixes[suffix])
43     else:
44         return -1
45
46 def format_tc_rate(rate):
47     """
48     Formats a bits/second rate into a tc rate string
49     """
50
51     if rate >= 1000000000 and (rate % 1000000000) == 0:
52         return "%.0fgbit" % (rate / 1000000000.)
53     elif rate >= 1000000 and (rate % 1000000) == 0:
54         return "%.0fmbit" % (rate / 1000000.)
55     elif rate >= 1000:
56         return "%.0fkbit" % (rate / 1000.)
57     else:
58         return "%.0fbit" % rate
59
60 def get_virt_ip(self, remote):
61         link = self.get_link_id(remote)
62         iface = self.get_iface_id(remote)
63         first = link >> 6
64         second = ((link & 0x3f)<<2) + iface
65         return "192.168.%d.%d" % (first, second)
66
67 def get_virt_net(self, remote):
68     link = self.get_link_id(remote)
69     first = link >> 6
70     second = (link & 0x3f)<<2
71     return "192.168.%d.%d/30" % (first, second)
72
73 def get_topo_rspec(self, link):
74     if link.end1 == self:
75         remote = link.end2
76     elif link.end2 == self:
77         remote = link.end1
78     else:
79         raise Error("Link does not connect to Node")
80
81     my_ip = self.get_virt_ip(remote)
82     remote_ip = remote.get_virt_ip(self)
83     net = self.get_virt_net(remote)
84     bw = format_tc_rate(link.bps)
85     ipaddr = remote.get_primary_iface().ipv4
86     return (remote.id, ipaddr, bw, my_ip, remote_ip, net)