python3 - 2to3 + miscell obvious tweaks
[sfa.git] / sfa / planetlab / vlink.py
1 import re
2 from sfa.util.xrn import Xrn
3 # Taken from bwlimit.py
4 #
5 # See tc_util.c and http://physics.nist.gov/cuu/Units/binary.html. Be
6 # warned that older versions of tc interpret "kbps", "mbps", "mbit",
7 # and "kbit" to mean (in this system) "kibps", "mibps", "mibit", and
8 # "kibit" and that if an older version is installed, all rates will
9 # be off by a small fraction.
10 suffixes = {
11     "":         1,
12     "bit":  1,
13     "kibit":    1024,
14     "kbit": 1000,
15     "mibit":    1024 * 1024,
16     "mbit": 1000000,
17     "gibit":    1024 * 1024 * 1024,
18     "gbit": 1000000000,
19     "tibit":    1024 * 1024 * 1024 * 1024,
20     "tbit": 1000000000000,
21     "bps":  8,
22     "kibps":    8 * 1024,
23     "kbps": 8000,
24     "mibps":    8 * 1024 * 1024,
25     "mbps": 8000000,
26     "gibps":    8 * 1024 * 1024 * 1024,
27     "gbps": 8000000000,
28     "tibps":    8 * 1024 * 1024 * 1024 * 1024,
29     "tbps": 8000000000000
30 }
31
32
33 def get_tc_rate(s):
34     """
35     Parses an integer or a tc rate string (e.g., 1.5mbit) into bits/second
36     """
37
38     if type(s) == int:
39         return s
40     m = re.match(r"([0-9.]+)(\D*)", s)
41     if m is None:
42         return -1
43     suffix = m.group(2).lower()
44     if suffix in suffixes:
45         return int(float(m.group(1)) * suffixes[suffix])
46     else:
47         return -1
48
49
50 def format_tc_rate(rate):
51     """
52     Formats a bits/second rate into a tc rate string
53     """
54
55     if rate >= 1000000000 and (rate % 1000000000) == 0:
56         return "%.0fgbit" % (rate / 1000000000.)
57     elif rate >= 1000000 and (rate % 1000000) == 0:
58         return "%.0fmbit" % (rate / 1000000.)
59     elif rate >= 1000:
60         return "%.0fkbit" % (rate / 1000.)
61     else:
62         return "%.0fbit" % rate
63
64
65 class VLink:
66
67     @staticmethod
68     def get_link_id(if1, if2):
69         if if1['id'] < if2['id']:
70             link = (if1['id'] << 7) + if2['id']
71         else:
72             link = (if2['id'] << 7) + if1['id']
73         return link
74
75     @staticmethod
76     def get_iface_id(if1, if2):
77         if if1['id'] < if2['id']:
78             iface = 1
79         else:
80             iface = 2
81         return iface
82
83     @staticmethod
84     def get_virt_ip(if1, if2):
85         link_id = VLink.get_link_id(if1, if2)
86         iface_id = VLink.get_iface_id(if1, if2)
87         first = link_id >> 6
88         second = ((link_id & 0x3f) << 2) + iface_id
89         return "192.168.%d.%s" % (first, second)
90
91     @staticmethod
92     def get_virt_net(link):
93         link_id = VLink.get_link_id(link['interface1'], link['interface2'])
94         first = link_id >> 6
95         second = (link_id & 0x3f) << 2
96         return "192.168.%d.%d/30" % (first, second)
97
98     @staticmethod
99     def get_interface_id(interface):
100         if_name = Xrn(interface['component_id']).get_leaf()
101         node, dev = if_name.split(":")
102         node_id = int(node.replace("node", ""))
103         return node_id
104
105     @staticmethod
106     def get_topo_rspec(link, ipaddr):
107         link['interface1']['id'] = VLink.get_interface_id(link['interface1'])
108         link['interface2']['id'] = VLink.get_interface_id(link['interface2'])
109         my_ip = VLink.get_virt_ip(link['interface1'], link['interface2'])
110         remote_ip = VLink.get_virt_ip(link['interface2'], link['interface1'])
111         net = VLink.get_virt_net(link)
112         bw = format_tc_rate(int(link['capacity']))
113         return (link['interface2']['id'], ipaddr, bw, my_ip, remote_ip, net)
114
115     @staticmethod
116     def topo_rspec_to_link(topo_rspec):
117         pass