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:
6 # http://www.apache.org/licenses/LICENSE-2.0
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.
15 from robot.api import logger
17 from resources.libraries.python.VatExecutor import VatExecutor, VatTerminal
20 class Classify(object):
21 """Classify utilities."""
24 def vpp_creates_classify_table_l3(node, ip_version, direction):
25 """Create classify table for IP address filtering.
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.
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.
41 output = VatExecutor.cmd_from_template(node, "classify_add_table.vat",
42 ip_version=ip_version,
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']))
52 raise RuntimeError('Unable to create classify table on node {}'
53 .format(node['host']))
55 return table_index, skip_n, match_n
58 def vpp_creates_classify_table_l2(node, direction):
59 """Create classify table for MAC address filtering.
61 :param node: VPP node to create classify table.
62 :param direction: Direction of traffic - src/dst.
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.
72 output = VatExecutor.cmd_from_template(node,
73 "classify_add_table_l2.vat",
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']))
83 raise RuntimeError('Unable to create classify table on node {}'
84 .format(node['host']))
86 return table_index, skip_n, match_n
89 def vpp_creates_classify_table_hex(node, hex_mask):
90 """Create classify table with hex mask.
92 :param node: VPP node to create classify table based on hex mask.
93 :param hex_mask: Classify hex mask.
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.
103 output = VatExecutor.cmd_from_template(node,
104 "classify_add_table_hex.vat",
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']))
114 raise RuntimeError('Unable to create classify table on node {}'
115 .format(node['host']))
117 return table_index, skip_n, match_n
120 def vpp_configures_classify_session_l3(node, acl_method, table_index, skip_n,
121 match_n, ip_version, direction,
123 """Configuration of classify session for IP address filtering.
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.
134 :type acl_method: str
135 :type table_index: int
138 :type ip_version: str
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,
148 ip_version=ip_version,
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.
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.
165 :type acl_method: str
166 :type table_index: int
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,
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.
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.
193 :type acl_method: str
194 :type table_index: int
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,
209 def vpp_configures_classify_session_generic(node, session_type, table_index,
210 skip_n, match_n, match,
212 """Configuration of classify session.
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.
225 :type session_type: str
226 :type table_index: int
233 match = ' '.join((match, match2))
235 with VatTerminal(node) as vat:
236 vat.vat_terminal_exec_cmd_from_template(
237 "classify_add_session_generic.vat",
239 table_index=table_index,
246 def compute_classify_hex_mask(ip_version, protocol, direction):
247 """Compute classify hex mask for TCP or UDP packet matching.
249 :param ip_version: Version of IP protocol.
250 :param protocol: Type of protocol.
251 :param direction: Traffic direction.
252 :type ip_version: str
255 :return: Classify hex mask.
257 :raises ValueError: If protocol is not TCP or UDP.
258 :raises ValueError: If direction is not source or destination or
259 source + destination.
261 if protocol == 'TCP' or protocol == 'UDP':
262 base_mask = Classify._compute_base_mask(ip_version)
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'
271 raise ValueError("Invalid direction!")
273 raise ValueError("Invalid protocol!")
276 def compute_classify_hex_value(hex_mask, source_port, destination_port):
277 """Compute classify hex value for TCP or UDP packet matching.
279 :param hex_mask: Classify hex mask.
280 :param source_port: Source TCP/UDP port.
281 :param destination_port: Destination TCP/UDP port.
283 :type source_port: str
284 :type destination_port: str
285 :return: Classify hex value.
288 source_port_hex = Classify._port_convert(source_port)
289 destination_port_hex = Classify._port_convert(destination_port)
291 return hex_mask[:-8] + source_port_hex + destination_port_hex
294 def _port_convert(port):
295 """Convert port number for classify hex table format.
297 :param port: TCP/UDP port number.
299 :return: TCP/UDP port number in 4-digit hexadecimal format.
302 return '{0:04x}'.format(int(port))
305 def _compute_base_mask(ip_version):
306 """Compute base classify hex mask based on IP version.
308 :param ip_version: Version of IP protocol.
309 :type ip_version: str
310 :return: Base hex mask.
313 if ip_version == 'ip4':
315 # base value of classify hex table for IPv4 TCP/UDP ports
316 elif ip_version == 'ip6':
318 # base value of classify hex table for IPv6 TCP/UDP ports
320 raise ValueError("Invalid IP version!")
323 def get_classify_table_data(node, table_index):
324 """Retrieve settings for classify table by ID.
326 :param node: VPP node to retrieve classify data from.
327 :param table_index: Index of a specific classify table.
329 :type table_index: int
330 :return: Classify table settings.
333 with VatTerminal(node) as vat:
334 data = vat.vat_terminal_exec_cmd_from_template(
335 "classify_table_info.vat",
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.
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)
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.
355 with VatTerminal(node) as vat:
356 data = vat.vat_terminal_exec_cmd_from_template(
357 "classify_session_dump.vat",
360 if session_index is not None:
361 return data[0][session_index]