blob: 48b6b9d2da68c804bdf74f2a72f0869f9b038cf5 [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
Jakub Grajciar2df2f752020-12-01 11:23:44 +010010from vpp_object import VppObject
Paul Vinciguerra9e315952019-01-29 11:51:44 -080011try:
12 text_type = unicode
13except NameError:
14 text_type = str
Neale Rannsd0df49f2018-08-08 01:06:40 -070015
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -080016_log = logging.getLogger(__name__)
17
Neale Rannsd0df49f2018-08-08 01:06:40 -070018
Neale Rannsc0a93142018-09-05 15:42:26 -070019class DpoProto:
20 DPO_PROTO_IP4 = 0
21 DPO_PROTO_IP6 = 1
22 DPO_PROTO_MPLS = 2
23 DPO_PROTO_ETHERNET = 3
24 DPO_PROTO_BIER = 4
25 DPO_PROTO_NSH = 5
26
27
Neale Rannsd0df49f2018-08-08 01:06:40 -070028INVALID_INDEX = 0xffffffff
29
30
Neale Rannsefd7bc22019-11-11 08:32:34 +000031def get_dpo_proto(addr):
32 if ip_address(addr).version == 6:
33 return DpoProto.DPO_PROTO_IP6
34 else:
35 return DpoProto.DPO_PROTO_IP4
36
37
Neale Rannsd0df49f2018-08-08 01:06:40 -070038class VppIpAddressUnion():
39 def __init__(self, addr):
40 self.addr = addr
Paul Vinciguerra9e315952019-01-29 11:51:44 -080041 self.ip_addr = ip_address(text_type(self.addr))
Neale Rannsd0df49f2018-08-08 01:06:40 -070042
Neale Rannsd0df49f2018-08-08 01:06:40 -070043 def encode(self):
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -080044 if self.version == 6:
Neale Ranns097fa662018-05-01 05:17:55 -070045 return {'ip6': self.ip_addr}
Neale Rannsd0df49f2018-08-08 01:06:40 -070046 else:
Neale Ranns097fa662018-05-01 05:17:55 -070047 return {'ip4': self.ip_addr}
Neale Rannsd0df49f2018-08-08 01:06:40 -070048
Neale Rannsc0a93142018-09-05 15:42:26 -070049 @property
50 def version(self):
51 return self.ip_addr.version
52
53 @property
54 def address(self):
55 return self.addr
56
57 @property
58 def length(self):
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -080059 return self.ip_addr.max_prefixlen
Neale Rannsc0a93142018-09-05 15:42:26 -070060
61 @property
62 def bytes(self):
63 return self.ip_addr.packed
64
65 def __eq__(self, other):
66 if isinstance(other, self.__class__):
67 return self.ip_addr == other.ip_addr
68 elif hasattr(other, "ip4") and hasattr(other, "ip6"):
69 # vl_api_address_union_t
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -080070 if 4 == self.version:
Neale Ranns9db6ada2019-11-08 12:42:31 +000071 return self.ip_addr == other.ip4
Neale Rannsc0a93142018-09-05 15:42:26 -070072 else:
Neale Ranns9db6ada2019-11-08 12:42:31 +000073 return self.ip_addr == other.ip6
Neale Rannsc0a93142018-09-05 15:42:26 -070074 else:
Neale Ranns9db6ada2019-11-08 12:42:31 +000075 raise Exception("Comparing VppIpAddressUnions:%s"
76 " with incomparable type: %s",
77 self, other)
78
79 def __ne__(self, other):
80 return not (self == other)
Neale Rannsc0a93142018-09-05 15:42:26 -070081
Neale Ranns097fa662018-05-01 05:17:55 -070082 def __str__(self):
83 return str(self.ip_addr)
84
Neale Rannsd0df49f2018-08-08 01:06:40 -070085
Neale Rannsd0df49f2018-08-08 01:06:40 -070086class VppIpMPrefix():
Neale Ranns097fa662018-05-01 05:17:55 -070087 def __init__(self, saddr, gaddr, glen):
Neale Rannsd0df49f2018-08-08 01:06:40 -070088 self.saddr = saddr
89 self.gaddr = gaddr
Neale Ranns097fa662018-05-01 05:17:55 -070090 self.glen = glen
Neale Rannsefd7bc22019-11-11 08:32:34 +000091 if ip_address(self.saddr).version != \
92 ip_address(self.gaddr).version:
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -080093 raise ValueError('Source and group addresses must be of the '
94 'same address family.')
Neale Rannsd0df49f2018-08-08 01:06:40 -070095
96 def encode(self):
Paul Vinciguerrae64e5ff2020-04-28 00:27:38 -040097 return {
98 'af': ip_address(self.gaddr).vapi_af,
99 'grp_address': {
100 ip_address(self.gaddr).vapi_af_name: self.gaddr
101 },
102 'src_address': {
103 ip_address(self.saddr).vapi_af_name: self.saddr
104 },
105 'grp_address_length': self.glen,
106 }
Neale Ranns097fa662018-05-01 05:17:55 -0700107
108 @property
109 def length(self):
110 return self.glen
111
112 @property
113 def version(self):
Neale Rannsefd7bc22019-11-11 08:32:34 +0000114 return ip_address(self.gaddr).version
Neale Ranns097fa662018-05-01 05:17:55 -0700115
116 def __str__(self):
117 return "(%s,%s)/%d" % (self.saddr, self.gaddr, self.glen)
118
119 def __eq__(self, other):
120 if isinstance(other, self.__class__):
121 return (self.glen == other.glen and
Neale Rannsefd7bc22019-11-11 08:32:34 +0000122 self.saddr == other.gaddr and
123 self.saddr == other.saddr)
Neale Ranns097fa662018-05-01 05:17:55 -0700124 elif (hasattr(other, "grp_address_length") and
125 hasattr(other, "grp_address") and
126 hasattr(other, "src_address")):
127 # vl_api_mprefix_t
Neale Rannsefd7bc22019-11-11 08:32:34 +0000128 if 4 == self.version:
129 return (self.glen == other.grp_address_length and
130 self.gaddr == str(other.grp_address.ip4) and
131 self.saddr == str(other.src_address.ip4))
Neale Ranns097fa662018-05-01 05:17:55 -0700132 else:
133 return (self.glen == other.grp_address_length and
Neale Rannsefd7bc22019-11-11 08:32:34 +0000134 self.gaddr == str(other.grp_address.ip6) and
135 self.saddr == str(other.src_address.ip6))
Paul Vinciguerrae64e5ff2020-04-28 00:27:38 -0400136 return NotImplemented
Jakub Grajciar2df2f752020-12-01 11:23:44 +0100137
138
139class VppIpPuntPolicer(VppObject):
140 def __init__(self, test, policer_index, is_ip6=False):
141 self._test = test
142 self._policer_index = policer_index
143 self._is_ip6 = is_ip6
144
145 def add_vpp_config(self):
146 self._test.vapi.ip_punt_police(policer_index=self._policer_index,
147 is_ip6=self._is_ip6, is_add=True)
148
149 def remove_vpp_config(self):
150 self._test.vapi.ip_punt_police(policer_index=self._policer_index,
151 is_ip6=self._is_ip6, is_add=False)
152
153 def query_vpp_config(self):
154 NotImplemented
155
156
157class VppIpPuntRedirect(VppObject):
158 def __init__(self, test, rx_index, tx_index, nh_addr):
159 self._test = test
160 self._rx_index = rx_index
161 self._tx_index = tx_index
162 self._nh_addr = ip_address(nh_addr)
163
164 def encode(self):
165 return {"rx_sw_if_index": self._rx_index,
166 "tx_sw_if_index": self._tx_index, "nh": self._nh_addr}
167
168 def add_vpp_config(self):
169 self._test.vapi.ip_punt_redirect(punt=self.encode(), is_add=True)
170 self._test.registry.register(self, self._test.logger)
Neale Rannsaa7cfd02022-03-24 12:28:42 +0000171 return self
Jakub Grajciar2df2f752020-12-01 11:23:44 +0100172
173 def remove_vpp_config(self):
174 self._test.vapi.ip_punt_redirect(punt=self.encode(), is_add=False)
175
176 def get_vpp_config(self):
177 is_ipv6 = True if self._nh_addr.version == 6 else False
178 return self._test.vapi.ip_punt_redirect_dump(
179 sw_if_index=self._rx_index, is_ipv6=is_ipv6)
180
181 def query_vpp_config(self):
182 if self.get_vpp_config():
183 return True
184 return False
Neale Ranns8f5fef22020-12-21 08:29:34 +0000185
186
187class VppIpPathMtu(VppObject):
188 def __init__(self, test, nh, pmtu, table_id=0):
189 self._test = test
190 self.nh = nh
191 self.pmtu = pmtu
192 self.table_id = table_id
193
194 def add_vpp_config(self):
195 self._test.vapi.ip_path_mtu_update(pmtu={'nh': self.nh,
196 'table_id': self.table_id,
197 'path_mtu': self.pmtu})
198 self._test.registry.register(self, self._test.logger)
199 return self
200
201 def modify(self, pmtu):
202 self.pmtu = pmtu
203 self._test.vapi.ip_path_mtu_update(pmtu={'nh': self.nh,
204 'table_id': self.table_id,
205 'path_mtu': self.pmtu})
206 return self
207
208 def remove_vpp_config(self):
209 self._test.vapi.ip_path_mtu_update(pmtu={'nh': self.nh,
210 'table_id': self.table_id,
211 'path_mtu': 0})
212
213 def query_vpp_config(self):
214 ds = list(self._test.vapi.vpp.details_iter(
215 self._test.vapi.ip_path_mtu_get))
216
217 for d in ds:
218 if self.nh == str(d.pmtu.nh) \
219 and self.table_id == d.pmtu.table_id \
220 and self.pmtu == d.pmtu.path_mtu:
221 return True
222 return False
223
224 def object_id(self):
225 return ("ip-path-mtu-%d-%s-%d" % (self.table_id,
226 self.nh,
227 self.pmtu))
228
229 def __str__(self):
230 return self.object_id()