diff --git a/src/plugins/memif/memif.c b/src/plugins/memif/memif.c index e352f3faa4..b0ec7d684d 100644 --- a/src/plugins/memif/memif.c +++ b/src/plugins/memif/memif.c @@ -355,7 +355,7 @@ memif_conn_fd_read_ready (unix_file_t * uf) else if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) { - clib_memcpy (fd_array, CMSG_DATA (cmsg), sizeof (fd_array)); + clib_memcpy (fd_array, CMSG_DATA (cmsg), sizeof (fd_array)*2); } cmsg = CMSG_NXTHDR (&mh, cmsg); } diff --git a/test/extra_vpp.py b/test/extra_vpp.py index 47b99d95fc..4e5e6fb1a2 100644 --- a/test/extra_vpp.py +++ b/test/extra_vpp.py @@ -7,12 +7,19 @@ from pickle import dumps, PicklingError from scapy.layers.inet import IP, TCP, UDP, ICMP from scapy.layers.l2 import Ether, ARP -from scapy.utils import rdpcap from scapy.plist import PacketList from framework import VppTestCase from vpp_pg_interface import VppPGInterface -from picklable_packet import PicklablePacket +class PicklablePacket: + def __init__(self, p): + self.bytes = bytes(p) + self.time = p.time + + def __call__(self): + p = Ether(self.bytes) + p.time = self.time + return p class SerializableClassCopy(object): """ @@ -139,15 +146,9 @@ def _remote_exec(self, op, path=None, ret=True, *args, **kwargs): if isinstance(val, RemoteClass) or isinstance(val, RemoteClassAttr): kwargs[key] = val.get_remote_value() # send request - if args: - if type(args[0]) is list: - if type(args[0][0]) is Ether: - l = [] - for p in args[0]: - l.append(PicklablePacket(p)) - del args; - args = (l,); - self._pipe[RemoteClass.PIPE_PARENT].send((op, path, args, kwargs)) + args = self._make_serializable(args) + kwargs = self._make_serializable(kwargs) + self._pipe[RemoteClass.PIPE_PARENT].send((op, path, args, kwargs)) if not ret: # no return value expected return None @@ -162,6 +163,7 @@ def _remote_exec(self, op, path=None, ret=True, *args, **kwargs): return None try: rv = self._pipe[RemoteClass.PIPE_PARENT].recv() + rv = self._deserialize(rv) return rv except EOFError: return None @@ -223,9 +225,11 @@ def _make_obj_serializable(self, obj): Make a serializable copy of an object. Members which are difficult/impossible to serialize are stripped. """ + if type(obj) is Ether: + return PicklablePacket(obj) if self._serializable(obj): return obj # already serializable - copy = SerializableClassCopy() + copy = SerializableClassCopy() # copy at least serializable attributes and properties for name, member in inspect.getmembers(obj): if name[0] == '_': # skip private members @@ -244,18 +248,31 @@ def _make_serializable(self, obj): """ if (type(obj) is list) or (type(obj) is tuple) or (type(obj) is PacketList): rv = [] - if (type(obj) is PacketList): - for p in obj: - rv.append(PicklablePacket(p)) - else: - for item in obj: - rv.append(self._make_serializable(item)) - if type(obj) is tuple: - rv = tuple(rv) + for item in obj: + rv.append(self._make_serializable(item)) + if type(obj) is tuple: + rv = tuple(rv) return rv else: return self._make_obj_serializable(obj) + def _deserialize_obj(self, obj): + if isinstance(obj, PicklablePacket): + return obj() + return obj + + def _deserialize(self, obj): + if (type(obj) is list) or (type(obj) is tuple) or (type(obj) is PacketList): + rv = [] + for item in obj: + rv.append(self._deserialize(item)) + if type(obj) is tuple: + rv = tuple(rv) + return rv + else: + return self._deserialize_obj(obj) + + def start_remote(self): """ Start remote execution """ self.start() @@ -283,6 +300,8 @@ def run(self): rv = None # get request from the parent process (op, path, args, kwargs) = self._pipe[RemoteClass.PIPE_CHILD].recv() + args = self._deserialize(args) + kwargs = self._deserialize(kwargs) path = path.split('.') if path else [] if op == RemoteClass.GET: rv = self._get_local_value(path) @@ -349,3 +368,4 @@ def setTestFunctionInfo(self, name, doc): """ self._testMethodName = name self._testMethodDoc = doc + diff --git a/test/memif.py b/test/memif.py index 9028963d70..a3e9cdadf9 100644 --- a/test/memif.py +++ b/test/memif.py @@ -17,244 +17,244 @@ class MEMIF2(ExtraVpp): - """ second vpp class """ - @classmethod - def setUpClass(cls): - super(MEMIF2, cls).setUpClass() - try: - intf = VppPGInterface(cls, 1) - setattr(cls, intf.name, intf) - cls.pg_interfaces = [intf] - cls.create_loopback_interfaces([0]) - cls.loopback0 = cls.lo_interfaces[0] - cls.loopback0.config_ip4() - cls.loopback0.admin_up() - for i in cls.pg_interfaces: - i.set_ip4('169.54','08') - i.config_ip4() - i.configure_ipv4_neighbors() - i.admin_up() - i.resolve_arp() - #cls.icmp_id = 6305 - - except Exception: - super(MEMIF2, cls).tearDownClass() - raise - - def tearDown(self): - super(MEMIF2, self).tearDown() - if not self.vpp_dead: - self.logger.info(self.vapi.cli("show interfaces address")) - self.logger.info(self.vapi.cli("show memif")) + """ second vpp class """ + @classmethod + def setUpClass(cls): + super(MEMIF2, cls).setUpClass() + try: + intf = VppPGInterface(cls, 1) + setattr(cls, intf.name, intf) + cls.pg_interfaces = [intf] + cls.create_loopback_interfaces([0]) + cls.loopback0 = cls.lo_interfaces[0] + cls.loopback0.config_ip4() + cls.loopback0.admin_up() + for i in cls.pg_interfaces: + i.set_ip4('169.54') + i.config_ip4() + i.configure_ipv4_neighbors() + i.admin_up() + #i.resolve_arp() + #cls.icmp_id = 6305 + + except Exception: + super(MEMIF2, cls).tearDownClass() + raise + + def tearDown(self): + super(MEMIF2, self).tearDown() + if not self.vpp_dead: + self.logger.info(self.vapi.cli("show interfaces address")) + self.logger.info(self.vapi.cli("show memif")) class MEMIF3(ExtraVpp): - """ third vpp class """ - @classmethod - def setUpClass(cls): - super(MEMIF3, cls).setUpClass() - try: - intf = VppPGInterface(cls, 1) - setattr(cls, intf.name, intf) - cls.pg_interfaces = [intf] - cls.create_loopback_interfaces([0]) - cls.loopback0 = cls.lo_interfaces[0] - cls.loopback0.config_ip4() - cls.loopback0.admin_up() - for i in cls.pg_interfaces: - i.set_ip4('169.55','07') - i.config_ip4() - i.configure_ipv4_neighbors() - i.admin_up() - i.resolve_arp() - #cls.icmp_id = 6305 - - except Exception: - super(MEMIF3, cls).tearDownClass() - raise - - def tearDown(self): - super(MEMIF3, self).tearDown() - if not self.vpp_dead: - self.logger.info(self.vapi.cli("show interfaces address")) - self.logger.info(self.vapi.cli("show memif")) - - + """ third vpp class """ + @classmethod + def setUpClass(cls): + super(MEMIF3, cls).setUpClass() + try: + intf = VppPGInterface(cls, 1) + setattr(cls, intf.name, intf) + cls.pg_interfaces = [intf] + cls.create_loopback_interfaces([0]) + cls.loopback0 = cls.lo_interfaces[0] + cls.loopback0.config_ip4() + cls.loopback0.admin_up() + for i in cls.pg_interfaces: + i.set_ip4('169.55') + i.config_ip4() + i.configure_ipv4_neighbors() + i.admin_up() + #i.resolve_arp() + #cls.icmp_id = 6303 + + except Exception: + super(MEMIF3, cls).tearDownClass() + raise + + def tearDown(self): + super(MEMIF3, self).tearDown() + if not self.vpp_dead: + self.logger.info(self.vapi.cli("show interfaces address")) + self.logger.info(self.vapi.cli("show memif")) + + class MEMIFApi(object): - - @staticmethod - def create_memif(vpp, key=0, role='slave', socket='', - ring_size=0, buffer_size=0, hw_addr='00:00:00:00:00:00'): - """ - Create Memif interface - :param vpp: VPPTestCase instance - :param key: 64bit integer used to authenticate and match opposite sides - of the connection - :param role: role of the interface in the connection (master/slave) - :param socket: filename of the socket to be used for connection - establishment - :returns: sw_if_index - """ - role_id = (1 if role == 'slave' else 0) - reply = vpp.vapi.memif_create(role_id, key, socket, ring_size, buffer_size, hw_addr) - return reply.sw_if_index - - - @staticmethod - def delete_memif(vpp, sw_if_index): - vpp.vapi.memif_delete(sw_if_index) - - - @staticmethod - def dump_memif(vpp, sw_if_index=None): - memifs = vpp.vapi.memif_dump() - if sw_if_index is None: - return memifs - else: - for memif in memifs: - if memif.sw_if_index == sw_if_index: - return memif - return None - - @staticmethod - def log_memif_config(vpp): - dump = vpp.vapi.memif_dump() - for memif in dump: - if_name = memif.if_name.rstrip('\0') - vpp.logger.info('%s: sw_if_index %d mac %s', - if_name, memif.sw_if_index, - ':'.join([('%0.2x' % ord(i)) for i in memif.hw_addr])) - vpp.logger.info('%s: key %d socket %s role %s', - if_name, memif.key, memif.socket_filename.rstrip('\0'), - 'slave' if memif.role else 'master') - vpp.logger.info('%s: ring_size %d buffer_size %d', - if_name, memif.ring_size, memif.buffer_size) - vpp.logger.info('%s: state %s link %s', - if_name, - 'up' if memif.admin_up_down else 'down', - 'up' if memif.link_up_down else 'down') - - - + + @staticmethod + def create_memif(vpp, key=0, role='slave', socket='', + ring_size=0, buffer_size=0, hw_addr='00:00:00:00:00:00'): + """ + Create Memif interface + :param vpp: VPPTestCase instance + :param key: 64bit integer used to authenticate and match opposite sides + of the connection + :param role: role of the interface in the connection (master/slave) + :param socket: filename of the socket to be used for connection + establishment + :returns: sw_if_index + """ + role_id = (1 if role == 'slave' else 0) + reply = vpp.vapi.memif_create(role_id, key, socket, ring_size, buffer_size, hw_addr) + return reply.sw_if_index + + + @staticmethod + def delete_memif(vpp, sw_if_index): + vpp.vapi.memif_delete(sw_if_index) + + + @staticmethod + def dump_memif(vpp, sw_if_index=None): + memifs = vpp.vapi.memif_dump() + if sw_if_index is None: + return memifs + else: + for memif in memifs: + if memif.sw_if_index == sw_if_index: + return memif + return None + + @staticmethod + def log_memif_config(vpp): + dump = vpp.vapi.memif_dump() + for memif in dump: + if_name = memif.if_name.rstrip('\0') + vpp.logger.info('%s: sw_if_index %d mac %s', + if_name, memif.sw_if_index, + ':'.join([('%0.2x' % ord(i)) for i in memif.hw_addr])) + vpp.logger.info('%s: key %d socket %s role %s', + if_name, memif.key, memif.socket_filename.rstrip('\0'), + 'slave' if memif.role else 'master') + vpp.logger.info('%s: ring_size %d buffer_size %d', + if_name, memif.ring_size, memif.buffer_size) + vpp.logger.info('%s: state %s link %s', + if_name, + 'up' if memif.admin_up_down else 'down', + 'up' if memif.link_up_down else 'down') class MEMIFTestCase(VppTestCase): - """ parent class for memif test cases """ - - @classmethod - def setUpClass(cls): - cls.vpp2 = RemoteClass(MEMIF2) - cls.vpp2.start_remote() - cls.vpp2.setUpClass() - cls.vpp3 = RemoteClass(MEMIF3) - cls.vpp3.start_remote() - cls.vpp3.setUpClass() - super(MEMIFTestCase, cls).setUpClass() - try: - cls.create_pg_interfaces(range(1)) - cls.create_loopback_interfaces([0]) - cls.loopback0 = cls.lo_interfaces[0] - cls.loopback0.config_ip4() - cls.loopback0.admin_up() - for i in cls.pg_interfaces: - i.config_ip4() - i.configure_ipv4_neighbors() - i.admin_up() - i.resolve_arp() - #cls.icmp_id = 6305 - - except Exception: - super(MEMIFTestCase, cls).tearDownClass() - raise - - - @staticmethod - def create_icmp(vpp, src_if, dst_if, ttl=64): - """ - Create ICMP packet - - :param vpp: VPPTestCase instance - :param in_if: Inside interface - :param out_if: Outside interface - :param ttl: TTL of the generated packet - """ - p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) / - IP(src=src_if.remote_ip4, dst=dst_if.remote_ip4, ttl=ttl) / - ICMP(id=src_if.sw_if_index, type='echo-request')) - return p - - - @staticmethod - def create_UDPp(self, src_if, dst_if): - """ - Create UDP packet - - :param src_if: Inside interface - :param dst_if: Outside interface - """ - p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) / - IP(src=src_if.remote_ip4, dst=dst_if.remote_ip4) / - UDP(sport=1234, dport=5678) / - Raw(payload)) - return p - - - @staticmethod - def clear_memif_config(self): - """ Clear Memif configuration """ - # VPP 1 - for memif in MEMIFApi.dump_memif(self): - self.logger.info("Deleting memif sw_if_index: %d" % memif.sw_if_index) - MEMIFApi.delete_memif(self, memif.sw_if_index) - MEMIFApi.log_memif_config(self) - - # VPP 2 - for memif in MEMIFApi.dump_memif(self.vpp2): - self.logger.info("Deleting memif sw_if_index: %d" % memif.sw_if_index) - MEMIFApi.delete_memif(self.vpp2, memif.sw_if_index) - MEMIFApi.log_memif_config(self.vpp2) - - - def setUp(self): - """ - Create memory interface - """ - super(MEMIFTestCase, self).setUp() - master_if_index = MEMIFApi.create_memif(self, 15, 'master', - '/tmp/vpp.sock', 512, 4096, 'aa:bb:cc:11:22:33') - self.logger.info("Created memif sw_if_index: %d" % master_if_index) - self.vpp2.set_request_timeout(10) - - - def tearDown(self): - """ - Delete memory interface - """ - super(MEMIFTestCase, self).tearDown() - if not self.vpp_dead: - self.logger.info(self.vapi.cli("show interfaces address")) - self.logger.info(self.vapi.cli("show memif")) - self.vpp2.tearDown() - self.vpp3.tearDown() - if not self.vpp_dead and not self.vpp2.vpp_dead.get_remote_value(): - self.clear_memif_config(self) - if not self.vpp3.vpp_dead.get_remote_value(): - for m in MEMIFApi.dump_memif(self.vpp3): - self.logger.info("Deleting memif sw_if_index: %d" - % m.sw_if_index) - MEMIFApi.delete_memif(self.vpp3, m.sw_if_index) - MEMIFApi.log_memif_config(self.vpp3) - - @classmethod - def tearDownClass(cls): - cls.vpp2.tearDownClass() - cls.vpp2.quit_remote() - cls.vpp2.join() - cls.vpp3.tearDownClass() - cls.vpp3.quit_remote() - cls.vpp3.join() - super(MEMIFTestCase, cls).tearDownClass() + """ parent class for memif test cases """ + + @classmethod + def setUpClass(cls): + cls.vpp2 = RemoteClass(MEMIF2) + cls.vpp2.start_remote() + cls.vpp2.setUpClass() + cls.vpp3 = RemoteClass(MEMIF3) + cls.vpp3.start_remote() + cls.vpp3.setUpClass() + super(MEMIFTestCase, cls).setUpClass() + try: + cls.create_pg_interfaces(range(1)) + cls.create_loopback_interfaces([0]) + cls.loopback0 = cls.lo_interfaces[0] + cls.loopback0.config_ip4() + cls.loopback0.admin_up() + for i in cls.pg_interfaces: + i.config_ip4() + i.configure_ipv4_neighbors() + i.admin_up() + i.resolve_arp() + #cls.icmp_id = 6305 + + except Exception: + super(MEMIFTestCase, cls).tearDownClass() + raise + + @staticmethod + def create_icmp(vpp, src_if, dst_if, ttl=64): + """ + Create ICMP packet + + :param vpp: VPPTestCase instance + :param in_if: Inside interface + :param out_if: Outside interface + :param ttl: TTL of the generated packet + """ + p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) / + IP(src=src_if.remote_ip4, dst=dst_if.remote_ip4, ttl=ttl) / + ICMP(id=src_if.sw_if_index, type='echo-request')) + return p + + + @staticmethod + def create_UDPp(self, src_if, dst_if): + """ + Create UDP packet + + :param src_if: Inside interface + :param dst_if: Outside interface + """ + p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) / + IP(src=src_if.remote_ip4, dst=dst_if.remote_ip4) / + UDP(sport=1234, dport=5678) / + Raw(payload)) + return p + + @staticmethod + def clear_memif_config(self): + """ Clear Memif configuration """ + # VPP 1 + for memif in MEMIFApi.dump_memif(self): + self.logger.info("Deleting memif sw_if_index: %d" % memif.sw_if_index) + MEMIFApi.delete_memif(self, memif.sw_if_index) + MEMIFApi.log_memif_config(self) + + # VPP 2 + for memif in MEMIFApi.dump_memif(self.vpp2): + self.logger.info("Deleting memif sw_if_index: %d" % memif.sw_if_index) + MEMIFApi.delete_memif(self.vpp2, memif.sw_if_index) + MEMIFApi.log_memif_config(self.vpp2) + def setUp(self): + """ + Create memory interface + """ + super(MEMIFTestCase, self).setUp() + master_if_index = MEMIFApi.create_memif(self, 15, 'master', + '/tmp/vpp.sock', 512, 4096, 'aa:bb:cc:11:22:33') + self.logger.info("Created memif sw_if_index: %d" % master_if_index) + self.vpp2.set_request_timeout(10) + def tearDown(self): + """ + Delete memory interface + """ + super(MEMIFTestCase, self).tearDown() + if not self.vpp_dead: + self.logger.info(self.vapi.cli("show interfaces address")) + self.logger.info(self.vapi.cli("show memif")) + self.vpp2.tearDown() + self.vpp3.tearDown() + if not self.vpp_dead: + for memif in MEMIFApi.dump_memif(self): + self.logger.info("Deleting memif sw_if_index: %d" + % memif.sw_if_index) + MEMIFApi.delete_memif(self, memif.sw_if_index) + MEMIFApi.log_memif_config(self) + if not self.vpp2.vpp_dead.get_remote_value(): + for memif in MEMIFApi.dump_memif(self.vpp2): + self.logger.info("Deleting memif sw_if_index: %d" + % memif.sw_if_index) + MEMIFApi.delete_memif(self.vpp2, memif.sw_if_index) + MEMIFApi.log_memif_config(self.vpp2) + if not self.vpp3.vpp_dead.get_remote_value(): + for m in MEMIFApi.dump_memif(self.vpp3): + self.logger.info("Deleting memif sw_if_index: %d" + % m.sw_if_index) + MEMIFApi.delete_memif(self.vpp3, m.sw_if_index) + MEMIFApi.log_memif_config(self.vpp3) + @classmethod + def tearDownClass(cls): + cls.vpp2.tearDownClass() + cls.vpp2.quit_remote() + cls.vpp2.join() + cls.vpp3.tearDownClass() + cls.vpp3.quit_remote() + cls.vpp3.join() + super(MEMIFTestCase, cls).tearDownClass() diff --git a/test/picklable_packet.py b/test/picklable_packet.py deleted file mode 100644 index fa3181ed61..0000000000 --- a/test/picklable_packet.py +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env python - -from scapy.layers.l2 import Ether - -class PicklablePacket: - def __init__(self, p): - self.bytes = bytes(p) - self.time = p.time - - def __call__(self): - p = Ether(self.bytes) - p.time = self.time - return p diff --git a/test/test_memif.py b/test/test_memif.py index 9d2835384e..8d34be209f 100644 --- a/test/test_memif.py +++ b/test/test_memif.py @@ -15,530 +15,539 @@ from scapy.data import IP_PROTOS from util import ppp from memif import MEMIFTestCase, MEMIFApi, MEMIF2, MEMIF3 -from extra_vpp import ExtraVpp, RemoteClass -from picklable_packet import PicklablePacket +from extra_vpp import ExtraVpp, RemoteClass, PicklablePacket #@unittest.skip("DONE") class MEMIFTestCase_s(MEMIFTestCase): - """ Single MEMIF instance tests - - testing basic memif creating and deleting - """ - def test_memif_create(self): - """ Create memif - - memif created in setUp() method in MEMIFTestCase class (memif.py) - check if memifs list is not empty - """ - self.assertTrue(MEMIFApi.dump_memif(self)) - - def test_memif_delete(self): - """ Delete memif - - clearing memif instance(s) - check if memifs list is empty - """ - MEMIFTestCase_s.clear_memif_config(self) - self.assertFalse(MEMIFApi.dump_memif(self)) - - def test_memif_admin_up_down(self): - """ Admin up/down """ - memifs = MEMIFApi.dump_memif(self) - self.assertTrue(memifs) - if memifs: - master_if_index = memifs[0].sw_if_index - #admin up - self.vapi.sw_interface_set_flags(master_if_index, admin_up_down=1) - self.assertEqual(MEMIFApi.dump_memif(self, - master_if_index).admin_up_down,1) - #admin down - self.vapi.sw_interface_set_flags(master_if_index, admin_up_down=0) - self.assertEqual(MEMIFApi.dump_memif(self, - master_if_index).admin_up_down,0) - - def tearDown(self): - for memif in MEMIFApi.dump_memif(self): - MEMIFApi.delete_memif(self, memif.sw_if_index) - super(MEMIFTestCase_s, self).tearDown() + """ Single MEMIF instance tests + + testing basic memif creating and deleting + """ + def test_memif_create(self): + """ Create memif + + memif created in setUp() method in MEMIFTestCase class (memif.py) + check if memifs list is not empty + """ + self.assertTrue(MEMIFApi.dump_memif(self)) + + def test_memif_delete(self): + """ Delete memif + + clearing memif instance(s) + check if memifs list is empty + """ + MEMIFTestCase_s.clear_memif_config(self) + self.assertFalse(MEMIFApi.dump_memif(self)) + + def test_memif_admin_up_down(self): + """ Admin up/down """ + memifs = MEMIFApi.dump_memif(self) + self.assertTrue(memifs) + if memifs: + master_if_index = memifs[0].sw_if_index + #admin up + self.vapi.sw_interface_set_flags(master_if_index, admin_up_down=1) + self.assertEqual(MEMIFApi.dump_memif(self, + master_if_index).admin_up_down,1) + #admin down + self.vapi.sw_interface_set_flags(master_if_index, admin_up_down=0) + self.assertEqual(MEMIFApi.dump_memif(self, + master_if_index).admin_up_down,0) + + def tearDown(self): + for memif in MEMIFApi.dump_memif(self): + MEMIFApi.delete_memif(self, memif.sw_if_index) + super(MEMIFTestCase_s, self).tearDown() #@unittest.skip("asd") class MEMIFTestCase_m(MEMIFTestCase): - """ MEMIF tests - - testing memif: - link establishment - packet stream - """ - - def verify_capture_m_s(self, capture): - """ - Verify ICMP packet capture vpp1(master)->vpp2(slave) - - :param capture: Captured packets - """ - self.assertTrue(capture) - for p in capture: - try: - self.assertEqual(p[IP].src, self.pg0.remote_ip4) - self.assertEqual(p[IP].dst, - self.vpp2.pg1.remote_ip4.get_remote_value()) - self.assertEqual(p[ICMP].id, 1) - self.assertEqual(p[ICMP].type, 8) - except: - self.logger.error( - ppp("Unexpected or invalid packet: ",p)) - - - def verify_capture_s_m(self, capture): - """ - Verify ICMP packet capture vpp2(slave)->vpp1(master) - - :param capture: Captured packets - """ - self.assertTrue(capture) - for p in capture: - try: - self.assertEqual(p[IP].src, - self.vpp2.pg1.remote_ip4.get_remote_value()) - self.assertEqual(p[IP].dst, self.pg0.remote_ip4) - self.assertEqual(p[ICMP].id, 2) - self.assertEqual(p[ICMP].type, 8) - except: - self.logger.error( - ppp("Unexpected or invalid packet: ", p)) - - def verify_capture_m(self, capture, counts): - """ - Verify ICMP packet capture vpp2(slave)->vpp1(master) && vpp3(slave)->vpp1(master) - - :param capture: Captured packets - :param counts: List containing number of packets sent - """ - self.assertTrue(capture) - c2=c3=0 - count = sum(counts) - for p in capture: - try: - if p[ICMP].id == 2: - self.assertEqual(p[IP].src, - self.vpp2.pg1.remote_ip4.get_remote_value()) - self.assertEqual(p[IP].dst, self.pg0.remote_ip4) - self.assertEqual(p[ICMP].type, 8) - c2 += 1 - elif p[ICMP].id == 3: - self.assertEqual(p[IP].src, - self.vpp3.pg1.remote_ip4.get_remote_value()) - self.assertEqual(p[IP].dst, self.pg0.remote_ip4) - self.assertEqual(p[ICMP].type, 8) - c3 += 1 - else: - self.logger.error( - ppp("Unexpected or invalid packet: ", p)) - self.fail("Unexpected or invalid packet") - except: - self.logger.error( - ppp("Unexpected or invalid packet: ", p)) - - if c2 + c3 == count: - self.logger.error( - ppp("Unexpected or invalid packet: ", p)) - self.fail("Unexpected or invalid packet") - - - def create_stream_vpp2(self, count): - """ - Create packets to stream vpp2->vpp1 - - :param count: Number of packets to be created - """ - packets = [] - for i in range(count): - #info = self.create_packet_info(1, 2) - #payload = self.info_to_payload(info) - #p = self.create_icmp(self, src_if, dst_if) - p = (Ether(dst=self.vpp2.pg1.local_mac.get_remote_value(), - src=self.vpp2.pg1.remote_mac.get_remote_value()) / - IP(src=self.vpp2.pg1.remote_ip4.get_remote_value(), - dst=self.pg0.remote_ip4, - ttl=64) / - ICMP(id=2, type='echo-request')) - #info.data = p.copy() - packets.append(p) - - return packets - - def create_stream(self, count): - """ - Create packets to stream vpp1->vpp2 - - :param count: Number of packets to be created - """ - packets = [] - for i in range(count): - #info = self.create_packet_info(1, 2) - #payload = self.info_to_payload(info) - #p = self.create_icmp(self, src_if, dst_if) - p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) / - IP(src=self.pg0.remote_ip4, - dst=self.vpp2.pg1.remote_ip4.get_remote_value(), ttl=64) / - ICMP(id=1, type='echo-request')) - #info.data = p.copy() - packets.append(p) - - return packets - - def create_stream_vpp3(self, count): - """ - Create packets to stream vpp3->vpp1 - - :param count: Number of packets to be created - """ - packets = [] - for i in range(count): - p = (Ether(dst=self.vpp3.pg1.local_mac.get_remote_value(), - src=self.vpp3.pg1.remote_mac.get_remote_value()) / - IP(src=self.vpp3.pg1.remote_ip4.get_remote_value(), - dst=self.pg0.remote_ip4, ttl=64) / - ICMP(id=3, type='echo-request')) - packets.append(p) - return packets - - def start_pg(self, counts): - """ - Set up and start packet generator - sending packets from vpp2(slave) and vpp3(slave) to vpp1(master) - - :param counts: List containing number of packets to be created - """ - self.pg0.enable_capture() - for count in counts: - packets2 = self.create_stream_vpp2(count) - packets3 = self.create_stream_vpp3(count) - self.vpp2.pg1.add_stream_vpp2(packets2) - self.vpp3.pg1.add_stream_vpp2(packets3) - self.vpp2.pg1.enable_capture() - self.vpp3.pg1.enable_capture() - self.vpp2.pg_start() - self.vpp3.pg_start() - - def connect_memif(self): - """ link establishment - connects two memifs vpp1(master)<->vpp2(slave) - """ - - memifs_index = [MEMIFApi.dump_memif(self)[0].sw_if_index] - self.vapi.sw_interface_add_del_address( - memifs_index[0], socket.inet_pton(socket.AF_INET, '192.168.1.1'), 24) - self.vapi.sw_interface_set_flags(memifs_index[0], admin_up_down=1) - - - memifs_index.append(MEMIFApi.create_memif(self.vpp2, 15, 'slave', - '/tmp/vpp.sock')) - self.vpp2.logger.info("created memif sw_if_index: %d" % memifs_index[1]) - - self.vpp2.vapi.sw_interface_add_del_address( - memifs_index[1], socket.inet_pton(socket.AF_INET, '192.168.1.2'), 24) - self.vpp2.vapi.sw_interface_set_flags(memifs_index[1], admin_up_down=1) - - #Wait - self.sleep(4, "waiting for memif connection to establish") - MEMIFApi.log_memif_config(self) - MEMIFApi.log_memif_config(self.vpp2) - - return memifs_index - - def connect_memif_3ifs(self): - """ link establishment - - (memif0)vpp1(master)<->(meif0)vpp2(slave) - (memif1)vpp1(master)<->(meif0)vpp3(slave) - - returns: memifs_index - 0: vpp1 memif0 (master) - 1: vpp2 memif0 (slave) - 2: vpp1 memif1 (master) - 3: vpp3 memif0 (slave) - """ - #vpp1 memif0 - memifs_index = [MEMIFApi.dump_memif(self)[0].sw_if_index] - self.vapi.sw_interface_add_del_address( - memifs_index[0], socket.inet_pton(socket.AF_INET, '192.168.1.1'), 24) - self.vapi.sw_interface_set_flags(memifs_index[0], admin_up_down=1) - - #vpp2 memif0 - memifs_index.append(MEMIFApi.create_memif(self.vpp2, 15, 'slave', - '/tmp/vpp.sock')) - self.vpp2.logger.info("created memif sw_if_index: %d" % memifs_index[1]) - - self.vpp2.vapi.sw_interface_add_del_address( - memifs_index[1], socket.inet_pton(socket.AF_INET, '192.168.1.2'), 24) - self.vpp2.vapi.sw_interface_set_flags(memifs_index[1], admin_up_down=1) - - #Wait for link - self.sleep(4, "waiting for memif connection to establish") - MEMIFApi.log_memif_config(self) - MEMIFApi.log_memif_config(self.vpp2) - - #vpp1 memif1 - memifs_index.append(MEMIFApi.create_memif(self, 16, 'master', - '/tmp/vpp.sock', 512, 4096, 'aa:bb:cc:22:33:44')) - self.logger.info("created memif sw_if_index: %d" % memifs_index[2]) - - self.vapi.sw_interface_add_del_address( - memifs_index[2], socket.inet_pton(socket.AF_INET, '192.168.2.1'), 24) - self.vapi.sw_interface_set_flags(memifs_index[2], admin_up_down=1) - - #vpp3 memif0 - memifs_index.append(MEMIFApi.create_memif(self.vpp3, 16, 'slave', - '/tmp/vpp.sock')) - self.vpp3.logger.info("created memif sw_if_index: %d" % memifs_index[3]) - - self.vpp3.vapi.sw_interface_add_del_address( - memifs_index[3], socket.inet_pton(socket.AF_INET, '192.168.2.2'), 24) - self.vpp3.vapi.sw_interface_set_flags(memifs_index[3], admin_up_down=1) - - #Wait for link - self.sleep(4, "waiting for memif connection to establish") - MEMIFApi.log_memif_config(self) - MEMIFApi.log_memif_config(self.vpp3) - - return memifs_index - - - def add_route(self): - """ add routing for vpp1<->vpp2 setup """ - self.vapi.cli('ip route add 169.54.1.0/24 via 192.168.1.2') - self.vpp2.vapi.cli('ip route add 172.16.1.0/24 via 192.168.1.1') - - def add_route_3ifs(self): - """ add routing for vpp1<->vpp2 vpp1<->vpp3 setup """ - self.vapi.cli('ip route add 169.54.1.0/24 via 192.168.1.2') - self.vapi.cli('ip route add 169.55.1.0/24 via 192.168.2.2') - self.vpp2.vapi.cli('ip route add 172.16.1.0/24 via 192.168.1.1') - self.vpp3.vapi.cli('ip route add 172.16.1.0/24 via 192.168.2.1') - - #@unittest.skip("DONE") - def test_memif_connect(self): - """ Establish link - - assert link up - ping (memif0)vpp2 - - """ - - memifs_index = self.connect_memif() - - # Test VPP 1 - master = MEMIFApi.dump_memif(self, memifs_index[0]) - self.assertIsNotNone(master) - self.assertEqual(master.admin_up_down, 1) - self.assertEqual(master.link_up_down, 1) - - # Test VPP 2 - slave = MEMIFApi.dump_memif(self.vpp2, memifs_index[1]) - self.assertIsNotNone(slave) - self.assertEqual(slave.admin_up_down, 1) - self.assertEqual(slave.link_up_down, 1) - - retval = self.vapi.cli("ping 192.168.1.2").split('\n')[-2].split(' ') - self.assertNotEqual(int(retval[1]), 0) - self.assertTrue((int(retval[1]) == int(retval[3])) - or (int(retval[1]) == (int(retval[3]) + 1))) - - #@unittest.skip("DONE") - def test_memif_traffic_01_slave_master(self): - """ ICMP packet stream slave -> master """ - memifs_index = self.connect_memif() - self.vpp2.vapi.cli("ping 192.168.1.1") - count = 5 - self.add_route() - packets = self.create_stream_vpp2(count) - self.vpp2.pg1.add_stream_vpp2(packets) - self.vpp2.pg1.enable_capture() - self.pg0.enable_capture() - self.vpp2.pg_start() - capture = self.pg0.get_capture(expected_count=(count)) - self.vpp2.pg1.assert_nothing_captured() - self.verify_capture_s_m(capture) - - #@unittest.skip("DONE") - def test_memif_traffic_02_master_slave(self): - """ ICMP packet stream master -> slave """ - memifs_index = self.connect_memif() - self.vpp2.vapi.cli("ping 192.168.1.1") - count = 5 - self.add_route() - packets = self.create_stream(count) - self.pg0.add_stream(packets) - self.vpp2.pg1.enable_capture() - self.pg0.enable_capture() - self.pg_start() - capture = self.vpp2.pg1.get_capture(expected_count=(count)) - self.assertTrue(capture) - if capture: - n_cap = [] - for p in capture: - if isinstance(p, PicklablePacket): - p = p() - n_cap.append(p) - self.verify_capture_m_s(n_cap) - self.pg0.assert_nothing_captured() - - #@unittest.skip("depends on prev") - def test_memif_ps_m(self): - """ ICMP packet stream from multiple slaves """ - memifs_index = self.connect_memif_3ifs() - self.vpp3.set_request_timeout(10) - self.vpp2.set_request_tiomeout(10) - self.vpp2.vapi.cli('ping 192.168.1.1') - self.vpp3.vapi.cli('ping 192.168.2.1') - - self.add_route_3ifs() - - self.vpp3.set_request_timeout(2) - self.vpp2.set_request_tiomeout(2) - - count1 = 3 - count2 = 2 - self.start_pg([count1, count2]) - capture = self.pg0.get_capture(expected_count=count1*2 + count2*2) - self.vpp2.pg1.assert_nothing_captured() - self.vpp3.pg1.assert_nothing_captured() - - self.verify_capture_m(capture, [count1, count2]) - - - def assert_link_up_down(self, memifs, link_up_down=1): - """ check if link is up/down and verify with ping """ - for memif in memifs: - self.assertIsNotNone(memif) - self.assertEqual(memif.link_up_down, link_up_down) - - if link_up_down: - retval = self.vapi.cli("ping 192.168.1.2").split('\n')[-2].split(' ') - self.assertNotEqual(int(retval[1]), 0) - self.assertTrue((int(retval[1]) == int(retval[3])) - or (int(retval[1]) == (int(retval[3]) + 1))) - else: - retval = self.vapi.cli("ping 192.168.1.2").split('\n')[-2].split(' ') - self.assertNotEqual(int(retval[1]), 0) - self.assertEqual(int(retval[3]), 0) - - - - - #@unittest.skip("DONE") - def test_reconnect_01(self): - """ Break connection then reconnect (Admin up/down)""" - memifs_index = self.connect_memif() - - master = MEMIFApi.dump_memif(self, memifs_index[0]) - slave = MEMIFApi.dump_memif(self.vpp2, memifs_index[1]) - - self.assert_link_up_down([master, slave]) - - self.vapi.sw_interface_set_flags(master.sw_if_index, admin_up_down=0) - self.sleep(4, "waiting for disconection") - - master = MEMIFApi.dump_memif(self, memifs_index[0]) - slave = MEMIFApi.dump_memif(self.vpp2, memifs_index[1]) - - self.assert_link_up_down([master, slave], 0) - - self.vapi.sw_interface_set_flags(master.sw_if_index, admin_up_down=1) - self.sleep(4, "waiting for connection") - - master = MEMIFApi.dump_memif(self, memifs_index[0]) - slave = MEMIFApi.dump_memif(self.vpp2, memifs_index[1]) - - self.assert_link_up_down([master, slave]) - - self.vpp2.vapi.sw_interface_set_flags(slave.sw_if_index, admin_up_down=0) - self.sleep(4, "waiting for disconection") - - master = MEMIFApi.dump_memif(self, memifs_index[0]) - slave = MEMIFApi.dump_memif(self.vpp2, memifs_index[1]) - - self.assert_link_up_down([master, slave], 0) - - self.vpp2.vapi.sw_interface_set_flags(slave.sw_if_index, admin_up_down=1) - self.sleep(4, "waiting for connection") - - master = MEMIFApi.dump_memif(self, memifs_index[0]) - slave = MEMIFApi.dump_memif(self.vpp2, memifs_index[1]) - - self.assert_link_up_down([master, slave]) - - #@unittest.skip("DONE") - def test_reconnect_02(self): - """ Break connection then reconnect (IP add/del)""" - - memifs_index = self.connect_memif() - master = MEMIFApi.dump_memif(self, memifs_index[0]) - slave = MEMIFApi.dump_memif(self.vpp2, memifs_index[1]) - self.assertEqual(slave.link_up_down, 1) - self.assertEqual(master.link_up_down, 1) - - retval = self.vpp2.vapi.cli("ping 192.168.1.1").split('\n')[-2].split(' ') - self.assertNotEqual(int(retval[1]), 0) - self.assertTrue((int(retval[1]) == int(retval[3])) - or (int(retval[1]) == (int(retval[3]) + 1))) - - - self.vapi.sw_interface_add_del_address( - master.sw_if_index, socket.inet_pton(socket.AF_INET, - '192.168.1.1'), 24, del_all=1) - self.sleep(4, "waiting for disconnection") - - - retval = self.vpp2.vapi.cli("ping 192.168.1.1").split('\n')[-2].split(' ') - self.assertNotEqual(int(retval[1]), 0) - self.assertEqual(int(retval[3]), 0) - - - self.vapi.sw_interface_add_del_address( - master.sw_if_index, socket.inet_pton(socket.AF_INET, - '192.168.1.1'), 24) - self.sleep(4, "waiting for connection") - - - retval = self.vpp2.vapi.cli("ping 192.168.1.1").split('\n')[-2].split(' ') - self.assertNotEqual(int(retval[1]), 0) - self.assertTrue((int(retval[1]) == int(retval[3])) - or (int(retval[1]) == (int(retval[3]) + 1))) - - - self.vpp2.vapi.sw_interface_add_del_address( - slave.sw_if_index, socket.inet_pton(socket.AF_INET, - '192.168.1.2'), 24, del_all=1) - self.sleep(4, "waiting for disconnection") - - retval = self.vapi.cli("ping 192.168.1.2").split('\n')[-2].split(' ') - self.assertNotEqual(int(retval[1]), 0) - self.assertEqual(int(retval[3]), 0) - - self.vpp2.vapi.sw_interface_add_del_address( - slave.sw_if_index, socket.inet_pton(socket.AF_INET, - '192.168.1.2'), 24) - self.sleep(4, "waiting for connection") - - retval = self.vapi.cli("ping 192.168.1.2").split('\n')[-2].split(' ') - self.assertNotEqual(int(retval[1]), 0) - self.assertTrue((int(retval[1]) == int(retval[3])) - or (int(retval[1]) == (int(retval[3]) + 1))) - - def setUp(self): - self.vpp2.setTestFunctionInfo(self._testMethodName,self._testMethodDoc) - self.vpp2.setUp() - super(MEMIFTestCase_m, self).setUp() - - @classmethod - def setUpClass(cls): - super(MEMIFTestCase_m, cls).setUpClass() - - @classmethod - def tearDownClass(cls): - super(MEMIFTestCase_m, cls).tearDownClass() + """ MEMIF tests + + testing memif: + link establishment + packet stream + """ + + def verify_capture_m_s(self, capture): + """ + Verify ICMP packet capture vpp1(master)->vpp2(slave) + + :param capture: Captured packets + """ + self.assertTrue(capture) + for p in capture: + try: + self.assertEqual(p[IP].src, self.pg0.remote_ip4) + self.assertEqual(p[IP].dst, + self.vpp2.pg1.remote_ip4.get_remote_value()) + self.assertEqual(p[ICMP].id, 1) + self.assertEqual(p[ICMP].type, 8) + except: + self.logger.error( + ppp("Unexpected or invalid packet: ",p)) + + + def verify_capture_s_m(self, capture): + """ + Verify ICMP packet capture vpp2(slave)->vpp1(master) + + :param capture: Captured packets + """ + self.assertTrue(capture) + for p in capture: + try: + self.assertEqual(p[IP].src, + self.vpp2.pg1.remote_ip4.get_remote_value()) + self.assertEqual(p[IP].dst, self.pg0.remote_ip4) + self.assertEqual(p[ICMP].id, 2) + self.assertEqual(p[ICMP].type, 8) + except: + self.logger.error( + ppp("Unexpected or invalid packet: ", p)) + + def verify_capture_m(self, capture, counts): + """ + Verify ICMP packet capture vpp2(slave)->vpp1(master) && vpp3(slave)->vpp1(master) + + :param capture: Captured packets + :param counts: List containing number of packets sent + """ + self.assertTrue(capture) + c2=c3=0 + count = sum(counts) + for p in capture: + try: + if p[ICMP].id == 2: + self.assertEqual(p[IP].src, + self.vpp2.pg1.remote_ip4.get_remote_value()) + self.assertEqual(p[IP].dst, self.pg0.remote_ip4) + self.assertEqual(p[ICMP].type, 8) + c2 += 1 + elif p[ICMP].id == 3: + self.assertEqual(p[IP].src, + self.vpp3.pg1.remote_ip4.get_remote_value()) + self.assertEqual(p[IP].dst, self.pg0.remote_ip4) + self.assertEqual(p[ICMP].type, 8) + c3 += 1 + else: + self.logger.error( + ppp("Unexpected or invalid packet: ", p)) + self.fail("Unexpected or invalid packet") + except: + self.logger.error( + ppp("Unexpected or invalid packet: ", p)) + + if c2 + c3 == count: + self.logger.error( + ppp("Unexpected or invalid packet: ", p)) + self.fail("Unexpected or invalid packet") + + + def create_stream_vpp2(self, count): + """ + Create packets to stream vpp2->vpp1 + + :param count: Number of packets to be created + """ + packets = [] + for i in range(count): + #info = self.create_packet_info(1, 2) + #payload = self.info_to_payload(info) + #p = self.create_icmp(self, src_if, dst_if) + p = (Ether(dst=self.vpp2.pg1.local_mac.get_remote_value(), + src=self.vpp2.pg1.remote_mac.get_remote_value()) / + IP(src=self.vpp2.pg1.remote_ip4.get_remote_value(), + dst=self.pg0.remote_ip4, + ttl=64) / + ICMP(id=2, type='echo-request')) + #info.data = p.copy() + packets.append(p) + + return packets + + def create_stream(self, count): + """ + Create packets to stream vpp1->vpp2 + + :param count: Number of packets to be created + """ + packets = [] + for i in range(count): + #info = self.create_packet_info(1, 2) + #payload = self.info_to_payload(info) + #p = self.create_icmp(self, src_if, dst_if) + p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) / + IP(src=self.pg0.remote_ip4, + dst=self.vpp2.pg1.remote_ip4.get_remote_value(), ttl=64) / + ICMP(id=1, type='echo-request')) + #info.data = p.copy() + packets.append(p) + + return packets + + def create_stream_vpp3(self, count): + """ + Create packets to stream vpp3->vpp1 + + :param count: Number of packets to be created + """ + packets = [] + for i in range(count): + p = (Ether(dst=self.vpp3.pg1.local_mac.get_remote_value(), + src=self.vpp3.pg1.remote_mac.get_remote_value()) / + IP(src=self.vpp3.pg1.remote_ip4.get_remote_value(), + dst=self.pg0.remote_ip4, ttl=64) / + ICMP(id=3, type='echo-request')) + packets.append(p) + return packets + + def start_pg(self, counts): + """ + Set up and start packet generator + sending packets from vpp2(slave) and vpp3(slave) to vpp1(master) + + :param counts: List containing number of packets to be created + """ + self.pg0.enable_capture() + for count in counts: + packets2 = self.create_stream_vpp2(count) + packets3 = self.create_stream_vpp3(count) + self.vpp2.pg1.add_stream(packets2) + self.vpp3.pg1.add_stream(packets3) + self.vpp2.pg1.enable_capture() + self.vpp3.pg1.enable_capture() + self.vpp2.pg_start() + self.vpp3.pg_start() + + def connect_memif(self): + """ link establishment + connects two memifs vpp1(master)<->vpp2(slave) + """ + + memifs_index = [MEMIFApi.dump_memif(self)[0].sw_if_index] + self.vapi.sw_interface_add_del_address( + memifs_index[0], socket.inet_pton(socket.AF_INET, '192.168.1.1'), 24) + self.vapi.sw_interface_set_flags(memifs_index[0], admin_up_down=1) + + + memifs_index.append(MEMIFApi.create_memif(self.vpp2, 15, 'slave', + '/tmp/vpp.sock', 512, 4096, 'aa:bb:cc:22:33:44')) + self.vpp2.logger.info("created memif sw_if_index: %d" % memifs_index[1]) + + self.vpp2.vapi.sw_interface_add_del_address( + memifs_index[1], socket.inet_pton(socket.AF_INET, '192.168.1.2'), 24) + self.vpp2.vapi.sw_interface_set_flags(memifs_index[1], admin_up_down=1) + + #Wait + self.sleep(4, "waiting for memif connection to establish") + MEMIFApi.log_memif_config(self) + MEMIFApi.log_memif_config(self.vpp2) + + return memifs_index + + def connect_memif_3ifs(self): + """ link establishment + + (memif0)vpp1(master)<->(meif0)vpp2(slave) + (memif1)vpp1(master)<->(meif0)vpp3(slave) + + returns: memifs_index + 0: vpp1 memif0 (master) + 1: vpp2 memif0 (slave) + 2: vpp1 memif1 (master) + 3: vpp3 memif0 (slave) + """ + #vpp1 memif0 + memifs_index = [MEMIFApi.dump_memif(self)[0].sw_if_index] + self.vapi.sw_interface_add_del_address( + memifs_index[0], socket.inet_pton(socket.AF_INET, '192.168.1.1'), 24) + self.vapi.sw_interface_set_flags(memifs_index[0], admin_up_down=1) + + #vpp2 memif0 + memifs_index.append(MEMIFApi.create_memif(self.vpp2, 15, 'slave', + '/tmp/vpp.sock', 512, 4096, 'aa:bb:cc:22:33:44')) + self.vpp2.logger.info("created memif sw_if_index: %d" % memifs_index[1]) + + self.vpp2.vapi.sw_interface_add_del_address( + memifs_index[1], socket.inet_pton(socket.AF_INET, '192.168.1.2'), 24) + self.vpp2.vapi.sw_interface_set_flags(memifs_index[1], admin_up_down=1) + + #Wait for link + self.sleep(4, "waiting for memif connection to establish") + MEMIFApi.log_memif_config(self) + MEMIFApi.log_memif_config(self.vpp2) + + #vpp1 memif1 + memifs_index.append(MEMIFApi.create_memif(self, 16, 'master', + '/tmp/vpp.sock', 512, 4096, 'aa:bb:cc:33:44:55')) + self.logger.info("created memif sw_if_index: %d" % memifs_index[2]) + + self.vapi.sw_interface_add_del_address( + memifs_index[2], socket.inet_pton(socket.AF_INET, '192.168.2.1'), 24) + self.vapi.sw_interface_set_flags(memifs_index[2], admin_up_down=1) + + #vpp3 memif0 + memifs_index.append(MEMIFApi.create_memif(self.vpp3, 16, 'slave', + '/tmp/vpp.sock', 512, 4096, 'aa:bb:cc:44:55:66')) + self.vpp3.logger.info("created memif sw_if_index: %d" % memifs_index[3]) + + self.vpp3.vapi.sw_interface_add_del_address( + memifs_index[3], socket.inet_pton(socket.AF_INET, '192.168.2.2'), 24) + self.vpp3.vapi.sw_interface_set_flags(memifs_index[3], admin_up_down=1) + + #Wait for link + self.sleep(4, "waiting for memif connection to establish") + MEMIFApi.log_memif_config(self) + MEMIFApi.log_memif_config(self.vpp3) + + return memifs_index + + + def add_route(self): + """ add routing for vpp1<->vpp2 setup """ + self.vapi.cli('ip route add 169.54.1.0/24 via 192.168.1.2') + self.vpp2.vapi.cli('ip route add 172.16.1.0/24 via 192.168.1.1') + #self.vapi.ip_add_del_route('169.54.1.0', 24, '192.168.1.2') + #self.vpp2.vapi.ip_add_del_route('172.16.1.0', 24, '192.168.1.1') + + def add_route_3ifs(self): + """ add routing for vpp1<->vpp2 vpp1<->vpp3 setup """ + self.vapi.cli('ip route add 169.54.1.0/24 via 192.168.1.2') + self.vapi.cli('ip route add 169.55.1.0/24 via 192.168.2.2') + #self.vapi.ip_add_del_route('169.54.1.0', 24, '192.168.1.2') + #self.vapi.ip_add_del_route('169.55.1.0', 24, '192.168.2.2') + self.vpp2.vapi.cli('ip route add 172.16.1.0/24 via 192.168.1.1') + self.vpp3.vapi.cli('ip route add 172.16.1.0/24 via 192.168.2.1') + #self.vpp2.vapi.ip_add_del_route('172.16.1.0', 24, '192.168.1.1') + #self.vpp3.vapi.ip_add_del_route('172.16.1.0', 24, '192.168.2.1') + + #@unittest.skip("DONE") + def test_memif_connect(self): + """ Establish link + + assert link up + ping (memif0)vpp2 + + """ + + memifs_index = self.connect_memif() + + # Test VPP 1 + master = MEMIFApi.dump_memif(self, memifs_index[0]) + self.assertIsNotNone(master) + self.assertEqual(master.admin_up_down, 1) + self.assertEqual(master.link_up_down, 1) + + # Test VPP 2 + slave = MEMIFApi.dump_memif(self.vpp2, memifs_index[1]) + self.assertIsNotNone(slave) + self.assertEqual(slave.admin_up_down, 1) + self.assertEqual(slave.link_up_down, 1) + + retval = self.vapi.cli("ping 192.168.1.2").split('\n')[-2].split(' ') + self.assertNotEqual(int(retval[1]), 0) + self.assertTrue((int(retval[1]) == int(retval[3])) + or (int(retval[1]) == (int(retval[3]) + 1))) + + MEMIFApi.delete_memif(self, memifs_index[0]) + MEMIFApi.delete_memif(self.vpp2, memifs_index[1]) + + #@unittest.skip("DONE") + def test_memif_traffic_01_slave_master(self): + """ ICMP packet stream slave -> master """ + memifs_index = self.connect_memif() + self.vpp2.vapi.cli("ping 192.168.1.1") + count = 5 + self.add_route() + packets = self.create_stream_vpp2(count) + self.vpp2.pg1.add_stream(packets) + self.vpp2.pg1.enable_capture() + self.pg0.enable_capture() + self.vpp2.pg_start() + capture = self.pg0.get_capture(expected_count=(count)) + self.vpp2.pg1.assert_nothing_captured() + self.verify_capture_s_m(capture) + + #@unittest.skip("DONE") + def test_memif_traffic_02_master_slave(self): + """ ICMP packet stream master -> slave """ + memifs_index = self.connect_memif() + self.vpp2.vapi.cli("ping 192.168.1.1") + count = 5 + self.add_route() + packets = self.create_stream(count) + self.pg0.add_stream(packets) + self.vpp2.pg1.enable_capture() + self.pg0.enable_capture() + self.pg_start() + capture = self.vpp2.pg1.get_capture(expected_count=(count)) + self.assertTrue(capture) + self.verify_capture_m_s(capture) + self.pg0.assert_nothing_captured() + + #@unittest.skip("depends on prev") + def test_memif_ps_m(self): + """ ICMP packet stream from multiple slaves """ + memifs_index = self.connect_memif_3ifs() + self.vpp3.set_request_timeout(10) + self.vpp2.set_request_tiomeout(10) + self.vpp2.vapi.cli('ping 192.168.1.1') + self.vpp3.vapi.cli('ping 192.168.2.1') + + self.add_route_3ifs() + + self.vpp3.set_request_timeout(2) + self.vpp2.set_request_tiomeout(2) + + count1 = 3 + count2 = 2 + self.start_pg([count1, count2]) + capture = self.pg0.get_capture(expected_count=count1*2 + count2*2) + self.vpp2.pg1.assert_nothing_captured() + self.vpp3.pg1.assert_nothing_captured() + + self.verify_capture_m(capture, [count1, count2]) + + + def assert_link_up_down(self, memifs, link_up_down=1): + """ check if link is up/down and verify with ping """ + for memif in memifs: + self.assertIsNotNone(memif) + self.assertEqual(memif.link_up_down, link_up_down) + + if link_up_down: + retval = self.vapi.cli("ping 192.168.1.2").split('\n')[-2].split(' ') + self.assertNotEqual(int(retval[1]), 0) + self.assertTrue((int(retval[1]) == int(retval[3])) + or (int(retval[1]) == (int(retval[3]) + 1))) + else: + retval = self.vapi.cli("ping 192.168.1.2").split('\n')[-2].split(' ') + self.assertNotEqual(int(retval[1]), 0) + self.assertEqual(int(retval[3]), 0) + + + + #@unittest.skip("DONE") + def test_reconnect_01(self): + """ Break connection then reconnect (Admin up/down)""" + memifs_index = self.connect_memif() + self.vpp2.set_request_timeout(10) + master = MEMIFApi.dump_memif(self, memifs_index[0]) + slave = MEMIFApi.dump_memif(self.vpp2, memifs_index[1]) + + self.assert_link_up_down([master, slave]) + + self.vapi.sw_interface_set_flags(memifs_index[0], admin_up_down=0) + self.sleep(4, "waiting for disconection") + master = MEMIFApi.dump_memif(self, memifs_index[0]) + slave = MEMIFApi.dump_memif(self.vpp2, memifs_index[1]) + self.assert_link_up_down([master, slave], 0) + + self.vapi.sw_interface_set_flags(memifs_index[0], admin_up_down=1) + self.sleep(4, "waiting for connection") + + master = MEMIFApi.dump_memif(self, memifs_index[0]) + slave = MEMIFApi.dump_memif(self.vpp2, memifs_index[1]) + + self.assert_link_up_down([master, slave]) + self.vpp2.vapi.sw_interface_set_flags(memifs_index[1], admin_up_down=0) + self.sleep(4, "waiting for disconection") + + master = MEMIFApi.dump_memif(self, memifs_index[0]) + slave = MEMIFApi.dump_memif(self.vpp2, memifs_index[1]) + self.assert_link_up_down([master, slave], 0) + self.vpp2.vapi.sw_interface_set_flags(slave.sw_if_index, admin_up_down=1) + self.sleep(4, "waiting for connection") + + master = MEMIFApi.dump_memif(self, memifs_index[0]) + slave = MEMIFApi.dump_memif(self.vpp2, memifs_index[1]) + + self.assert_link_up_down([master, slave]) + + #@unittest.skip("DONE") + def test_reconnect_02(self): + """ Break connection then reconnect (create/delete memif)""" + self.vpp2.setTestFunctionInfo(self._testMethodName,self._testMethodDoc) + + memifs_index = self.connect_memif() + master = MEMIFApi.dump_memif(self, memifs_index[0]) + slave = MEMIFApi.dump_memif(self.vpp2, memifs_index[1]) + self.assertEqual(slave.link_up_down, 1) + self.assertEqual(master.link_up_down, 1) + + retval = self.vapi.cli("ping 192.168.1.2").split('\n')[-2].split(' ') + self.assertNotEqual(int(retval[1]), 0) + self.assertTrue((int(retval[1]) == int(retval[3])) + or (int(retval[1]) == (int(retval[3]) + 1))) + + + MEMIFApi.delete_memif(self.vpp2, memifs_index[1]) + master = MEMIFApi.dump_memif(self, memifs_index[0]) + self.assertEqual(master.link_up_down, 0) + retval = self.vapi.cli("ping 192.168.1.2").split('\n')[-2].split(' ') + self.assertNotEqual(int(retval[1]), 0) + self.assertEqual(int(retval[3]), 0) + memifs_index[1] = MEMIFApi.create_memif(self.vpp2, 15, 'slave', + '/tmp/vpp.sock', 512, 4096, 'aa:bb:cc:22:33:44') + self.vpp2.logger.info("created memif sw_if_index: %d" % memifs_index[1]) + + self.vpp2.vapi.sw_interface_add_del_address( + memifs_index[1], socket.inet_pton(socket.AF_INET, '192.168.1.2'), 24) + self.vpp2.vapi.sw_interface_set_flags(memifs_index[1], admin_up_down=1) + self.sleep(4, "Wait for memif connection") + + master = MEMIFApi.dump_memif(self, memifs_index[0]) + slave = MEMIFApi.dump_memif(self.vpp2, memifs_index[1]) + self.assertEqual(slave.link_up_down, 1) + self.assertEqual(master.link_up_down, 1) + + retval = self.vapi.cli("ping 192.168.1.2").split('\n')[-2].split(' ') + self.assertNotEqual(int(retval[1]), 0) + self.assertTrue((int(retval[1]) == int(retval[3])) + or (int(retval[1]) == (int(retval[3]) + 1))) + + MEMIFApi.delete_memif(self, memifs_index[0]) + + slave = MEMIFApi.dump_memif(self.vpp2, memifs_index[1]) + self.assertEqual(slave.link_up_down, 0) + retval = self.vpp2.vapi.cli("ping 192.168.1.1").split('\n')[-2].split(' ') + self.assertNotEqual(int(retval[1]), 0) + self.assertEqual(int(retval[3]), 0) + + memifs_index[0] = MEMIFApi.create_memif(self, 15, 'master', + '/tmp/vpp.sock', 512, 4096, 'aa:bb:cc:11:22:33') + self.logger.info("created memif sw_if_index: %d" % memifs_index[0]) + + self.vapi.sw_interface_add_del_address( + memifs_index[0], socket.inet_pton(socket.AF_INET, '192.168.1.1'), 24) + self.vapi.sw_interface_set_flags(memifs_index[0], admin_up_down=1) + self.sleep(4, "Wait for memif connection") + + master = MEMIFApi.dump_memif(self, memifs_index[0]) + slave = MEMIFApi.dump_memif(self.vpp2, memifs_index[1]) + self.assertEqual(slave.link_up_down, 1) + self.assertEqual(master.link_up_down, 1) + + retval = self.vpp2.vapi.cli("ping 192.168.1.1").split('\n')[-2].split(' ') + self.assertNotEqual(int(retval[1]), 0) + self.assertTrue((int(retval[1]) == int(retval[3])) + or (int(retval[1]) == (int(retval[3]) + 1))) + + + + def setUp(self): + self.vpp2.setUp() + super(MEMIFTestCase_m, self).setUp() + + @classmethod + def setUpClass(cls): + super(MEMIFTestCase_m, cls).setUpClass() + + @classmethod + def tearDownClass(cls): + super(MEMIFTestCase_m, cls).tearDownClass() if __name__ == '__main__': - unittest.main(testRunner=VppTestRunner) + unittest.main(testRunner=VppTestRunner) + diff --git a/test/vpp_interface.py b/test/vpp_interface.py index 10bf102ea5..ce1e57378b 100644 --- a/test/vpp_interface.py +++ b/test/vpp_interface.py @@ -177,15 +177,17 @@ def __init__(self, test): "in interface dump %s" % (self.sw_if_index, repr(r))) - def set_ip4(self, ip='172.16', mc='02', count=1): + + + def set_ip4(self, net_prefix='172.16', count=1): self._remote_hosts = [] self._hosts_by_mac = {} self._hosts_by_ip4 = {} self._hosts_by_ip6 = {} for i in range( 2, count + 2): # 0: network address, 1: local vpp address - mac = mc + ":%02x:00:00:ff:%02x" % (self.sw_if_index, i) - ip4 = ip + ".%u.%u" % (self.sw_if_index, i) + mac = "02:%02x:00:00:ff:%02x" % (self.sw_if_index, i) + ip4 = net_prefix + ".%u.%u" % (self.sw_if_index, i) ip6 = "fd01:%x::%x" % (self.sw_if_index, i) host = Host(mac, ip4, ip6) self._remote_hosts.append(host) @@ -193,12 +195,12 @@ def set_ip4(self, ip='172.16', mc='02', count=1): self._hosts_by_ip4[ip4] = host self._hosts_by_ip6[ip6] = host - self._local_ip4 = ip + ".%u.1" % self.sw_if_index + self._local_ip4 = net_prefix + ".%u.1" % self.sw_if_index self._local_ip4n = socket.inet_pton(socket.AF_INET, self.local_ip4) self.local_ip4_prefix_len = 24 self.has_ip4_config = False self.ip4_table_id = 0 - + def config_ip4(self): """Configure IPv4 address on the VPP interface.""" self.test.vapi.sw_interface_add_del_address( @@ -343,6 +345,11 @@ def enable_mpls(self): self.test.vapi.sw_interface_enable_disable_mpls( self.sw_if_index) + def disable_mpls(self): + """Enable MPLS on the VPP interface.""" + self.test.vapi.sw_interface_enable_disable_mpls( + self.sw_if_index, 0) + def is_ip4_entry_in_fib_dump(self, dump): for i in dump: if i.address == self.local_ip4n and \ @@ -358,7 +365,7 @@ def set_unnumbered(self, ip_sw_if_index): ip_sw_if_index) def unset_unnumbered(self, ip_sw_if_index): - """ Unaet the interface to unnumbered via ip_sw_if_index """ + """ Unset the interface to unnumbered via ip_sw_if_index """ self.test.vapi.sw_interface_set_unnumbered( self.sw_if_index, ip_sw_if_index, diff --git a/test/vpp_pg_interface.py b/test/vpp_pg_interface.py index 8c343e606b..e24af79e42 100644 --- a/test/vpp_pg_interface.py +++ b/test/vpp_pg_interface.py @@ -15,7 +15,6 @@ from scapy.utils6 import in6_getnsma, in6_getnsmac, in6_ismaddr from scapy.utils import inet_pton, inet_ntop -import picklable_packet class CaptureTimeoutError(Exception): """ Exception raised if capture or packet doesn't appear within timeout """ @@ -148,38 +147,9 @@ def add_stream(self, pkts): self.test.register_capture(self.cap_name) # FIXME this should be an API, but no such exists atm self.test.vapi.cli(self.input_cli) - - def add_stream_vpp2(self, pkts): - """ - Add a stream of packets to this packet-generator - - :param pkts: iterable packets - - """ - n_p = [] - for p in pkts: - n_p.append(p()) - pkts = n_p - try: - if os.path.isfile(self.in_path): - name = "%s/history.[timestamp:%f].[%s-counter:%04d].%s" %\ - (self.test.tempdir, - time.time(), - self.name, - self.in_history_counter, - self._in_file) - self.test.logger.debug("Renaming %s->%s" % - (self.in_path, name)) - os.rename(self.in_path, name) - except: - pass - wrpcap(self.in_path, pkts) - self.test.register_capture(self.cap_name) - # FIXME this should be an API, but no such exists atm - self.test.vapi.cli(self.input_cli) def generate_debug_aid(self, kind): - """ Create a hardlink to the out file with a counter and a file + """ hardlink to the out file with a counter and a file containing stack trace to ease debugging in case of multiple capture files present. """ self.test.logger.debug("Generating debug aid for %s on %s" % @@ -195,7 +165,7 @@ def generate_debug_aid(self, kind): self._out_assert_counter += 1 def _get_capture(self, timeout, filter_out_fn=is_ipv6_misc): - """ Helper method to get capture and filter it """ + """ Helper method to get capture and filter it """ try: if not self.wait_for_capture_file(timeout): return None