2to3 -f has_key
[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 def format_tc_rate(rate):
50     """
51     Formats a bits/second rate into a tc rate string
52     """
53
54     if rate >= 1000000000 and (rate % 1000000000) == 0:
55         return "%.0fgbit" % (rate / 1000000000.)
56     elif rate >= 1000000 and (rate % 1000000) == 0:
57         return "%.0fmbit" % (rate / 1000000.)
58     elif rate >= 1000:
59         return "%.0fkbit" % (rate / 1000.)
60     else:
61         return "%.0fbit" % rate
62
63 class VLink:
64     @staticmethod
65     def get_link_id(if1, if2):
66         if if1['id'] < if2['id']:
67             link = (if1['id']<<7) + if2['id']
68         else:
69             link = (if2['id']<<7) + if1['id']
70         return link
71
72     @staticmethod
73     def get_iface_id(if1, if2):
74         if if1['id'] < if2['id']:
75             iface = 1
76         else:
77             iface = 2
78         return iface
79
80     @staticmethod
81     def get_virt_ip(if1, if2):
82         link_id = VLink.get_link_id(if1, if2)
83         iface_id = VLink.get_iface_id(if1, if2)
84         first = link_id >> 6
85         second = ((link_id & 0x3f)<<2) + iface_id
86         return "192.168.%d.%s" % (first, second)
87
88     @staticmethod
89     def get_virt_net(link):
90         link_id = VLink.get_link_id(link['interface1'], link['interface2'])
91         first = link_id >> 6
92         second = (link_id & 0x3f)<<2
93         return "192.168.%d.%d/30" % (first, second)
94
95     @staticmethod
96     def get_interface_id(interface):
97         if_name = Xrn(interface['component_id']).get_leaf()
98         node, dev = if_name.split(":")
99         node_id = int(node.replace("node", ""))
100         return node_id
101
102         
103     @staticmethod
104     def get_topo_rspec(link, ipaddr):
105         link['interface1']['id'] = VLink.get_interface_id(link['interface1'])
106         link['interface2']['id'] = VLink.get_interface_id(link['interface2'])
107         my_ip = VLink.get_virt_ip(link['interface1'], link['interface2'])
108         remote_ip = VLink.get_virt_ip(link['interface2'], link['interface1'])
109         net = VLink.get_virt_net(link)
110         bw = format_tc_rate(long(link['capacity']))
111         return (link['interface2']['id'], ipaddr, bw, my_ip, remote_ip, net)
112
113     @staticmethod 
114     def topo_rspec_to_link(topo_rspec):
115         pass