tests: Add support for getting corefile patterns on FreeBSD
[vpp.git] / test / vpp_ip.py
1 """
2   IP Types
3
4 """
5 import logging
6
7 from ipaddress import ip_address
8 from vpp_object import VppObject
9
10 try:
11     text_type = unicode
12 except NameError:
13     text_type = str
14
15 _log = logging.getLogger(__name__)
16
17
18 class 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
27 INVALID_INDEX = 0xFFFFFFFF
28
29
30 def 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
37 class VppIpAddressUnion:
38     def __init__(self, addr):
39         self.addr = addr
40         self.ip_addr = ip_address(text_type(self.addr))
41
42     def encode(self):
43         if self.version == 6:
44             return {"ip6": self.ip_addr}
45         else:
46             return {"ip4": self.ip_addr}
47
48     @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):
58         return self.ip_addr.max_prefixlen
59
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
69             if 4 == self.version:
70                 return self.ip_addr == other.ip4
71             else:
72                 return self.ip_addr == other.ip6
73         else:
74             raise Exception(
75                 "Comparing VppIpAddressUnions:%s with incomparable type: %s",
76                 self,
77                 other,
78             )
79
80     def __ne__(self, other):
81         return not (self == other)
82
83     def __str__(self):
84         return str(self.ip_addr)
85
86
87 class VppIpMPrefix:
88     def __init__(self, saddr, gaddr, glen):
89         self.saddr = saddr
90         self.gaddr = gaddr
91         self.glen = glen
92         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             )
96
97     def encode(self):
98         return {
99             "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,
103         }
104
105     @property
106     def length(self):
107         return self.glen
108
109     @property
110     def version(self):
111         return ip_address(self.gaddr).version
112
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__):
118             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         ):
128             # vl_api_mprefix_t
129             if 4 == self.version:
130                 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                 )
135             else:
136                 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                 )
141         return NotImplemented
142
143
144 class 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):
151         self._test.vapi.ip_punt_police(
152             policer_index=self._policer_index, is_ip6=self._is_ip6, is_add=True
153         )
154
155     def remove_vpp_config(self):
156         self._test.vapi.ip_punt_police(
157             policer_index=self._policer_index, is_ip6=self._is_ip6, is_add=False
158         )
159
160     def query_vpp_config(self):
161         NotImplemented
162
163
164 class 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):
172         return {
173             "rx_sw_if_index": self._rx_index,
174             "tx_sw_if_index": self._tx_index,
175             "nh": self._nh_addr,
176         }
177
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)
181         return self
182
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(
189             sw_if_index=self._rx_index, is_ipv6=is_ipv6
190         )
191
192     def query_vpp_config(self):
193         if self.get_vpp_config():
194             return True
195         return False
196
197
198 class 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):
206         self._test.vapi.ip_path_mtu_update(
207             pmtu={"nh": self.nh, "table_id": self.table_id, "path_mtu": self.pmtu}
208         )
209         self._test.registry.register(self, self._test.logger)
210         return self
211
212     def modify(self, pmtu):
213         self.pmtu = pmtu
214         self._test.vapi.ip_path_mtu_update(
215             pmtu={"nh": self.nh, "table_id": self.table_id, "path_mtu": self.pmtu}
216         )
217         return self
218
219     def remove_vpp_config(self):
220         self._test.vapi.ip_path_mtu_update(
221             pmtu={"nh": self.nh, "table_id": self.table_id, "path_mtu": 0}
222         )
223
224     def query_vpp_config(self):
225         ds = list(self._test.vapi.vpp.details_iter(self._test.vapi.ip_path_mtu_get))
226
227         for d in ds:
228             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             ):
233                 return True
234         return False
235
236     def object_id(self):
237         return "ip-path-mtu-%d-%s-%d" % (self.table_id, self.nh, self.pmtu)
238
239     def __str__(self):
240         return self.object_id()