blob: fa32c35200f36588db990f63354c74a29ee8153f [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
Jakub Grajciar2df2f752020-12-01 11:23:44 +01008from vpp_object import VppObject
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02009
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
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020027INVALID_INDEX = 0xFFFFFFFF
Neale Rannsd0df49f2018-08-08 01:06:40 -070028
29
Neale Rannsefd7bc22019-11-11 08:32:34 +000030def get_dpo_proto(addr):
31 if ip_address(addr).version == 6:
32 return DpoProto.DPO_PROTO_IP6
33 else:
34 return DpoProto.DPO_PROTO_IP4
35
36
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020037class VppIpAddressUnion:
Neale Rannsd0df49f2018-08-08 01:06:40 -070038 def __init__(self, addr):
39 self.addr = addr
Paul Vinciguerra9e315952019-01-29 11:51:44 -080040 self.ip_addr = ip_address(text_type(self.addr))
Neale Rannsd0df49f2018-08-08 01:06:40 -070041
Neale Rannsd0df49f2018-08-08 01:06:40 -070042 def encode(self):
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -080043 if self.version == 6:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020044 return {"ip6": self.ip_addr}
Neale Rannsd0df49f2018-08-08 01:06:40 -070045 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020046 return {"ip4": self.ip_addr}
Neale Rannsd0df49f2018-08-08 01:06:40 -070047
Neale Rannsc0a93142018-09-05 15:42:26 -070048 @property
49 def version(self):
50 return self.ip_addr.version
51
52 @property
53 def address(self):
54 return self.addr
55
56 @property
57 def length(self):
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -080058 return self.ip_addr.max_prefixlen
Neale Rannsc0a93142018-09-05 15:42:26 -070059
60 @property
61 def bytes(self):
62 return self.ip_addr.packed
63
64 def __eq__(self, other):
65 if isinstance(other, self.__class__):
66 return self.ip_addr == other.ip_addr
67 elif hasattr(other, "ip4") and hasattr(other, "ip6"):
68 # vl_api_address_union_t
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -080069 if 4 == self.version:
Neale Ranns9db6ada2019-11-08 12:42:31 +000070 return self.ip_addr == other.ip4
Neale Rannsc0a93142018-09-05 15:42:26 -070071 else:
Neale Ranns9db6ada2019-11-08 12:42:31 +000072 return self.ip_addr == other.ip6
Neale Rannsc0a93142018-09-05 15:42:26 -070073 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020074 raise Exception(
75 "Comparing VppIpAddressUnions:%s with incomparable type: %s",
76 self,
77 other,
78 )
Neale Ranns9db6ada2019-11-08 12:42:31 +000079
80 def __ne__(self, other):
81 return not (self == other)
Neale Rannsc0a93142018-09-05 15:42:26 -070082
Neale Ranns097fa662018-05-01 05:17:55 -070083 def __str__(self):
84 return str(self.ip_addr)
85
Neale Rannsd0df49f2018-08-08 01:06:40 -070086
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020087class VppIpMPrefix:
Neale Ranns097fa662018-05-01 05:17:55 -070088 def __init__(self, saddr, gaddr, glen):
Neale Rannsd0df49f2018-08-08 01:06:40 -070089 self.saddr = saddr
90 self.gaddr = gaddr
Neale Ranns097fa662018-05-01 05:17:55 -070091 self.glen = glen
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020092 if ip_address(self.saddr).version != ip_address(self.gaddr).version:
93 raise ValueError(
94 "Source and group addresses must be of the same address family."
95 )
Neale Rannsd0df49f2018-08-08 01:06:40 -070096
97 def encode(self):
Paul Vinciguerrae64e5ff2020-04-28 00:27:38 -040098 return {
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020099 "af": ip_address(self.gaddr).vapi_af,
100 "grp_address": {ip_address(self.gaddr).vapi_af_name: self.gaddr},
101 "src_address": {ip_address(self.saddr).vapi_af_name: self.saddr},
102 "grp_address_length": self.glen,
Paul Vinciguerrae64e5ff2020-04-28 00:27:38 -0400103 }
Neale Ranns097fa662018-05-01 05:17:55 -0700104
105 @property
106 def length(self):
107 return self.glen
108
109 @property
110 def version(self):
Neale Rannsefd7bc22019-11-11 08:32:34 +0000111 return ip_address(self.gaddr).version
Neale Ranns097fa662018-05-01 05:17:55 -0700112
113 def __str__(self):
114 return "(%s,%s)/%d" % (self.saddr, self.gaddr, self.glen)
115
116 def __eq__(self, other):
117 if isinstance(other, self.__class__):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200118 return (
119 self.glen == other.glen
120 and self.saddr == other.gaddr
121 and self.saddr == other.saddr
122 )
123 elif (
124 hasattr(other, "grp_address_length")
125 and hasattr(other, "grp_address")
126 and hasattr(other, "src_address")
127 ):
Neale Ranns097fa662018-05-01 05:17:55 -0700128 # vl_api_mprefix_t
Neale Rannsefd7bc22019-11-11 08:32:34 +0000129 if 4 == self.version:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200130 return (
131 self.glen == other.grp_address_length
132 and self.gaddr == str(other.grp_address.ip4)
133 and self.saddr == str(other.src_address.ip4)
134 )
Neale Ranns097fa662018-05-01 05:17:55 -0700135 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200136 return (
137 self.glen == other.grp_address_length
138 and self.gaddr == str(other.grp_address.ip6)
139 and self.saddr == str(other.src_address.ip6)
140 )
Paul Vinciguerrae64e5ff2020-04-28 00:27:38 -0400141 return NotImplemented
Jakub Grajciar2df2f752020-12-01 11:23:44 +0100142
143
144class VppIpPuntPolicer(VppObject):
145 def __init__(self, test, policer_index, is_ip6=False):
146 self._test = test
147 self._policer_index = policer_index
148 self._is_ip6 = is_ip6
149
150 def add_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200151 self._test.vapi.ip_punt_police(
152 policer_index=self._policer_index, is_ip6=self._is_ip6, is_add=True
153 )
Jakub Grajciar2df2f752020-12-01 11:23:44 +0100154
155 def remove_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200156 self._test.vapi.ip_punt_police(
157 policer_index=self._policer_index, is_ip6=self._is_ip6, is_add=False
158 )
Jakub Grajciar2df2f752020-12-01 11:23:44 +0100159
160 def query_vpp_config(self):
161 NotImplemented
162
163
164class VppIpPuntRedirect(VppObject):
165 def __init__(self, test, rx_index, tx_index, nh_addr):
166 self._test = test
167 self._rx_index = rx_index
168 self._tx_index = tx_index
169 self._nh_addr = ip_address(nh_addr)
170
171 def encode(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200172 return {
173 "rx_sw_if_index": self._rx_index,
174 "tx_sw_if_index": self._tx_index,
175 "nh": self._nh_addr,
176 }
Jakub Grajciar2df2f752020-12-01 11:23:44 +0100177
178 def add_vpp_config(self):
179 self._test.vapi.ip_punt_redirect(punt=self.encode(), is_add=True)
180 self._test.registry.register(self, self._test.logger)
Neale Rannsaa7cfd02022-03-24 12:28:42 +0000181 return self
Jakub Grajciar2df2f752020-12-01 11:23:44 +0100182
183 def remove_vpp_config(self):
184 self._test.vapi.ip_punt_redirect(punt=self.encode(), is_add=False)
185
186 def get_vpp_config(self):
187 is_ipv6 = True if self._nh_addr.version == 6 else False
188 return self._test.vapi.ip_punt_redirect_dump(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200189 sw_if_index=self._rx_index, is_ipv6=is_ipv6
190 )
Jakub Grajciar2df2f752020-12-01 11:23:44 +0100191
192 def query_vpp_config(self):
193 if self.get_vpp_config():
194 return True
195 return False
Neale Ranns8f5fef22020-12-21 08:29:34 +0000196
197
198class VppIpPathMtu(VppObject):
199 def __init__(self, test, nh, pmtu, table_id=0):
200 self._test = test
201 self.nh = nh
202 self.pmtu = pmtu
203 self.table_id = table_id
204
205 def add_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200206 self._test.vapi.ip_path_mtu_update(
207 pmtu={"nh": self.nh, "table_id": self.table_id, "path_mtu": self.pmtu}
208 )
Neale Ranns8f5fef22020-12-21 08:29:34 +0000209 self._test.registry.register(self, self._test.logger)
210 return self
211
212 def modify(self, pmtu):
213 self.pmtu = pmtu
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200214 self._test.vapi.ip_path_mtu_update(
215 pmtu={"nh": self.nh, "table_id": self.table_id, "path_mtu": self.pmtu}
216 )
Neale Ranns8f5fef22020-12-21 08:29:34 +0000217 return self
218
219 def remove_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200220 self._test.vapi.ip_path_mtu_update(
221 pmtu={"nh": self.nh, "table_id": self.table_id, "path_mtu": 0}
222 )
Neale Ranns8f5fef22020-12-21 08:29:34 +0000223
224 def query_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200225 ds = list(self._test.vapi.vpp.details_iter(self._test.vapi.ip_path_mtu_get))
Neale Ranns8f5fef22020-12-21 08:29:34 +0000226
227 for d in ds:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200228 if (
229 self.nh == str(d.pmtu.nh)
230 and self.table_id == d.pmtu.table_id
231 and self.pmtu == d.pmtu.path_mtu
232 ):
Neale Ranns8f5fef22020-12-21 08:29:34 +0000233 return True
234 return False
235
236 def object_id(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200237 return "ip-path-mtu-%d-%s-%d" % (self.table_id, self.nh, self.pmtu)
Neale Ranns8f5fef22020-12-21 08:29:34 +0000238
239 def __str__(self):
240 return self.object_id()