blob: 54571c6741ab42f246c299230dfb4bd389bb787f [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
Zachary Leaf26fec712021-10-26 10:05:58 -0500309 # interfaces bound to an SPD, will by default drop inbound
310 # traffic with no matching policies. add catch-all inbound
311 # bypass rule to SPD:
312 self.spd_add_rem_policy( # inbound, all interfaces
313 1, None, None, socket.IPPROTO_UDP, is_out=0, priority=10,
314 policy_type="bypass", all_ips=True)
315
Govindarajan Mohandoss6d7dfcb2021-03-19 19:20:49 +0000316 # check flow cache is empty (0 active elements) before sending traffic
317 self.verify_num_outbound_flow_cache_entries(0)
318
319 # create the packet streams
320 packets0 = self.create_stream(self.pg0, self.pg1, pkt_count)
321 packets1 = self.create_stream(self.pg1, self.pg2, pkt_count)
322 packets2 = self.create_stream(self.pg2, self.pg0, pkt_count)
323 # add the streams to the source interfaces
324 self.pg0.add_stream(packets0)
325 self.pg1.add_stream(packets1)
326 self.pg2.add_stream(packets2)
327 # enable capture on all interfaces
328 for pg in self.pg_interfaces:
329 pg.enable_capture()
330 # start the packet generator
331 self.pg_start()
332
333 # get captures
334 if_caps = []
335 for pg in [self.pg1, self.pg2]: # we are expecting captures on pg1/pg2
336 if_caps.append(pg.get_capture())
337 for packet in if_caps[-1]:
338 try:
339 self.logger.debug(ppp("SPD - Got packet:", packet))
340 except Exception:
341 self.logger.error(
342 ppp("Unexpected or invalid packet:", packet))
343 raise
344 self.logger.debug("SPD: Num packets: %s", len(if_caps[0].res))
345 self.logger.debug("SPD: Num packets: %s", len(if_caps[1].res))
346
347 # verify captures that matched BYPASS rule
348 self.verify_capture(self.pg0, self.pg1, if_caps[0])
349 self.verify_capture(self.pg1, self.pg2, if_caps[1])
350 # verify that traffic to pg0 matched DISCARD rule and was dropped
351 self.pg0.assert_nothing_captured()
352 # verify all packets that were expected to match rules, matched
353 # pg0 -> pg1
354 self.verify_policy_match(pkt_count, policy_01)
355 self.verify_policy_match(0, policy_02)
356 # pg1 -> pg2
357 self.verify_policy_match(pkt_count, policy_11)
358 self.verify_policy_match(0, policy_12)
359 # pg2 -> pg0
360 self.verify_policy_match(0, policy_21)
361 self.verify_policy_match(pkt_count, policy_22)
362 # check that 3 matching policies in SPD have been cached
363 self.verify_num_outbound_flow_cache_entries(3)
364
365
366class IPSec4SpdTestCaseOverwriteStale(SpdFlowCacheOutbound):
367 """ IPSec/IPv4 outbound: Policy mode test case with flow cache \
368 (overwrite stale entries)"""
369 def test_ipsec_spd_outbound_overwrite(self):
370 # The operation of the flow cache is setup so that the entire cache
371 # is invalidated when adding or removing an SPD policy rule.
372 # For performance, old cache entries are not zero'd, but remain
373 # in the table as "stale" entries. If a flow matches a stale entry,
374 # and the epoch count does NOT match the current count, the entry
375 # is overwritten.
376 # In this test, 3 active rules are created and matched to enter
377 # them into the flow cache.
378 # A single entry is removed to invalidate the entire cache.
379 # We then readd the rule and test that overwriting of the previous
380 # stale entries occurs as expected, and that the flow cache entry
381 # counter is updated correctly.
382 self.create_interfaces(3)
383 pkt_count = 2
384 # bind SPD to all interfaces
385 self.spd_create_and_intf_add(1, self.pg_interfaces)
386 # add output rules on all interfaces
387 # pg0 -> pg1
388 policy_0 = self.spd_add_rem_policy( # outbound
389 1, self.pg0, self.pg1, socket.IPPROTO_UDP,
390 is_out=1, priority=10, policy_type="bypass")
391 # pg1 -> pg2
392 policy_1 = self.spd_add_rem_policy( # outbound
393 1, self.pg1, self.pg2, socket.IPPROTO_UDP,
394 is_out=1, priority=10, policy_type="bypass")
395 # pg2 -> pg0
396 policy_2 = self.spd_add_rem_policy( # outbound
397 1, self.pg2, self.pg0, socket.IPPROTO_UDP,
398 is_out=1, priority=10, policy_type="discard")
399
Zachary Leaf26fec712021-10-26 10:05:58 -0500400 # interfaces bound to an SPD, will by default drop inbound
401 # traffic with no matching policies. add catch-all inbound
402 # bypass rule to SPD:
403 self.spd_add_rem_policy( # inbound, all interfaces
404 1, None, None, socket.IPPROTO_UDP, is_out=0, priority=10,
405 policy_type="bypass", all_ips=True)
406
Govindarajan Mohandoss6d7dfcb2021-03-19 19:20:49 +0000407 # check flow cache is empty (0 active elements) before sending traffic
408 self.verify_num_outbound_flow_cache_entries(0)
409
410 # create the packet streams
411 packets0 = self.create_stream(self.pg0, self.pg1, pkt_count)
412 packets1 = self.create_stream(self.pg1, self.pg2, pkt_count)
413 packets2 = self.create_stream(self.pg2, self.pg0, pkt_count)
414 # add the streams to the source interfaces
415 self.pg0.add_stream(packets0)
416 self.pg1.add_stream(packets1)
417 self.pg2.add_stream(packets2)
418 # enable capture on all interfaces
419 for pg in self.pg_interfaces:
420 pg.enable_capture()
421 # start the packet generator
422 self.pg_start()
423
424 # get captures from ifs
425 if_caps = []
426 for pg in [self.pg1, self.pg2]: # we are expecting captures on pg1/pg2
427 if_caps.append(pg.get_capture())
428 for packet in if_caps[-1]:
429 try:
430 self.logger.debug(ppp("SPD Add - Got packet:", packet))
431 except Exception:
432 self.logger.error(
433 ppp("Unexpected or invalid packet:", packet))
434 raise
435
436 # verify captures that matched BYPASS rules
437 self.verify_capture(self.pg0, self.pg1, if_caps[0])
438 self.verify_capture(self.pg1, self.pg2, if_caps[1])
439 # verify that traffic to pg0 matched DISCARD rule and was dropped
440 self.pg0.assert_nothing_captured()
441 # verify all policies matched the expected number of times
442 self.verify_policy_match(pkt_count, policy_0)
443 self.verify_policy_match(pkt_count, policy_1)
444 self.verify_policy_match(pkt_count, policy_2)
445 # check flow/policy match was cached for: 3x output policies
446 self.verify_num_outbound_flow_cache_entries(3)
447
448 # adding an inbound policy should not invalidate output flow cache
449 self.spd_add_rem_policy( # inbound
450 1, self.pg0, self.pg1, socket.IPPROTO_UDP,
451 is_out=0, priority=10, policy_type="bypass")
452 # check flow cache counter has not been reset
453 self.verify_num_outbound_flow_cache_entries(3)
454
455 # remove a bypass policy - flow cache counter will be reset, and
456 # there will be 3x stale entries in flow cache
457 self.spd_add_rem_policy( # outbound
458 1, self.pg0, self.pg1, socket.IPPROTO_UDP,
459 is_out=1, priority=10, policy_type="bypass",
460 remove=True)
461 # readd policy
462 policy_0 = self.spd_add_rem_policy( # outbound
463 1, self.pg0, self.pg1, socket.IPPROTO_UDP,
464 is_out=1, priority=10, policy_type="bypass")
465 # check counter was reset with flow cache invalidation
466 self.verify_num_outbound_flow_cache_entries(0)
467
468 # resend the same packets
469 self.pg0.add_stream(packets0)
470 self.pg1.add_stream(packets1)
471 self.pg2.add_stream(packets2)
472 for pg in self.pg_interfaces:
473 pg.enable_capture() # flush previous captures
474 self.pg_start()
475
476 # get captures from ifs
477 if_caps = []
478 for pg in [self.pg1, self.pg2]: # we are expecting captures on pg1/pg2
479 if_caps.append(pg.get_capture())
480 for packet in if_caps[-1]:
481 try:
482 self.logger.debug(ppp("SPD Add - Got packet:", packet))
483 except Exception:
484 self.logger.error(
485 ppp("Unexpected or invalid packet:", packet))
486 raise
487
488 # verify captures that matched BYPASS rules
489 self.verify_capture(self.pg0, self.pg1, if_caps[0])
490 self.verify_capture(self.pg1, self.pg2, if_caps[1])
491 # verify that traffic to pg0 matched DISCARD rule and was dropped
492 self.pg0.assert_nothing_captured()
493 # verify all policies matched the expected number of times
494 self.verify_policy_match(pkt_count, policy_0)
495 self.verify_policy_match(pkt_count*2, policy_1)
496 self.verify_policy_match(pkt_count*2, policy_2)
497 # we are overwriting 3x stale entries - check flow cache counter
498 # is correct
499 self.verify_num_outbound_flow_cache_entries(3)
500
501
502class IPSec4SpdTestCaseCollision(SpdFlowCacheOutbound):
503 """ IPSec/IPv4 outbound: Policy mode test case with flow cache \
504 (hash collision)"""
505 # Override class setup to restrict vector size to 16 elements.
506 # This forces using only the lower 4 bits of the hash as a key,
507 # making hash collisions easy to find.
508 @classmethod
509 def setUpConstants(cls):
510 super(SpdFlowCacheOutbound, cls).setUpConstants()
511 cls.vpp_cmdline.extend(["ipsec", "{",
512 "ipv4-outbound-spd-flow-cache on",
513 "ipv4-outbound-spd-hash-buckets 16",
514 "}"])
515 cls.logger.info("VPP modified cmdline is %s" % " "
516 .join(cls.vpp_cmdline))
517
518 def test_ipsec_spd_outbound_collision(self):
519 # The flow cache operation is setup to overwrite an entry
520 # if a hash collision occurs.
521 # In this test, 2 packets are configured that result in a
522 # hash with the same lower 4 bits.
523 # After the first packet is received, there should be one
524 # active entry in the flow cache.
525 # After the second packet with the same lower 4 bit hash
526 # is received, this should overwrite the same entry.
527 # Therefore there will still be a total of one (1) entry,
528 # in the flow cache with two matching policies.
529 # crc32_supported() method is used to check cpu for crc32
530 # intrinsic support for hashing.
531 # If crc32 is not supported, we fall back to clib_xxhash()
532 self.create_interfaces(3)
533 pkt_count = 5
534 # bind SPD to all interfaces
535 self.spd_create_and_intf_add(1, self.pg_interfaces)
536 # add rules
537 policy_0 = self.spd_add_rem_policy( # outbound, priority 10
538 1, self.pg1, self.pg2, socket.IPPROTO_UDP,
539 is_out=1, priority=10, policy_type="bypass")
540 policy_1 = self.spd_add_rem_policy( # outbound, priority 10
541 1, self.pg2, self.pg0, socket.IPPROTO_UDP,
542 is_out=1, priority=10, policy_type="bypass")
543
Zachary Leaf26fec712021-10-26 10:05:58 -0500544 # interfaces bound to an SPD, will by default drop inbound
545 # traffic with no matching policies. add catch-all inbound
546 # bypass rule to SPD:
547 self.spd_add_rem_policy( # inbound, all interfaces
548 1, None, None, socket.IPPROTO_UDP, is_out=0, priority=10,
549 policy_type="bypass", all_ips=True)
550
Govindarajan Mohandoss6d7dfcb2021-03-19 19:20:49 +0000551 # check flow cache is empty (0 active elements) before sending traffic
552 self.verify_num_outbound_flow_cache_entries(0)
553
554 # create the packet streams generating collision on last 4 bits
555 if self.crc32_supported():
556 # packet hashes to:
557 # 432c99c2
558 packets1 = self.create_stream(self.pg1, self.pg2, pkt_count, 1, 1)
559 # 31f8f3f2
560 packets2 = self.create_stream(self.pg2, self.pg0, pkt_count, 6, 6)
561 else: # clib_xxhash
562 # ec3a258551bc0306
563 packets1 = self.create_stream(self.pg1, self.pg2, pkt_count, 2, 2)
564 # 61fee526d18d7a6
565 packets2 = self.create_stream(self.pg2, self.pg0, pkt_count, 3, 3)
566
567 # add the streams to the source interfaces
568 self.pg1.add_stream(packets1)
569 self.pg2.add_stream(packets2)
570 # enable capture on all interfaces
571 for pg in self.pg_interfaces:
572 pg.enable_capture()
573 # start the packet generator
574 self.pg_start()
575
576 # get captures from ifs - the proper pkt_count of packets was saved by
577 # create_packet_info() based on dst_if parameter
578 if_caps = []
579 for pg in [self.pg2, self.pg0]: # we are expecting captures on pg2/pg0
580 if_caps.append(pg.get_capture())
581 for packet in if_caps[-1]:
582 try:
583 self.logger.debug(ppp(
584 "SPD - Got packet:", packet))
585 except Exception:
586 self.logger.error(ppp(
587 "Unexpected or invalid packet:", packet))
588 raise
589 self.logger.debug("SPD: Num packets: %s", len(if_caps[0].res))
590 self.logger.debug("SPD: Num packets: %s", len(if_caps[1].res))
591
592 # verify captures that matched BYPASS rule
593 self.verify_capture(self.pg1, self.pg2, if_caps[0])
594 self.verify_capture(self.pg2, self.pg0, if_caps[1])
595 # verify all packets that were expected to match rules, matched
596 self.verify_policy_match(pkt_count, policy_0)
597 self.verify_policy_match(pkt_count, policy_1)
598 # we have matched 2 policies, but due to the hash collision
599 # one active entry is expected
600 self.verify_num_outbound_flow_cache_entries(1)
601
602
603if __name__ == '__main__':
604 unittest.main(testRunner=VppTestRunner)