blob: a59a213506b98bd24dd9fdc50323a106358e2aec [file] [log] [blame]
Klement Sekera31da2e32018-06-24 22:49:55 +02001import unittest
Klement Sekera611864f2018-09-26 11:19:00 +02002import socket
Neale Ranns80f6fd52019-04-16 02:41:34 +00003import struct
Klement Sekera31da2e32018-06-24 22:49:55 +02004
Neale Ranns53f526b2019-02-25 14:32:02 +00005from scapy.layers.inet import IP, ICMP, TCP, UDP
Damjan Mariona829b132019-04-24 23:39:16 +02006from scapy.layers.ipsec import SecurityAssociation, ESP
Klement Sekera31da2e32018-06-24 22:49:55 +02007from scapy.layers.l2 import Ether, Raw
Klement Sekera611864f2018-09-26 11:19:00 +02008from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest
Klement Sekera31da2e32018-06-24 22:49:55 +02009
10from framework import VppTestCase, VppTestRunner
Neale Ranns14046982019-07-29 14:49:52 +000011from util import ppp, reassemble4, fragment_rfc791, fragment_rfc8200
Neale Ranns17dcec02019-01-09 21:22:20 -080012from vpp_papi import VppEnum
Klement Sekera31da2e32018-06-24 22:49:55 +020013
14
Klement Sekera611864f2018-09-26 11:19:00 +020015class IPsecIPv4Params(object):
Neale Ranns17dcec02019-01-09 21:22:20 -080016
Klement Sekera611864f2018-09-26 11:19:00 +020017 addr_type = socket.AF_INET
18 addr_any = "0.0.0.0"
19 addr_bcast = "255.255.255.255"
20 addr_len = 32
21 is_ipv6 = 0
Klement Sekera611864f2018-09-26 11:19:00 +020022
Neale Ranns17dcec02019-01-09 21:22:20 -080023 def __init__(self):
24 self.remote_tun_if_host = '1.1.1.1'
Neale Ranns987aea82019-03-27 13:40:35 +000025 self.remote_tun_if_host6 = '1111::1'
Klement Sekera611864f2018-09-26 11:19:00 +020026
Neale Ranns17dcec02019-01-09 21:22:20 -080027 self.scapy_tun_sa_id = 10
28 self.scapy_tun_spi = 1001
29 self.vpp_tun_sa_id = 20
30 self.vpp_tun_spi = 1000
Klement Sekera611864f2018-09-26 11:19:00 +020031
Neale Ranns17dcec02019-01-09 21:22:20 -080032 self.scapy_tra_sa_id = 30
33 self.scapy_tra_spi = 2001
34 self.vpp_tra_sa_id = 40
35 self.vpp_tra_spi = 2000
Klement Sekera611864f2018-09-26 11:19:00 +020036
Neale Ranns17dcec02019-01-09 21:22:20 -080037 self.auth_algo_vpp_id = (VppEnum.vl_api_ipsec_integ_alg_t.
38 IPSEC_API_INTEG_ALG_SHA1_96)
39 self.auth_algo = 'HMAC-SHA1-96' # scapy name
Ole Troan64e978b2019-10-17 21:40:36 +020040 self.auth_key = b'C91KUR9GYMm5GfkEvNjX'
Neale Ranns17dcec02019-01-09 21:22:20 -080041
42 self.crypt_algo_vpp_id = (VppEnum.vl_api_ipsec_crypto_alg_t.
43 IPSEC_API_CRYPTO_ALG_AES_CBC_128)
44 self.crypt_algo = 'AES-CBC' # scapy name
Ole Troan64e978b2019-10-17 21:40:36 +020045 self.crypt_key = b'JPjyOWBeVEQiMe7h'
Neale Ranns80f6fd52019-04-16 02:41:34 +000046 self.salt = 0
Neale Ranns53f526b2019-02-25 14:32:02 +000047 self.flags = 0
48 self.nat_header = None
Klement Sekera611864f2018-09-26 11:19:00 +020049
50
51class IPsecIPv6Params(object):
Neale Ranns17dcec02019-01-09 21:22:20 -080052
Klement Sekera611864f2018-09-26 11:19:00 +020053 addr_type = socket.AF_INET6
54 addr_any = "0::0"
55 addr_bcast = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"
56 addr_len = 128
57 is_ipv6 = 1
Klement Sekera611864f2018-09-26 11:19:00 +020058
Neale Ranns17dcec02019-01-09 21:22:20 -080059 def __init__(self):
60 self.remote_tun_if_host = '1111:1111:1111:1111:1111:1111:1111:1111'
Neale Ranns987aea82019-03-27 13:40:35 +000061 self.remote_tun_if_host4 = '1.1.1.1'
Klement Sekera611864f2018-09-26 11:19:00 +020062
Neale Ranns17dcec02019-01-09 21:22:20 -080063 self.scapy_tun_sa_id = 50
64 self.scapy_tun_spi = 3001
65 self.vpp_tun_sa_id = 60
66 self.vpp_tun_spi = 3000
Klement Sekera611864f2018-09-26 11:19:00 +020067
Neale Ranns17dcec02019-01-09 21:22:20 -080068 self.scapy_tra_sa_id = 70
69 self.scapy_tra_spi = 4001
70 self.vpp_tra_sa_id = 80
71 self.vpp_tra_spi = 4000
Klement Sekera611864f2018-09-26 11:19:00 +020072
Neale Ranns17dcec02019-01-09 21:22:20 -080073 self.auth_algo_vpp_id = (VppEnum.vl_api_ipsec_integ_alg_t.
Neale Ranns1091c4a2019-04-08 14:48:23 +000074 IPSEC_API_INTEG_ALG_SHA1_96)
75 self.auth_algo = 'HMAC-SHA1-96' # scapy name
Ole Troan64e978b2019-10-17 21:40:36 +020076 self.auth_key = b'C91KUR9GYMm5GfkEvNjX'
Neale Ranns17dcec02019-01-09 21:22:20 -080077
78 self.crypt_algo_vpp_id = (VppEnum.vl_api_ipsec_crypto_alg_t.
Neale Ranns4f33c802019-04-10 12:39:10 +000079 IPSEC_API_CRYPTO_ALG_AES_CBC_128)
Neale Ranns17dcec02019-01-09 21:22:20 -080080 self.crypt_algo = 'AES-CBC' # scapy name
Ole Troan64e978b2019-10-17 21:40:36 +020081 self.crypt_key = b'JPjyOWBeVEQiMe7h'
Neale Ranns80f6fd52019-04-16 02:41:34 +000082 self.salt = 0
Neale Ranns53f526b2019-02-25 14:32:02 +000083 self.flags = 0
84 self.nat_header = None
Klement Sekera611864f2018-09-26 11:19:00 +020085
86
Neale Ranns12989b52019-09-26 16:20:19 +000087def mk_scapy_crypt_key(p):
Neale Ranns6afaae12019-07-17 15:07:14 +000088 if p.crypt_algo == "AES-GCM":
89 return p.crypt_key + struct.pack("!I", p.salt)
90 else:
91 return p.crypt_key
92
93
Neale Ranns2ac885c2019-03-20 18:24:43 +000094def config_tun_params(p, encryption_type, tun_if):
95 ip_class_by_addr_type = {socket.AF_INET: IP, socket.AF_INET6: IPv6}
Neale Ranns3833ffd2019-03-21 14:34:09 +000096 use_esn = bool(p.flags & (VppEnum.vl_api_ipsec_sad_flags_t.
Damjan Marion1e3aa5e2019-03-28 10:58:59 +010097 IPSEC_API_SAD_FLAG_USE_ESN))
Neale Ranns12989b52019-09-26 16:20:19 +000098 crypt_key = mk_scapy_crypt_key(p)
Neale Ranns2ac885c2019-03-20 18:24:43 +000099 p.scapy_tun_sa = SecurityAssociation(
100 encryption_type, spi=p.vpp_tun_spi,
Neale Ranns80f6fd52019-04-16 02:41:34 +0000101 crypt_algo=p.crypt_algo,
102 crypt_key=crypt_key,
Neale Ranns2ac885c2019-03-20 18:24:43 +0000103 auth_algo=p.auth_algo, auth_key=p.auth_key,
104 tunnel_header=ip_class_by_addr_type[p.addr_type](
105 src=tun_if.remote_addr[p.addr_type],
106 dst=tun_if.local_addr[p.addr_type]),
Neale Ranns3833ffd2019-03-21 14:34:09 +0000107 nat_t_header=p.nat_header,
108 use_esn=use_esn)
Neale Ranns2ac885c2019-03-20 18:24:43 +0000109 p.vpp_tun_sa = SecurityAssociation(
110 encryption_type, spi=p.scapy_tun_spi,
Neale Ranns80f6fd52019-04-16 02:41:34 +0000111 crypt_algo=p.crypt_algo,
112 crypt_key=crypt_key,
Neale Ranns2ac885c2019-03-20 18:24:43 +0000113 auth_algo=p.auth_algo, auth_key=p.auth_key,
114 tunnel_header=ip_class_by_addr_type[p.addr_type](
115 dst=tun_if.remote_addr[p.addr_type],
116 src=tun_if.local_addr[p.addr_type]),
Neale Ranns3833ffd2019-03-21 14:34:09 +0000117 nat_t_header=p.nat_header,
118 use_esn=use_esn)
Neale Ranns2ac885c2019-03-20 18:24:43 +0000119
120
121def config_tra_params(p, encryption_type):
Neale Ranns4f33c802019-04-10 12:39:10 +0000122 use_esn = bool(p.flags & (VppEnum.vl_api_ipsec_sad_flags_t.
123 IPSEC_API_SAD_FLAG_USE_ESN))
Neale Ranns12989b52019-09-26 16:20:19 +0000124 crypt_key = mk_scapy_crypt_key(p)
Neale Ranns2ac885c2019-03-20 18:24:43 +0000125 p.scapy_tra_sa = SecurityAssociation(
126 encryption_type,
127 spi=p.vpp_tra_spi,
128 crypt_algo=p.crypt_algo,
Neale Ranns80f6fd52019-04-16 02:41:34 +0000129 crypt_key=crypt_key,
Neale Ranns2ac885c2019-03-20 18:24:43 +0000130 auth_algo=p.auth_algo,
131 auth_key=p.auth_key,
Neale Ranns3833ffd2019-03-21 14:34:09 +0000132 nat_t_header=p.nat_header,
133 use_esn=use_esn)
Neale Ranns2ac885c2019-03-20 18:24:43 +0000134 p.vpp_tra_sa = SecurityAssociation(
135 encryption_type,
136 spi=p.scapy_tra_spi,
137 crypt_algo=p.crypt_algo,
Neale Ranns80f6fd52019-04-16 02:41:34 +0000138 crypt_key=crypt_key,
Neale Ranns2ac885c2019-03-20 18:24:43 +0000139 auth_algo=p.auth_algo,
140 auth_key=p.auth_key,
Neale Ranns3833ffd2019-03-21 14:34:09 +0000141 nat_t_header=p.nat_header,
142 use_esn=use_esn)
Neale Ranns2ac885c2019-03-20 18:24:43 +0000143
144
Klement Sekera31da2e32018-06-24 22:49:55 +0200145class TemplateIpsec(VppTestCase):
146 """
147 TRANSPORT MODE:
148
149 ------ encrypt ---
150 |tra_if| <-------> |VPP|
151 ------ decrypt ---
152
153 TUNNEL MODE:
154
155 ------ encrypt --- plain ---
156 |tun_if| <------- |VPP| <------ |pg1|
157 ------ --- ---
158
159 ------ decrypt --- plain ---
160 |tun_if| -------> |VPP| ------> |pg1|
161 ------ --- ---
162 """
Neale Ranns4f33c802019-04-10 12:39:10 +0000163 tun_spd_id = 1
164 tra_spd_id = 2
Klement Sekera31da2e32018-06-24 22:49:55 +0200165
Neale Ranns8e4a89b2019-01-23 08:16:17 -0800166 def ipsec_select_backend(self):
Klement Sekerab4d30532018-11-08 13:00:02 +0100167 """ empty method to be overloaded when necessary """
168 pass
169
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -0700170 @classmethod
171 def setUpClass(cls):
172 super(TemplateIpsec, cls).setUpClass()
173
174 @classmethod
175 def tearDownClass(cls):
176 super(TemplateIpsec, cls).tearDownClass()
177
Neale Ranns3833ffd2019-03-21 14:34:09 +0000178 def setup_params(self):
Neale Ranns8e4a89b2019-01-23 08:16:17 -0800179 self.ipv4_params = IPsecIPv4Params()
180 self.ipv6_params = IPsecIPv6Params()
181 self.params = {self.ipv4_params.addr_type: self.ipv4_params,
182 self.ipv6_params.addr_type: self.ipv6_params}
183
Neale Ranns4f33c802019-04-10 12:39:10 +0000184 def config_interfaces(self):
Neale Ranns8e4a89b2019-01-23 08:16:17 -0800185 self.create_pg_interfaces(range(3))
186 self.interfaces = list(self.pg_interfaces)
187 for i in self.interfaces:
Klement Sekera31da2e32018-06-24 22:49:55 +0200188 i.admin_up()
189 i.config_ip4()
190 i.resolve_arp()
Klement Sekera611864f2018-09-26 11:19:00 +0200191 i.config_ip6()
192 i.resolve_ndp()
Neale Ranns4f33c802019-04-10 12:39:10 +0000193
194 def setUp(self):
195 super(TemplateIpsec, self).setUp()
196
197 self.setup_params()
198
199 self.vpp_esp_protocol = (VppEnum.vl_api_ipsec_proto_t.
200 IPSEC_API_PROTO_ESP)
201 self.vpp_ah_protocol = (VppEnum.vl_api_ipsec_proto_t.
202 IPSEC_API_PROTO_AH)
203
204 self.config_interfaces()
Paul Vinciguerra90cf21b2019-03-13 09:23:05 -0700205
Neale Ranns8e4a89b2019-01-23 08:16:17 -0800206 self.ipsec_select_backend()
Klement Sekera31da2e32018-06-24 22:49:55 +0200207
Neale Ranns4f33c802019-04-10 12:39:10 +0000208 def unconfig_interfaces(self):
Neale Ranns8e4a89b2019-01-23 08:16:17 -0800209 for i in self.interfaces:
210 i.admin_down()
211 i.unconfig_ip4()
212 i.unconfig_ip6()
213
Neale Ranns4f33c802019-04-10 12:39:10 +0000214 def tearDown(self):
215 super(TemplateIpsec, self).tearDown()
216
217 self.unconfig_interfaces()
218
Paul Vinciguerra90cf21b2019-03-13 09:23:05 -0700219 def show_commands_at_teardown(self):
220 self.logger.info(self.vapi.cli("show hardware"))
Klement Sekera31da2e32018-06-24 22:49:55 +0200221
Neale Rannsd7603d92019-03-28 08:56:10 +0000222 def gen_encrypt_pkts(self, sa, sw_intf, src, dst, count=1,
223 payload_size=54):
Klement Sekera31da2e32018-06-24 22:49:55 +0200224 return [Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac) /
Neale Rannsd7603d92019-03-28 08:56:10 +0000225 sa.encrypt(IP(src=src, dst=dst) /
Ole Troan8b76c232019-10-21 20:55:13 +0200226 ICMP() / Raw(b'X' * payload_size))
Klement Sekera31da2e32018-06-24 22:49:55 +0200227 for i in range(count)]
228
Neale Rannsd7603d92019-03-28 08:56:10 +0000229 def gen_encrypt_pkts6(self, sa, sw_intf, src, dst, count=1,
230 payload_size=54):
Klement Sekera611864f2018-09-26 11:19:00 +0200231 return [Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac) /
232 sa.encrypt(IPv6(src=src, dst=dst) /
Neale Rannsd7603d92019-03-28 08:56:10 +0000233 ICMPv6EchoRequest(id=0, seq=1,
234 data='X' * payload_size))
Klement Sekera611864f2018-09-26 11:19:00 +0200235 for i in range(count)]
236
Neale Rannsd7603d92019-03-28 08:56:10 +0000237 def gen_pkts(self, sw_intf, src, dst, count=1, payload_size=54):
Klement Sekera31da2e32018-06-24 22:49:55 +0200238 return [Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac) /
Ole Troan8b76c232019-10-21 20:55:13 +0200239 IP(src=src, dst=dst) / ICMP() / Raw(b'X' * payload_size)
Klement Sekera31da2e32018-06-24 22:49:55 +0200240 for i in range(count)]
241
Neale Rannsd7603d92019-03-28 08:56:10 +0000242 def gen_pkts6(self, sw_intf, src, dst, count=1, payload_size=54):
Klement Sekera611864f2018-09-26 11:19:00 +0200243 return [Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac) /
244 IPv6(src=src, dst=dst) /
Neale Rannsd7603d92019-03-28 08:56:10 +0000245 ICMPv6EchoRequest(id=0, seq=1, data='X' * payload_size)
Klement Sekera611864f2018-09-26 11:19:00 +0200246 for i in range(count)]
247
Klement Sekera31da2e32018-06-24 22:49:55 +0200248
Neale Ranns4f33c802019-04-10 12:39:10 +0000249class IpsecTcp(object):
250 def verify_tcp_checksum(self):
Klement Sekera31da2e32018-06-24 22:49:55 +0200251 self.vapi.cli("test http server")
Klement Sekera611864f2018-09-26 11:19:00 +0200252 p = self.params[socket.AF_INET]
Klement Sekera31da2e32018-06-24 22:49:55 +0200253 send = (Ether(src=self.tun_if.remote_mac, dst=self.tun_if.local_mac) /
Neale Ranns2ac885c2019-03-20 18:24:43 +0000254 p.scapy_tun_sa.encrypt(IP(src=p.remote_tun_if_host,
255 dst=self.tun_if.local_ip4) /
256 TCP(flags='S', dport=80)))
Klement Sekera31da2e32018-06-24 22:49:55 +0200257 self.logger.debug(ppp("Sending packet:", send))
Klement Sekera611864f2018-09-26 11:19:00 +0200258 recv = self.send_and_expect(self.tun_if, [send], self.tun_if)
Klement Sekera31da2e32018-06-24 22:49:55 +0200259 recv = recv[0]
Neale Ranns2ac885c2019-03-20 18:24:43 +0000260 decrypted = p.vpp_tun_sa.decrypt(recv[IP])
Klement Sekera31da2e32018-06-24 22:49:55 +0200261 self.assert_packet_checksums_valid(decrypted)
262
263
Neale Ranns4f33c802019-04-10 12:39:10 +0000264class IpsecTcpTests(IpsecTcp):
265 def test_tcp_checksum(self):
266 """ verify checksum correctness for vpp generated packets """
267 self.verify_tcp_checksum()
268
269
270class IpsecTra4(object):
271 """ verify methods for Transport v4 """
Neale Ranns6afaae12019-07-17 15:07:14 +0000272 def verify_tra_anti_replay(self):
Neale Rannsde847272018-11-28 01:38:34 -0800273 p = self.params[socket.AF_INET]
Neale Ranns3833ffd2019-03-21 14:34:09 +0000274 use_esn = p.vpp_tra_sa.use_esn
Neale Rannsde847272018-11-28 01:38:34 -0800275
Neale Ranns6afaae12019-07-17 15:07:14 +0000276 seq_cycle_node_name = ('/err/%s/sequence number cycled' %
277 self.tra4_encrypt_node_name)
278 replay_node_name = ('/err/%s/SA replayed packet' %
279 self.tra4_decrypt_node_name)
280 if ESP == self.encryption_type and p.crypt_algo == "AES-GCM":
281 hash_failed_node_name = ('/err/%s/ESP decryption failed' %
282 self.tra4_decrypt_node_name)
283 else:
284 hash_failed_node_name = ('/err/%s/Integrity check failed' %
285 self.tra4_decrypt_node_name)
286 replay_count = self.statistics.get_err_counter(replay_node_name)
287 hash_failed_count = self.statistics.get_err_counter(
288 hash_failed_node_name)
289 seq_cycle_count = self.statistics.get_err_counter(seq_cycle_node_name)
Neale Rannsde847272018-11-28 01:38:34 -0800290
Neale Ranns6afaae12019-07-17 15:07:14 +0000291 if ESP == self.encryption_type:
292 undersize_node_name = ('/err/%s/undersized packet' %
293 self.tra4_decrypt_node_name)
294 undersize_count = self.statistics.get_err_counter(
295 undersize_node_name)
296
297 #
298 # send packets with seq numbers 1->34
299 # this means the window size is still in Case B (see RFC4303
300 # Appendix A)
301 #
302 # for reasons i haven't investigated Scapy won't create a packet with
303 # seq_num=0
304 #
305 pkts = [(Ether(src=self.tra_if.remote_mac,
306 dst=self.tra_if.local_mac) /
307 p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
308 dst=self.tra_if.local_ip4) /
309 ICMP(),
310 seq_num=seq))
311 for seq in range(1, 34)]
312 recv_pkts = self.send_and_expect(self.tra_if, pkts, self.tra_if)
313
314 # replayed packets are dropped
315 self.send_and_assert_no_replies(self.tra_if, pkts)
316 replay_count += len(pkts)
317 self.assert_error_counter_equal(replay_node_name, replay_count)
318
319 #
Neale Ranns3b9374f2019-08-01 04:45:15 -0700320 # now send a batch of packets all with the same sequence number
321 # the first packet in the batch is legitimate, the rest bogus
322 #
323 pkts = (Ether(src=self.tra_if.remote_mac,
324 dst=self.tra_if.local_mac) /
325 p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
326 dst=self.tra_if.local_ip4) /
327 ICMP(),
328 seq_num=35))
329 recv_pkts = self.send_and_expect(self.tra_if, pkts * 8,
330 self.tra_if, n_rx=1)
331 replay_count += 7
332 self.assert_error_counter_equal(replay_node_name, replay_count)
333
334 #
Neale Ranns6afaae12019-07-17 15:07:14 +0000335 # now move the window over to 257 (more than one byte) and into Case A
336 #
Neale Rannsde847272018-11-28 01:38:34 -0800337 pkt = (Ether(src=self.tra_if.remote_mac,
338 dst=self.tra_if.local_mac) /
339 p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
340 dst=self.tra_if.local_ip4) /
341 ICMP(),
Neale Ranns6afaae12019-07-17 15:07:14 +0000342 seq_num=257))
Neale Rannsde847272018-11-28 01:38:34 -0800343 recv_pkts = self.send_and_expect(self.tra_if, [pkt], self.tra_if)
344
Neale Ranns3833ffd2019-03-21 14:34:09 +0000345 # replayed packets are dropped
346 self.send_and_assert_no_replies(self.tra_if, pkt * 3)
Neale Ranns6afaae12019-07-17 15:07:14 +0000347 replay_count += 3
348 self.assert_error_counter_equal(replay_node_name, replay_count)
Neale Ranns3833ffd2019-03-21 14:34:09 +0000349
Neale Rannsde847272018-11-28 01:38:34 -0800350 # the window size is 64 packets
351 # in window are still accepted
352 pkt = (Ether(src=self.tra_if.remote_mac,
353 dst=self.tra_if.local_mac) /
354 p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
355 dst=self.tra_if.local_ip4) /
356 ICMP(),
Neale Ranns6afaae12019-07-17 15:07:14 +0000357 seq_num=200))
Neale Rannsde847272018-11-28 01:38:34 -0800358 recv_pkts = self.send_and_expect(self.tra_if, [pkt], self.tra_if)
359
Neale Rannsde847272018-11-28 01:38:34 -0800360 # a packet that does not decrypt does not move the window forward
361 bogus_sa = SecurityAssociation(self.encryption_type,
Damjan Mariona829b132019-04-24 23:39:16 +0200362 p.vpp_tra_spi,
363 crypt_algo=p.crypt_algo,
Neale Ranns12989b52019-09-26 16:20:19 +0000364 crypt_key=mk_scapy_crypt_key(p)[::-1],
Damjan Mariona829b132019-04-24 23:39:16 +0200365 auth_algo=p.auth_algo,
366 auth_key=p.auth_key[::-1])
Neale Rannsde847272018-11-28 01:38:34 -0800367 pkt = (Ether(src=self.tra_if.remote_mac,
368 dst=self.tra_if.local_mac) /
369 bogus_sa.encrypt(IP(src=self.tra_if.remote_ip4,
370 dst=self.tra_if.local_ip4) /
371 ICMP(),
372 seq_num=350))
373 self.send_and_assert_no_replies(self.tra_if, pkt * 17)
374
Neale Ranns6afaae12019-07-17 15:07:14 +0000375 hash_failed_count += 17
376 self.assert_error_counter_equal(hash_failed_node_name,
377 hash_failed_count)
Neale Rannsde847272018-11-28 01:38:34 -0800378
Damjan Mariona829b132019-04-24 23:39:16 +0200379 # a malformed 'runt' packet
380 # created by a mis-constructed SA
Neale Ranns2cdcd0c2019-08-27 12:26:14 +0000381 if (ESP == self.encryption_type and p.crypt_algo != "NULL"):
Damjan Mariona829b132019-04-24 23:39:16 +0200382 bogus_sa = SecurityAssociation(self.encryption_type,
383 p.vpp_tra_spi)
384 pkt = (Ether(src=self.tra_if.remote_mac,
385 dst=self.tra_if.local_mac) /
386 bogus_sa.encrypt(IP(src=self.tra_if.remote_ip4,
387 dst=self.tra_if.local_ip4) /
388 ICMP(),
389 seq_num=350))
390 self.send_and_assert_no_replies(self.tra_if, pkt * 17)
391
Neale Ranns6afaae12019-07-17 15:07:14 +0000392 undersize_count += 17
393 self.assert_error_counter_equal(undersize_node_name,
394 undersize_count)
Damjan Mariona829b132019-04-24 23:39:16 +0200395
Neale Rannsde847272018-11-28 01:38:34 -0800396 # which we can determine since this packet is still in the window
397 pkt = (Ether(src=self.tra_if.remote_mac,
398 dst=self.tra_if.local_mac) /
399 p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
400 dst=self.tra_if.local_ip4) /
401 ICMP(),
402 seq_num=234))
Klement Sekera14d7e902018-12-10 13:46:09 +0100403 self.send_and_expect(self.tra_if, [pkt], self.tra_if)
Neale Rannsde847272018-11-28 01:38:34 -0800404
Neale Ranns6afaae12019-07-17 15:07:14 +0000405 #
Neale Ranns3833ffd2019-03-21 14:34:09 +0000406 # out of window are dropped
Neale Ranns6afaae12019-07-17 15:07:14 +0000407 # this is Case B. So VPP will consider this to be a high seq num wrap
408 # and so the decrypt attempt will fail
409 #
Neale Ranns3833ffd2019-03-21 14:34:09 +0000410 pkt = (Ether(src=self.tra_if.remote_mac,
411 dst=self.tra_if.local_mac) /
412 p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
413 dst=self.tra_if.local_ip4) /
414 ICMP(),
415 seq_num=17))
416 self.send_and_assert_no_replies(self.tra_if, pkt * 17)
Neale Ranns00a44202019-03-21 16:36:28 +0000417
Neale Ranns3833ffd2019-03-21 14:34:09 +0000418 if use_esn:
419 # an out of window error with ESN looks like a high sequence
420 # wrap. but since it isn't then the verify will fail.
Neale Ranns6afaae12019-07-17 15:07:14 +0000421 hash_failed_count += 17
422 self.assert_error_counter_equal(hash_failed_node_name,
423 hash_failed_count)
Neale Ranns3833ffd2019-03-21 14:34:09 +0000424
425 else:
Neale Ranns6afaae12019-07-17 15:07:14 +0000426 replay_count += 17
427 self.assert_error_counter_equal(replay_node_name,
428 replay_count)
Neale Ranns3833ffd2019-03-21 14:34:09 +0000429
Neale Ranns6afaae12019-07-17 15:07:14 +0000430 # valid packet moves the window over to 258
Neale Ranns00a44202019-03-21 16:36:28 +0000431 pkt = (Ether(src=self.tra_if.remote_mac,
432 dst=self.tra_if.local_mac) /
433 p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
434 dst=self.tra_if.local_ip4) /
435 ICMP(),
Neale Ranns6afaae12019-07-17 15:07:14 +0000436 seq_num=258))
Neale Ranns3833ffd2019-03-21 14:34:09 +0000437 rx = self.send_and_expect(self.tra_if, [pkt], self.tra_if)
438 decrypted = p.vpp_tra_sa.decrypt(rx[0][IP])
439
Neale Ranns6afaae12019-07-17 15:07:14 +0000440 #
441 # move VPP's SA TX seq-num to just before the seq-number wrap.
442 # then fire in a packet that VPP should drop on TX because it
443 # causes the TX seq number to wrap; unless we're using extened sequence
444 # numbers.
445 #
Neale Ranns3833ffd2019-03-21 14:34:09 +0000446 self.vapi.cli("test ipsec sa %d seq 0xffffffff" % p.scapy_tra_sa_id)
Neale Ranns6afaae12019-07-17 15:07:14 +0000447 self.logger.info(self.vapi.ppcli("show ipsec sa 0"))
448 self.logger.info(self.vapi.ppcli("show ipsec sa 1"))
Neale Ranns3833ffd2019-03-21 14:34:09 +0000449
Neale Ranns6afaae12019-07-17 15:07:14 +0000450 pkts = [(Ether(src=self.tra_if.remote_mac,
451 dst=self.tra_if.local_mac) /
452 p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
453 dst=self.tra_if.local_ip4) /
454 ICMP(),
455 seq_num=seq))
456 for seq in range(259, 280)]
Neale Ranns3833ffd2019-03-21 14:34:09 +0000457
458 if use_esn:
Neale Ranns6afaae12019-07-17 15:07:14 +0000459 rxs = self.send_and_expect(self.tra_if, pkts, self.tra_if)
Neale Ranns3833ffd2019-03-21 14:34:09 +0000460
Neale Ranns6afaae12019-07-17 15:07:14 +0000461 #
462 # in order for scapy to decrypt its SA's high order number needs
463 # to wrap
464 #
465 p.vpp_tra_sa.seq_num = 0x100000000
466 for rx in rxs:
467 decrypted = p.vpp_tra_sa.decrypt(rx[0][IP])
468
469 #
470 # wrap scapy's TX high sequence number. VPP is in case B, so it
471 # will consider this a high seq wrap also.
472 # The low seq num we set it to will place VPP's RX window in Case A
473 #
Neale Ranns3833ffd2019-03-21 14:34:09 +0000474 p.scapy_tra_sa.seq_num = 0x100000005
475 pkt = (Ether(src=self.tra_if.remote_mac,
476 dst=self.tra_if.local_mac) /
477 p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
478 dst=self.tra_if.local_ip4) /
479 ICMP(),
480 seq_num=0x100000005))
481 rx = self.send_and_expect(self.tra_if, [pkt], self.tra_if)
Neale Ranns3833ffd2019-03-21 14:34:09 +0000482 decrypted = p.vpp_tra_sa.decrypt(rx[0][IP])
Neale Ranns6afaae12019-07-17 15:07:14 +0000483
484 #
485 # A packet that has seq num between (2^32-64) and 5 is within
486 # the window
487 #
488 p.scapy_tra_sa.seq_num = 0xfffffffd
489 pkt = (Ether(src=self.tra_if.remote_mac,
490 dst=self.tra_if.local_mac) /
491 p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
492 dst=self.tra_if.local_ip4) /
493 ICMP(),
494 seq_num=0xfffffffd))
495 rx = self.send_and_expect(self.tra_if, [pkt], self.tra_if)
496 decrypted = p.vpp_tra_sa.decrypt(rx[0][IP])
497
498 #
499 # While in case A we cannot wrap the high sequence number again
500 # becuase VPP will consider this packet to be one that moves the
501 # window forward
502 #
503 pkt = (Ether(src=self.tra_if.remote_mac,
504 dst=self.tra_if.local_mac) /
505 p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
506 dst=self.tra_if.local_ip4) /
507 ICMP(),
508 seq_num=0x200000999))
509 self.send_and_assert_no_replies(self.tra_if, [pkt], self.tra_if)
510
511 hash_failed_count += 1
512 self.assert_error_counter_equal(hash_failed_node_name,
513 hash_failed_count)
514
515 #
516 # but if we move the wondow forward to case B, then we can wrap
517 # again
518 #
519 p.scapy_tra_sa.seq_num = 0x100000555
520 pkt = (Ether(src=self.tra_if.remote_mac,
521 dst=self.tra_if.local_mac) /
522 p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
523 dst=self.tra_if.local_ip4) /
524 ICMP(),
525 seq_num=0x100000555))
526 rx = self.send_and_expect(self.tra_if, [pkt], self.tra_if)
527 decrypted = p.vpp_tra_sa.decrypt(rx[0][IP])
528
529 p.scapy_tra_sa.seq_num = 0x200000444
530 pkt = (Ether(src=self.tra_if.remote_mac,
531 dst=self.tra_if.local_mac) /
532 p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
533 dst=self.tra_if.local_ip4) /
534 ICMP(),
535 seq_num=0x200000444))
536 rx = self.send_and_expect(self.tra_if, [pkt], self.tra_if)
537 decrypted = p.vpp_tra_sa.decrypt(rx[0][IP])
538
Neale Ranns3833ffd2019-03-21 14:34:09 +0000539 else:
Neale Ranns6afaae12019-07-17 15:07:14 +0000540 #
541 # without ESN TX sequence numbers can't wrap and packets are
542 # dropped from here on out.
543 #
544 self.send_and_assert_no_replies(self.tra_if, pkts)
545 seq_cycle_count += len(pkts)
546 self.assert_error_counter_equal(seq_cycle_node_name,
547 seq_cycle_count)
Neale Ranns00a44202019-03-21 16:36:28 +0000548
Neale Rannsde847272018-11-28 01:38:34 -0800549 # move the security-associations seq number on to the last we used
Neale Ranns00a44202019-03-21 16:36:28 +0000550 self.vapi.cli("test ipsec sa %d seq 0x15f" % p.scapy_tra_sa_id)
Neale Rannsde847272018-11-28 01:38:34 -0800551 p.scapy_tra_sa.seq_num = 351
552 p.vpp_tra_sa.seq_num = 351
553
Neale Ranns4f33c802019-04-10 12:39:10 +0000554 def verify_tra_basic4(self, count=1):
Klement Sekera31da2e32018-06-24 22:49:55 +0200555 """ ipsec v4 transport basic test """
Klement Sekera10d066e2018-11-13 11:12:57 +0100556 self.vapi.cli("clear errors")
Neale Ranns6afaae12019-07-17 15:07:14 +0000557 self.vapi.cli("clear ipsec sa")
Klement Sekera31da2e32018-06-24 22:49:55 +0200558 try:
Klement Sekera611864f2018-09-26 11:19:00 +0200559 p = self.params[socket.AF_INET]
Neale Rannsde847272018-11-28 01:38:34 -0800560 send_pkts = self.gen_encrypt_pkts(p.scapy_tra_sa, self.tra_if,
Klement Sekera31da2e32018-06-24 22:49:55 +0200561 src=self.tra_if.remote_ip4,
562 dst=self.tra_if.local_ip4,
563 count=count)
564 recv_pkts = self.send_and_expect(self.tra_if, send_pkts,
Klement Sekera611864f2018-09-26 11:19:00 +0200565 self.tra_if)
Neale Rannsde847272018-11-28 01:38:34 -0800566 for rx in recv_pkts:
Neale Ranns1b582b82019-04-18 19:49:13 -0700567 self.assertEqual(len(rx) - len(Ether()), rx[IP].len)
568 self.assert_packet_checksums_valid(rx)
Klement Sekera611864f2018-09-26 11:19:00 +0200569 try:
Neale Rannsde847272018-11-28 01:38:34 -0800570 decrypted = p.vpp_tra_sa.decrypt(rx[IP])
Klement Sekera611864f2018-09-26 11:19:00 +0200571 self.assert_packet_checksums_valid(decrypted)
572 except:
Neale Rannsde847272018-11-28 01:38:34 -0800573 self.logger.debug(ppp("Unexpected packet:", rx))
Klement Sekera611864f2018-09-26 11:19:00 +0200574 raise
Klement Sekera31da2e32018-06-24 22:49:55 +0200575 finally:
576 self.logger.info(self.vapi.ppcli("show error"))
Paul Vinciguerra9673e3e2019-05-10 20:41:08 -0400577 self.logger.info(self.vapi.ppcli("show ipsec all"))
Klement Sekera31da2e32018-06-24 22:49:55 +0200578
Neale Rannseba31ec2019-02-17 18:04:27 +0000579 pkts = p.tra_sa_in.get_stats()['packets']
580 self.assertEqual(pkts, count,
581 "incorrect SA in counts: expected %d != %d" %
582 (count, pkts))
583 pkts = p.tra_sa_out.get_stats()['packets']
584 self.assertEqual(pkts, count,
585 "incorrect SA out counts: expected %d != %d" %
586 (count, pkts))
587
Klement Sekera10d066e2018-11-13 11:12:57 +0100588 self.assert_packet_counter_equal(self.tra4_encrypt_node_name, count)
589 self.assert_packet_counter_equal(self.tra4_decrypt_node_name, count)
590
Neale Ranns4f33c802019-04-10 12:39:10 +0000591
592class IpsecTra4Tests(IpsecTra4):
593 """ UT test methods for Transport v4 """
594 def test_tra_anti_replay(self):
595 """ ipsec v4 transport anti-reply test """
Neale Ranns6afaae12019-07-17 15:07:14 +0000596 self.verify_tra_anti_replay()
Neale Ranns4f33c802019-04-10 12:39:10 +0000597
598 def test_tra_basic(self, count=1):
599 """ ipsec v4 transport basic test """
600 self.verify_tra_basic4(count=1)
601
Klement Sekera31da2e32018-06-24 22:49:55 +0200602 def test_tra_burst(self):
603 """ ipsec v4 transport burst test """
Neale Ranns4f33c802019-04-10 12:39:10 +0000604 self.verify_tra_basic4(count=257)
Klement Sekera611864f2018-09-26 11:19:00 +0200605
Neale Ranns53f526b2019-02-25 14:32:02 +0000606
Neale Ranns4f33c802019-04-10 12:39:10 +0000607class IpsecTra6(object):
608 """ verify methods for Transport v6 """
609 def verify_tra_basic6(self, count=1):
Klement Sekera10d066e2018-11-13 11:12:57 +0100610 self.vapi.cli("clear errors")
Klement Sekera31da2e32018-06-24 22:49:55 +0200611 try:
Klement Sekera611864f2018-09-26 11:19:00 +0200612 p = self.params[socket.AF_INET6]
Neale Rannsde847272018-11-28 01:38:34 -0800613 send_pkts = self.gen_encrypt_pkts6(p.scapy_tra_sa, self.tra_if,
Klement Sekera611864f2018-09-26 11:19:00 +0200614 src=self.tra_if.remote_ip6,
615 dst=self.tra_if.local_ip6,
616 count=count)
617 recv_pkts = self.send_and_expect(self.tra_if, send_pkts,
618 self.tra_if)
Neale Rannsde847272018-11-28 01:38:34 -0800619 for rx in recv_pkts:
Neale Rannsd207fd72019-04-18 17:18:12 -0700620 self.assertEqual(len(rx) - len(Ether()) - len(IPv6()),
621 rx[IPv6].plen)
Klement Sekera611864f2018-09-26 11:19:00 +0200622 try:
Neale Rannsde847272018-11-28 01:38:34 -0800623 decrypted = p.vpp_tra_sa.decrypt(rx[IPv6])
Klement Sekera611864f2018-09-26 11:19:00 +0200624 self.assert_packet_checksums_valid(decrypted)
625 except:
Neale Rannsde847272018-11-28 01:38:34 -0800626 self.logger.debug(ppp("Unexpected packet:", rx))
Klement Sekera611864f2018-09-26 11:19:00 +0200627 raise
Klement Sekera31da2e32018-06-24 22:49:55 +0200628 finally:
629 self.logger.info(self.vapi.ppcli("show error"))
Paul Vinciguerra9673e3e2019-05-10 20:41:08 -0400630 self.logger.info(self.vapi.ppcli("show ipsec all"))
Klement Sekera31da2e32018-06-24 22:49:55 +0200631
Neale Rannseba31ec2019-02-17 18:04:27 +0000632 pkts = p.tra_sa_in.get_stats()['packets']
633 self.assertEqual(pkts, count,
634 "incorrect SA in counts: expected %d != %d" %
635 (count, pkts))
636 pkts = p.tra_sa_out.get_stats()['packets']
637 self.assertEqual(pkts, count,
638 "incorrect SA out counts: expected %d != %d" %
639 (count, pkts))
Klement Sekera10d066e2018-11-13 11:12:57 +0100640 self.assert_packet_counter_equal(self.tra6_encrypt_node_name, count)
641 self.assert_packet_counter_equal(self.tra6_decrypt_node_name, count)
642
Neale Ranns4f33c802019-04-10 12:39:10 +0000643
644class IpsecTra6Tests(IpsecTra6):
645 """ UT test methods for Transport v6 """
646 def test_tra_basic6(self):
647 """ ipsec v6 transport basic test """
648 self.verify_tra_basic6(count=1)
649
Klement Sekera611864f2018-09-26 11:19:00 +0200650 def test_tra_burst6(self):
651 """ ipsec v6 transport burst test """
Neale Ranns4f33c802019-04-10 12:39:10 +0000652 self.verify_tra_basic6(count=257)
Klement Sekera31da2e32018-06-24 22:49:55 +0200653
Klement Sekera611864f2018-09-26 11:19:00 +0200654
Neale Ranns53f526b2019-02-25 14:32:02 +0000655class IpsecTra46Tests(IpsecTra4Tests, IpsecTra6Tests):
Neale Ranns4f33c802019-04-10 12:39:10 +0000656 """ UT test methods for Transport v6 and v4"""
Neale Ranns53f526b2019-02-25 14:32:02 +0000657 pass
658
659
Neale Ranns2ac885c2019-03-20 18:24:43 +0000660class IpsecTun4(object):
Neale Ranns4f33c802019-04-10 12:39:10 +0000661 """ verify methods for Tunnel v4 """
Klement Sekera6aa58b72019-05-16 14:34:55 +0200662 def verify_counters4(self, p, count, n_frags=None):
663 if not n_frags:
664 n_frags = count
Neale Ranns987aea82019-03-27 13:40:35 +0000665 if (hasattr(p, "spd_policy_in_any")):
666 pkts = p.spd_policy_in_any.get_stats()['packets']
667 self.assertEqual(pkts, count,
668 "incorrect SPD any policy: expected %d != %d" %
669 (count, pkts))
670
671 if (hasattr(p, "tun_sa_in")):
672 pkts = p.tun_sa_in.get_stats()['packets']
673 self.assertEqual(pkts, count,
674 "incorrect SA in counts: expected %d != %d" %
675 (count, pkts))
676 pkts = p.tun_sa_out.get_stats()['packets']
677 self.assertEqual(pkts, count,
678 "incorrect SA out counts: expected %d != %d" %
679 (count, pkts))
680
Klement Sekera6aa58b72019-05-16 14:34:55 +0200681 self.assert_packet_counter_equal(self.tun4_encrypt_node_name, n_frags)
Neale Ranns987aea82019-03-27 13:40:35 +0000682 self.assert_packet_counter_equal(self.tun4_decrypt_node_name, count)
683
Neale Rannsf05e7322019-03-29 20:23:58 +0000684 def verify_decrypted(self, p, rxs):
685 for rx in rxs:
686 self.assert_equal(rx[IP].src, p.remote_tun_if_host)
687 self.assert_equal(rx[IP].dst, self.pg1.remote_ip4)
688 self.assert_packet_checksums_valid(rx)
689
690 def verify_encrypted(self, p, sa, rxs):
691 decrypt_pkts = []
692 for rx in rxs:
Neale Ranns41afb332019-07-16 06:19:35 -0700693 if p.nat_header:
694 self.assertEqual(rx[UDP].dport, 4500)
Neale Ranns1b582b82019-04-18 19:49:13 -0700695 self.assert_packet_checksums_valid(rx)
696 self.assertEqual(len(rx) - len(Ether()), rx[IP].len)
Neale Rannsf05e7322019-03-29 20:23:58 +0000697 try:
698 decrypt_pkt = p.vpp_tun_sa.decrypt(rx[IP])
699 if not decrypt_pkt.haslayer(IP):
700 decrypt_pkt = IP(decrypt_pkt[Raw].load)
701 decrypt_pkts.append(decrypt_pkt)
702 self.assert_equal(decrypt_pkt.src, self.pg1.remote_ip4)
703 self.assert_equal(decrypt_pkt.dst, p.remote_tun_if_host)
704 except:
705 self.logger.debug(ppp("Unexpected packet:", rx))
706 try:
707 self.logger.debug(ppp("Decrypted packet:", decrypt_pkt))
708 except:
709 pass
710 raise
711 pkts = reassemble4(decrypt_pkts)
712 for pkt in pkts:
713 self.assert_packet_checksums_valid(pkt)
714
Neale Rannsd7603d92019-03-28 08:56:10 +0000715 def verify_tun_44(self, p, count=1, payload_size=64, n_rx=None):
Klement Sekera10d066e2018-11-13 11:12:57 +0100716 self.vapi.cli("clear errors")
Neale Rannsd7603d92019-03-28 08:56:10 +0000717 if not n_rx:
718 n_rx = count
Klement Sekera31da2e32018-06-24 22:49:55 +0200719 try:
Neale Ranns2ac885c2019-03-20 18:24:43 +0000720 send_pkts = self.gen_encrypt_pkts(p.scapy_tun_sa, self.tun_if,
Klement Sekera611864f2018-09-26 11:19:00 +0200721 src=p.remote_tun_if_host,
Klement Sekera31da2e32018-06-24 22:49:55 +0200722 dst=self.pg1.remote_ip4,
723 count=count)
Klement Sekera611864f2018-09-26 11:19:00 +0200724 recv_pkts = self.send_and_expect(self.tun_if, send_pkts, self.pg1)
Neale Rannsf05e7322019-03-29 20:23:58 +0000725 self.verify_decrypted(p, recv_pkts)
726
Klement Sekera31da2e32018-06-24 22:49:55 +0200727 send_pkts = self.gen_pkts(self.pg1, src=self.pg1.remote_ip4,
Neale Rannsd7603d92019-03-28 08:56:10 +0000728 dst=p.remote_tun_if_host, count=count,
729 payload_size=payload_size)
730 recv_pkts = self.send_and_expect(self.pg1, send_pkts,
731 self.tun_if, n_rx)
Neale Rannsf05e7322019-03-29 20:23:58 +0000732 self.verify_encrypted(p, p.vpp_tun_sa, recv_pkts)
733
Klement Sekera31da2e32018-06-24 22:49:55 +0200734 finally:
735 self.logger.info(self.vapi.ppcli("show error"))
Paul Vinciguerra9673e3e2019-05-10 20:41:08 -0400736 self.logger.info(self.vapi.ppcli("show ipsec all"))
Klement Sekera31da2e32018-06-24 22:49:55 +0200737
Klement Sekera6aa58b72019-05-16 14:34:55 +0200738 self.verify_counters4(p, count, n_rx)
Neale Rannseba31ec2019-02-17 18:04:27 +0000739
Neale Ranns14046982019-07-29 14:49:52 +0000740 def verify_tun_reass_44(self, p):
741 self.vapi.cli("clear errors")
742 self.vapi.ip_reassembly_enable_disable(
743 sw_if_index=self.tun_if.sw_if_index, enable_ip4=True)
744
745 try:
Neale Ranns14046982019-07-29 14:49:52 +0000746 send_pkts = self.gen_encrypt_pkts(p.scapy_tun_sa, self.tun_if,
747 src=p.remote_tun_if_host,
748 dst=self.pg1.remote_ip4,
749 payload_size=1900,
750 count=1)
751 send_pkts = fragment_rfc791(send_pkts[0], 1400)
752 recv_pkts = self.send_and_expect(self.tun_if, send_pkts,
753 self.pg1, n_rx=1)
754 self.verify_decrypted(p, recv_pkts)
755
756 send_pkts = self.gen_pkts(self.pg1, src=self.pg1.remote_ip4,
757 dst=p.remote_tun_if_host, count=1)
758 recv_pkts = self.send_and_expect(self.pg1, send_pkts,
759 self.tun_if)
760 self.verify_encrypted(p, p.vpp_tun_sa, recv_pkts)
761
762 finally:
763 self.logger.info(self.vapi.ppcli("show error"))
764 self.logger.info(self.vapi.ppcli("show ipsec all"))
765
766 self.verify_counters4(p, 1, 1)
767 self.vapi.ip_reassembly_enable_disable(
768 sw_if_index=self.tun_if.sw_if_index, enable_ip4=False)
769
Neale Ranns987aea82019-03-27 13:40:35 +0000770 def verify_tun_64(self, p, count=1):
771 self.vapi.cli("clear errors")
772 try:
Neale Ranns987aea82019-03-27 13:40:35 +0000773 send_pkts = self.gen_encrypt_pkts6(p.scapy_tun_sa, self.tun_if,
774 src=p.remote_tun_if_host6,
775 dst=self.pg1.remote_ip6,
776 count=count)
777 recv_pkts = self.send_and_expect(self.tun_if, send_pkts, self.pg1)
778 for recv_pkt in recv_pkts:
779 self.assert_equal(recv_pkt[IPv6].src, p.remote_tun_if_host6)
780 self.assert_equal(recv_pkt[IPv6].dst, self.pg1.remote_ip6)
781 self.assert_packet_checksums_valid(recv_pkt)
782 send_pkts = self.gen_pkts6(self.pg1, src=self.pg1.remote_ip6,
783 dst=p.remote_tun_if_host6, count=count)
784 recv_pkts = self.send_and_expect(self.pg1, send_pkts, self.tun_if)
785 for recv_pkt in recv_pkts:
786 try:
787 decrypt_pkt = p.vpp_tun_sa.decrypt(recv_pkt[IP])
788 if not decrypt_pkt.haslayer(IPv6):
789 decrypt_pkt = IPv6(decrypt_pkt[Raw].load)
790 self.assert_equal(decrypt_pkt.src, self.pg1.remote_ip6)
791 self.assert_equal(decrypt_pkt.dst, p.remote_tun_if_host6)
792 self.assert_packet_checksums_valid(decrypt_pkt)
793 except:
794 self.logger.error(ppp("Unexpected packet:", recv_pkt))
795 try:
796 self.logger.debug(
797 ppp("Decrypted packet:", decrypt_pkt))
798 except:
799 pass
800 raise
801 finally:
802 self.logger.info(self.vapi.ppcli("show error"))
Paul Vinciguerra9673e3e2019-05-10 20:41:08 -0400803 self.logger.info(self.vapi.ppcli("show ipsec all"))
Neale Rannseba31ec2019-02-17 18:04:27 +0000804
Klement Sekera6aa58b72019-05-16 14:34:55 +0200805 self.verify_counters4(p, count)
Klement Sekera10d066e2018-11-13 11:12:57 +0100806
Neale Ranns41afb332019-07-16 06:19:35 -0700807 def verify_keepalive(self, p):
808 pkt = (Ether(src=self.tun_if.remote_mac, dst=self.tun_if.local_mac) /
809 IP(src=p.remote_tun_if_host, dst=self.tun_if.local_ip4) /
810 UDP(sport=333, dport=4500) /
Ole Troan8b76c232019-10-21 20:55:13 +0200811 Raw(b'\xff'))
Neale Ranns41afb332019-07-16 06:19:35 -0700812 self.send_and_assert_no_replies(self.tun_if, pkt*31)
813 self.assert_error_counter_equal(
814 '/err/%s/NAT Keepalive' % self.tun4_input_node, 31)
815
816 pkt = (Ether(src=self.tun_if.remote_mac, dst=self.tun_if.local_mac) /
817 IP(src=p.remote_tun_if_host, dst=self.tun_if.local_ip4) /
818 UDP(sport=333, dport=4500) /
Ole Troan8b76c232019-10-21 20:55:13 +0200819 Raw(b'\xfe'))
Neale Ranns41afb332019-07-16 06:19:35 -0700820 self.send_and_assert_no_replies(self.tun_if, pkt*31)
821 self.assert_error_counter_equal(
822 '/err/%s/Too Short' % self.tun4_input_node, 31)
823
Neale Ranns2ac885c2019-03-20 18:24:43 +0000824
825class IpsecTun4Tests(IpsecTun4):
Neale Ranns4f33c802019-04-10 12:39:10 +0000826 """ UT test methods for Tunnel v4 """
Neale Ranns2ac885c2019-03-20 18:24:43 +0000827 def test_tun_basic44(self):
828 """ ipsec 4o4 tunnel basic test """
829 self.verify_tun_44(self.params[socket.AF_INET], count=1)
830
Neale Ranns14046982019-07-29 14:49:52 +0000831 def test_tun_reass_basic44(self):
832 """ ipsec 4o4 tunnel basic reassembly test """
833 self.verify_tun_reass_44(self.params[socket.AF_INET])
834
Klement Sekera611864f2018-09-26 11:19:00 +0200835 def test_tun_burst44(self):
Klement Sekera31da2e32018-06-24 22:49:55 +0200836 """ ipsec 4o4 tunnel burst test """
Neale Ranns2ac885c2019-03-20 18:24:43 +0000837 self.verify_tun_44(self.params[socket.AF_INET], count=257)
Klement Sekera611864f2018-09-26 11:19:00 +0200838
839
Neale Ranns2ac885c2019-03-20 18:24:43 +0000840class IpsecTun6(object):
Neale Ranns4f33c802019-04-10 12:39:10 +0000841 """ verify methods for Tunnel v6 """
Neale Rannsc87b66c2019-02-07 07:26:12 -0800842 def verify_counters6(self, p_in, p_out, count):
843 if (hasattr(p_in, "tun_sa_in")):
844 pkts = p_in.tun_sa_in.get_stats()['packets']
Neale Ranns987aea82019-03-27 13:40:35 +0000845 self.assertEqual(pkts, count,
846 "incorrect SA in counts: expected %d != %d" %
847 (count, pkts))
Neale Rannsc87b66c2019-02-07 07:26:12 -0800848 if (hasattr(p_out, "tun_sa_out")):
849 pkts = p_out.tun_sa_out.get_stats()['packets']
Neale Ranns987aea82019-03-27 13:40:35 +0000850 self.assertEqual(pkts, count,
851 "incorrect SA out counts: expected %d != %d" %
852 (count, pkts))
853 self.assert_packet_counter_equal(self.tun6_encrypt_node_name, count)
854 self.assert_packet_counter_equal(self.tun6_decrypt_node_name, count)
855
Neale Rannsc87b66c2019-02-07 07:26:12 -0800856 def verify_decrypted6(self, p, rxs):
857 for rx in rxs:
858 self.assert_equal(rx[IPv6].src, p.remote_tun_if_host)
859 self.assert_equal(rx[IPv6].dst, self.pg1.remote_ip6)
860 self.assert_packet_checksums_valid(rx)
861
862 def verify_encrypted6(self, p, sa, rxs):
863 for rx in rxs:
864 self.assert_packet_checksums_valid(rx)
865 self.assertEqual(len(rx) - len(Ether()) - len(IPv6()),
866 rx[IPv6].plen)
867 try:
868 decrypt_pkt = p.vpp_tun_sa.decrypt(rx[IPv6])
869 if not decrypt_pkt.haslayer(IPv6):
870 decrypt_pkt = IPv6(decrypt_pkt[Raw].load)
871 self.assert_packet_checksums_valid(decrypt_pkt)
872 self.assert_equal(decrypt_pkt.src, self.pg1.remote_ip6)
873 self.assert_equal(decrypt_pkt.dst, p.remote_tun_if_host)
874 except:
875 self.logger.debug(ppp("Unexpected packet:", rx))
876 try:
877 self.logger.debug(ppp("Decrypted packet:", decrypt_pkt))
878 except:
879 pass
880 raise
881
882 def verify_drop_tun_66(self, p_in, count=1, payload_size=64):
Klement Sekera10d066e2018-11-13 11:12:57 +0100883 self.vapi.cli("clear errors")
Neale Rannsc87b66c2019-02-07 07:26:12 -0800884 self.vapi.cli("clear ipsec sa")
885
Neale Rannsc87b66c2019-02-07 07:26:12 -0800886 send_pkts = self.gen_encrypt_pkts6(p_in.scapy_tun_sa, self.tun_if,
887 src=p_in.remote_tun_if_host,
888 dst=self.pg1.remote_ip6,
889 count=count)
890 self.send_and_assert_no_replies(self.tun_if, send_pkts)
891 self.logger.info(self.vapi.cli("sh punt stats"))
892
893 def verify_tun_66(self, p_in, p_out=None, count=1, payload_size=64):
894 self.vapi.cli("clear errors")
895 self.vapi.cli("clear ipsec sa")
896 if not p_out:
897 p_out = p_in
Klement Sekera31da2e32018-06-24 22:49:55 +0200898 try:
Neale Rannsc87b66c2019-02-07 07:26:12 -0800899 send_pkts = self.gen_encrypt_pkts6(p_in.scapy_tun_sa, self.tun_if,
900 src=p_in.remote_tun_if_host,
Klement Sekera611864f2018-09-26 11:19:00 +0200901 dst=self.pg1.remote_ip6,
902 count=count)
903 recv_pkts = self.send_and_expect(self.tun_if, send_pkts, self.pg1)
Neale Rannsc87b66c2019-02-07 07:26:12 -0800904 self.verify_decrypted6(p_in, recv_pkts)
905
Klement Sekera611864f2018-09-26 11:19:00 +0200906 send_pkts = self.gen_pkts6(self.pg1, src=self.pg1.remote_ip6,
Neale Rannsc87b66c2019-02-07 07:26:12 -0800907 dst=p_out.remote_tun_if_host,
908 count=count,
909 payload_size=payload_size)
910 recv_pkts = self.send_and_expect(self.pg1, send_pkts,
911 self.tun_if)
912 self.verify_encrypted6(p_out, p_out.vpp_tun_sa, recv_pkts)
913
Klement Sekera31da2e32018-06-24 22:49:55 +0200914 finally:
915 self.logger.info(self.vapi.ppcli("show error"))
Paul Vinciguerra9673e3e2019-05-10 20:41:08 -0400916 self.logger.info(self.vapi.ppcli("show ipsec all"))
Neale Rannsc87b66c2019-02-07 07:26:12 -0800917 self.verify_counters6(p_in, p_out, count)
Klement Sekera31da2e32018-06-24 22:49:55 +0200918
Neale Ranns14046982019-07-29 14:49:52 +0000919 def verify_tun_reass_66(self, p):
920 self.vapi.cli("clear errors")
921 self.vapi.ip_reassembly_enable_disable(
922 sw_if_index=self.tun_if.sw_if_index, enable_ip6=True)
923
924 try:
Neale Ranns14046982019-07-29 14:49:52 +0000925 send_pkts = self.gen_encrypt_pkts6(p.scapy_tun_sa, self.tun_if,
926 src=p.remote_tun_if_host,
927 dst=self.pg1.remote_ip6,
928 count=1,
929 payload_size=1900)
930 send_pkts = fragment_rfc8200(send_pkts[0], 1, 1400, self.logger)
931 recv_pkts = self.send_and_expect(self.tun_if, send_pkts,
932 self.pg1, n_rx=1)
933 self.verify_decrypted6(p, recv_pkts)
934
935 send_pkts = self.gen_pkts6(self.pg1, src=self.pg1.remote_ip6,
936 dst=p.remote_tun_if_host,
937 count=1,
938 payload_size=64)
939 recv_pkts = self.send_and_expect(self.pg1, send_pkts,
940 self.tun_if)
941 self.verify_encrypted6(p, p.vpp_tun_sa, recv_pkts)
942 finally:
943 self.logger.info(self.vapi.ppcli("show error"))
944 self.logger.info(self.vapi.ppcli("show ipsec all"))
945 self.verify_counters6(p, p, 1)
946 self.vapi.ip_reassembly_enable_disable(
947 sw_if_index=self.tun_if.sw_if_index, enable_ip6=False)
948
Neale Ranns987aea82019-03-27 13:40:35 +0000949 def verify_tun_46(self, p, count=1):
950 """ ipsec 4o6 tunnel basic test """
951 self.vapi.cli("clear errors")
952 try:
Neale Ranns987aea82019-03-27 13:40:35 +0000953 send_pkts = self.gen_encrypt_pkts(p.scapy_tun_sa, self.tun_if,
954 src=p.remote_tun_if_host4,
955 dst=self.pg1.remote_ip4,
956 count=count)
957 recv_pkts = self.send_and_expect(self.tun_if, send_pkts, self.pg1)
958 for recv_pkt in recv_pkts:
959 self.assert_equal(recv_pkt[IP].src, p.remote_tun_if_host4)
960 self.assert_equal(recv_pkt[IP].dst, self.pg1.remote_ip4)
961 self.assert_packet_checksums_valid(recv_pkt)
962 send_pkts = self.gen_pkts(self.pg1, src=self.pg1.remote_ip4,
963 dst=p.remote_tun_if_host4,
964 count=count)
965 recv_pkts = self.send_and_expect(self.pg1, send_pkts, self.tun_if)
966 for recv_pkt in recv_pkts:
967 try:
968 decrypt_pkt = p.vpp_tun_sa.decrypt(recv_pkt[IPv6])
969 if not decrypt_pkt.haslayer(IP):
970 decrypt_pkt = IP(decrypt_pkt[Raw].load)
971 self.assert_equal(decrypt_pkt.src, self.pg1.remote_ip4)
972 self.assert_equal(decrypt_pkt.dst, p.remote_tun_if_host4)
973 self.assert_packet_checksums_valid(decrypt_pkt)
974 except:
975 self.logger.debug(ppp("Unexpected packet:", recv_pkt))
976 try:
977 self.logger.debug(ppp("Decrypted packet:",
978 decrypt_pkt))
979 except:
980 pass
981 raise
982 finally:
983 self.logger.info(self.vapi.ppcli("show error"))
Paul Vinciguerra9673e3e2019-05-10 20:41:08 -0400984 self.logger.info(self.vapi.ppcli("show ipsec all"))
Neale Rannsc87b66c2019-02-07 07:26:12 -0800985 self.verify_counters6(p, p, count)
Klement Sekera10d066e2018-11-13 11:12:57 +0100986
Neale Ranns2ac885c2019-03-20 18:24:43 +0000987
988class IpsecTun6Tests(IpsecTun6):
Neale Ranns4f33c802019-04-10 12:39:10 +0000989 """ UT test methods for Tunnel v6 """
Neale Ranns2ac885c2019-03-20 18:24:43 +0000990
991 def test_tun_basic66(self):
992 """ ipsec 6o6 tunnel basic test """
993 self.verify_tun_66(self.params[socket.AF_INET6], count=1)
994
Neale Ranns14046982019-07-29 14:49:52 +0000995 def test_tun_reass_basic66(self):
996 """ ipsec 6o6 tunnel basic reassembly test """
997 self.verify_tun_reass_66(self.params[socket.AF_INET6])
998
Klement Sekera611864f2018-09-26 11:19:00 +0200999 def test_tun_burst66(self):
1000 """ ipsec 6o6 tunnel burst test """
Neale Ranns2ac885c2019-03-20 18:24:43 +00001001 self.verify_tun_66(self.params[socket.AF_INET6], count=257)
Klement Sekera611864f2018-09-26 11:19:00 +02001002
1003
Neale Ranns53f526b2019-02-25 14:32:02 +00001004class IpsecTun46Tests(IpsecTun4Tests, IpsecTun6Tests):
Neale Ranns4f33c802019-04-10 12:39:10 +00001005 """ UT test methods for Tunnel v6 & v4 """
Klement Sekera611864f2018-09-26 11:19:00 +02001006 pass
1007
Klement Sekera31da2e32018-06-24 22:49:55 +02001008
1009if __name__ == '__main__':
1010 unittest.main(testRunner=VppTestRunner)