X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;ds=sidebyside;f=test%2Ftest_punt.py;h=ac059e904bd66b02d5190895efe72ca349ab9163;hb=687cf6faf29af9ae683965b09d4648fd60f786af;hp=0b4585a15c7961d00ad985f1e5fe05f1228d1277;hpb=cb265c6948658a10a46252afc889403f0baab31c;p=vpp.git diff --git a/test/test_punt.py b/test/test_punt.py index 0b4585a15c7..ac059e904bd 100644 --- a/test/test_punt.py +++ b/test/test_punt.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import binascii import random import socket @@ -6,6 +6,9 @@ import os import threading import struct import copy +import fcntl +import time + from struct import unpack, unpack_from try: @@ -23,13 +26,13 @@ from scapy.layers.ipsec import ESP import scapy.layers.inet6 as inet6 from scapy.layers.inet6 import IPv6, ICMPv6DestUnreach from scapy.contrib.ospf import OSPF_Hdr, OSPFv3_Hello -import six +from framework import tag_fixme_vpp_workers from framework import VppTestCase, VppTestRunner from vpp_ip import DpoProto from vpp_ip_route import VppIpRoute, VppRoutePath +from vpp_ipsec import VppIpsecSA, VppIpsecTunProtect, VppIpsecInterface from vpp_papi import VppEnum -from vpp_ipsec_tun_interface import VppIpsecTunInterface NUM_PKTS = 67 @@ -43,17 +46,28 @@ class serverSocketThread(threading.Thread): self.sockName = sockName self.sock = None self.rx_pkts = [] + self.stop_running = False def rx_packets(self): # Wait for some packets on socket while True: - data = self.sock.recv(65536) - - # punt socket metadata - # packet_desc = data[0:8] - - # Ethernet - self.rx_pkts.append(Ether(data[8:])) + try: + data = self.sock.recv(65536) + + # punt socket metadata + # packet_desc = data[0:8] + + # Ethernet + self.rx_pkts.append(Ether(data[8:])) + except IOError as e: + if e.errno == 11: + # nothing to receive, stop running or sleep a little + if self.stop_running: + break + time.sleep(0.1) + pass + else: + raise def run(self): self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM) @@ -63,11 +77,14 @@ class serverSocketThread(threading.Thread): pass self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 65536) self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 65536) + fcntl.fcntl(self.sock, fcntl.F_SETFL, os.O_NONBLOCK) self.sock.bind(self.sockName) self.rx_packets() def close(self): + self.stop_running = True + threading.Thread.join(self) self.sock.close() return self.rx_pkts @@ -231,11 +248,9 @@ class TestIP4PuntSocket(TestPuntSocket): punt_l4 = mk_vpp_cfg4() self.vapi.punt_socket_register(set_port(punt_l4, 1111), - b"%s/socket_punt_1111" % - six.ensure_binary(self.tempdir)) + "%s/socket_punt_1111" % self.tempdir) self.vapi.punt_socket_register(set_port(punt_l4, 2222), - b"%s/socket_punt_2222" % - six.ensure_binary(self.tempdir)) + "%s/socket_punt_2222" % self.tempdir) punts = self.vapi.punt_socket_dump(type=pt_l4) self.assertEqual(len(punts), 2) self.verify_port(set_port(punt_l4, 1111), punts[0]) @@ -252,11 +267,9 @@ class TestIP4PuntSocket(TestPuntSocket): # configure a punt socket again # self.vapi.punt_socket_register(set_port(punt_l4, 1111), - b"%s/socket_punt_1111" % - six.ensure_binary(self.tempdir)) + "%s/socket_punt_1111" % self.tempdir) self.vapi.punt_socket_register(set_port(punt_l4, 3333), - b"%s/socket_punt_3333" % - six.ensure_binary(self.tempdir)) + "%s/socket_punt_3333" % self.tempdir) punts = self.vapi.punt_socket_dump(type=pt_l4) self.assertEqual(len(punts), 3) @@ -282,7 +295,7 @@ class TestIP4PuntSocket(TestPuntSocket): dst=self.pg0.local_mac) / IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4) / UDP(sport=9876, dport=port) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) pkts = p * self.nr_packets @@ -292,7 +305,7 @@ class TestIP4PuntSocket(TestPuntSocket): # # expect ICMP - port unreachable for all packets # - rx = self.send_and_expect(self.pg0, pkts, self.pg0) + rx = self.send_and_expect_some(self.pg0, pkts, self.pg0) for p in rx: self.assertEqual(int(p[IP].proto), 1) # ICMP @@ -301,10 +314,9 @@ class TestIP4PuntSocket(TestPuntSocket): # # configure a punt socket # - self.socket_client_create(b"%s/socket_%d" % ( - six.ensure_binary(self.tempdir), port)) - self.vapi.punt_socket_register(punt_l4, b"%s/socket_%d" % ( - six.ensure_binary(self.tempdir), port)) + self.socket_client_create("%s/socket_%d" % (self.tempdir, port)) + self.vapi.punt_socket_register(punt_l4, "%s/socket_%d" % + (self.tempdir, port)) punts = self.vapi.punt_socket_dump(type=pt_l4) self.assertEqual(len(punts), 1) @@ -322,7 +334,7 @@ class TestIP4PuntSocket(TestPuntSocket): punts = self.vapi.punt_socket_dump(type=pt_l4) self.assertEqual(len(punts), 0) - rx = self.send_and_expect(self.pg0, pkts, self.pg0) + rx = self.send_and_expect_some(self.pg0, pkts, self.pg0) for p in rx: self.assertEqual(int(p[IP].proto), 1) # ICMP self.assertEqual(int(p[ICMP].code), 3) # unreachable @@ -346,18 +358,17 @@ class TestIP4PuntSocket(TestPuntSocket): dst=self.pg0.local_mac) / IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4) / UDP(sport=9876, dport=port) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) cfgs[port]['pkts'] = pkt * self.nr_packets cfgs[port]['port'] = port cfgs[port]['vpp'] = copy.deepcopy(set_port(punt_l4, port)) # configure punt sockets cfgs[port]['sock'] = self.socket_client_create( - b"%s/socket_%d" % (six.ensure_binary(self.tempdir), port)) + "%s/socket_%d" % (self.tempdir, port)) self.vapi.punt_socket_register( cfgs[port]['vpp'], - b"%s/socket_%d" % (six.ensure_binary(self.tempdir), - port)) + "%s/socket_%d" % (self.tempdir, port)) # # send the packets that get punted @@ -389,18 +400,16 @@ class TestIP4PuntSocket(TestPuntSocket): dst=self.pg0.local_mac) / IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4) / UDP(sport=9876, dport=port) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) pkts += pkt * self.nr_packets # # configure a punt socket # - self.socket_client_create(b"%s/socket_multi" % - six.ensure_binary(self.tempdir)) + self.socket_client_create("%s/socket_multi" % self.tempdir) for p in self.ports: self.vapi.punt_socket_register(set_port(punt_l4, p), - b"%s/socket_multi" % - six.ensure_binary(self.tempdir)) + "%s/socket_multi" % self.tempdir) punts = self.vapi.punt_socket_dump(type=pt_l4) self.assertEqual(len(punts), len(self.ports)) @@ -468,11 +477,9 @@ class TestIP6PuntSocket(TestPuntSocket): # configure a punt socket # self.vapi.punt_socket_register(set_port(punt_l4, 1111), - b"%s/socket_1111" % - six.ensure_binary(self.tempdir)) + "%s/socket_1111" % self.tempdir) self.vapi.punt_socket_register(set_port(punt_l4, 2222), - b"%s/socket_2222" % - six.ensure_binary(self.tempdir)) + "%s/socket_2222" % self.tempdir) punts = self.vapi.punt_socket_dump(type=pt_l4) self.assertEqual(len(punts), 2) self.verify_port(set_port(punt_l4, 1111), punts[0]) @@ -489,8 +496,7 @@ class TestIP6PuntSocket(TestPuntSocket): # configure a punt socket again # self.vapi.punt_socket_register(set_port(punt_l4, 1111), - b"%s/socket_1111" % - six.ensure_binary(self.tempdir)) + "%s/socket_1111" % self.tempdir) punts = self.vapi.punt_socket_dump(type=pt_l4) self.assertEqual(len(punts), 2) @@ -525,7 +531,7 @@ class TestIP6PuntSocket(TestPuntSocket): dst=self.pg0.local_mac) / IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6) / inet6.UDP(sport=9876, dport=port) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) pkts = p * self.nr_packets @@ -548,10 +554,9 @@ class TestIP6PuntSocket(TestPuntSocket): # # configure a punt socket # - self.socket_client_create(b"%s/socket_%d" % ( - six.ensure_binary(self.tempdir), port)) - self.vapi.punt_socket_register(punt_l4, b"%s/socket_%d" % ( - six.ensure_binary(self.tempdir), port)) + self.socket_client_create("%s/socket_%d" % (self.tempdir, port)) + self.vapi.punt_socket_register(punt_l4, "%s/socket_%d" % + (self.tempdir, port)) punts = self.vapi.punt_socket_dump(type=pt_l4) self.assertEqual(len(punts), 1) @@ -599,18 +604,17 @@ class TestIP6PuntSocket(TestPuntSocket): dst=self.pg0.local_mac) / IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6) / UDP(sport=9876, dport=port) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) cfgs[port]['pkts'] = pkt * self.nr_packets cfgs[port]['port'] = port cfgs[port]['vpp'] = copy.deepcopy(set_port(punt_l4, port)) # configure punt sockets cfgs[port]['sock'] = self.socket_client_create( - b"%s/socket_%d" % (six.ensure_binary(self.tempdir), port)) + "%s/socket_%d" % (self.tempdir, port)) self.vapi.punt_socket_register( cfgs[port]['vpp'], - b"%s/socket_%d" % (six.ensure_binary(self.tempdir), - port)) + "%s/socket_%d" % (self.tempdir, port)) # # send the packets that get punted @@ -652,7 +656,7 @@ class TestIP6PuntSocket(TestPuntSocket): dst=self.pg0.local_mac) / IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6) / UDP(sport=9876, dport=port) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) pkts += pkt * self.nr_packets # @@ -664,12 +668,10 @@ class TestIP6PuntSocket(TestPuntSocket): # # configure a punt socket # - self.socket_client_create(b"%s/socket_multi" % - six.ensure_binary(self.tempdir)) + self.socket_client_create("%s/socket_multi" % self.tempdir) for p in self.ports: self.vapi.punt_socket_register(set_port(punt_l4, p), - b"%s/socket_multi" % - six.ensure_binary(self.tempdir)) + "%s/socket_multi" % self.tempdir) punts = self.vapi.punt_socket_dump(type=pt_l4) self.assertEqual(len(punts), len(self.ports)) @@ -707,6 +709,7 @@ class TestExceptionPuntSocket(TestPuntSocket): def setUp(self): super(TestExceptionPuntSocket, self).setUp() + self.create_pg_interfaces(range(2)) for i in self.pg_interfaces: i.config_ip4() i.resolve_arp() @@ -736,11 +739,9 @@ class TestExceptionPuntSocket(TestPuntSocket): } self.vapi.punt_socket_register(set_reason(punt_ex, 1), - b"%s/socket_punt_1" % - six.ensure_binary(self.tempdir)) + "%s/socket_punt_1" % self.tempdir) self.vapi.punt_socket_register(set_reason(punt_ex, 2), - b"%s/socket_punt_2" % - six.ensure_binary(self.tempdir)) + "%s/socket_punt_2" % self.tempdir) punts = self.vapi.punt_socket_dump(type=pt_ex) self.assertEqual(len(punts), 2) self.verify_exception(set_reason(punt_ex, 1), punts[0]) @@ -757,11 +758,9 @@ class TestExceptionPuntSocket(TestPuntSocket): # configure a punt socket again # self.vapi.punt_socket_register(set_reason(punt_ex, 1), - b"%s/socket_punt_1" % - six.ensure_binary(self.tempdir)) + "%s/socket_punt_1" % self.tempdir) self.vapi.punt_socket_register(set_reason(punt_ex, 3), - b"%s/socket_punt_3" % - six.ensure_binary(self.tempdir)) + "%s/socket_punt_3" % self.tempdir) punts = self.vapi.punt_socket_dump(type=pt_ex) self.assertEqual(len(punts), 3) @@ -797,37 +796,14 @@ class TestExceptionPuntSocket(TestPuntSocket): } } - # - # we need an IPSec tunnels for this to work otherwise ESP gets dropped - # due to unknown IP proto - # - VppIpsecTunInterface(self, self.pg0, 1000, 1000, - (VppEnum.vl_api_ipsec_crypto_alg_t. - IPSEC_API_CRYPTO_ALG_AES_CBC_128), - "0123456701234567", - "0123456701234567", - (VppEnum.vl_api_ipsec_integ_alg_t. - IPSEC_API_INTEG_ALG_SHA1_96), - "0123456701234567", - "0123456701234567").add_vpp_config() - VppIpsecTunInterface(self, self.pg0, 1001, 1001, - (VppEnum.vl_api_ipsec_crypto_alg_t. - IPSEC_API_CRYPTO_ALG_AES_CBC_128), - "0123456701234567", - "0123456701234567", - (VppEnum.vl_api_ipsec_integ_alg_t. - IPSEC_API_INTEG_ALG_SHA1_96), - "0123456701234567", - "0123456701234567", - udp_encap=True).add_vpp_config() - # # we're dealing with IPSec tunnels punting for no-such-tunnel - # adn SPI=0 + # (SPI=0 goes to ikev2) # cfgs = dict() - cfgs['ipsec4-no-such-tunnel'] = {'spi': 99, 'udp': False} - cfgs['ipsec4-spi-o-udp-0'] = {'spi': 0, 'udp': True} + cfgs['ipsec4-no-such-tunnel'] = {'spi': 99, + 'udp': False, + 'itf': self.pg0} # # find the VPP ID for these punt exception reasin @@ -835,6 +811,8 @@ class TestExceptionPuntSocket(TestPuntSocket): rs = self.vapi.punt_reason_dump() for key in cfgs: for r in rs: + print(r.reason.name) + print(key) if r.reason.name == key: cfgs[key]['id'] = r.reason.id cfgs[key]['vpp'] = copy.deepcopy( @@ -846,31 +824,30 @@ class TestExceptionPuntSocket(TestPuntSocket): # configure punt sockets # for cfg in cfgs.values(): - cfg['sock'] = self.socket_client_create(b"%s/socket_%d" % ( - six.ensure_binary(self.tempdir), cfg['id'])) + cfg['sock'] = self.socket_client_create("%s/socket_%d" % + (self.tempdir, cfg['id'])) self.vapi.punt_socket_register( - cfg['vpp'], - b"%s/socket_%d" % (six.ensure_binary(self.tempdir), - cfg['id'])) + cfg['vpp'], "%s/socket_%d" % (self.tempdir, cfg['id'])) # # create packet streams for 'no-such-tunnel' exception # for cfg in cfgs.values(): - pkt = (Ether(src=self.pg0.remote_mac, - dst=self.pg0.local_mac) / - IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4)) + pkt = (Ether(src=cfg['itf'].remote_mac, + dst=cfg['itf'].local_mac) / + IP(src=cfg['itf'].remote_ip4, + dst=cfg['itf'].local_ip4)) if (cfg['udp']): pkt = pkt / UDP(sport=666, dport=4500) pkt = (pkt / ESP(spi=cfg['spi'], seq=3) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) cfg['pkts'] = [pkt] # # send packets for each SPI we expect to be punted # for cfg in cfgs.values(): - self.send_and_assert_no_replies(self.pg0, cfg['pkts']) + self.send_and_assert_no_replies(cfg['itf'], cfg['pkts']) # # verify the punted packets arrived on the associated socket @@ -881,6 +858,47 @@ class TestExceptionPuntSocket(TestPuntSocket): cfg['spi'], cfg['udp']) # + # add some tunnels, make sure it still punts + # + tun = VppIpsecInterface(self).add_vpp_config() + sa_in = VppIpsecSA(self, 11, 11, + (VppEnum.vl_api_ipsec_integ_alg_t. + IPSEC_API_INTEG_ALG_SHA1_96), + b"0123456701234567", + (VppEnum.vl_api_ipsec_crypto_alg_t. + IPSEC_API_CRYPTO_ALG_AES_CBC_128), + b"0123456701234567", + 50, + self.pg0.local_ip4, + self.pg0.remote_ip4).add_vpp_config() + sa_out = VppIpsecSA(self, 22, 22, + (VppEnum.vl_api_ipsec_integ_alg_t. + IPSEC_API_INTEG_ALG_SHA1_96), + b"0123456701234567", + (VppEnum.vl_api_ipsec_crypto_alg_t. + IPSEC_API_CRYPTO_ALG_AES_CBC_128), + b"0123456701234567", + 50, + self.pg0.local_ip4, + self.pg0.remote_ip4).add_vpp_config() + protect = VppIpsecTunProtect(self, tun, + sa_out, + [sa_in]).add_vpp_config() + + # + # send packets for each SPI we expect to be punted + # + for cfg in cfgs.values(): + self.send_and_assert_no_replies(cfg['itf'], cfg['pkts']) + + # + # verify the punted packets arrived on the associated socket + # + for cfg in cfgs.values(): + rx = cfg['sock'].close() + self.verify_esp_pkts(rx, len(cfg['pkts']), + cfg['spi'], cfg['udp']) + # # socket deregister # for cfg in cfgs.values(): @@ -945,11 +963,9 @@ class TestIpProtoPuntSocket(TestPuntSocket): } self.vapi.punt_socket_register(punt_ospf, - b"%s/socket_punt_1" % - six.ensure_binary(self.tempdir)) + "%s/socket_punt_1" % self.tempdir) self.vapi.punt_socket_register(punt_eigrp, - b"%s/socket_punt_2" % - six.ensure_binary(self.tempdir)) + "%s/socket_punt_2" % self.tempdir) self.logger.info(self.vapi.cli("sh punt sock reg ip")) punts = self.vapi.punt_socket_dump(type=pt_ip) self.assertEqual(len(punts), 2) @@ -967,8 +983,7 @@ class TestIpProtoPuntSocket(TestPuntSocket): # configure a punt socket again # self.vapi.punt_socket_register(punt_ospf, - b"%s/socket_punt_3" % - six.ensure_binary(self.tempdir)) + "%s/socket_punt_3" % self.tempdir) punts = self.vapi.punt_socket_dump(type=pt_ip) self.assertEqual(len(punts), 2) @@ -1017,11 +1032,9 @@ class TestIpProtoPuntSocket(TestPuntSocket): OSPFv3_Hello()) pkts = pkt * 7 - sock = self.socket_client_create(b"%s/socket_1" % ( - six.ensure_binary(self.tempdir))) + sock = self.socket_client_create("%s/socket_1" % self.tempdir) self.vapi.punt_socket_register( - punt_ospf, - b"%s/socket_1" % (six.ensure_binary(self.tempdir))) + punt_ospf, "%s/socket_1" % self.tempdir) # # send packets for each SPI we expect to be punted @@ -1036,6 +1049,7 @@ class TestIpProtoPuntSocket(TestPuntSocket): self.vapi.punt_socket_deregister(punt_ospf) +@tag_fixme_vpp_workers class TestPunt(VppTestCase): """ Exception Punt Test Case """ @@ -1063,7 +1077,6 @@ class TestPunt(VppTestCase): for i in self.pg_interfaces: i.unconfig_ip4() i.unconfig_ip6() - i.ip6_disable() i.admin_down() super(TestPunt, self).tearDown() @@ -1107,12 +1120,12 @@ class TestPunt(VppTestCase): dst=self.pg2.local_mac) / IP(src="1.1.1.1", dst="1.1.1.2") / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) p6 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) / IPv6(src="1::1", dst="1::2") / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) self.send_and_expect(self.pg2, p4*1, self.pg3) self.send_and_expect(self.pg2, p6*1, self.pg3)