2016-11-16 15:19:11 +03:00
|
|
|
# Copyright (c) 2016 Mirantis, Inc.
|
|
|
|
# All Rights Reserved.
|
|
|
|
#
|
|
|
|
# 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.
|
|
|
|
|
2016-11-21 04:18:05 +03:00
|
|
|
|
2020-02-28 17:40:22 +03:00
|
|
|
import os
|
|
|
|
|
2017-03-28 09:47:09 +08:00
|
|
|
from kuryr.lib._i18n import _
|
2016-11-20 15:45:45 +03:00
|
|
|
from kuryr.lib.binding.drivers import utils as kl_utils
|
|
|
|
from kuryr.lib import constants as kl_const
|
|
|
|
from os_vif.objects import fixed_ip as osv_fixed_ip
|
2016-11-16 15:19:11 +03:00
|
|
|
from os_vif.objects import network as osv_network
|
|
|
|
from os_vif.objects import route as osv_route
|
|
|
|
from os_vif.objects import subnet as osv_subnet
|
2016-11-20 15:45:45 +03:00
|
|
|
from os_vif.objects import vif as osv_vif
|
|
|
|
from oslo_config import cfg as oslo_cfg
|
Support DPDK application on bare-metal host
This patch contains binding driver, which intend to copy vhostuser port
to containers's directory. Here container's directory it's mounted
directory. Also this patch contains code to create proper VIF in case
when neutron ovs agent configured to work with vhostuser ports.
There is no code here for port creation, due to it performs in
base.connect by os_vif.plug. This function creates/or recreates OVS
bridge with netdev type, then it creates port in this bridge. It uses
vif.network.bridge as the name for integration bridge, IOW it doesn't
use ovs_bridge from kuryr.conf, vif.network.bridge is configured by
neutron ovs agent.
VhostUser mode is defined by neutron ovs agent, it obtains from
Open vSwitch configuration:
Command to check Open vSwitch configuration
ovs-vsctl list Open_vSwitch |grep iface_types
If neutron ovs agent finds dpdkvhostuserclient there, it sets
vhostuser_mode to VIFVHostUserMode.SERVER, it means DPDK application in
container will be a server, and OVS will be a client, so DPDK
application will create/bind/listen vhostuser socket by predefined path.
This path is set in kuryr.conf/vhostuser/mount_point.
When dpdkvhostuserclient is not in OVS's capability list, e.g. it's old
OVS or it was built w/o dpdkvhostuserclient support, the mode will be
VIFVHostUserMode.CLIENT. In this case OVS will create/bind/listen
socket, so socket file will exist, and it shoud be copied to container's
mount volume. At the moment of copying OVS server already has to listen
it, otherwise approach is not working.
Partially Implements: blueprint support-vhost-user-port-type-on-bm-installation
Change-Id: Ib9c22368e518815064282f4c3b9f9ddaf58dc622
Signed-off-by: Alexey Perevalov <a.perevalov@samsung.com>
Signed-off-by: Andrey Zaikin <a.zaikin@partner.samsung.com>
Signed-off-by: Vladimir Kuramshin <v.kuramshin@samsung.com>
2020-01-31 11:31:34 +03:00
|
|
|
from oslo_log import log as logging
|
2016-11-20 15:45:45 +03:00
|
|
|
from stevedore import driver as stv_driver
|
Support DPDK application on bare-metal host
This patch contains binding driver, which intend to copy vhostuser port
to containers's directory. Here container's directory it's mounted
directory. Also this patch contains code to create proper VIF in case
when neutron ovs agent configured to work with vhostuser ports.
There is no code here for port creation, due to it performs in
base.connect by os_vif.plug. This function creates/or recreates OVS
bridge with netdev type, then it creates port in this bridge. It uses
vif.network.bridge as the name for integration bridge, IOW it doesn't
use ovs_bridge from kuryr.conf, vif.network.bridge is configured by
neutron ovs agent.
VhostUser mode is defined by neutron ovs agent, it obtains from
Open vSwitch configuration:
Command to check Open vSwitch configuration
ovs-vsctl list Open_vSwitch |grep iface_types
If neutron ovs agent finds dpdkvhostuserclient there, it sets
vhostuser_mode to VIFVHostUserMode.SERVER, it means DPDK application in
container will be a server, and OVS will be a client, so DPDK
application will create/bind/listen vhostuser socket by predefined path.
This path is set in kuryr.conf/vhostuser/mount_point.
When dpdkvhostuserclient is not in OVS's capability list, e.g. it's old
OVS or it was built w/o dpdkvhostuserclient support, the mode will be
VIFVHostUserMode.CLIENT. In this case OVS will create/bind/listen
socket, so socket file will exist, and it shoud be copied to container's
mount volume. At the moment of copying OVS server already has to listen
it, otherwise approach is not working.
Partially Implements: blueprint support-vhost-user-port-type-on-bm-installation
Change-Id: Ib9c22368e518815064282f4c3b9f9ddaf58dc622
Signed-off-by: Alexey Perevalov <a.perevalov@samsung.com>
Signed-off-by: Andrey Zaikin <a.zaikin@partner.samsung.com>
Signed-off-by: Vladimir Kuramshin <v.kuramshin@samsung.com>
2020-01-31 11:31:34 +03:00
|
|
|
from vif_plug_ovs import constants as osv_const
|
2016-11-20 15:45:45 +03:00
|
|
|
|
|
|
|
from kuryr_kubernetes import config
|
2017-03-02 16:26:21 +00:00
|
|
|
from kuryr_kubernetes import constants as const
|
2016-11-20 15:45:45 +03:00
|
|
|
from kuryr_kubernetes import exceptions as k_exc
|
2016-12-14 12:58:58 +05:30
|
|
|
from kuryr_kubernetes.objects import vif as k_vif
|
2016-11-20 15:45:45 +03:00
|
|
|
|
|
|
|
|
Support DPDK application on bare-metal host
This patch contains binding driver, which intend to copy vhostuser port
to containers's directory. Here container's directory it's mounted
directory. Also this patch contains code to create proper VIF in case
when neutron ovs agent configured to work with vhostuser ports.
There is no code here for port creation, due to it performs in
base.connect by os_vif.plug. This function creates/or recreates OVS
bridge with netdev type, then it creates port in this bridge. It uses
vif.network.bridge as the name for integration bridge, IOW it doesn't
use ovs_bridge from kuryr.conf, vif.network.bridge is configured by
neutron ovs agent.
VhostUser mode is defined by neutron ovs agent, it obtains from
Open vSwitch configuration:
Command to check Open vSwitch configuration
ovs-vsctl list Open_vSwitch |grep iface_types
If neutron ovs agent finds dpdkvhostuserclient there, it sets
vhostuser_mode to VIFVHostUserMode.SERVER, it means DPDK application in
container will be a server, and OVS will be a client, so DPDK
application will create/bind/listen vhostuser socket by predefined path.
This path is set in kuryr.conf/vhostuser/mount_point.
When dpdkvhostuserclient is not in OVS's capability list, e.g. it's old
OVS or it was built w/o dpdkvhostuserclient support, the mode will be
VIFVHostUserMode.CLIENT. In this case OVS will create/bind/listen
socket, so socket file will exist, and it shoud be copied to container's
mount volume. At the moment of copying OVS server already has to listen
it, otherwise approach is not working.
Partially Implements: blueprint support-vhost-user-port-type-on-bm-installation
Change-Id: Ib9c22368e518815064282f4c3b9f9ddaf58dc622
Signed-off-by: Alexey Perevalov <a.perevalov@samsung.com>
Signed-off-by: Andrey Zaikin <a.zaikin@partner.samsung.com>
Signed-off-by: Vladimir Kuramshin <v.kuramshin@samsung.com>
2020-01-31 11:31:34 +03:00
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
2016-11-16 15:19:11 +03:00
|
|
|
# REVISIT(ivc): consider making this module part of kuryr-lib
|
2016-11-20 15:45:45 +03:00
|
|
|
_VIF_TRANSLATOR_NAMESPACE = "kuryr_kubernetes.vif_translators"
|
|
|
|
_VIF_MANAGERS = {}
|
2016-11-16 15:19:11 +03:00
|
|
|
|
|
|
|
|
2019-12-10 14:46:17 +01:00
|
|
|
def neutron_to_osvif_network(os_network):
|
2016-11-20 15:45:45 +03:00
|
|
|
"""Converts Neutron network to os-vif Subnet.
|
|
|
|
|
2019-12-10 14:46:17 +01:00
|
|
|
:param os_network: openstack.network.v2.netwrork.Network object.
|
2016-11-20 15:45:45 +03:00
|
|
|
:return: an os-vif Network object
|
|
|
|
"""
|
|
|
|
|
2019-12-10 14:46:17 +01:00
|
|
|
obj = osv_network.Network(id=os_network.id)
|
2016-11-16 15:19:11 +03:00
|
|
|
|
2019-12-10 14:46:17 +01:00
|
|
|
if os_network.name is not None:
|
|
|
|
obj.label = os_network.name
|
2016-11-16 15:19:11 +03:00
|
|
|
|
2019-12-10 14:46:17 +01:00
|
|
|
if os_network.mtu is not None:
|
|
|
|
obj.mtu = os_network.mtu
|
2016-11-16 15:19:11 +03:00
|
|
|
|
2017-10-10 14:30:59 +03:00
|
|
|
# Vlan information will be used later in Sriov binding driver
|
2019-12-10 14:46:17 +01:00
|
|
|
if os_network.provider_network_type == 'vlan':
|
2017-10-10 14:30:59 +03:00
|
|
|
obj.should_provide_vlan = True
|
2019-12-10 14:46:17 +01:00
|
|
|
obj.vlan = os_network.provider_segmentation_id
|
2017-10-10 14:30:59 +03:00
|
|
|
|
2016-11-16 15:19:11 +03:00
|
|
|
return obj
|
|
|
|
|
|
|
|
|
2019-12-10 14:46:17 +01:00
|
|
|
def neutron_to_osvif_subnet(os_subnet):
|
2016-11-20 15:45:45 +03:00
|
|
|
"""Converts Neutron subnet to os-vif Subnet.
|
|
|
|
|
2019-12-10 14:46:17 +01:00
|
|
|
:param os_subnet: openstack.network.v2.subnet.Subnet object
|
2016-11-20 15:45:45 +03:00
|
|
|
:return: an os-vif Subnet object
|
|
|
|
"""
|
|
|
|
|
2016-11-16 15:19:11 +03:00
|
|
|
obj = osv_subnet.Subnet(
|
2019-12-10 14:46:17 +01:00
|
|
|
cidr=os_subnet.cidr,
|
|
|
|
dns=os_subnet.dns_nameservers,
|
|
|
|
routes=_neutron_to_osvif_routes(os_subnet.host_routes))
|
2016-11-16 15:19:11 +03:00
|
|
|
|
2019-12-10 14:46:17 +01:00
|
|
|
if os_subnet.gateway_ip is not None:
|
|
|
|
obj.gateway = os_subnet.gateway_ip
|
2016-11-16 15:19:11 +03:00
|
|
|
|
|
|
|
return obj
|
|
|
|
|
|
|
|
|
|
|
|
def _neutron_to_osvif_routes(neutron_routes):
|
2016-11-20 15:45:45 +03:00
|
|
|
"""Converts Neutron host_routes to os-vif RouteList.
|
|
|
|
|
|
|
|
:param neutron_routes: list of routes as returned by neutron client's
|
|
|
|
'show_subnet' in 'host_routes' attribute
|
|
|
|
:return: an os-vif RouteList object
|
|
|
|
"""
|
|
|
|
|
2019-12-10 14:46:17 +01:00
|
|
|
# NOTE(gryf): Nested attributes for OpenStackSDK objects are simple types,
|
|
|
|
# like dicts and lists, that's why neutron_routes is a list of dicts.
|
2016-11-16 15:19:11 +03:00
|
|
|
obj_list = [osv_route.Route(cidr=route['destination'],
|
|
|
|
gateway=route['nexthop'])
|
|
|
|
for route in neutron_routes]
|
|
|
|
|
|
|
|
return osv_route.RouteList(objects=obj_list)
|
2016-11-20 15:45:45 +03:00
|
|
|
|
|
|
|
|
|
|
|
def _make_vif_subnet(subnets, subnet_id):
|
|
|
|
"""Makes a copy of an os-vif Subnet from subnets mapping.
|
|
|
|
|
|
|
|
:param subnets: subnet mapping as returned by PodSubnetsDriver.get_subnets
|
|
|
|
:param subnet_id: ID of the subnet to extract from 'subnets' mapping
|
|
|
|
:return: a copy of an os-vif Subnet object matching 'subnet_id'
|
|
|
|
"""
|
|
|
|
|
|
|
|
network = subnets[subnet_id]
|
|
|
|
|
|
|
|
if len(network.subnets.objects) != 1:
|
2017-03-28 09:47:09 +08:00
|
|
|
raise k_exc.IntegrityError(_(
|
2016-11-20 15:45:45 +03:00
|
|
|
"Network object for subnet %(subnet_id)s is invalid, "
|
|
|
|
"must contain a single subnet, but %(num_subnets)s found") % {
|
|
|
|
'subnet_id': subnet_id,
|
|
|
|
'num_subnets': len(network.subnets.objects)})
|
|
|
|
|
|
|
|
subnet = network.subnets.objects[0].obj_clone()
|
|
|
|
subnet.ips = osv_fixed_ip.FixedIPList(objects=[])
|
|
|
|
return subnet
|
|
|
|
|
|
|
|
|
|
|
|
def _make_vif_subnets(neutron_port, subnets):
|
|
|
|
"""Gets a list of os-vif Subnet objects for port.
|
|
|
|
|
|
|
|
:param neutron_port: dict containing port information as returned by
|
2019-12-09 15:22:19 +01:00
|
|
|
neutron client's 'show_port' or
|
|
|
|
openstack.network.v2.port.Port object
|
2016-11-20 15:45:45 +03:00
|
|
|
:param subnets: subnet mapping as returned by PodSubnetsDriver.get_subnets
|
|
|
|
:return: list of os-vif Subnet object
|
|
|
|
"""
|
|
|
|
|
|
|
|
vif_subnets = {}
|
2019-12-09 15:22:19 +01:00
|
|
|
try:
|
|
|
|
fixed_ips = neutron_port.get('fixed_ips', [])
|
|
|
|
port_id = neutron_port.get('id')
|
|
|
|
except TypeError:
|
|
|
|
fixed_ips = neutron_port.fixed_ips
|
|
|
|
port_id = neutron_port.get.id
|
2016-11-20 15:45:45 +03:00
|
|
|
|
2019-12-09 15:22:19 +01:00
|
|
|
for neutron_fixed_ip in fixed_ips:
|
2016-11-20 15:45:45 +03:00
|
|
|
subnet_id = neutron_fixed_ip['subnet_id']
|
|
|
|
ip_address = neutron_fixed_ip['ip_address']
|
|
|
|
|
|
|
|
if subnet_id not in subnets:
|
|
|
|
continue
|
|
|
|
|
|
|
|
try:
|
|
|
|
subnet = vif_subnets[subnet_id]
|
|
|
|
except KeyError:
|
|
|
|
subnet = _make_vif_subnet(subnets, subnet_id)
|
|
|
|
vif_subnets[subnet_id] = subnet
|
|
|
|
|
|
|
|
subnet.ips.objects.append(osv_fixed_ip.FixedIP(address=ip_address))
|
|
|
|
|
|
|
|
if not vif_subnets:
|
2017-03-28 09:47:09 +08:00
|
|
|
raise k_exc.IntegrityError(_(
|
2016-11-20 15:45:45 +03:00
|
|
|
"No valid subnets found for port %(port_id)s") % {
|
2019-12-09 15:22:19 +01:00
|
|
|
'port_id': port_id})
|
2016-11-20 15:45:45 +03:00
|
|
|
|
|
|
|
return list(vif_subnets.values())
|
|
|
|
|
|
|
|
|
|
|
|
def _make_vif_network(neutron_port, subnets):
|
2018-06-21 17:12:59 +08:00
|
|
|
"""Get an os-vif Network object for port.
|
2016-11-20 15:45:45 +03:00
|
|
|
|
|
|
|
:param neutron_port: dict containing port information as returned by
|
2019-12-09 15:22:19 +01:00
|
|
|
neutron client's 'show_port', or
|
|
|
|
openstack.network.v2.port.Port object
|
2016-11-20 15:45:45 +03:00
|
|
|
:param subnets: subnet mapping as returned by PodSubnetsDriver.get_subnets
|
|
|
|
:return: os-vif Network object
|
|
|
|
"""
|
|
|
|
|
2019-12-09 15:22:19 +01:00
|
|
|
# NOTE(gryf): Because we didn't convert macvlan driver, neutron_port can
|
|
|
|
# be either a dict or an object
|
|
|
|
try:
|
|
|
|
network_id = neutron_port.get('network_id')
|
|
|
|
port_id = neutron_port.get('id')
|
|
|
|
except TypeError:
|
|
|
|
network_id = neutron_port.network_id
|
|
|
|
port_id = neutron_port.id
|
|
|
|
|
2016-11-20 15:45:45 +03:00
|
|
|
try:
|
|
|
|
network = next(net.obj_clone() for net in subnets.values()
|
2019-12-09 15:22:19 +01:00
|
|
|
if net.id == network_id)
|
2016-11-20 15:45:45 +03:00
|
|
|
except StopIteration:
|
2017-03-28 09:47:09 +08:00
|
|
|
raise k_exc.IntegrityError(_(
|
2016-11-20 15:45:45 +03:00
|
|
|
"Port %(port_id)s belongs to network %(network_id)s, "
|
|
|
|
"but requested networks are: %(requested_networks)s") % {
|
2019-12-09 15:22:19 +01:00
|
|
|
'port_id': port_id,
|
|
|
|
'network_id': network_id,
|
2016-11-20 15:45:45 +03:00
|
|
|
'requested_networks': [net.id for net in subnets.values()]})
|
|
|
|
|
|
|
|
network.subnets = osv_subnet.SubnetList(
|
|
|
|
objects=_make_vif_subnets(neutron_port, subnets))
|
|
|
|
|
|
|
|
return network
|
|
|
|
|
|
|
|
|
Support DPDK application on bare-metal host
This patch contains binding driver, which intend to copy vhostuser port
to containers's directory. Here container's directory it's mounted
directory. Also this patch contains code to create proper VIF in case
when neutron ovs agent configured to work with vhostuser ports.
There is no code here for port creation, due to it performs in
base.connect by os_vif.plug. This function creates/or recreates OVS
bridge with netdev type, then it creates port in this bridge. It uses
vif.network.bridge as the name for integration bridge, IOW it doesn't
use ovs_bridge from kuryr.conf, vif.network.bridge is configured by
neutron ovs agent.
VhostUser mode is defined by neutron ovs agent, it obtains from
Open vSwitch configuration:
Command to check Open vSwitch configuration
ovs-vsctl list Open_vSwitch |grep iface_types
If neutron ovs agent finds dpdkvhostuserclient there, it sets
vhostuser_mode to VIFVHostUserMode.SERVER, it means DPDK application in
container will be a server, and OVS will be a client, so DPDK
application will create/bind/listen vhostuser socket by predefined path.
This path is set in kuryr.conf/vhostuser/mount_point.
When dpdkvhostuserclient is not in OVS's capability list, e.g. it's old
OVS or it was built w/o dpdkvhostuserclient support, the mode will be
VIFVHostUserMode.CLIENT. In this case OVS will create/bind/listen
socket, so socket file will exist, and it shoud be copied to container's
mount volume. At the moment of copying OVS server already has to listen
it, otherwise approach is not working.
Partially Implements: blueprint support-vhost-user-port-type-on-bm-installation
Change-Id: Ib9c22368e518815064282f4c3b9f9ddaf58dc622
Signed-off-by: Alexey Perevalov <a.perevalov@samsung.com>
Signed-off-by: Andrey Zaikin <a.zaikin@partner.samsung.com>
Signed-off-by: Vladimir Kuramshin <v.kuramshin@samsung.com>
2020-01-31 11:31:34 +03:00
|
|
|
# TODO(a.perevalov) generalize it with get_veth_pair_names
|
|
|
|
# but it's reasonable if we're going to add vhostuser support
|
|
|
|
# into kuryr project
|
|
|
|
def _get_vhu_vif_name(port_id):
|
|
|
|
ifname = osv_const.OVS_VHOSTUSER_PREFIX + port_id
|
|
|
|
ifname = ifname[:kl_const.NIC_NAME_LEN]
|
|
|
|
return ifname
|
|
|
|
|
|
|
|
|
2016-11-20 15:45:45 +03:00
|
|
|
def _get_vif_name(neutron_port):
|
|
|
|
"""Gets a VIF device name for port.
|
|
|
|
|
|
|
|
:param neutron_port: dict containing port information as returned by
|
2019-12-09 15:22:19 +01:00
|
|
|
neutron client's 'show_port', or an port object
|
|
|
|
returned by openstack client.
|
2016-11-20 15:45:45 +03:00
|
|
|
"""
|
|
|
|
|
2019-12-09 15:22:19 +01:00
|
|
|
try:
|
|
|
|
port_id = neutron_port['id']
|
|
|
|
except TypeError:
|
|
|
|
port_id = neutron_port.id
|
|
|
|
|
|
|
|
vif_name, _ = kl_utils.get_veth_pair_names(port_id)
|
2016-11-20 15:45:45 +03:00
|
|
|
return vif_name
|
|
|
|
|
|
|
|
|
2019-12-09 15:22:19 +01:00
|
|
|
def _get_ovs_hybrid_bridge_name(os_port):
|
2016-11-20 15:45:45 +03:00
|
|
|
"""Gets a name of the Linux bridge name for hybrid OpenVSwitch port.
|
|
|
|
|
2019-12-09 15:22:19 +01:00
|
|
|
:param os_port: openstack.network.v2.port.Port object
|
2016-11-20 15:45:45 +03:00
|
|
|
"""
|
2019-12-09 15:22:19 +01:00
|
|
|
return ('qbr' + os_port.id)[:kl_const.NIC_NAME_LEN]
|
2016-11-20 15:45:45 +03:00
|
|
|
|
|
|
|
|
|
|
|
def _is_port_active(neutron_port):
|
|
|
|
"""Checks if port is active.
|
|
|
|
|
|
|
|
:param neutron_port: dict containing port information as returned by
|
2019-12-09 15:22:19 +01:00
|
|
|
neutron client's 'show_port' or
|
|
|
|
openstack.network.v2.port.Port object
|
2016-11-20 15:45:45 +03:00
|
|
|
"""
|
2019-12-09 15:22:19 +01:00
|
|
|
try:
|
|
|
|
return (neutron_port['status'] == kl_const.PORT_STATUS_ACTIVE)
|
|
|
|
except TypeError:
|
|
|
|
return (neutron_port.status == kl_const.PORT_STATUS_ACTIVE)
|
2016-11-20 15:45:45 +03:00
|
|
|
|
|
|
|
|
2019-12-09 15:22:19 +01:00
|
|
|
def neutron_to_osvif_vif_ovs(vif_plugin, os_port, subnets):
|
2016-11-20 15:45:45 +03:00
|
|
|
"""Converts Neutron port to VIF object for os-vif 'ovs' plugin.
|
|
|
|
|
|
|
|
:param vif_plugin: name of the os-vif plugin to use (i.e. 'ovs')
|
2019-12-09 15:22:19 +01:00
|
|
|
:param os_port: openstack.network.v2.port.Port object
|
2016-11-20 15:45:45 +03:00
|
|
|
:param subnets: subnet mapping as returned by PodSubnetsDriver.get_subnets
|
|
|
|
:return: os-vif VIF object
|
|
|
|
"""
|
2019-11-29 15:21:53 +01:00
|
|
|
profile = osv_vif.VIFPortProfileOpenVSwitch(interface_id=os_port.id)
|
2016-11-20 15:45:45 +03:00
|
|
|
|
2019-11-29 15:21:53 +01:00
|
|
|
details = os_port.binding_vif_details or {}
|
2016-11-20 15:45:45 +03:00
|
|
|
ovs_bridge = details.get('bridge_name',
|
|
|
|
config.CONF.neutron_defaults.ovs_bridge)
|
|
|
|
if not ovs_bridge:
|
|
|
|
raise oslo_cfg.RequiredOptError('ovs_bridge', 'neutron_defaults')
|
|
|
|
|
2019-12-09 15:22:19 +01:00
|
|
|
network = _make_vif_network(os_port, subnets)
|
2016-11-20 15:45:45 +03:00
|
|
|
network.bridge = ovs_bridge
|
Support DPDK application on bare-metal host
This patch contains binding driver, which intend to copy vhostuser port
to containers's directory. Here container's directory it's mounted
directory. Also this patch contains code to create proper VIF in case
when neutron ovs agent configured to work with vhostuser ports.
There is no code here for port creation, due to it performs in
base.connect by os_vif.plug. This function creates/or recreates OVS
bridge with netdev type, then it creates port in this bridge. It uses
vif.network.bridge as the name for integration bridge, IOW it doesn't
use ovs_bridge from kuryr.conf, vif.network.bridge is configured by
neutron ovs agent.
VhostUser mode is defined by neutron ovs agent, it obtains from
Open vSwitch configuration:
Command to check Open vSwitch configuration
ovs-vsctl list Open_vSwitch |grep iface_types
If neutron ovs agent finds dpdkvhostuserclient there, it sets
vhostuser_mode to VIFVHostUserMode.SERVER, it means DPDK application in
container will be a server, and OVS will be a client, so DPDK
application will create/bind/listen vhostuser socket by predefined path.
This path is set in kuryr.conf/vhostuser/mount_point.
When dpdkvhostuserclient is not in OVS's capability list, e.g. it's old
OVS or it was built w/o dpdkvhostuserclient support, the mode will be
VIFVHostUserMode.CLIENT. In this case OVS will create/bind/listen
socket, so socket file will exist, and it shoud be copied to container's
mount volume. At the moment of copying OVS server already has to listen
it, otherwise approach is not working.
Partially Implements: blueprint support-vhost-user-port-type-on-bm-installation
Change-Id: Ib9c22368e518815064282f4c3b9f9ddaf58dc622
Signed-off-by: Alexey Perevalov <a.perevalov@samsung.com>
Signed-off-by: Andrey Zaikin <a.zaikin@partner.samsung.com>
Signed-off-by: Vladimir Kuramshin <v.kuramshin@samsung.com>
2020-01-31 11:31:34 +03:00
|
|
|
vhostuser_mode = details.get('vhostuser_mode', False)
|
|
|
|
|
|
|
|
LOG.debug('Detected vhostuser_mode=%s for port %s', vhostuser_mode,
|
|
|
|
os_port.id)
|
|
|
|
if vhostuser_mode:
|
|
|
|
# TODO(a.perevalov) obtain path to mount point from pod's mountVolumes
|
|
|
|
vhostuser_mount_point = (config.CONF.vhostuser.mount_point)
|
|
|
|
if not vhostuser_mount_point:
|
|
|
|
raise oslo_cfg.RequiredOptError('vhostuser_mount_point',
|
|
|
|
'neutron_defaults')
|
2020-02-28 17:40:22 +03:00
|
|
|
vif_name = _get_vhu_vif_name(os_port.id)
|
Support DPDK application on bare-metal host
This patch contains binding driver, which intend to copy vhostuser port
to containers's directory. Here container's directory it's mounted
directory. Also this patch contains code to create proper VIF in case
when neutron ovs agent configured to work with vhostuser ports.
There is no code here for port creation, due to it performs in
base.connect by os_vif.plug. This function creates/or recreates OVS
bridge with netdev type, then it creates port in this bridge. It uses
vif.network.bridge as the name for integration bridge, IOW it doesn't
use ovs_bridge from kuryr.conf, vif.network.bridge is configured by
neutron ovs agent.
VhostUser mode is defined by neutron ovs agent, it obtains from
Open vSwitch configuration:
Command to check Open vSwitch configuration
ovs-vsctl list Open_vSwitch |grep iface_types
If neutron ovs agent finds dpdkvhostuserclient there, it sets
vhostuser_mode to VIFVHostUserMode.SERVER, it means DPDK application in
container will be a server, and OVS will be a client, so DPDK
application will create/bind/listen vhostuser socket by predefined path.
This path is set in kuryr.conf/vhostuser/mount_point.
When dpdkvhostuserclient is not in OVS's capability list, e.g. it's old
OVS or it was built w/o dpdkvhostuserclient support, the mode will be
VIFVHostUserMode.CLIENT. In this case OVS will create/bind/listen
socket, so socket file will exist, and it shoud be copied to container's
mount volume. At the moment of copying OVS server already has to listen
it, otherwise approach is not working.
Partially Implements: blueprint support-vhost-user-port-type-on-bm-installation
Change-Id: Ib9c22368e518815064282f4c3b9f9ddaf58dc622
Signed-off-by: Alexey Perevalov <a.perevalov@samsung.com>
Signed-off-by: Andrey Zaikin <a.zaikin@partner.samsung.com>
Signed-off-by: Vladimir Kuramshin <v.kuramshin@samsung.com>
2020-01-31 11:31:34 +03:00
|
|
|
vif = osv_vif.VIFVHostUser(
|
|
|
|
id=os_port.id,
|
|
|
|
address=os_port.mac_address,
|
|
|
|
network=network,
|
|
|
|
has_traffic_filtering=details.get('port_filter', False),
|
|
|
|
preserve_on_delete=False,
|
|
|
|
active=_is_port_active(os_port),
|
|
|
|
port_profile=profile,
|
|
|
|
plugin='ovs',
|
2020-02-28 17:40:22 +03:00
|
|
|
path=os.path.join(vhostuser_mount_point, vif_name),
|
Support DPDK application on bare-metal host
This patch contains binding driver, which intend to copy vhostuser port
to containers's directory. Here container's directory it's mounted
directory. Also this patch contains code to create proper VIF in case
when neutron ovs agent configured to work with vhostuser ports.
There is no code here for port creation, due to it performs in
base.connect by os_vif.plug. This function creates/or recreates OVS
bridge with netdev type, then it creates port in this bridge. It uses
vif.network.bridge as the name for integration bridge, IOW it doesn't
use ovs_bridge from kuryr.conf, vif.network.bridge is configured by
neutron ovs agent.
VhostUser mode is defined by neutron ovs agent, it obtains from
Open vSwitch configuration:
Command to check Open vSwitch configuration
ovs-vsctl list Open_vSwitch |grep iface_types
If neutron ovs agent finds dpdkvhostuserclient there, it sets
vhostuser_mode to VIFVHostUserMode.SERVER, it means DPDK application in
container will be a server, and OVS will be a client, so DPDK
application will create/bind/listen vhostuser socket by predefined path.
This path is set in kuryr.conf/vhostuser/mount_point.
When dpdkvhostuserclient is not in OVS's capability list, e.g. it's old
OVS or it was built w/o dpdkvhostuserclient support, the mode will be
VIFVHostUserMode.CLIENT. In this case OVS will create/bind/listen
socket, so socket file will exist, and it shoud be copied to container's
mount volume. At the moment of copying OVS server already has to listen
it, otherwise approach is not working.
Partially Implements: blueprint support-vhost-user-port-type-on-bm-installation
Change-Id: Ib9c22368e518815064282f4c3b9f9ddaf58dc622
Signed-off-by: Alexey Perevalov <a.perevalov@samsung.com>
Signed-off-by: Andrey Zaikin <a.zaikin@partner.samsung.com>
Signed-off-by: Vladimir Kuramshin <v.kuramshin@samsung.com>
2020-01-31 11:31:34 +03:00
|
|
|
mode=vhostuser_mode,
|
2020-02-28 17:40:22 +03:00
|
|
|
vif_name=vif_name,
|
Support DPDK application on bare-metal host
This patch contains binding driver, which intend to copy vhostuser port
to containers's directory. Here container's directory it's mounted
directory. Also this patch contains code to create proper VIF in case
when neutron ovs agent configured to work with vhostuser ports.
There is no code here for port creation, due to it performs in
base.connect by os_vif.plug. This function creates/or recreates OVS
bridge with netdev type, then it creates port in this bridge. It uses
vif.network.bridge as the name for integration bridge, IOW it doesn't
use ovs_bridge from kuryr.conf, vif.network.bridge is configured by
neutron ovs agent.
VhostUser mode is defined by neutron ovs agent, it obtains from
Open vSwitch configuration:
Command to check Open vSwitch configuration
ovs-vsctl list Open_vSwitch |grep iface_types
If neutron ovs agent finds dpdkvhostuserclient there, it sets
vhostuser_mode to VIFVHostUserMode.SERVER, it means DPDK application in
container will be a server, and OVS will be a client, so DPDK
application will create/bind/listen vhostuser socket by predefined path.
This path is set in kuryr.conf/vhostuser/mount_point.
When dpdkvhostuserclient is not in OVS's capability list, e.g. it's old
OVS or it was built w/o dpdkvhostuserclient support, the mode will be
VIFVHostUserMode.CLIENT. In this case OVS will create/bind/listen
socket, so socket file will exist, and it shoud be copied to container's
mount volume. At the moment of copying OVS server already has to listen
it, otherwise approach is not working.
Partially Implements: blueprint support-vhost-user-port-type-on-bm-installation
Change-Id: Ib9c22368e518815064282f4c3b9f9ddaf58dc622
Signed-off-by: Alexey Perevalov <a.perevalov@samsung.com>
Signed-off-by: Andrey Zaikin <a.zaikin@partner.samsung.com>
Signed-off-by: Vladimir Kuramshin <v.kuramshin@samsung.com>
2020-01-31 11:31:34 +03:00
|
|
|
bridge_name=network.bridge)
|
|
|
|
elif details.get('ovs_hybrid_plug'):
|
2016-11-20 15:45:45 +03:00
|
|
|
vif = osv_vif.VIFBridge(
|
2019-11-29 15:21:53 +01:00
|
|
|
id=os_port.id,
|
|
|
|
address=os_port.mac_address,
|
2016-11-20 15:45:45 +03:00
|
|
|
network=network,
|
|
|
|
has_traffic_filtering=details.get('port_filter', False),
|
|
|
|
preserve_on_delete=False,
|
2019-12-09 15:22:19 +01:00
|
|
|
active=_is_port_active(os_port),
|
2016-11-20 15:45:45 +03:00
|
|
|
port_profile=profile,
|
|
|
|
plugin=vif_plugin,
|
2019-12-09 15:22:19 +01:00
|
|
|
vif_name=_get_vif_name(os_port),
|
|
|
|
bridge_name=_get_ovs_hybrid_bridge_name(os_port))
|
2016-11-20 15:45:45 +03:00
|
|
|
else:
|
2016-12-18 14:36:21 +02:00
|
|
|
vif = osv_vif.VIFOpenVSwitch(
|
2019-11-29 15:21:53 +01:00
|
|
|
id=os_port.id,
|
|
|
|
address=os_port.mac_address,
|
2016-12-18 14:36:21 +02:00
|
|
|
network=network,
|
|
|
|
has_traffic_filtering=details.get('port_filter', False),
|
|
|
|
preserve_on_delete=False,
|
2019-12-09 15:22:19 +01:00
|
|
|
active=_is_port_active(os_port),
|
2016-12-18 14:36:21 +02:00
|
|
|
port_profile=profile,
|
|
|
|
plugin=vif_plugin,
|
2019-12-09 15:22:19 +01:00
|
|
|
vif_name=_get_vif_name(os_port),
|
2016-12-18 14:36:21 +02:00
|
|
|
bridge_name=network.bridge)
|
2016-11-20 15:45:45 +03:00
|
|
|
|
|
|
|
return vif
|
|
|
|
|
|
|
|
|
2019-12-09 15:22:19 +01:00
|
|
|
def neutron_to_osvif_vif_nested_vlan(os_port, subnets, vlan_id):
|
2017-03-02 16:26:21 +00:00
|
|
|
"""Converts Neutron port to VIF object for VLAN nested containers.
|
2016-12-14 12:58:58 +05:30
|
|
|
|
2019-12-09 15:22:19 +01:00
|
|
|
:param os_port: openstack.network.v2.port.Port object
|
2016-12-14 12:58:58 +05:30
|
|
|
:param subnets: subnet mapping as returned by PodSubnetsDriver.get_subnets
|
2017-03-02 16:26:21 +00:00
|
|
|
:param vlan_id: VLAN id associated to the VIF object for the pod
|
|
|
|
:return: kuryr-k8s native VIF object for VLAN nested
|
2016-12-14 12:58:58 +05:30
|
|
|
"""
|
2019-12-09 15:22:19 +01:00
|
|
|
details = os_port.binding_vif_details or {}
|
2017-03-02 16:26:21 +00:00
|
|
|
|
|
|
|
return k_vif.VIFVlanNested(
|
2019-12-09 15:22:19 +01:00
|
|
|
id=os_port.id,
|
|
|
|
address=os_port.mac_address,
|
|
|
|
network=_make_vif_network(os_port, subnets),
|
2017-03-02 16:26:21 +00:00
|
|
|
has_traffic_filtering=details.get('port_filter', False),
|
|
|
|
preserve_on_delete=False,
|
2019-12-09 15:22:19 +01:00
|
|
|
active=_is_port_active(os_port),
|
2017-03-02 16:26:21 +00:00
|
|
|
plugin=const.K8S_OS_VIF_NOOP_PLUGIN,
|
2019-12-09 15:22:19 +01:00
|
|
|
vif_name=_get_vif_name(os_port),
|
2017-03-02 16:26:21 +00:00
|
|
|
vlan_id=vlan_id)
|
|
|
|
|
2016-12-14 12:58:58 +05:30
|
|
|
|
2017-03-02 16:26:21 +00:00
|
|
|
def neutron_to_osvif_vif_nested_macvlan(neutron_port, subnets):
|
|
|
|
"""Converts Neutron port to VIF object for MACVLAN nested containers.
|
|
|
|
|
|
|
|
:param neutron_port: dict containing port information as returned by
|
|
|
|
neutron client's 'show_port'
|
|
|
|
:param subnets: subnet mapping as returned by PodSubnetsDriver.get_subnets
|
|
|
|
:return: kuryr-k8s native VIF object for MACVLAN nested
|
|
|
|
"""
|
2016-12-14 12:58:58 +05:30
|
|
|
details = neutron_port.get('binding:vif_details', {})
|
|
|
|
|
2017-03-02 16:26:21 +00:00
|
|
|
return k_vif.VIFMacvlanNested(
|
2016-12-14 12:58:58 +05:30
|
|
|
id=neutron_port['id'],
|
|
|
|
address=neutron_port['mac_address'],
|
2017-03-02 16:26:21 +00:00
|
|
|
network=_make_vif_network(neutron_port, subnets),
|
2016-12-14 12:58:58 +05:30
|
|
|
has_traffic_filtering=details.get('port_filter', False),
|
|
|
|
preserve_on_delete=False,
|
|
|
|
active=_is_port_active(neutron_port),
|
2017-03-02 16:26:21 +00:00
|
|
|
plugin=const.K8S_OS_VIF_NOOP_PLUGIN,
|
2016-12-14 12:58:58 +05:30
|
|
|
vif_name=_get_vif_name(neutron_port))
|
|
|
|
|
|
|
|
|
2019-12-09 15:22:19 +01:00
|
|
|
def neutron_to_osvif_vif_sriov(vif_plugin, os_port, subnets):
|
2017-10-10 14:30:59 +03:00
|
|
|
"""Converts Neutron port to VIF object for SRIOV containers.
|
|
|
|
|
|
|
|
:param vif_plugin: name of the os-vif plugin to use (i.e. 'noop')
|
2019-12-09 15:22:19 +01:00
|
|
|
:param os_port: openstack.network.v2.port.Port object
|
2017-10-10 14:30:59 +03:00
|
|
|
:param subnets: subnet mapping as returned by PodSubnetsDriver.get_subnets
|
|
|
|
:return: osv_vif VIFSriov object
|
|
|
|
"""
|
|
|
|
|
2019-12-09 15:22:19 +01:00
|
|
|
details = os_port.binding_vif_details or {}
|
|
|
|
network = _make_vif_network(os_port, subnets)
|
2017-10-10 14:30:59 +03:00
|
|
|
vlan_name = network.vlan if network.should_provide_vlan else ''
|
|
|
|
vif = k_vif.VIFSriov(
|
2019-12-09 15:22:19 +01:00
|
|
|
id=os_port.id,
|
|
|
|
address=os_port.mac_address,
|
2017-10-10 14:30:59 +03:00
|
|
|
network=network,
|
|
|
|
has_traffic_filtering=details.get('port_filter', False),
|
|
|
|
preserve_on_delete=False,
|
2019-12-09 15:22:19 +01:00
|
|
|
active=_is_port_active(os_port),
|
2017-10-10 14:30:59 +03:00
|
|
|
plugin=vif_plugin,
|
|
|
|
mode='passthrough',
|
|
|
|
vlan_name=vlan_name,
|
2019-12-09 15:22:19 +01:00
|
|
|
vif_name=_get_vif_name(os_port),
|
2017-10-10 14:30:59 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
return vif
|
|
|
|
|
|
|
|
|
2018-04-06 15:58:39 +01:00
|
|
|
def neutron_to_osvif_vif_dpdk(os_port, subnets, pod):
|
|
|
|
"""Converts Neutron port to VIF object for nested dpdk containers.
|
|
|
|
|
|
|
|
:param os_port: dict containing port information as returned by
|
|
|
|
neutron client's 'show_port'
|
|
|
|
:param subnets: subnet mapping as returned by PodSubnetsDriver.get_subnets
|
|
|
|
:param pod: pod object received by k8s and containing profile details
|
|
|
|
:return: os-vif VIF object
|
|
|
|
"""
|
|
|
|
|
|
|
|
details = os_port.get('binding:vif_details', {})
|
|
|
|
profile = osv_vif.VIFPortProfileK8sDPDK(
|
|
|
|
l3_setup=False,
|
|
|
|
selflink=pod['metadata']['selfLink'])
|
|
|
|
|
|
|
|
return k_vif.VIFDPDKNested(
|
|
|
|
id=os_port['id'],
|
|
|
|
port_profile=profile,
|
|
|
|
address=os_port['mac_address'],
|
|
|
|
network=_make_vif_network(os_port, subnets),
|
|
|
|
has_traffic_filtering=details.get('port_filter', False),
|
|
|
|
preserve_on_delete=False,
|
|
|
|
active=_is_port_active(os_port),
|
|
|
|
plugin=const.K8S_OS_VIF_NOOP_PLUGIN,
|
|
|
|
pci_address="",
|
|
|
|
dev_driver="",
|
|
|
|
vif_name=_get_vif_name(os_port))
|
|
|
|
|
|
|
|
|
2019-12-09 15:22:19 +01:00
|
|
|
def neutron_to_osvif_vif(vif_translator, os_port, subnets):
|
2016-11-20 15:45:45 +03:00
|
|
|
"""Converts Neutron port to os-vif VIF object.
|
|
|
|
|
2017-03-02 16:26:21 +00:00
|
|
|
:param vif_translator: name of the traslator for the os-vif plugin to use
|
2019-12-09 15:22:19 +01:00
|
|
|
:param os_port: openstack.network.v2.port.Port object
|
2016-11-20 15:45:45 +03:00
|
|
|
:param subnets: subnet mapping as returned by PodSubnetsDriver.get_subnets
|
|
|
|
:return: os-vif VIF object
|
|
|
|
"""
|
|
|
|
try:
|
2017-03-02 16:26:21 +00:00
|
|
|
mgr = _VIF_MANAGERS[vif_translator]
|
2016-11-20 15:45:45 +03:00
|
|
|
except KeyError:
|
2017-06-08 15:53:52 +03:00
|
|
|
mgr = stv_driver.DriverManager(
|
|
|
|
namespace=_VIF_TRANSLATOR_NAMESPACE,
|
|
|
|
name=vif_translator, invoke_on_load=False)
|
2017-03-02 16:26:21 +00:00
|
|
|
_VIF_MANAGERS[vif_translator] = mgr
|
2016-11-20 15:45:45 +03:00
|
|
|
|
2019-12-09 15:22:19 +01:00
|
|
|
return mgr.driver(vif_translator, os_port, subnets)
|
2016-11-21 04:18:05 +03:00
|
|
|
|
|
|
|
|
|
|
|
def osvif_to_neutron_fixed_ips(subnets):
|
|
|
|
fixed_ips = []
|
|
|
|
|
2017-04-24 21:49:19 +08:00
|
|
|
for subnet_id, network in subnets.items():
|
2016-11-21 04:18:05 +03:00
|
|
|
ips = []
|
|
|
|
if len(network.subnets.objects) > 1:
|
2017-03-28 09:47:09 +08:00
|
|
|
raise k_exc.IntegrityError(_(
|
2016-11-21 04:18:05 +03:00
|
|
|
"Network object for subnet %(subnet_id)s is invalid, "
|
|
|
|
"must contain a single subnet, but %(num_subnets)s found") % {
|
|
|
|
'subnet_id': subnet_id,
|
|
|
|
'num_subnets': len(network.subnets.objects)})
|
|
|
|
|
|
|
|
for subnet in network.subnets.objects:
|
|
|
|
if subnet.obj_attr_is_set('ips'):
|
|
|
|
ips.extend([str(ip.address) for ip in subnet.ips.objects])
|
|
|
|
if ips:
|
|
|
|
fixed_ips.extend([{'subnet_id': subnet_id, 'ip_address': ip}
|
|
|
|
for ip in ips])
|
|
|
|
else:
|
|
|
|
fixed_ips.append({'subnet_id': subnet_id})
|
|
|
|
|
|
|
|
return fixed_ips
|