blob: 5396e8457e20ebfdbfe454aac2ce8b424a90a222 [file] [log] [blame]
Neale Rannsd0df49f2018-08-08 01:06:40 -07001"""
2 IP Types
3
4"""
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -08005import logging
Neale Rannsd0df49f2018-08-08 01:06:40 -07006
7from ipaddress import ip_address
Neale Rannsc0a93142018-09-05 15:42:26 -07008from socket import AF_INET, AF_INET6
Ole Troan0685da42018-10-16 14:42:50 +02009from vpp_papi import VppEnum
Paul Vinciguerra9e315952019-01-29 11:51:44 -080010try:
11 text_type = unicode
12except NameError:
13 text_type = str
Neale Rannsd0df49f2018-08-08 01:06:40 -070014
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -080015_log = logging.getLogger(__name__)
16
Neale Rannsd0df49f2018-08-08 01:06:40 -070017
Neale Rannsc0a93142018-09-05 15:42:26 -070018class DpoProto:
19 DPO_PROTO_IP4 = 0
20 DPO_PROTO_IP6 = 1
21 DPO_PROTO_MPLS = 2
22 DPO_PROTO_ETHERNET = 3
23 DPO_PROTO_BIER = 4
24 DPO_PROTO_NSH = 5
25
26
Neale Rannsd0df49f2018-08-08 01:06:40 -070027INVALID_INDEX = 0xffffffff
28
29
Neale Rannsd0df49f2018-08-08 01:06:40 -070030class VppIpAddressUnion():
31 def __init__(self, addr):
32 self.addr = addr
Paul Vinciguerra9e315952019-01-29 11:51:44 -080033 self.ip_addr = ip_address(text_type(self.addr))
Neale Rannsd0df49f2018-08-08 01:06:40 -070034
Neale Rannsd0df49f2018-08-08 01:06:40 -070035 def encode(self):
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -080036 if self.version == 6:
Neale Ranns097fa662018-05-01 05:17:55 -070037 return {'ip6': self.ip_addr}
Neale Rannsd0df49f2018-08-08 01:06:40 -070038 else:
Neale Ranns097fa662018-05-01 05:17:55 -070039 return {'ip4': self.ip_addr}
Neale Rannsd0df49f2018-08-08 01:06:40 -070040
Neale Rannsc0a93142018-09-05 15:42:26 -070041 @property
42 def version(self):
43 return self.ip_addr.version
44
45 @property
46 def address(self):
47 return self.addr
48
49 @property
50 def length(self):
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -080051 return self.ip_addr.max_prefixlen
Neale Rannsc0a93142018-09-05 15:42:26 -070052
53 @property
54 def bytes(self):
55 return self.ip_addr.packed
56
57 def __eq__(self, other):
58 if isinstance(other, self.__class__):
59 return self.ip_addr == other.ip_addr
60 elif hasattr(other, "ip4") and hasattr(other, "ip6"):
61 # vl_api_address_union_t
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -080062 if 4 == self.version:
Ole Troan8c8acc02018-11-27 10:05:23 +010063 return self.ip_addr.packed == other.ip4
Neale Rannsc0a93142018-09-05 15:42:26 -070064 else:
Ole Troan8c8acc02018-11-27 10:05:23 +010065 return self.ip_addr.packed == other.ip6
Neale Rannsc0a93142018-09-05 15:42:26 -070066 else:
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -080067 _log.error("Comparing VppIpAddressUnions:%s"
68 " with incomparable type: %s",
69 self, other)
70 return NotImplemented
Neale Rannsc0a93142018-09-05 15:42:26 -070071
Neale Ranns097fa662018-05-01 05:17:55 -070072 def __str__(self):
73 return str(self.ip_addr)
74
Neale Rannsd0df49f2018-08-08 01:06:40 -070075
76class VppIpAddress():
77 def __init__(self, addr):
78 self.addr = VppIpAddressUnion(addr)
79
80 def encode(self):
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -080081 if self.addr.version == 6:
Neale Rannsd0df49f2018-08-08 01:06:40 -070082 return {
Ole Troan0685da42018-10-16 14:42:50 +020083 'af': VppEnum.vl_api_address_family_t.ADDRESS_IP6,
Neale Rannsd0df49f2018-08-08 01:06:40 -070084 'un': self.addr.encode()
85 }
86 else:
87 return {
Ole Troan0685da42018-10-16 14:42:50 +020088 'af': VppEnum.vl_api_address_family_t.ADDRESS_IP4,
Neale Rannsd0df49f2018-08-08 01:06:40 -070089 'un': self.addr.encode()
90 }
91
Neale Rannsc0a93142018-09-05 15:42:26 -070092 def __eq__(self, other):
93 if isinstance(other, self.__class__):
94 return self.addr == other.addr
95 elif hasattr(other, "af") and hasattr(other, "un"):
96 # a vp_api_address_t
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -080097 if 4 == self.version:
Ole Troan0685da42018-10-16 14:42:50 +020098 return other.af == \
99 VppEnum.vl_api_address_family_t.ADDRESS_IP4 and \
Neale Rannsc0a93142018-09-05 15:42:26 -0700100 other.un == self.addr
101 else:
Ole Troan0685da42018-10-16 14:42:50 +0200102 return other.af == \
103 VppEnum.vl_api_address_family_t.ADDRESS_IP6 and \
Neale Rannsc0a93142018-09-05 15:42:26 -0700104 other.un == self.addr
105 else:
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -0800106 _log.error(
107 "Comparing VppIpAddress:<%s> %s with incomparable "
108 "type: <%s> %s",
109 self.__class__.__name__, self,
110 other.__class__.__name__, other)
111 return NotImplemented
Neale Rannsc0a93142018-09-05 15:42:26 -0700112
113 def __ne__(self, other):
114 return not (self == other)
115
116 def __str__(self):
117 return self.address
118
119 @property
120 def bytes(self):
121 return self.addr.bytes
122
Neale Rannsd0df49f2018-08-08 01:06:40 -0700123 @property
124 def address(self):
125 return self.addr.address
126
Neale Rannsc0a93142018-09-05 15:42:26 -0700127 @property
128 def length(self):
129 return self.addr.length
130
131 @property
132 def version(self):
133 return self.addr.version
134
135 @property
136 def is_ip6(self):
137 return (self.version == 6)
138
139 @property
140 def af(self):
141 if self.version == 6:
142 return AF_INET6
143 else:
144 return AF_INET
145
146 @property
147 def dpo_proto(self):
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -0800148 if self.version == 6:
Neale Rannsc0a93142018-09-05 15:42:26 -0700149 return DpoProto.DPO_PROTO_IP6
150 else:
151 return DpoProto.DPO_PROTO_IP4
152
Neale Rannsd0df49f2018-08-08 01:06:40 -0700153
154class VppIpPrefix():
155 def __init__(self, addr, len):
156 self.addr = VppIpAddress(addr)
157 self.len = len
158
Neale Ranns097fa662018-05-01 05:17:55 -0700159 def __eq__(self, other):
160 if self.address == other.address and self.len == other.len:
161 return True
162 return False
163
Neale Rannsd0df49f2018-08-08 01:06:40 -0700164 def encode(self):
165 return {'address': self.addr.encode(),
166 'address_length': self.len}
167
168 @property
Neale Ranns097fa662018-05-01 05:17:55 -0700169 def version(self):
170 return self.addr.version
171
172 @property
Neale Rannsd0df49f2018-08-08 01:06:40 -0700173 def address(self):
174 return self.addr.address
175
Neale Rannsc0a93142018-09-05 15:42:26 -0700176 @property
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700177 def bytes(self):
178 return self.addr.bytes
179
180 @property
Neale Rannsc0a93142018-09-05 15:42:26 -0700181 def length(self):
182 return self.len
183
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700184 @property
185 def is_ip6(self):
186 return self.addr.is_ip6
187
Neale Rannsc0a93142018-09-05 15:42:26 -0700188 def __str__(self):
189 return "%s/%d" % (self.address, self.length)
190
191 def __eq__(self, other):
192 if isinstance(other, self.__class__):
193 return (self.len == other.len and self.addr == other.addr)
194 elif hasattr(other, "address") and hasattr(other, "address_length"):
195 # vl_api_prefix_t
196 return self.len == other.address_length and \
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -0800197 self.addr == other.address
Neale Rannsc0a93142018-09-05 15:42:26 -0700198 else:
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -0800199 _log.error(
200 "Comparing VppIpPrefix:%s with incomparable type: %s" %
201 (self, other))
202 return NotImplemented
Neale Rannsc0a93142018-09-05 15:42:26 -0700203
Neale Rannsd0df49f2018-08-08 01:06:40 -0700204
205class VppIpMPrefix():
Neale Ranns097fa662018-05-01 05:17:55 -0700206 def __init__(self, saddr, gaddr, glen):
Neale Rannsd0df49f2018-08-08 01:06:40 -0700207 self.saddr = saddr
208 self.gaddr = gaddr
Neale Ranns097fa662018-05-01 05:17:55 -0700209 self.glen = glen
210 self.ip_saddr = VppIpAddressUnion(text_type(self.saddr))
211 self.ip_gaddr = VppIpAddressUnion(text_type(self.gaddr))
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -0800212 if self.ip_saddr.version != self.ip_gaddr.version:
213 raise ValueError('Source and group addresses must be of the '
214 'same address family.')
Neale Rannsd0df49f2018-08-08 01:06:40 -0700215
216 def encode(self):
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -0800217 if 6 == self.ip_saddr.version:
Neale Rannsd0df49f2018-08-08 01:06:40 -0700218 prefix = {
Ole Troan0685da42018-10-16 14:42:50 +0200219 'af': VppEnum.vl_api_address_family_t.ADDRESS_IP6,
Neale Ranns097fa662018-05-01 05:17:55 -0700220 'grp_address': {
221 'ip6': self.gaddr
222 },
223 'src_address': {
224 'ip6': self.saddr
225 },
226 'grp_address_length': self.glen,
Neale Rannsd0df49f2018-08-08 01:06:40 -0700227 }
228 else:
229 prefix = {
Ole Troan0685da42018-10-16 14:42:50 +0200230 'af': VppEnum.vl_api_address_family_t.ADDRESS_IP4,
Neale Ranns097fa662018-05-01 05:17:55 -0700231 'grp_address': {
232 'ip4': self.gaddr
233 },
234 'src_address': {
235 'ip4': self.saddr
236 },
237 'grp_address_length': self.glen,
Neale Rannsd0df49f2018-08-08 01:06:40 -0700238 }
239 return prefix
Neale Ranns097fa662018-05-01 05:17:55 -0700240
241 @property
242 def length(self):
243 return self.glen
244
245 @property
246 def version(self):
247 return self.ip_gaddr.version
248
249 def __str__(self):
250 return "(%s,%s)/%d" % (self.saddr, self.gaddr, self.glen)
251
252 def __eq__(self, other):
253 if isinstance(other, self.__class__):
254 return (self.glen == other.glen and
255 self.ip_saddr == other.ip_gaddr and
256 self.ip_saddr == other.ip_saddr)
257 elif (hasattr(other, "grp_address_length") and
258 hasattr(other, "grp_address") and
259 hasattr(other, "src_address")):
260 # vl_api_mprefix_t
261 if 4 == self.ip_saddr.version:
262 if self.glen == other.grp_address_length and \
263 self.gaddr == str(other.grp_address.ip4) and \
264 self.saddr == str(other.src_address.ip4):
265 return True
266 return False
267 else:
268 return (self.glen == other.grp_address_length and
269 self.gaddr == other.grp_address.ip6 and
270 self.saddr == other.src_address.ip6)
271 else:
272 raise Exception("Comparing VppIpPrefix:%s with unknown type: %s" %
273 (self, other))
274 return False