blob: f9de210e6dc991e42860d3f75973e293dfce35e9 [file] [log] [blame]
Zachary Leaf26fec712021-10-26 10:05:58 -05001import socket
2import unittest
3
4from util import ppp
5from framework import VppTestRunner
6from template_ipsec import IPSecIPv4Fwd
7
8"""
9When an IPSec SPD is configured on an interface, any inbound packets
10not matching inbound policies, or outbound packets not matching outbound
11policies, must be dropped by default as per RFC4301.
12
13This test uses simple IPv4 forwarding on interfaces with IPSec enabled
14to check if packets with no matching rules are dropped by default.
15
16The basic setup is a single SPD bound to two interfaces, pg0 and pg1.
17
18 ┌────┐ ┌────┐
19 │SPD1│ │SPD1│
20 ├────┤ ─────> ├────┤
21 │PG0 │ │PG1 │
22 └────┘ └────┘
23
24First, both inbound and outbound BYPASS policies are configured allowing
25traffic to pass from pg0 -> pg1.
26
27Packets are captured and verified at pg1.
28
29Then either the inbound or outbound policies are removed and we verify
30packets are dropped as expected.
31
32"""
33
34
35class IPSecInboundDefaultDrop(IPSecIPv4Fwd):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020036 """IPSec: inbound packets drop by default with no matching rule"""
Klement Sekera16ce09d2022-04-23 11:34:29 +020037
Zachary Leaf26fec712021-10-26 10:05:58 -050038 def test_ipsec_inbound_default_drop(self):
39 # configure two interfaces and bind the same SPD to both
40 self.create_interfaces(2)
41 self.spd_create_and_intf_add(1, self.pg_interfaces)
42 pkt_count = 5
43
44 # catch-all inbound BYPASS policy, all interfaces
45 inbound_policy = self.spd_add_rem_policy(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020046 1,
47 None,
48 None,
49 socket.IPPROTO_UDP,
50 is_out=0,
51 priority=10,
52 policy_type="bypass",
53 all_ips=True,
54 )
Zachary Leaf26fec712021-10-26 10:05:58 -050055
56 # outbound BYPASS policy allowing traffic from pg0->pg1
57 outbound_policy = self.spd_add_rem_policy(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020058 1,
59 self.pg0,
60 self.pg1,
61 socket.IPPROTO_UDP,
62 is_out=1,
63 priority=10,
64 policy_type="bypass",
65 )
Zachary Leaf26fec712021-10-26 10:05:58 -050066
67 # create a packet stream pg0->pg1 + add to pg0
68 packets0 = self.create_stream(self.pg0, self.pg1, pkt_count)
69 self.pg0.add_stream(packets0)
70
71 # with inbound BYPASS rule at pg0, we expect to see forwarded
72 # packets on pg1
73 self.pg_interfaces[1].enable_capture()
74 self.pg_start()
75 cap1 = self.pg1.get_capture()
76 for packet in cap1:
77 try:
78 self.logger.debug(ppp("SPD - Got packet:", packet))
79 except Exception:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020080 self.logger.error(ppp("Unexpected or invalid packet:", packet))
Zachary Leaf26fec712021-10-26 10:05:58 -050081 raise
82 self.logger.debug("SPD: Num packets: %s", len(cap1.res))
83 # verify captures on pg1
84 self.verify_capture(self.pg0, self.pg1, cap1)
85 # verify policies matched correct number of times
86 self.verify_policy_match(pkt_count, inbound_policy)
87 self.verify_policy_match(pkt_count, outbound_policy)
88
89 # remove inbound catch-all BYPASS rule, traffic should now be dropped
90 self.spd_add_rem_policy( # inbound, all interfaces
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020091 1,
92 None,
93 None,
94 socket.IPPROTO_UDP,
95 is_out=0,
96 priority=10,
97 policy_type="bypass",
98 all_ips=True,
99 remove=True,
100 )
Zachary Leaf26fec712021-10-26 10:05:58 -0500101
102 # create another packet stream pg0->pg1 + add to pg0
103 packets1 = self.create_stream(self.pg0, self.pg1, pkt_count)
104 self.pg0.add_stream(packets1)
105 self.pg_interfaces[1].enable_capture()
106 self.pg_start()
107 # confirm traffic has now been dropped
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200108 self.pg1.assert_nothing_captured(
109 remark="inbound pkts with no matching" "rules NOT dropped by default"
110 )
Zachary Leaf26fec712021-10-26 10:05:58 -0500111 # both policies should not have matched any further packets
112 # since we've dropped at input stage
113 self.verify_policy_match(pkt_count, outbound_policy)
114 self.verify_policy_match(pkt_count, inbound_policy)
115
116
117class IPSecOutboundDefaultDrop(IPSecIPv4Fwd):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200118 """IPSec: outbound packets drop by default with no matching rule"""
Klement Sekera16ce09d2022-04-23 11:34:29 +0200119
Zachary Leaf26fec712021-10-26 10:05:58 -0500120 def test_ipsec_inbound_default_drop(self):
121 # configure two interfaces and bind the same SPD to both
122 self.create_interfaces(2)
123 self.spd_create_and_intf_add(1, self.pg_interfaces)
124 pkt_count = 5
125
126 # catch-all inbound BYPASS policy, all interfaces
127 inbound_policy = self.spd_add_rem_policy(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200128 1,
129 None,
130 None,
131 socket.IPPROTO_UDP,
132 is_out=0,
133 priority=10,
134 policy_type="bypass",
135 all_ips=True,
136 )
Zachary Leaf26fec712021-10-26 10:05:58 -0500137
138 # outbound BYPASS policy allowing traffic from pg0->pg1
139 outbound_policy = self.spd_add_rem_policy(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200140 1,
141 self.pg0,
142 self.pg1,
143 socket.IPPROTO_UDP,
144 is_out=1,
145 priority=10,
146 policy_type="bypass",
147 )
Zachary Leaf26fec712021-10-26 10:05:58 -0500148
149 # create a packet stream pg0->pg1 + add to pg0
150 packets0 = self.create_stream(self.pg0, self.pg1, pkt_count)
151 self.pg0.add_stream(packets0)
152
153 # with outbound BYPASS rule allowing pg0->pg1, we expect to see
154 # forwarded packets on pg1
155 self.pg_interfaces[1].enable_capture()
156 self.pg_start()
157 cap1 = self.pg1.get_capture()
158 for packet in cap1:
159 try:
160 self.logger.debug(ppp("SPD - Got packet:", packet))
161 except Exception:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200162 self.logger.error(ppp("Unexpected or invalid packet:", packet))
Zachary Leaf26fec712021-10-26 10:05:58 -0500163 raise
164 self.logger.debug("SPD: Num packets: %s", len(cap1.res))
165 # verify captures on pg1
166 self.verify_capture(self.pg0, self.pg1, cap1)
167 # verify policies matched correct number of times
168 self.verify_policy_match(pkt_count, inbound_policy)
169 self.verify_policy_match(pkt_count, outbound_policy)
170
171 # remove outbound rule
172 self.spd_add_rem_policy(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200173 1,
174 self.pg0,
175 self.pg1,
176 socket.IPPROTO_UDP,
177 is_out=1,
178 priority=10,
179 policy_type="bypass",
180 remove=True,
181 )
Zachary Leaf26fec712021-10-26 10:05:58 -0500182
183 # create another packet stream pg0->pg1 + add to pg0
184 packets1 = self.create_stream(self.pg0, self.pg1, pkt_count)
185 self.pg0.add_stream(packets1)
186 self.pg_interfaces[1].enable_capture()
187 self.pg_start()
188 # confirm traffic was dropped and not forwarded
Klement Sekera16ce09d2022-04-23 11:34:29 +0200189 self.pg1.assert_nothing_captured(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200190 remark="outbound pkts with no matching rules NOT dropped " "by default"
191 )
Zachary Leaf26fec712021-10-26 10:05:58 -0500192 # inbound rule should have matched twice the # of pkts now
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200193 self.verify_policy_match(pkt_count * 2, inbound_policy)
Zachary Leaf26fec712021-10-26 10:05:58 -0500194 # as dropped at outbound, outbound policy is the same
195 self.verify_policy_match(pkt_count, outbound_policy)
196
Klement Sekera16ce09d2022-04-23 11:34:29 +0200197
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200198if __name__ == "__main__":
Zachary Leaf26fec712021-10-26 10:05:58 -0500199 unittest.main(testRunner=VppTestRunner)