Fix east_west capture for vlan tenant
With vlan tenant we have mac-mapping configured in ovs db for compute nodes. These MAC values should be used when filtering relevant traffic for east_west communication. Also, introduced separate tunnel_interface config parameter to define an appropriate value when capturing traffic on a normal node and on ovs_pod. Change-Id: Ibef4498604bd9fff7ab537ed276ce59e8a052cd6
This commit is contained in:
parent
a022d38865
commit
048c752ca3
@ -15,7 +15,6 @@
|
||||
|
||||
GLOBAL_IP = '1.1.1.1'
|
||||
METADATA_SERVICE_IP = '169.254.169.254'
|
||||
NODE_TUNNEL_INTERFACE = 'genev_sys_6081'
|
||||
OVN_MAX_GW_PORTS_PER_ROUTER = 5
|
||||
NEUTRON_CONF = {
|
||||
'devstack': '/etc/neutron/neutron.conf',
|
||||
|
@ -128,6 +128,10 @@ WhiteboxNeutronPluginOptions = [
|
||||
default='eth1',
|
||||
help='Physical interface of a node that is connected to the '
|
||||
'external network.'),
|
||||
cfg.StrOpt('ovs_pod_ext_interface',
|
||||
default='datacentre',
|
||||
help='Interface of a ovs pod (on podified openstack) that is '
|
||||
'connected to the external network.'),
|
||||
cfg.IntOpt('minbw_placement_nic_kbps_egress',
|
||||
default=None,
|
||||
help='BW configured per NIC for the minimum BW placement '
|
||||
@ -150,6 +154,18 @@ WhiteboxNeutronPluginOptions = [
|
||||
help='Interface of a node that intended to pass tenant'
|
||||
'network traffic. Note: currently only environments with '
|
||||
'the same name of the tenant interface are supported'),
|
||||
cfg.StrOpt('node_tunnel_interface',
|
||||
default='genev_sys_6081',
|
||||
help='Interface of a node that intended to pass tunnelled '
|
||||
'traffic. genev_sys_6081 is default for geneve tenant '
|
||||
'networks but for vlan tenant network this value should '
|
||||
'be updated according to the environment.'),
|
||||
cfg.StrOpt('ovs_pod_tunnel_interface',
|
||||
default='genev_sys_6081',
|
||||
help='Interface of a ovs pod that intended to pass tunnelled '
|
||||
'traffic. genev_sys_6081 is default for geneve tenant '
|
||||
'networks but for vlan tenant network this value should '
|
||||
'be updated according to the environment.'),
|
||||
cfg.IntOpt('capture_timeout',
|
||||
default=120,
|
||||
help='Maximal time for running remote capture, in seconds. '
|
||||
|
@ -182,6 +182,11 @@ class BaseTempestWhiteboxTestCase(base.BaseTempestTestCase):
|
||||
return host_name
|
||||
return hostname
|
||||
|
||||
def get_network_type(self, network_id):
|
||||
network_details = self.os_admin.network_client.show_network(
|
||||
network_id)
|
||||
return network_details['network']['provider:network_type']
|
||||
|
||||
@staticmethod
|
||||
def _get_local_ip_from_network(network):
|
||||
host_ip_addresses = [ifaddresses(iface)[AF_INET][0]['addr']
|
||||
@ -1055,7 +1060,7 @@ class TrafficFlowTest(BaseTempestWhiteboxTestCase):
|
||||
if node['name'] == line.split()[0]:
|
||||
node['ovs_pod'] = line.split()[1]
|
||||
|
||||
def _start_captures(self, filters, interface=None):
|
||||
def _start_captures(self, filters, scenario='north_south', interface=None):
|
||||
for node in self.nodes:
|
||||
if not (node['is_controller'] or
|
||||
node['is_compute'] or
|
||||
@ -1067,18 +1072,27 @@ class TrafficFlowTest(BaseTempestWhiteboxTestCase):
|
||||
node['is_controller']):
|
||||
capture_client = self.proxy_host_client
|
||||
command_prefix = "{} rsh {} ".format(self.OC, node['ovs_pod'])
|
||||
capture_interface = interface if interface else 'datacentre'
|
||||
if interface:
|
||||
capture_interface = interface
|
||||
else:
|
||||
if scenario == 'north_south':
|
||||
capture_interface = WB_CONF.ovs_pod_ext_interface
|
||||
else:
|
||||
capture_interface = WB_CONF.ovs_pod_tunnel_interface
|
||||
else:
|
||||
capture_client = node['client']
|
||||
command_prefix = ''
|
||||
if interface:
|
||||
capture_interface = interface
|
||||
else:
|
||||
if scenario == 'north_south':
|
||||
capture_interface = WB_CONF.node_ext_interface
|
||||
else:
|
||||
capture_interface = WB_CONF.node_tunnel_interface
|
||||
node['capture'] = capture.TcpdumpCapture(
|
||||
capture_client, capture_interface, filters, command_prefix)
|
||||
self.useFixture(node['capture'])
|
||||
time.sleep(10)
|
||||
time.sleep(2)
|
||||
|
||||
def _stop_captures(self):
|
||||
for node in self.nodes:
|
||||
@ -1116,9 +1130,9 @@ class TrafficFlowTest(BaseTempestWhiteboxTestCase):
|
||||
else:
|
||||
raise TypeError(expected_macs)
|
||||
|
||||
self._start_captures(filters,
|
||||
interface=local_constants.NODE_TUNNEL_INTERFACE)
|
||||
self._start_captures(filters, scenario='east_west')
|
||||
self.check_remote_connectivity(ssh_client, dst_ip, ping_count=2)
|
||||
time.sleep(5)
|
||||
self._stop_captures()
|
||||
LOG.debug('Expected routing nodes: {}'.format(
|
||||
','.join(expected_routing_nodes)))
|
||||
@ -1345,6 +1359,14 @@ class BaseTempestTestCaseOvn(BaseTempestWhiteboxTestCase):
|
||||
output = self.run_on_master_controller(cmd)
|
||||
self.assertEqual(output, '')
|
||||
|
||||
def get_mac_mappings(self, client, physical_network):
|
||||
output = client.exec_command(
|
||||
"sudo ovs-vsctl get open . external_ids:ovn-chassis-mac-"
|
||||
"mappings").strip().replace('"', '').split(',')
|
||||
for value in output:
|
||||
if physical_network in value:
|
||||
return value.replace(physical_network + ':', '')
|
||||
|
||||
|
||||
class BaseDisruptiveTempestTestCase(BaseTempestWhiteboxTestCase):
|
||||
@classmethod
|
||||
|
@ -123,9 +123,7 @@ class OvnDvrBase(base.TrafficFlowTest, base.BaseTempestTestCaseOvn):
|
||||
# on environments that schedule ovn routers on compute nodes
|
||||
self.exclude_hosts = [self.chassis_name]
|
||||
|
||||
network_details = self.os_admin.network_client.show_network(
|
||||
self.network['id'])
|
||||
if network_details['network']['provider:network_type'] == 'vlan':
|
||||
if self.get_network_type(self.network['id']) == 'vlan':
|
||||
# This helps to avoid false positives with vlan+dvr,see BZ2192633
|
||||
self.ignore_outbound = True
|
||||
else:
|
||||
@ -534,10 +532,29 @@ class OvnDvrTest(OvnDvrBase):
|
||||
device_owner=constants.DEVICE_OWNER_ROUTER_INTF,
|
||||
network_id=networks[i]['id'])['ports'][0]['mac_address'])
|
||||
|
||||
def get_mac_mapping_for_vm(vm):
|
||||
return self.get_mac_mappings(
|
||||
self.find_node_client(
|
||||
self.get_host_for_server(vm['server']['id'])),
|
||||
'datacentre')
|
||||
|
||||
def get_expected_macs_for_vlan_tenant():
|
||||
return [
|
||||
(servers[0]['port']['mac_address'],
|
||||
get_mac_mapping_for_vm(servers[1])),
|
||||
(get_mac_mapping_for_vm(servers[0]),
|
||||
servers[1]['port']['mac_address'])]
|
||||
|
||||
# verify E/W connection between servers
|
||||
if self.get_network_type(networks[0]['id']) == 'vlan' and \
|
||||
self.get_network_type(networks[1]['id']) == 'vlan':
|
||||
ew_expected_macs = get_expected_macs_for_vlan_tenant()
|
||||
else:
|
||||
ew_expected_macs = [
|
||||
(servers[0]['port']['mac_address'], router_port_subnet_macs[0]),
|
||||
(router_port_subnet_macs[1], servers[1]['port']['mac_address'])]
|
||||
(servers[0]['port']['mac_address'],
|
||||
router_port_subnet_macs[0]),
|
||||
(router_port_subnet_macs[1],
|
||||
servers[1]['port']['mac_address'])]
|
||||
# remove duplicates
|
||||
expected_routing_nodes = list(set([host for host in servers_host]))
|
||||
if len(expected_routing_nodes) == 1:
|
||||
@ -581,6 +598,13 @@ class OvnDvrTest(OvnDvrBase):
|
||||
ssh_client=servers_ssh_client[i])
|
||||
|
||||
# verify E/W connection between servers
|
||||
# Since with vlan tenant we have MAC mapping on compute nodes
|
||||
# and VMs migrated, we need to retrieve MAC address combination
|
||||
# for filtering again
|
||||
if self.get_network_type(networks[0]['id']) == 'vlan' and \
|
||||
self.get_network_type(networks[1]['id']) == 'vlan':
|
||||
ew_expected_macs = get_expected_macs_for_vlan_tenant()
|
||||
|
||||
# remove duplicates
|
||||
expected_routing_nodes = list(set([host for host in new_servers_host]))
|
||||
if len(expected_routing_nodes) == 1:
|
||||
|
Loading…
Reference in New Issue
Block a user