Exemple #1
0
    def test_multiproc_pub_sub(self):
        if not self.do_test:
            self.skipTest('pub/sub is not enabled')
            return
        self.event_received = False
        cfg.CONF.set_override('publisher_multiproc_socket',
                              '/tmp/ipc_test_socket',
                              group='df')
        pub_sub_driver = df_utils.load_driver(
            cfg.CONF.df.pub_sub_multiproc_driver,
            df_utils.DF_PUBSUB_DRIVER_NAMESPACE)
        publisher = pub_sub_driver.get_publisher()
        publisher.initialize()
        self.subscriber = pub_sub_driver.get_subscriber()
        self.subscriber.initialize(self._handle_received_event)
        self.subscriber.daemonize()
        publisher.send_event(self.event)
        test_utils.wait_until_true(lambda: self.event_received)
        self.subscriber.close()
        self.subscriber = None

        # Check that we received the same event
        self.assertEqual(self.event.table, self.event_received_info.table)
        self.assertEqual(self.event.key, self.event_received_info.key)
        self.assertEqual(self.event.action, self.event_received_info.action)
        # Value is not tested, since it's currently set to None
        # self.assertEqual(self.event.value, self.event_received_info.value)
        self.assertEqual(self.event.topic, self.event_received_info.topic)
Exemple #2
0
    def test_router_add_extra_route(self):
        lport = self.port1.port.get_logical_port()
        ip1 = lport.ip
        dest = "20.{}.{}.0/24".format(random.randint(0, 254),
                                      random.randint(0, 254))
        body = {"routes": [{"nexthop": str(ip1), "destination": dest}]}
        self.neutron.update_router(self.router.router.router_id,
                                   body={'router': body})

        # table = L3_LOOKUP_TABLE, priority = PRIORITY_VERY_HIGH, ip,
        # reg5 = router_unique_key, nw_dst = destination,
        # dl_dst = router_interface_mac
        # actions = dec_ttl, load: router_interface_mac->eth_src,
        # load: lport_mac->eth_dst, load:lport_unique_key->NXM_NX_REG7[],
        # resubmit(, 64)
        utils.wait_until_true(
            lambda: any(self._get_extra_route_flows(dest)),
            timeout=test_const.DEFAULT_RESOURCE_READY_TIMEOUT,
            exception=Exception('route flow entry is not installed'))
        body['routes'] = []
        self.neutron.update_router(self.router.router.router_id,
                                   body={'router': body})

        utils.wait_until_true(
            lambda: not any(self._get_extra_route_flows(dest)),
            timeout=test_const.DEFAULT_RESOURCE_READY_TIMEOUT,
            exception=Exception('route flow entry is not deleted'))
Exemple #3
0
 def test_create_update_subnet_with_dhcp(self):
     ovs = utils.OvsFlowsParser()
     flows_before_change = ovs.dump(self.integration_bridge)
     network = self.store(objects.NetworkTestObj(self.neutron, self.nb_api))
     network_id = network.create()
     subnet = {
         'network_id': network_id,
         'cidr': '10.10.254.0/24',
         'gateway_ip': '10.10.254.1',
         'ip_version': 4,
         'name': 'subnet-test',
         'enable_dhcp': True
     }
     subnet = self.neutron.create_subnet({'subnet': subnet})
     subnet_id = subnet['subnet']['id']
     dhcp_ip = utils.wait_until_is_and_return(
         lambda: self.get_dhcp_ip(network_id, subnet_id),
         exception=Exception('DHCP IP was not generated'))
     self.assertFalse(utils.check_dhcp_ip_rule(flows_before_change,
                                               dhcp_ip))
     utils.wait_until_true(
         lambda: utils.check_dhcp_ip_rule(ovs.dump(self.integration_bridge),
                                          dhcp_ip),
         exception=Exception('DHCP ip was not found in OpenFlow rules'),
         timeout=5)
     # change dhcp
     updated_subnet = {'enable_dhcp': False}
     self.neutron.update_subnet(subnet_id, {'subnet': updated_subnet})
     time.sleep(const.DEFAULT_RESOURCE_READY_TIMEOUT)
     flows_after_update = ovs.dump(self.integration_bridge)
     self.assertFalse(utils.check_dhcp_ip_rule(flows_after_update, dhcp_ip))
     network.close()
Exemple #4
0
    def test_dhcp_app_dos_block(self):
        def internal_predicate():
            ovs = test_utils.OvsFlowsParser()
            return (self._check_dhcp_block_rule(
                ovs.dump(self.integration_bridge)))

        self._create_topology()
        dhcp_packet = self._create_dhcp_discover()
        send_dhcp_offer = app_testing_objects.SendAction(
            self.subnet1.subnet_id,
            self.port1.port_id,
            dhcp_packet,
        )

        port_policies = self._create_port_policies(disable_rule=False)
        policy = app_testing_objects.Policy(
            initial_actions=[
                send_dhcp_offer, send_dhcp_offer, send_dhcp_offer,
                send_dhcp_offer
            ],
            port_policies=port_policies,
            unknown_port_action=app_testing_objects.IgnoreAction())
        self.addCleanup(policy.close)

        policy.start(self.topology)
        test_utils.wait_until_true(internal_predicate,
                                   const.DEFAULT_RESOURCE_READY_TIMEOUT, 1,
                                   None)
Exemple #5
0
 def wait_until_fip_active(self, timeout=const.DEFAULT_CMD_TIMEOUT,
                           sleep=1, exception=None):
     def internal_predicate():
         fip = self.get_floatingip()
         if fip and fip.get_status() == 'ACTIVE':
             return True
         return False
     utils.wait_until_true(internal_predicate, timeout, sleep, exception)
Exemple #6
0
 def start_subscribing(self):
     self._topology = self.store(
         test_objects.Topology(self.neutron, self.nb_api))
     subnet = self._topology.create_subnet(cidr="192.168.200.0/24")
     port = subnet.create_port()
     utils.wait_until_true(lambda: port.name is not None,
                           timeout=const.DEFAULT_RESOURCE_READY_TIMEOUT,
                           exception=Exception('Port was not created'))
Exemple #7
0
    def test_remote_port(self):
        if cfg.CONF.core_plugin == DF_PLUGIN:
            return

        network = self.store(objects.NetworkTestObj(self.neutron, self.nb_api))
        network_id = network.create(network={'name': 'network1'})
        self.assertTrue(network.exists())

        subnet_info = {
            'network_id': network_id,
            'cidr': '192.168.150.0/24',
            'gateway_ip': '192.168.150.1',
            'ip_version': 4,
            'name': 'subnet1',
            'enable_dhcp': True
        }
        subnet = self.store(
            objects.SubnetTestObj(self.neutron,
                                  self.nb_api,
                                  network_id=network_id))
        subnet.create(subnet_info)
        self.assertTrue(subnet.exists())

        port = self.store(
            objects.PortTestObj(self.neutron, self.nb_api, network_id))
        port_body = {
            'admin_state_up': True,
            'name': 'port1',
            'network_id': network_id,
            'binding:profile': {
                'port_key': 'remote_port',
                'host_ip': '10.10.10.10'
            }
        }
        port.create(port=port_body)
        self.assertTrue(port.exists())

        ovsdb = utils.OvsDBParser()
        utils.wait_until_true(
            lambda: self._get_wanted_tunnel_port(ovsdb, '10.10.10.10'),
            timeout=const.DEFAULT_RESOURCE_READY_TIMEOUT,
            sleep=2,
            exception=Exception('Could not get wanted tunnel port'))

        port.close()
        self.assertFalse(port.exists())

        utils.wait_until_none(
            lambda: ovsdb.get_tunnel_ofport('10.10.10.10'),
            timeout=const.DEFAULT_RESOURCE_READY_TIMEOUT,
            sleep=2,
            exception=Exception('Could not delete wanted tunnel port'))

        subnet.close()
        network.close()
Exemple #8
0
    def test_arp_responder(self):
        """
        Add a VM. Verify it's ARP flow is there.
        """
        network = objects.NetworkTestObj(self.neutron, self.nb_api)
        self.addCleanup(network.close)
        network_id = network.create(network={'name': 'arp_responder_test'})
        subnet_obj = objects.SubnetTestObj(self.neutron, self.nb_api,
                                           network_id)
        self.addCleanup(subnet_obj.close)

        subnet = {
            'network_id': network_id,
            'cidr': '10.10.10.0/24',
            'gateway_ip': '10.10.10.1',
            'ip_version': 4,
            'name': 'arp_responder_test',
            'enable_dhcp': True
        }
        subnet = subnet_obj.create(subnet)

        flows_before = self._get_arp_table_flows()
        vm = objects.VMTestObj(self, self.neutron)
        self.addCleanup(vm.close)
        vm.create(network=network)
        ip = vm.get_first_ipv4()
        self.assertIsNotNone(ip)

        flows_middle = self._get_arp_table_flows()

        vm.close()
        time.sleep(test_const.DEFAULT_RESOURCE_READY_TIMEOUT)
        flows_delta = [
            flow for flow in flows_middle if flow not in flows_before
        ]
        self.assertIsNotNone(
            self._find_arp_responder_flow_by_ip(flows_delta, ip))

        condition = lambda: self._check_arp_flow_removal(ip)
        try:
            test_utils.wait_until_true(
                condition,
                timeout=test_const.DEFAULT_RESOURCE_READY_TIMEOUT,
                sleep=1,
                exception=RuntimeError(
                    "Timed out waiting for arp responder flow from %(ip)s"
                    " to be removed" % {'ip': ip}))
        except Exception as e:
            self.assertIsNone(e)
        finally:
            network.close()
Exemple #9
0
    def test_reply_message(self):
        network = objects.NetworkTestObj(self.neutron, self.nb_api)
        self.addCleanup(network.close)
        network_id = network.create()
        subnet = objects.SubnetTestObj(self.neutron, self.nb_api, network_id)
        self.addCleanup(subnet.close)
        subnet_body = {
            'network_id': network_id,
            'cidr': '10.20.0.0/24',
            'gateway_ip': '10.20.0.1',
            'ip_version': 4,
            'name': 'private',
            'enable_dhcp': True
        }
        subnet.create(subnet=subnet_body)
        self.assertTrue(network.exists())
        self.assertTrue(subnet.exists())

        vm1 = objects.VMTestObj(self, self.neutron)
        self.addCleanup(vm1.close)
        vm1.create(network=network)
        self.assertIsNotNone(vm1.server.addresses['mynetwork'])
        mac1 = vm1.server.addresses['mynetwork'][0]['OS-EXT-IPS-MAC:mac_addr']
        self.assertIsNotNone(mac1)

        vm2 = objects.VMTestObj(self, self.neutron)
        self.addCleanup(vm2.close)
        vm2.create(network=network)
        self.assertIsNotNone(vm2.server.addresses['mynetwork'])
        mac2 = vm2.server.addresses['mynetwork'][0]['OS-EXT-IPS-MAC:mac_addr']
        self.assertIsNotNone(mac2)

        # wait util get the message we want
        self.set_wanted_vms.clear()
        utils.wait_until_true(
            lambda: self._get_all_wanted_vms_online(mac1, mac2),
            timeout=const.DEFAULT_RESOURCE_READY_TIMEOUT,
            sleep=1,
            exception=Exception('Could not get wanted online vm'))
        vm1.close()
        vm2.close()
        utils.wait_until_none(
            lambda: utils.find_logical_port(self.nb_api, ip=None, mac=mac1),
            timeout=const.DEFAULT_RESOURCE_READY_TIMEOUT,
            sleep=1,
            exception=Exception('Port was not deleted'))
        utils.wait_until_none(
            lambda: utils.find_logical_port(self.nb_api, ip=None, mac=mac2),
            timeout=const.DEFAULT_RESOURCE_READY_TIMEOUT,
            sleep=1,
            exception=Exception('Port was not deleted'))
Exemple #10
0
 def _create_vm(self, network):
     vm = self.store(objects.VMTestObj(self, self.neutron))
     vm.create(network=network)
     vm_mac = vm.get_first_mac()
     self.assertTrue(vm_mac is not None)
     vm_flows = self._get_vm_flows(vm_mac)
     self.assertTrue(any(vm_flows))
     if cfg.CONF.df.enable_neutron_notifier:
         # test port status update
         utils.wait_until_true(
             lambda: self._is_VM_port_status(vm, 'ACTIVE'),
             timeout=60,
             exception=Exception('Port status not change to ACTIVE')
         )
     return vm
Exemple #11
0
 def _remove_vm(self, vm):
     vm_mac = vm.get_first_mac()
     if cfg.CONF.df.enable_neutron_notifier:
         # test port status update
         vm.server.stop()
         utils.wait_until_true(
             lambda: self._is_VM_port_status(vm, 'DOWN'),
             timeout=60,
             exception=Exception('Port status not change to DOWN'))
     # delete vm
     vm.close()
     utils.wait_until_none(lambda: 1
                           if any(self._get_vm_flows(vm_mac)) else None,
                           timeout=60,
                           exception=Exception('VM flow was not deleted'))
Exemple #12
0
 def test_multiproc_pub_sub(self):
     if not self.do_test:
         return
     self.event_received = False
     cfg.CONF.set_override('publisher_multiproc_socket',
                           '/tmp/ipc_test_socket', group='df')
     pub_sub_driver = df_utils.load_driver(
         cfg.CONF.df.pub_sub_multiproc_driver,
         df_utils.DF_PUBSUB_DRIVER_NAMESPACE)
     publisher = pub_sub_driver.get_publisher()
     publisher.initialize()
     self.subscriber = pub_sub_driver.get_subscriber()
     self.subscriber.initialize(self._verify_event)
     self.subscriber.daemonize()
     publisher.send_event(self.event)
     test_utils.wait_until_true(lambda: self.event_received)
Exemple #13
0
    def test_notify_message(self):
        network = self.store(objects.NetworkTestObj(self.neutron, self.nb_api))
        network_id = network.create()
        subnet = self.store(
            objects.SubnetTestObj(self.neutron, self.nb_api, network_id))
        subnet_body = {
            'network_id': network_id,
            'cidr': '10.10.0.0/24',
            'gateway_ip': '10.10.0.1',
            'ip_version': 4,
            'name': 'private',
            'enable_dhcp': True
        }
        subnet.create(subnet=subnet_body)
        self.assertTrue(network.exists())
        self.assertTrue(subnet.exists())

        vm = self.store(objects.VMTestObj(self, self.neutron))
        vm.create(network=network)
        self.assertIsNotNone(vm.server.addresses['mynetwork'])
        mac = vm.server.addresses['mynetwork'][0]['OS-EXT-IPS-MAC:mac_addr']
        self.assertIsNotNone(mac)
        # wait util get the message we want
        utils.wait_until_true(
            lambda: self._get_wanted_vm_online(mac),
            timeout=const.DEFAULT_RESOURCE_READY_TIMEOUT,
            sleep=1,
            exception=Exception('Could not get wanted online vm'))

        # wait util get the message we want
        vm.close()
        utils.wait_until_true(
            lambda: self._get_wanted_vm_offline(mac),
            timeout=const.DEFAULT_RESOURCE_READY_TIMEOUT,
            sleep=1,
            exception=Exception('Could not get wanted offline vm'))
        utils.wait_until_none(
            lambda: utils.get_vm_port(self.nb_api, ip=None, mac=mac),
            timeout=const.DEFAULT_RESOURCE_READY_TIMEOUT,
            sleep=1,
            exception=Exception('Port was not deleted'))
Exemple #14
0
 def test_create_update_subnet_without_dhcp(self):
     ovs = utils.OvsFlowsParser()
     flows_before_change = ovs.dump(self.integration_bridge)
     network, network_id, network_key = self._create_network()
     subnet = {'network_id': network_id,
               'cidr': '10.20.0.0/24',
               'gateway_ip': '10.20.0.1',
               'ip_version': 4,
               'name': 'subnet-test',
               'enable_dhcp': False}
     subnet = self.neutron.create_subnet({'subnet': subnet})
     subnet_id = subnet['subnet']['id']
     time.sleep(const.DEFAULT_CMD_TIMEOUT)
     flows_after_change = ovs.dump(self.integration_bridge)
     # change dhcp
     updated_subnet = {'enable_dhcp': True}
     self.neutron.update_subnet(subnet_id, {'subnet': updated_subnet})
     dhcp_ip = utils.wait_until_is_and_return(
         lambda: self.get_dhcp_ip(network_id, subnet_id),
         exception=Exception('DHCP IP was not generated')
     )
     self.assertIsNotNone(dhcp_ip)
     self.assertFalse(utils.check_dhcp_network_rule(
         flows_before_change, network_key))
     self.assertFalse(utils.check_dhcp_network_rule(
         flows_after_change, network_key))
     utils.wait_until_true(
         lambda: utils.check_dhcp_network_rule(
             ovs.dump(self.integration_bridge),
             network_key),
         exception=Exception('DHCP ip was not found in OpenFlow rules'),
         timeout=5
     )
     network.close()
     utils.wait_until_none(
         lambda: utils.check_dhcp_network_rule(
             ovs.dump(self.integration_bridge),
             network_key),
         exception=Exception('DHCP IP was not removed from OpenFlow rules'),
         timeout=30
     )
Exemple #15
0
    def test_router_add_route(self):
        lport = self.port1.port.get_logical_port()
        ip1 = lport.get_ip()
        dest = "10.{}.{}.0/24".format(random.randint(0, 254),
                                      random.randint(0, 254))
        body = {"routes": [{"nexthop": ip1, "destination": dest}]}
        self.neutron.update_router(self.router.router.router_id,
                                   body={'router': body})

        # table = 20, priority = 100, ip, nw_src = 192.168.10.0/24,
        # nw_dst = 10.110.10.0/24
        # actions = dec_ttl, load:0x18->NXM_NX_REG7[], resubmit(, 64)
        utils.wait_until_true(
            lambda: any(self._get_route_flows('192.168.10.0/24', dest)),
            timeout=test_const.DEFAULT_RESOURCE_READY_TIMEOUT,
            exception=Exception('route flow entry is not installed'))
        body['routes'] = []
        self.neutron.update_router(self.router.router.router_id,
                                   body={'router': body})

        utils.wait_until_true(
            lambda: not any(self._get_route_flows('192.168.10.0/24', dest)),
            timeout=test_const.DEFAULT_RESOURCE_READY_TIMEOUT,
            exception=Exception('route flow entry is not deleted'))
    def test_db_consistent(self):
        self.db_sync_time = self.conf.db_sync_time
        network = self.store(objects.NetworkTestObj(self.neutron, self.nb_api))
        network_id = network.create()
        self.addCleanup(network.close)
        topic = network.get_topic()
        subnet = self.store(objects.SubnetTestObj(self.neutron, self.nb_api,
                                                  network_id))
        subnet_body = {'network_id': network_id,
                       'cidr': '10.50.0.0/24',
                       'gateway_ip': '10.50.0.1',
                       'ip_version': 4,
                       'name': 'private',
                       'enable_dhcp': True}
        subnet.create(subnet=subnet_body)
        self.addCleanup(subnet.close)
        time.sleep(constants.DEFAULT_RESOURCE_READY_TIMEOUT)
        self.assertTrue(network.exists())
        self.assertTrue(subnet.exists())

        vm = self.store(objects.VMTestObj(self, self.neutron))
        vm.create(network=network)
        self.addCleanup(vm.close)
        self.assertIsNotNone(vm.server.addresses['mynetwork'])
        mac = vm.server.addresses['mynetwork'][0]['OS-EXT-IPS-MAC:mac_addr']
        self.assertIsNotNone(mac)

        ovs = utils.OvsFlowsParser()
        utils.wait_until_true(
            lambda: self._check_l2_lookup_rule(
                    ovs.dump(self.integration_bridge), mac),
            timeout=10, sleep=1,
            exception=Exception('no rule for vm in l2 lookup table')
        )
        net_id = '11111111-1111-1111-1111-111111111111'
        df_network = l2.LogicalSwitch(
            id=net_id,
            topic=topic,
            name='df_nw1',
            network_type='vxlan',
            segmentation_id=4000,
            is_external=False,
            mtu=1500,
            unique_key=1,
            version=1)
        df_network_json = df_network.to_json()
        self.nb_api.driver.create_key(l2.LogicalSwitch.table_name,
                                      net_id, df_network_json, topic)
        self.addCleanup(self.nb_api.driver.delete_key, 'lswitch',
                        net_id, topic)

        subnet_id = '22222222-2222-2222-2222-222222222222'
        df_subnet = l2.Subnet(
            id=subnet_id,
            topic=topic,
            name='df_sn1',
            enable_dhcp=True,
            cidr='10.60.0.0/24',
            dhcp_ip='10.60.0.2',
            gateway_ip='10.60.0.1',
            version=1,
            lswitch=net_id)
        self.nb_api.driver.create_key(l2.Subnet.table_name,
                                      subnet_id, df_subnet.to_json(), topic)
        self.addCleanup(self.nb_api.driver.delete_key, l2.Subnet.table_name,
                        subnet_id, topic)

        port_id = '33333333-2222-2222-2222-222222222222,'
        dhcp_port = l2.LogicalPort(
            topic=topic,
            name='df_dhcp1',
            macs=['aa:bb:cc:dd:ee:ff'],
            id=port_id,
            ips=['10.60.0.2'],
            subnets=[df_subnet.id],
            device_owner=n_const.DEVICE_OWNER_DHCP,
            lswitch=df_network.id,
            unique_key=1
        ).to_json()

        self.nb_api.driver.create_key(
            'lport', port_id, dhcp_port, topic)

        df_net_unique_key = df_network.unique_key
        time.sleep(self.db_sync_time)
        utils.wait_until_true(
            lambda: utils.check_dhcp_network_rule(
                    ovs.dump(self.integration_bridge), df_net_unique_key),
            timeout=self.db_sync_time + constants.DEFAULT_CMD_TIMEOUT, sleep=1,
            exception=Exception('no goto dhcp rule for lswitch')
        )

        self.nb_api.driver.delete_key('lport', port_id, topic)
        time.sleep(self.db_sync_time)
        utils.wait_until_true(
            lambda: self._check_no_lswitch_dhcp_rule(
                    ovs.dump(self.integration_bridge), df_net_unique_key),
            timeout=self.db_sync_time + constants.DEFAULT_CMD_TIMEOUT, sleep=1,
            exception=Exception('could not delete goto dhcp rule for lswitch')
        )
Exemple #17
0
    def test_icmp_responder(self):
        """
        Add a VM. Verify the icmp flow is there.
        """
        network = self.store(objects.NetworkTestObj(self.neutron, self.nb_api))
        network_id = network.create(network={'name': 'icmp_responder_test'})
        subnet_obj = self.store(objects.SubnetTestObj(
            self.neutron,
            self.nb_api,
            network_id,
        ))

        subnet = {'network_id': network_id,
                  'cidr': '10.10.10.0/24',
                  'gateway_ip': '10.10.10.1',
                  'ip_version': 4,
                  'name': 'arp_responder_test',
                  'enable_dhcp': True}
        subnet_id = subnet_obj.create(subnet)

        flows_before = self._get_l3_lookup_table_flows()

        router = self.store(objects.RouterTestObj(self.neutron, self.nb_api))
        router_id = router.create()
        subnet_msg = {'subnet_id': subnet_id}
        interface = self.neutron.add_interface_router(router_id,
                                                      body=subnet_msg)
        port_id = interface['port_id']
        router_port = self.neutron.list_ports(id=port_id)['ports'][0]
        router_ip = None
        for ip in router_port['fixed_ips']:
            if ip['subnet_id'] == subnet_id:
                router_ip = ip['ip_address']
                break

        vm = self.store(objects.VMTestObj(self, self.neutron))
        vm.create(network=network)
        ip = vm.get_first_ipv4()
        self.assertIsNotNone(ip)

        flows_middle = self._get_l3_lookup_table_flows()

        vm.close()
        router.close()
        time.sleep(test_const.DEFAULT_RESOURCE_READY_TIMEOUT)

        flows_delta = [flow for flow in flows_middle
                       if flow not in flows_before]

        self.assertIsNotNone(
            self._find_icmp_responder_flow_by_ip(flows_delta, router_ip)
        )
        condition = lambda: self._check_icmp_flow_removal(router_ip)
        try:
            test_utils.wait_until_true(
                condition, timeout=test_const.DEFAULT_RESOURCE_READY_TIMEOUT,
                sleep=1,
                exception=RuntimeError(
                    "Timed out waiting for icmp responder flow from %(ip)s"
                    " to be removed" % {'ip': router_ip}))
        except Exception as e:
            self.assertIsNone(e)
        finally:
            network.close()
Exemple #18
0
    def test_db_consistent(self):
        self.db_sync_time = self.conf.db_sync_time
        network = self.store(objects.NetworkTestObj(self.neutron, self.nb_api))
        network_id = network.create()
        topic = network.get_topic()
        subnet = self.store(objects.SubnetTestObj(self.neutron, self.nb_api,
                                                  network_id))
        subnet_body = {'network_id': network_id,
                       'cidr': '10.50.0.0/24',
                       'gateway_ip': '10.50.0.1',
                       'ip_version': 4,
                       'name': 'private',
                       'enable_dhcp': True}
        subnet.create(subnet=subnet_body)
        time.sleep(constants.DEFAULT_RESOURCE_READY_TIMEOUT)
        self.assertTrue(network.exists())
        self.assertTrue(subnet.exists())

        vm = self.store(objects.VMTestObj(self, self.neutron))
        vm.create(network=network)
        self.assertIsNotNone(vm.server.addresses['mynetwork'])
        mac = vm.server.addresses['mynetwork'][0]['OS-EXT-IPS-MAC:mac_addr']
        self.assertIsNotNone(mac)

        ovs = utils.OvsFlowsParser()
        utils.wait_until_true(
            lambda: self._check_l2_lookup_rule(
                    ovs.dump(self.integration_bridge), mac),
            timeout=10, sleep=1,
            exception=Exception('no rule for vm in l2 lookup table')
        )
        net_id = '11111111-1111-1111-1111-111111111111'
        df_network = l2.LogicalSwitch(
            id=net_id,
            topic=topic,
            name='df_nw1',
            network_type='vxlan',
            segmentation_id=4000,
            is_external=False,
            mtu=1500,
            unique_key=1,
            version=1)

        df_subnet = l2.Subnet(
            id='22222222-2222-2222-2222-222222222222',
            topic=topic,
            name='df_sn1',
            enable_dhcp=True,
            cidr='10.60.0.0/24',
            dhcp_ip='10.60.0.2',
            gateway_ip='10.60.0.1')

        df_network.add_subnet(df_subnet)
        df_network_json = df_network.to_json()

        self.nb_api.driver.create_key(
                'lswitch', net_id, df_network_json, topic)

        time.sleep(self.db_sync_time)
        utils.wait_until_true(
            lambda: utils.check_dhcp_ip_rule(
                    ovs.dump(self.integration_bridge), '10.60.0.2'),
            timeout=self.db_sync_time + constants.DEFAULT_CMD_TIMEOUT, sleep=1,
            exception=Exception('no goto dhcp rule for lswitch')
        )

        df_network.version = 2
        df_network.subnets[0].dhcp_ip = '10.60.0.3'
        df_network_json = df_network.to_json()
        self.nb_api.driver.set_key('lswitch', net_id, df_network_json, topic)

        time.sleep(self.db_sync_time)
        utils.wait_until_true(
            lambda: utils.check_dhcp_ip_rule(
                    ovs.dump(self.integration_bridge), '10.60.0.3'),
            timeout=self.db_sync_time + constants.DEFAULT_CMD_TIMEOUT, sleep=1,
            exception=Exception('no goto dhcp rule for lswitch')
        )

        self.nb_api.driver.delete_key('lswitch', net_id, topic)
        time.sleep(self.db_sync_time)
        utils.wait_until_true(
            lambda: self._check_no_lswitch_dhcp_rule(
                    ovs.dump(self.integration_bridge), '10.60.0.3'),
            timeout=self.db_sync_time + constants.DEFAULT_CMD_TIMEOUT, sleep=1,
            exception=Exception('could not delete goto dhcp rule for lswitch')
        )

        vm.close()
        subnet.close()
        network.close()