X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=test%2Ftest_ipsec_tun_if_esp.py;h=14c9b3e3f1182c34bab7a0e5d1c0b73039962743;hb=e5a3ae017;hp=2ef1351ae7fdca1f8a2d9b6e369fe9f62518dcf9;hpb=9ec846c2684b69f47505d73ea9f873b793a11558;p=vpp.git diff --git a/test/test_ipsec_tun_if_esp.py b/test/test_ipsec_tun_if_esp.py index 2ef1351ae7f..14c9b3e3f11 100644 --- a/test/test_ipsec_tun_if_esp.py +++ b/test/test_ipsec_tun_if_esp.py @@ -4,10 +4,11 @@ import copy from scapy.layers.ipsec import SecurityAssociation, ESP from scapy.layers.l2 import Ether, GRE, Dot1Q -from scapy.packet import Raw +from scapy.packet import Raw, bind_layers from scapy.layers.inet import IP, UDP from scapy.layers.inet6 import IPv6 from scapy.contrib.mpls import MPLS +from framework import tag_fixme_vpp_workers from framework import VppTestRunner from template_ipsec import TemplateIpsec, IpsecTun4Tests, IpsecTun6Tests, \ IpsecTun4, IpsecTun6, IpsecTcpTests, mk_scapy_crypt_key, \ @@ -24,6 +25,7 @@ from util import ppp from vpp_papi import VppEnum from vpp_papi_provider import CliFailedCommandError from vpp_acl import AclRule, VppAcl, VppAclInterface +from vpp_policer import PolicerAction, VppPolicer, Dir def config_tun_params(p, encryption_type, tun_if, src=None, dst=None): @@ -38,6 +40,18 @@ def config_tun_params(p, encryption_type, tun_if, src=None, dst=None): p.tun_dst = dst p.tun_src = src + if p.nat_header: + is_default_port = (p.nat_header.dport == 4500) + else: + is_default_port = True + + if is_default_port: + outbound_nat_header = p.nat_header + else: + outbound_nat_header = UDP(sport=p.nat_header.dport, + dport=p.nat_header.sport) + bind_layers(UDP, ESP, dport=p.nat_header.dport) + p.scapy_tun_sa = SecurityAssociation( encryption_type, spi=p.vpp_tun_spi, crypt_algo=p.crypt_algo, @@ -46,7 +60,7 @@ def config_tun_params(p, encryption_type, tun_if, src=None, dst=None): tunnel_header=ip_class_by_addr_type[p.addr_type]( src=p.tun_dst, dst=p.tun_src), - nat_t_header=p.nat_header, + nat_t_header=outbound_nat_header, esn_en=esn_en) p.vpp_tun_sa = SecurityAssociation( encryption_type, spi=p.scapy_tun_spi, @@ -67,13 +81,26 @@ def config_tra_params(p, encryption_type, tun_if): crypt_key = mk_scapy_crypt_key(p) p.tun_dst = tun_if.remote_ip p.tun_src = tun_if.local_ip + + if p.nat_header: + is_default_port = (p.nat_header.dport == 4500) + else: + is_default_port = True + + if is_default_port: + outbound_nat_header = p.nat_header + else: + outbound_nat_header = UDP(sport=p.nat_header.dport, + dport=p.nat_header.sport) + bind_layers(UDP, ESP, dport=p.nat_header.dport) + p.scapy_tun_sa = SecurityAssociation( encryption_type, spi=p.vpp_tun_spi, crypt_algo=p.crypt_algo, crypt_key=crypt_key, auth_algo=p.auth_algo, auth_key=p.auth_key, esn_en=esn_en, - nat_t_header=p.nat_header) + nat_t_header=outbound_nat_header) p.vpp_tun_sa = SecurityAssociation( encryption_type, spi=p.scapy_tun_spi, crypt_algo=p.crypt_algo, @@ -88,7 +115,7 @@ class TemplateIpsec4TunProtect(object): encryption_type = ESP tun4_encrypt_node_name = "esp4-encrypt-tun" - tun4_decrypt_node_name = "esp4-decrypt-tun" + tun4_decrypt_node_name = ["esp4-decrypt-tun", "esp4-decrypt-tun-post"] tun4_input_node = "ipsec4-tun-input" def config_sa_tra(self, p): @@ -205,7 +232,7 @@ class TemplateIpsec4TunIfEspUdp(TemplateIpsec4TunProtect, """ IPsec UDP tunnel interface tests """ tun4_encrypt_node_name = "esp4-encrypt-tun" - tun4_decrypt_node_name = "esp4-decrypt-tun" + tun4_decrypt_node_name = ["esp4-decrypt-tun", "esp4-decrypt-tun-post"] encryption_type = ESP @classmethod @@ -282,7 +309,7 @@ class TemplateIpsec4TunIfEspUdp(TemplateIpsec4TunProtect, class TestIpsec4TunIfEsp1(TemplateIpsec4TunIfEsp, IpsecTun4Tests): """ Ipsec ESP - TUN tests """ tun4_encrypt_node_name = "esp4-encrypt-tun" - tun4_decrypt_node_name = "esp4-decrypt-tun" + tun4_decrypt_node_name = ["esp4-decrypt-tun", "esp4-decrypt-tun-post"] def test_tun_basic64(self): """ ipsec 6o4 tunnel basic test """ @@ -449,7 +476,7 @@ class TestIpsec6TunIfEsp1(TemplateIpsec6TunIfEsp, IpsecTun6Tests): """ Ipsec ESP - TUN tests """ tun6_encrypt_node_name = "esp6-encrypt-tun" - tun6_decrypt_node_name = "esp6-decrypt-tun" + tun6_decrypt_node_name = ["esp6-decrypt-tun", "esp6-decrypt-tun-post"] def test_tun_basic46(self): """ ipsec 4o6 tunnel basic test """ @@ -466,16 +493,147 @@ class TestIpsec6TunIfEspHandoff(TemplateIpsec6TunIfEsp, IpsecTun6HandoffTests): """ Ipsec ESP 6 Handoff tests """ tun6_encrypt_node_name = "esp6-encrypt-tun" - tun6_decrypt_node_name = "esp6-decrypt-tun" + tun6_decrypt_node_name = ["esp6-decrypt-tun", "esp6-decrypt-tun-post"] + + def test_tun_handoff_66_police(self): + """ ESP 6o6 tunnel with policer worker hand-off test """ + self.vapi.cli("clear errors") + self.vapi.cli("clear ipsec sa") + + N_PKTS = 15 + p = self.params[socket.AF_INET6] + + action_tx = PolicerAction( + VppEnum.vl_api_sse2_qos_action_type_t.SSE2_QOS_ACTION_API_TRANSMIT, + 0) + policer = VppPolicer(self, "pol1", 80, 0, 1000, 0, + conform_action=action_tx, + exceed_action=action_tx, + violate_action=action_tx) + policer.add_vpp_config() + + # Start policing on tun + policer.apply_vpp_config(p.tun_if.sw_if_index, Dir.RX, True) + + for pol_bind in [1, 0]: + policer.bind_vpp_config(pol_bind, True) + + # inject alternately on worker 0 and 1. + for worker in [0, 1, 0, 1]: + send_pkts = self.gen_encrypt_pkts6(p, p.scapy_tun_sa, + self.tun_if, + src=p.remote_tun_if_host, + dst=self.pg1.remote_ip6, + count=N_PKTS) + recv_pkts = self.send_and_expect(self.tun_if, send_pkts, + self.pg1, worker=worker) + self.verify_decrypted6(p, recv_pkts) + self.logger.debug(self.vapi.cli("show trace max 100")) + + stats = policer.get_stats() + stats0 = policer.get_stats(worker=0) + stats1 = policer.get_stats(worker=1) + + if pol_bind == 1: + # First pass: Worker 1, should have done all the policing + self.assertEqual(stats, stats1) + + # Worker 0, should have handed everything off + self.assertEqual(stats0['conform_packets'], 0) + self.assertEqual(stats0['exceed_packets'], 0) + self.assertEqual(stats0['violate_packets'], 0) + else: + # Second pass: both workers should have policed equal amounts + self.assertGreater(stats1['conform_packets'], 0) + self.assertEqual(stats1['exceed_packets'], 0) + self.assertGreater(stats1['violate_packets'], 0) + + self.assertGreater(stats0['conform_packets'], 0) + self.assertEqual(stats0['exceed_packets'], 0) + self.assertGreater(stats0['violate_packets'], 0) + + self.assertEqual(stats0['conform_packets'] + + stats0['violate_packets'], + stats1['conform_packets'] + + stats1['violate_packets']) + + policer.apply_vpp_config(p.tun_if.sw_if_index, Dir.RX, False) + policer.remove_vpp_config() class TestIpsec4TunIfEspHandoff(TemplateIpsec4TunIfEsp, IpsecTun4HandoffTests): """ Ipsec ESP 4 Handoff tests """ tun4_encrypt_node_name = "esp4-encrypt-tun" - tun4_decrypt_node_name = "esp4-decrypt-tun" + tun4_decrypt_node_name = ["esp4-decrypt-tun", "esp4-decrypt-tun-post"] + def test_tun_handoff_44_police(self): + """ ESP 4o4 tunnel with policer worker hand-off test """ + self.vapi.cli("clear errors") + self.vapi.cli("clear ipsec sa") + N_PKTS = 15 + p = self.params[socket.AF_INET] + + action_tx = PolicerAction( + VppEnum.vl_api_sse2_qos_action_type_t.SSE2_QOS_ACTION_API_TRANSMIT, + 0) + policer = VppPolicer(self, "pol1", 80, 0, 1000, 0, + conform_action=action_tx, + exceed_action=action_tx, + violate_action=action_tx) + policer.add_vpp_config() + + # Start policing on tun + policer.apply_vpp_config(p.tun_if.sw_if_index, Dir.RX, True) + + for pol_bind in [1, 0]: + policer.bind_vpp_config(pol_bind, True) + + # inject alternately on worker 0 and 1. + for worker in [0, 1, 0, 1]: + send_pkts = self.gen_encrypt_pkts(p, p.scapy_tun_sa, + self.tun_if, + src=p.remote_tun_if_host, + dst=self.pg1.remote_ip4, + count=N_PKTS) + recv_pkts = self.send_and_expect(self.tun_if, send_pkts, + self.pg1, worker=worker) + self.verify_decrypted(p, recv_pkts) + self.logger.debug(self.vapi.cli("show trace max 100")) + + stats = policer.get_stats() + stats0 = policer.get_stats(worker=0) + stats1 = policer.get_stats(worker=1) + + if pol_bind == 1: + # First pass: Worker 1, should have done all the policing + self.assertEqual(stats, stats1) + + # Worker 0, should have handed everything off + self.assertEqual(stats0['conform_packets'], 0) + self.assertEqual(stats0['exceed_packets'], 0) + self.assertEqual(stats0['violate_packets'], 0) + else: + # Second pass: both workers should have policed equal amounts + self.assertGreater(stats1['conform_packets'], 0) + self.assertEqual(stats1['exceed_packets'], 0) + self.assertGreater(stats1['violate_packets'], 0) + + self.assertGreater(stats0['conform_packets'], 0) + self.assertEqual(stats0['exceed_packets'], 0) + self.assertGreater(stats0['violate_packets'], 0) + + self.assertEqual(stats0['conform_packets'] + + stats0['violate_packets'], + stats1['conform_packets'] + + stats1['violate_packets']) + + policer.apply_vpp_config(p.tun_if.sw_if_index, Dir.RX, False) + policer.remove_vpp_config() + + +@tag_fixme_vpp_workers class TestIpsec4MultiTunIfEsp(TemplateIpsec4TunProtect, TemplateIpsec, IpsecTun4): @@ -483,7 +641,7 @@ class TestIpsec4MultiTunIfEsp(TemplateIpsec4TunProtect, encryption_type = ESP tun4_encrypt_node_name = "esp4-encrypt-tun" - tun4_decrypt_node_name = "esp4-decrypt-tun" + tun4_decrypt_node_name = ["esp4-decrypt-tun", "esp4-decrypt-tun-post"] def setUp(self): super(TestIpsec4MultiTunIfEsp, self).setUp() @@ -521,10 +679,8 @@ class TestIpsec4MultiTunIfEsp(TemplateIpsec4TunProtect, """Multiple IPSEC tunnel interfaces """ for p in self.multi_params: self.verify_tun_44(p, count=127) - c = p.tun_if.get_rx_stats() - self.assertEqual(c['packets'], 127) - c = p.tun_if.get_tx_stats() - self.assertEqual(c['packets'], 127) + self.assertEqual(p.tun_if.get_rx_stats(), 127) + self.assertEqual(p.tun_if.get_tx_stats(), 127) def test_tun_rr_44(self): """ Round-robin packets acrros multiple interface """ @@ -555,7 +711,7 @@ class TestIpsec4TunIfEspAll(TemplateIpsec4TunProtect, encryption_type = ESP tun4_encrypt_node_name = "esp4-encrypt-tun" - tun4_decrypt_node_name = "esp4-decrypt-tun" + tun4_decrypt_node_name = ["esp4-decrypt-tun", "esp4-decrypt-tun-post"] def setUp(self): super(TestIpsec4TunIfEspAll, self).setUp() @@ -713,7 +869,7 @@ class TestIpsec4TunIfEspNoAlgo(TemplateIpsec4TunProtect, encryption_type = ESP tun4_encrypt_node_name = "esp4-encrypt-tun" - tun4_decrypt_node_name = "esp4-decrypt-tun" + tun4_decrypt_node_name = ["esp4-decrypt-tun", "esp4-decrypt-tun-post"] def setUp(self): super(TestIpsec4TunIfEspNoAlgo, self).setUp() @@ -750,6 +906,7 @@ class TestIpsec4TunIfEspNoAlgo(TemplateIpsec4TunProtect, self.unconfig_network(p) +@tag_fixme_vpp_workers class TestIpsec6MultiTunIfEsp(TemplateIpsec6TunProtect, TemplateIpsec, IpsecTun6): @@ -757,7 +914,7 @@ class TestIpsec6MultiTunIfEsp(TemplateIpsec6TunProtect, encryption_type = ESP tun6_encrypt_node_name = "esp6-encrypt-tun" - tun6_decrypt_node_name = "esp6-decrypt-tun" + tun6_decrypt_node_name = ["esp6-decrypt-tun", "esp6-decrypt-tun-post"] def setUp(self): super(TestIpsec6MultiTunIfEsp, self).setUp() @@ -795,17 +952,15 @@ class TestIpsec6MultiTunIfEsp(TemplateIpsec6TunProtect, """Multiple IPSEC tunnel interfaces """ for p in self.multi_params: self.verify_tun_66(p, count=127) - c = p.tun_if.get_rx_stats() - self.assertEqual(c['packets'], 127) - c = p.tun_if.get_tx_stats() - self.assertEqual(c['packets'], 127) + self.assertEqual(p.tun_if.get_rx_stats(), 127) + self.assertEqual(p.tun_if.get_tx_stats(), 127) class TestIpsecGreTebIfEsp(TemplateIpsec, IpsecTun4Tests): """ Ipsec GRE TEB ESP - TUN tests """ tun4_encrypt_node_name = "esp4-encrypt-tun" - tun4_decrypt_node_name = "esp4-decrypt-tun" + tun4_decrypt_node_name = ["esp4-decrypt-tun", "esp4-decrypt-tun-post"] encryption_type = ESP omac = "00:11:22:33:44:55" @@ -916,7 +1071,7 @@ class TestIpsecGreTebVlanIfEsp(TemplateIpsec, IpsecTun4Tests): """ Ipsec GRE TEB ESP - TUN tests """ tun4_encrypt_node_name = "esp4-encrypt-tun" - tun4_decrypt_node_name = "esp4-decrypt-tun" + tun4_decrypt_node_name = ["esp4-decrypt-tun", "esp4-decrypt-tun-post"] encryption_type = ESP omac = "00:11:22:33:44:55" @@ -1036,7 +1191,7 @@ class TestIpsecGreTebIfEspTra(TemplateIpsec, IpsecTun4Tests): """ Ipsec GRE TEB ESP - Tra tests """ tun4_encrypt_node_name = "esp4-encrypt-tun" - tun4_decrypt_node_name = "esp4-decrypt-tun" + tun4_decrypt_node_name = ["esp4-decrypt-tun", "esp4-decrypt-tun-post"] encryption_type = ESP omac = "00:11:22:33:44:55" @@ -1141,7 +1296,7 @@ class TestIpsecGreTebUdpIfEspTra(TemplateIpsec, IpsecTun4Tests): """ Ipsec GRE TEB UDP ESP - Tra tests """ tun4_encrypt_node_name = "esp4-encrypt-tun" - tun4_decrypt_node_name = "esp4-decrypt-tun" + tun4_decrypt_node_name = ["esp4-decrypt-tun", "esp4-decrypt-tun-post"] encryption_type = ESP omac = "00:11:22:33:44:55" @@ -1224,8 +1379,8 @@ class TestIpsecGreTebUdpIfEspTra(TemplateIpsec, flags=(p.flags | VppEnum.vl_api_ipsec_sad_flags_t. IPSEC_API_SAD_FLAG_IS_INBOUND), - udp_src=5454, - udp_dst=4545) + udp_src=4545, + udp_dst=5454) p.tun_sa_in.add_vpp_config() p.tun_if = VppGreInterface(self, @@ -1262,7 +1417,7 @@ class TestIpsecGreIfEsp(TemplateIpsec, IpsecTun4Tests): """ Ipsec GRE ESP - TUN tests """ tun4_encrypt_node_name = "esp4-encrypt-tun" - tun4_decrypt_node_name = "esp4-decrypt-tun" + tun4_decrypt_node_name = ["esp4-decrypt-tun", "esp4-decrypt-tun-post"] encryption_type = ESP def gen_encrypt_pkts(self, p, sa, sw_intf, src, dst, count=1, @@ -1365,7 +1520,7 @@ class TestIpsecGreIfEspTra(TemplateIpsec, IpsecTun4Tests): """ Ipsec GRE ESP - TRA tests """ tun4_encrypt_node_name = "esp4-encrypt-tun" - tun4_decrypt_node_name = "esp4-decrypt-tun" + tun4_decrypt_node_name = ["esp4-decrypt-tun", "esp4-decrypt-tun-post"] encryption_type = ESP def gen_encrypt_pkts(self, p, sa, sw_intf, src, dst, count=1, @@ -1471,7 +1626,7 @@ class TestIpsecGreIfEspTra(TemplateIpsec, dst=self.pg1.remote_ip6) self.send_and_assert_no_replies(self.tun_if, tx) node_name = ('/err/%s/unsupported payload' % - self.tun4_decrypt_node_name) + self.tun4_decrypt_node_name[0]) self.assertEqual(1, self.statistics.get_err_counter(node_name)) @@ -1479,7 +1634,7 @@ class TestIpsecGre6IfEspTra(TemplateIpsec, IpsecTun6Tests): """ Ipsec GRE ESP - TRA tests """ tun6_encrypt_node_name = "esp6-encrypt-tun" - tun6_decrypt_node_name = "esp6-decrypt-tun" + tun6_decrypt_node_name = ["esp6-decrypt-tun", "esp6-decrypt-tun-post"] encryption_type = ESP def gen_encrypt_pkts6(self, p, sa, sw_intf, src, dst, count=1, @@ -1577,7 +1732,7 @@ class TestIpsecGre6IfEspTra(TemplateIpsec, class TestIpsecMGreIfEspTra4(TemplateIpsec, IpsecTun4): """ Ipsec mGRE ESP v4 TRA tests """ tun4_encrypt_node_name = "esp4-encrypt-tun" - tun4_decrypt_node_name = "esp4-decrypt-tun" + tun4_decrypt_node_name = ["esp4-decrypt-tun", "esp4-decrypt-tun-post"] encryption_type = ESP def gen_encrypt_pkts(self, p, sa, sw_intf, src, dst, count=1, @@ -1709,7 +1864,7 @@ class TestIpsecMGreIfEspTra4(TemplateIpsec, IpsecTun4): class TestIpsecMGreIfEspTra6(TemplateIpsec, IpsecTun6): """ Ipsec mGRE ESP v6 TRA tests """ tun6_encrypt_node_name = "esp6-encrypt-tun" - tun6_decrypt_node_name = "esp6-decrypt-tun" + tun6_decrypt_node_name = ["esp6-decrypt-tun", "esp6-decrypt-tun-post"] encryption_type = ESP def gen_encrypt_pkts6(self, p, sa, sw_intf, src, dst, count=1, @@ -1839,6 +1994,7 @@ class TestIpsecMGreIfEspTra6(TemplateIpsec, IpsecTun6): self.verify_tun_66(p, count=63) +@tag_fixme_vpp_workers class TestIpsec4TunProtect(TemplateIpsec, TemplateIpsec4TunProtect, IpsecTun4): @@ -1862,17 +2018,13 @@ class TestIpsec4TunProtect(TemplateIpsec, self.config_protect(p) self.verify_tun_44(p, count=127) - c = p.tun_if.get_rx_stats() - self.assertEqual(c['packets'], 127) - c = p.tun_if.get_tx_stats() - self.assertEqual(c['packets'], 127) + self.assertEqual(p.tun_if.get_rx_stats(), 127) + self.assertEqual(p.tun_if.get_tx_stats(), 127) self.vapi.cli("clear ipsec sa") self.verify_tun_64(p, count=127) - c = p.tun_if.get_rx_stats() - self.assertEqual(c['packets'], 254) - c = p.tun_if.get_tx_stats() - self.assertEqual(c['packets'], 254) + self.assertEqual(p.tun_if.get_rx_stats(), 254) + self.assertEqual(p.tun_if.get_tx_stats(), 254) # rekey - create new SAs and update the tunnel protection np = copy.copy(p) @@ -1889,10 +2041,8 @@ class TestIpsec4TunProtect(TemplateIpsec, self.unconfig_sa(p) self.verify_tun_44(np, count=127) - c = p.tun_if.get_rx_stats() - self.assertEqual(c['packets'], 381) - c = p.tun_if.get_tx_stats() - self.assertEqual(c['packets'], 381) + self.assertEqual(p.tun_if.get_rx_stats(), 381) + self.assertEqual(p.tun_if.get_tx_stats(), 381) # teardown self.unconfig_protect(np) @@ -1900,6 +2050,7 @@ class TestIpsec4TunProtect(TemplateIpsec, self.unconfig_network(p) +@tag_fixme_vpp_workers class TestIpsec4TunProtectUdp(TemplateIpsec, TemplateIpsec4TunProtect, IpsecTun4): @@ -1938,16 +2089,15 @@ class TestIpsec4TunProtectUdp(TemplateIpsec, p = self.ipv4_params self.verify_tun_44(p, count=127) - c = p.tun_if.get_rx_stats() - self.assertEqual(c['packets'], 127) - c = p.tun_if.get_tx_stats() - self.assertEqual(c['packets'], 127) + self.assertEqual(p.tun_if.get_rx_stats(), 127) + self.assertEqual(p.tun_if.get_tx_stats(), 127) def test_keepalive(self): """ IPSEC NAT Keepalive """ self.verify_keepalive(self.ipv4_params) +@tag_fixme_vpp_workers class TestIpsec4TunProtectTun(TemplateIpsec, TemplateIpsec4TunProtect, IpsecTun4): @@ -1955,7 +2105,7 @@ class TestIpsec4TunProtectTun(TemplateIpsec, encryption_type = ESP tun4_encrypt_node_name = "esp4-encrypt-tun" - tun4_decrypt_node_name = "esp4-decrypt-tun" + tun4_decrypt_node_name = ["esp4-decrypt-tun", "esp4-decrypt-tun-post"] def setUp(self): super(TestIpsec4TunProtectTun, self).setUp() @@ -2031,10 +2181,8 @@ class TestIpsec4TunProtectTun(TemplateIpsec, self.verify_tun_44(p, count=127) - c = p.tun_if.get_rx_stats() - self.assertEqual(c['packets'], 127) - c = p.tun_if.get_tx_stats() - self.assertEqual(c['packets'], 127) + self.assertEqual(p.tun_if.get_rx_stats(), 127) + self.assertEqual(p.tun_if.get_tx_stats(), 127) # rekey - create new SAs and update the tunnel protection np = copy.copy(p) @@ -2051,10 +2199,8 @@ class TestIpsec4TunProtectTun(TemplateIpsec, self.unconfig_sa(p) self.verify_tun_44(np, count=127) - c = p.tun_if.get_rx_stats() - self.assertEqual(c['packets'], 254) - c = p.tun_if.get_tx_stats() - self.assertEqual(c['packets'], 254) + self.assertEqual(p.tun_if.get_rx_stats(), 254) + self.assertEqual(p.tun_if.get_tx_stats(), 254) # teardown self.unconfig_protect(np) @@ -2069,7 +2215,7 @@ class TestIpsec4TunProtectTunDrop(TemplateIpsec, encryption_type = ESP tun4_encrypt_node_name = "esp4-encrypt-tun" - tun4_decrypt_node_name = "esp4-decrypt-tun" + tun4_decrypt_node_name = ["esp4-decrypt-tun", "esp4-decrypt-tun-post"] def setUp(self): super(TestIpsec4TunProtectTunDrop, self).setUp() @@ -2110,6 +2256,7 @@ class TestIpsec4TunProtectTunDrop(TemplateIpsec, self.unconfig_network(p) +@tag_fixme_vpp_workers class TestIpsec6TunProtect(TemplateIpsec, TemplateIpsec6TunProtect, IpsecTun6): @@ -2117,7 +2264,7 @@ class TestIpsec6TunProtect(TemplateIpsec, encryption_type = ESP tun6_encrypt_node_name = "esp6-encrypt-tun" - tun6_decrypt_node_name = "esp6-decrypt-tun" + tun6_decrypt_node_name = ["esp6-decrypt-tun", "esp6-decrypt-tun-post"] def setUp(self): super(TestIpsec6TunProtect, self).setUp() @@ -2137,10 +2284,8 @@ class TestIpsec6TunProtect(TemplateIpsec, self.config_protect(p) self.verify_tun_66(p, count=127) - c = p.tun_if.get_rx_stats() - self.assertEqual(c['packets'], 127) - c = p.tun_if.get_tx_stats() - self.assertEqual(c['packets'], 127) + self.assertEqual(p.tun_if.get_rx_stats(), 127) + self.assertEqual(p.tun_if.get_tx_stats(), 127) # rekey - create new SAs and update the tunnel protection np = copy.copy(p) @@ -2157,10 +2302,8 @@ class TestIpsec6TunProtect(TemplateIpsec, self.unconfig_sa(p) self.verify_tun_66(np, count=127) - c = p.tun_if.get_rx_stats() - self.assertEqual(c['packets'], 254) - c = p.tun_if.get_tx_stats() - self.assertEqual(c['packets'], 254) + self.assertEqual(p.tun_if.get_rx_stats(), 254) + self.assertEqual(p.tun_if.get_tx_stats(), 254) # bounce the interface state p.tun_if.admin_down() @@ -2202,12 +2345,10 @@ class TestIpsec6TunProtect(TemplateIpsec, p.tun_protect.update_vpp_config(np3.tun_sa_out, [np3.tun_sa_in]) self.verify_tun_66(np3, np3, count=127) - self.verify_drop_tun_66(np, count=127) + self.verify_drop_tun_rx_66(np, count=127) - c = p.tun_if.get_rx_stats() - self.assertEqual(c['packets'], 127*9) - c = p.tun_if.get_tx_stats() - self.assertEqual(c['packets'], 127*8) + self.assertEqual(p.tun_if.get_rx_stats(), 127*9) + self.assertEqual(p.tun_if.get_tx_stats(), 127*8) self.unconfig_sa(np) # teardown @@ -2225,10 +2366,8 @@ class TestIpsec6TunProtect(TemplateIpsec, self.config_protect(p) self.verify_tun_46(p, count=127) - c = p.tun_if.get_rx_stats() - self.assertEqual(c['packets'], 127) - c = p.tun_if.get_tx_stats() - self.assertEqual(c['packets'], 127) + self.assertEqual(p.tun_if.get_rx_stats(), 127) + self.assertEqual(p.tun_if.get_tx_stats(), 127) # teardown self.unconfig_protect(p) @@ -2236,6 +2375,7 @@ class TestIpsec6TunProtect(TemplateIpsec, self.unconfig_network(p) +@tag_fixme_vpp_workers class TestIpsec6TunProtectTun(TemplateIpsec, TemplateIpsec6TunProtect, IpsecTun6): @@ -2243,7 +2383,7 @@ class TestIpsec6TunProtectTun(TemplateIpsec, encryption_type = ESP tun6_encrypt_node_name = "esp6-encrypt-tun" - tun6_decrypt_node_name = "esp6-decrypt-tun" + tun6_decrypt_node_name = ["esp6-decrypt-tun", "esp6-decrypt-tun-post"] def setUp(self): super(TestIpsec6TunProtectTun, self).setUp() @@ -2308,10 +2448,8 @@ class TestIpsec6TunProtectTun(TemplateIpsec, self.verify_tun_66(p, count=127) - c = p.tun_if.get_rx_stats() - self.assertEqual(c['packets'], 127) - c = p.tun_if.get_tx_stats() - self.assertEqual(c['packets'], 127) + self.assertEqual(p.tun_if.get_rx_stats(), 127) + self.assertEqual(p.tun_if.get_tx_stats(), 127) # rekey - create new SAs and update the tunnel protection np = copy.copy(p) @@ -2328,10 +2466,8 @@ class TestIpsec6TunProtectTun(TemplateIpsec, self.unconfig_sa(p) self.verify_tun_66(np, count=127) - c = p.tun_if.get_rx_stats() - self.assertEqual(c['packets'], 254) - c = p.tun_if.get_tx_stats() - self.assertEqual(c['packets'], 254) + self.assertEqual(p.tun_if.get_rx_stats(), 254) + self.assertEqual(p.tun_if.get_tx_stats(), 254) # teardown self.unconfig_protect(np) @@ -2346,7 +2482,7 @@ class TestIpsec6TunProtectTunDrop(TemplateIpsec, encryption_type = ESP tun6_encrypt_node_name = "esp6-encrypt-tun" - tun6_decrypt_node_name = "esp6-decrypt-tun" + tun6_decrypt_node_name = ["esp6-decrypt-tun", "esp6-decrypt-tun-post"] def setUp(self): super(TestIpsec6TunProtectTunDrop, self).setUp() @@ -2393,7 +2529,7 @@ class TemplateIpsecItf4(object): encryption_type = ESP tun4_encrypt_node_name = "esp4-encrypt-tun" - tun4_decrypt_node_name = "esp4-decrypt-tun" + tun4_decrypt_node_name = ["esp4-decrypt-tun", "esp4-decrypt-tun-post"] tun4_input_node = "ipsec4-tun-input" def config_sa_tun(self, p, src, dst): @@ -2452,6 +2588,7 @@ class TemplateIpsecItf4(object): p.tun_sa_in.remove_vpp_config() +@tag_fixme_vpp_workers class TestIpsecItf4(TemplateIpsec, TemplateIpsecItf4, IpsecTun4): @@ -2484,35 +2621,33 @@ class TestIpsecItf4(TemplateIpsec, p = self.ipv4_params self.config_network(p) + config_tun_params(p, self.encryption_type, None, + self.pg0.local_ip4, + self.pg0.remote_ip4) + self.verify_tun_dropped_44(p, count=n_pkts) self.config_sa_tun(p, self.pg0.local_ip4, self.pg0.remote_ip4) self.config_protect(p) self.verify_tun_44(p, count=n_pkts) - c = p.tun_if.get_rx_stats() - self.assertEqual(c['packets'], n_pkts) - c = p.tun_if.get_tx_stats() - self.assertEqual(c['packets'], n_pkts) + self.assertEqual(p.tun_if.get_rx_stats(), n_pkts) + self.assertEqual(p.tun_if.get_tx_stats(), n_pkts) p.tun_if.admin_down() self.verify_tun_dropped_44(p, count=n_pkts) p.tun_if.admin_up() self.verify_tun_44(p, count=n_pkts) - c = p.tun_if.get_rx_stats() - self.assertEqual(c['packets'], 3*n_pkts) - c = p.tun_if.get_tx_stats() - self.assertEqual(c['packets'], 2*n_pkts) + self.assertEqual(p.tun_if.get_rx_stats(), 3*n_pkts) + self.assertEqual(p.tun_if.get_tx_stats(), 2*n_pkts) # it's a v6 packet when its encrypted self.tun4_encrypt_node_name = "esp6-encrypt-tun" self.verify_tun_64(p, count=n_pkts) - c = p.tun_if.get_rx_stats() - self.assertEqual(c['packets'], 4*n_pkts) - c = p.tun_if.get_tx_stats() - self.assertEqual(c['packets'], 3*n_pkts) + self.assertEqual(p.tun_if.get_rx_stats(), 4*n_pkts) + self.assertEqual(p.tun_if.get_tx_stats(), 3*n_pkts) self.tun4_encrypt_node_name = "esp4-encrypt-tun" @@ -2535,10 +2670,8 @@ class TestIpsecItf4(TemplateIpsec, self.unconfig_sa(p) self.verify_tun_44(np, count=n_pkts) - c = p.tun_if.get_rx_stats() - self.assertEqual(c['packets'], n_pkts) - c = p.tun_if.get_tx_stats() - self.assertEqual(c['packets'], n_pkts) + self.assertEqual(p.tun_if.get_rx_stats(), n_pkts) + self.assertEqual(p.tun_if.get_tx_stats(), n_pkts) # teardown self.unconfig_protect(np) @@ -2564,9 +2697,58 @@ class TestIpsecItf4(TemplateIpsec, self.pg0.remote_ip4) self.config_protect(p) + self.logger.info(self.vapi.cli("sh ipsec sa")) + self.verify_tun_44(p, count=n_pkts) + + # teardown + self.unconfig_protect(p) + self.unconfig_sa(p) + self.unconfig_network(p) + + def test_tun_44_police(self): + """IPSEC interface IPv4 with input policer""" + n_pkts = 127 + p = self.ipv4_params + + self.config_network(p) + self.config_sa_tun(p, + self.pg0.local_ip4, + self.pg0.remote_ip4) + self.config_protect(p) + + action_tx = PolicerAction( + VppEnum.vl_api_sse2_qos_action_type_t.SSE2_QOS_ACTION_API_TRANSMIT, + 0) + policer = VppPolicer(self, "pol1", 80, 0, 1000, 0, + conform_action=action_tx, + exceed_action=action_tx, + violate_action=action_tx) + policer.add_vpp_config() + + # Start policing on tun + policer.apply_vpp_config(p.tun_if.sw_if_index, Dir.RX, True) + + self.verify_tun_44(p, count=n_pkts) + self.assertEqual(p.tun_if.get_rx_stats(), n_pkts) + self.assertEqual(p.tun_if.get_tx_stats(), n_pkts) + + stats = policer.get_stats() + + # Single rate, 2 colour policer - expect conform, violate but no exceed + self.assertGreater(stats['conform_packets'], 0) + self.assertEqual(stats['exceed_packets'], 0) + self.assertGreater(stats['violate_packets'], 0) + + # Stop policing on tun + policer.apply_vpp_config(p.tun_if.sw_if_index, Dir.RX, False) self.verify_tun_44(p, count=n_pkts) + # No new policer stats + statsnew = policer.get_stats() + self.assertEqual(stats, statsnew) + # teardown + policer.remove_vpp_config() self.unconfig_protect(p) self.unconfig_sa(p) self.unconfig_network(p) @@ -2653,7 +2835,7 @@ class TemplateIpsecItf6(object): encryption_type = ESP tun6_encrypt_node_name = "esp6-encrypt-tun" - tun6_decrypt_node_name = "esp6-decrypt-tun" + tun6_decrypt_node_name = ["esp6-decrypt-tun", "esp6-decrypt-tun-post"] tun6_input_node = "ipsec6-tun-input" def config_sa_tun(self, p, src, dst): @@ -2720,6 +2902,7 @@ class TemplateIpsecItf6(object): p.tun_sa_in.remove_vpp_config() +@tag_fixme_vpp_workers class TestIpsecItf6(TemplateIpsec, TemplateIpsecItf6, IpsecTun6): @@ -2733,7 +2916,7 @@ class TestIpsecItf6(TemplateIpsec, def tearDown(self): super(TestIpsecItf6, self).tearDown() - def test_tun_44(self): + def test_tun_66(self): """IPSEC interface IPv6""" tf = VppEnum.vl_api_tunnel_encap_decap_flags_t @@ -2745,35 +2928,33 @@ class TestIpsecItf6(TemplateIpsec, p.tun_flags = tf.TUNNEL_API_ENCAP_DECAP_FLAG_ENCAP_COPY_HOP_LIMIT self.config_network(p) + config_tun_params(p, self.encryption_type, None, + self.pg0.local_ip6, + self.pg0.remote_ip6) + self.verify_drop_tun_66(p, count=n_pkts) self.config_sa_tun(p, self.pg0.local_ip6, self.pg0.remote_ip6) self.config_protect(p) self.verify_tun_66(p, count=n_pkts) - c = p.tun_if.get_rx_stats() - self.assertEqual(c['packets'], n_pkts) - c = p.tun_if.get_tx_stats() - self.assertEqual(c['packets'], n_pkts) + self.assertEqual(p.tun_if.get_rx_stats(), n_pkts) + self.assertEqual(p.tun_if.get_tx_stats(), n_pkts) p.tun_if.admin_down() self.verify_drop_tun_66(p, count=n_pkts) p.tun_if.admin_up() self.verify_tun_66(p, count=n_pkts) - c = p.tun_if.get_rx_stats() - self.assertEqual(c['packets'], 3*n_pkts) - c = p.tun_if.get_tx_stats() - self.assertEqual(c['packets'], 2*n_pkts) + self.assertEqual(p.tun_if.get_rx_stats(), 3*n_pkts) + self.assertEqual(p.tun_if.get_tx_stats(), 2*n_pkts) # it's a v4 packet when its encrypted self.tun6_encrypt_node_name = "esp4-encrypt-tun" self.verify_tun_46(p, count=n_pkts) - c = p.tun_if.get_rx_stats() - self.assertEqual(c['packets'], 4*n_pkts) - c = p.tun_if.get_tx_stats() - self.assertEqual(c['packets'], 3*n_pkts) + self.assertEqual(p.tun_if.get_rx_stats(), 4*n_pkts) + self.assertEqual(p.tun_if.get_tx_stats(), 3*n_pkts) self.tun6_encrypt_node_name = "esp6-encrypt-tun" @@ -2802,21 +2983,72 @@ class TestIpsecItf6(TemplateIpsec, self.unconfig_sa(p) self.verify_tun_66(np, count=n_pkts) - c = p.tun_if.get_rx_stats() - self.assertEqual(c['packets'], n_pkts) - c = p.tun_if.get_tx_stats() - self.assertEqual(c['packets'], n_pkts) + self.assertEqual(p.tun_if.get_rx_stats(), n_pkts) + self.assertEqual(p.tun_if.get_tx_stats(), n_pkts) # teardown self.unconfig_protect(np) self.unconfig_sa(np) self.unconfig_network(p) + def test_tun_66_police(self): + """IPSEC interface IPv6 with input policer""" + tf = VppEnum.vl_api_tunnel_encap_decap_flags_t + n_pkts = 127 + p = self.ipv6_params + p.inner_hop_limit = 24 + p.outer_hop_limit = 23 + p.outer_flow_label = 243224 + p.tun_flags = tf.TUNNEL_API_ENCAP_DECAP_FLAG_ENCAP_COPY_HOP_LIMIT + + self.config_network(p) + self.config_sa_tun(p, + self.pg0.local_ip6, + self.pg0.remote_ip6) + self.config_protect(p) + + action_tx = PolicerAction( + VppEnum.vl_api_sse2_qos_action_type_t.SSE2_QOS_ACTION_API_TRANSMIT, + 0) + policer = VppPolicer(self, "pol1", 80, 0, 1000, 0, + conform_action=action_tx, + exceed_action=action_tx, + violate_action=action_tx) + policer.add_vpp_config() + + # Start policing on tun + policer.apply_vpp_config(p.tun_if.sw_if_index, Dir.RX, True) + + self.verify_tun_66(p, count=n_pkts) + self.assertEqual(p.tun_if.get_rx_stats(), n_pkts) + self.assertEqual(p.tun_if.get_tx_stats(), n_pkts) + + stats = policer.get_stats() + + # Single rate, 2 colour policer - expect conform, violate but no exceed + self.assertGreater(stats['conform_packets'], 0) + self.assertEqual(stats['exceed_packets'], 0) + self.assertGreater(stats['violate_packets'], 0) + + # Stop policing on tun + policer.apply_vpp_config(p.tun_if.sw_if_index, Dir.RX, False) + self.verify_tun_66(p, count=n_pkts) + + # No new policer stats + statsnew = policer.get_stats() + self.assertEqual(stats, statsnew) + + # teardown + policer.remove_vpp_config() + self.unconfig_protect(p) + self.unconfig_sa(p) + self.unconfig_network(p) + class TestIpsecMIfEsp4(TemplateIpsec, IpsecTun4): """ Ipsec P2MP ESP v4 tests """ tun4_encrypt_node_name = "esp4-encrypt-tun" - tun4_decrypt_node_name = "esp4-decrypt-tun" + tun4_decrypt_node_name = ["esp4-decrypt-tun", "esp4-decrypt-tun-post"] encryption_type = ESP def gen_encrypt_pkts(self, p, sa, sw_intf, src, dst, count=1, @@ -2879,6 +3111,15 @@ class TestIpsecMIfEsp4(TemplateIpsec, IpsecTun4): self.pg0.generate_remote_hosts(N_NHS) self.pg0.configure_ipv4_neighbors() + r_all = AclRule(True, + src_prefix="0.0.0.0/0", + dst_prefix="0.0.0.0/0", + proto=0) + a = VppAcl(self, [r_all]).add_vpp_config() + + VppAclInterface(self, self.pg0.sw_if_index, [a]).add_vpp_config() + VppAclInterface(self, p.tun_if.sw_if_index, [a]).add_vpp_config() + # setup some SAs for several next-hops on the interface self.multi_params = [] @@ -2930,9 +3171,10 @@ class TestIpsecMIfEsp4(TemplateIpsec, IpsecTun4): self.pg0.remote_hosts[ii].ip4) self.multi_params.append(p) - VppIpRoute(self, p.remote_tun_if_host, 32, - [VppRoutePath(p.tun_if.remote_hosts[ii].ip4, - p.tun_if.sw_if_index)]).add_vpp_config() + p.via_tun_route = VppIpRoute( + self, p.remote_tun_if_host, 32, + [VppRoutePath(p.tun_if.remote_hosts[ii].ip4, + p.tun_if.sw_if_index)]).add_vpp_config() p.tun_dst = self.pg0.remote_hosts[ii].ip4 @@ -2947,6 +3189,21 @@ class TestIpsecMIfEsp4(TemplateIpsec, IpsecTun4): for p in self.multi_params: self.verify_tun_44(p, count=N_PKTS) + # remove one tunnel protect, the rest should still work + self.multi_params[0].tun_protect.remove_vpp_config() + self.verify_tun_dropped_44(self.multi_params[0], count=N_PKTS) + self.multi_params[0].via_tun_route.remove_vpp_config() + self.verify_tun_dropped_44(self.multi_params[0], count=N_PKTS) + + for p in self.multi_params[1:]: + self.verify_tun_44(p, count=N_PKTS) + + self.multi_params[0].tun_protect.add_vpp_config() + self.multi_params[0].via_tun_route.add_vpp_config() + + for p in self.multi_params: + self.verify_tun_44(p, count=N_PKTS) + class TestIpsecItf6MPLS(TemplateIpsec, TemplateIpsecItf6,