blob: 331accb993e6de26aa47adaf097f48391a16480c [file] [log] [blame]
Neale Rannsd0df49f2018-08-08 01:06:40 -07001"""
2 IP Types
3
4"""
Dave Wallace940a70f2024-04-03 12:31:42 -04005
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -08006import logging
Neale Rannsd0df49f2018-08-08 01:06:40 -07007
8from ipaddress import ip_address
Jakub Grajciar2df2f752020-12-01 11:23:44 +01009from vpp_object import VppObject
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020010
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
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020028INVALID_INDEX = 0xFFFFFFFF
Neale Rannsd0df49f2018-08-08 01:06:40 -070029
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
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020038class VppIpAddressUnion:
Neale Rannsd0df49f2018-08-08 01:06:40 -070039 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:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020045 return {"ip6": self.ip_addr}
Neale Rannsd0df49f2018-08-08 01:06:40 -070046 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020047 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:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020075 raise Exception(
76 "Comparing VppIpAddressUnions:%s with incomparable type: %s",
77 self,
78 other,
79 )
Neale Ranns9db6ada2019-11-08 12:42:31 +000080
81 def __ne__(self, other):
82 return not (self == other)
Neale Rannsc0a93142018-09-05 15:42:26 -070083
Neale Ranns097fa662018-05-01 05:17:55 -070084 def __str__(self):
85 return str(self.ip_addr)
86
Neale Rannsd0df49f2018-08-08 01:06:40 -070087
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020088class VppIpMPrefix:
Neale Ranns097fa662018-05-01 05:17:55 -070089 def __init__(self, saddr, gaddr, glen):
Neale Rannsd0df49f2018-08-08 01:06:40 -070090 self.saddr = saddr
91 self.gaddr = gaddr
Neale Ranns097fa662018-05-01 05:17:55 -070092 self.glen = glen
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020093 if ip_address(self.saddr).version != ip_address(self.gaddr).version:
94 raise ValueError(
95 "Source and group addresses must be of the same address family."
96 )
Neale Rannsd0df49f2018-08-08 01:06:40 -070097
98 def encode(self):
Paul Vinciguerrae64e5ff2020-04-28 00:27:38 -040099 return {
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200100 "af": ip_address(self.gaddr).vapi_af,
101 "grp_address": {ip_address(self.gaddr).vapi_af_name: self.gaddr},
102 "src_address": {ip_address(self.saddr).vapi_af_name: self.saddr},
103 "grp_address_length": self.glen,
Paul Vinciguerrae64e5ff2020-04-28 00:27:38 -0400104 }
Neale Ranns097fa662018-05-01 05:17:55 -0700105
106 @property
107 def length(self):
108 return self.glen
109
110 @property
111 def version(self):
Neale Rannsefd7bc22019-11-11 08:32:34 +0000112 return ip_address(self.gaddr).version
Neale Ranns097fa662018-05-01 05:17:55 -0700113
114 def __str__(self):
115 return "(%s,%s)/%d" % (self.saddr, self.gaddr, self.glen)
116
117 def __eq__(self, other):
118 if isinstance(other, self.__class__):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200119 return (
120 self.glen == other.glen
121 and self.saddr == other.gaddr
122 and self.saddr == other.saddr
123 )
124 elif (
125 hasattr(other, "grp_address_length")
126 and hasattr(other, "grp_address")
127 and hasattr(other, "src_address")
128 ):
Neale Ranns097fa662018-05-01 05:17:55 -0700129 # vl_api_mprefix_t
Neale Rannsefd7bc22019-11-11 08:32:34 +0000130 if 4 == self.version:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200131 return (
132 self.glen == other.grp_address_length
133 and self.gaddr == str(other.grp_address.ip4)
134 and self.saddr == str(other.src_address.ip4)
135 )
Neale Ranns097fa662018-05-01 05:17:55 -0700136 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200137 return (
138 self.glen == other.grp_address_length
139 and self.gaddr == str(other.grp_address.ip6)
140 and self.saddr == str(other.src_address.ip6)
141 )
Paul Vinciguerrae64e5ff2020-04-28 00:27:38 -0400142 return NotImplemented
Jakub Grajciar2df2f752020-12-01 11:23:44 +0100143
144
145class VppIpPuntPolicer(VppObject):
146 def __init__(self, test, policer_index, is_ip6=False):
147 self._test = test
148 self._policer_index = policer_index
149 self._is_ip6 = is_ip6
150
151 def add_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200152 self._test.vapi.ip_punt_police(
153 policer_index=self._policer_index, is_ip6=self._is_ip6, is_add=True
154 )
Jakub Grajciar2df2f752020-12-01 11:23:44 +0100155
156 def remove_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200157 self._test.vapi.ip_punt_police(
158 policer_index=self._policer_index, is_ip6=self._is_ip6, is_add=False
159 )
Jakub Grajciar2df2f752020-12-01 11:23:44 +0100160
161 def query_vpp_config(self):
162 NotImplemented
163
164
165class VppIpPuntRedirect(VppObject):
166 def __init__(self, test, rx_index, tx_index, nh_addr):
167 self._test = test
168 self._rx_index = rx_index
169 self._tx_index = tx_index
170 self._nh_addr = ip_address(nh_addr)
171
172 def encode(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200173 return {
174 "rx_sw_if_index": self._rx_index,
175 "tx_sw_if_index": self._tx_index,
176 "nh": self._nh_addr,
177 }
Jakub Grajciar2df2f752020-12-01 11:23:44 +0100178
179 def add_vpp_config(self):
180 self._test.vapi.ip_punt_redirect(punt=self.encode(), is_add=True)
181 self._test.registry.register(self, self._test.logger)
Neale Rannsaa7cfd02022-03-24 12:28:42 +0000182 return self
Jakub Grajciar2df2f752020-12-01 11:23:44 +0100183
184 def remove_vpp_config(self):
185 self._test.vapi.ip_punt_redirect(punt=self.encode(), is_add=False)
186
187 def get_vpp_config(self):
188 is_ipv6 = True if self._nh_addr.version == 6 else False
189 return self._test.vapi.ip_punt_redirect_dump(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200190 sw_if_index=self._rx_index, is_ipv6=is_ipv6
191 )
Jakub Grajciar2df2f752020-12-01 11:23:44 +0100192
193 def query_vpp_config(self):
194 if self.get_vpp_config():
195 return True
196 return False
Neale Ranns8f5fef22020-12-21 08:29:34 +0000197
198
199class VppIpPathMtu(VppObject):
200 def __init__(self, test, nh, pmtu, table_id=0):
201 self._test = test
202 self.nh = nh
203 self.pmtu = pmtu
204 self.table_id = table_id
205
206 def add_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200207 self._test.vapi.ip_path_mtu_update(
208 pmtu={"nh": self.nh, "table_id": self.table_id, "path_mtu": self.pmtu}
209 )
Neale Ranns8f5fef22020-12-21 08:29:34 +0000210 self._test.registry.register(self, self._test.logger)
211 return self
212
213 def modify(self, pmtu):
214 self.pmtu = pmtu
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200215 self._test.vapi.ip_path_mtu_update(
216 pmtu={"nh": self.nh, "table_id": self.table_id, "path_mtu": self.pmtu}
217 )
Neale Ranns8f5fef22020-12-21 08:29:34 +0000218 return self
219
220 def remove_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200221 self._test.vapi.ip_path_mtu_update(
222 pmtu={"nh": self.nh, "table_id": self.table_id, "path_mtu": 0}
223 )
Neale Ranns8f5fef22020-12-21 08:29:34 +0000224
225 def query_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200226 ds = list(self._test.vapi.vpp.details_iter(self._test.vapi.ip_path_mtu_get))
Neale Ranns8f5fef22020-12-21 08:29:34 +0000227
228 for d in ds:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200229 if (
230 self.nh == str(d.pmtu.nh)
231 and self.table_id == d.pmtu.table_id
232 and self.pmtu == d.pmtu.path_mtu
233 ):
Neale Ranns8f5fef22020-12-21 08:29:34 +0000234 return True
235 return False
236
237 def object_id(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200238 return "ip-path-mtu-%d-%s-%d" % (self.table_id, self.nh, self.pmtu)
Neale Ranns8f5fef22020-12-21 08:29:34 +0000239
240 def __str__(self):
241 return self.object_id()