os-vif/vif_plug_ovs/ovsdb/ovsdb_lib.py
Rodolfo Alonso Hernandez d5b61d1065 [OVS] VLAN tag should be set in the Port register
In OVS, the VLAN tag for a device is set in the Port register,
not the Interface [1][2]. Method "BaseOVS.create_ovs_vif_port"
should implement it.

[1] http://docs.openvswitch.org/en/latest/faq/configuration/
[2] 1d354f7577/neutron/agent/common/ovs_lib.py (L346-L347)

Change-Id: Iaebd42af6d5b8e3165cf10e269addae0ff3665fb
Closes-Bug: #1860329
2020-01-30 12:19:51 +00:00

116 lines
4.9 KiB
Python

# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import sys
from oslo_log import log as logging
from vif_plug_ovs import constants
from vif_plug_ovs import linux_net
from vif_plug_ovs.ovsdb import api as ovsdb_api
LOG = logging.getLogger(__name__)
class BaseOVS(object):
def __init__(self, config):
self.timeout = config.ovs_vsctl_timeout
self.connection = config.ovsdb_connection
self.interface = config.ovsdb_interface
self.ovsdb = ovsdb_api.get_instance(self)
def _ovs_supports_mtu_requests(self):
return self.ovsdb.has_table_column('Interface', 'mtu_request')
def _set_mtu_request(self, dev, mtu):
self.ovsdb.db_set('Interface', dev, ('mtu_request', mtu)).execute()
def update_device_mtu(self, dev, mtu, interface_type=None):
if not mtu:
return
if interface_type not in [
constants.OVS_VHOSTUSER_INTERFACE_TYPE,
constants.OVS_VHOSTUSER_CLIENT_INTERFACE_TYPE]:
if sys.platform != constants.PLATFORM_WIN32:
# Hyper-V with OVS does not support external programming of
# virtual interface MTUs via netsh or other Windows tools.
# When plugging an interface on Windows, we therefore skip
# programming the MTU and fallback to DHCP advertisement.
linux_net.set_device_mtu(dev, mtu)
elif self._ovs_supports_mtu_requests():
self._set_mtu_request(dev, mtu)
else:
LOG.debug("MTU not set on %(interface_name)s interface "
"of type %(interface_type)s.",
{'interface_name': dev,
'interface_type': interface_type})
def ensure_ovs_bridge(self, bridge, datapath_type):
return self.ovsdb.add_br(bridge, may_exist=True,
datapath_type=datapath_type).execute()
def create_ovs_vif_port(self, bridge, dev, iface_id, mac, instance_id,
mtu=None, interface_type=None,
vhost_server_path=None, tag=None,
pf_pci=None, vf_num=None):
"""Create OVS port
:param bridge: bridge name to create the port on.
:param dev: port name.
:param iface_id: port ID.
:param mac: port MAC.
:param instance_id: VM ID on which the port is attached to.
:param mtu: port MTU.
:param interface_type: OVS interface type.
:param vhost_server_path: path to socket file of vhost server.
:param tag: OVS interface tag.
:param pf_pci: PCI address of PF for dpdk representor port.
:param vf_num: VF number of PF for dpdk representor port.
.. note:: create DPDK representor port by setting all three values:
`interface_type`, `pf_pci` and `vf_num`. if interface type is
not `OVS_DPDK_INTERFACE_TYPE` then `pf_pci` and `vf_num` values
are ignored.
"""
external_ids = {'iface-id': iface_id,
'iface-status': 'active',
'attached-mac': mac,
'vm-uuid': instance_id}
col_values = [('external_ids', external_ids)]
if interface_type:
col_values.append(('type', interface_type))
if vhost_server_path:
col_values.append(('options',
{'vhost-server-path': vhost_server_path}))
if (interface_type == constants.OVS_DPDK_INTERFACE_TYPE and
pf_pci and vf_num):
devargs_string = "{PF_PCI},representor=[{VF_NUM}]".format(
PF_PCI=pf_pci, VF_NUM=vf_num)
col_values.append(('options',
{'dpdk-devargs': devargs_string}))
with self.ovsdb.transaction() as txn:
txn.add(self.ovsdb.add_port(bridge, dev))
if tag:
txn.add(self.ovsdb.db_set('Port', dev, ('tag', tag)))
txn.add(self.ovsdb.db_set('Interface', dev, *col_values))
self.update_device_mtu(dev, mtu, interface_type=interface_type)
def update_ovs_vif_port(self, dev, mtu=None, interface_type=None):
self.update_device_mtu(dev, mtu, interface_type=interface_type)
def delete_ovs_vif_port(self, bridge, dev, delete_netdev=True):
self.ovsdb.del_port(dev, bridge=bridge, if_exists=True).execute()
if delete_netdev:
linux_net.delete_net_dev(dev)