Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions doc/source/admin/config-ovs-offload.rst
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ Validate Open vSwitch hardware offloading

.. code-block:: bash

# openstack port create --network private --vnic-type=direct --binding-profile '{"capabilities": ["switchdev"]}' direct_port1
# openstack port create --network private --vnic-type=direct direct_port1


#. Create an instance using the direct port on 'First Compute Node'
Expand All @@ -369,7 +369,7 @@ Validate Open vSwitch hardware offloading

.. code-block:: bash

# openstack port create --network private --vnic-type=direct --binding-profile '{"capabilities": ["switchdev"]}' direct_port2
# openstack port create --network private --vnic-type=direct direct_port2
# openstack server create --flavor m1.small --image mellanox_fedora --nic port-id=direct_port2 vm2

.. note::
Expand Down
34 changes: 17 additions & 17 deletions doc/source/contributor/internals/openvswitch_agent.rst
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,7 @@ The IDs used for bridge and port names are truncated.
| tbr-trunk-id |
| |
| tpt-parent-id spt-subport-id |
| (tag 100) |
| (tag 0) (tag 100) |
+-----+-----------------+--------+
| |
| |
Expand All @@ -514,27 +514,27 @@ spi-subport-id: int bridge side of the patch port that implements a subport.
Trunk creation
++++++++++++++

A VM is spawned passing to Nova the port-id of a parent port associated with
a trunk. Neutron will pass to Nova the bridge where to plug the vif as part of the vif details.
The os-vif driver creates the trunk bridge tbr-trunk-id if it does not exist in plug().
It will create the tap interface tap1 and plug it into tbr-trunk-id setting the parent port ID in the external-ids.
The OVS agent will be monitoring the creation of ports on the trunk bridges. When it detects
that a new port has been created on the trunk bridge, it will do the following:
A VM is spawned passing to Nova the port-id of a parent port associated
with a trunk. Neutron will pass to Nova the bridge where to plug the
vif as part of the vif details. The os-vif driver creates the trunk
bridge tbr-trunk-id if it does not exist in plug(). It will create the
tap interface tap1 and plug it into tbr-trunk-id setting the parent port
ID in the external-ids. The trunk driver will wire the parent port via
a patch port to connect the trunk bridge to the integration bridge:

::

ovs-vsctl add-port tbr-trunk-id tpt-parent-id -- set Interface tpt-parent-id type=patch options:peer=tpi-parent-id
ovs-vsctl add-port br-int tpi-parent-id tag=3 -- set Interface tpi-parent-id type=patch options:peer=tpt-parent-id
ovs-vsctl add-port tbr-trunk-id tpt-parent-id -- set Interface tpt-parent-id type=patch options:peer=tpi-parent-id -- set Port tpt-parent-id vlan_mode=access tag=0
ovs-vsctl add-port br-int tpi-parent-id -- set Interface tpi-parent-id type=patch options:peer=tpt-parent-id


A patch port is created to connect the trunk bridge to the integration bridge.
tpt-parent-id, the trunk bridge side of the patch is not associated to any
tag. It will carry untagged traffic.
tpi-parent-id, the br-int side the patch port is tagged with VLAN 3. We assume that the
trunk is on network1 that on this host is associated with VLAN 3.
The OVS agent will set the trunk ID in the external-ids of tpt-parent-id and tpi-parent-id.
If the parent port is associated with one or more subports the agent will process them as
described in the next paragraph.
tpt-parent-id, the trunk bridge side of the patch will carry untagged
traffic (vlan_mode=access tag=0). The OVS agent will be monitoring the
creation of ports on the integration bridge. tpi-parent-id, the br-int
side the patch port is tagged with VLAN 3 by ovs-agent. We assume that
the trunk is on network1 that on this host is associated with VLAN 3.
If the parent port is associated with one or more subports the agent
will process them as described in the next paragraph.

Subport creation
++++++++++++++++
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def __init__(self, trunk_id, port_id, port_mac=None):
self.DEV_PREFIX, port_id)
self._transaction = None

def plug(self, br_int):
def plug(self, br_int, tag=0):
"""Plug patch ports between trunk bridge and given bridge.

The method plugs one patch port on the given bridge side using
Expand Down Expand Up @@ -124,6 +124,9 @@ def plug(self, br_int):
self.patch_port_trunk_name))
txn.add(ovsdb.db_set('Interface', self.patch_port_trunk_name,
*patch_trunk_attrs))
txn.add(ovsdb.db_set('Port', self.patch_port_trunk_name,
('vlan_mode', 'access'),
('tag', tag)))

def unplug(self, bridge):
"""Unplug the trunk from bridge.
Expand Down Expand Up @@ -168,12 +171,7 @@ def plug(self, br_int):
:param br_int: an integration bridge where peer endpoint of patch port
will be created.
"""
ovsdb = self.bridge.ovsdb
with ovsdb.transaction() as txn:
super(SubPort, self).plug(br_int)
txn.add(ovsdb.db_set(
"Port", self.patch_port_trunk_name,
("tag", self.segmentation_id)))
super(SubPort, self).plug(br_int, tag=self.segmentation_id)

def unplug(self, bridge):
"""Unplug the sub port from the bridge.
Expand Down
17 changes: 0 additions & 17 deletions neutron/tests/fullstack/agents/ovs_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,25 +22,9 @@
from neutron.agent.common import polling
from neutron.agent.l2.extensions import qos as qos_extension
from neutron.common import config
from neutron.services.trunk.drivers.openvswitch.agent \
import driver as trunk_driver
from neutron.tests.common.agents import ovs_agent


def monkeypatch_init_handler():
original_handler = trunk_driver.init_handler

def new_init_handler(resource, event, trigger, payload=None):
# NOTE(slaweq): make this setup conditional based on server-side
# capabilities for fullstack tests we can assume that server-side
# and agent-side conf are in sync
if "trunk" not in cfg.CONF.service_plugins:
return
original_handler(resource, event, trigger, payload)

trunk_driver.init_handler = new_init_handler


def monkeypatch_qos():
mock.patch.object(ovs_lib.OVSBridge, 'clear_bandwidth_qos').start()
if "qos" in cfg.CONF.service_plugins:
Expand All @@ -63,7 +47,6 @@ def main():
# ovs-vswitchd processes for each test will be isolated in separate
# namespace
config.register_common_config_options()
monkeypatch_init_handler()
monkeypatch_qos()
monkeypatch_event_filtering()
ovs_agent.main()
Expand Down
16 changes: 0 additions & 16 deletions neutron/tests/fullstack/test_connectivity.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,22 +83,6 @@ def _test_connectivity(self):
vms.ping_all()


class TestOvsConnectivitySameNetwork(BaseConnectivitySameNetworkTest):

l2_agent_type = constants.AGENT_TYPE_OVS
scenarios = [
('VXLAN', {'network_type': 'vxlan',
'l2_pop': False}),
('GRE-l2pop-arp_responder', {'network_type': 'gre',
'l2_pop': True,
'arp_responder': True}),
('VLANs', {'network_type': 'vlan',
'l2_pop': False})]

def test_connectivity(self):
self._test_connectivity()


class TestOvsConnectivitySameNetworkOnOvsBridgeControllerStop(
BaseConnectivitySameNetworkTest):

Expand Down
9 changes: 0 additions & 9 deletions neutron/tests/fullstack/test_dhcp_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,15 +91,6 @@ class TestDhcpAgentNoHA(BaseDhcpAgentTest):
number_of_hosts = 1
agent_down_time = 60

def test_dhcp_assignment(self):
# First check if network was scheduled to one DHCP agent
dhcp_agents = self.client.list_dhcp_agent_hosting_networks(
self.network['id'])
self.assertEqual(1, len(dhcp_agents['agents']))

# And check if IP and gateway config is fine on FakeMachine
self.vm.block_until_dhcp_config_done()

def test_mtu_update(self):
# The test case needs access to devices in nested namespaces. ip_lib
# doesn't support it, and it's probably unsafe to touch the library for
Expand Down
99 changes: 0 additions & 99 deletions neutron/tests/fullstack/test_l3_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
import os
import time

import netaddr
from neutron_lib import constants
from neutronclient.common import exceptions
from oslo_utils import uuidutils
Expand Down Expand Up @@ -323,18 +322,6 @@ def setUp(self):
host_descriptions)
super(TestLegacyL3Agent, self).setUp(env)

def test_namespace_exists(self):
tenant_id = uuidutils.generate_uuid()

router = self.safe_client.create_router(tenant_id)
network = self.safe_client.create_network(tenant_id)
subnet = self.safe_client.create_subnet(
tenant_id, network['id'], '20.0.0.0/24', gateway_ip='20.0.0.1')
self.safe_client.add_router_interface(router['id'], subnet['id'])

namespace = self._get_namespace(router['id'])
self.assert_namespace_exists(namespace)

def test_mtu_update(self):
tenant_id = uuidutils.generate_uuid()

Expand All @@ -361,92 +348,6 @@ def test_mtu_update(self):
network = self.safe_client.update_network(network['id'], mtu=mtu)
common_utils.wait_until_true(lambda: ri_dev.link.mtu == mtu)

def test_east_west_traffic(self):
tenant_id = uuidutils.generate_uuid()
router = self.safe_client.create_router(tenant_id)

vm1 = self._create_net_subnet_and_vm(
tenant_id, ['20.0.0.0/24', '2001:db8:aaaa::/64'],
self.environment.hosts[0], router)
vm2 = self._create_net_subnet_and_vm(
tenant_id, ['21.0.0.0/24', '2001:db8:bbbb::/64'],
self.environment.hosts[1], router)

vm1.block_until_ping(vm2.ip)
# Verify ping6 from vm2 to vm1 IPv6 Address
vm2.block_until_ping(vm1.ipv6)

def test_north_south_traffic(self):
# This function creates an external network which is connected to
# central_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._create_external_vm(ext_net, ext_sub)
# Create an IPv6 subnet in the external network
v6network = self.useFixture(
ip_network.ExclusiveIPNetwork(
"2001:db8:1234::1", "2001:db8:1234::10", "64")).network
# NOTE(ykarel): gateway_ip is explicitly added as iputils package
# requires fix for https://github.com/iputils/iputils/issues/371
# is not available in CentOS 9-Stream
ext_v6sub = self.safe_client.create_subnet(
tenant_id, ext_net['id'], v6network, gateway_ip='2001:db8:1234::1')

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)

# Now let's remove and create again phys bridge and check connectivity
# once again
br_phys = self.environment.hosts[0].br_phys
br_phys.destroy()
br_phys.create()
self.environment.hosts[0].connect_to_central_network_via_vlans(
br_phys)

# 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 test_gateway_ip_changed(self):
self._test_gateway_ip_changed()

Expand Down
Loading