blob: 24e7c19652af36952443bee35451b9725f1ee850 [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
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020011
Paul Vinciguerra9e315952019-01-29 11:51:44 -080012try:
13 text_type = unicode
14except NameError:
15 text_type = str
Neale Rannsd0df49f2018-08-08 01:06:40 -070016
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -080017_log = logging.getLogger(__name__)
18
Neale Rannsd0df49f2018-08-08 01:06:40 -070019
Neale Rannsc0a93142018-09-05 15:42:26 -070020class DpoProto:
21 DPO_PROTO_IP4 = 0
22 DPO_PROTO_IP6 = 1
23 DPO_PROTO_MPLS = 2
24 DPO_PROTO_ETHERNET = 3
25 DPO_PROTO_BIER = 4
26 DPO_PROTO_NSH = 5
27
28
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020029INVALID_INDEX = 0xFFFFFFFF
Neale Rannsd0df49f2018-08-08 01:06:40 -070030
31
Neale Rannsefd7bc22019-11-11 08:32:34 +000032def get_dpo_proto(addr):
33 if ip_address(addr).version == 6:
34 return DpoProto.DPO_PROTO_IP6
35 else:
36 return DpoProto.DPO_PROTO_IP4
37
38
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020039class VppIpAddressUnion:
Neale Rannsd0df49f2018-08-08 01:06:40 -070040 def __init__(self, addr):
41 self.addr = addr
Paul Vinciguerra9e315952019-01-29 11:51:44 -080042 self.ip_addr = ip_address(text_type(self.addr))
Neale Rannsd0df49f2018-08-08 01:06:40 -070043
Neale Rannsd0df49f2018-08-08 01:06:40 -070044 def encode(self):
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -080045 if self.version == 6:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020046 return {"ip6": self.ip_addr}
Neale Rannsd0df49f2018-08-08 01:06:40 -070047 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020048 return {"ip4": self.ip_addr}
Neale Rannsd0df49f2018-08-08 01:06:40 -070049
Neale Rannsc0a93142018-09-05 15:42:26 -070050 @property
51 def version(self):
52 return self.ip_addr.version
53
54 @property
55 def address(self):
56 return self.addr
57
58 @property
59 def length(self):
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -080060 return self.ip_addr.max_prefixlen
Neale Rannsc0a93142018-09-05 15:42:26 -070061
62 @property
63 def bytes(self):
64 return self.ip_addr.packed
65
66 def __eq__(self, other):
67 if isinstance(other, self.__class__):
68 return self.ip_addr == other.ip_addr
69 elif hasattr(other, "ip4") and hasattr(other, "ip6"):
70 # vl_api_address_union_t
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -080071 if 4 == self.version:
Neale Ranns9db6ada2019-11-08 12:42:31 +000072 return self.ip_addr == other.ip4
Neale Rannsc0a93142018-09-05 15:42:26 -070073 else:
Neale Ranns9db6ada2019-11-08 12:42:31 +000074 return self.ip_addr == other.ip6
Neale Rannsc0a93142018-09-05 15:42:26 -070075 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020076 raise Exception(
77 "Comparing VppIpAddressUnions:%s with incomparable type: %s",
78 self,
79 other,
80 )
Neale Ranns9db6ada2019-11-08 12:42:31 +000081
82 def __ne__(self, other):
83 return not (self == other)
Neale Rannsc0a93142018-09-05 15:42:26 -070084
Neale Ranns097fa662018-05-01 05:17:55 -070085 def __str__(self):
86 return str(self.ip_addr)
87
Neale Rannsd0df49f2018-08-08 01:06:40 -070088
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020089class VppIpMPrefix:
Neale Ranns097fa662018-05-01 05:17:55 -070090 def __init__(self, saddr, gaddr, glen):
Neale Rannsd0df49f2018-08-08 01:06:40 -070091 self.saddr = saddr
92 self.gaddr = gaddr
Neale Ranns097fa662018-05-01 05:17:55 -070093 self.glen = glen
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020094 if ip_address(self.saddr).version != ip_address(self.gaddr).version:
95 raise ValueError(
96 "Source and group addresses must be of the same address family."
97 )
Neale Rannsd0df49f2018-08-08 01:06:40 -070098
99 def encode(self):
Paul Vinciguerrae64e5ff2020-04-28 00:27:38 -0400100 return {
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200101 "af": ip_address(self.gaddr).vapi_af,
102 "grp_address": {ip_address(self.gaddr).vapi_af_name: self.gaddr},
103 "src_address": {ip_address(self.saddr).vapi_af_name: self.saddr},
104 "grp_address_length": self.glen,
Paul Vinciguerrae64e5ff2020-04-28 00:27:38 -0400105 }
Neale Ranns097fa662018-05-01 05:17:55 -0700106
107 @property
108 def length(self):
109 return self.glen
110
111 @property
112 def version(self):
Neale Rannsefd7bc22019-11-11 08:32:34 +0000113 return ip_address(self.gaddr).version
Neale Ranns097fa662018-05-01 05:17:55 -0700114
115 def __str__(self):
116 return "(%s,%s)/%d" % (self.saddr, self.gaddr, self.glen)
117
118 def __eq__(self, other):
119 if isinstance(other, self.__class__):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200120 return (
121 self.glen == other.glen
122 and self.saddr == other.gaddr
123 and self.saddr == other.saddr
124 )
125 elif (
126 hasattr(other, "grp_address_length")
127 and hasattr(other, "grp_address")
128 and hasattr(other, "src_address")
129 ):
Neale Ranns097fa662018-05-01 05:17:55 -0700130 # vl_api_mprefix_t
Neale Rannsefd7bc22019-11-11 08:32:34 +0000131 if 4 == self.version:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200132 return (
133 self.glen == other.grp_address_length
134 and self.gaddr == str(other.grp_address.ip4)
135 and self.saddr == str(other.src_address.ip4)
136 )
Neale Ranns097fa662018-05-01 05:17:55 -0700137 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200138 return (
139 self.glen == other.grp_address_length
140 and self.gaddr == str(other.grp_address.ip6)
141 and self.saddr == str(other.src_address.ip6)
142 )
Paul Vinciguerrae64e5ff2020-04-28 00:27:38 -0400143 return NotImplemented
Jakub Grajciar2df2f752020-12-01 11:23:44 +0100144
145
146class VppIpPuntPolicer(VppObject):
147 def __init__(self, test, policer_index, is_ip6=False):
148 self._test = test
149 self._policer_index = policer_index
150 self._is_ip6 = is_ip6
151
152 def add_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200153 self._test.vapi.ip_punt_police(
154 policer_index=self._policer_index, is_ip6=self._is_ip6, is_add=True
155 )
Jakub Grajciar2df2f752020-12-01 11:23:44 +0100156
157 def remove_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200158 self._test.vapi.ip_punt_police(
159 policer_index=self._policer_index, is_ip6=self._is_ip6, is_add=False
160 )
Jakub Grajciar2df2f752020-12-01 11:23:44 +0100161
162 def query_vpp_config(self):
163 NotImplemented
164
165
166class VppIpPuntRedirect(VppObject):
167 def __init__(self, test, rx_index, tx_index, nh_addr):
168 self._test = test
169 self._rx_index = rx_index
170 self._tx_index = tx_index
171 self._nh_addr = ip_address(nh_addr)
172
173 def encode(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200174 return {
175 "rx_sw_if_index": self._rx_index,
176 "tx_sw_if_index": self._tx_index,
177 "nh": self._nh_addr,
178 }
Jakub Grajciar2df2f752020-12-01 11:23:44 +0100179
180 def add_vpp_config(self):
181 self._test.vapi.ip_punt_redirect(punt=self.encode(), is_add=True)
182 self._test.registry.register(self, self._test.logger)
Neale Rannsaa7cfd02022-03-24 12:28:42 +0000183 return self
Jakub Grajciar2df2f752020-12-01 11:23:44 +0100184
185 def remove_vpp_config(self):
186 self._test.vapi.ip_punt_redirect(punt=self.encode(), is_add=False)
187
188 def get_vpp_config(self):
189 is_ipv6 = True if self._nh_addr.version == 6 else False
190 return self._test.vapi.ip_punt_redirect_dump(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200191 sw_if_index=self._rx_index, is_ipv6=is_ipv6
192 )
Jakub Grajciar2df2f752020-12-01 11:23:44 +0100193
194 def query_vpp_config(self):
195 if self.get_vpp_config():
196 return True
197 return False
Neale Ranns8f5fef22020-12-21 08:29:34 +0000198
199
200class VppIpPathMtu(VppObject):
201 def __init__(self, test, nh, pmtu, table_id=0):
202 self._test = test
203 self.nh = nh
204 self.pmtu = pmtu
205 self.table_id = table_id
206
207 def add_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200208 self._test.vapi.ip_path_mtu_update(
209 pmtu={"nh": self.nh, "table_id": self.table_id, "path_mtu": self.pmtu}
210 )
Neale Ranns8f5fef22020-12-21 08:29:34 +0000211 self._test.registry.register(self, self._test.logger)
212 return self
213
214 def modify(self, pmtu):
215 self.pmtu = pmtu
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200216 self._test.vapi.ip_path_mtu_update(
217 pmtu={"nh": self.nh, "table_id": self.table_id, "path_mtu": self.pmtu}
218 )
Neale Ranns8f5fef22020-12-21 08:29:34 +0000219 return self
220
221 def remove_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200222 self._test.vapi.ip_path_mtu_update(
223 pmtu={"nh": self.nh, "table_id": self.table_id, "path_mtu": 0}
224 )
Neale Ranns8f5fef22020-12-21 08:29:34 +0000225
226 def query_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200227 ds = list(self._test.vapi.vpp.details_iter(self._test.vapi.ip_path_mtu_get))
Neale Ranns8f5fef22020-12-21 08:29:34 +0000228
229 for d in ds:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200230 if (
231 self.nh == str(d.pmtu.nh)
232 and self.table_id == d.pmtu.table_id
233 and self.pmtu == d.pmtu.path_mtu
234 ):
Neale Ranns8f5fef22020-12-21 08:29:34 +0000235 return True
236 return False
237
238 def object_id(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200239 return "ip-path-mtu-%d-%s-%d" % (self.table_id, self.nh, self.pmtu)
Neale Ranns8f5fef22020-12-21 08:29:34 +0000240
241 def __str__(self):
242 return self.object_id()