|
1
|
|
|
"""Module with identifier types for Links and Interfaces""" |
|
2
|
|
|
|
|
3
|
1 |
|
import hashlib |
|
4
|
|
|
|
|
5
|
|
|
|
|
6
|
1 |
|
class InterfaceID(str): |
|
7
|
|
|
"""Interface Identifier""" |
|
8
|
|
|
|
|
9
|
1 |
|
__slots__ = ("switch", "port") |
|
10
|
|
|
|
|
11
|
1 |
|
def __new__(cls, switch: str, port: int): |
|
12
|
1 |
|
return super().__new__(cls, f"{switch}:{port}") |
|
13
|
|
|
|
|
14
|
1 |
|
def __init__(self, switch: str, port: int): |
|
15
|
|
|
# Used for sorting, but can be accessed |
|
16
|
1 |
|
self.switch = switch |
|
17
|
1 |
|
self.port = port |
|
18
|
1 |
|
super().__init__() |
|
19
|
|
|
|
|
20
|
1 |
|
def __lt__(self, other): |
|
21
|
|
|
# Ensures that instances are sortable in a way that maintains backwards |
|
22
|
|
|
# compatibility when creating instances of LinkID |
|
23
|
1 |
|
dpid_a = self.switch |
|
24
|
1 |
|
port_a = self.port |
|
25
|
1 |
|
dpid_b = other.switch |
|
26
|
1 |
|
port_b = other.port |
|
27
|
1 |
|
if dpid_a < dpid_b: |
|
28
|
1 |
|
return True |
|
29
|
1 |
|
return dpid_a == dpid_b and port_a < port_b |
|
30
|
|
|
|
|
31
|
1 |
|
def __getnewargs__(self): |
|
32
|
|
|
"""To make sure it's pickleable""" |
|
33
|
1 |
|
return (self.switch, self.port) |
|
34
|
|
|
|
|
35
|
|
|
|
|
36
|
1 |
|
class LinkID(str): |
|
37
|
|
|
"""Link Identifier""" |
|
38
|
|
|
|
|
39
|
1 |
|
def __new__(cls, interface_a: InterfaceID, interface_b: InterfaceID): |
|
40
|
1 |
|
raw_str = ":".join(sorted((interface_a, interface_b))) |
|
41
|
1 |
|
digest = hashlib.sha256(raw_str.encode('utf-8')).hexdigest() |
|
42
|
1 |
|
return super().__new__(cls, digest) |
|
43
|
|
|
|
|
44
|
1 |
|
def __init__(self, interface_a: InterfaceID, interface_b: InterfaceID): |
|
45
|
1 |
|
self.interfaces = (interface_a, interface_b) |
|
46
|
1 |
|
super().__init__() |
|
47
|
|
|
|
|
48
|
1 |
|
def __getnewargs__(self): |
|
49
|
|
|
"""To make sure it's pickleable""" |
|
50
|
|
|
return self.interfaces |
|
51
|
|
|
|