From 6ba4e41d33ffda2596d9d4b3a1d7fdd3c9a6b870 Mon Sep 17 00:00:00 2001 From: Neale Ranns Date: Mon, 19 Oct 2020 09:59:41 +0000 Subject: ipsec: support for multipoint on ipsec interfaces Type: feature Signed-off-by: Neale Ranns Change-Id: Iae9fe35cfbce4c675fa25e0800c0f4629a83e012 --- test/test_ipsec_tun_if_esp.py | 125 +++++++++++++++++++++++++++++++++++++++++- test/vpp_ipsec.py | 7 ++- 2 files changed, 128 insertions(+), 4 deletions(-) (limited to 'test') diff --git a/test/test_ipsec_tun_if_esp.py b/test/test_ipsec_tun_if_esp.py index 9d01b93114e..fb31f221aed 100644 --- a/test/test_ipsec_tun_if_esp.py +++ b/test/test_ipsec_tun_if_esp.py @@ -1576,7 +1576,7 @@ class TestIpsecMGreIfEspTra4(TemplateIpsec, IpsecTun4): # setup some SAs for several next-hops on the interface self.multi_params = [] - for ii in range(1): + for ii in range(N_NHS): p = copy.copy(self.ipv4_params) p.remote_tun_if_host = "1.1.1.%d" % (ii + 1) @@ -2810,5 +2810,128 @@ class TestIpsecItf6(TemplateIpsec, 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" + encryption_type = ESP + + def gen_encrypt_pkts(self, p, sa, sw_intf, src, dst, count=1, + payload_size=100): + return [Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac) / + sa.encrypt(IP(src=self.pg1.local_ip4, + dst=self.pg1.remote_ip4) / + UDP(sport=1144, dport=2233) / + Raw(b'X' * payload_size)) + for i in range(count)] + + def gen_pkts(self, sw_intf, src, dst, count=1, + payload_size=100): + return [Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac) / + IP(src="1.1.1.1", dst=dst) / + UDP(sport=1144, dport=2233) / + Raw(b'X' * payload_size) + for i in range(count)] + + def verify_decrypted(self, p, rxs): + for rx in rxs: + self.assert_equal(rx[Ether].dst, self.pg1.remote_mac) + self.assert_equal(rx[IP].dst, self.pg1.remote_ip4) + + def verify_encrypted(self, p, sa, rxs): + for rx in rxs: + try: + pkt = sa.decrypt(rx[IP]) + if not pkt.haslayer(IP): + pkt = IP(pkt[Raw].load) + self.assert_packet_checksums_valid(pkt) + e = pkt[IP] + self.assertEqual(e[IP].dst, p.remote_tun_if_host) + except (IndexError, AssertionError): + self.logger.debug(ppp("Unexpected packet:", rx)) + try: + self.logger.debug(ppp("Decrypted packet:", pkt)) + except: + pass + raise + + def setUp(self): + super(TestIpsecMIfEsp4, self).setUp() + + N_NHS = 16 + self.tun_if = self.pg0 + p = self.ipv4_params + p.tun_if = VppIpsecInterface(self, + mode=(VppEnum.vl_api_tunnel_mode_t. + TUNNEL_API_MODE_MP)) + p.tun_if.add_vpp_config() + p.tun_if.admin_up() + p.tun_if.config_ip4() + p.tun_if.generate_remote_hosts(N_NHS) + self.pg0.generate_remote_hosts(N_NHS) + self.pg0.configure_ipv4_neighbors() + + # setup some SAs for several next-hops on the interface + self.multi_params = [] + + for ii in range(N_NHS): + p = copy.copy(self.ipv4_params) + + p.remote_tun_if_host = "1.1.1.%d" % (ii + 1) + p.scapy_tun_sa_id = p.scapy_tun_sa_id + ii + p.scapy_tun_spi = p.scapy_tun_spi + ii + p.vpp_tun_sa_id = p.vpp_tun_sa_id + ii + p.vpp_tun_spi = p.vpp_tun_spi + ii + + p.scapy_tra_sa_id = p.scapy_tra_sa_id + ii + p.scapy_tra_spi = p.scapy_tra_spi + ii + p.vpp_tra_sa_id = p.vpp_tra_sa_id + ii + p.vpp_tra_spi = p.vpp_tra_spi + ii + p.tun_sa_out = VppIpsecSA(self, p.scapy_tun_sa_id, p.scapy_tun_spi, + p.auth_algo_vpp_id, p.auth_key, + p.crypt_algo_vpp_id, p.crypt_key, + self.vpp_esp_protocol, + self.pg0.local_ip4, + self.pg0.remote_hosts[ii].ip4) + p.tun_sa_out.add_vpp_config() + + p.tun_sa_in = VppIpsecSA(self, p.vpp_tun_sa_id, p.vpp_tun_spi, + p.auth_algo_vpp_id, p.auth_key, + p.crypt_algo_vpp_id, p.crypt_key, + self.vpp_esp_protocol, + self.pg0.remote_hosts[ii].ip4, + self.pg0.local_ip4) + p.tun_sa_in.add_vpp_config() + + p.tun_protect = VppIpsecTunProtect( + self, + p.tun_if, + p.tun_sa_out, + [p.tun_sa_in], + nh=p.tun_if.remote_hosts[ii].ip4) + p.tun_protect.add_vpp_config() + config_tun_params(p, self.encryption_type, None, + self.pg0.local_ip4, + 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.tun_dst = self.pg0.remote_hosts[ii].ip4 + + def tearDown(self): + p = self.ipv4_params + p.tun_if.unconfig_ip4() + super(TestIpsecMIfEsp4, self).tearDown() + + def test_tun_44(self): + """P2MP IPSEC 44""" + N_PKTS = 63 + for p in self.multi_params: + self.verify_tun_44(p, count=N_PKTS) + + if __name__ == '__main__': unittest.main(testRunner=VppTestRunner) diff --git a/test/vpp_ipsec.py b/test/vpp_ipsec.py index f9dcdf09f1a..479870621e0 100644 --- a/test/vpp_ipsec.py +++ b/test/vpp_ipsec.py @@ -379,9 +379,10 @@ class VppIpsecInterface(VppInterface): def __init__(self, test, mode=None, instance=0xffffffff): super(VppIpsecInterface, self).__init__(test) - # only p2p mode is supported currently - self.mode = (VppEnum.vl_api_tunnel_mode_t. - TUNNEL_API_MODE_P2P) + self.mode = mode + if not self.mode: + self.mode = (VppEnum.vl_api_tunnel_mode_t. + TUNNEL_API_MODE_P2P) self.instance = instance def add_vpp_config(self): -- cgit 1.2.3-korg