1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609
|
# 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.
from debtcollector import removals
from oslo_utils import versionutils
from oslo_versionedobjects import base
from oslo_versionedobjects import fields
from os_vif.objects import base as osv_base
from os_vif.objects import fields as osv_fields
@base.VersionedObjectRegistry.register
class VIFBase(osv_base.VersionedObject, base.ComparableVersionedObject):
"""Represents a virtual network interface.
The base VIF defines fields that are common to all types of VIF and
provides an association to the network the VIF is plugged into. It should
not be instantiated itself - use a subclass instead.
"""
# Version 1.0: Initial release
VERSION = '1.0'
fields = {
#: Unique identifier of the VIF port.
'id': fields.UUIDField(),
#: The guest MAC address.
'address': fields.MACAddressField(nullable=True),
#: The network to which the VIF is connected.
'network': fields.ObjectField('Network', nullable=True),
#: Name of the registered os_vif plugin.
'plugin': fields.StringField(),
#: Whether the VIF is initially online.
'active': fields.BooleanField(default=True),
#: Whether the host VIF should be preserved on unplug.
'preserve_on_delete': fields.BooleanField(default=False),
#: Whether the network service has provided traffic filtering.
'has_traffic_filtering': fields.BooleanField(default=False),
#: The virtual port profile metadata.
'port_profile': fields.ObjectField('VIFPortProfileBase',
subclasses=True)
}
@base.VersionedObjectRegistry.register
class VIFGeneric(VIFBase):
"""A generic-style VIF.
Generic-style VIFs are unbound, floating TUN/TAP devices that should be
setup by the plugin, not the hypervisor. The way the TAP device is
connected to the host network stack is explicitly left undefined.
For libvirt drivers, this maps to type="ethernet" which just implies a bare
TAP device with all setup delegated to the plugin.
"""
# Version 1.0: Initial release
VERSION = '1.0'
fields = {
#: Name of the device to create.
'vif_name': fields.StringField()
}
@base.VersionedObjectRegistry.register
class VIFBridge(VIFBase):
"""A bridge-style VIF.
Bridge-style VIFs are bound to a Linux host bridge by the hypervisor. This
provides Ethernet layer bridging, typically to the LAN. Other devices may
be bound to the same L2 virtual bridge.
For libvirt drivers, this maps to type='bridge'.
"""
# Version 1.0: Initial release
VERSION = '1.0'
fields = {
#: Name of the virtual device to create.
'vif_name': fields.StringField(),
#: Name of the physical device to connect to (e.g. ``br0``).
'bridge_name': fields.StringField(),
}
@base.VersionedObjectRegistry.register
class VIFOpenVSwitch(VIFBase):
"""A bridge-style VIF specifically for use with OVS.
Open vSwitch VIFs are bound directly (or indirectly) to an Open vSwitch
bridge by the hypervisor. Other devices may be bound to the same virtual
bridge.
For libvirt drivers, this also maps to type='bridge'.
"""
# Version 1.0: Initial release
VERSION = '1.0'
fields = {
#: Name of the virtual device to create.
'vif_name': fields.StringField(),
#: Name of the physical device to connect to (e.g. ``br0``).
'bridge_name': fields.StringField(),
}
@base.VersionedObjectRegistry.register
class VIFDirect(VIFBase):
"""A direct-style VIF.
Despite the confusing name, direct-style VIFs utilize macvtap which is a
device driver that inserts a software layer between a guest and an SR-IOV
Virtual Function (VF). Contrast this with
:class:`~os_vif.objects.vif.VIFHostDevice`, which allows the guest to
directly connect to the VF.
The connection to the device may operate in one of a number of different
modes, :term:`VEPA` (either :term:`802.1Qbg` or :term:`802.1Qbh`),
passthrough (exclusive assignment of the host NIC) or bridge (ethernet
layer bridging of traffic). The passthrough mode would be used when there
is a network device which needs to have a MAC address or VLAN
configuration. For passthrough of network devices without MAC/VLAN
configuration, :class:`~os_vif.objects.vif.VIFHostDevice` should be used
instead.
For libvirt drivers, this maps to type='direct'
"""
# Version 1.0: Initial release
VERSION = '1.0'
fields = {
#: Name of the device to create.
'vif_name': fields.StringField(),
#: The PCI address of the host device.
'dev_address': fields.PCIAddressField(),
#: Port connection mode.
'mode': osv_fields.VIFDirectModeField(),
#: The VLAN device name to use.
'vlan_name': fields.StringField(),
}
@base.VersionedObjectRegistry.register
class VIFVHostUser(VIFBase):
"""A vhostuser-style VIF.
vhostuser-style VIFs utilize a :term:`userspace vhost <vhost-user>`
backend, which allows traffic to traverse between the guest and a host
userspace application (commonly a virtual switch), bypassing the kernel
network stack. Contrast this with :class:`~os_vif.objects.vif.VIFBridge`,
where all packets must be handled by the hypervisor.
For libvirt drivers, this maps to type='vhostuser'
"""
# Version 1.0: Initial release
# Version 1.1: Added 'vif_name'
VERSION = '1.1'
fields = {
#: Name of the vhostuser port to create.
'vif_name': fields.StringField(),
#: UNIX socket path.
'path': fields.StringField(),
#: UNIX socket access permissions.
'mode': osv_fields.VIFVHostUserModeField(),
}
def obj_make_compatible(self, primitive, target_version):
target_version = versionutils.convert_version_to_tuple(target_version)
if target_version < (1, 1) and 'vif_name' in primitive:
del primitive['vif_name']
super(VIFVHostUser, self).obj_make_compatible(primitive, '1.0')
@base.VersionedObjectRegistry.register
class VIFHostDevice(VIFBase):
"""A hostdev-style VIF.
Hostdev-style VIFs provide a guest with direct access to an :term:`SR-IOV`
:term:`Virtual Function` (VF) or an entire :term:`Physical Function` (PF).
Contrast this with :class:`~ovs_vif.objects.vif.VIFDirect`, which includes
a software layer between the interface and the guest.
For libvirt drivers, this maps to type='hostdev'
"""
# Version 1.0: Initial release
VERSION = '1.0'
fields = {
#: The type of the host device.
#:
#: Valid values are ``ethernet`` and ``generic``.
#:
#: - ``ethernet`` is ``<interface type='hostdev'>``
#: - ``generic`` is ``<hostdev mode='subsystem' type='pci'>``
'dev_type': osv_fields.VIFHostDeviceDevTypeField(),
#: The PCI address of the host device.
'dev_address': fields.PCIAddressField(),
}
@base.VersionedObjectRegistry.register
class VIFNestedDPDK(VIFBase):
"""A nested DPDK-style VIF.
Nested DPDK-style VIFs are used by Kuryr-Kubernetes to provide accelerated
DPDK datapath for nested Kubernetes pods running inside the VM. The port
is first attached to the virtual machine, bound to the userspace driver
(e.g. ``uio_pci_generic``, ``igb_uio`` or ``vfio-pci``) and then consumed
by Kubernetes pod via the kuryr-kubernetes CNI plugin.
This does not apply to libvirt drivers.
"""
# Version 1.0: Initial release
VERSION = '1.0'
fields = {
#: PCI address of the device.
'pci_address': fields.StringField(),
#: Name of the driver the device was previously bound to; it makes
#: the controller driver agnostic (virtio, SR-IOV, etc.).
'dev_driver': fields.StringField(),
}
@base.VersionedObjectRegistry.register
class DatapathOffloadBase(osv_base.VersionedObject,
base.ComparableVersionedObject):
"""Base class for all types of datapath offload."""
# Version 1.0: Initial release
VERSION = '1.0'
@base.VersionedObjectRegistry.register
class DatapathOffloadRepresentor(DatapathOffloadBase):
"""Offload type for VF Representors conforming to the switchdev model.
This datapath offloads provides the metadata required to associate a VIF
with a :term:`VF` representor conforming to the `switchdev`_ kernel model.
If ``representor_name`` is specified, it indicates a desire to rename the
representor to the given name on plugging.
.. _switchdev: https://netdevconf.org/1.2/session.html?or-gerlitz
"""
# Version 1.0: Initial release
VERSION = '1.0'
fields = {
#: Name to set on the representor (if set).
'representor_name': fields.StringField(nullable=True),
#: The PCI address of the Virtual Function.
'representor_address': fields.StringField(nullable=True),
}
@base.VersionedObjectRegistry.register
class VIFPortProfileBase(osv_base.VersionedObject,
base.ComparableVersionedObject):
"""Base class for all types of port profile.
The base profile defines fields that are common to all types of profile. It
should not be instantiated itself - use a subclass instead.
"""
# Version 1.0: Initial release
# Version 1.1: Added 'datapath_offload'
VERSION = '1.1'
fields = {
#: Datapath offload type of the port.
'datapath_offload': fields.ObjectField('DatapathOffloadBase',
nullable=True,
subclasses=True),
}
obj_relationships = {
'datapath_offload': (('1.1', '1.0'),),
}
@base.VersionedObjectRegistry.register
class VIFPortProfileOpenVSwitch(VIFPortProfileBase):
"""Port profile info for Open vSwitch networks.
This profile provides the metadata required to associate a VIF with an Open
vSwitch interface.
"""
# Version 1.0: Initial release
# Version 1.1: Added 'datapath_type'
# Version 1.2: VIFPortProfileBase updated to 1.1 from 1.0
# Version 1.3: Added 'create_port'
VERSION = '1.3'
fields = {
#: A UUID to uniquely identify the interface. If omitted one will be
#: generated automatically.
'interface_id': fields.UUIDField(),
#: The OpenVSwitch port profile for the interface.
'profile_id': fields.StringField(),
#: Datapath type of the bridge.
'datapath_type': fields.StringField(nullable=True),
#: Whether the os-vif plugin should add the port to the bridge.
'create_port': fields.BooleanField(default=False),
}
def obj_make_compatible(self, primitive, target_version):
target_version = versionutils.convert_version_to_tuple(target_version)
if target_version < (1, 3) and 'create_port' in primitive:
del primitive['create_port']
if target_version < (1, 1) and 'datapath_type' in primitive:
del primitive['datapath_type']
if target_version < (1, 2):
super(VIFPortProfileOpenVSwitch, self).obj_make_compatible(
primitive, '1.0')
else:
super(VIFPortProfileOpenVSwitch, self).obj_make_compatible(
primitive, '1.1')
@base.VersionedObjectRegistry.register
class VIFPortProfileFPOpenVSwitch(VIFPortProfileOpenVSwitch):
"""Port profile info for Open vSwitch networks using fast path.
This profile provides the metadata required to associate a :term:`fast
path <Fast Path>` VIF with an :term:`Open vSwitch` port.
"""
# Version 1.0: Initial release
# Version 1.1: VIFPortProfileOpenVSwitch updated to 1.1 from 1.0
# Version 1.2: VIFPortProfileOpenVSwitch updated to 1.2 from 1.1
# Version 1.3: VIFPortProfileOpenVSwitch updated to 1.3 from 1.2
VERSION = '1.3'
fields = {
#: Name of the bridge (managed by fast path) to connect to.
'bridge_name': fields.StringField(),
#: Whether the OpenVSwitch network is using hybrid plug.
'hybrid_plug': fields.BooleanField(default=False),
}
def obj_make_compatible(self, primitive, target_version):
target_version = versionutils.convert_version_to_tuple(target_version)
if target_version < (1, 1):
super(VIFPortProfileFPOpenVSwitch, self).obj_make_compatible(
primitive, '1.0')
elif target_version < (1, 2):
super(VIFPortProfileFPOpenVSwitch, self).obj_make_compatible(
primitive, '1.1')
elif target_version < (1, 3):
super(VIFPortProfileFPOpenVSwitch, self).obj_make_compatible(
primitive, '1.2')
else:
super(VIFPortProfileFPOpenVSwitch, self).obj_make_compatible(
primitive, '1.3')
@removals.removed_class("VIFPortProfileOVSRepresentor",
category=PendingDeprecationWarning)
@base.VersionedObjectRegistry.register
class VIFPortProfileOVSRepresentor(VIFPortProfileOpenVSwitch):
"""Port profile info for OpenVSwitch networks using a representor.
This profile provides the metadata required to associate a VIF with a
:term:`VF` representor and :term:`Open vSwitch` port. If `representor_name`
is specified, it indicates a desire to rename the representor to the given
name on plugging.
.. note::
This port profile is provided for backwards compatibility only.
This interface has been superceded by the one provided by the
:class:`DatapathOffloadRepresentor` class, which is now a field element
of the :class:`VIFPortProfileBase` class. The ``datapath_offload``
field in port profiles should be used instead.
"""
# Version 1.0: Initial release
# Version 1.1: VIFPortProfileOpenVSwitch updated to 1.1 from 1.0
# Version 1.2: VIFPortProfileOpenVSwitch updated to 1.2 from 1.1
# Version 1.3: VIFPortProfileOpenVSwitch updated to 1.3 from 1.2
VERSION = '1.3'
fields = {
#: Name to set on the representor (if set).
'representor_name': fields.StringField(nullable=True),
#: The PCI address of the Virtual Function.
'representor_address': fields.PCIAddressField(nullable=True),
}
def obj_make_compatible(self, primitive, target_version):
target_version = versionutils.convert_version_to_tuple(target_version)
if target_version < (1, 1):
super(VIFPortProfileOVSRepresentor, self).obj_make_compatible(
primitive, '1.0')
elif target_version < (1, 2):
super(VIFPortProfileOVSRepresentor, self).obj_make_compatible(
primitive, '1.1')
elif target_version < (1, 3):
super(VIFPortProfileOVSRepresentor, self).obj_make_compatible(
primitive, '1.2')
else:
super(VIFPortProfileOVSRepresentor, self).obj_make_compatible(
primitive, '1.3')
@base.VersionedObjectRegistry.register
class VIFPortProfileFPBridge(VIFPortProfileBase):
"""Port profile info for Linux Bridge networks using fast path.
This profile provides the metadata required to associate a :term:`fast
path <Fast Path>` VIF with a :term:`Linux Bridge` port.
"""
# Version 1.0: Initial release
# Version 1.1: VIFPortProfileBase updated to 1.1 from 1.0
VERSION = '1.1'
fields = {
#: Name of the bridge (managed by fast path) to connect to.
'bridge_name': fields.StringField(),
}
def obj_make_compatible(self, primitive, target_version):
target_version = versionutils.convert_version_to_tuple(target_version)
if target_version < (1, 1):
super(VIFPortProfileFPBridge, self).obj_make_compatible(
primitive, '1.0')
else:
super(VIFPortProfileFPBridge, self).obj_make_compatible(
primitive, '1.1')
@base.VersionedObjectRegistry.register
class VIFPortProfileFPTap(VIFPortProfileBase):
"""Port profile info for Calico networks using fast path.
This profile provides the metadata required to associate a :term:`fast
path <Fast Path>` VIF with a :term:`Calico` port.
"""
# Version 1.0: Initial release
# Version 1.1: VIFPortProfileBase updated to 1.1 from 1.0
VERSION = '1.1'
fields = {
#: The MAC address of the host vhostuser port.
'mac_address': fields.MACAddressField(nullable=True),
}
def obj_make_compatible(self, primitive, target_version):
target_version = versionutils.convert_version_to_tuple(target_version)
if target_version < (1, 1):
super(VIFPortProfileFPTap, self).obj_make_compatible(
primitive, '1.0')
else:
super(VIFPortProfileFPTap, self).obj_make_compatible(
primitive, '1.1')
@base.VersionedObjectRegistry.register
class VIFPortProfile8021Qbg(VIFPortProfileBase):
"""Port profile info for VEPA 802.1qbg networks.
This profile provides the metadata required to associate a VIF with a VEPA
host device supporting the :term:`802.1Qbg` spec.
"""
# Version 1.0: Initial release
# Version 1.1: VIFPortProfileBase updated to 1.1 from 1.0
VERSION = '1.1'
fields = {
# TODO(stephenfin): Apparently the value 0 is reserved for manager_id,
# so should we set 'minimum=1'?
# https://libvirt.org/formatdomain.html#elementsNICS
#: The VSI Manager ID identifies the database containing the VSI type
#: and instance definitions.
'manager_id': fields.IntegerField(),
#: The VSI Type ID identifies a VSI type characterizing the network
#: access. VSI types are typically managed by network administrator.
'type_id': fields.IntegerField(),
#: The VSI Type Version allows multiple versions of a VSI Type.
'type_id_version': fields.IntegerField(),
#: The VSI Instance ID Identifier is generated when a VSI instance
#: (i.e. a virtual interface of a virtual machine) is created. This is
#: a globally unique identifier.
'instance_id': fields.UUIDField(),
}
def obj_make_compatible(self, primitive, target_version):
target_version = versionutils.convert_version_to_tuple(target_version)
if target_version < (1, 1):
super(VIFPortProfile8021Qbg, self).obj_make_compatible(
primitive, '1.0')
else:
super(VIFPortProfile8021Qbg, self).obj_make_compatible(
primitive, '1.1')
@base.VersionedObjectRegistry.register
class VIFPortProfile8021Qbh(VIFPortProfileBase):
"""Port profile info for VEPA 802.1qbh networks.
This profile provides the metadata required to associate a VIF with a VEPA
host device supporting the :term:`802.1Qbh` spec.
"""
# Version 1.0: Initial release
# Version 1.1: VIFPortProfileBase updated to 1.1 from 1.0
VERSION = '1.1'
fields = {
#: The name of the port profile that is to be applied to this
#: interface. This name is resolved by the port profile database into
#: the network parameters from the port profile, and those network
#: parameters will be applied to this interface.
'profile_id': fields.StringField()
}
def obj_make_compatible(self, primitive, target_version):
target_version = versionutils.convert_version_to_tuple(target_version)
if target_version < (1, 1):
super(VIFPortProfile8021Qbh, self).obj_make_compatible(
primitive, '1.0')
else:
super(VIFPortProfile8021Qbh, self).obj_make_compatible(
primitive, '1.1')
@base.VersionedObjectRegistry.register
class VIFPortProfileK8sDPDK(VIFPortProfileBase):
"""Port profile info for Kuryr-Kubernetes DPDK ports.
This profile provides the metadata required to associate nested DPDK VIF
with a Kubernetes pod.
"""
# Version 1.0: Initial release
# Version 1.1: VIFPortProfileBase updated to 1.1 from 1.0
VERSION = '1.1'
fields = {
#: Specify whether this vif requires L3 setup.
'l3_setup': fields.BooleanField(),
#: String containing URL representing object in Kubernetes v1 API.
'selflink': fields.StringField(),
#: String used in Kubernetes v1 API to identify the server's internal
#: version of this object.
'resourceversion': fields.StringField()
}
def obj_make_compatible(self, primitive, target_version):
target_version = versionutils.convert_version_to_tuple(target_version)
if target_version < (1, 1):
super(VIFPortProfileK8sDPDK, self).obj_make_compatible(
primitive, '1.0')
else:
super(VIFPortProfileK8sDPDK, self).obj_make_compatible(
primitive, '1.1')
|