6 from framework import VppTestRunner
7 from template_ipsec import SpdFlowCacheTemplate
10 class SpdFlowCacheInbound(SpdFlowCacheTemplate):
11 # Override setUpConstants to enable inbound flow cache in config
13 def setUpConstants(cls):
14 super(SpdFlowCacheInbound, cls).setUpConstants()
15 cls.vpp_cmdline.extend(["ipsec", "{",
16 "ipv4-inbound-spd-flow-cache on",
18 cls.logger.info("VPP modified cmdline is %s" % " "
19 .join(cls.vpp_cmdline))
22 class IPSec4SpdTestCaseBypass(SpdFlowCacheInbound):
23 """ IPSec/IPv4 inbound: Policy mode test case with flow cache \
25 def test_ipsec_spd_inbound_bypass(self):
26 # In this test case, packets in IPv4 FWD path are configured
27 # to go through IPSec inbound SPD policy lookup.
29 # 2 inbound SPD rules (1 HIGH and 1 LOW) are added.
30 # - High priority rule action is set to DISCARD.
31 # - Low priority rule action is set to BYPASS.
33 # Since BYPASS rules take precedence over DISCARD
34 # (the order being PROTECT, BYPASS, DISCARD) we expect the
35 # BYPASS rule to match and traffic to be correctly forwarded.
36 self.create_interfaces(2)
39 self.spd_create_and_intf_add(1, [self.pg1, self.pg0])
42 # bypass rule should take precedence over discard rule,
43 # even though it's lower priority
44 policy_0 = self.spd_add_rem_policy( # inbound, priority 10
45 1, self.pg1, self.pg0, socket.IPPROTO_UDP,
46 is_out=0, priority=10, policy_type="bypass")
47 policy_1 = self.spd_add_rem_policy( # inbound, priority 15
48 1, self.pg1, self.pg0, socket.IPPROTO_UDP,
49 is_out=0, priority=15, policy_type="discard")
51 # create output rule so we can capture forwarded packets
52 policy_2 = self.spd_add_rem_policy( # outbound, priority 10
53 1, self.pg0, self.pg1, socket.IPPROTO_UDP,
54 is_out=1, priority=10, policy_type="bypass")
56 # check flow cache is empty before sending traffic
57 self.verify_num_inbound_flow_cache_entries(0)
58 # create the packet stream
59 packets = self.create_stream(self.pg0, self.pg1, pkt_count)
60 # add the stream to the source interface
61 self.pg0.add_stream(packets)
62 self.pg1.enable_capture()
65 # check capture on pg1
66 capture = self.pg1.get_capture()
67 for packet in capture:
69 self.logger.debug(ppp("SPD Add - Got packet:", packet))
71 self.logger.error(ppp("Unexpected or invalid packet:", packet))
73 self.logger.debug("SPD: Num packets: %s", len(capture.res))
75 # verify captured packets
76 self.verify_capture(self.pg0, self.pg1, capture)
77 # verify all policies matched the expected number of times
78 self.verify_policy_match(pkt_count, policy_0)
79 self.verify_policy_match(0, policy_1)
80 self.verify_policy_match(pkt_count, policy_2)
81 # check input policy has been cached
82 self.verify_num_inbound_flow_cache_entries(1)
85 class IPSec4SpdTestCaseDiscard(SpdFlowCacheInbound):
86 """ IPSec/IPv4 inbound: Policy mode test case with flow cache \
88 def test_ipsec_spd_inbound_discard(self):
89 # In this test case, packets in IPv4 FWD path are configured
90 # to go through IPSec inbound SPD policy lookup.
91 # 1 DISCARD rule is added, so all traffic should be dropped.
92 self.create_interfaces(2)
95 self.spd_create_and_intf_add(1, [self.pg1, self.pg0])
98 policy_0 = self.spd_add_rem_policy( # inbound, priority 10
99 1, self.pg1, self.pg0, socket.IPPROTO_UDP,
100 is_out=0, priority=10, policy_type="discard")
102 # create output rule so we can capture forwarded packets
103 policy_1 = self.spd_add_rem_policy( # outbound, priority 10
104 1, self.pg0, self.pg1, socket.IPPROTO_UDP,
105 is_out=1, priority=10, policy_type="bypass")
107 # check flow cache is empty before sending traffic
108 self.verify_num_inbound_flow_cache_entries(0)
109 # create the packet stream
110 packets = self.create_stream(self.pg0, self.pg1, pkt_count)
111 # add the stream to the source interface
112 self.pg0.add_stream(packets)
113 self.pg1.enable_capture()
115 # inbound discard rule should have dropped traffic
116 self.pg1.assert_nothing_captured()
117 # verify all policies matched the expected number of times
118 self.verify_policy_match(pkt_count, policy_0)
119 self.verify_policy_match(0, policy_1)
120 # only inbound discard rule should have been cached
121 self.verify_num_inbound_flow_cache_entries(1)
124 class IPSec4SpdTestCaseRemove(SpdFlowCacheInbound):
125 """ IPSec/IPv4 inbound: Policy mode test case with flow cache \
127 def test_ipsec_spd_inbound_remove(self):
128 # In this test case, packets in IPv4 FWD path are configured
129 # to go through IPSec inbound SPD policy lookup.
131 # 2 inbound SPD rules (1 HIGH and 1 LOW) are added.
132 # - High priority rule action is set to DISCARD.
133 # - Low priority rule action is set to BYPASS.
135 # Since BYPASS rules take precedence over DISCARD
136 # (the order being PROTECT, BYPASS, DISCARD) we expect the
137 # BYPASS rule to match and traffic to be correctly forwarded.
139 # The BYPASS rules is then removed, and we check that all traffic
140 # is now correctly dropped.
141 self.create_interfaces(2)
144 self.spd_create_and_intf_add(1, [self.pg1, self.pg0])
147 # bypass rule should take precedence over discard rule,
148 # even though it's lower priority
149 policy_0 = self.spd_add_rem_policy( # inbound, priority 10
150 1, self.pg1, self.pg0, socket.IPPROTO_UDP,
151 is_out=0, priority=10, policy_type="bypass")
152 policy_1 = self.spd_add_rem_policy( # inbound, priority 15
153 1, self.pg1, self.pg0, socket.IPPROTO_UDP,
154 is_out=0, priority=15, policy_type="discard")
156 # create output rule so we can capture forwarded packets
157 policy_2 = self.spd_add_rem_policy( # outbound, priority 10
158 1, self.pg0, self.pg1, socket.IPPROTO_UDP,
159 is_out=1, priority=10, policy_type="bypass")
161 # check flow cache is empty before sending traffic
162 self.verify_num_inbound_flow_cache_entries(0)
163 # create the packet stream
164 packets = self.create_stream(self.pg0, self.pg1, pkt_count)
165 # add the stream to the source interface
166 self.pg0.add_stream(packets)
167 self.pg1.enable_capture()
170 # check capture on pg1
171 capture = self.pg1.get_capture()
172 for packet in capture:
174 self.logger.debug(ppp("SPD Add - Got packet:", packet))
176 self.logger.error(ppp("Unexpected or invalid packet:", packet))
178 self.logger.debug("SPD: Num packets: %s", len(capture.res))
180 # verify captured packets
181 self.verify_capture(self.pg0, self.pg1, capture)
182 # verify all policies matched the expected number of times
183 self.verify_policy_match(pkt_count, policy_0)
184 self.verify_policy_match(0, policy_1)
185 self.verify_policy_match(pkt_count, policy_2)
186 # check input policy has been cached
187 self.verify_num_inbound_flow_cache_entries(1)
189 # remove the input bypass rule
190 self.spd_add_rem_policy( # inbound, priority 10
191 1, self.pg1, self.pg0, socket.IPPROTO_UDP,
192 is_out=0, priority=10, policy_type="bypass",
194 # verify flow cache counter has been reset by rule removal
195 self.verify_num_inbound_flow_cache_entries(0)
197 # resend the same packets
198 self.pg0.add_stream(packets)
199 self.pg1.enable_capture() # flush the old capture
202 # inbound discard rule should have dropped traffic
203 self.pg1.assert_nothing_captured()
204 # verify all policies matched the expected number of times
205 self.verify_policy_match(pkt_count, policy_0)
206 self.verify_policy_match(pkt_count, policy_1)
207 self.verify_policy_match(pkt_count, policy_2)
208 # by removing the bypass rule, we should have reset the flow cache
209 # we only expect the discard rule to now be in the flow cache
210 self.verify_num_inbound_flow_cache_entries(1)
213 class IPSec4SpdTestCaseReadd(SpdFlowCacheInbound):
214 """ IPSec/IPv4 inbound: Policy mode test case with flow cache \
215 (add, remove, re-add bypass)"""
216 def test_ipsec_spd_inbound_readd(self):
217 # In this test case, packets in IPv4 FWD path are configured
218 # to go through IPSec inbound SPD policy lookup.
220 # 2 inbound SPD rules (1 HIGH and 1 LOW) are added.
221 # - High priority rule action is set to DISCARD.
222 # - Low priority rule action is set to BYPASS.
224 # Since BYPASS rules take precedence over DISCARD
225 # (the order being PROTECT, BYPASS, DISCARD) we expect the
226 # BYPASS rule to match and traffic to be correctly forwarded.
228 # The BYPASS rules is then removed, and we check that all traffic
229 # is now correctly dropped.
231 # The BYPASS rule is then readded, checking traffic is not forwarded
233 self.create_interfaces(2)
236 self.spd_create_and_intf_add(1, [self.pg1, self.pg0])
239 # bypass rule should take precedence over discard rule,
240 # even though it's lower priority
241 policy_0 = self.spd_add_rem_policy( # inbound, priority 10
242 1, self.pg1, self.pg0, socket.IPPROTO_UDP,
243 is_out=0, priority=10, policy_type="bypass")
244 policy_1 = self.spd_add_rem_policy( # inbound, priority 15
245 1, self.pg1, self.pg0, socket.IPPROTO_UDP,
246 is_out=0, priority=15, policy_type="discard")
248 # create output rule so we can capture forwarded packets
249 policy_2 = self.spd_add_rem_policy( # outbound, priority 10
250 1, self.pg0, self.pg1, socket.IPPROTO_UDP,
251 is_out=1, priority=10, policy_type="bypass")
253 # check flow cache is empty before sending traffic
254 self.verify_num_inbound_flow_cache_entries(0)
255 # create the packet stream
256 packets = self.create_stream(self.pg0, self.pg1, pkt_count)
257 # add the stream to the source interface
258 self.pg0.add_stream(packets)
259 self.pg1.enable_capture()
262 # check capture on pg1
263 capture = self.pg1.get_capture()
264 for packet in capture:
266 self.logger.debug(ppp("SPD Add - Got packet:", packet))
268 self.logger.error(ppp("Unexpected or invalid packet:", packet))
270 self.logger.debug("SPD: Num packets: %s", len(capture.res))
272 # verify captured packets
273 self.verify_capture(self.pg0, self.pg1, capture)
274 # verify all policies matched the expected number of times
275 self.verify_policy_match(pkt_count, policy_0)
276 self.verify_policy_match(0, policy_1)
277 self.verify_policy_match(pkt_count, policy_2)
278 # check input policy has been cached
279 self.verify_num_inbound_flow_cache_entries(1)
281 # remove the input bypass rule
282 self.spd_add_rem_policy( # inbound, priority 10
283 1, self.pg1, self.pg0, socket.IPPROTO_UDP,
284 is_out=0, priority=10, policy_type="bypass",
286 # verify flow cache counter has been reset by rule removal
287 self.verify_num_inbound_flow_cache_entries(0)
289 # resend the same packets
290 self.pg0.add_stream(packets)
291 self.pg1.enable_capture() # flush the old capture
294 # inbound discard rule should have dropped traffic
295 self.pg1.assert_nothing_captured()
296 # verify all policies matched the expected number of times
297 self.verify_policy_match(pkt_count, policy_0)
298 self.verify_policy_match(pkt_count, policy_1)
299 self.verify_policy_match(pkt_count, policy_2)
300 # by removing the bypass rule, flow cache was reset
301 # we only expect the discard rule to now be in the flow cache
302 self.verify_num_inbound_flow_cache_entries(1)
304 # readd the input bypass rule
305 policy_0 = self.spd_add_rem_policy( # inbound, priority 10
306 1, self.pg1, self.pg0, socket.IPPROTO_UDP,
307 is_out=0, priority=10, policy_type="bypass")
308 # verify flow cache counter has been reset by rule addition
309 self.verify_num_inbound_flow_cache_entries(0)
311 # resend the same packets
312 self.pg0.add_stream(packets)
313 self.pg1.enable_capture() # flush the old capture
316 # check capture on pg1
317 capture = self.pg1.get_capture()
318 for packet in capture:
320 self.logger.debug(ppp("SPD Add - Got packet:", packet))
322 self.logger.error(ppp("Unexpected or invalid packet:", packet))
325 # verify captured packets
326 self.verify_capture(self.pg0, self.pg1, capture)
327 # verify all policies matched the expected number of times
328 self.verify_policy_match(pkt_count, policy_0)
329 self.verify_policy_match(pkt_count, policy_1)
330 self.verify_policy_match(pkt_count*2, policy_2)
331 # by readding the bypass rule, we reset the flow cache
332 # we only expect the bypass rule to now be in the flow cache
333 self.verify_num_inbound_flow_cache_entries(1)
336 class IPSec4SpdTestCaseMultiple(SpdFlowCacheInbound):
337 """ IPSec/IPv4 inbound: Policy mode test case with flow cache \
338 (multiple interfaces, multiple rules)"""
339 def test_ipsec_spd_inbound_multiple(self):
340 # In this test case, packets in IPv4 FWD path are configured to go
341 # through IPSec outbound SPD policy lookup.
343 # Multiples rules on multiple interfaces are tested at the same time.
344 # 3x interfaces are configured, binding the same SPD to each.
345 # Each interface has 1 SPD rule- 2x BYPASS and 1x DISCARD
347 # Traffic should be forwarded with destinations pg1 & pg2
348 # and dropped to pg0.
349 self.create_interfaces(3)
351 # bind SPD to all interfaces
352 self.spd_create_and_intf_add(1, self.pg_interfaces)
353 # add input rules on all interfaces
355 policy_0 = self.spd_add_rem_policy( # inbound, priority 10
356 1, self.pg1, self.pg0, socket.IPPROTO_UDP,
357 is_out=0, priority=10, policy_type="bypass")
359 policy_1 = self.spd_add_rem_policy( # inbound, priority 10
360 1, self.pg2, self.pg1, socket.IPPROTO_UDP,
361 is_out=0, priority=10, policy_type="bypass")
363 policy_2 = self.spd_add_rem_policy( # inbound, priority 10
364 1, self.pg0, self.pg2, socket.IPPROTO_UDP,
365 is_out=0, priority=10, policy_type="discard")
367 # create output rules covering the the full ip range
368 # 0.0.0.0 -> 255.255.255.255, so we can capture forwarded packets
369 policy_3 = self.spd_add_rem_policy( # outbound, priority 10
370 1, self.pg0, self.pg0, socket.IPPROTO_UDP,
371 is_out=1, priority=10, policy_type="bypass",
374 # check flow cache is empty (0 active elements) before sending traffic
375 self.verify_num_inbound_flow_cache_entries(0)
377 # create the packet streams
378 packets0 = self.create_stream(self.pg0, self.pg1, pkt_count)
379 packets1 = self.create_stream(self.pg1, self.pg2, pkt_count)
380 packets2 = self.create_stream(self.pg2, self.pg0, pkt_count)
381 # add the streams to the source interfaces
382 self.pg0.add_stream(packets0)
383 self.pg1.add_stream(packets1)
384 self.pg2.add_stream(packets2)
385 # enable capture on all interfaces
386 for pg in self.pg_interfaces:
388 # start the packet generator
391 # get captures from ifs
393 for pg in [self.pg1, self.pg2]: # we are expecting captures on pg1/pg2
394 if_caps.append(pg.get_capture())
395 for packet in if_caps[-1]:
397 self.logger.debug(ppp("SPD Add - Got packet:", packet))
400 ppp("Unexpected or invalid packet:", packet))
403 # verify captures that matched BYPASS rules
404 self.verify_capture(self.pg0, self.pg1, if_caps[0])
405 self.verify_capture(self.pg1, self.pg2, if_caps[1])
406 # verify that traffic to pg0 matched DISCARD rule and was dropped
407 self.pg0.assert_nothing_captured()
408 # verify all policies matched the expected number of times
409 self.verify_policy_match(pkt_count, policy_0)
410 self.verify_policy_match(pkt_count, policy_1)
411 self.verify_policy_match(pkt_count, policy_2)
412 # check flow/policy match was cached for: 3x input policies
413 self.verify_num_inbound_flow_cache_entries(3)
416 class IPSec4SpdTestCaseOverwriteStale(SpdFlowCacheInbound):
417 """ IPSec/IPv4 inbound: Policy mode test case with flow cache \
418 (overwrite stale entries)"""
419 def test_ipsec_spd_inbound_overwrite(self):
420 # The operation of the flow cache is setup so that the entire cache
421 # is invalidated when adding or removing an SPD policy rule.
422 # For performance, old cache entries are not zero'd, but remain
423 # in the table as "stale" entries. If a flow matches a stale entry,
424 # and the epoch count does NOT match the current count, the entry
426 # In this test, 3 active rules are created and matched to enter
427 # them into the flow cache.
428 # A single entry is removed to invalidate the entire cache.
429 # We then readd the rule and test that overwriting of the previous
430 # stale entries occurs as expected, and that the flow cache entry
431 # counter is updated correctly.
432 self.create_interfaces(3)
434 # bind SPD to all interfaces
435 self.spd_create_and_intf_add(1, self.pg_interfaces)
436 # add input rules on all interfaces
438 policy_0 = self.spd_add_rem_policy( # inbound
439 1, self.pg1, self.pg0, socket.IPPROTO_UDP,
440 is_out=0, priority=10, policy_type="bypass")
442 policy_1 = self.spd_add_rem_policy( # inbound
443 1, self.pg2, self.pg1, socket.IPPROTO_UDP,
444 is_out=0, priority=10, policy_type="bypass")
446 policy_2 = self.spd_add_rem_policy( # inbound
447 1, self.pg0, self.pg2, socket.IPPROTO_UDP,
448 is_out=0, priority=10, policy_type="discard")
450 # create output rules covering the the full ip range
451 # 0.0.0.0 -> 255.255.255.255, so we can capture forwarded packets
452 policy_3 = self.spd_add_rem_policy( # outbound
453 1, self.pg0, self.pg0, socket.IPPROTO_UDP,
454 is_out=1, priority=10, policy_type="bypass",
457 # check flow cache is empty (0 active elements) before sending traffic
458 self.verify_num_inbound_flow_cache_entries(0)
460 # create the packet streams
461 packets0 = self.create_stream(self.pg0, self.pg1, pkt_count)
462 packets1 = self.create_stream(self.pg1, self.pg2, pkt_count)
463 packets2 = self.create_stream(self.pg2, self.pg0, pkt_count)
464 # add the streams to the source interfaces
465 self.pg0.add_stream(packets0)
466 self.pg1.add_stream(packets1)
467 self.pg2.add_stream(packets2)
468 # enable capture on all interfaces
469 for pg in self.pg_interfaces:
471 # start the packet generator
474 # get captures from ifs
476 for pg in [self.pg1, self.pg2]: # we are expecting captures on pg1/pg2
477 if_caps.append(pg.get_capture())
478 for packet in if_caps[-1]:
480 self.logger.debug(ppp("SPD Add - Got packet:", packet))
483 ppp("Unexpected or invalid packet:", packet))
486 # verify captures that matched BYPASS rules
487 self.verify_capture(self.pg0, self.pg1, if_caps[0])
488 self.verify_capture(self.pg1, self.pg2, if_caps[1])
489 # verify that traffic to pg0 matched DISCARD rule and was dropped
490 self.pg0.assert_nothing_captured()
491 # verify all policies matched the expected number of times
492 self.verify_policy_match(pkt_count, policy_0)
493 self.verify_policy_match(pkt_count, policy_1)
494 self.verify_policy_match(pkt_count, policy_2)
495 # check flow/policy match was cached for: 3x input policies
496 self.verify_num_inbound_flow_cache_entries(3)
498 # adding an outbound policy should not invalidate output flow cache
499 self.spd_add_rem_policy( # outbound
500 1, self.pg0, self.pg0, socket.IPPROTO_UDP,
501 is_out=1, priority=1, policy_type="bypass",
503 # check inbound flow cache counter has not been reset
504 self.verify_num_inbound_flow_cache_entries(3)
506 # remove + readd bypass policy - flow cache counter will be reset,
507 # and there will be 3x stale entries in flow cache
508 self.spd_add_rem_policy( # inbound, priority 10
509 1, self.pg1, self.pg0, socket.IPPROTO_UDP,
510 is_out=0, priority=10, policy_type="bypass",
513 policy_0 = self.spd_add_rem_policy( # inbound, priority 10
514 1, self.pg1, self.pg0, socket.IPPROTO_UDP,
515 is_out=0, priority=10, policy_type="bypass")
516 # check counter was reset
517 self.verify_num_inbound_flow_cache_entries(0)
519 # resend the same packets
520 self.pg0.add_stream(packets0)
521 self.pg1.add_stream(packets1)
522 self.pg2.add_stream(packets2)
523 for pg in self.pg_interfaces:
524 pg.enable_capture() # flush previous captures
527 # get captures from ifs
529 for pg in [self.pg1, self.pg2]: # we are expecting captures on pg1/pg2
530 if_caps.append(pg.get_capture())
531 for packet in if_caps[-1]:
533 self.logger.debug(ppp("SPD Add - Got packet:", packet))
536 ppp("Unexpected or invalid packet:", packet))
539 # verify captures that matched BYPASS rules
540 self.verify_capture(self.pg0, self.pg1, if_caps[0])
541 self.verify_capture(self.pg1, self.pg2, if_caps[1])
542 # verify that traffic to pg0 matched DISCARD rule and was dropped
543 self.pg0.assert_nothing_captured()
544 # verify all policies matched the expected number of times
545 self.verify_policy_match(pkt_count, policy_0)
546 self.verify_policy_match(pkt_count*2, policy_1)
547 self.verify_policy_match(pkt_count*2, policy_2)
548 # we are overwriting 3x stale entries - check flow cache counter
550 self.verify_num_inbound_flow_cache_entries(3)
553 class IPSec4SpdTestCaseCollision(SpdFlowCacheInbound):
554 """ IPSec/IPv4 inbound: Policy mode test case with flow cache \
556 # Override class setup to restrict hash table size to 16 buckets.
557 # This forces using only the lower 4 bits of the hash as a key,
558 # making hash collisions easy to find.
560 def setUpConstants(cls):
561 super(SpdFlowCacheInbound, cls).setUpConstants()
562 cls.vpp_cmdline.extend(["ipsec", "{",
563 "ipv4-inbound-spd-flow-cache on",
564 "ipv4-inbound-spd-hash-buckets 16",
566 cls.logger.info("VPP modified cmdline is %s" % " "
567 .join(cls.vpp_cmdline))
569 def test_ipsec_spd_inbound_collision(self):
570 # The flow cache operation is setup to overwrite an entry
571 # if a hash collision occurs.
572 # In this test, 2 packets are configured that result in a
573 # hash with the same lower 4 bits.
574 # After the first packet is received, there should be one
575 # active entry in the flow cache.
576 # After the second packet with the same lower 4 bit hash
577 # is received, this should overwrite the same entry.
578 # Therefore there will still be a total of one (1) entry,
579 # in the flow cache with two matching policies.
580 # crc32_supported() method is used to check cpu for crc32
581 # intrinsic support for hashing.
582 # If crc32 is not supported, we fall back to clib_xxhash()
583 self.create_interfaces(4)
585 # bind SPD to all interfaces
586 self.spd_create_and_intf_add(1, self.pg_interfaces)
588 # create output rules covering the the full ip range
589 # 0.0.0.0 -> 255.255.255.255, so we can capture forwarded packets
590 policy_0 = self.spd_add_rem_policy( # outbound
591 1, self.pg0, self.pg0, socket.IPPROTO_UDP,
592 is_out=1, priority=10, policy_type="bypass",
596 if self.crc32_supported(): # create crc32 collision on last 4 bits
597 hashed_with_crc32 = True
599 policy_1 = self.spd_add_rem_policy( # inbound, priority 10
600 1, self.pg1, self.pg2, socket.IPPROTO_UDP,
601 is_out=0, priority=10, policy_type="bypass")
602 policy_2 = self.spd_add_rem_policy( # inbound, priority 10
603 1, self.pg3, self.pg0, socket.IPPROTO_UDP,
604 is_out=0, priority=10, policy_type="bypass")
606 # we expect to get captures on pg1 + pg3
607 capture_intfs.append(self.pg1)
608 capture_intfs.append(self.pg3)
610 # check flow cache is empty before sending traffic
611 self.verify_num_inbound_flow_cache_entries(0)
613 # create the packet streams
616 packets1 = self.create_stream(self.pg2, self.pg1, pkt_count, 1, 1)
618 packets2 = self.create_stream(self.pg0, self.pg3, pkt_count, 1, 1)
619 # add the streams to the source interfaces
620 self.pg2.add_stream(packets1)
621 self.pg0.add_stream(packets2)
622 else: # create xxhash collision on last 4 bits
623 hashed_with_crc32 = False
625 policy_1 = self.spd_add_rem_policy( # inbound, priority 10
626 1, self.pg1, self.pg2, socket.IPPROTO_UDP,
627 is_out=0, priority=10, policy_type="bypass")
628 policy_2 = self.spd_add_rem_policy( # inbound, priority 10
629 1, self.pg2, self.pg3, socket.IPPROTO_UDP,
630 is_out=0, priority=10, policy_type="bypass")
632 capture_intfs.append(self.pg1)
633 capture_intfs.append(self.pg2)
635 # check flow cache is empty before sending traffic
636 self.verify_num_inbound_flow_cache_entries(0)
638 # create the packet streams
640 packets1 = self.create_stream(self.pg2, self.pg1, pkt_count, 1, 1)
642 packets2 = self.create_stream(self.pg3, self.pg2, pkt_count, 1, 1)
643 # add the streams to the source interfaces
644 self.pg2.add_stream(packets1)
645 self.pg3.add_stream(packets2)
647 # enable capture on interfaces we expect capture on & send pkts
648 for pg in capture_intfs:
654 for pg in capture_intfs:
655 if_caps.append(pg.get_capture())
656 for packet in if_caps[-1]:
658 self.logger.debug(ppp(
659 "SPD Add - Got packet:", packet))
661 self.logger.error(ppp(
662 "Unexpected or invalid packet:", packet))
665 # verify captures that matched BYPASS rule
666 if(hashed_with_crc32):
667 self.verify_capture(self.pg2, self.pg1, if_caps[0])
668 self.verify_capture(self.pg0, self.pg3, if_caps[1])
669 else: # hashed with xxhash
670 self.verify_capture(self.pg2, self.pg1, if_caps[0])
671 self.verify_capture(self.pg3, self.pg2, if_caps[1])
673 # verify all policies matched the expected number of times
674 self.verify_policy_match(pkt_count, policy_1)
675 self.verify_policy_match(pkt_count, policy_2)
676 self.verify_policy_match(pkt_count*2, policy_0) # output policy
677 # we have matched 2 policies, but due to the hash collision
678 # one active entry is expected
679 self.verify_num_inbound_flow_cache_entries(1)
682 if __name__ == '__main__':
683 unittest.main(testRunner=VppTestRunner)