CSIT-233 IPv4 IPFIX - baseline tests
[csit.git] / resources / libraries / python / Classify.py
1 # Copyright (c) 2016 Cisco and/or its affiliates.
2 # Licensed under the Apache License, Version 2.0 (the "License");
3 # you may not use this file except in compliance with the License.
4 # You may obtain a copy of the License at:
5 #
6 #     http://www.apache.org/licenses/LICENSE-2.0
7 #
8 # Unless required by applicable law or agreed to in writing, software
9 # distributed under the License is distributed on an "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 # See the License for the specific language governing permissions and
12 # limitations under the License.
13
14
15 from robot.api import logger
16
17 from resources.libraries.python.VatExecutor import VatExecutor, VatTerminal
18
19
20 class Classify(object):
21     """Classify utilities."""
22
23     @staticmethod
24     def vpp_creates_classify_table_l3(node, ip_version, direction):
25         """Create classify table for IP address filtering.
26
27         :param node: VPP node to create classify table.
28         :param ip_version: Version of IP protocol.
29         :param direction: Direction of traffic - src/dst.
30         :type node: dict
31         :type ip_version: str
32         :type direction: str
33         :return (table_index, skip_n, match_n)
34         table_index: Classify table index.
35         skip_n: Number of skip vectors.
36         match_n: Number of match vectors.
37         :rtype: tuple(int, int, int)
38         :raises RuntimeError: If VPP can't create table.
39         """
40
41         output = VatExecutor.cmd_from_template(node, "classify_add_table.vat",
42                                                ip_version=ip_version,
43                                                direction=direction)
44
45         if output[0]["retval"] == 0:
46             table_index = output[0]["new_table_index"]
47             skip_n = output[0]["skip_n_vectors"]
48             match_n = output[0]["match_n_vectors"]
49             logger.trace('Classify table with table_index {} created on node {}'
50                          .format(table_index, node['host']))
51         else:
52             raise RuntimeError('Unable to create classify table on node {}'
53                                .format(node['host']))
54
55         return table_index, skip_n, match_n
56
57     @staticmethod
58     def vpp_creates_classify_table_l2(node, direction):
59         """Create classify table for MAC address filtering.
60
61         :param node: VPP node to create classify table.
62         :param direction: Direction of traffic - src/dst.
63         :type node: dict
64         :type direction: str
65         :return (table_index, skip_n, match_n)
66         table_index: Classify table index.
67         skip_n: Number of skip vectors.
68         match_n: Number of match vectors.
69         :rtype: tuple(int, int, int)
70         :raises RuntimeError: If VPP can't create table.
71         """
72         output = VatExecutor.cmd_from_template(node,
73                                                "classify_add_table_l2.vat",
74                                                direction=direction)
75
76         if output[0]["retval"] == 0:
77             table_index = output[0]["new_table_index"]
78             skip_n = output[0]["skip_n_vectors"]
79             match_n = output[0]["match_n_vectors"]
80             logger.trace('Classify table with table_index {} created on node {}'
81                          .format(table_index, node['host']))
82         else:
83             raise RuntimeError('Unable to create classify table on node {}'
84                                .format(node['host']))
85
86         return table_index, skip_n, match_n
87
88     @staticmethod
89     def vpp_creates_classify_table_hex(node, hex_mask):
90         """Create classify table with hex mask.
91
92         :param node: VPP node to create classify table based on hex mask.
93         :param hex_mask: Classify hex mask.
94         :type node: dict
95         :type hex_mask: str
96         :return (table_index, skip_n, match_n)
97         table_index: Classify table index.
98         skip_n: Number of skip vectors.
99         match_n: Number of match vectors.
100         :rtype: tuple(int, int, int)
101         :raises RuntimeError: If VPP can't create table.
102         """
103         output = VatExecutor.cmd_from_template(node,
104                                                "classify_add_table_hex.vat",
105                                                hex_mask=hex_mask)
106
107         if output[0]["retval"] == 0:
108             table_index = output[0]["new_table_index"]
109             skip_n = output[0]["skip_n_vectors"]
110             match_n = output[0]["match_n_vectors"]
111             logger.trace('Classify table with table_index {} created on node {}'
112                          .format(table_index, node['host']))
113         else:
114             raise RuntimeError('Unable to create classify table on node {}'
115                                .format(node['host']))
116
117         return table_index, skip_n, match_n
118
119     @staticmethod
120     def vpp_configures_classify_session_l3(node, acl_method, table_index, skip_n,
121                                           match_n, ip_version, direction,
122                                           address):
123         """Configuration of classify session for IP address filtering.
124
125         :param node: VPP node to setup classify session.
126         :param acl_method: ACL method - deny/permit.
127         :param table_index: Classify table index.
128         :param skip_n: Number of skip vectors based on mask.
129         :param match_n: Number of match vectors based on mask.
130         :param ip_version: Version of IP protocol.
131         :param direction: Direction of traffic - src/dst.
132         :param address: IPv4 or IPv6 address.
133         :type node: dict
134         :type acl_method: str
135         :type table_index: int
136         :type skip_n: int
137         :type match_n: int
138         :type ip_version: str
139         :type direction: str
140         :type address: str
141         """
142         with VatTerminal(node) as vat:
143             vat.vat_terminal_exec_cmd_from_template("classify_add_session.vat",
144                                                     acl_method=acl_method,
145                                                     table_index=table_index,
146                                                     skip_n=skip_n,
147                                                     match_n=match_n,
148                                                     ip_version=ip_version,
149                                                     direction=direction,
150                                                     address=address)
151
152     @staticmethod
153     def vpp_configures_classify_session_l2(node, acl_method, table_index, skip_n,
154                                           match_n, direction, address):
155         """Configuration of classify session for MAC address filtering.
156
157         :param node: VPP node to setup classify session.
158         :param acl_method: ACL method - deny/permit.
159         :param table_index: Classify table index.
160         :param skip_n: Number of skip vectors based on mask.
161         :param match_n: Number of match vectors based on mask.
162         :param direction: Direction of traffic - src/dst.
163         :param address: IPv4 or IPv6 address.
164         :type node: dict
165         :type acl_method: str
166         :type table_index: int
167         :type skip_n: int
168         :type match_n: int
169         :type direction: str
170         :type address: str
171         """
172         with VatTerminal(node) as vat:
173             vat.vat_terminal_exec_cmd_from_template("classify_add_session_l2.vat",
174                                                     acl_method=acl_method,
175                                                     table_index=table_index,
176                                                     skip_n=skip_n,
177                                                     match_n=match_n,
178                                                     direction=direction,
179                                                     address=address)
180
181     @staticmethod
182     def vpp_configures_classify_session_hex(node, acl_method, table_index,
183                                            skip_n, match_n, hex_value):
184         """Configuration of classify session with hex value.
185
186         :param node: VPP node to setup classify session.
187         :param acl_method: ACL method - deny/permit.
188         :param table_index: Classify table index.
189         :param skip_n: Number of skip vectors based on mask.
190         :param match_n: Number of match vectors based on mask.
191         :param hex_value: Classify hex value.
192         :type node: dict
193         :type acl_method: str
194         :type table_index: int
195         :type skip_n: int
196         :type match_n: int
197         :type hex_value: str
198         """
199         with VatTerminal(node) as vat:
200             vat.vat_terminal_exec_cmd_from_template(
201                 "classify_add_session_hex.vat",
202                 acl_method=acl_method,
203                 table_index=table_index,
204                 skip_n=skip_n,
205                 match_n=match_n,
206                 hex_value=hex_value)
207
208     @staticmethod
209     def vpp_configures_classify_session_generic(node, session_type, table_index,
210                                                 skip_n, match_n, match,
211                                                 match2=''):
212         """Configuration of classify session.
213
214         :param node: VPP node to setup classify session.
215         :param session_type: Session type - hit-next, l2-hit-next, acl-hit-next
216         or policer-hit-next, and their respective parameters.
217         :param table_index: Classify table index.
218         :param skip_n: Number of skip vectors based on mask.
219         :param match_n: Number of match vectors based on mask.
220         :param match: Match value - l2, l3, l4 or hex, and their
221         respective parameters.
222         :param match2: Additional match values, to avoid using overly long
223         variables in RobotFramework.
224         :type node: dict
225         :type session_type: str
226         :type table_index: int
227         :type skip_n: int
228         :type match_n: int
229         :type match: str
230         :type match2: str
231         """
232
233         match = ' '.join((match, match2))
234
235         with VatTerminal(node) as vat:
236             vat.vat_terminal_exec_cmd_from_template(
237                 "classify_add_session_generic.vat",
238                 type=session_type,
239                 table_index=table_index,
240                 skip_n=skip_n,
241                 match_n=match_n,
242                 match=match,
243             )
244
245     @staticmethod
246     def compute_classify_hex_mask(ip_version, protocol, direction):
247         """Compute classify hex mask for TCP or UDP packet matching.
248
249         :param ip_version: Version of IP protocol.
250         :param protocol: Type of protocol.
251         :param direction: Traffic direction.
252         :type ip_version: str
253         :type protocol: str
254         :type direction: str
255         :return: Classify hex mask.
256         :rtype : str
257         :raises ValueError: If protocol is not TCP or UDP.
258         :raises ValueError: If direction is not source or destination or
259                             source + destination.
260         """
261         if protocol == 'TCP' or protocol == 'UDP':
262             base_mask = Classify._compute_base_mask(ip_version)
263
264             if direction == 'source':
265                 return base_mask + 'FFFF0000'
266             elif direction == 'destination':
267                 return base_mask + '0000FFFF'
268             elif direction == 'source + destination':
269                 return base_mask + 'FFFFFFFF'
270             else:
271                 raise ValueError("Invalid direction!")
272         else:
273             raise ValueError("Invalid protocol!")
274
275     @staticmethod
276     def compute_classify_hex_value(hex_mask, source_port, destination_port):
277         """Compute classify hex value for TCP or UDP packet matching.
278
279         :param hex_mask: Classify hex mask.
280         :param source_port: Source TCP/UDP port.
281         :param destination_port: Destination TCP/UDP port.
282         :type hex_mask: str
283         :type source_port: str
284         :type destination_port: str
285         :return: Classify hex value.
286         :rtype: str
287         """
288         source_port_hex = Classify._port_convert(source_port)
289         destination_port_hex = Classify._port_convert(destination_port)
290
291         return hex_mask[:-8] + source_port_hex + destination_port_hex
292
293     @staticmethod
294     def _port_convert(port):
295         """Convert port number for classify hex table format.
296
297         :param port: TCP/UDP port number.
298         :type port: str
299         :return: TCP/UDP port number in 4-digit hexadecimal format.
300         :rtype: str
301         """
302         return '{0:04x}'.format(int(port))
303
304     @staticmethod
305     def _compute_base_mask(ip_version):
306         """Compute base classify hex mask based on IP version.
307
308         :param ip_version: Version of IP protocol.
309         :type ip_version: str
310         :return: Base hex mask.
311         :rtype: str
312         """
313         if ip_version == 'ip4':
314             return 68 * '0'
315             # base value of classify hex table for IPv4 TCP/UDP ports
316         elif ip_version == 'ip6':
317             return 108 * '0'
318             # base value of classify hex table for IPv6 TCP/UDP ports
319         else:
320             raise ValueError("Invalid IP version!")
321
322     @staticmethod
323     def get_classify_table_data(node, table_index):
324         """Retrieve settings for classify table by ID.
325
326         :param node: VPP node to retrieve classify data from.
327         :param table_index: Index of a specific classify table.
328         :type node: dict
329         :type table_index: int
330         :return: Classify table settings.
331         :rtype: dict
332         """
333         with VatTerminal(node) as vat:
334             data = vat.vat_terminal_exec_cmd_from_template(
335                 "classify_table_info.vat",
336                 table_id=table_index
337             )
338         return data[0]
339
340     @staticmethod
341     def get_classify_session_data(node, table_index, session_index=None):
342         """Retrieve settings for all classify sessions in a table,
343         or for a specific classify session.
344
345         :param node: VPP node to retrieve classify data from.
346         :param table_index: Index of a classify table.
347         :param session_index: Index of a specific classify session. (Optional)
348         :type node: dict
349         :type table_index: int
350         :type session_index: int
351         :return: List of classify session settings, or a dictionary of settings
352          for a specific classify session.
353         :rtype: list or dict
354         """
355         with VatTerminal(node) as vat:
356             data = vat.vat_terminal_exec_cmd_from_template(
357                 "classify_session_dump.vat",
358                 table_id=table_index
359             )
360         if session_index is not None:
361             return data[0][session_index]
362         else:
363             return data[0]