blob: fb9e03ba3d4dbc9f8dbfb9e28c51c6ed727a8206 [file] [log] [blame]
Andrew Yourtchenko08118f02018-02-08 21:45:08 +01001#!/usr/bin/env python
2""" Classifier-based L2 ACL Test Case HLD:
3"""
4
5import unittest
6import random
7import binascii
8import socket
9
10
11from scapy.packet import Raw
Jan Gelety059d1d02018-07-03 13:58:24 +020012from scapy.data import ETH_P_IP
Andrew Yourtchenko08118f02018-02-08 21:45:08 +010013from scapy.layers.l2 import Ether
14from scapy.layers.inet import IP, TCP, UDP, ICMP
15from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest
16from scapy.layers.inet6 import IPv6ExtHdrFragment
17from framework import VppTestCase, VppTestRunner
18from util import Host, ppp
19
20
21class TestClassifyAcl(VppTestCase):
22 """ Classifier-based L2 input and output ACL Test Case """
23
24 # traffic types
25 IP = 0
26 ICMP = 1
27
28 # IP version
29 IPRANDOM = -1
30 IPV4 = 0
31 IPV6 = 1
32
33 # rule types
34 DENY = 0
35 PERMIT = 1
36
37 # supported protocols
38 proto = [[6, 17], [1, 58]]
39 proto_map = {1: 'ICMP', 58: 'ICMPv6EchoRequest', 6: 'TCP', 17: 'UDP'}
40 ICMPv4 = 0
41 ICMPv6 = 1
42 TCP = 0
43 UDP = 1
44 PROTO_ALL = 0
45
46 # port ranges
47 PORTS_ALL = -1
48 PORTS_RANGE = 0
49 PORTS_RANGE_2 = 1
50 udp_sport_from = 10
51 udp_sport_to = udp_sport_from + 5
52 udp_dport_from = 20000
53 udp_dport_to = udp_dport_from + 5000
54 tcp_sport_from = 30
55 tcp_sport_to = tcp_sport_from + 5
56 tcp_dport_from = 40000
57 tcp_dport_to = tcp_dport_from + 5000
58
59 udp_sport_from_2 = 90
60 udp_sport_to_2 = udp_sport_from_2 + 5
61 udp_dport_from_2 = 30000
62 udp_dport_to_2 = udp_dport_from_2 + 5000
63 tcp_sport_from_2 = 130
64 tcp_sport_to_2 = tcp_sport_from_2 + 5
65 tcp_dport_from_2 = 20000
66 tcp_dport_to_2 = tcp_dport_from_2 + 5000
67
68 icmp4_type = 8 # echo request
69 icmp4_code = 3
70 icmp6_type = 128 # echo request
71 icmp6_code = 3
72
73 icmp4_type_2 = 8
74 icmp4_code_from_2 = 5
75 icmp4_code_to_2 = 20
76 icmp6_type_2 = 128
77 icmp6_code_from_2 = 8
78 icmp6_code_to_2 = 42
79
80 # Test variables
81 bd_id = 1
82
83 @classmethod
84 def setUpClass(cls):
85 """
86 Perform standard class setup (defined by class method setUpClass in
87 class VppTestCase) before running the test case, set test case related
88 variables and configure VPP.
89 """
90 super(TestClassifyAcl, cls).setUpClass()
91
92 try:
93 # Create 2 pg interfaces
94 cls.create_pg_interfaces(range(2))
95
96 # Packet flows mapping pg0 -> pg1, pg2 etc.
97 cls.flows = dict()
98 cls.flows[cls.pg0] = [cls.pg1]
99
100 # Packet sizes
101 cls.pg_if_packet_sizes = [64, 512, 1518, 9018]
102
103 # Create BD with MAC learning and unknown unicast flooding disabled
104 # and put interfaces to this BD
105 cls.vapi.bridge_domain_add_del(bd_id=cls.bd_id, uu_flood=1,
106 learn=1)
107 for pg_if in cls.pg_interfaces:
Ole Troana5b2eec2019-03-11 19:23:25 +0100108 cls.vapi.sw_interface_set_l2_bridge(
109 rx_sw_if_index=pg_if.sw_if_index, bd_id=cls.bd_id)
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100110
111 # Set up all interfaces
112 for i in cls.pg_interfaces:
113 i.admin_up()
114
115 # Mapping between packet-generator index and lists of test hosts
116 cls.hosts_by_pg_idx = dict()
117 for pg_if in cls.pg_interfaces:
118 cls.hosts_by_pg_idx[pg_if.sw_if_index] = []
119
120 # Create list of deleted hosts
121 cls.deleted_hosts_by_pg_idx = dict()
122 for pg_if in cls.pg_interfaces:
123 cls.deleted_hosts_by_pg_idx[pg_if.sw_if_index] = []
124
125 # warm-up the mac address tables
126 # self.warmup_test()
127
Jan Gelety059d1d02018-07-03 13:58:24 +0200128 # Holder of the active classify table key
129 cls.acl_active_table = ''
130
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100131 except Exception:
132 super(TestClassifyAcl, cls).tearDownClass()
133 raise
134
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -0700135 @classmethod
136 def tearDownClass(cls):
137 super(TestClassifyAcl, cls).tearDownClass()
138
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100139 def setUp(self):
140 super(TestClassifyAcl, self).setUp()
141
142 self.acl_tbl_idx = {}
143 self.reset_packet_infos()
144
145 def tearDown(self):
146 """
147 Show various debug prints after each test.
148 """
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100149 if not self.vpp_dead:
150 self.logger.info(self.vapi.ppcli("show inacl type l2"))
151 self.logger.info(self.vapi.ppcli("show outacl type l2"))
152 self.logger.info(self.vapi.ppcli("show classify tables verbose"))
153 self.logger.info(self.vapi.ppcli("show bridge-domain %s detail"
154 % self.bd_id))
Jan Gelety059d1d02018-07-03 13:58:24 +0200155 if self.acl_active_table == 'mac_inout':
156 self.output_acl_set_interface(
157 self.pg1, self.acl_tbl_idx.get(self.acl_active_table), 0)
158 self.input_acl_set_interface(
159 self.pg0, self.acl_tbl_idx.get(self.acl_active_table), 0)
160 self.acl_active_table = ''
161 elif self.acl_active_table == 'mac_out':
162 self.output_acl_set_interface(
163 self.pg1, self.acl_tbl_idx.get(self.acl_active_table), 0)
164 self.acl_active_table = ''
165 elif self.acl_active_table == 'mac_in':
166 self.input_acl_set_interface(
167 self.pg0, self.acl_tbl_idx.get(self.acl_active_table), 0)
168 self.acl_active_table = ''
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100169
Jan Gelety059d1d02018-07-03 13:58:24 +0200170 super(TestClassifyAcl, self).tearDown()
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100171
172 @staticmethod
173 def build_mac_mask(dst_mac='', src_mac='', ether_type=''):
174 """Build MAC ACL mask data with hexstring format
175
176 :param str dst_mac: source MAC address <0-ffffffffffff>
177 :param str src_mac: destination MAC address <0-ffffffffffff>
178 :param str ether_type: ethernet type <0-ffff>
179 """
180
Paul Vinciguerraea2450f2019-03-06 08:23:58 -0800181 return ('{!s:0>12}{!s:0>12}{!s:0>4}'.format(
182 dst_mac, src_mac, ether_type)).rstrip('0')
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100183
184 @staticmethod
185 def build_mac_match(dst_mac='', src_mac='', ether_type=''):
186 """Build MAC ACL match data with hexstring format
187
188 :param str dst_mac: source MAC address <x:x:x:x:x:x>
189 :param str src_mac: destination MAC address <x:x:x:x:x:x>
190 :param str ether_type: ethernet type <0-ffff>
191 """
192 if dst_mac:
193 dst_mac = dst_mac.replace(':', '')
194 if src_mac:
195 src_mac = src_mac.replace(':', '')
196
Paul Vinciguerraea2450f2019-03-06 08:23:58 -0800197 return ('{!s:0>12}{!s:0>12}{!s:0>4}'.format(
198 dst_mac, src_mac, ether_type)).rstrip('0')
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100199
200 def create_classify_table(self, key, mask, data_offset=0, is_add=1):
201 """Create Classify Table
202
203 :param str key: key for classify table (ex, ACL name).
204 :param str mask: mask value for interested traffic.
205 :param int match_n_vectors:
206 :param int is_add: option to configure classify table.
207 - create(1) or delete(0)
208 """
209 r = self.vapi.classify_add_del_table(
210 is_add,
211 binascii.unhexlify(mask),
212 match_n_vectors=(len(mask) - 1) // 32 + 1,
213 miss_next_index=0,
214 current_data_flag=1,
215 current_data_offset=data_offset)
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800216 self.assertIsNotNone(r, 'No response msg for add_del_table')
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100217 self.acl_tbl_idx[key] = r.new_table_index
218
219 def create_classify_session(self, intf, table_index, match,
220 hit_next_index=0xffffffff, is_add=1):
221 """Create Classify Session
222
223 :param VppInterface intf: Interface to apply classify session.
224 :param int table_index: table index to identify classify table.
225 :param str match: matched value for interested traffic.
226 :param int pbr_action: enable/disable PBR feature.
227 :param int vrfid: VRF id.
228 :param int is_add: option to configure classify session.
229 - create(1) or delete(0)
230 """
231 r = self.vapi.classify_add_del_session(
232 is_add,
233 table_index,
234 binascii.unhexlify(match),
235 hit_next_index=hit_next_index)
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800236 self.assertIsNotNone(r, 'No response msg for add_del_session')
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100237
238 def input_acl_set_interface(self, intf, table_index, is_add=1):
239 """Configure Input ACL interface
240
241 :param VppInterface intf: Interface to apply Input ACL feature.
242 :param int table_index: table index to identify classify table.
243 :param int is_add: option to configure classify session.
244 - enable(1) or disable(0)
245 """
246 r = self.vapi.input_acl_set_interface(
247 is_add,
248 intf.sw_if_index,
249 l2_table_index=table_index)
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800250 self.assertIsNotNone(r, 'No response msg for acl_set_interface')
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100251
252 def output_acl_set_interface(self, intf, table_index, is_add=1):
253 """Configure Output ACL interface
254
255 :param VppInterface intf: Interface to apply Output ACL feature.
256 :param int table_index: table index to identify classify table.
257 :param int is_add: option to configure classify session.
258 - enable(1) or disable(0)
259 """
260 r = self.vapi.output_acl_set_interface(
261 is_add,
262 intf.sw_if_index,
263 l2_table_index=table_index)
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800264 self.assertIsNotNone(r, 'No response msg for acl_set_interface')
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100265
266 def create_hosts(self, count, start=0):
267 """
268 Create required number of host MAC addresses and distribute them among
269 interfaces. Create host IPv4 address for every host MAC address.
270
271 :param int count: Number of hosts to create MAC/IPv4 addresses for.
272 :param int start: Number to start numbering from.
273 """
274 n_int = len(self.pg_interfaces)
275 macs_per_if = count / n_int
276 i = -1
277 for pg_if in self.pg_interfaces:
278 i += 1
279 start_nr = macs_per_if * i + start
280 end_nr = count + start if i == (n_int - 1) \
281 else macs_per_if * (i + 1) + start
282 hosts = self.hosts_by_pg_idx[pg_if.sw_if_index]
283 for j in range(start_nr, end_nr):
284 host = Host(
285 "00:00:00:ff:%02x:%02x" % (pg_if.sw_if_index, j),
286 "172.17.1%02x.%u" % (pg_if.sw_if_index, j),
287 "2017:dead:%02x::%u" % (pg_if.sw_if_index, j))
288 hosts.append(host)
289
290 def create_upper_layer(self, packet_index, proto, ports=0):
291 p = self.proto_map[proto]
292 if p == 'UDP':
293 if ports == 0:
294 return UDP(sport=random.randint(self.udp_sport_from,
295 self.udp_sport_to),
296 dport=random.randint(self.udp_dport_from,
297 self.udp_dport_to))
298 else:
299 return UDP(sport=ports, dport=ports)
300 elif p == 'TCP':
301 if ports == 0:
302 return TCP(sport=random.randint(self.tcp_sport_from,
303 self.tcp_sport_to),
304 dport=random.randint(self.tcp_dport_from,
305 self.tcp_dport_to))
306 else:
307 return TCP(sport=ports, dport=ports)
308 return ''
309
310 def create_stream(self, src_if, packet_sizes, traffic_type=0, ipv6=0,
311 proto=-1, ports=0, fragments=False,
312 pkt_raw=True, etype=-1):
313 """
314 Create input packet stream for defined interface using hosts or
315 deleted_hosts list.
316
317 :param object src_if: Interface to create packet stream for.
318 :param list packet_sizes: List of required packet sizes.
319 :param traffic_type: 1: ICMP packet, 2: IPv6 with EH, 0: otherwise.
320 :return: Stream of packets.
321 """
322 pkts = []
323 if self.flows.__contains__(src_if):
324 src_hosts = self.hosts_by_pg_idx[src_if.sw_if_index]
325 for dst_if in self.flows[src_if]:
326 dst_hosts = self.hosts_by_pg_idx[dst_if.sw_if_index]
327 n_int = len(dst_hosts) * len(src_hosts)
328 for i in range(0, n_int):
329 dst_host = dst_hosts[i / len(src_hosts)]
330 src_host = src_hosts[i % len(src_hosts)]
331 pkt_info = self.create_packet_info(src_if, dst_if)
332 if ipv6 == 1:
333 pkt_info.ip = 1
334 elif ipv6 == 0:
335 pkt_info.ip = 0
336 else:
337 pkt_info.ip = random.choice([0, 1])
338 if proto == -1:
339 pkt_info.proto = random.choice(self.proto[self.IP])
340 else:
341 pkt_info.proto = proto
342 payload = self.info_to_payload(pkt_info)
343 p = Ether(dst=dst_host.mac, src=src_host.mac)
344 if etype > 0:
345 p = Ether(dst=dst_host.mac,
346 src=src_host.mac,
347 type=etype)
348 if pkt_info.ip:
349 p /= IPv6(dst=dst_host.ip6, src=src_host.ip6)
350 if fragments:
351 p /= IPv6ExtHdrFragment(offset=64, m=1)
352 else:
353 if fragments:
354 p /= IP(src=src_host.ip4, dst=dst_host.ip4,
355 flags=1, frag=64)
356 else:
357 p /= IP(src=src_host.ip4, dst=dst_host.ip4)
358 if traffic_type == self.ICMP:
359 if pkt_info.ip:
360 p /= ICMPv6EchoRequest(type=self.icmp6_type,
361 code=self.icmp6_code)
362 else:
363 p /= ICMP(type=self.icmp4_type,
364 code=self.icmp4_code)
365 else:
366 p /= self.create_upper_layer(i, pkt_info.proto, ports)
367 if pkt_raw:
368 p /= Raw(payload)
369 pkt_info.data = p.copy()
370 if pkt_raw:
371 size = random.choice(packet_sizes)
372 self.extend_packet(p, size)
373 pkts.append(p)
374 return pkts
375
376 def verify_capture(self, pg_if, capture,
377 traffic_type=0, ip_type=0, etype=-1):
378 """
379 Verify captured input packet stream for defined interface.
380
381 :param object pg_if: Interface to verify captured packet stream for.
382 :param list capture: Captured packet stream.
383 :param traffic_type: 1: ICMP packet, 2: IPv6 with EH, 0: otherwise.
384 """
385 last_info = dict()
386 for i in self.pg_interfaces:
387 last_info[i.sw_if_index] = None
388 dst_sw_if_index = pg_if.sw_if_index
389 for packet in capture:
390 if etype > 0:
391 if packet[Ether].type != etype:
392 self.logger.error(ppp("Unexpected ethertype in packet:",
393 packet))
394 else:
395 continue
396 try:
397 # Raw data for ICMPv6 are stored in ICMPv6EchoRequest.data
398 if traffic_type == self.ICMP and ip_type == self.IPV6:
399 payload_info = self.payload_to_info(
400 packet[ICMPv6EchoRequest].data)
401 payload = packet[ICMPv6EchoRequest]
402 else:
Paul Vinciguerraeaea4212019-03-06 11:58:06 -0800403 payload_info = self.payload_to_info(packet[Raw])
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100404 payload = packet[self.proto_map[payload_info.proto]]
405 except:
406 self.logger.error(ppp("Unexpected or invalid packet "
407 "(outside network):", packet))
408 raise
409
410 if ip_type != 0:
411 self.assertEqual(payload_info.ip, ip_type)
412 if traffic_type == self.ICMP:
413 try:
414 if payload_info.ip == 0:
415 self.assertEqual(payload.type, self.icmp4_type)
416 self.assertEqual(payload.code, self.icmp4_code)
417 else:
418 self.assertEqual(payload.type, self.icmp6_type)
419 self.assertEqual(payload.code, self.icmp6_code)
420 except:
421 self.logger.error(ppp("Unexpected or invalid packet "
422 "(outside network):", packet))
423 raise
424 else:
425 try:
426 ip_version = IPv6 if payload_info.ip == 1 else IP
427
428 ip = packet[ip_version]
429 packet_index = payload_info.index
430
431 self.assertEqual(payload_info.dst, dst_sw_if_index)
432 self.logger.debug("Got packet on port %s: src=%u (id=%u)" %
433 (pg_if.name, payload_info.src,
434 packet_index))
435 next_info = self.get_next_packet_info_for_interface2(
436 payload_info.src, dst_sw_if_index,
437 last_info[payload_info.src])
438 last_info[payload_info.src] = next_info
439 self.assertTrue(next_info is not None)
440 self.assertEqual(packet_index, next_info.index)
441 saved_packet = next_info.data
442 # Check standard fields
443 self.assertEqual(ip.src, saved_packet[ip_version].src)
444 self.assertEqual(ip.dst, saved_packet[ip_version].dst)
445 p = self.proto_map[payload_info.proto]
446 if p == 'TCP':
447 tcp = packet[TCP]
448 self.assertEqual(tcp.sport, saved_packet[
449 TCP].sport)
450 self.assertEqual(tcp.dport, saved_packet[
451 TCP].dport)
452 elif p == 'UDP':
453 udp = packet[UDP]
454 self.assertEqual(udp.sport, saved_packet[
455 UDP].sport)
456 self.assertEqual(udp.dport, saved_packet[
457 UDP].dport)
458 except:
459 self.logger.error(ppp("Unexpected or invalid packet:",
460 packet))
461 raise
462 for i in self.pg_interfaces:
463 remaining_packet = self.get_next_packet_info_for_interface2(
464 i, dst_sw_if_index, last_info[i.sw_if_index])
465 self.assertTrue(
466 remaining_packet is None,
467 "Port %u: Packet expected from source %u didn't arrive" %
468 (dst_sw_if_index, i.sw_if_index))
469
470 def run_traffic_no_check(self):
471 # Test
472 # Create incoming packet streams for packet-generator interfaces
473 for i in self.pg_interfaces:
474 if self.flows.__contains__(i):
475 pkts = self.create_stream(i, self.pg_if_packet_sizes)
476 if len(pkts) > 0:
477 i.add_stream(pkts)
478
479 # Enable packet capture and start packet sending
480 self.pg_enable_capture(self.pg_interfaces)
481 self.pg_start()
482
483 def run_verify_test(self, traffic_type=0, ip_type=0, proto=-1, ports=0,
484 frags=False, pkt_raw=True, etype=-1):
485 # Test
486 # Create incoming packet streams for packet-generator interfaces
487 pkts_cnt = 0
488 for i in self.pg_interfaces:
489 if self.flows.__contains__(i):
490 pkts = self.create_stream(i, self.pg_if_packet_sizes,
491 traffic_type, ip_type, proto, ports,
492 frags, pkt_raw, etype)
493 if len(pkts) > 0:
494 i.add_stream(pkts)
495 pkts_cnt += len(pkts)
496
497 # Enable packet capture and start packet sendingself.IPV
498 self.pg_enable_capture(self.pg_interfaces)
499 self.pg_start()
500
501 # Verify
502 # Verify outgoing packet streams per packet-generator interface
503 for src_if in self.pg_interfaces:
504 if self.flows.__contains__(src_if):
505 for dst_if in self.flows[src_if]:
506 capture = dst_if.get_capture(pkts_cnt)
507 self.logger.info("Verifying capture on interface %s" %
508 dst_if.name)
509 self.verify_capture(dst_if, capture,
510 traffic_type, ip_type, etype)
511
512 def run_verify_negat_test(self, traffic_type=0, ip_type=0, proto=-1,
513 ports=0, frags=False, etype=-1):
514 # Test
515 self.reset_packet_infos()
516 for i in self.pg_interfaces:
517 if self.flows.__contains__(i):
518 pkts = self.create_stream(i, self.pg_if_packet_sizes,
519 traffic_type, ip_type, proto, ports,
520 frags, True, etype)
521 if len(pkts) > 0:
522 i.add_stream(pkts)
523
524 # Enable packet capture and start packet sending
525 self.pg_enable_capture(self.pg_interfaces)
526 self.pg_start()
527
528 # Verify
529 # Verify outgoing packet streams per packet-generator interface
530 for src_if in self.pg_interfaces:
531 if self.flows.__contains__(src_if):
532 for dst_if in self.flows[src_if]:
533 self.logger.info("Verifying capture on interface %s" %
534 dst_if.name)
535 capture = dst_if.get_capture(0)
536 self.assertEqual(len(capture), 0)
537
Jan Gelety059d1d02018-07-03 13:58:24 +0200538 def build_classify_table(self, src_mac='', dst_mac='', ether_type='',
539 etype='', key='mac', hit_next_index=0xffffffff):
540 # Basic ACL testing
541 a_mask = self.build_mac_mask(src_mac=src_mac, dst_mac=dst_mac,
542 ether_type=ether_type)
543 self.create_classify_table(key, a_mask)
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100544 for host in self.hosts_by_pg_idx[self.pg0.sw_if_index]:
Jan Gelety059d1d02018-07-03 13:58:24 +0200545 s_mac = host.mac if src_mac else ''
546 if dst_mac:
547 for dst_if in self.flows[self.pg0]:
548 for dst_host in self.hosts_by_pg_idx[dst_if.sw_if_index]:
549 self.create_classify_session(
550 self.pg0, self.acl_tbl_idx.get(key),
551 self.build_mac_match(src_mac=s_mac,
552 dst_mac=dst_host.mac,
553 ether_type=etype),
554 hit_next_index=hit_next_index)
555 else:
556 self.create_classify_session(
557 self.pg0, self.acl_tbl_idx.get(key),
558 self.build_mac_match(src_mac=s_mac, dst_mac='',
559 ether_type=etype),
560 hit_next_index=hit_next_index)
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100561
562 def test_0000_warmup_test(self):
563 """ Learn the MAC addresses
564 """
565 self.create_hosts(2)
566 self.run_traffic_no_check()
567
Jan Gelety059d1d02018-07-03 13:58:24 +0200568 def test_0010_inacl_permit_src_mac(self):
569 """ Input L2 ACL test - permit source MAC
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100570
571 Test scenario for basic IP ACL with source IP
572 - Create IPv4 stream for pg0 -> pg1 interface.
573 - Create ACL with source MAC address.
574 - Send and verify received packets on pg1 interface.
575 """
Jan Gelety059d1d02018-07-03 13:58:24 +0200576 key = 'mac_in'
577 self.build_classify_table(src_mac='ffffffffffff', key=key)
578 self.input_acl_set_interface(self.pg0, self.acl_tbl_idx.get(key))
579 self.acl_active_table = key
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100580 self.run_verify_test(self.IP, self.IPV4, -1)
Jan Gelety059d1d02018-07-03 13:58:24 +0200581
582 def test_0011_inacl_permit_dst_mac(self):
583 """ Input L2 ACL test - permit destination MAC
584
585 Test scenario for basic IP ACL with source IP
586 - Create IPv4 stream for pg0 -> pg1 interface.
587 - Create ACL with destination MAC address.
588 - Send and verify received packets on pg1 interface.
589 """
590 key = 'mac_in'
591 self.build_classify_table(dst_mac='ffffffffffff', key=key)
592 self.input_acl_set_interface(self.pg0, self.acl_tbl_idx.get(key))
593 self.acl_active_table = key
594 self.run_verify_test(self.IP, self.IPV4, -1)
595
596 def test_0012_inacl_permit_src_dst_mac(self):
597 """ Input L2 ACL test - permit source and destination MAC
598
599 Test scenario for basic IP ACL with source IP
600 - Create IPv4 stream for pg0 -> pg1 interface.
601 - Create ACL with source and destination MAC addresses.
602 - Send and verify received packets on pg1 interface.
603 """
604 key = 'mac_in'
605 self.build_classify_table(
606 src_mac='ffffffffffff', dst_mac='ffffffffffff', key=key)
607 self.input_acl_set_interface(self.pg0, self.acl_tbl_idx.get(key))
608 self.acl_active_table = key
609 self.run_verify_test(self.IP, self.IPV4, -1)
610
611 def test_0013_inacl_permit_ether_type(self):
612 """ Input L2 ACL test - permit ether_type
613
614 Test scenario for basic IP ACL with source IP
615 - Create IPv4 stream for pg0 -> pg1 interface.
616 - Create ACL with destination MAC address.
617 - Send and verify received packets on pg1 interface.
618 """
619 key = 'mac_in'
620 self.build_classify_table(
621 ether_type='ffff', etype=hex(ETH_P_IP)[2:], key=key)
622 self.input_acl_set_interface(self.pg0, self.acl_tbl_idx.get(key))
623 self.acl_active_table = key
624 self.run_verify_test(self.IP, self.IPV4, -1)
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100625
626 def test_0015_inacl_deny(self):
627 """ Input L2 ACL test - deny
628
629 Test scenario for basic IP ACL with source IP
630 - Create IPv4 stream for pg0 -> pg1 interface.
Jan Gelety059d1d02018-07-03 13:58:24 +0200631
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100632 - Create ACL with source MAC address.
633 - Send and verify no received packets on pg1 interface.
634 """
Jan Gelety059d1d02018-07-03 13:58:24 +0200635 key = 'mac_in'
636 self.build_classify_table(
637 src_mac='ffffffffffff', hit_next_index=0, key=key)
638 self.input_acl_set_interface(self.pg0, self.acl_tbl_idx.get(key))
639 self.acl_active_table = key
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100640 self.run_verify_negat_test(self.IP, self.IPV4, -1)
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100641
642 def test_0020_outacl_permit(self):
643 """ Output L2 ACL test - permit
644
645 Test scenario for basic IP ACL with source IP
646 - Create IPv4 stream for pg0 -> pg1 interface.
647 - Create ACL with source MAC address.
648 - Send and verify received packets on pg1 interface.
649 """
Jan Gelety059d1d02018-07-03 13:58:24 +0200650 key = 'mac_out'
651 self.build_classify_table(src_mac='ffffffffffff', key=key)
652 self.output_acl_set_interface(self.pg1, self.acl_tbl_idx.get(key))
653 self.acl_active_table = key
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100654 self.run_verify_test(self.IP, self.IPV4, -1)
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100655
656 def test_0025_outacl_deny(self):
657 """ Output L2 ACL test - deny
658
659 Test scenario for basic IP ACL with source IP
660 - Create IPv4 stream for pg0 -> pg1 interface.
661 - Create ACL with source MAC address.
662 - Send and verify no received packets on pg1 interface.
663 """
Jan Gelety059d1d02018-07-03 13:58:24 +0200664 key = 'mac_out'
665 self.build_classify_table(
666 src_mac='ffffffffffff', hit_next_index=0, key=key)
667 self.output_acl_set_interface(self.pg1, self.acl_tbl_idx.get(key))
668 self.acl_active_table = key
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100669 self.run_verify_negat_test(self.IP, self.IPV4, -1)
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100670
671 def test_0030_inoutacl_permit(self):
672 """ Input+Output L2 ACL test - permit
673
674 Test scenario for basic IP ACL with source IP
675 - Create IPv4 stream for pg0 -> pg1 interface.
676 - Create ACLs with source MAC address.
677 - Send and verify received packets on pg1 interface.
678 """
Jan Gelety059d1d02018-07-03 13:58:24 +0200679 key = 'mac_inout'
680 self.build_classify_table(src_mac='ffffffffffff', key=key)
681 self.output_acl_set_interface(self.pg1, self.acl_tbl_idx.get(key))
682 self.input_acl_set_interface(self.pg0, self.acl_tbl_idx.get(key))
683 self.acl_active_table = key
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100684 self.run_verify_test(self.IP, self.IPV4, -1)
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100685
686if __name__ == '__main__':
687 unittest.main(testRunner=VppTestRunner)