blob: 0c26e7b9e6ad450bd2a8237bf825aef085bde38a [file] [log] [blame]
Govindarajan Mohandoss6d7dfcb2021-03-19 19:20:49 +00001import socket
2import unittest
3
4from util import ppp
5from framework import VppTestRunner
6from template_ipsec import SpdFlowCacheTemplate
7
8
9class SpdFlowCacheOutbound(SpdFlowCacheTemplate):
10 # Override setUpConstants to enable outbound flow cache in config
11 @classmethod
12 def setUpConstants(cls):
13 super(SpdFlowCacheOutbound, cls).setUpConstants()
14 cls.vpp_cmdline.extend(["ipsec", "{",
15 "ipv4-outbound-spd-flow-cache on",
16 "}"])
17 cls.logger.info("VPP modified cmdline is %s" % " "
18 .join(cls.vpp_cmdline))
19
20
21class IPSec4SpdTestCaseAdd(SpdFlowCacheOutbound):
22 """ IPSec/IPv4 outbound: Policy mode test case with flow cache \
23 (add rule)"""
24 def test_ipsec_spd_outbound_add(self):
25 # In this test case, packets in IPv4 FWD path are configured
26 # to go through IPSec outbound SPD policy lookup.
27 # 2 SPD rules (1 HIGH and 1 LOW) are added.
28 # High priority rule action is set to BYPASS.
29 # Low priority rule action is set to DISCARD.
30 # Traffic sent on pg0 interface should match high priority
31 # rule and should be sent out on pg1 interface.
32 self.create_interfaces(2)
33 pkt_count = 5
34 self.spd_create_and_intf_add(1, [self.pg1])
35 policy_0 = self.spd_add_rem_policy( # outbound, priority 10
36 1, self.pg0, self.pg1, socket.IPPROTO_UDP,
37 is_out=1, priority=10, policy_type="bypass")
38 policy_1 = self.spd_add_rem_policy( # outbound, priority 5
39 1, self.pg0, self.pg1, socket.IPPROTO_UDP,
40 is_out=1, priority=5, policy_type="discard")
41
42 # check flow cache is empty before sending traffic
43 self.verify_num_outbound_flow_cache_entries(0)
44
45 # create the packet stream
46 packets = self.create_stream(self.pg0, self.pg1, pkt_count)
47 # add the stream to the source interface + enable capture
48 self.pg0.add_stream(packets)
49 self.pg0.enable_capture()
50 self.pg1.enable_capture()
51 # start the packet generator
52 self.pg_start()
53 # get capture
54 capture = self.pg1.get_capture()
55 for packet in capture:
56 try:
57 self.logger.debug(ppp("SPD - Got packet:", packet))
58 except Exception:
59 self.logger.error(ppp("Unexpected or invalid packet:", packet))
60 raise
61 self.logger.debug("SPD: Num packets: %s", len(capture.res))
62
63 # assert nothing captured on pg0
64 self.pg0.assert_nothing_captured()
65 # verify captured packets
66 self.verify_capture(self.pg0, self.pg1, capture)
67 # verify all policies matched the expected number of times
68 self.verify_policy_match(pkt_count, policy_0)
69 self.verify_policy_match(0, policy_1)
70 # check policy in SPD has been cached after traffic
71 # matched BYPASS rule in SPD
72 self.verify_num_outbound_flow_cache_entries(1)
73
74
75class IPSec4SpdTestCaseRemove(SpdFlowCacheOutbound):
76 """ IPSec/IPv4 outbound: Policy mode test case with flow cache \
77 (remove rule)"""
78 def test_ipsec_spd_outbound_remove(self):
79 # In this test case, packets in IPv4 FWD path are configured
80 # to go through IPSec outbound SPD policy lookup.
81 # 2 SPD rules (1 HIGH and 1 LOW) are added.
82 # High priority rule action is set to BYPASS.
83 # Low priority rule action is set to DISCARD.
84 # High priority rule is then removed.
85 # Traffic sent on pg0 interface should match low priority
86 # rule and should be discarded after SPD lookup.
87 self.create_interfaces(2)
88 pkt_count = 5
89 self.spd_create_and_intf_add(1, [self.pg1])
90 policy_0 = self.spd_add_rem_policy( # outbound, priority 10
91 1, self.pg0, self.pg1, socket.IPPROTO_UDP,
92 is_out=1, priority=10, policy_type="bypass")
93 policy_1 = self.spd_add_rem_policy( # outbound, priority 5
94 1, self.pg0, self.pg1, socket.IPPROTO_UDP,
95 is_out=1, priority=5, policy_type="discard")
96
97 # check flow cache is empty before sending traffic
98 self.verify_num_outbound_flow_cache_entries(0)
99
100 # create the packet stream
101 packets = self.create_stream(self.pg0, self.pg1, pkt_count)
102 # add the stream to the source interface + enable capture
103 self.pg0.add_stream(packets)
104 self.pg0.enable_capture()
105 self.pg1.enable_capture()
106 # start the packet generator
107 self.pg_start()
108 # get capture
109 capture = self.pg1.get_capture()
110 for packet in capture:
111 try:
112 self.logger.debug(ppp("SPD - Got packet:", packet))
113 except Exception:
114 self.logger.error(ppp("Unexpected or invalid packet:", packet))
115 raise
116
117 # assert nothing captured on pg0
118 self.pg0.assert_nothing_captured()
119 # verify capture on pg1
120 self.logger.debug("SPD: Num packets: %s", len(capture.res))
121 self.verify_capture(self.pg0, self.pg1, capture)
122 # verify all policies matched the expected number of times
123 self.verify_policy_match(pkt_count, policy_0)
124 self.verify_policy_match(0, policy_1)
125 # check policy in SPD has been cached after traffic
126 # matched BYPASS rule in SPD
127 self.verify_num_outbound_flow_cache_entries(1)
128
129 # now remove the bypass rule
130 self.spd_add_rem_policy( # outbound, priority 10
131 1, self.pg0, self.pg1, socket.IPPROTO_UDP,
132 is_out=1, priority=10, policy_type="bypass",
133 remove=True)
134 # verify flow cache counter has been reset by rule removal
135 self.verify_num_outbound_flow_cache_entries(0)
136
137 # resend the same packets
138 self.pg0.add_stream(packets)
139 self.pg0.enable_capture() # flush the old captures
140 self.pg1.enable_capture()
141 self.pg_start()
142 # assert nothing captured on pg0
143 self.pg0.assert_nothing_captured()
144 # all packets will be dropped by SPD rule
145 self.pg1.assert_nothing_captured()
146 # verify all policies matched the expected number of times
147 self.verify_policy_match(pkt_count, policy_0)
148 self.verify_policy_match(pkt_count, policy_1)
149 # previous stale entry in flow cache should have been overwritten,
150 # with one active entry
151 self.verify_num_outbound_flow_cache_entries(1)
152
153
154class IPSec4SpdTestCaseReadd(SpdFlowCacheOutbound):
155 """ IPSec/IPv4 outbound: Policy mode test case with flow cache \
156 (add, remove, re-add)"""
157 def test_ipsec_spd_outbound_readd(self):
158 # In this test case, packets in IPv4 FWD path are configured
159 # to go through IPSec outbound SPD policy lookup.
160 # 2 SPD rules (1 HIGH and 1 LOW) are added.
161 # High priority rule action is set to BYPASS.
162 # Low priority rule action is set to DISCARD.
163 # Traffic sent on pg0 interface should match high priority
164 # rule and should be sent out on pg1 interface.
165 # High priority rule is then removed.
166 # Traffic sent on pg0 interface should match low priority
167 # rule and should be discarded after SPD lookup.
168 # Readd high priority rule.
169 # Traffic sent on pg0 interface should match high priority
170 # rule and should be sent out on pg1 interface.
171 self.create_interfaces(2)
172 pkt_count = 5
173 self.spd_create_and_intf_add(1, [self.pg1])
174 policy_0 = self.spd_add_rem_policy( # outbound, priority 10
175 1, self.pg0, self.pg1, socket.IPPROTO_UDP,
176 is_out=1, priority=10, policy_type="bypass")
177 policy_1 = self.spd_add_rem_policy( # outbound, priority 5
178 1, self.pg0, self.pg1, socket.IPPROTO_UDP,
179 is_out=1, priority=5, policy_type="discard")
180
181 # check flow cache is empty before sending traffic
182 self.verify_num_outbound_flow_cache_entries(0)
183
184 # create the packet stream
185 packets = self.create_stream(self.pg0, self.pg1, pkt_count)
186 # add the stream to the source interface + enable capture
187 self.pg0.add_stream(packets)
188 self.pg0.enable_capture()
189 self.pg1.enable_capture()
190 # start the packet generator
191 self.pg_start()
192 # get capture
193 capture = self.pg1.get_capture()
194 for packet in capture:
195 try:
196 self.logger.debug(ppp("SPD - Got packet:", packet))
197 except Exception:
198 self.logger.error(ppp("Unexpected or invalid packet:", packet))
199 raise
200 self.logger.debug("SPD: Num packets: %s", len(capture.res))
201
202 # assert nothing captured on pg0
203 self.pg0.assert_nothing_captured()
204 # verify capture on pg1
205 self.verify_capture(self.pg0, self.pg1, capture)
206 # verify all policies matched the expected number of times
207 self.verify_policy_match(pkt_count, policy_0)
208 self.verify_policy_match(0, policy_1)
209 # check policy in SPD has been cached after traffic
210 # matched BYPASS rule in SPD
211 self.verify_num_outbound_flow_cache_entries(1)
212
213 # now remove the bypass rule, leaving only the discard rule
214 self.spd_add_rem_policy( # outbound, priority 10
215 1, self.pg0, self.pg1, socket.IPPROTO_UDP,
216 is_out=1, priority=10, policy_type="bypass",
217 remove=True)
218 # verify flow cache counter has been reset by rule removal
219 self.verify_num_outbound_flow_cache_entries(0)
220
221 # resend the same packets
222 self.pg0.add_stream(packets)
223 self.pg0.enable_capture() # flush the old captures
224 self.pg1.enable_capture()
225 self.pg_start()
226
227 # assert nothing captured on pg0
228 self.pg0.assert_nothing_captured()
229 # all packets will be dropped by SPD rule
230 self.pg1.assert_nothing_captured()
231 # verify all policies matched the expected number of times
232 self.verify_policy_match(pkt_count, policy_0)
233 self.verify_policy_match(pkt_count, policy_1)
234 # previous stale entry in flow cache should have been overwritten
235 self.verify_num_outbound_flow_cache_entries(1)
236
237 # now readd the bypass rule
238 policy_0 = self.spd_add_rem_policy( # outbound, priority 10
239 1, self.pg0, self.pg1, socket.IPPROTO_UDP,
240 is_out=1, priority=10, policy_type="bypass")
241 # verify flow cache counter has been reset by rule addition
242 self.verify_num_outbound_flow_cache_entries(0)
243
244 # resend the same packets
245 self.pg0.add_stream(packets)
246 self.pg0.enable_capture() # flush the old captures
247 self.pg1.enable_capture()
248 self.pg_start()
249
250 # get capture
251 capture = self.pg1.get_capture(pkt_count)
252 for packet in capture:
253 try:
254 self.logger.debug(ppp("SPD - Got packet:", packet))
255 except Exception:
256 self.logger.error(ppp("Unexpected or invalid packet:", packet))
257 raise
258 self.logger.debug("SPD: Num packets: %s", len(capture.res))
259
260 # assert nothing captured on pg0
261 self.pg0.assert_nothing_captured()
262 # verify captured packets
263 self.verify_capture(self.pg0, self.pg1, capture)
264 # verify all policies matched the expected number of times
265 self.verify_policy_match(pkt_count, policy_0)
266 self.verify_policy_match(pkt_count, policy_1)
267 # previous stale entry in flow cache should have been overwritten
268 self.verify_num_outbound_flow_cache_entries(1)
269
270
271class IPSec4SpdTestCaseMultiple(SpdFlowCacheOutbound):
272 """ IPSec/IPv4 outbound: Policy mode test case with flow cache \
273 (multiple interfaces, multiple rules)"""
274 def test_ipsec_spd_outbound_multiple(self):
275 # In this test case, packets in IPv4 FWD path are configured to go
276 # through IPSec outbound SPD policy lookup.
277 # Multiples rules on multiple interfaces are tested at the same time.
278 # 3x interfaces are configured, binding the same SPD to each.
279 # Each interface has 2 SPD rules (1 BYPASS and 1 DISCARD).
280 # On pg0 & pg1, the BYPASS rule is HIGH priority
281 # On pg2, the DISCARD rule is HIGH priority
282 # Traffic should be received on pg0 & pg1 and dropped on pg2.
283 self.create_interfaces(3)
284 pkt_count = 5
285 # bind SPD to all interfaces
286 self.spd_create_and_intf_add(1, self.pg_interfaces)
287 # add rules on all interfaces
288 policy_01 = self.spd_add_rem_policy( # outbound, priority 10
289 1, self.pg0, self.pg1, socket.IPPROTO_UDP,
290 is_out=1, priority=10, policy_type="bypass")
291 policy_02 = self.spd_add_rem_policy( # outbound, priority 5
292 1, self.pg0, self.pg1, socket.IPPROTO_UDP,
293 is_out=1, priority=5, policy_type="discard")
294
295 policy_11 = self.spd_add_rem_policy( # outbound, priority 10
296 1, self.pg1, self.pg2, socket.IPPROTO_UDP,
297 is_out=1, priority=10, policy_type="bypass")
298 policy_12 = self.spd_add_rem_policy( # outbound, priority 5
299 1, self.pg1, self.pg2, socket.IPPROTO_UDP,
300 is_out=1, priority=5, policy_type="discard")
301
302 policy_21 = self.spd_add_rem_policy( # outbound, priority 5
303 1, self.pg2, self.pg0, socket.IPPROTO_UDP,
304 is_out=1, priority=5, policy_type="bypass")
305 policy_22 = self.spd_add_rem_policy( # outbound, priority 10
306 1, self.pg2, self.pg0, socket.IPPROTO_UDP,
307 is_out=1, priority=10, policy_type="discard")
308
309 # check flow cache is empty (0 active elements) before sending traffic
310 self.verify_num_outbound_flow_cache_entries(0)
311
312 # create the packet streams
313 packets0 = self.create_stream(self.pg0, self.pg1, pkt_count)
314 packets1 = self.create_stream(self.pg1, self.pg2, pkt_count)
315 packets2 = self.create_stream(self.pg2, self.pg0, pkt_count)
316 # add the streams to the source interfaces
317 self.pg0.add_stream(packets0)
318 self.pg1.add_stream(packets1)
319 self.pg2.add_stream(packets2)
320 # enable capture on all interfaces
321 for pg in self.pg_interfaces:
322 pg.enable_capture()
323 # start the packet generator
324 self.pg_start()
325
326 # get captures
327 if_caps = []
328 for pg in [self.pg1, self.pg2]: # we are expecting captures on pg1/pg2
329 if_caps.append(pg.get_capture())
330 for packet in if_caps[-1]:
331 try:
332 self.logger.debug(ppp("SPD - Got packet:", packet))
333 except Exception:
334 self.logger.error(
335 ppp("Unexpected or invalid packet:", packet))
336 raise
337 self.logger.debug("SPD: Num packets: %s", len(if_caps[0].res))
338 self.logger.debug("SPD: Num packets: %s", len(if_caps[1].res))
339
340 # verify captures that matched BYPASS rule
341 self.verify_capture(self.pg0, self.pg1, if_caps[0])
342 self.verify_capture(self.pg1, self.pg2, if_caps[1])
343 # verify that traffic to pg0 matched DISCARD rule and was dropped
344 self.pg0.assert_nothing_captured()
345 # verify all packets that were expected to match rules, matched
346 # pg0 -> pg1
347 self.verify_policy_match(pkt_count, policy_01)
348 self.verify_policy_match(0, policy_02)
349 # pg1 -> pg2
350 self.verify_policy_match(pkt_count, policy_11)
351 self.verify_policy_match(0, policy_12)
352 # pg2 -> pg0
353 self.verify_policy_match(0, policy_21)
354 self.verify_policy_match(pkt_count, policy_22)
355 # check that 3 matching policies in SPD have been cached
356 self.verify_num_outbound_flow_cache_entries(3)
357
358
359class IPSec4SpdTestCaseOverwriteStale(SpdFlowCacheOutbound):
360 """ IPSec/IPv4 outbound: Policy mode test case with flow cache \
361 (overwrite stale entries)"""
362 def test_ipsec_spd_outbound_overwrite(self):
363 # The operation of the flow cache is setup so that the entire cache
364 # is invalidated when adding or removing an SPD policy rule.
365 # For performance, old cache entries are not zero'd, but remain
366 # in the table as "stale" entries. If a flow matches a stale entry,
367 # and the epoch count does NOT match the current count, the entry
368 # is overwritten.
369 # In this test, 3 active rules are created and matched to enter
370 # them into the flow cache.
371 # A single entry is removed to invalidate the entire cache.
372 # We then readd the rule and test that overwriting of the previous
373 # stale entries occurs as expected, and that the flow cache entry
374 # counter is updated correctly.
375 self.create_interfaces(3)
376 pkt_count = 2
377 # bind SPD to all interfaces
378 self.spd_create_and_intf_add(1, self.pg_interfaces)
379 # add output rules on all interfaces
380 # pg0 -> pg1
381 policy_0 = self.spd_add_rem_policy( # outbound
382 1, self.pg0, self.pg1, socket.IPPROTO_UDP,
383 is_out=1, priority=10, policy_type="bypass")
384 # pg1 -> pg2
385 policy_1 = self.spd_add_rem_policy( # outbound
386 1, self.pg1, self.pg2, socket.IPPROTO_UDP,
387 is_out=1, priority=10, policy_type="bypass")
388 # pg2 -> pg0
389 policy_2 = self.spd_add_rem_policy( # outbound
390 1, self.pg2, self.pg0, socket.IPPROTO_UDP,
391 is_out=1, priority=10, policy_type="discard")
392
393 # check flow cache is empty (0 active elements) before sending traffic
394 self.verify_num_outbound_flow_cache_entries(0)
395
396 # create the packet streams
397 packets0 = self.create_stream(self.pg0, self.pg1, pkt_count)
398 packets1 = self.create_stream(self.pg1, self.pg2, pkt_count)
399 packets2 = self.create_stream(self.pg2, self.pg0, pkt_count)
400 # add the streams to the source interfaces
401 self.pg0.add_stream(packets0)
402 self.pg1.add_stream(packets1)
403 self.pg2.add_stream(packets2)
404 # enable capture on all interfaces
405 for pg in self.pg_interfaces:
406 pg.enable_capture()
407 # start the packet generator
408 self.pg_start()
409
410 # get captures from ifs
411 if_caps = []
412 for pg in [self.pg1, self.pg2]: # we are expecting captures on pg1/pg2
413 if_caps.append(pg.get_capture())
414 for packet in if_caps[-1]:
415 try:
416 self.logger.debug(ppp("SPD Add - Got packet:", packet))
417 except Exception:
418 self.logger.error(
419 ppp("Unexpected or invalid packet:", packet))
420 raise
421
422 # verify captures that matched BYPASS rules
423 self.verify_capture(self.pg0, self.pg1, if_caps[0])
424 self.verify_capture(self.pg1, self.pg2, if_caps[1])
425 # verify that traffic to pg0 matched DISCARD rule and was dropped
426 self.pg0.assert_nothing_captured()
427 # verify all policies matched the expected number of times
428 self.verify_policy_match(pkt_count, policy_0)
429 self.verify_policy_match(pkt_count, policy_1)
430 self.verify_policy_match(pkt_count, policy_2)
431 # check flow/policy match was cached for: 3x output policies
432 self.verify_num_outbound_flow_cache_entries(3)
433
434 # adding an inbound policy should not invalidate output flow cache
435 self.spd_add_rem_policy( # inbound
436 1, self.pg0, self.pg1, socket.IPPROTO_UDP,
437 is_out=0, priority=10, policy_type="bypass")
438 # check flow cache counter has not been reset
439 self.verify_num_outbound_flow_cache_entries(3)
440
441 # remove a bypass policy - flow cache counter will be reset, and
442 # there will be 3x stale entries in flow cache
443 self.spd_add_rem_policy( # outbound
444 1, self.pg0, self.pg1, socket.IPPROTO_UDP,
445 is_out=1, priority=10, policy_type="bypass",
446 remove=True)
447 # readd policy
448 policy_0 = self.spd_add_rem_policy( # outbound
449 1, self.pg0, self.pg1, socket.IPPROTO_UDP,
450 is_out=1, priority=10, policy_type="bypass")
451 # check counter was reset with flow cache invalidation
452 self.verify_num_outbound_flow_cache_entries(0)
453
454 # resend the same packets
455 self.pg0.add_stream(packets0)
456 self.pg1.add_stream(packets1)
457 self.pg2.add_stream(packets2)
458 for pg in self.pg_interfaces:
459 pg.enable_capture() # flush previous captures
460 self.pg_start()
461
462 # get captures from ifs
463 if_caps = []
464 for pg in [self.pg1, self.pg2]: # we are expecting captures on pg1/pg2
465 if_caps.append(pg.get_capture())
466 for packet in if_caps[-1]:
467 try:
468 self.logger.debug(ppp("SPD Add - Got packet:", packet))
469 except Exception:
470 self.logger.error(
471 ppp("Unexpected or invalid packet:", packet))
472 raise
473
474 # verify captures that matched BYPASS rules
475 self.verify_capture(self.pg0, self.pg1, if_caps[0])
476 self.verify_capture(self.pg1, self.pg2, if_caps[1])
477 # verify that traffic to pg0 matched DISCARD rule and was dropped
478 self.pg0.assert_nothing_captured()
479 # verify all policies matched the expected number of times
480 self.verify_policy_match(pkt_count, policy_0)
481 self.verify_policy_match(pkt_count*2, policy_1)
482 self.verify_policy_match(pkt_count*2, policy_2)
483 # we are overwriting 3x stale entries - check flow cache counter
484 # is correct
485 self.verify_num_outbound_flow_cache_entries(3)
486
487
488class IPSec4SpdTestCaseCollision(SpdFlowCacheOutbound):
489 """ IPSec/IPv4 outbound: Policy mode test case with flow cache \
490 (hash collision)"""
491 # Override class setup to restrict vector size to 16 elements.
492 # This forces using only the lower 4 bits of the hash as a key,
493 # making hash collisions easy to find.
494 @classmethod
495 def setUpConstants(cls):
496 super(SpdFlowCacheOutbound, cls).setUpConstants()
497 cls.vpp_cmdline.extend(["ipsec", "{",
498 "ipv4-outbound-spd-flow-cache on",
499 "ipv4-outbound-spd-hash-buckets 16",
500 "}"])
501 cls.logger.info("VPP modified cmdline is %s" % " "
502 .join(cls.vpp_cmdline))
503
504 def test_ipsec_spd_outbound_collision(self):
505 # The flow cache operation is setup to overwrite an entry
506 # if a hash collision occurs.
507 # In this test, 2 packets are configured that result in a
508 # hash with the same lower 4 bits.
509 # After the first packet is received, there should be one
510 # active entry in the flow cache.
511 # After the second packet with the same lower 4 bit hash
512 # is received, this should overwrite the same entry.
513 # Therefore there will still be a total of one (1) entry,
514 # in the flow cache with two matching policies.
515 # crc32_supported() method is used to check cpu for crc32
516 # intrinsic support for hashing.
517 # If crc32 is not supported, we fall back to clib_xxhash()
518 self.create_interfaces(3)
519 pkt_count = 5
520 # bind SPD to all interfaces
521 self.spd_create_and_intf_add(1, self.pg_interfaces)
522 # add rules
523 policy_0 = self.spd_add_rem_policy( # outbound, priority 10
524 1, self.pg1, self.pg2, socket.IPPROTO_UDP,
525 is_out=1, priority=10, policy_type="bypass")
526 policy_1 = self.spd_add_rem_policy( # outbound, priority 10
527 1, self.pg2, self.pg0, socket.IPPROTO_UDP,
528 is_out=1, priority=10, policy_type="bypass")
529
530 # check flow cache is empty (0 active elements) before sending traffic
531 self.verify_num_outbound_flow_cache_entries(0)
532
533 # create the packet streams generating collision on last 4 bits
534 if self.crc32_supported():
535 # packet hashes to:
536 # 432c99c2
537 packets1 = self.create_stream(self.pg1, self.pg2, pkt_count, 1, 1)
538 # 31f8f3f2
539 packets2 = self.create_stream(self.pg2, self.pg0, pkt_count, 6, 6)
540 else: # clib_xxhash
541 # ec3a258551bc0306
542 packets1 = self.create_stream(self.pg1, self.pg2, pkt_count, 2, 2)
543 # 61fee526d18d7a6
544 packets2 = self.create_stream(self.pg2, self.pg0, pkt_count, 3, 3)
545
546 # add the streams to the source interfaces
547 self.pg1.add_stream(packets1)
548 self.pg2.add_stream(packets2)
549 # enable capture on all interfaces
550 for pg in self.pg_interfaces:
551 pg.enable_capture()
552 # start the packet generator
553 self.pg_start()
554
555 # get captures from ifs - the proper pkt_count of packets was saved by
556 # create_packet_info() based on dst_if parameter
557 if_caps = []
558 for pg in [self.pg2, self.pg0]: # we are expecting captures on pg2/pg0
559 if_caps.append(pg.get_capture())
560 for packet in if_caps[-1]:
561 try:
562 self.logger.debug(ppp(
563 "SPD - Got packet:", packet))
564 except Exception:
565 self.logger.error(ppp(
566 "Unexpected or invalid packet:", packet))
567 raise
568 self.logger.debug("SPD: Num packets: %s", len(if_caps[0].res))
569 self.logger.debug("SPD: Num packets: %s", len(if_caps[1].res))
570
571 # verify captures that matched BYPASS rule
572 self.verify_capture(self.pg1, self.pg2, if_caps[0])
573 self.verify_capture(self.pg2, self.pg0, if_caps[1])
574 # verify all packets that were expected to match rules, matched
575 self.verify_policy_match(pkt_count, policy_0)
576 self.verify_policy_match(pkt_count, policy_1)
577 # we have matched 2 policies, but due to the hash collision
578 # one active entry is expected
579 self.verify_num_outbound_flow_cache_entries(1)
580
581
582if __name__ == '__main__':
583 unittest.main(testRunner=VppTestRunner)