def _setUp(self): super(OVSTrunkConnectionTester, self)._setUp() self.bridge = self.useFixture(net_helpers.OVSBridgeFixture()).bridge self.br_trunk = self.useFixture( net_helpers.OVSTrunkBridgeFixture(self._br_trunk_name)).bridge self._peer = self.useFixture( machine_fixtures.FakeMachine(self.bridge, self.ip_cidr)) ip_cidr = net_helpers.increment_ip_cidr(self.ip_cidr, 1) self._vm = self.useFixture( machine_fixtures.FakeMachine(self.br_trunk, ip_cidr))
def test_fip_connection_for_address_scope(self): self.agent.conf.agent_mode = 'dvr_snat' (machine_same_scope, machine_diff_scope, router) = self._setup_address_scope('scope1', 'scope2', 'scope1') router.router[l3_constants.FLOATINGIP_KEY] = [] fip_same_scope = '19.4.4.10' self._add_fip(router, fip_same_scope, fixed_address=machine_same_scope.ip, host=self.agent.conf.host, fixed_ip_address_scope='scope1') fip_diff_scope = '19.4.4.11' self._add_fip(router, fip_diff_scope, fixed_address=machine_diff_scope.ip, host=self.agent.conf.host, fixed_ip_address_scope='scope2') router.process(self.agent) br_ex = framework.get_ovs_bridge( self.agent.conf.external_network_bridge) src_machine = self.useFixture( machine_fixtures.FakeMachine(br_ex, '19.4.4.12/24')) # Floating ip should work no matter of address scope net_helpers.assert_ping(src_machine.namespace, fip_same_scope, 5) net_helpers.assert_ping(src_machine.namespace, fip_diff_scope, 5)
def test_access_to_metadata_proxy(self): """Test access to the l3-agent metadata proxy. The test creates: * A l3-agent metadata service: * A router (which creates a metadata proxy in the router namespace), * A fake metadata server * A "client" namespace (simulating a vm) with a port on router internal subnet. The test queries from the "client" namespace the metadata proxy on http://169.254.169.254 and asserts that the metadata proxy added the X-Forwarded-For and X-Neutron-Router-Id headers to the request and forwarded the http request to the fake metadata server and the response to the "client" namespace. """ router_info = self.generate_router_info(enable_ha=False) router = self.manage_router(self.agent, router_info) self._create_metadata_fake_server(webob.exc.HTTPOk.code) # Create and configure client namespace router_ip_cidr = self._port_first_ip_cidr(router.internal_ports[0]) br_int = framework.get_ovs_bridge( self.agent.conf.OVS.integration_bridge) machine = self.useFixture( machine_fixtures.FakeMachine( br_int, net_helpers.increment_ip_cidr(router_ip_cidr), router_ip_cidr.partition('/')[0])) # Query metadata proxy firstline = self._query_metadata_proxy(machine) # Check status code self.assertIn(str(webob.exc.HTTPOk.code), firstline.split())
def test_ha_router_restart_agents_no_packet_lost(self): tenant_id = uuidutils.generate_uuid() ext_net, ext_sub = self._create_external_network_and_subnet(tenant_id) router = self.safe_client.create_router(tenant_id, ha=True, external_network=ext_net['id']) external_vm = self.useFixture( machine_fixtures.FakeMachine( self.environment.central_bridge, common_utils.ip_to_cidr(ext_sub['gateway_ip'], 24))) common_utils.wait_until_true( lambda: len(self.client.list_l3_agent_hosting_routers( router['id'])['agents']) == 2, timeout=90) common_utils.wait_until_true( functools.partial( self._is_ha_router_active_on_one_agent, router['id']), timeout=90) router_ip = router['external_gateway_info'][ 'external_fixed_ips'][0]['ip_address'] # Let's check first if connectivity from external_vm to router's # external gateway IP is possible before we restart agents external_vm.block_until_ping(router_ip) l3_agents = [host.agents['l3'] for host in self.environment.hosts] self._assert_ping_during_agents_restart( l3_agents, external_vm.namespace, [router_ip], count=60, max_workers=1)
def test_ha_router_restart_standby_agents_no_packet_lost(self): tenant_id = uuidutils.generate_uuid() ext_net, ext_sub = self._create_external_network_and_subnet(tenant_id) router = self.safe_client.create_router(tenant_id, ha=True, external_network=ext_net['id']) external_vm = self.useFixture( machine_fixtures.FakeMachine( self.environment.central_external_bridge, common_utils.ip_to_cidr(ext_sub['gateway_ip'], 24))) common_utils.wait_until_true(lambda: len( self.client.list_l3_agent_hosting_routers(router['id'])['agents']) == 2, timeout=90) common_utils.wait_until_true(functools.partial( self._is_ha_router_active_on_one_agent, router['id']), timeout=90) router_ip = router['external_gateway_info']['external_fixed_ips'][0][ 'ip_address'] l3_agents = [host.agents['l3'] for host in self.environment.hosts] l3_standby_agents = self._get_l3_agents_with_ha_state( l3_agents, router['id'], 'standby') self._assert_ping_during_agents_restart(l3_standby_agents, external_vm.namespace, [router_ip], count=60)
def test_snat_and_floatingip(self): # This function creates external network and boots an extrenal vm # on it with gateway ip and connected to central_external_bridge. # Later it creates a tenant vm on tenant network, with tenant router # connected to tenant network and external network. # To test snat and floatingip, try ping between tenant and external vms tenant_id = uuidutils.generate_uuid() ext_net, ext_sub = self._create_external_network_and_subnet(tenant_id) external_vm = self.useFixture( machine_fixtures.FakeMachine( self.environment.central_external_bridge, common_utils.ip_to_cidr(ext_sub['gateway_ip'], 24))) router = self.safe_client.create_router(tenant_id, external_network=ext_net['id']) vm = self._create_net_subnet_and_vm(tenant_id, ['20.0.0.0/24'], self.environment.hosts[1], router) # ping external vm to test snat vm.block_until_ping(external_vm.ip) fip = self.safe_client.create_floatingip(tenant_id, ext_net['id'], vm.ip, vm.neutron_port['id']) # ping floating ip from external vm external_vm.block_until_ping(fip['floating_ip_address'])
def _create_external_vm(self, network, subnet): vm = self.useFixture( machine_fixtures.FakeMachine( self.environment.central_bridge, common_utils.ip_to_cidr(subnet['gateway_ip'], 24))) # NOTE(slaweq): as ext_net is 'vlan' network type external_vm needs to # send packets with proper vlan also vm.bridge.set_db_attribute("Port", vm.port.name, "tag", network.get("provider:segmentation_id")) return vm
def _setup_address_scope(self, internal_address_scope1, internal_address_scope2, gw_address_scope=None): router_info = self.generate_dvr_router_info(enable_snat=True) address_scope1 = { str(l3_constants.IP_VERSION_4): internal_address_scope1 } address_scope2 = { str(l3_constants.IP_VERSION_4): internal_address_scope2 } if gw_address_scope: router_info['gw_port']['address_scopes'] = { str(l3_constants.IP_VERSION_4): gw_address_scope } router_info[l3_constants.INTERFACE_KEY][0]['address_scopes'] = ( address_scope1) router_info[l3_constants.INTERFACE_KEY][1]['address_scopes'] = ( address_scope2) # Renew the address scope router_info[n_const.SNAT_ROUTER_INTF_KEY] = [] self._add_snat_port_info_to_router( router_info, router_info[l3_constants.INTERFACE_KEY]) router = self.manage_router(self.agent, router_info) router_ip_cidr1 = self._port_first_ip_cidr(router.internal_ports[0]) router_ip1 = router_ip_cidr1.partition('/')[0] router_ip_cidr2 = self._port_first_ip_cidr(router.internal_ports[1]) router_ip2 = router_ip_cidr2.partition('/')[0] br_int = framework.get_ovs_bridge( self.agent.conf.ovs_integration_bridge) test_machine1 = self.useFixture( machine_fixtures.FakeMachine( br_int, net_helpers.increment_ip_cidr(router_ip_cidr1, 10), router_ip1)) test_machine2 = self.useFixture( machine_fixtures.FakeMachine( br_int, net_helpers.increment_ip_cidr(router_ip_cidr2, 10), router_ip2)) return test_machine1, test_machine2, router
def test_north_south_traffic(self): # This function creates an external network which is connected to # central_external_bridge and spawns an external_vm on it. # The external_vm is configured with the gateway_ip (both v4 & v6 # addresses) of external subnet. Later, it creates a tenant router, # a tenant network and two tenant subnets (v4 and v6). The tenant # router is associated with tenant network and external network to # provide north-south connectivity to the VMs. # We validate the following in this testcase. # 1. SNAT support: using ping from tenant VM to external_vm # 2. Floating IP support: using ping from external_vm to VM floating ip # 3. IPv6 ext connectivity: using ping6 from tenant vm to external_vm. tenant_id = uuidutils.generate_uuid() ext_net, ext_sub = self._create_external_network_and_subnet(tenant_id) external_vm = self.useFixture( machine_fixtures.FakeMachine( self.environment.central_external_bridge, common_utils.ip_to_cidr(ext_sub['gateway_ip'], 24))) # Create an IPv6 subnet in the external network v6network = self.useFixture( ip_network.ExclusiveIPNetwork("2001:db8:1234::1", "2001:db8:1234::10", "64")).network ext_v6sub = self.safe_client.create_subnet(tenant_id, ext_net['id'], v6network) router = self.safe_client.create_router(tenant_id, external_network=ext_net['id']) # Configure the gateway_ip of external v6subnet on the external_vm. external_vm.ipv6_cidr = common_utils.ip_to_cidr( ext_v6sub['gateway_ip'], 64) # Configure an IPv6 downstream route to the v6Address of router gw port for fixed_ip in router['external_gateway_info']['external_fixed_ips']: if netaddr.IPNetwork(fixed_ip['ip_address']).version == 6: external_vm.set_default_gateway(fixed_ip['ip_address']) vm = self._create_net_subnet_and_vm( tenant_id, ['20.0.0.0/24', '2001:db8:aaaa::/64'], self.environment.hosts[1], router) # ping external vm to test snat vm.block_until_ping(external_vm.ip) fip = self.safe_client.create_floatingip(tenant_id, ext_net['id'], vm.ip, vm.neutron_port['id']) # ping floating ip from external vm external_vm.block_until_ping(fip['floating_ip_address']) # Verify VM is able to reach the router interface. vm.block_until_ping(vm.gateway_ipv6) # Verify north-south connectivity using ping6 to external_vm. vm.block_until_ping(external_vm.ipv6)
def _setup_address_scope(self, internal_address_scope1, internal_address_scope2, gw_address_scope=None): router_info = self.generate_router_info(enable_ha=False, num_internal_ports=2) address_scope1 = { str(l3_constants.IP_VERSION_4): internal_address_scope1 } address_scope2 = { str(l3_constants.IP_VERSION_4): internal_address_scope2 } if gw_address_scope: router_info['gw_port']['address_scopes'] = { str(l3_constants.IP_VERSION_4): gw_address_scope } router_info[l3_constants.INTERFACE_KEY][0]['address_scopes'] = ( address_scope1) router_info[l3_constants.INTERFACE_KEY][1]['address_scopes'] = ( address_scope2) router = self.manage_router(self.agent, router_info) router_ip_cidr1 = self._port_first_ip_cidr(router.internal_ports[0]) router_ip1 = router_ip_cidr1.partition('/')[0] router_ip_cidr2 = self._port_first_ip_cidr(router.internal_ports[1]) router_ip2 = router_ip_cidr2.partition('/')[0] br_int = framework.get_ovs_bridge( self.agent.conf.ovs_integration_bridge) test_machine1 = self.useFixture( machine_fixtures.FakeMachine( br_int, net_helpers.increment_ip_cidr(router_ip_cidr1), router_ip1)) test_machine2 = self.useFixture( machine_fixtures.FakeMachine( br_int, net_helpers.increment_ip_cidr(router_ip_cidr2), router_ip2)) return test_machine1, test_machine2, router
def _test_gateway_ip_changed(self): tenant_id = uuidutils.generate_uuid() ext_net, ext_sub = self._create_external_network_and_subnet(tenant_id) external_vm = self.useFixture( machine_fixtures.FakeMachine( self.environment.central_bridge, common_utils.ip_to_cidr(ext_sub['gateway_ip'], 24))) router = self.safe_client.create_router(tenant_id, external_network=ext_net['id']) vm = self._create_net_subnet_and_vm( tenant_id, ['20.0.0.0/24', '2001:db8:aaaa::/64'], self.environment.hosts[1], router) # ping external vm to test snat vm.block_until_ping(external_vm.ip) fip = self.safe_client.create_floatingip(tenant_id, ext_net['id'], vm.ip, vm.neutron_port['id']) # ping floating ip from external vm external_vm.block_until_ping(fip['floating_ip_address']) # ping router gateway IP old_gw_ip = router['external_gateway_info']['external_fixed_ips'][0][ 'ip_address'] external_vm.block_until_ping(old_gw_ip) gateway_port = self.safe_client.list_ports( device_id=router['id'], device_owner=constants.DEVICE_OWNER_ROUTER_GW)[0] ip_1 = str(netaddr.IPNetwork( ext_sub['gateway_ip']).next(100)).split('/')[0] ip_2 = str(netaddr.IPNetwork( ext_sub['gateway_ip']).next(101)).split('/')[0] self.safe_client.update_port(gateway_port['id'], fixed_ips=[{ 'ip_address': ip_1 }, { 'ip_address': ip_2 }]) # ping router gateway new IPs external_vm.block_until_ping(ip_1) external_vm.block_until_ping(ip_2) # ping router old gateway IP, should fail now external_vm.block_until_no_ping(old_gw_ip)
def test_direct_route_for_address_scope(self): (machine_same_scope, machine_diff_scope, router) = self._setup_address_scope('scope1', 'scope2', 'scope1') gw_port = router.get_ex_gw_port() gw_ip = self._port_first_ip_cidr(gw_port).partition('/')[0] br_int = framework.get_ovs_bridge( self.agent.conf.OVS.integration_bridge) src_machine = self.useFixture( machine_fixtures.FakeMachine(br_int, '19.4.4.12/24', gw_ip)) # For the internal networks that are in the same address scope as # external network, they can directly route to external network net_helpers.assert_ping(src_machine.namespace, machine_same_scope.ip) # For the internal networks that are not in the same address scope as # external networks. SNAT will be used. Direct route will not work # here. src_machine.assert_no_ping(machine_diff_scope.ip)
def add_vlan_interface_and_peer(self, vlan, ip_cidr): """Create a sub_port and a peer We create a sub_port that uses vlan as segmentation ID. In the vm namespace we create a vlan subinterface on the same vlan. A peer on the same network is created. When pinging from the peer to the sub_port packets will be tagged using the internal vlan ID of the network. The sub_port will remove that vlan tag and push the vlan specified in the segmentation ID. The packets will finally reach the vlan subinterface in the vm namespace. """ network = netaddr.IPNetwork(ip_cidr) net_helpers.create_vlan_interface(self._vm.namespace, self._vm.port.name, self.vm_mac_address, network, vlan) self._ip_vlan = str(network.ip) ip_cidr = net_helpers.increment_ip_cidr(ip_cidr, 1) self._peer2 = self.useFixture( machine_fixtures.FakeMachine(self.bridge, ip_cidr))
def test_fip_connection_for_address_scope(self): (machine_same_scope, machine_diff_scope, router) = self._setup_address_scope('scope1', 'scope2', 'scope1') router.router[lib_constants.FLOATINGIP_KEY] = [] fip_same_scope = '19.4.4.10' self._add_fip(router, fip_same_scope, fixed_address=machine_same_scope.ip, fixed_ip_address_scope='scope1') fip_diff_scope = '19.4.4.11' self._add_fip(router, fip_diff_scope, fixed_address=machine_diff_scope.ip, fixed_ip_address_scope='scope2') router.process() br_int = framework.get_ovs_bridge( self.agent.conf.ovs_integration_bridge) src_machine = self.useFixture( machine_fixtures.FakeMachine(br_int, '19.4.4.12/24')) # Floating ip should work no matter of address scope net_helpers.assert_ping(src_machine.namespace, fip_same_scope) net_helpers.assert_ping(src_machine.namespace, fip_diff_scope)
def add_vlan_interface_and_peer(self, vlan, ip_cidr): """Create a sub_port and a peer We create a sub_port that uses vlan as segmentation ID. In the vm namespace we create a vlan subinterface on the same vlan. A peer on the same network is created. When pinging from the peer to the sub_port packets will be tagged using the internal vlan ID of the network. The sub_port will remove that vlan tag and push the vlan specified in the segmentation ID. The packets will finally reach the vlan subinterface in the vm namespace. """ ip_wrap = ip_lib.IPWrapper(self._vm.namespace) dev_name = self._vm.port.name + ".%d" % vlan ip_wrap.add_vlan(dev_name, self._vm.port.name, vlan) dev = ip_wrap.device(dev_name) dev.addr.add(ip_cidr) dev.link.set_up() self._ip_vlan = ip_cidr.partition('/')[0] ip_cidr = net_helpers.increment_ip_cidr(ip_cidr, 1) self._peer2 = self.useFixture( machine_fixtures.FakeMachine(self.bridge, ip_cidr))