1 | # encoding: utf-8 |
||
2 | """ |
||
3 | rt.py |
||
4 | |||
5 | Created by Thomas Mangin on 2014-06-20. |
||
6 | Copyright (c) 2014-2017 Orange. All rights reserved. |
||
7 | Copyright (c) 2014-2017 Exa Networks. All rights reserved. |
||
8 | License: 3-clause BSD. (See the COPYRIGHT file) |
||
9 | """ |
||
10 | |||
11 | from struct import pack |
||
12 | from struct import unpack |
||
13 | |||
14 | from exabgp.protocol.ip import IPv4 |
||
15 | from exabgp.bgp.message.open.asn import ASN |
||
16 | from exabgp.bgp.message.update.attribute.community.extended import ExtendedCommunity |
||
17 | |||
18 | |||
19 | # ================================================================== RouteTarget |
||
20 | # RFC 4360 / RFC 7153 |
||
21 | |||
22 | |||
23 | class RouteTarget(ExtendedCommunity): |
||
24 | COMMUNITY_SUBTYPE = 0x02 |
||
25 | LIMIT = 0 |
||
26 | DESCRIPTION = 'target' |
||
27 | |||
28 | @property |
||
29 | def la(self): |
||
30 | return self.community[2 : self.LIMIT] |
||
31 | |||
32 | @property |
||
33 | def ga(self): |
||
34 | return self.community[self.LIMIT : 8] |
||
35 | |||
36 | def __eq__(self, other): |
||
37 | return self.COMMUNITY_SUBTYPE == other.COMMUNITY_SUBTYPE and ExtendedCommunity.__eq__(self, other) |
||
38 | |||
39 | def __ne__(self, other): |
||
40 | return not self.__eq__(other) |
||
41 | |||
42 | |||
43 | # ============================================================= RouteTargetASN2Number |
||
44 | # RFC 4360 / RFC 7153 |
||
45 | |||
46 | |||
47 | View Code Duplication | @ExtendedCommunity.register |
|
0 ignored issues
–
show
Duplication
introduced
by
Loading history...
|
|||
48 | class RouteTargetASN2Number(RouteTarget): |
||
49 | COMMUNITY_TYPE = 0x00 |
||
50 | LIMIT = 4 |
||
51 | |||
52 | def __init__(self, asn, number, transitive=True, community=None): |
||
53 | self.asn = asn |
||
54 | self.number = number |
||
55 | # assert(number < pow(2,32)) |
||
56 | RouteTarget.__init__(self, community if community else pack('!2sHL', self._subtype(transitive), asn, number)) |
||
57 | |||
58 | def __hash__(self): |
||
59 | return hash((self.asn, self.number)) |
||
60 | |||
61 | def __repr__(self): |
||
62 | return "%s:%d:%d" % (self.DESCRIPTION, self.asn, self.number) |
||
63 | |||
64 | @classmethod |
||
65 | def unpack(cls, data): |
||
66 | asn, number = unpack('!HL', data[2:8]) |
||
67 | return cls(ASN(asn), number, False, data[:8]) |
||
68 | |||
69 | |||
70 | # ============================================================= RouteTargetIPNumber |
||
71 | # RFC 4360 / RFC 7153 |
||
72 | |||
73 | |||
74 | View Code Duplication | @ExtendedCommunity.register |
|
0 ignored issues
–
show
|
|||
75 | class RouteTargetIPNumber(RouteTarget): |
||
76 | COMMUNITY_TYPE = 0x01 |
||
77 | LIMIT = 6 |
||
78 | |||
79 | def __init__(self, ip, number, transitive=True, community=None): |
||
80 | self.ip = ip |
||
81 | self.number = number |
||
82 | # assert(number < pow(2,16)) |
||
83 | RouteTarget.__init__( |
||
84 | self, community if community else pack('!2s4sH', self._subtype(transitive), IPv4.pton(ip), number) |
||
85 | ) |
||
86 | |||
87 | # why could we not simply use ExtendedCommunity.hash ? |
||
88 | def __hash__(self): |
||
89 | return hash((self.ip, self.number)) |
||
90 | |||
91 | def __repr__(self): |
||
92 | return "%s:%s:%d" % (self.DESCRIPTION, self.ip, self.number) |
||
93 | |||
94 | @classmethod |
||
95 | def unpack(cls, data): |
||
96 | ip, number = unpack('!4sH', data[2:8]) |
||
97 | return cls(IPv4.ntop(ip), number, False, data[:8]) |
||
98 | |||
99 | |||
100 | # ======================================================== RouteTargetASN4Number |
||
101 | # RFC 4360 / RFC 7153 |
||
102 | |||
103 | |||
104 | View Code Duplication | @ExtendedCommunity.register |
|
0 ignored issues
–
show
|
|||
105 | class RouteTargetASN4Number(RouteTarget): |
||
106 | COMMUNITY_TYPE = 0x02 |
||
107 | LIMIT = 6 |
||
108 | |||
109 | def __init__(self, asn, number, transitive=True, community=None): |
||
110 | self.asn = asn |
||
111 | self.number = number |
||
112 | # assert(number < pow(2,16)) |
||
113 | RouteTarget.__init__(self, community if community else pack('!2sLH', self._subtype(transitive), asn, number)) |
||
114 | |||
115 | # why could we not simply use ExtendedCommunity.hash ? |
||
116 | def __hash__(self): |
||
117 | return hash((self.asn, self.number)) |
||
118 | |||
119 | def __repr__(self): |
||
120 | return "%s:%dL:%d" % (self.DESCRIPTION, self.asn, self.number) |
||
121 | |||
122 | @classmethod |
||
123 | def unpack(cls, data): |
||
124 | asn, number = unpack('!LH', data[2:8]) |
||
125 | return cls(ASN(asn), number, False, data[:8]) |
||
126 |