blob: 8b7ea222a67a841dbcee046c6a3c07bdb2bb4930 [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:
Ole Troan8c8acc02018-11-27 10:05:23 +010037 return {'ip6': self.ip_addr.packed}
Neale Rannsd0df49f2018-08-08 01:06:40 -070038 else:
Ole Troan8c8acc02018-11-27 10:05:23 +010039 return {'ip4': self.ip_addr.packed}
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 Rannsd0df49f2018-08-08 01:06:40 -070072
73class VppIpAddress():
74 def __init__(self, addr):
75 self.addr = VppIpAddressUnion(addr)
76
77 def encode(self):
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -080078 if self.addr.version == 6:
Neale Rannsd0df49f2018-08-08 01:06:40 -070079 return {
Ole Troan0685da42018-10-16 14:42:50 +020080 'af': VppEnum.vl_api_address_family_t.ADDRESS_IP6,
Neale Rannsd0df49f2018-08-08 01:06:40 -070081 'un': self.addr.encode()
82 }
83 else:
84 return {
Ole Troan0685da42018-10-16 14:42:50 +020085 'af': VppEnum.vl_api_address_family_t.ADDRESS_IP4,
Neale Rannsd0df49f2018-08-08 01:06:40 -070086 'un': self.addr.encode()
87 }
88
Neale Rannsc0a93142018-09-05 15:42:26 -070089 def __eq__(self, other):
90 if isinstance(other, self.__class__):
91 return self.addr == other.addr
92 elif hasattr(other, "af") and hasattr(other, "un"):
93 # a vp_api_address_t
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -080094 if 4 == self.version:
Ole Troan0685da42018-10-16 14:42:50 +020095 return other.af == \
96 VppEnum.vl_api_address_family_t.ADDRESS_IP4 and \
Neale Rannsc0a93142018-09-05 15:42:26 -070097 other.un == self.addr
98 else:
Ole Troan0685da42018-10-16 14:42:50 +020099 return other.af == \
100 VppEnum.vl_api_address_family_t.ADDRESS_IP6 and \
Neale Rannsc0a93142018-09-05 15:42:26 -0700101 other.un == self.addr
102 else:
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -0800103 _log.error(
104 "Comparing VppIpAddress:<%s> %s with incomparable "
105 "type: <%s> %s",
106 self.__class__.__name__, self,
107 other.__class__.__name__, other)
108 return NotImplemented
Neale Rannsc0a93142018-09-05 15:42:26 -0700109
110 def __ne__(self, other):
111 return not (self == other)
112
113 def __str__(self):
114 return self.address
115
116 @property
117 def bytes(self):
118 return self.addr.bytes
119
Neale Rannsd0df49f2018-08-08 01:06:40 -0700120 @property
121 def address(self):
122 return self.addr.address
123
Neale Rannsc0a93142018-09-05 15:42:26 -0700124 @property
125 def length(self):
126 return self.addr.length
127
128 @property
129 def version(self):
130 return self.addr.version
131
132 @property
133 def is_ip6(self):
134 return (self.version == 6)
135
136 @property
137 def af(self):
138 if self.version == 6:
139 return AF_INET6
140 else:
141 return AF_INET
142
143 @property
144 def dpo_proto(self):
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -0800145 if self.version == 6:
Neale Rannsc0a93142018-09-05 15:42:26 -0700146 return DpoProto.DPO_PROTO_IP6
147 else:
148 return DpoProto.DPO_PROTO_IP4
149
Neale Rannsd0df49f2018-08-08 01:06:40 -0700150
151class VppIpPrefix():
152 def __init__(self, addr, len):
153 self.addr = VppIpAddress(addr)
154 self.len = len
155
Neale Rannsd0df49f2018-08-08 01:06:40 -0700156 def encode(self):
157 return {'address': self.addr.encode(),
158 'address_length': self.len}
159
160 @property
161 def address(self):
162 return self.addr.address
163
Neale Rannsc0a93142018-09-05 15:42:26 -0700164 @property
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700165 def bytes(self):
166 return self.addr.bytes
167
168 @property
Neale Rannsc0a93142018-09-05 15:42:26 -0700169 def length(self):
170 return self.len
171
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700172 @property
173 def is_ip6(self):
174 return self.addr.is_ip6
175
Neale Rannsc0a93142018-09-05 15:42:26 -0700176 def __str__(self):
177 return "%s/%d" % (self.address, self.length)
178
179 def __eq__(self, other):
180 if isinstance(other, self.__class__):
181 return (self.len == other.len and self.addr == other.addr)
182 elif hasattr(other, "address") and hasattr(other, "address_length"):
183 # vl_api_prefix_t
184 return self.len == other.address_length and \
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -0800185 self.addr == other.address
Neale Rannsc0a93142018-09-05 15:42:26 -0700186 else:
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -0800187 _log.error(
188 "Comparing VppIpPrefix:%s with incomparable type: %s" %
189 (self, other))
190 return NotImplemented
Neale Rannsc0a93142018-09-05 15:42:26 -0700191
Neale Rannsd0df49f2018-08-08 01:06:40 -0700192
193class VppIpMPrefix():
194 def __init__(self, saddr, gaddr, len):
195 self.saddr = saddr
196 self.gaddr = gaddr
197 self.len = len
Paul Vinciguerra9e315952019-01-29 11:51:44 -0800198 self.ip_saddr = ip_address(text_type(self.saddr))
199 self.ip_gaddr = ip_address(text_type(self.gaddr))
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -0800200 if self.ip_saddr.version != self.ip_gaddr.version:
201 raise ValueError('Source and group addresses must be of the '
202 'same address family.')
Neale Rannsd0df49f2018-08-08 01:06:40 -0700203
204 def encode(self):
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -0800205 if 6 == self.ip_saddr.version:
Neale Rannsd0df49f2018-08-08 01:06:40 -0700206 prefix = {
Ole Troan0685da42018-10-16 14:42:50 +0200207 'af': VppEnum.vl_api_address_family_t.ADDRESS_IP6,
Ole Troan8c8acc02018-11-27 10:05:23 +0100208 'grp_address': {'ip6': self.ip_gaddr.packed},
209 'src_address': {'ip6': self.ip_saddr.packed},
Neale Rannsd0df49f2018-08-08 01:06:40 -0700210 'grp_address_length': self.len,
211 }
212 else:
213 prefix = {
Ole Troan0685da42018-10-16 14:42:50 +0200214 'af': VppEnum.vl_api_address_family_t.ADDRESS_IP4,
Ole Troan8c8acc02018-11-27 10:05:23 +0100215 'grp_address': {'ip4': self.ip_gaddr.packed},
216 'src_address': {'ip4': self.ip_saddr.packed},
Neale Rannsd0df49f2018-08-08 01:06:40 -0700217 'grp_address_length': self.len,
218 }
219 return prefix