blob: 0c1f5a1929839ae48223d88467a1150fbb93355b [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
snaramre5d4b8912019-12-13 23:39:35 +00007from scapy.layers.l2 import Ether
Paul Vinciguerra582eac52020-04-03 12:18:40 -04008from scapy.packet import raw, Raw
Neale Ranns02950402019-12-20 00:54:57 +00009from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest, IPv6ExtHdrHopByHop, \
10 IPv6ExtHdrFragment, IPv6ExtHdrDestOpt
11
Klement Sekera31da2e32018-06-24 22:49:55 +020012
13from framework import VppTestCase, VppTestRunner
Neale Ranns14046982019-07-29 14:49:52 +000014from util import ppp, reassemble4, fragment_rfc791, fragment_rfc8200
Neale Ranns17dcec02019-01-09 21:22:20 -080015from vpp_papi import VppEnum
Klement Sekera31da2e32018-06-24 22:49:55 +020016
17
Paul Vinciguerrae061dad2020-12-04 14:57:51 -050018class IPsecIPv4Params:
Neale Ranns17dcec02019-01-09 21:22:20 -080019
Klement Sekera611864f2018-09-26 11:19:00 +020020 addr_type = socket.AF_INET
21 addr_any = "0.0.0.0"
22 addr_bcast = "255.255.255.255"
23 addr_len = 32
24 is_ipv6 = 0
Klement Sekera611864f2018-09-26 11:19:00 +020025
Neale Ranns17dcec02019-01-09 21:22:20 -080026 def __init__(self):
27 self.remote_tun_if_host = '1.1.1.1'
Neale Ranns987aea82019-03-27 13:40:35 +000028 self.remote_tun_if_host6 = '1111::1'
Klement Sekera611864f2018-09-26 11:19:00 +020029
Neale Ranns28287212019-12-16 00:53:11 +000030 self.scapy_tun_sa_id = 100
Neale Rannsa9e27742020-12-23 16:22:28 +000031 self.scapy_tun_spi = 1000
Neale Ranns28287212019-12-16 00:53:11 +000032 self.vpp_tun_sa_id = 200
Neale Rannsa9e27742020-12-23 16:22:28 +000033 self.vpp_tun_spi = 2000
Klement Sekera611864f2018-09-26 11:19:00 +020034
Neale Ranns28287212019-12-16 00:53:11 +000035 self.scapy_tra_sa_id = 300
Neale Rannsa9e27742020-12-23 16:22:28 +000036 self.scapy_tra_spi = 3000
Neale Ranns28287212019-12-16 00:53:11 +000037 self.vpp_tra_sa_id = 400
Neale Rannsa9e27742020-12-23 16:22:28 +000038 self.vpp_tra_spi = 4000
Klement Sekera611864f2018-09-26 11:19:00 +020039
Neale Ranns9ec846c2021-02-09 14:04:02 +000040 self.outer_hop_limit = 64
41 self.inner_hop_limit = 255
42 self.outer_flow_label = 0
43 self.inner_flow_label = 0x12345
44
Neale Ranns17dcec02019-01-09 21:22:20 -080045 self.auth_algo_vpp_id = (VppEnum.vl_api_ipsec_integ_alg_t.
46 IPSEC_API_INTEG_ALG_SHA1_96)
47 self.auth_algo = 'HMAC-SHA1-96' # scapy name
Ole Troan64e978b2019-10-17 21:40:36 +020048 self.auth_key = b'C91KUR9GYMm5GfkEvNjX'
Neale Ranns17dcec02019-01-09 21:22:20 -080049
50 self.crypt_algo_vpp_id = (VppEnum.vl_api_ipsec_crypto_alg_t.
51 IPSEC_API_CRYPTO_ALG_AES_CBC_128)
52 self.crypt_algo = 'AES-CBC' # scapy name
Ole Troan64e978b2019-10-17 21:40:36 +020053 self.crypt_key = b'JPjyOWBeVEQiMe7h'
Neale Ranns80f6fd52019-04-16 02:41:34 +000054 self.salt = 0
Neale Ranns53f526b2019-02-25 14:32:02 +000055 self.flags = 0
56 self.nat_header = None
Neale Ranns041add72020-01-02 04:06:10 +000057 self.tun_flags = (VppEnum.vl_api_tunnel_encap_decap_flags_t.
58 TUNNEL_API_ENCAP_DECAP_FLAG_NONE)
59 self.dscp = 0
Klement Sekera611864f2018-09-26 11:19:00 +020060
61
Paul Vinciguerrae061dad2020-12-04 14:57:51 -050062class IPsecIPv6Params:
Neale Ranns17dcec02019-01-09 21:22:20 -080063
Klement Sekera611864f2018-09-26 11:19:00 +020064 addr_type = socket.AF_INET6
65 addr_any = "0::0"
66 addr_bcast = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"
67 addr_len = 128
68 is_ipv6 = 1
Klement Sekera611864f2018-09-26 11:19:00 +020069
Neale Ranns17dcec02019-01-09 21:22:20 -080070 def __init__(self):
71 self.remote_tun_if_host = '1111:1111:1111:1111:1111:1111:1111:1111'
Neale Ranns987aea82019-03-27 13:40:35 +000072 self.remote_tun_if_host4 = '1.1.1.1'
Klement Sekera611864f2018-09-26 11:19:00 +020073
Neale Ranns28287212019-12-16 00:53:11 +000074 self.scapy_tun_sa_id = 500
Neale Ranns17dcec02019-01-09 21:22:20 -080075 self.scapy_tun_spi = 3001
Neale Ranns28287212019-12-16 00:53:11 +000076 self.vpp_tun_sa_id = 600
Neale Ranns17dcec02019-01-09 21:22:20 -080077 self.vpp_tun_spi = 3000
Klement Sekera611864f2018-09-26 11:19:00 +020078
Neale Ranns28287212019-12-16 00:53:11 +000079 self.scapy_tra_sa_id = 700
Neale Ranns17dcec02019-01-09 21:22:20 -080080 self.scapy_tra_spi = 4001
Neale Ranns28287212019-12-16 00:53:11 +000081 self.vpp_tra_sa_id = 800
Neale Ranns17dcec02019-01-09 21:22:20 -080082 self.vpp_tra_spi = 4000
Klement Sekera611864f2018-09-26 11:19:00 +020083
Neale Ranns9ec846c2021-02-09 14:04:02 +000084 self.outer_hop_limit = 64
85 self.inner_hop_limit = 255
86 self.outer_flow_label = 0
87 self.inner_flow_label = 0x12345
88
Neale Ranns17dcec02019-01-09 21:22:20 -080089 self.auth_algo_vpp_id = (VppEnum.vl_api_ipsec_integ_alg_t.
Neale Ranns1091c4a2019-04-08 14:48:23 +000090 IPSEC_API_INTEG_ALG_SHA1_96)
91 self.auth_algo = 'HMAC-SHA1-96' # scapy name
Ole Troan64e978b2019-10-17 21:40:36 +020092 self.auth_key = b'C91KUR9GYMm5GfkEvNjX'
Neale Ranns17dcec02019-01-09 21:22:20 -080093
94 self.crypt_algo_vpp_id = (VppEnum.vl_api_ipsec_crypto_alg_t.
Neale Ranns4f33c802019-04-10 12:39:10 +000095 IPSEC_API_CRYPTO_ALG_AES_CBC_128)
Neale Ranns17dcec02019-01-09 21:22:20 -080096 self.crypt_algo = 'AES-CBC' # scapy name
Ole Troan64e978b2019-10-17 21:40:36 +020097 self.crypt_key = b'JPjyOWBeVEQiMe7h'
Neale Ranns80f6fd52019-04-16 02:41:34 +000098 self.salt = 0
Neale Ranns53f526b2019-02-25 14:32:02 +000099 self.flags = 0
100 self.nat_header = None
Neale Ranns041add72020-01-02 04:06:10 +0000101 self.tun_flags = (VppEnum.vl_api_tunnel_encap_decap_flags_t.
102 TUNNEL_API_ENCAP_DECAP_FLAG_NONE)
103 self.dscp = 0
Klement Sekera611864f2018-09-26 11:19:00 +0200104
105
Neale Ranns12989b52019-09-26 16:20:19 +0000106def mk_scapy_crypt_key(p):
Benoît Ganne490b9272021-01-22 18:03:09 +0100107 if p.crypt_algo in ("AES-GCM", "AES-CTR"):
Neale Ranns6afaae12019-07-17 15:07:14 +0000108 return p.crypt_key + struct.pack("!I", p.salt)
109 else:
110 return p.crypt_key
111
112
Neale Ranns2ac885c2019-03-20 18:24:43 +0000113def config_tun_params(p, encryption_type, tun_if):
114 ip_class_by_addr_type = {socket.AF_INET: IP, socket.AF_INET6: IPv6}
snaramre5d4b8912019-12-13 23:39:35 +0000115 esn_en = bool(p.flags & (VppEnum.vl_api_ipsec_sad_flags_t.
116 IPSEC_API_SAD_FLAG_USE_ESN))
Neale Rannsf3a66222020-01-02 05:04:00 +0000117 p.tun_dst = tun_if.remote_addr[p.addr_type]
118 p.tun_src = tun_if.local_addr[p.addr_type]
Neale Ranns12989b52019-09-26 16:20:19 +0000119 crypt_key = mk_scapy_crypt_key(p)
Neale Ranns2ac885c2019-03-20 18:24:43 +0000120 p.scapy_tun_sa = SecurityAssociation(
121 encryption_type, spi=p.vpp_tun_spi,
Neale Ranns80f6fd52019-04-16 02:41:34 +0000122 crypt_algo=p.crypt_algo,
123 crypt_key=crypt_key,
Neale Ranns2ac885c2019-03-20 18:24:43 +0000124 auth_algo=p.auth_algo, auth_key=p.auth_key,
125 tunnel_header=ip_class_by_addr_type[p.addr_type](
Neale Rannsf3a66222020-01-02 05:04:00 +0000126 src=p.tun_dst,
127 dst=p.tun_src),
Neale Ranns3833ffd2019-03-21 14:34:09 +0000128 nat_t_header=p.nat_header,
snaramre5d4b8912019-12-13 23:39:35 +0000129 esn_en=esn_en)
Neale Ranns2ac885c2019-03-20 18:24:43 +0000130 p.vpp_tun_sa = SecurityAssociation(
131 encryption_type, spi=p.scapy_tun_spi,
Neale Ranns80f6fd52019-04-16 02:41:34 +0000132 crypt_algo=p.crypt_algo,
133 crypt_key=crypt_key,
Neale Ranns2ac885c2019-03-20 18:24:43 +0000134 auth_algo=p.auth_algo, auth_key=p.auth_key,
135 tunnel_header=ip_class_by_addr_type[p.addr_type](
Neale Rannsf3a66222020-01-02 05:04:00 +0000136 dst=p.tun_dst,
137 src=p.tun_src),
Neale Ranns3833ffd2019-03-21 14:34:09 +0000138 nat_t_header=p.nat_header,
snaramre5d4b8912019-12-13 23:39:35 +0000139 esn_en=esn_en)
Neale Ranns2ac885c2019-03-20 18:24:43 +0000140
141
142def config_tra_params(p, encryption_type):
snaramre5d4b8912019-12-13 23:39:35 +0000143 esn_en = bool(p.flags & (VppEnum.vl_api_ipsec_sad_flags_t.
144 IPSEC_API_SAD_FLAG_USE_ESN))
Neale Ranns12989b52019-09-26 16:20:19 +0000145 crypt_key = mk_scapy_crypt_key(p)
Neale Ranns2ac885c2019-03-20 18:24:43 +0000146 p.scapy_tra_sa = SecurityAssociation(
147 encryption_type,
148 spi=p.vpp_tra_spi,
149 crypt_algo=p.crypt_algo,
Neale Ranns80f6fd52019-04-16 02:41:34 +0000150 crypt_key=crypt_key,
Neale Ranns2ac885c2019-03-20 18:24:43 +0000151 auth_algo=p.auth_algo,
152 auth_key=p.auth_key,
Neale Ranns3833ffd2019-03-21 14:34:09 +0000153 nat_t_header=p.nat_header,
snaramre5d4b8912019-12-13 23:39:35 +0000154 esn_en=esn_en)
Neale Ranns2ac885c2019-03-20 18:24:43 +0000155 p.vpp_tra_sa = SecurityAssociation(
156 encryption_type,
157 spi=p.scapy_tra_spi,
158 crypt_algo=p.crypt_algo,
Neale Ranns80f6fd52019-04-16 02:41:34 +0000159 crypt_key=crypt_key,
Neale Ranns2ac885c2019-03-20 18:24:43 +0000160 auth_algo=p.auth_algo,
161 auth_key=p.auth_key,
Neale Ranns3833ffd2019-03-21 14:34:09 +0000162 nat_t_header=p.nat_header,
snaramre5d4b8912019-12-13 23:39:35 +0000163 esn_en=esn_en)
Neale Ranns2ac885c2019-03-20 18:24:43 +0000164
165
Klement Sekera31da2e32018-06-24 22:49:55 +0200166class TemplateIpsec(VppTestCase):
167 """
168 TRANSPORT MODE:
169
170 ------ encrypt ---
171 |tra_if| <-------> |VPP|
172 ------ decrypt ---
173
174 TUNNEL MODE:
175
176 ------ encrypt --- plain ---
177 |tun_if| <------- |VPP| <------ |pg1|
178 ------ --- ---
179
180 ------ decrypt --- plain ---
181 |tun_if| -------> |VPP| ------> |pg1|
182 ------ --- ---
183 """
Neale Ranns4f33c802019-04-10 12:39:10 +0000184 tun_spd_id = 1
185 tra_spd_id = 2
Klement Sekera31da2e32018-06-24 22:49:55 +0200186
Neale Ranns8e4a89b2019-01-23 08:16:17 -0800187 def ipsec_select_backend(self):
Klement Sekerab4d30532018-11-08 13:00:02 +0100188 """ empty method to be overloaded when necessary """
189 pass
190
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -0700191 @classmethod
192 def setUpClass(cls):
193 super(TemplateIpsec, cls).setUpClass()
194
195 @classmethod
196 def tearDownClass(cls):
197 super(TemplateIpsec, cls).tearDownClass()
198
Neale Ranns3833ffd2019-03-21 14:34:09 +0000199 def setup_params(self):
Neale Ranns041add72020-01-02 04:06:10 +0000200 if not hasattr(self, 'ipv4_params'):
201 self.ipv4_params = IPsecIPv4Params()
202 if not hasattr(self, 'ipv6_params'):
203 self.ipv6_params = IPsecIPv6Params()
Neale Ranns8e4a89b2019-01-23 08:16:17 -0800204 self.params = {self.ipv4_params.addr_type: self.ipv4_params,
205 self.ipv6_params.addr_type: self.ipv6_params}
206
Neale Ranns4f33c802019-04-10 12:39:10 +0000207 def config_interfaces(self):
Neale Ranns8e4a89b2019-01-23 08:16:17 -0800208 self.create_pg_interfaces(range(3))
209 self.interfaces = list(self.pg_interfaces)
210 for i in self.interfaces:
Klement Sekera31da2e32018-06-24 22:49:55 +0200211 i.admin_up()
212 i.config_ip4()
213 i.resolve_arp()
Klement Sekera611864f2018-09-26 11:19:00 +0200214 i.config_ip6()
215 i.resolve_ndp()
Neale Ranns4f33c802019-04-10 12:39:10 +0000216
217 def setUp(self):
218 super(TemplateIpsec, self).setUp()
219
220 self.setup_params()
221
222 self.vpp_esp_protocol = (VppEnum.vl_api_ipsec_proto_t.
223 IPSEC_API_PROTO_ESP)
224 self.vpp_ah_protocol = (VppEnum.vl_api_ipsec_proto_t.
225 IPSEC_API_PROTO_AH)
226
227 self.config_interfaces()
Paul Vinciguerra90cf21b2019-03-13 09:23:05 -0700228
Neale Ranns8e4a89b2019-01-23 08:16:17 -0800229 self.ipsec_select_backend()
Klement Sekera31da2e32018-06-24 22:49:55 +0200230
Neale Ranns4f33c802019-04-10 12:39:10 +0000231 def unconfig_interfaces(self):
Neale Ranns8e4a89b2019-01-23 08:16:17 -0800232 for i in self.interfaces:
233 i.admin_down()
234 i.unconfig_ip4()
235 i.unconfig_ip6()
236
Neale Ranns4f33c802019-04-10 12:39:10 +0000237 def tearDown(self):
238 super(TemplateIpsec, self).tearDown()
239
240 self.unconfig_interfaces()
241
Paul Vinciguerra90cf21b2019-03-13 09:23:05 -0700242 def show_commands_at_teardown(self):
243 self.logger.info(self.vapi.cli("show hardware"))
Klement Sekera31da2e32018-06-24 22:49:55 +0200244
Neale Ranns28287212019-12-16 00:53:11 +0000245 def gen_encrypt_pkts(self, p, sa, sw_intf, src, dst, count=1,
Neale Rannsd7603d92019-03-28 08:56:10 +0000246 payload_size=54):
Klement Sekera31da2e32018-06-24 22:49:55 +0200247 return [Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac) /
Neale Rannsd7603d92019-03-28 08:56:10 +0000248 sa.encrypt(IP(src=src, dst=dst) /
Ole Troan8b76c232019-10-21 20:55:13 +0200249 ICMP() / Raw(b'X' * payload_size))
Klement Sekera31da2e32018-06-24 22:49:55 +0200250 for i in range(count)]
251
Neale Ranns28287212019-12-16 00:53:11 +0000252 def gen_encrypt_pkts6(self, p, sa, sw_intf, src, dst, count=1,
Neale Rannsd7603d92019-03-28 08:56:10 +0000253 payload_size=54):
Klement Sekera611864f2018-09-26 11:19:00 +0200254 return [Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac) /
Neale Ranns9ec846c2021-02-09 14:04:02 +0000255 sa.encrypt(IPv6(src=src, dst=dst,
256 hlim=p.inner_hop_limit,
257 fl=p.inner_flow_label) /
Neale Rannsd7603d92019-03-28 08:56:10 +0000258 ICMPv6EchoRequest(id=0, seq=1,
259 data='X' * payload_size))
Klement Sekera611864f2018-09-26 11:19:00 +0200260 for i in range(count)]
261
Neale Rannsd7603d92019-03-28 08:56:10 +0000262 def gen_pkts(self, sw_intf, src, dst, count=1, payload_size=54):
Klement Sekera31da2e32018-06-24 22:49:55 +0200263 return [Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac) /
Ole Troan8b76c232019-10-21 20:55:13 +0200264 IP(src=src, dst=dst) / ICMP() / Raw(b'X' * payload_size)
Klement Sekera31da2e32018-06-24 22:49:55 +0200265 for i in range(count)]
266
Neale Ranns9ec846c2021-02-09 14:04:02 +0000267 def gen_pkts6(self, p, sw_intf, src, dst, count=1, payload_size=54):
Klement Sekera611864f2018-09-26 11:19:00 +0200268 return [Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac) /
Neale Ranns9ec846c2021-02-09 14:04:02 +0000269 IPv6(src=src, dst=dst,
270 hlim=p.inner_hop_limit, fl=p.inner_flow_label) /
Neale Rannsd7603d92019-03-28 08:56:10 +0000271 ICMPv6EchoRequest(id=0, seq=1, data='X' * payload_size)
Klement Sekera611864f2018-09-26 11:19:00 +0200272 for i in range(count)]
273
Klement Sekera31da2e32018-06-24 22:49:55 +0200274
Neale Ranns4f33c802019-04-10 12:39:10 +0000275class IpsecTcp(object):
276 def verify_tcp_checksum(self):
Klement Sekera31da2e32018-06-24 22:49:55 +0200277 self.vapi.cli("test http server")
Klement Sekera611864f2018-09-26 11:19:00 +0200278 p = self.params[socket.AF_INET]
Klement Sekera31da2e32018-06-24 22:49:55 +0200279 send = (Ether(src=self.tun_if.remote_mac, dst=self.tun_if.local_mac) /
Neale Ranns2ac885c2019-03-20 18:24:43 +0000280 p.scapy_tun_sa.encrypt(IP(src=p.remote_tun_if_host,
281 dst=self.tun_if.local_ip4) /
282 TCP(flags='S', dport=80)))
Klement Sekera31da2e32018-06-24 22:49:55 +0200283 self.logger.debug(ppp("Sending packet:", send))
Klement Sekera611864f2018-09-26 11:19:00 +0200284 recv = self.send_and_expect(self.tun_if, [send], self.tun_if)
Klement Sekera31da2e32018-06-24 22:49:55 +0200285 recv = recv[0]
Neale Ranns2ac885c2019-03-20 18:24:43 +0000286 decrypted = p.vpp_tun_sa.decrypt(recv[IP])
Klement Sekera31da2e32018-06-24 22:49:55 +0200287 self.assert_packet_checksums_valid(decrypted)
288
289
Neale Ranns4f33c802019-04-10 12:39:10 +0000290class IpsecTcpTests(IpsecTcp):
291 def test_tcp_checksum(self):
292 """ verify checksum correctness for vpp generated packets """
293 self.verify_tcp_checksum()
294
295
296class IpsecTra4(object):
297 """ verify methods for Transport v4 """
Neale Ranns6afaae12019-07-17 15:07:14 +0000298 def verify_tra_anti_replay(self):
Neale Rannsde847272018-11-28 01:38:34 -0800299 p = self.params[socket.AF_INET]
snaramre5d4b8912019-12-13 23:39:35 +0000300 esn_en = p.vpp_tra_sa.esn_en
Neale Rannsde847272018-11-28 01:38:34 -0800301
Neale Ranns6afaae12019-07-17 15:07:14 +0000302 seq_cycle_node_name = ('/err/%s/sequence number cycled' %
303 self.tra4_encrypt_node_name)
304 replay_node_name = ('/err/%s/SA replayed packet' %
305 self.tra4_decrypt_node_name)
306 if ESP == self.encryption_type and p.crypt_algo == "AES-GCM":
307 hash_failed_node_name = ('/err/%s/ESP decryption failed' %
308 self.tra4_decrypt_node_name)
309 else:
310 hash_failed_node_name = ('/err/%s/Integrity check failed' %
311 self.tra4_decrypt_node_name)
312 replay_count = self.statistics.get_err_counter(replay_node_name)
313 hash_failed_count = self.statistics.get_err_counter(
314 hash_failed_node_name)
315 seq_cycle_count = self.statistics.get_err_counter(seq_cycle_node_name)
Neale Rannsde847272018-11-28 01:38:34 -0800316
Neale Ranns6afaae12019-07-17 15:07:14 +0000317 if ESP == self.encryption_type:
318 undersize_node_name = ('/err/%s/undersized packet' %
319 self.tra4_decrypt_node_name)
320 undersize_count = self.statistics.get_err_counter(
321 undersize_node_name)
322
323 #
324 # send packets with seq numbers 1->34
325 # this means the window size is still in Case B (see RFC4303
326 # Appendix A)
327 #
328 # for reasons i haven't investigated Scapy won't create a packet with
329 # seq_num=0
330 #
331 pkts = [(Ether(src=self.tra_if.remote_mac,
332 dst=self.tra_if.local_mac) /
333 p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
334 dst=self.tra_if.local_ip4) /
335 ICMP(),
336 seq_num=seq))
337 for seq in range(1, 34)]
338 recv_pkts = self.send_and_expect(self.tra_if, pkts, self.tra_if)
339
340 # replayed packets are dropped
341 self.send_and_assert_no_replies(self.tra_if, pkts)
342 replay_count += len(pkts)
343 self.assert_error_counter_equal(replay_node_name, replay_count)
344
345 #
Neale Ranns3b9374f2019-08-01 04:45:15 -0700346 # now send a batch of packets all with the same sequence number
347 # the first packet in the batch is legitimate, the rest bogus
348 #
349 pkts = (Ether(src=self.tra_if.remote_mac,
350 dst=self.tra_if.local_mac) /
351 p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
352 dst=self.tra_if.local_ip4) /
353 ICMP(),
354 seq_num=35))
355 recv_pkts = self.send_and_expect(self.tra_if, pkts * 8,
356 self.tra_if, n_rx=1)
357 replay_count += 7
358 self.assert_error_counter_equal(replay_node_name, replay_count)
359
360 #
Neale Ranns6afaae12019-07-17 15:07:14 +0000361 # now move the window over to 257 (more than one byte) and into Case A
362 #
Neale Rannsde847272018-11-28 01:38:34 -0800363 pkt = (Ether(src=self.tra_if.remote_mac,
364 dst=self.tra_if.local_mac) /
365 p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
366 dst=self.tra_if.local_ip4) /
367 ICMP(),
Neale Ranns6afaae12019-07-17 15:07:14 +0000368 seq_num=257))
Neale Rannsde847272018-11-28 01:38:34 -0800369 recv_pkts = self.send_and_expect(self.tra_if, [pkt], self.tra_if)
370
Neale Ranns3833ffd2019-03-21 14:34:09 +0000371 # replayed packets are dropped
372 self.send_and_assert_no_replies(self.tra_if, pkt * 3)
Neale Ranns6afaae12019-07-17 15:07:14 +0000373 replay_count += 3
374 self.assert_error_counter_equal(replay_node_name, replay_count)
Neale Ranns3833ffd2019-03-21 14:34:09 +0000375
Neale Rannsde847272018-11-28 01:38:34 -0800376 # the window size is 64 packets
377 # in window are still accepted
378 pkt = (Ether(src=self.tra_if.remote_mac,
379 dst=self.tra_if.local_mac) /
380 p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
381 dst=self.tra_if.local_ip4) /
382 ICMP(),
Neale Ranns6afaae12019-07-17 15:07:14 +0000383 seq_num=200))
Neale Rannsde847272018-11-28 01:38:34 -0800384 recv_pkts = self.send_and_expect(self.tra_if, [pkt], self.tra_if)
385
Neale Rannsde847272018-11-28 01:38:34 -0800386 # a packet that does not decrypt does not move the window forward
387 bogus_sa = SecurityAssociation(self.encryption_type,
Damjan Mariona829b132019-04-24 23:39:16 +0200388 p.vpp_tra_spi,
389 crypt_algo=p.crypt_algo,
Neale Ranns12989b52019-09-26 16:20:19 +0000390 crypt_key=mk_scapy_crypt_key(p)[::-1],
Damjan Mariona829b132019-04-24 23:39:16 +0200391 auth_algo=p.auth_algo,
392 auth_key=p.auth_key[::-1])
Neale Rannsde847272018-11-28 01:38:34 -0800393 pkt = (Ether(src=self.tra_if.remote_mac,
394 dst=self.tra_if.local_mac) /
395 bogus_sa.encrypt(IP(src=self.tra_if.remote_ip4,
396 dst=self.tra_if.local_ip4) /
397 ICMP(),
398 seq_num=350))
399 self.send_and_assert_no_replies(self.tra_if, pkt * 17)
400
Neale Ranns6afaae12019-07-17 15:07:14 +0000401 hash_failed_count += 17
402 self.assert_error_counter_equal(hash_failed_node_name,
403 hash_failed_count)
Neale Rannsde847272018-11-28 01:38:34 -0800404
Damjan Mariona829b132019-04-24 23:39:16 +0200405 # a malformed 'runt' packet
406 # created by a mis-constructed SA
Neale Ranns2cdcd0c2019-08-27 12:26:14 +0000407 if (ESP == self.encryption_type and p.crypt_algo != "NULL"):
Damjan Mariona829b132019-04-24 23:39:16 +0200408 bogus_sa = SecurityAssociation(self.encryption_type,
409 p.vpp_tra_spi)
410 pkt = (Ether(src=self.tra_if.remote_mac,
411 dst=self.tra_if.local_mac) /
412 bogus_sa.encrypt(IP(src=self.tra_if.remote_ip4,
413 dst=self.tra_if.local_ip4) /
414 ICMP(),
415 seq_num=350))
416 self.send_and_assert_no_replies(self.tra_if, pkt * 17)
417
Neale Ranns6afaae12019-07-17 15:07:14 +0000418 undersize_count += 17
419 self.assert_error_counter_equal(undersize_node_name,
420 undersize_count)
Damjan Mariona829b132019-04-24 23:39:16 +0200421
Neale Rannsde847272018-11-28 01:38:34 -0800422 # which we can determine since this packet is still in the window
423 pkt = (Ether(src=self.tra_if.remote_mac,
424 dst=self.tra_if.local_mac) /
425 p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
426 dst=self.tra_if.local_ip4) /
427 ICMP(),
428 seq_num=234))
Klement Sekera14d7e902018-12-10 13:46:09 +0100429 self.send_and_expect(self.tra_if, [pkt], self.tra_if)
Neale Rannsde847272018-11-28 01:38:34 -0800430
Neale Ranns6afaae12019-07-17 15:07:14 +0000431 #
Neale Ranns3833ffd2019-03-21 14:34:09 +0000432 # out of window are dropped
Neale Ranns6afaae12019-07-17 15:07:14 +0000433 # this is Case B. So VPP will consider this to be a high seq num wrap
434 # and so the decrypt attempt will fail
435 #
Neale Ranns3833ffd2019-03-21 14:34:09 +0000436 pkt = (Ether(src=self.tra_if.remote_mac,
437 dst=self.tra_if.local_mac) /
438 p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
439 dst=self.tra_if.local_ip4) /
440 ICMP(),
441 seq_num=17))
442 self.send_and_assert_no_replies(self.tra_if, pkt * 17)
Neale Ranns00a44202019-03-21 16:36:28 +0000443
snaramre5d4b8912019-12-13 23:39:35 +0000444 if esn_en:
Neale Ranns3833ffd2019-03-21 14:34:09 +0000445 # an out of window error with ESN looks like a high sequence
446 # wrap. but since it isn't then the verify will fail.
Neale Ranns6afaae12019-07-17 15:07:14 +0000447 hash_failed_count += 17
448 self.assert_error_counter_equal(hash_failed_node_name,
449 hash_failed_count)
Neale Ranns3833ffd2019-03-21 14:34:09 +0000450
451 else:
Neale Ranns6afaae12019-07-17 15:07:14 +0000452 replay_count += 17
453 self.assert_error_counter_equal(replay_node_name,
454 replay_count)
Neale Ranns3833ffd2019-03-21 14:34:09 +0000455
Neale Ranns6afaae12019-07-17 15:07:14 +0000456 # valid packet moves the window over to 258
Neale Ranns00a44202019-03-21 16:36:28 +0000457 pkt = (Ether(src=self.tra_if.remote_mac,
458 dst=self.tra_if.local_mac) /
459 p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
460 dst=self.tra_if.local_ip4) /
461 ICMP(),
Neale Ranns6afaae12019-07-17 15:07:14 +0000462 seq_num=258))
Neale Ranns3833ffd2019-03-21 14:34:09 +0000463 rx = self.send_and_expect(self.tra_if, [pkt], self.tra_if)
464 decrypted = p.vpp_tra_sa.decrypt(rx[0][IP])
465
Neale Ranns6afaae12019-07-17 15:07:14 +0000466 #
467 # move VPP's SA TX seq-num to just before the seq-number wrap.
468 # then fire in a packet that VPP should drop on TX because it
469 # causes the TX seq number to wrap; unless we're using extened sequence
470 # numbers.
471 #
Neale Ranns3833ffd2019-03-21 14:34:09 +0000472 self.vapi.cli("test ipsec sa %d seq 0xffffffff" % p.scapy_tra_sa_id)
Neale Ranns6afaae12019-07-17 15:07:14 +0000473 self.logger.info(self.vapi.ppcli("show ipsec sa 0"))
474 self.logger.info(self.vapi.ppcli("show ipsec sa 1"))
Neale Ranns3833ffd2019-03-21 14:34:09 +0000475
Neale Ranns6afaae12019-07-17 15:07:14 +0000476 pkts = [(Ether(src=self.tra_if.remote_mac,
477 dst=self.tra_if.local_mac) /
478 p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
479 dst=self.tra_if.local_ip4) /
480 ICMP(),
481 seq_num=seq))
482 for seq in range(259, 280)]
Neale Ranns3833ffd2019-03-21 14:34:09 +0000483
snaramre5d4b8912019-12-13 23:39:35 +0000484 if esn_en:
Neale Ranns6afaae12019-07-17 15:07:14 +0000485 rxs = self.send_and_expect(self.tra_if, pkts, self.tra_if)
Neale Ranns3833ffd2019-03-21 14:34:09 +0000486
Neale Ranns6afaae12019-07-17 15:07:14 +0000487 #
488 # in order for scapy to decrypt its SA's high order number needs
489 # to wrap
490 #
491 p.vpp_tra_sa.seq_num = 0x100000000
492 for rx in rxs:
493 decrypted = p.vpp_tra_sa.decrypt(rx[0][IP])
494
495 #
496 # wrap scapy's TX high sequence number. VPP is in case B, so it
497 # will consider this a high seq wrap also.
498 # The low seq num we set it to will place VPP's RX window in Case A
499 #
Neale Ranns3833ffd2019-03-21 14:34:09 +0000500 p.scapy_tra_sa.seq_num = 0x100000005
501 pkt = (Ether(src=self.tra_if.remote_mac,
502 dst=self.tra_if.local_mac) /
503 p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
504 dst=self.tra_if.local_ip4) /
505 ICMP(),
506 seq_num=0x100000005))
507 rx = self.send_and_expect(self.tra_if, [pkt], self.tra_if)
Neale Ranns3833ffd2019-03-21 14:34:09 +0000508 decrypted = p.vpp_tra_sa.decrypt(rx[0][IP])
Neale Ranns6afaae12019-07-17 15:07:14 +0000509
510 #
511 # A packet that has seq num between (2^32-64) and 5 is within
512 # the window
513 #
514 p.scapy_tra_sa.seq_num = 0xfffffffd
515 pkt = (Ether(src=self.tra_if.remote_mac,
516 dst=self.tra_if.local_mac) /
517 p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
518 dst=self.tra_if.local_ip4) /
519 ICMP(),
520 seq_num=0xfffffffd))
521 rx = self.send_and_expect(self.tra_if, [pkt], self.tra_if)
522 decrypted = p.vpp_tra_sa.decrypt(rx[0][IP])
523
524 #
525 # While in case A we cannot wrap the high sequence number again
526 # becuase VPP will consider this packet to be one that moves the
527 # window forward
528 #
529 pkt = (Ether(src=self.tra_if.remote_mac,
530 dst=self.tra_if.local_mac) /
531 p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
532 dst=self.tra_if.local_ip4) /
533 ICMP(),
534 seq_num=0x200000999))
535 self.send_and_assert_no_replies(self.tra_if, [pkt], self.tra_if)
536
537 hash_failed_count += 1
538 self.assert_error_counter_equal(hash_failed_node_name,
539 hash_failed_count)
540
541 #
542 # but if we move the wondow forward to case B, then we can wrap
543 # again
544 #
545 p.scapy_tra_sa.seq_num = 0x100000555
546 pkt = (Ether(src=self.tra_if.remote_mac,
547 dst=self.tra_if.local_mac) /
548 p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
549 dst=self.tra_if.local_ip4) /
550 ICMP(),
551 seq_num=0x100000555))
552 rx = self.send_and_expect(self.tra_if, [pkt], self.tra_if)
553 decrypted = p.vpp_tra_sa.decrypt(rx[0][IP])
554
555 p.scapy_tra_sa.seq_num = 0x200000444
556 pkt = (Ether(src=self.tra_if.remote_mac,
557 dst=self.tra_if.local_mac) /
558 p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
559 dst=self.tra_if.local_ip4) /
560 ICMP(),
561 seq_num=0x200000444))
562 rx = self.send_and_expect(self.tra_if, [pkt], self.tra_if)
563 decrypted = p.vpp_tra_sa.decrypt(rx[0][IP])
564
Neale Ranns3833ffd2019-03-21 14:34:09 +0000565 else:
Neale Ranns6afaae12019-07-17 15:07:14 +0000566 #
567 # without ESN TX sequence numbers can't wrap and packets are
568 # dropped from here on out.
569 #
570 self.send_and_assert_no_replies(self.tra_if, pkts)
571 seq_cycle_count += len(pkts)
572 self.assert_error_counter_equal(seq_cycle_node_name,
573 seq_cycle_count)
Neale Ranns00a44202019-03-21 16:36:28 +0000574
Neale Rannsde847272018-11-28 01:38:34 -0800575 # move the security-associations seq number on to the last we used
Neale Ranns00a44202019-03-21 16:36:28 +0000576 self.vapi.cli("test ipsec sa %d seq 0x15f" % p.scapy_tra_sa_id)
Neale Rannsde847272018-11-28 01:38:34 -0800577 p.scapy_tra_sa.seq_num = 351
578 p.vpp_tra_sa.seq_num = 351
579
Filip Tehlarefcad1a2020-02-04 09:36:04 +0000580 def verify_tra_basic4(self, count=1, payload_size=54):
Klement Sekera31da2e32018-06-24 22:49:55 +0200581 """ ipsec v4 transport basic test """
Klement Sekera10d066e2018-11-13 11:12:57 +0100582 self.vapi.cli("clear errors")
Neale Ranns6afaae12019-07-17 15:07:14 +0000583 self.vapi.cli("clear ipsec sa")
Klement Sekera31da2e32018-06-24 22:49:55 +0200584 try:
Klement Sekera611864f2018-09-26 11:19:00 +0200585 p = self.params[socket.AF_INET]
Neale Ranns28287212019-12-16 00:53:11 +0000586 send_pkts = self.gen_encrypt_pkts(p, p.scapy_tra_sa, self.tra_if,
Klement Sekera31da2e32018-06-24 22:49:55 +0200587 src=self.tra_if.remote_ip4,
588 dst=self.tra_if.local_ip4,
Filip Tehlarefcad1a2020-02-04 09:36:04 +0000589 count=count,
590 payload_size=payload_size)
Klement Sekera31da2e32018-06-24 22:49:55 +0200591 recv_pkts = self.send_and_expect(self.tra_if, send_pkts,
Klement Sekera611864f2018-09-26 11:19:00 +0200592 self.tra_if)
Neale Rannsde847272018-11-28 01:38:34 -0800593 for rx in recv_pkts:
Neale Ranns1b582b82019-04-18 19:49:13 -0700594 self.assertEqual(len(rx) - len(Ether()), rx[IP].len)
595 self.assert_packet_checksums_valid(rx)
Klement Sekera611864f2018-09-26 11:19:00 +0200596 try:
Neale Rannsde847272018-11-28 01:38:34 -0800597 decrypted = p.vpp_tra_sa.decrypt(rx[IP])
Klement Sekera611864f2018-09-26 11:19:00 +0200598 self.assert_packet_checksums_valid(decrypted)
599 except:
Neale Rannsde847272018-11-28 01:38:34 -0800600 self.logger.debug(ppp("Unexpected packet:", rx))
Klement Sekera611864f2018-09-26 11:19:00 +0200601 raise
Klement Sekera31da2e32018-06-24 22:49:55 +0200602 finally:
603 self.logger.info(self.vapi.ppcli("show error"))
Paul Vinciguerra9673e3e2019-05-10 20:41:08 -0400604 self.logger.info(self.vapi.ppcli("show ipsec all"))
Klement Sekera31da2e32018-06-24 22:49:55 +0200605
Neale Rannseba31ec2019-02-17 18:04:27 +0000606 pkts = p.tra_sa_in.get_stats()['packets']
607 self.assertEqual(pkts, count,
608 "incorrect SA in counts: expected %d != %d" %
609 (count, pkts))
610 pkts = p.tra_sa_out.get_stats()['packets']
611 self.assertEqual(pkts, count,
612 "incorrect SA out counts: expected %d != %d" %
613 (count, pkts))
614
Klement Sekera10d066e2018-11-13 11:12:57 +0100615 self.assert_packet_counter_equal(self.tra4_encrypt_node_name, count)
616 self.assert_packet_counter_equal(self.tra4_decrypt_node_name, count)
617
Neale Ranns4f33c802019-04-10 12:39:10 +0000618
619class IpsecTra4Tests(IpsecTra4):
620 """ UT test methods for Transport v4 """
621 def test_tra_anti_replay(self):
Paul Vinciguerra6e20e032019-12-27 00:19:23 -0500622 """ ipsec v4 transport anti-replay test """
Neale Ranns6afaae12019-07-17 15:07:14 +0000623 self.verify_tra_anti_replay()
Neale Ranns4f33c802019-04-10 12:39:10 +0000624
625 def test_tra_basic(self, count=1):
626 """ ipsec v4 transport basic test """
627 self.verify_tra_basic4(count=1)
628
Klement Sekera31da2e32018-06-24 22:49:55 +0200629 def test_tra_burst(self):
630 """ ipsec v4 transport burst test """
Neale Ranns4f33c802019-04-10 12:39:10 +0000631 self.verify_tra_basic4(count=257)
Klement Sekera611864f2018-09-26 11:19:00 +0200632
Neale Ranns53f526b2019-02-25 14:32:02 +0000633
Neale Ranns4f33c802019-04-10 12:39:10 +0000634class IpsecTra6(object):
635 """ verify methods for Transport v6 """
Filip Tehlarefcad1a2020-02-04 09:36:04 +0000636 def verify_tra_basic6(self, count=1, payload_size=54):
Klement Sekera10d066e2018-11-13 11:12:57 +0100637 self.vapi.cli("clear errors")
Filip Tehlarefcad1a2020-02-04 09:36:04 +0000638 self.vapi.cli("clear ipsec sa")
Klement Sekera31da2e32018-06-24 22:49:55 +0200639 try:
Klement Sekera611864f2018-09-26 11:19:00 +0200640 p = self.params[socket.AF_INET6]
Neale Ranns28287212019-12-16 00:53:11 +0000641 send_pkts = self.gen_encrypt_pkts6(p, p.scapy_tra_sa, self.tra_if,
Klement Sekera611864f2018-09-26 11:19:00 +0200642 src=self.tra_if.remote_ip6,
643 dst=self.tra_if.local_ip6,
Filip Tehlarefcad1a2020-02-04 09:36:04 +0000644 count=count,
645 payload_size=payload_size)
Klement Sekera611864f2018-09-26 11:19:00 +0200646 recv_pkts = self.send_and_expect(self.tra_if, send_pkts,
647 self.tra_if)
Neale Rannsde847272018-11-28 01:38:34 -0800648 for rx in recv_pkts:
Neale Rannsd207fd72019-04-18 17:18:12 -0700649 self.assertEqual(len(rx) - len(Ether()) - len(IPv6()),
650 rx[IPv6].plen)
Klement Sekera611864f2018-09-26 11:19:00 +0200651 try:
Neale Rannsde847272018-11-28 01:38:34 -0800652 decrypted = p.vpp_tra_sa.decrypt(rx[IPv6])
Klement Sekera611864f2018-09-26 11:19:00 +0200653 self.assert_packet_checksums_valid(decrypted)
654 except:
Neale Rannsde847272018-11-28 01:38:34 -0800655 self.logger.debug(ppp("Unexpected packet:", rx))
Klement Sekera611864f2018-09-26 11:19:00 +0200656 raise
Klement Sekera31da2e32018-06-24 22:49:55 +0200657 finally:
658 self.logger.info(self.vapi.ppcli("show error"))
Paul Vinciguerra9673e3e2019-05-10 20:41:08 -0400659 self.logger.info(self.vapi.ppcli("show ipsec all"))
Klement Sekera31da2e32018-06-24 22:49:55 +0200660
Neale Rannseba31ec2019-02-17 18:04:27 +0000661 pkts = p.tra_sa_in.get_stats()['packets']
662 self.assertEqual(pkts, count,
663 "incorrect SA in counts: expected %d != %d" %
664 (count, pkts))
665 pkts = p.tra_sa_out.get_stats()['packets']
666 self.assertEqual(pkts, count,
667 "incorrect SA out counts: expected %d != %d" %
668 (count, pkts))
Klement Sekera10d066e2018-11-13 11:12:57 +0100669 self.assert_packet_counter_equal(self.tra6_encrypt_node_name, count)
670 self.assert_packet_counter_equal(self.tra6_decrypt_node_name, count)
671
Neale Ranns02950402019-12-20 00:54:57 +0000672 def gen_encrypt_pkts_ext_hdrs6(self, sa, sw_intf, src, dst, count=1,
673 payload_size=54):
674 return [Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac) /
675 sa.encrypt(IPv6(src=src, dst=dst) /
676 ICMPv6EchoRequest(id=0, seq=1,
677 data='X' * payload_size))
678 for i in range(count)]
679
680 def gen_pkts_ext_hdrs6(self, sw_intf, src, dst, count=1, payload_size=54):
681 return [Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac) /
682 IPv6(src=src, dst=dst) /
683 IPv6ExtHdrHopByHop() /
684 IPv6ExtHdrFragment(id=2, offset=200) /
685 Raw(b'\xff' * 200)
686 for i in range(count)]
687
688 def verify_tra_encrypted6(self, p, sa, rxs):
689 decrypted = []
690 for rx in rxs:
691 self.assert_packet_checksums_valid(rx)
692 try:
693 decrypt_pkt = p.vpp_tra_sa.decrypt(rx[IPv6])
694 decrypted.append(decrypt_pkt)
695 self.assert_equal(decrypt_pkt.src, self.tra_if.local_ip6)
696 self.assert_equal(decrypt_pkt.dst, self.tra_if.remote_ip6)
697 except:
698 self.logger.debug(ppp("Unexpected packet:", rx))
699 try:
700 self.logger.debug(ppp("Decrypted packet:", decrypt_pkt))
701 except:
702 pass
703 raise
704 return decrypted
705
706 def verify_tra_66_ext_hdrs(self, p):
707 count = 63
708
709 #
710 # check we can decrypt with options
711 #
712 tx = self.gen_encrypt_pkts_ext_hdrs6(p.scapy_tra_sa, self.tra_if,
713 src=self.tra_if.remote_ip6,
714 dst=self.tra_if.local_ip6,
715 count=count)
716 self.send_and_expect(self.tra_if, tx, self.tra_if)
717
718 #
719 # injecting a packet from ourselves to be routed of box is a hack
720 # but it matches an outbout policy, alors je ne regrette rien
721 #
722
723 # one extension before ESP
724 tx = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
725 IPv6(src=self.tra_if.local_ip6,
726 dst=self.tra_if.remote_ip6) /
727 IPv6ExtHdrFragment(id=2, offset=200) /
728 Raw(b'\xff' * 200))
729
730 rxs = self.send_and_expect(self.pg2, [tx], self.tra_if)
731 dcs = self.verify_tra_encrypted6(p, p.vpp_tra_sa, rxs)
732
733 for dc in dcs:
734 # for reasons i'm not going to investigate scapy does not
735 # created the correct headers after decrypt. but reparsing
736 # the ipv6 packet fixes it
737 dc = IPv6(raw(dc[IPv6]))
738 self.assert_equal(dc[IPv6ExtHdrFragment].id, 2)
739
740 # two extensions before ESP
741 tx = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
742 IPv6(src=self.tra_if.local_ip6,
743 dst=self.tra_if.remote_ip6) /
744 IPv6ExtHdrHopByHop() /
745 IPv6ExtHdrFragment(id=2, offset=200) /
746 Raw(b'\xff' * 200))
747
748 rxs = self.send_and_expect(self.pg2, [tx], self.tra_if)
749 dcs = self.verify_tra_encrypted6(p, p.vpp_tra_sa, rxs)
750
751 for dc in dcs:
752 dc = IPv6(raw(dc[IPv6]))
753 self.assertTrue(dc[IPv6ExtHdrHopByHop])
754 self.assert_equal(dc[IPv6ExtHdrFragment].id, 2)
755
756 # two extensions before ESP, one after
757 tx = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
758 IPv6(src=self.tra_if.local_ip6,
759 dst=self.tra_if.remote_ip6) /
760 IPv6ExtHdrHopByHop() /
761 IPv6ExtHdrFragment(id=2, offset=200) /
762 IPv6ExtHdrDestOpt() /
763 Raw(b'\xff' * 200))
764
765 rxs = self.send_and_expect(self.pg2, [tx], self.tra_if)
766 dcs = self.verify_tra_encrypted6(p, p.vpp_tra_sa, rxs)
767
768 for dc in dcs:
769 dc = IPv6(raw(dc[IPv6]))
770 self.assertTrue(dc[IPv6ExtHdrDestOpt])
771 self.assertTrue(dc[IPv6ExtHdrHopByHop])
772 self.assert_equal(dc[IPv6ExtHdrFragment].id, 2)
773
Neale Ranns4f33c802019-04-10 12:39:10 +0000774
775class IpsecTra6Tests(IpsecTra6):
776 """ UT test methods for Transport v6 """
777 def test_tra_basic6(self):
778 """ ipsec v6 transport basic test """
779 self.verify_tra_basic6(count=1)
780
Klement Sekera611864f2018-09-26 11:19:00 +0200781 def test_tra_burst6(self):
782 """ ipsec v6 transport burst test """
Neale Ranns4f33c802019-04-10 12:39:10 +0000783 self.verify_tra_basic6(count=257)
Klement Sekera31da2e32018-06-24 22:49:55 +0200784
Klement Sekera611864f2018-09-26 11:19:00 +0200785
Neale Ranns02950402019-12-20 00:54:57 +0000786class IpsecTra6ExtTests(IpsecTra6):
787 def test_tra_ext_hdrs_66(self):
788 """ ipsec 6o6 tra extension headers test """
789 self.verify_tra_66_ext_hdrs(self.params[socket.AF_INET6])
790
791
Neale Ranns53f526b2019-02-25 14:32:02 +0000792class IpsecTra46Tests(IpsecTra4Tests, IpsecTra6Tests):
Neale Ranns4f33c802019-04-10 12:39:10 +0000793 """ UT test methods for Transport v6 and v4"""
Neale Ranns53f526b2019-02-25 14:32:02 +0000794 pass
795
796
Neale Ranns2ac885c2019-03-20 18:24:43 +0000797class IpsecTun4(object):
Neale Ranns4f33c802019-04-10 12:39:10 +0000798 """ verify methods for Tunnel v4 """
Neale Ranns4a56f4e2019-12-23 04:10:25 +0000799 def verify_counters4(self, p, count, n_frags=None, worker=None):
Klement Sekera6aa58b72019-05-16 14:34:55 +0200800 if not n_frags:
801 n_frags = count
Neale Ranns987aea82019-03-27 13:40:35 +0000802 if (hasattr(p, "spd_policy_in_any")):
Neale Ranns4a56f4e2019-12-23 04:10:25 +0000803 pkts = p.spd_policy_in_any.get_stats(worker)['packets']
Neale Ranns987aea82019-03-27 13:40:35 +0000804 self.assertEqual(pkts, count,
805 "incorrect SPD any policy: expected %d != %d" %
806 (count, pkts))
807
808 if (hasattr(p, "tun_sa_in")):
Neale Ranns4a56f4e2019-12-23 04:10:25 +0000809 pkts = p.tun_sa_in.get_stats(worker)['packets']
Neale Ranns987aea82019-03-27 13:40:35 +0000810 self.assertEqual(pkts, count,
811 "incorrect SA in counts: expected %d != %d" %
812 (count, pkts))
Neale Ranns4a56f4e2019-12-23 04:10:25 +0000813 pkts = p.tun_sa_out.get_stats(worker)['packets']
Neale Rannsa9e27742020-12-23 16:22:28 +0000814 self.assertEqual(pkts, n_frags,
Neale Ranns987aea82019-03-27 13:40:35 +0000815 "incorrect SA out counts: expected %d != %d" %
816 (count, pkts))
817
Klement Sekera6aa58b72019-05-16 14:34:55 +0200818 self.assert_packet_counter_equal(self.tun4_encrypt_node_name, n_frags)
Neale Ranns987aea82019-03-27 13:40:35 +0000819 self.assert_packet_counter_equal(self.tun4_decrypt_node_name, count)
820
Neale Rannsf05e7322019-03-29 20:23:58 +0000821 def verify_decrypted(self, p, rxs):
822 for rx in rxs:
823 self.assert_equal(rx[IP].src, p.remote_tun_if_host)
824 self.assert_equal(rx[IP].dst, self.pg1.remote_ip4)
825 self.assert_packet_checksums_valid(rx)
826
Christian Hoppsfb7e7ed2019-11-03 07:02:15 -0500827 def verify_esp_padding(self, sa, esp_payload, decrypt_pkt):
828 align = sa.crypt_algo.block_size
829 if align < 4:
830 align = 4
831 exp_len = (len(decrypt_pkt) + 2 + (align - 1)) & ~(align - 1)
832 exp_len += sa.crypt_algo.iv_size
833 exp_len += sa.crypt_algo.icv_size or sa.auth_algo.icv_size
834 self.assertEqual(exp_len, len(esp_payload))
835
Neale Rannsf05e7322019-03-29 20:23:58 +0000836 def verify_encrypted(self, p, sa, rxs):
837 decrypt_pkts = []
838 for rx in rxs:
Neale Ranns41afb332019-07-16 06:19:35 -0700839 if p.nat_header:
840 self.assertEqual(rx[UDP].dport, 4500)
Neale Ranns1b582b82019-04-18 19:49:13 -0700841 self.assert_packet_checksums_valid(rx)
842 self.assertEqual(len(rx) - len(Ether()), rx[IP].len)
Neale Rannsf05e7322019-03-29 20:23:58 +0000843 try:
Christian Hoppsfb7e7ed2019-11-03 07:02:15 -0500844 rx_ip = rx[IP]
845 decrypt_pkt = p.vpp_tun_sa.decrypt(rx_ip)
Neale Rannsf05e7322019-03-29 20:23:58 +0000846 if not decrypt_pkt.haslayer(IP):
847 decrypt_pkt = IP(decrypt_pkt[Raw].load)
Christian Hoppsfb7e7ed2019-11-03 07:02:15 -0500848 if rx_ip.proto == socket.IPPROTO_ESP:
849 self.verify_esp_padding(sa, rx_ip[ESP].data, decrypt_pkt)
Neale Rannsf05e7322019-03-29 20:23:58 +0000850 decrypt_pkts.append(decrypt_pkt)
851 self.assert_equal(decrypt_pkt.src, self.pg1.remote_ip4)
852 self.assert_equal(decrypt_pkt.dst, p.remote_tun_if_host)
853 except:
854 self.logger.debug(ppp("Unexpected packet:", rx))
855 try:
856 self.logger.debug(ppp("Decrypted packet:", decrypt_pkt))
857 except:
858 pass
859 raise
860 pkts = reassemble4(decrypt_pkts)
861 for pkt in pkts:
862 self.assert_packet_checksums_valid(pkt)
863
Neale Rannsd7603d92019-03-28 08:56:10 +0000864 def verify_tun_44(self, p, count=1, payload_size=64, n_rx=None):
Klement Sekera10d066e2018-11-13 11:12:57 +0100865 self.vapi.cli("clear errors")
Neale Ranns02950402019-12-20 00:54:57 +0000866 self.vapi.cli("clear ipsec counters")
Neale Ranns28287212019-12-16 00:53:11 +0000867 self.vapi.cli("clear ipsec sa")
Neale Rannsd7603d92019-03-28 08:56:10 +0000868 if not n_rx:
869 n_rx = count
Klement Sekera31da2e32018-06-24 22:49:55 +0200870 try:
Neale Ranns28287212019-12-16 00:53:11 +0000871 send_pkts = self.gen_encrypt_pkts(p, p.scapy_tun_sa, self.tun_if,
Klement Sekera611864f2018-09-26 11:19:00 +0200872 src=p.remote_tun_if_host,
Klement Sekera31da2e32018-06-24 22:49:55 +0200873 dst=self.pg1.remote_ip4,
Filip Tehlarefcad1a2020-02-04 09:36:04 +0000874 count=count,
875 payload_size=payload_size)
Klement Sekera611864f2018-09-26 11:19:00 +0200876 recv_pkts = self.send_and_expect(self.tun_if, send_pkts, self.pg1)
Neale Rannsf05e7322019-03-29 20:23:58 +0000877 self.verify_decrypted(p, recv_pkts)
878
Klement Sekera31da2e32018-06-24 22:49:55 +0200879 send_pkts = self.gen_pkts(self.pg1, src=self.pg1.remote_ip4,
Neale Rannsd7603d92019-03-28 08:56:10 +0000880 dst=p.remote_tun_if_host, count=count,
881 payload_size=payload_size)
882 recv_pkts = self.send_and_expect(self.pg1, send_pkts,
883 self.tun_if, n_rx)
Neale Rannsf05e7322019-03-29 20:23:58 +0000884 self.verify_encrypted(p, p.vpp_tun_sa, recv_pkts)
885
Neale Rannsf3a66222020-01-02 05:04:00 +0000886 for rx in recv_pkts:
887 self.assertEqual(rx[IP].src, p.tun_src)
888 self.assertEqual(rx[IP].dst, p.tun_dst)
889
Klement Sekera31da2e32018-06-24 22:49:55 +0200890 finally:
891 self.logger.info(self.vapi.ppcli("show error"))
Paul Vinciguerra9673e3e2019-05-10 20:41:08 -0400892 self.logger.info(self.vapi.ppcli("show ipsec all"))
Klement Sekera31da2e32018-06-24 22:49:55 +0200893
Neale Ranns02950402019-12-20 00:54:57 +0000894 self.logger.info(self.vapi.ppcli("show ipsec sa 0"))
895 self.logger.info(self.vapi.ppcli("show ipsec sa 4"))
Klement Sekera6aa58b72019-05-16 14:34:55 +0200896 self.verify_counters4(p, count, n_rx)
Neale Rannseba31ec2019-02-17 18:04:27 +0000897
Neale Ranns28287212019-12-16 00:53:11 +0000898 def verify_tun_dropped_44(self, p, count=1, payload_size=64, n_rx=None):
899 self.vapi.cli("clear errors")
900 if not n_rx:
901 n_rx = count
902 try:
903 send_pkts = self.gen_encrypt_pkts(p, p.scapy_tun_sa, self.tun_if,
904 src=p.remote_tun_if_host,
905 dst=self.pg1.remote_ip4,
906 count=count)
907 self.send_and_assert_no_replies(self.tun_if, send_pkts)
908
909 send_pkts = self.gen_pkts(self.pg1, src=self.pg1.remote_ip4,
910 dst=p.remote_tun_if_host, count=count,
911 payload_size=payload_size)
912 self.send_and_assert_no_replies(self.pg1, send_pkts)
913
914 finally:
915 self.logger.info(self.vapi.ppcli("show error"))
916 self.logger.info(self.vapi.ppcli("show ipsec all"))
917
Neale Ranns14046982019-07-29 14:49:52 +0000918 def verify_tun_reass_44(self, p):
919 self.vapi.cli("clear errors")
920 self.vapi.ip_reassembly_enable_disable(
921 sw_if_index=self.tun_if.sw_if_index, enable_ip4=True)
922
923 try:
Neale Ranns28287212019-12-16 00:53:11 +0000924 send_pkts = self.gen_encrypt_pkts(p, p.scapy_tun_sa, self.tun_if,
Neale Ranns14046982019-07-29 14:49:52 +0000925 src=p.remote_tun_if_host,
926 dst=self.pg1.remote_ip4,
927 payload_size=1900,
928 count=1)
929 send_pkts = fragment_rfc791(send_pkts[0], 1400)
930 recv_pkts = self.send_and_expect(self.tun_if, send_pkts,
931 self.pg1, n_rx=1)
932 self.verify_decrypted(p, recv_pkts)
933
934 send_pkts = self.gen_pkts(self.pg1, src=self.pg1.remote_ip4,
935 dst=p.remote_tun_if_host, count=1)
936 recv_pkts = self.send_and_expect(self.pg1, send_pkts,
937 self.tun_if)
938 self.verify_encrypted(p, p.vpp_tun_sa, recv_pkts)
939
940 finally:
941 self.logger.info(self.vapi.ppcli("show error"))
942 self.logger.info(self.vapi.ppcli("show ipsec all"))
943
944 self.verify_counters4(p, 1, 1)
945 self.vapi.ip_reassembly_enable_disable(
946 sw_if_index=self.tun_if.sw_if_index, enable_ip4=False)
947
Neale Ranns987aea82019-03-27 13:40:35 +0000948 def verify_tun_64(self, p, count=1):
949 self.vapi.cli("clear errors")
Neale Rannsdd4ccf22020-06-30 07:47:14 +0000950 self.vapi.cli("clear ipsec sa")
Neale Ranns987aea82019-03-27 13:40:35 +0000951 try:
Neale Ranns28287212019-12-16 00:53:11 +0000952 send_pkts = self.gen_encrypt_pkts6(p, p.scapy_tun_sa, self.tun_if,
Neale Ranns987aea82019-03-27 13:40:35 +0000953 src=p.remote_tun_if_host6,
954 dst=self.pg1.remote_ip6,
955 count=count)
956 recv_pkts = self.send_and_expect(self.tun_if, send_pkts, self.pg1)
957 for recv_pkt in recv_pkts:
958 self.assert_equal(recv_pkt[IPv6].src, p.remote_tun_if_host6)
959 self.assert_equal(recv_pkt[IPv6].dst, self.pg1.remote_ip6)
960 self.assert_packet_checksums_valid(recv_pkt)
Neale Ranns9ec846c2021-02-09 14:04:02 +0000961 send_pkts = self.gen_pkts6(p, self.pg1, src=self.pg1.remote_ip6,
Neale Ranns987aea82019-03-27 13:40:35 +0000962 dst=p.remote_tun_if_host6, count=count)
963 recv_pkts = self.send_and_expect(self.pg1, send_pkts, self.tun_if)
964 for recv_pkt in recv_pkts:
965 try:
966 decrypt_pkt = p.vpp_tun_sa.decrypt(recv_pkt[IP])
967 if not decrypt_pkt.haslayer(IPv6):
968 decrypt_pkt = IPv6(decrypt_pkt[Raw].load)
969 self.assert_equal(decrypt_pkt.src, self.pg1.remote_ip6)
970 self.assert_equal(decrypt_pkt.dst, p.remote_tun_if_host6)
971 self.assert_packet_checksums_valid(decrypt_pkt)
972 except:
973 self.logger.error(ppp("Unexpected packet:", recv_pkt))
974 try:
975 self.logger.debug(
976 ppp("Decrypted packet:", decrypt_pkt))
977 except:
978 pass
979 raise
980 finally:
981 self.logger.info(self.vapi.ppcli("show error"))
Paul Vinciguerra9673e3e2019-05-10 20:41:08 -0400982 self.logger.info(self.vapi.ppcli("show ipsec all"))
Neale Rannseba31ec2019-02-17 18:04:27 +0000983
Klement Sekera6aa58b72019-05-16 14:34:55 +0200984 self.verify_counters4(p, count)
Klement Sekera10d066e2018-11-13 11:12:57 +0100985
Neale Ranns41afb332019-07-16 06:19:35 -0700986 def verify_keepalive(self, p):
987 pkt = (Ether(src=self.tun_if.remote_mac, dst=self.tun_if.local_mac) /
988 IP(src=p.remote_tun_if_host, dst=self.tun_if.local_ip4) /
989 UDP(sport=333, dport=4500) /
Ole Troan8b76c232019-10-21 20:55:13 +0200990 Raw(b'\xff'))
Neale Ranns41afb332019-07-16 06:19:35 -0700991 self.send_and_assert_no_replies(self.tun_if, pkt*31)
992 self.assert_error_counter_equal(
993 '/err/%s/NAT Keepalive' % self.tun4_input_node, 31)
994
995 pkt = (Ether(src=self.tun_if.remote_mac, dst=self.tun_if.local_mac) /
996 IP(src=p.remote_tun_if_host, dst=self.tun_if.local_ip4) /
997 UDP(sport=333, dport=4500) /
Ole Troan8b76c232019-10-21 20:55:13 +0200998 Raw(b'\xfe'))
Neale Ranns41afb332019-07-16 06:19:35 -0700999 self.send_and_assert_no_replies(self.tun_if, pkt*31)
1000 self.assert_error_counter_equal(
1001 '/err/%s/Too Short' % self.tun4_input_node, 31)
1002
Neale Ranns2ac885c2019-03-20 18:24:43 +00001003
1004class IpsecTun4Tests(IpsecTun4):
Neale Ranns4f33c802019-04-10 12:39:10 +00001005 """ UT test methods for Tunnel v4 """
Neale Ranns2ac885c2019-03-20 18:24:43 +00001006 def test_tun_basic44(self):
1007 """ ipsec 4o4 tunnel basic test """
1008 self.verify_tun_44(self.params[socket.AF_INET], count=1)
Neale Ranns02950402019-12-20 00:54:57 +00001009 self.tun_if.admin_down()
1010 self.tun_if.resolve_arp()
1011 self.tun_if.admin_up()
1012 self.verify_tun_44(self.params[socket.AF_INET], count=1)
Neale Ranns2ac885c2019-03-20 18:24:43 +00001013
Neale Ranns14046982019-07-29 14:49:52 +00001014 def test_tun_reass_basic44(self):
1015 """ ipsec 4o4 tunnel basic reassembly test """
1016 self.verify_tun_reass_44(self.params[socket.AF_INET])
1017
Klement Sekera611864f2018-09-26 11:19:00 +02001018 def test_tun_burst44(self):
Klement Sekera31da2e32018-06-24 22:49:55 +02001019 """ ipsec 4o4 tunnel burst test """
Neale Ranns02950402019-12-20 00:54:57 +00001020 self.verify_tun_44(self.params[socket.AF_INET], count=127)
1021
1022
Neale Ranns2ac885c2019-03-20 18:24:43 +00001023class IpsecTun6(object):
Neale Ranns4f33c802019-04-10 12:39:10 +00001024 """ verify methods for Tunnel v6 """
Neale Ranns4a56f4e2019-12-23 04:10:25 +00001025 def verify_counters6(self, p_in, p_out, count, worker=None):
Neale Rannsc87b66c2019-02-07 07:26:12 -08001026 if (hasattr(p_in, "tun_sa_in")):
Neale Ranns4a56f4e2019-12-23 04:10:25 +00001027 pkts = p_in.tun_sa_in.get_stats(worker)['packets']
Neale Ranns987aea82019-03-27 13:40:35 +00001028 self.assertEqual(pkts, count,
1029 "incorrect SA in counts: expected %d != %d" %
1030 (count, pkts))
Neale Rannsc87b66c2019-02-07 07:26:12 -08001031 if (hasattr(p_out, "tun_sa_out")):
Neale Ranns4a56f4e2019-12-23 04:10:25 +00001032 pkts = p_out.tun_sa_out.get_stats(worker)['packets']
Neale Ranns987aea82019-03-27 13:40:35 +00001033 self.assertEqual(pkts, count,
1034 "incorrect SA out counts: expected %d != %d" %
1035 (count, pkts))
1036 self.assert_packet_counter_equal(self.tun6_encrypt_node_name, count)
1037 self.assert_packet_counter_equal(self.tun6_decrypt_node_name, count)
1038
Neale Rannsc87b66c2019-02-07 07:26:12 -08001039 def verify_decrypted6(self, p, rxs):
1040 for rx in rxs:
1041 self.assert_equal(rx[IPv6].src, p.remote_tun_if_host)
1042 self.assert_equal(rx[IPv6].dst, self.pg1.remote_ip6)
1043 self.assert_packet_checksums_valid(rx)
1044
1045 def verify_encrypted6(self, p, sa, rxs):
1046 for rx in rxs:
1047 self.assert_packet_checksums_valid(rx)
1048 self.assertEqual(len(rx) - len(Ether()) - len(IPv6()),
1049 rx[IPv6].plen)
Neale Ranns9ec846c2021-02-09 14:04:02 +00001050 self.assert_equal(rx[IPv6].hlim, p.outer_hop_limit)
1051 if p.outer_flow_label:
1052 self.assert_equal(rx[IPv6].fl, p.outer_flow_label)
Neale Rannsc87b66c2019-02-07 07:26:12 -08001053 try:
1054 decrypt_pkt = p.vpp_tun_sa.decrypt(rx[IPv6])
1055 if not decrypt_pkt.haslayer(IPv6):
1056 decrypt_pkt = IPv6(decrypt_pkt[Raw].load)
1057 self.assert_packet_checksums_valid(decrypt_pkt)
1058 self.assert_equal(decrypt_pkt.src, self.pg1.remote_ip6)
1059 self.assert_equal(decrypt_pkt.dst, p.remote_tun_if_host)
Neale Ranns9ec846c2021-02-09 14:04:02 +00001060 self.assert_equal(decrypt_pkt.hlim, p.inner_hop_limit - 1)
1061 self.assert_equal(decrypt_pkt.fl, p.inner_flow_label)
Neale Rannsc87b66c2019-02-07 07:26:12 -08001062 except:
1063 self.logger.debug(ppp("Unexpected packet:", rx))
1064 try:
1065 self.logger.debug(ppp("Decrypted packet:", decrypt_pkt))
1066 except:
1067 pass
1068 raise
1069
1070 def verify_drop_tun_66(self, p_in, count=1, payload_size=64):
Klement Sekera10d066e2018-11-13 11:12:57 +01001071 self.vapi.cli("clear errors")
Neale Rannsc87b66c2019-02-07 07:26:12 -08001072 self.vapi.cli("clear ipsec sa")
1073
Neale Ranns28287212019-12-16 00:53:11 +00001074 send_pkts = self.gen_encrypt_pkts6(p_in, p_in.scapy_tun_sa,
1075 self.tun_if,
Neale Rannsc87b66c2019-02-07 07:26:12 -08001076 src=p_in.remote_tun_if_host,
1077 dst=self.pg1.remote_ip6,
1078 count=count)
1079 self.send_and_assert_no_replies(self.tun_if, send_pkts)
1080 self.logger.info(self.vapi.cli("sh punt stats"))
1081
1082 def verify_tun_66(self, p_in, p_out=None, count=1, payload_size=64):
1083 self.vapi.cli("clear errors")
1084 self.vapi.cli("clear ipsec sa")
1085 if not p_out:
1086 p_out = p_in
Klement Sekera31da2e32018-06-24 22:49:55 +02001087 try:
Neale Ranns28287212019-12-16 00:53:11 +00001088 send_pkts = self.gen_encrypt_pkts6(p_in, p_in.scapy_tun_sa,
1089 self.tun_if,
Neale Rannsc87b66c2019-02-07 07:26:12 -08001090 src=p_in.remote_tun_if_host,
Klement Sekera611864f2018-09-26 11:19:00 +02001091 dst=self.pg1.remote_ip6,
Filip Tehlarefcad1a2020-02-04 09:36:04 +00001092 count=count,
1093 payload_size=payload_size)
Klement Sekera611864f2018-09-26 11:19:00 +02001094 recv_pkts = self.send_and_expect(self.tun_if, send_pkts, self.pg1)
Neale Rannsc87b66c2019-02-07 07:26:12 -08001095 self.verify_decrypted6(p_in, recv_pkts)
1096
Neale Ranns9ec846c2021-02-09 14:04:02 +00001097 send_pkts = self.gen_pkts6(p_in, self.pg1, src=self.pg1.remote_ip6,
Neale Rannsc87b66c2019-02-07 07:26:12 -08001098 dst=p_out.remote_tun_if_host,
1099 count=count,
1100 payload_size=payload_size)
Neale Ranns4a56f4e2019-12-23 04:10:25 +00001101 recv_pkts = self.send_and_expect(self.pg1, send_pkts, self.tun_if)
Neale Rannsc87b66c2019-02-07 07:26:12 -08001102 self.verify_encrypted6(p_out, p_out.vpp_tun_sa, recv_pkts)
1103
Neale Rannsf3a66222020-01-02 05:04:00 +00001104 for rx in recv_pkts:
1105 self.assertEqual(rx[IPv6].src, p_out.tun_src)
1106 self.assertEqual(rx[IPv6].dst, p_out.tun_dst)
1107
Klement Sekera31da2e32018-06-24 22:49:55 +02001108 finally:
1109 self.logger.info(self.vapi.ppcli("show error"))
Paul Vinciguerra9673e3e2019-05-10 20:41:08 -04001110 self.logger.info(self.vapi.ppcli("show ipsec all"))
Neale Rannsc87b66c2019-02-07 07:26:12 -08001111 self.verify_counters6(p_in, p_out, count)
Klement Sekera31da2e32018-06-24 22:49:55 +02001112
Neale Ranns14046982019-07-29 14:49:52 +00001113 def verify_tun_reass_66(self, p):
1114 self.vapi.cli("clear errors")
1115 self.vapi.ip_reassembly_enable_disable(
1116 sw_if_index=self.tun_if.sw_if_index, enable_ip6=True)
1117
1118 try:
Neale Ranns28287212019-12-16 00:53:11 +00001119 send_pkts = self.gen_encrypt_pkts6(p, p.scapy_tun_sa, self.tun_if,
Neale Ranns14046982019-07-29 14:49:52 +00001120 src=p.remote_tun_if_host,
1121 dst=self.pg1.remote_ip6,
1122 count=1,
Neale Ranns02950402019-12-20 00:54:57 +00001123 payload_size=1850)
Neale Ranns14046982019-07-29 14:49:52 +00001124 send_pkts = fragment_rfc8200(send_pkts[0], 1, 1400, self.logger)
1125 recv_pkts = self.send_and_expect(self.tun_if, send_pkts,
1126 self.pg1, n_rx=1)
1127 self.verify_decrypted6(p, recv_pkts)
1128
Neale Ranns9ec846c2021-02-09 14:04:02 +00001129 send_pkts = self.gen_pkts6(p, self.pg1, src=self.pg1.remote_ip6,
Neale Ranns14046982019-07-29 14:49:52 +00001130 dst=p.remote_tun_if_host,
1131 count=1,
1132 payload_size=64)
1133 recv_pkts = self.send_and_expect(self.pg1, send_pkts,
1134 self.tun_if)
1135 self.verify_encrypted6(p, p.vpp_tun_sa, recv_pkts)
1136 finally:
1137 self.logger.info(self.vapi.ppcli("show error"))
1138 self.logger.info(self.vapi.ppcli("show ipsec all"))
1139 self.verify_counters6(p, p, 1)
1140 self.vapi.ip_reassembly_enable_disable(
1141 sw_if_index=self.tun_if.sw_if_index, enable_ip6=False)
1142
Neale Ranns987aea82019-03-27 13:40:35 +00001143 def verify_tun_46(self, p, count=1):
1144 """ ipsec 4o6 tunnel basic test """
1145 self.vapi.cli("clear errors")
Neale Rannsdd4ccf22020-06-30 07:47:14 +00001146 self.vapi.cli("clear ipsec sa")
Neale Ranns987aea82019-03-27 13:40:35 +00001147 try:
Neale Ranns28287212019-12-16 00:53:11 +00001148 send_pkts = self.gen_encrypt_pkts(p, p.scapy_tun_sa, self.tun_if,
Neale Ranns987aea82019-03-27 13:40:35 +00001149 src=p.remote_tun_if_host4,
1150 dst=self.pg1.remote_ip4,
1151 count=count)
1152 recv_pkts = self.send_and_expect(self.tun_if, send_pkts, self.pg1)
1153 for recv_pkt in recv_pkts:
1154 self.assert_equal(recv_pkt[IP].src, p.remote_tun_if_host4)
1155 self.assert_equal(recv_pkt[IP].dst, self.pg1.remote_ip4)
1156 self.assert_packet_checksums_valid(recv_pkt)
1157 send_pkts = self.gen_pkts(self.pg1, src=self.pg1.remote_ip4,
1158 dst=p.remote_tun_if_host4,
1159 count=count)
1160 recv_pkts = self.send_and_expect(self.pg1, send_pkts, self.tun_if)
1161 for recv_pkt in recv_pkts:
1162 try:
1163 decrypt_pkt = p.vpp_tun_sa.decrypt(recv_pkt[IPv6])
1164 if not decrypt_pkt.haslayer(IP):
1165 decrypt_pkt = IP(decrypt_pkt[Raw].load)
1166 self.assert_equal(decrypt_pkt.src, self.pg1.remote_ip4)
1167 self.assert_equal(decrypt_pkt.dst, p.remote_tun_if_host4)
1168 self.assert_packet_checksums_valid(decrypt_pkt)
1169 except:
1170 self.logger.debug(ppp("Unexpected packet:", recv_pkt))
1171 try:
1172 self.logger.debug(ppp("Decrypted packet:",
1173 decrypt_pkt))
1174 except:
1175 pass
1176 raise
1177 finally:
1178 self.logger.info(self.vapi.ppcli("show error"))
Paul Vinciguerra9673e3e2019-05-10 20:41:08 -04001179 self.logger.info(self.vapi.ppcli("show ipsec all"))
Neale Rannsc87b66c2019-02-07 07:26:12 -08001180 self.verify_counters6(p, p, count)
Klement Sekera10d066e2018-11-13 11:12:57 +01001181
Neale Ranns2ac885c2019-03-20 18:24:43 +00001182
1183class IpsecTun6Tests(IpsecTun6):
Neale Ranns4f33c802019-04-10 12:39:10 +00001184 """ UT test methods for Tunnel v6 """
Neale Ranns2ac885c2019-03-20 18:24:43 +00001185
1186 def test_tun_basic66(self):
1187 """ ipsec 6o6 tunnel basic test """
1188 self.verify_tun_66(self.params[socket.AF_INET6], count=1)
1189
Neale Ranns14046982019-07-29 14:49:52 +00001190 def test_tun_reass_basic66(self):
1191 """ ipsec 6o6 tunnel basic reassembly test """
1192 self.verify_tun_reass_66(self.params[socket.AF_INET6])
1193
Klement Sekera611864f2018-09-26 11:19:00 +02001194 def test_tun_burst66(self):
1195 """ ipsec 6o6 tunnel burst test """
Neale Ranns2ac885c2019-03-20 18:24:43 +00001196 self.verify_tun_66(self.params[socket.AF_INET6], count=257)
Klement Sekera611864f2018-09-26 11:19:00 +02001197
1198
Neale Ranns4a56f4e2019-12-23 04:10:25 +00001199class IpsecTun6HandoffTests(IpsecTun6):
1200 """ UT test methods for Tunnel v6 with multiple workers """
1201 worker_config = "workers 2"
1202
1203 def test_tun_handoff_66(self):
1204 """ ipsec 6o6 tunnel worker hand-off test """
1205 N_PKTS = 15
1206 p = self.params[socket.AF_INET6]
1207
1208 # inject alternately on worker 0 and 1. all counts on the SA
1209 # should be against worker 0
1210 for worker in [0, 1, 0, 1]:
Neale Ranns28287212019-12-16 00:53:11 +00001211 send_pkts = self.gen_encrypt_pkts6(p, p.scapy_tun_sa, self.tun_if,
Neale Ranns4a56f4e2019-12-23 04:10:25 +00001212 src=p.remote_tun_if_host,
1213 dst=self.pg1.remote_ip6,
1214 count=N_PKTS)
1215 recv_pkts = self.send_and_expect(self.tun_if, send_pkts,
1216 self.pg1, worker=worker)
1217 self.verify_decrypted6(p, recv_pkts)
1218
Neale Ranns9ec846c2021-02-09 14:04:02 +00001219 send_pkts = self.gen_pkts6(p, self.pg1, src=self.pg1.remote_ip6,
Neale Ranns4a56f4e2019-12-23 04:10:25 +00001220 dst=p.remote_tun_if_host,
1221 count=N_PKTS)
1222 recv_pkts = self.send_and_expect(self.pg1, send_pkts,
1223 self.tun_if, worker=worker)
1224 self.verify_encrypted6(p, p.vpp_tun_sa, recv_pkts)
1225
1226 # all counts against the first worker that was used
1227 self.verify_counters6(p, p, 4*N_PKTS, worker=0)
1228
1229
1230class IpsecTun4HandoffTests(IpsecTun4):
1231 """ UT test methods for Tunnel v4 with multiple workers """
1232 worker_config = "workers 2"
1233
1234 def test_tun_handooff_44(self):
1235 """ ipsec 4o4 tunnel worker hand-off test """
1236 N_PKTS = 15
1237 p = self.params[socket.AF_INET]
1238
1239 # inject alternately on worker 0 and 1. all counts on the SA
1240 # should be against worker 0
1241 for worker in [0, 1, 0, 1]:
Neale Ranns28287212019-12-16 00:53:11 +00001242 send_pkts = self.gen_encrypt_pkts(p, p.scapy_tun_sa, self.tun_if,
Neale Ranns4a56f4e2019-12-23 04:10:25 +00001243 src=p.remote_tun_if_host,
1244 dst=self.pg1.remote_ip4,
1245 count=N_PKTS)
1246 recv_pkts = self.send_and_expect(self.tun_if, send_pkts,
1247 self.pg1, worker=worker)
1248 self.verify_decrypted(p, recv_pkts)
1249
1250 send_pkts = self.gen_pkts(self.pg1, src=self.pg1.remote_ip4,
1251 dst=p.remote_tun_if_host,
1252 count=N_PKTS)
1253 recv_pkts = self.send_and_expect(self.pg1, send_pkts,
1254 self.tun_if, worker=worker)
1255 self.verify_encrypted(p, p.vpp_tun_sa, recv_pkts)
1256
1257 # all counts against the first worker that was used
1258 self.verify_counters4(p, 4*N_PKTS, worker=0)
1259
1260
Neale Ranns53f526b2019-02-25 14:32:02 +00001261class IpsecTun46Tests(IpsecTun4Tests, IpsecTun6Tests):
Neale Ranns4f33c802019-04-10 12:39:10 +00001262 """ UT test methods for Tunnel v6 & v4 """
Klement Sekera611864f2018-09-26 11:19:00 +02001263 pass
1264
Klement Sekera31da2e32018-06-24 22:49:55 +02001265
1266if __name__ == '__main__':
1267 unittest.main(testRunner=VppTestRunner)