blob: 2083e03b5e57a5503c4c25701bf4b3ebef28ea34 [file] [log] [blame]
Neale Rannsd0df49f2018-08-08 01:06:40 -07001"""
2 IP Types
3
4"""
5
6from ipaddress import ip_address
Neale Rannsc0a93142018-09-05 15:42:26 -07007from socket import AF_INET, AF_INET6
Ole Troan0685da42018-10-16 14:42:50 +02008from vpp_papi import VppEnum
Neale Rannsd0df49f2018-08-08 01:06:40 -07009
10
Neale Rannsc0a93142018-09-05 15:42:26 -070011class DpoProto:
12 DPO_PROTO_IP4 = 0
13 DPO_PROTO_IP6 = 1
14 DPO_PROTO_MPLS = 2
15 DPO_PROTO_ETHERNET = 3
16 DPO_PROTO_BIER = 4
17 DPO_PROTO_NSH = 5
18
19
Neale Rannsd0df49f2018-08-08 01:06:40 -070020INVALID_INDEX = 0xffffffff
21
22
Neale Rannsd0df49f2018-08-08 01:06:40 -070023class VppIpAddressUnion():
24 def __init__(self, addr):
25 self.addr = addr
26 self.ip_addr = ip_address(unicode(self.addr))
27
Neale Rannsd0df49f2018-08-08 01:06:40 -070028 def encode(self):
Neale Rannsc0a93142018-09-05 15:42:26 -070029 if self.version is 6:
Neale Rannsd0df49f2018-08-08 01:06:40 -070030 return {
31 'ip6': {
32 'address': self.ip_addr.packed
33 },
34 }
35 else:
36 return {
37 'ip4': {
38 'address': self.ip_addr.packed
39 },
40 }
41
Neale Rannsc0a93142018-09-05 15:42:26 -070042 @property
43 def version(self):
44 return self.ip_addr.version
45
46 @property
47 def address(self):
48 return self.addr
49
50 @property
51 def length(self):
52 if self.version is 6:
53 return 128
54 else:
55 return 32
56
57 @property
58 def bytes(self):
59 return self.ip_addr.packed
60
61 def __eq__(self, other):
62 if isinstance(other, self.__class__):
63 return self.ip_addr == other.ip_addr
64 elif hasattr(other, "ip4") and hasattr(other, "ip6"):
65 # vl_api_address_union_t
66 if 4 is self.version:
67 return self.ip_addr.packed == other.ip4.address
68 else:
69 return self.ip_addr.packed == other.ip6.address
70 else:
71 raise Exception("Comparing VppIpAddresUnions:%s"
72 " with unknown type: %s" %
73 (self, other))
74
75 return False
76
Neale Rannsd0df49f2018-08-08 01:06:40 -070077
78class VppIpAddress():
79 def __init__(self, addr):
80 self.addr = VppIpAddressUnion(addr)
81
82 def encode(self):
83 if self.addr.version is 6:
84 return {
Ole Troan0685da42018-10-16 14:42:50 +020085 'af': VppEnum.vl_api_address_family_t.ADDRESS_IP6,
Neale Rannsd0df49f2018-08-08 01:06:40 -070086 'un': self.addr.encode()
87 }
88 else:
89 return {
Ole Troan0685da42018-10-16 14:42:50 +020090 'af': VppEnum.vl_api_address_family_t.ADDRESS_IP4,
Neale Rannsd0df49f2018-08-08 01:06:40 -070091 'un': self.addr.encode()
92 }
93
Neale Rannsc0a93142018-09-05 15:42:26 -070094 def __eq__(self, other):
95 if isinstance(other, self.__class__):
96 return self.addr == other.addr
97 elif hasattr(other, "af") and hasattr(other, "un"):
98 # a vp_api_address_t
99 if 4 is self.version:
Ole Troan0685da42018-10-16 14:42:50 +0200100 return other.af == \
101 VppEnum.vl_api_address_family_t.ADDRESS_IP4 and \
Neale Rannsc0a93142018-09-05 15:42:26 -0700102 other.un == self.addr
103 else:
Ole Troan0685da42018-10-16 14:42:50 +0200104 return other.af == \
105 VppEnum.vl_api_address_family_t.ADDRESS_IP6 and \
Neale Rannsc0a93142018-09-05 15:42:26 -0700106 other.un == self.addr
107 else:
108 raise Exception("Comparing VppIpAddress:%s with unknown type: %s" %
109 (self, other))
110 return False
111
112 def __ne__(self, other):
113 return not (self == other)
114
115 def __str__(self):
116 return self.address
117
118 @property
119 def bytes(self):
120 return self.addr.bytes
121
Neale Rannsd0df49f2018-08-08 01:06:40 -0700122 @property
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700123 def bytes(self):
124 return self.addr.bytes
125
126 @property
Neale Rannsd0df49f2018-08-08 01:06:40 -0700127 def address(self):
128 return self.addr.address
129
Neale Rannsc0a93142018-09-05 15:42:26 -0700130 @property
131 def length(self):
132 return self.addr.length
133
134 @property
135 def version(self):
136 return self.addr.version
137
138 @property
139 def is_ip6(self):
140 return (self.version == 6)
141
142 @property
143 def af(self):
144 if self.version == 6:
145 return AF_INET6
146 else:
147 return AF_INET
148
149 @property
150 def dpo_proto(self):
151 if self.version is 6:
152 return DpoProto.DPO_PROTO_IP6
153 else:
154 return DpoProto.DPO_PROTO_IP4
155
Neale Rannsd0df49f2018-08-08 01:06:40 -0700156
157class VppIpPrefix():
158 def __init__(self, addr, len):
159 self.addr = VppIpAddress(addr)
160 self.len = len
161
162 def __eq__(self, other):
163 if self.addr == other.addr and self.len == other.len:
164 return True
165 return False
166
167 def encode(self):
168 return {'address': self.addr.encode(),
169 'address_length': self.len}
170
171 @property
172 def address(self):
173 return self.addr.address
174
Neale Rannsc0a93142018-09-05 15:42:26 -0700175 @property
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700176 def bytes(self):
177 return self.addr.bytes
178
179 @property
Neale Rannsc0a93142018-09-05 15:42:26 -0700180 def length(self):
181 return self.len
182
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700183 @property
184 def is_ip6(self):
185 return self.addr.is_ip6
186
Neale Rannsc0a93142018-09-05 15:42:26 -0700187 def __str__(self):
188 return "%s/%d" % (self.address, self.length)
189
190 def __eq__(self, other):
191 if isinstance(other, self.__class__):
192 return (self.len == other.len and self.addr == other.addr)
193 elif hasattr(other, "address") and hasattr(other, "address_length"):
194 # vl_api_prefix_t
195 return self.len == other.address_length and \
196 self.addr == other.address
197 else:
198 raise Exception("Comparing VppIpPrefix:%s with unknown type: %s" %
199 (self, other))
200 return False
201
Neale Rannsd0df49f2018-08-08 01:06:40 -0700202
Ole Troanffba3c32018-11-22 12:53:00 +0100203class VppIp6Prefix():
204 def __init__(self, prefix, prefixlen):
205 self.ip_prefix = ip_address(unicode(prefix))
206 self.prefixlen = prefixlen
207
208 def encode(self):
209 return {'prefix': {'address': self.ip_prefix.packed},
210 'len': self.prefixlen}
211
212
213class VppIp4Prefix(VppIp6Prefix):
214 pass
215
216
Neale Rannsd0df49f2018-08-08 01:06:40 -0700217class VppIpMPrefix():
218 def __init__(self, saddr, gaddr, len):
219 self.saddr = saddr
220 self.gaddr = gaddr
221 self.len = len
222 self.ip_saddr = ip_address(unicode(self.saddr))
223 self.ip_gaddr = ip_address(unicode(self.gaddr))
224
225 def encode(self):
226
227 if 6 is self.ip_saddr.version:
228 prefix = {
Ole Troan0685da42018-10-16 14:42:50 +0200229 'af': VppEnum.vl_api_address_family_t.ADDRESS_IP6,
Neale Rannsd0df49f2018-08-08 01:06:40 -0700230 'grp_address': {
231 'ip6': {
232 'address': self.ip_gaddr.packed
233 },
234 },
235 'src_address': {
236 'ip6': {
237 'address': self.ip_saddr.packed
238 },
239 },
240 'grp_address_length': self.len,
241 }
242 else:
243 prefix = {
Ole Troan0685da42018-10-16 14:42:50 +0200244 'af': VppEnum.vl_api_address_family_t.ADDRESS_IP4,
Neale Rannsd0df49f2018-08-08 01:06:40 -0700245 'grp_address': {
246 'ip4': {
247 'address': self.ip_gaddr.packed
248 },
249 },
250 'src_address': {
251 'ip4': {
252 'address': self.ip_saddr.packed
253 },
254 },
255 'grp_address_length': self.len,
256 }
257 return prefix