Merge "Adding VLAN support and other configs for sriov_vf"

This commit is contained in:
Zuul 2018-07-13 18:13:39 +00:00 committed by Gerrit Code Review
commit 420cdede7a
13 changed files with 834 additions and 119 deletions

View File

@ -4,7 +4,8 @@
"type": "sriov_pf",
"name": "p2p1",
"numvfs": 10,
"use_dhcp": false
"use_dhcp": false,
"promisc": on
},
{
"type": "sriov_vf",
@ -14,7 +15,31 @@
{
"ip_netmask": "192.0.2.1/24"
}
]
],
"vlan_id": 100,
"qos": 2,
"spoofcheck": true,
"macaddr": "00:78:90:80:cc:30",
"trust": true,
"state": auto,
"promisc": false
},
{
"type": "ovs_bridge",
"name": "br-vfs",
"members": [
{
"type": "sriov_vf",
"vfid": 1,
"trust": true,
"device": "p2p1",
"promisc": true,
"vlan_id": 116,
"qos": 2,
"spoofcheck": false
}
],
"use_dhcp": true
}
]
}

View File

@ -13,6 +13,9 @@ network_config:
numvfs: 10
# Dont set the IP address on the PF
use_dhcp: false
# Allow all the traffic received. It might be needed when one of its VF
# is attached to a ovs bridge
promisc: on
# sriov_vf type shall be used to configure the VF's of NICs.
# It requires the PF devices to be configured via sriov_pf types
@ -27,3 +30,56 @@ network_config:
vfid: 5
addresses:
- ip_netmask: 192.0.2.1/24
# When specified, all traffic sent from the VF will be tagged with the
# specified VLAN ID. Incoming traffic will be filtered for the specified
# VLAN ID, and will have all VLAN tags stripped before being passed to the
# VF. Setting this parameter to 0 disables VLAN tagging and filtering.
vlan_id: 100
# VLAN-Quality Of Service (priority) bits for the VLAN tag.
# When specified, all VLAN tags transmitted by the VF will include the
# specified priority bits in the VLAN tag. Requires vlan_id
# Default value is 0.
qos: 2
# MAC spoofing is a method of altering the MAC address
# The MAC address anti-spoofing when enabled protects from malicious MAC
# address spoofing. It should be disabled for 802.3ad bonds.
spoofcheck: on
# Change the MAC address of the VF.
macaddr: 00:78:90:80:cc:30
# Enabling trust (true) for VF allows enabling multicast/promiscuous mode
# on the VF. The default value is off.
trust: on
# Link state seen by the VF
# - auto: a reflection of the PF link state (default)
# - enable: lets the VF to communicate with other VFs on this host even
# if the PF link state is down
# - disable: causes the HW to drop any packets sent by the VF.
state: auto
# Enabling promisc mode allows the traffic originally targeted to go to the
# VF and it will also receive the unmatched traffic and all the multicast
# traffic received in the physical port. Note that all traffic that has
# destination mac that does not match any of the VFs/PF MAC addresses is
# referred to as unmatched traffic.
# The default value is off. Requires the enabling of trust mode
promisc: off
# Attach a SR-IOV VF to a ovs bridge
- type: ovs_bridge
name: br-vfs
use_dhcp: true
members:
# Specify the type
- type: sriov_vf
# Required field
device: p2p1
# Required field
vfid: 1
# Optional field
vlan_id: 116
# Optional field, but requires vlan_id
qos: 3
# Set trust to 'on' when attaching to ovs_bridge
trust: on
# Set promisc to 'on' when attaching to ovs_bridge
promisc: on
# Set spoofcheck to 'off' when attaching to ovs_bridge
spoofcheck: off

View File

@ -249,9 +249,16 @@ def main(argv=sys.argv):
# Look for the presence of SriovPF types in the first parse of the json
# if SriovPFs exists then PF devices needs to be configured so that the VF
# devices are created.
# The VFs will not be available now and an exception
# SriovVfNotFoundException will be raised while fetching the device name.
# After the first parse the SR-IOV PF devices would be configured and the
# VF devices would be created.
# In the second parse, all other objects shall be added
for iface_json in iface_array:
obj = objects.object_from_json(iface_json)
try:
obj = objects.object_from_json(iface_json)
except utils.SriovVfNotFoundException:
continue
if isinstance(obj, objects.SriovPF):
configure_sriov = True
provider.add_object(obj)
@ -263,11 +270,20 @@ def main(argv=sys.argv):
# All objects other than the sriov_pf will be added here.
# The VFs are expected to be available now and an exception
# SriovVfNotFoundException shall be raised if not available.
obj = objects.object_from_json(iface_json)
try:
obj = objects.object_from_json(iface_json)
except utils.SriovVfNotFoundException:
if not opts.noop:
raise
if not isinstance(obj, objects.SriovPF):
provider.add_object(obj)
if configure_sriov and not opts.noop:
utils.configure_sriov_vfs()
files_changed = provider.apply(cleanup=opts.cleanup,
activate=not opts.no_activate)
if opts.noop:
for location, data in files_changed.items():
print("File: %s\n" % location)

View File

@ -140,7 +140,6 @@ class IfcfgNetConfig(os_net_config.NetConfig):
def _add_common(self, base_opt):
ovs_extra = []
data = "# This file is autogenerated by os-net-config\n"
data += "DEVICE=%s\n" % base_opt.name
if base_opt.onboot:
@ -678,7 +677,8 @@ class IfcfgNetConfig(os_net_config.NetConfig):
logger.info('adding sriov pf: %s' % sriov_pf.name)
data = self._add_common(sriov_pf)
logger.debug('sriov pf data: %s' % data)
utils.update_sriov_pf_map(sriov_pf.name, sriov_pf.numvfs, self.noop)
utils.update_sriov_pf_map(sriov_pf.name, sriov_pf.numvfs,
self.noop, promisc=sriov_pf.promisc)
self.interface_data[sriov_pf.name] = data
def add_sriov_vf(self, sriov_vf):
@ -686,13 +686,6 @@ class IfcfgNetConfig(os_net_config.NetConfig):
:param sriov_vf: The SriovVF object to add
"""
# Retrieve the VF's name, using its PF device name and VF id.
# Note: The VF's name could be read only after setting the numvfs of
# the corresponding parent PF device. Untill this point the name field
# for VFs will be a empty string. An exception SriovVfNotFoundException
# shall be raised when the VF could not be found
sriov_vf.name = utils.get_vf_devname(sriov_vf.device, sriov_vf.vfid,
self.noop)
logger.info('adding sriov vf: %s for pf: %s, vfid: %d'
% (sriov_vf.name, sriov_vf.device, sriov_vf.vfid))
data = self._add_common(sriov_vf)

View File

@ -1121,7 +1121,8 @@ class SriovVF(_BaseOpts):
addresses=None, routes=None, mtu=None, primary=False,
nic_mapping=None, persist_mapping=False, defroute=True,
dhclient_args=None, dns_servers=None, nm_controlled=False,
onboot=True):
onboot=True, vlan_id=0, qos=0, spoofcheck=None,
trust=None, state=None, macaddr=None, promisc=None):
addresses = addresses or []
routes = routes or []
dns_servers = dns_servers or []
@ -1131,13 +1132,38 @@ class SriovVF(_BaseOpts):
# Empty strings are set for the name field.
# The provider shall identify the VF name from the PF device name
# (device) and the VF id.
super(SriovVF, self).__init__("", use_dhcp, use_dhcpv6, addresses,
name = utils.get_vf_devname(device, vfid)
super(SriovVF, self).__init__(name, use_dhcp, use_dhcpv6, addresses,
routes, mtu, primary, nic_mapping,
persist_mapping, defroute,
dhclient_args, dns_servers,
nm_controlled, onboot)
self.vfid = vfid
self.vfid = int(vfid)
self.device = device
self.vlan_id = int(vlan_id)
self.qos = int(qos)
self.spoofcheck = spoofcheck
self.trust = trust
self.state = state
self.macaddr = macaddr
self.promisc = promisc
utils.update_sriov_vf_map(device, self.vfid, name,
vlan_id=self.vlan_id,
qos=self.qos,
spoofcheck=spoofcheck,
trust=trust,
state=state,
macaddr=macaddr,
promisc=promisc)
@staticmethod
def get_on_off(config):
rval = None
if config:
rval = "on"
elif config is False:
rval = "off"
return rval
@staticmethod
def from_json(json):
@ -1146,7 +1172,22 @@ class SriovVF(_BaseOpts):
# Get the PF device name
device = _get_required_field(json, 'device', 'SriovVF')
opts = _BaseOpts.base_opts_from_json(json)
return SriovVF(device, vfid, *opts)
vlan_id = json.get('vlan_id', 0)
qos = json.get('qos', 0)
if qos != 0 and vlan_id == 0:
msg = "Vlan tag not set for QOS - VF: %s:%d" % (device, vfid)
raise InvalidConfigException(msg)
spoofcheck = SriovVF.get_on_off(json.get('spoofcheck'))
trust = SriovVF.get_on_off(json.get('trust'))
promisc = SriovVF.get_on_off(json.get('promisc'))
state = json.get('state')
if state not in [None, 'auto', 'enable', 'disable']:
msg = 'Expecting state to match auto/enable/disable'
raise InvalidConfigException(msg)
macaddr = json.get('macaddr')
return SriovVF(device, vfid, *opts, vlan_id=vlan_id, qos=qos,
spoofcheck=spoofcheck, trust=trust, state=state,
macaddr=macaddr, promisc=promisc)
class SriovPF(_BaseOpts):
@ -1156,7 +1197,7 @@ class SriovPF(_BaseOpts):
addresses=None, routes=None, mtu=None, primary=False,
nic_mapping=None, persist_mapping=False, defroute=True,
dhclient_args=None, dns_servers=None, nm_controlled=False,
onboot=True, members=None):
onboot=True, members=None, promisc=None):
addresses = addresses or []
routes = routes or []
dns_servers = dns_servers or []
@ -1165,19 +1206,25 @@ class SriovPF(_BaseOpts):
persist_mapping, defroute,
dhclient_args, dns_servers,
nm_controlled, onboot)
self.numvfs = numvfs
self.numvfs = int(numvfs)
mapped_nic_names = mapped_nics(nic_mapping)
if name in mapped_nic_names:
self.name = mapped_nic_names[name]
else:
self.name = name
self.promisc = promisc
@staticmethod
def from_json(json):
name = _get_required_field(json, 'name', 'SriovPF')
numvfs = _get_required_field(json, 'numvfs', 'SriovPF')
promisc = json.get('promisc', None)
if promisc is True:
promisc = "on"
elif promisc is False:
promisc = "off"
opts = _BaseOpts.base_opts_from_json(json)
return SriovPF(name, numvfs, *opts)
return SriovPF(name, numvfs, *opts, promisc=promisc)
class OvsDpdkBond(_BaseOpts):

View File

@ -30,7 +30,13 @@ definitions:
type: string
pattern: "(?i)^(t|true|on|y|yes|1|f|false|off|n|no|0)$"
- $ref: "#/definitions/param"
sriov_vf_state_string:
type: string
pattern: "^(auto|enable|disable)$"
# MAC address type
mac_address_string:
type: string
pattern: "^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$"
# IP address and address+prefix types
ipv4_address_string:
type: string
@ -256,6 +262,8 @@ definitions:
$ref: "#/definitions/bool_or_param"
numvfs:
$ref: "#/definitions/int_or_param"
promisc:
$ref: "#/definitions/bool_or_param"
hotplug:
$ref: "#/definitions/bool_or_param"
# common options:
@ -300,8 +308,22 @@ definitions:
$ref: "#/definitions/string_or_param"
vfid:
$ref: "#/definitions/int_or_param"
vlan_id:
$ref: "#/definitions/int_or_param"
qos:
$ref: "#/definitions/int_or_param"
hotplug:
$ref: "#/definitions/bool_or_param"
spoofcheck:
$ref: "#/definitions/bool_or_param"
trust:
$ref: "#/definitions/bool_or_param"
promisc:
$ref: "#/definitions/bool_or_param"
macaddr:
$ref: "#/definitions/mac_address_string"
state:
$ref: "#/definitions/sriov_vf_state_string"
# common options:
use_dhcp:
$ref: "#/definitions/bool_or_param"
@ -391,6 +413,7 @@ definitions:
- $ref: "#/definitions/ovs_bond"
- $ref: "#/definitions/ovs_tunnel"
- $ref: "#/definitions/ovs_patch_port"
- $ref: "#/definitions/sriov_vf"
ovs_options:
$ref: "#/definitions/ovs_options_string_or_param"
ovs_extra:

View File

@ -21,29 +21,53 @@
# it for the first time configuration.
# An entry point os-net-config-sriov is added for invocation of this module.
import argparse
import logging
import os
import pyudev
from six.moves import queue as Queue
import sys
import time
import yaml
logger = logging.getLogger(__name__)
from oslo_concurrency import processutils
# File to contain the list of SR-IOV nics and the numvfs
logger = logging.getLogger(__name__)
# Create a queue for passing the udev network events
vf_queue = Queue.Queue()
# File to contain the list of SR-IOV PF, VF and their configurations
# Format of the file shall be
#
# - name: eth1
# numvfs: 5
_SRIOV_PF_CONFIG_FILE = '/var/lib/os-net-config/sriov_pf.yaml'
_SYS_CLASS_NET = '/sys/class/net'
# maximum retries for checking the creation of VFs
_MAX_SRIOV_VFS_CONFIG_RETRIES = 60
# - device_type: pf
# name: <pf name>
# numvfs: <number of VFs>
# promisc: "on"/"off"
# - device_type: vf
# device:
# name: <pf name>
# vfid: <VF id>
# name: <vf name>
# vlan_id: <vlan>
# qos: <qos>
# spoofcheck: "on"/"off"
# trust: "on"/"off"
# state: "auto"/"enable"/"disable"
# macaddr: <mac address>
# promisc: "on"/"off"
_SRIOV_CONFIG_FILE = '/var/lib/os-net-config/sriov_config.yaml'
class SRIOVNumvfsException(ValueError):
pass
def udev_event_handler(action, device):
event = {"action": action, "device": device.sys_path}
logger.info("Received udev event %s for %s"
% (event["action"], event["device"]))
vf_queue.put(event)
def get_file_data(filename):
if not os.path.exists(filename):
return ''
@ -55,55 +79,161 @@ def get_file_data(filename):
return ''
def _get_sriov_pf_map():
contents = get_file_data(_SRIOV_PF_CONFIG_FILE)
sriov_pf_map = yaml.load(contents) if contents else []
return sriov_pf_map
def _get_sriov_map():
contents = get_file_data(_SRIOV_CONFIG_FILE)
sriov_map = yaml.load(contents) if contents else []
return sriov_map
def _configure_sriov_pf():
sriov_pf_map = _get_sriov_pf_map()
for item in sriov_pf_map:
try:
sriov_numvfs_path = ("/sys/class/net/%s/device/sriov_numvfs"
% item['name'])
with open(sriov_numvfs_path, 'w') as f:
f.write("%d" % item['numvfs'])
except IOError as exc:
msg = ("Unable to configure pf: %s with numvfs: %d\n%s"
% (item['name'], item['numvfs'], exc))
raise SRIOVNumvfsException(msg)
def configure_sriov_pf():
# Create a context for pyudev and observe udev events for network
context = pyudev.Context()
monitor = pyudev.Monitor.from_netlink(context)
monitor.filter_by('net')
observer = pyudev.MonitorObserver(monitor, udev_event_handler)
observer.start()
def _wait_for_vf_creation():
sriov_map = _get_sriov_pf_map()
sriov_map = _get_sriov_map()
for item in sriov_map:
count = 0
while count < _MAX_SRIOV_VFS_CONFIG_RETRIES:
pf = item['name']
numvfs = item['numvfs']
vf_path = os.path.join(_SYS_CLASS_NET, pf,
"device/virtfn%d/net" % (numvfs - 1))
if os.path.isdir(vf_path):
vf_nic = os.listdir(vf_path)
if len(vf_nic) == 1 and pf in vf_nic[0]:
logger.info("VFs created for PF: %s" % pf)
break
if item['device_type'] == 'pf':
_pf_interface_up(item)
try:
sriov_numvfs_path = ("/sys/class/net/%s/device/sriov_numvfs"
% item['name'])
with open(sriov_numvfs_path, 'w') as f:
f.write("%d" % item['numvfs'])
except IOError as exc:
msg = ("Unable to configure pf: %s with numvfs: %d\n%s"
% (item['name'], item['numvfs'], exc))
raise SRIOVNumvfsException(msg)
# Wait for the creation of VFs for each PF
_wait_for_vf_creation(item['name'], item['numvfs'])
observer.stop()
def _wait_for_vf_creation(pf_name, numvfs):
vf_count = 0
vf_list = []
while vf_count < numvfs:
try:
# wait for 5 seconds after every udev event
event = vf_queue.get(True, 5)
vf_name = os.path.basename(event["device"])
pf_path = os.path.normpath(os.path.join(event["device"],
"../../physfn/net"))
if os.path.isdir(pf_path):
pf_nic = os.listdir(pf_path)
if len(pf_nic) == 1 and pf_name == pf_nic[0]:
if vf_name not in vf_list:
vf_list.append(vf_name)
logger.info("VF: %s created for PF: %s"
% (vf_name, pf_name))
vf_count = vf_count + 1
else:
logger.debug("VF device name not present for PF %s" % pf)
logger.error("Unable to parse event %s" % event["device"])
else:
logger.info("Attempt#%d, VFs for PF %s is not yet created"
% (count + 1, pf))
time.sleep(1)
count += 1
logger.error("%s is not a directory" % pf_path)
except Queue.Empty:
logger.info("Timeout in the creation of VFs for PF %s" % pf_name)
return
logger.info("Required VFs are created for PF %s" % pf_name)
def main(argv=None):
def run_ip_config_cmd(*cmd, **kwargs):
logger.info("Running %s" % ' '.join(cmd))
try:
processutils.execute(*cmd, **kwargs)
except processutils.ProcessExecutionError:
logger.error("Failed to execute %s" % ' '.join(cmd))
raise
def _pf_interface_up(pf_device):
if 'promisc' in pf_device:
run_ip_config_cmd('ip', 'link', 'set', 'dev', pf_device['name'],
'promisc', pf_device['promisc'])
logger.info("Bringing up PF: %s" % pf_device['name'])
run_ip_config_cmd('ip', 'link', 'set', 'dev', pf_device['name'], 'up')
def configure_sriov_vf():
sriov_map = _get_sriov_map()
for item in sriov_map:
if item['device_type'] == 'vf':
pf_name = item['device']['name']
vfid = item['device']['vfid']
base_cmd = ('ip', 'link', 'set', 'dev', pf_name, 'vf', str(vfid))
logger.info("Configuring settings for PF: %s VF :%d VF name : %s"
% (pf_name, vfid, item['name']))
if 'macaddr' in item:
cmd = base_cmd + ('mac', item['macaddr'])
run_ip_config_cmd(*cmd)
if 'vlan_id' in item:
vlan_cmd = base_cmd + ('vlan', str(item['vlan_id']))
if 'qos' in item:
vlan_cmd = vlan_cmd + ('qos', str(item['qos']))
run_ip_config_cmd(*vlan_cmd)
if 'spoofcheck' in item:
cmd = base_cmd + ('spoofchk', item['spoofcheck'])
run_ip_config_cmd(*cmd)
if 'state' in item:
cmd = base_cmd + ('state', item['state'])
run_ip_config_cmd(*cmd)
if 'trust' in item:
cmd = base_cmd + ('trust', item['trust'])
run_ip_config_cmd(*cmd)
if 'promisc' in item:
run_ip_config_cmd('ip', 'link', 'set', 'dev', item['name'],
'promisc', item['promisc'])
def parse_opts(argv):
parser = argparse.ArgumentParser(
description='Configure SR-IOV PF and VF interfaces using a YAML'
' config file format.')
parser.add_argument(
'-d', '--debug',
dest="debug",
action='store_true',
help="Print debugging output.",
required=False)
parser.add_argument(
'-v', '--verbose',
dest="verbose",
action='store_true',
help="Print verbose output.",
required=False)
opts = parser.parse_args(argv[1:])
return opts
def configure_logger(verbose=False, debug=False):
LOG_FORMAT = '[%(asctime)s] [%(levelname)s] %(message)s'
DATE_FORMAT = '%Y/%m/%d %I:%M:%S %p'
log_level = logging.WARN
if debug:
log_level = logging.DEBUG
elif verbose:
log_level = logging.INFO
logging.basicConfig(format=LOG_FORMAT, datefmt=DATE_FORMAT,
level=log_level)
def main(argv=sys.argv):
opts = parse_opts(argv)
configure_logger(opts.verbose, opts.debug)
# Configure the PF's
_configure_sriov_pf()
# Wait for the VF's to get created
_wait_for_vf_creation()
configure_sriov_pf()
# Configure the VFs
configure_sriov_vf()
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))
sys.exit(main(sys.argv))

View File

@ -15,11 +15,13 @@
# under the License.
import os.path
import random
import sys
import yaml
import os_net_config
from os_net_config import cli
from os_net_config import sriov_config
from os_net_config.tests import base
import six
@ -31,6 +33,16 @@ SAMPLE_BASE = os.path.join(REALPATH, '../../', 'etc',
class TestCli(base.TestCase):
def setUp(self):
super(TestCli, self).setUp()
rand = str(int(random.random() * 100000))
sriov_config._SRIOV_CONFIG_FILE = '/tmp/sriov_config_' + rand + '.yaml'
def tearDown(self):
super(TestCli, self).tearDown()
if os.path.isfile(sriov_config._SRIOV_CONFIG_FILE):
os.remove(sriov_config._SRIOV_CONFIG_FILE)
def run_cli(self, argstr, exitcodes=(0,)):
orig = sys.stdout
orig_stderr = sys.stderr
@ -191,6 +203,10 @@ class TestCli(base.TestCase):
% interface_yaml, exitcodes=(0,))
def test_sriov_noop_output(self):
def test_get_vf_devname(device, vfid):
return device + '_' + str(vfid)
self.stub_out('os_net_config.utils.get_vf_devname',
test_get_vf_devname)
ivs_yaml = os.path.join(SAMPLE_BASE, 'sriov_pf.yaml')
ivs_json = os.path.join(SAMPLE_BASE, 'sriov_pf.json')
stdout_yaml, stderr = self.run_cli('ARG0 --provider=ifcfg --noop '
@ -202,7 +218,8 @@ class TestCli(base.TestCase):
'-c %s' % ivs_json)
self.assertEqual('', stderr)
sanity_devices = ['DEVICE=p2p1',
'DEVICE=p2p1_5']
'DEVICE=p2p1_5',
'DEVICE=p2p1_1']
for dev in sanity_devices:
self.assertIn(dev, stdout_yaml)
self.assertEqual(stdout_yaml, stdout_json)

View File

@ -15,6 +15,7 @@
# under the License.
import os.path
import random
import tempfile
from oslo_concurrency import processutils
@ -22,6 +23,7 @@ from oslo_concurrency import processutils
import os_net_config
from os_net_config import impl_ifcfg
from os_net_config import objects
from os_net_config import sriov_config
from os_net_config.tests import base
from os_net_config import utils
@ -475,14 +477,17 @@ CPU_LIST=2,3
class TestIfcfgNetConfig(base.TestCase):
def setUp(self):
super(TestIfcfgNetConfig, self).setUp()
rand = str(int(random.random() * 100000))
sriov_config._SRIOV_CONFIG_FILE = '/tmp/sriov_config_' + rand + '.yaml'
self.provider = impl_ifcfg.IfcfgNetConfig()
def tearDown(self):
super(TestIfcfgNetConfig, self).tearDown()
if os.path.isfile(sriov_config._SRIOV_CONFIG_FILE):
os.remove(sriov_config._SRIOV_CONFIG_FILE)
def get_interface_config(self, name='em1'):
return self.provider.interface_data[name]
@ -1120,18 +1125,31 @@ DNS2=5.6.7.8
bond_data = self.get_linux_bond_config('bond1')
self.assertEqual(_NM_CONTROLLED_BOND, bond_data)
def test_network_sriov_vf(self):
def test_network_sriov_vf_without_config(self):
nic_mapping = {'nic1': 'eth0', 'nic2': 'eth1', 'nic3': 'eth2'}
self.stubbed_mapped_nics = nic_mapping
addresses = [objects.Address('10.0.0.30/24')]
vf = objects.SriovVF(device='nic3', vfid=7, addresses=addresses)
def test_get_vf_devname(device, vfid, noop):
self.assertEqual(device, 'eth2')
def test_update_sriov_vf_map(pf_name, vfid, vf_name, vlan_id=None,
qos=None, spoofcheck=None, trust=None,
state=None, macaddr=None, promisc=None):
self.assertEqual(pf_name, 'eth2')
self.assertEqual(vfid, 7)
return 'eth2_7'
self.assertEqual(vlan_id, 0)
self.assertEqual(qos, 0)
self.assertEqual(spoofcheck, None)
self.assertEqual(trust, None)
self.assertEqual(state, None)
self.assertEqual(macaddr, None)
self.stub_out('os_net_config.utils.update_sriov_vf_map',
test_update_sriov_vf_map)
def test_get_vf_devname(device, vfid):
return device + '_' + str(vfid)
self.stub_out('os_net_config.utils.get_vf_devname',
test_get_vf_devname)
vf = objects.SriovVF(device='nic3', vfid=7, addresses=addresses)
self.provider.add_sriov_vf(vf)
vf_config = """# This file is autogenerated by os-net-config
DEVICE=eth2_7
@ -1145,15 +1163,152 @@ NETMASK=255.255.255.0
"""
self.assertEqual(vf_config, self.get_interface_config('eth2_7'))
def test_network_sriov_pf(self):
def test_network_sriov_vf_true(self):
nic_mapping = {'nic1': 'eth0', 'nic2': 'eth1', 'nic3': 'eth2'}
self.stubbed_mapped_nics = nic_mapping
addresses = [objects.Address('10.0.0.30/24')]
def test_update_sriov_vf_map(pf_name, vfid, vf_name, vlan_id=None,
qos=None, spoofcheck=None, trust=None,
state=None, macaddr=None, promisc=None):
self.assertEqual(pf_name, 'eth2')
self.assertEqual(vf_name, 'eth2_7')
self.assertEqual(vfid, 7)
self.assertEqual(vlan_id, 100)
self.assertEqual(qos, 10)
self.assertTrue(spoofcheck)
self.assertTrue(trust)
self.assertEqual(state, "auto")
self.assertEqual(macaddr, "AA:BB:CC:DD:EE:FF")
self.assertTrue(promisc)
self.stub_out('os_net_config.utils.update_sriov_vf_map',
test_update_sriov_vf_map)
def test_get_vf_devname(device, vfid):
return device + '_' + str(vfid)
self.stub_out('os_net_config.utils.get_vf_devname',
test_get_vf_devname)
vf = objects.SriovVF(device='nic3', vfid=7, addresses=addresses,
vlan_id='100', qos='10', spoofcheck=True,
trust=True, state="auto",
macaddr="AA:BB:CC:DD:EE:FF", promisc=True)
self.provider.add_sriov_vf(vf)
vf_config = """# This file is autogenerated by os-net-config
DEVICE=eth2_7
ONBOOT=yes
HOTPLUG=no
NM_CONTROLLED=no
PEERDNS=no
BOOTPROTO=static
IPADDR=10.0.0.30
NETMASK=255.255.255.0
"""
self.assertEqual(vf_config, self.get_interface_config('eth2_7'))
def test_network_sriov_vf_config_false(self):
nic_mapping = {'nic1': 'eth0', 'nic2': 'eth1', 'nic3': 'eth2'}
self.stubbed_mapped_nics = nic_mapping
addresses = [objects.Address('10.0.0.30/24')]
def test_update_sriov_vf_map(pf_name, vfid, vf_name, vlan_id=None,
qos=None, spoofcheck=None, trust=None,
state=None, macaddr=None, promisc=None):
self.assertEqual(pf_name, 'eth2')
self.assertEqual(vf_name, 'eth2_7')
self.assertEqual(vfid, 7)
self.assertEqual(vlan_id, 100)
self.assertEqual(qos, 10)
self.assertFalse(spoofcheck)
self.assertFalse(trust)
self.assertEqual(state, "enable")
self.assertEqual(macaddr, "AA:BB:CC:DD:EE:FF")
self.assertFalse(promisc)
self.stub_out('os_net_config.utils.update_sriov_vf_map',
test_update_sriov_vf_map)
def test_get_vf_devname(device, vfid):
return device + '_' + str(vfid)
self.stub_out('os_net_config.utils.get_vf_devname',
test_get_vf_devname)
vf = objects.SriovVF(device='nic3', vfid=7, addresses=addresses,
vlan_id='100', qos='10', spoofcheck=False,
trust=False, state="enable",
macaddr="AA:BB:CC:DD:EE:FF", promisc=False)
self.provider.add_sriov_vf(vf)
vf_config = """# This file is autogenerated by os-net-config
DEVICE=eth2_7
ONBOOT=yes
HOTPLUG=no
NM_CONTROLLED=no
PEERDNS=no
BOOTPROTO=static
IPADDR=10.0.0.30
NETMASK=255.255.255.0
"""
self.assertEqual(vf_config, self.get_interface_config('eth2_7'))
def test_network_sriov_pf_without_promisc(self):
nic_mapping = {'nic1': 'eth0', 'nic2': 'eth1', 'nic3': 'eth2'}
self.stubbed_mapped_nics = nic_mapping
pf = objects.SriovPF(name='nic3', numvfs=10)
def test_update_sriov_pf_map(name, numvfs, noop):
def test_update_sriov_pf_map(name, numvfs, noop, promisc=None):
self.assertEqual(name, 'eth2')
self.assertEqual(numvfs, 10)
self.assertEqual(promisc, None)
self.stub_out('os_net_config.utils.update_sriov_pf_map',
test_update_sriov_pf_map)
self.provider.add_sriov_pf(pf)
pf_config = """# This file is autogenerated by os-net-config
DEVICE=eth2
ONBOOT=yes
HOTPLUG=no
NM_CONTROLLED=no
PEERDNS=no
BOOTPROTO=none
"""
self.assertEqual(pf_config, self.get_interface_config('eth2'))
def test_network_sriov_pf_with_promisc_on(self):
nic_mapping = {'nic1': 'eth0', 'nic2': 'eth1', 'nic3': 'eth2'}
self.stubbed_mapped_nics = nic_mapping
pf = objects.SriovPF(name='nic3', numvfs=10, promisc=True)
def test_update_sriov_pf_map(name, numvfs, noop, promisc=None):
self.assertEqual(name, 'eth2')
self.assertEqual(numvfs, 10)
self.assertTrue(promisc)
self.stub_out('os_net_config.utils.update_sriov_pf_map',
test_update_sriov_pf_map)
self.provider.add_sriov_pf(pf)
pf_config = """# This file is autogenerated by os-net-config
DEVICE=eth2
ONBOOT=yes
HOTPLUG=no
NM_CONTROLLED=no
PEERDNS=no
BOOTPROTO=none
"""
self.assertEqual(pf_config, self.get_interface_config('eth2'))
def test_network_sriov_pf_with_promisc_off(self):
nic_mapping = {'nic1': 'eth0', 'nic2': 'eth1', 'nic3': 'eth2'}
self.stubbed_mapped_nics = nic_mapping
pf = objects.SriovPF(name='nic3', numvfs=10, promisc=False)
def test_update_sriov_pf_map(name, numvfs, noop, promisc=None):
self.assertEqual(name, 'eth2')
self.assertEqual(numvfs, 10)
self.assertFalse(promisc)
self.stub_out('os_net_config.utils.update_sriov_pf_map',
test_update_sriov_pf_map)
self.provider.add_sriov_pf(pf)

View File

@ -1210,10 +1210,11 @@ class TestSriovPF(base.TestCase):
def test_from_json_numvfs(self):
data = '{"type": "sriov_pf", "name": "em1", "numvfs": 16,' \
'"use_dhcp": false}'
'"use_dhcp": false, "promisc": false}'
pf = objects.object_from_json(json.loads(data))
self.assertEqual("em1", pf.name)
self.assertEqual(16, pf.numvfs)
self.assertEqual("off", pf.promisc)
self.assertFalse(pf.use_dhcp)
def test_from_json_numvfs_nic1(self):
@ -1221,37 +1222,148 @@ class TestSriovPF(base.TestCase):
return {"nic1": "em4"}
self.stub_out('os_net_config.objects.mapped_nics', dummy_mapped_nics)
data = '{"type": "sriov_pf", "name": "nic1", "numvfs": 16,' \
'"use_dhcp": false, "promisc": true}'
pf = objects.object_from_json(json.loads(data))
self.assertEqual("em4", pf.name)
self.assertEqual(16, pf.numvfs)
self.assertFalse(pf.use_dhcp)
self.assertEqual('on', pf.promisc)
def test_from_json_without_promisc(self):
def dummy_mapped_nics(nic_mapping=None):
return {"nic1": "em4"}
self.stub_out('os_net_config.objects.mapped_nics', dummy_mapped_nics)
data = '{"type": "sriov_pf", "name": "nic1", "numvfs": 16,' \
'"use_dhcp": false}'
pf = objects.object_from_json(json.loads(data))
self.assertEqual("em4", pf.name)
self.assertEqual(16, pf.numvfs)
self.assertFalse(pf.use_dhcp)
self.assertEqual(None, pf.promisc)
class TestSriovVF(base.TestCase):
def setUp(self):
super(TestSriovVF, self).setUp()
def tearDown(self):
super(TestSriovVF, self).tearDown()
def test_from_json_vfid(self):
def test_get_vf_devname(device, vfid):
return device + '_' + str(vfid)
self.stub_out('os_net_config.utils.get_vf_devname',
test_get_vf_devname)
data = '{"type": "sriov_vf", "device": "em1", "vfid": 16,' \
'"use_dhcp": false}'
vf = objects.object_from_json(json.loads(data))
self.assertEqual("em1", vf.device)
self.assertEqual(16, vf.vfid)
self.assertFalse(vf.use_dhcp)
self.assertEqual("", vf.name)
self.assertEqual("em1_16", vf.name)
def test_from_json_name_ignored(self):
def test_get_vf_devname(device, vfid):
return device + '_' + str(vfid)
self.stub_out('os_net_config.utils.get_vf_devname',
test_get_vf_devname)
data = '{"type": "sriov_vf", "device": "em1", "vfid": 16,' \
'"use_dhcp": false, "name": "em1_16"}'
'"use_dhcp": false, "name": "em1_7"}'
vf = objects.object_from_json(json.loads(data))
self.assertEqual("em1", vf.device)
self.assertEqual(16, vf.vfid)
self.assertFalse(vf.use_dhcp)
self.assertEqual("", vf.name)
self.assertEqual("em1_16", vf.name)
def test_from_json_vfid_configs_enabled(self):
def test_get_vf_devname(device, vfid):
return device + '_' + str(vfid)
self.stub_out('os_net_config.utils.get_vf_devname',
test_get_vf_devname)
data = '{"type": "sriov_vf", "device": "em4", "vfid": 16,' \
'"use_dhcp": false, "vlan_id": 100, "qos": 2, "trust": true,' \
'"state": "auto", "spoofcheck": true,' \
'"macaddr":"AA:BB:CC:DD:EE:FF", "promisc": true}'
vf = objects.object_from_json(json.loads(data))
self.assertEqual("em4", vf.device)
self.assertEqual(16, vf.vfid)
self.assertFalse(vf.use_dhcp)
self.assertEqual("em4_16", vf.name)
self.assertEqual(100, vf.vlan_id)
self.assertEqual(2, vf.qos)
self.assertEqual("on", vf.spoofcheck)
self.assertEqual("on", vf.trust)
self.assertEqual("auto", vf.state)
self.assertEqual("AA:BB:CC:DD:EE:FF", vf.macaddr)
self.assertEqual("on", vf.promisc)
def test_from_json_vfid_configs_disabled(self):
def test_get_vf_devname(device, vfid):
return device + '_' + str(vfid)
self.stub_out('os_net_config.utils.get_vf_devname',
test_get_vf_devname)
data = '{"type": "sriov_vf", "device": "em4", "vfid": 16,' \
'"use_dhcp": false, "vlan_id": 0, "qos": 0, "trust": false,' \
'"state": "disable", "spoofcheck": false,' \
'"promisc": false}'
vf = objects.object_from_json(json.loads(data))
self.assertEqual("em4", vf.device)
self.assertEqual(16, vf.vfid)
self.assertFalse(vf.use_dhcp)
self.assertEqual("em4_16", vf.name)
self.assertEqual(0, vf.vlan_id)
self.assertEqual(0, vf.qos)
self.assertEqual("off", vf.spoofcheck)
self.assertEqual("off", vf.trust)
self.assertEqual("disable", vf.state)
self.assertEqual(None, vf.macaddr)
self.assertEqual("off", vf.promisc)
def test_from_json_vfid_invalid_state(self):
def test_get_vf_devname(device, vfid):
return device + '_' + str(vfid)
self.stub_out('os_net_config.utils.get_vf_devname',
test_get_vf_devname)
data = '{"type": "sriov_vf", "device": "em4", "vfid": 16,' \
'"use_dhcp": false, "vlan_id": 0, "qos": 0, "trust": false,' \
'"state": "disabled", ' \
'"promisc": false}'
err = self.assertRaises(objects.InvalidConfigException,
objects.object_from_json,
json.loads(data))
expected = 'Expecting state to match auto/enable/disable'
self.assertIn(expected, six.text_type(err))
def test_from_json_vfid_invalid_qos(self):
def test_get_vf_devname(device, vfid):
return device + '_' + str(vfid)
self.stub_out('os_net_config.utils.get_vf_devname',
test_get_vf_devname)
data = '{"type": "sriov_vf", "device": "em4", "vfid": 16,' \
'"use_dhcp": false, "vlan_id": 0, "qos": 10, "trust": false,' \
'"promisc": false}'
err = self.assertRaises(objects.InvalidConfigException,
objects.object_from_json,
json.loads(data))
expected = 'Vlan tag not set for QOS - VF: em4:16'
self.assertIn(expected, six.text_type(err))
def test_from_json_vfid_nic1(self):
def test_get_vf_devname(device, vfid):
return device + '_' + str(vfid)
self.stub_out('os_net_config.utils.get_vf_devname',
test_get_vf_devname)
def dummy_mapped_nics(nic_mapping=None):
return {"nic1": "em4"}
self.stub_out('os_net_config.objects.mapped_nics', dummy_mapped_nics)
data = '{"type": "sriov_vf", "device": "nic1", "vfid": 16,' \
@ -1260,7 +1372,7 @@ class TestSriovVF(base.TestCase):
self.assertEqual("em4", vf.device)
self.assertEqual(16, vf.vfid)
self.assertFalse(vf.use_dhcp)
self.assertEqual("", vf.name)
self.assertEqual("em4_16", vf.name)
class TestOvsDpdkBond(base.TestCase):

View File

@ -23,6 +23,7 @@ import tempfile
import yaml
from os_net_config import objects
from os_net_config import sriov_config
from os_net_config.tests import base
from os_net_config import utils
@ -81,14 +82,14 @@ class TestUtils(base.TestCase):
super(TestUtils, self).setUp()
rand = str(int(random.random() * 100000))
utils._DPDK_MAPPING_FILE = '/tmp/dpdk_mapping_' + rand + '.yaml'
utils._SRIOV_PF_CONFIG_FILE = '/tmp/sriov_pf_' + rand + '.yaml'
sriov_config._SRIOV_CONFIG_FILE = '/tmp/sriov_config_' + rand + '.yaml'
def tearDown(self):
super(TestUtils, self).tearDown()
if os.path.isfile(utils._DPDK_MAPPING_FILE):
os.remove(utils._DPDK_MAPPING_FILE)
if os.path.isfile(utils._SRIOV_PF_CONFIG_FILE):
os.remove(utils._SRIOV_PF_CONFIG_FILE)
if os.path.isfile(sriov_config._SRIOV_CONFIG_FILE):
os.remove(sriov_config._SRIOV_CONFIG_FILE)
def test_ordered_active_nics(self):
@ -119,30 +120,126 @@ class TestUtils(base.TestCase):
def test_update_sriov_pf_map_new(self):
utils.update_sriov_pf_map('eth1', 10, False)
contents = utils.get_file_data(utils._SRIOV_PF_CONFIG_FILE)
contents = utils.get_file_data(sriov_config._SRIOV_CONFIG_FILE)
sriov_pf_map = yaml.load(contents) if contents else []
self.assertEqual(1, len(sriov_pf_map))
test_sriov_pf_map = [{'name': 'eth1', 'numvfs': 10}]
test_sriov_pf_map = [{'device_type': 'pf', 'name': 'eth1',
'numvfs': 10}]
self.assertListEqual(test_sriov_pf_map, sriov_pf_map)
def test_update_sriov_pf_map_new_with_promisc(self):
utils.update_sriov_pf_map('eth1', 10, False, promisc='off')
contents = utils.get_file_data(sriov_config._SRIOV_CONFIG_FILE)
sriov_pf_map = yaml.load(contents) if contents else []
self.assertEqual(1, len(sriov_pf_map))
test_sriov_pf_map = [{'device_type': 'pf', 'name': 'eth1',
'numvfs': 10, 'promisc': 'off'}]
self.assertListEqual(test_sriov_pf_map, sriov_pf_map)
def test_update_sriov_pf_map_exist(self):
pf_initial = [{'name': 'eth1', 'numvfs': 10}]
utils.write_yaml_config(utils._SRIOV_PF_CONFIG_FILE, pf_initial)
pf_initial = [{'device_type': 'pf', 'name': 'eth1', 'numvfs': 10}]
utils.write_yaml_config(sriov_config._SRIOV_CONFIG_FILE, pf_initial)
utils.update_sriov_pf_map('eth1', 20, False)
pf_final = [{'name': 'eth1', 'numvfs': 20}]
contents = utils.get_file_data(utils._SRIOV_PF_CONFIG_FILE)
pf_final = [{'device_type': 'pf', 'name': 'eth1', 'numvfs': 20}]
contents = utils.get_file_data(sriov_config._SRIOV_CONFIG_FILE)
pf_map = yaml.load(contents) if contents else []
self.assertEqual(1, len(pf_map))
self.assertListEqual(pf_final, pf_map)
def test_update_sriov_pf_map_exist_with_promisc(self):
pf_initial = [{'device_type': 'pf', 'name': 'eth1', 'numvfs': 10,
'promisc': 'on'}]
utils.write_yaml_config(sriov_config._SRIOV_CONFIG_FILE, pf_initial)
utils.update_sriov_pf_map('eth1', 20, False)
pf_final = [{'device_type': 'pf', 'name': 'eth1', 'numvfs': 20,
'promisc': 'on'}]
contents = utils.get_file_data(sriov_config._SRIOV_CONFIG_FILE)
pf_map = yaml.load(contents) if contents else []
self.assertEqual(1, len(pf_map))
self.assertListEqual(pf_final, pf_map)
def test_update_sriov_vf_map_minimal_new(self):
utils.update_sriov_vf_map('eth1', 2, 'eth1_2')
contents = utils.get_file_data(sriov_config._SRIOV_CONFIG_FILE)
sriov_vf_map = yaml.load(contents) if contents else []
self.assertEqual(1, len(sriov_vf_map))
test_sriov_vf_map = [{'device_type': 'vf', 'name': 'eth1_2',
'device': {"name": "eth1", "vfid": 2}}]
self.assertListEqual(test_sriov_vf_map, sriov_vf_map)
def test_update_sriov_vf_map_complete_new(self):
utils.update_sriov_vf_map('eth1', 2, 'eth1_2', vlan_id=10, qos=5,
spoofcheck="on", trust="on", state="enable",
macaddr="AA:BB:CC:DD:EE:FF", promisc="off")
contents = utils.get_file_data(sriov_config._SRIOV_CONFIG_FILE)
sriov_vf_map = yaml.load(contents) if contents else []
self.assertEqual(1, len(sriov_vf_map))
test_sriov_vf_map = [{'device_type': 'vf', 'name': 'eth1_2',
'device': {'name': 'eth1', 'vfid': 2},
'vlan_id': 10, 'qos': 5,
'spoofcheck': 'on', 'trust': 'on',
'state': 'enable',
'macaddr': 'AA:BB:CC:DD:EE:FF',
'promisc': 'off'}]
self.assertListEqual(test_sriov_vf_map, sriov_vf_map)
def test_update_sriov_vf_map_exist(self):
vf_initial = [{'device_type': 'vf', 'name': 'eth1_2',
'device': {"name": "eth1", "vfid": 2}}]
utils.write_yaml_config(sriov_config._SRIOV_CONFIG_FILE, vf_initial)
utils.update_sriov_vf_map('eth1', 2, 'eth1_2', vlan_id=10, qos=5,
spoofcheck="on", trust="on", state="enable",
macaddr="AA:BB:CC:DD:EE:FF", promisc="off")
vf_final = [{'device_type': 'vf', 'name': 'eth1_2',
'device': {'name': 'eth1', 'vfid': 2},
'vlan_id': 10, 'qos': 5,
'spoofcheck': 'on', 'trust': 'on',
'state': 'enable',
'macaddr': 'AA:BB:CC:DD:EE:FF',
'promisc': 'off'}]
contents = utils.get_file_data(sriov_config._SRIOV_CONFIG_FILE)
vf_map = yaml.load(contents) if contents else []
self.assertEqual(1, len(vf_map))
self.assertListEqual(vf_final, vf_map)
def test_update_sriov_vf_map_exist_complete(self):
vf_initial = [{'device_type': 'vf', 'name': 'eth1_2',
'device': {'name': 'eth1', 'vfid': 2},
'vlan_id': 10, 'qos': 5,
'spoofcheck': 'on', 'trust': 'on',
'state': 'enable',
'macaddr': 'AA:BB:CC:DD:EE:FF',
'promisc': 'off'}]
utils.write_yaml_config(sriov_config._SRIOV_CONFIG_FILE, vf_initial)
utils.update_sriov_vf_map('eth1', 2, 'eth1_2', vlan_id=100, qos=15,
spoofcheck="off", trust="off", state="auto",
macaddr="BB:BB:CC:DD:EE:FF", promisc="on")
vf_final = [{'device_type': 'vf', 'name': 'eth1_2',
'device': {'name': 'eth1', 'vfid': 2},
'vlan_id': 100, 'qos': 15,
'spoofcheck': 'off', 'trust': 'off',
'state': 'auto',
'macaddr': 'BB:BB:CC:DD:EE:FF',
'promisc': 'on'}]
contents = utils.get_file_data(sriov_config._SRIOV_CONFIG_FILE)
vf_map = yaml.load(contents) if contents else []
self.assertEqual(1, len(vf_map))
self.assertListEqual(vf_final, vf_map)
def test_get_vf_devname_net_dir_not_found(self):
tmpdir = tempfile.mkdtemp()
self.stub_out('os_net_config.utils._SYS_CLASS_NET', tmpdir)
self.assertRaises(utils.SriovVfNotFoundException,
utils.get_vf_devname, "eth1", 1, False)
utils.get_vf_devname, "eth1", 1)
shutil.rmtree(tmpdir)
def test_get_vf_devname_vf_dir_not_found(self):
@ -153,7 +250,7 @@ class TestUtils(base.TestCase):
os.makedirs(vf_path)
self.assertRaises(utils.SriovVfNotFoundException,
utils.get_vf_devname, "eth1", 1, False)
utils.get_vf_devname, "eth1", 1)
shutil.rmtree(tmpdir)
def test_get_vf_devname_vf_dir_found(self):
@ -164,7 +261,7 @@ class TestUtils(base.TestCase):
'eth1/device/virtfn1/net/eth1_1')
os.makedirs(vf_path)
self.assertEqual(utils.get_vf_devname("eth1", 1, False), "eth1_1")
self.assertEqual(utils.get_vf_devname("eth1", 1), "eth1_1")
shutil.rmtree(tmpdir)
def test_get_pci_address_success(self):

View File

@ -35,16 +35,9 @@ _SYS_CLASS_NET = '/sys/class/net'
# mac_address: 01:02:03:04:05:06
# driver: vfio-pci
_DPDK_MAPPING_FILE = '/var/lib/os-net-config/dpdk_mapping.yaml'
# File to contain the list of SR-IOV nics and the numvfs
# Format of the file shall be
#
# - name: eth1
# numvfs: 5
_SRIOV_PF_CONFIG_FILE = '/var/lib/os-net-config/sriov_pf.yaml'
# sriov_numvfs service shall be configured so that the numvfs for each of the
# SR-IOV PF device shall be configured during reboot as well
# sriov_config service shall be created and enabled so that the various
# SR-IOV PF and VF configurations shall be done during reboot as well using
# sriov_config.py installed in path /usr/bin/os-net-config-sriov
_SRIOV_CONFIG_SERVICE_FILE = "/etc/systemd/system/sriov_config.service"
_SRIOV_CONFIG_DEVICE_CONTENT = """[Unit]
Description=SR-IOV numvfs configuration
@ -420,28 +413,76 @@ def _get_dpdk_mac_address(name):
return item['mac_address']
def update_sriov_pf_map(ifname, numvfs, noop):
def update_sriov_pf_map(ifname, numvfs, noop, promisc=None):
if not noop:
sriov_map = _get_sriov_pf_map()
sriov_map = _get_sriov_map()
for item in sriov_map:
if item['name'] == ifname:
if item['device_type'] == 'pf' and item['name'] == ifname:
item['numvfs'] = numvfs
if promisc is not None:
item['promisc'] = promisc
break
else:
new_item = {}
new_item['device_type'] = 'pf'
new_item['name'] = ifname
new_item['numvfs'] = numvfs
if promisc is not None:
new_item['promisc'] = promisc
sriov_map.append(new_item)
write_yaml_config(_SRIOV_PF_CONFIG_FILE, sriov_map)
write_yaml_config(sriov_config._SRIOV_CONFIG_FILE, sriov_map)
def _get_sriov_pf_map():
contents = get_file_data(_SRIOV_PF_CONFIG_FILE)
def _get_sriov_map():
contents = get_file_data(sriov_config._SRIOV_CONFIG_FILE)
sriov_map = yaml.load(contents) if contents else []
return sriov_map
def _set_vf_fields(vf_name, vlan_id, qos, spoofcheck, trust, state, macaddr,
promisc):
vf_configs = {}
vf_configs['name'] = vf_name
if vlan_id != 0:
vf_configs['vlan_id'] = vlan_id
if qos != 0:
vf_configs['qos'] = qos
if spoofcheck is not None:
vf_configs['spoofcheck'] = spoofcheck
if trust is not None:
vf_configs['trust'] = trust
if state is not None:
vf_configs['state'] = state
if macaddr is not None:
vf_configs['macaddr'] = macaddr
if promisc is not None:
vf_configs['promisc'] = promisc
return vf_configs
def update_sriov_vf_map(pf_name, vfid, vf_name, vlan_id=0, qos=0,
spoofcheck=None, trust=None, state=None, macaddr=None,
promisc=None):
sriov_map = _get_sriov_map()
for item in sriov_map:
if (item['device_type'] == 'vf' and
item['device'].get('name') == pf_name and
item['device'].get('vfid') == vfid):
item.update(_set_vf_fields(vf_name, vlan_id, qos, spoofcheck,
trust, state, macaddr, promisc))
break
else:
new_item = {}
new_item['device_type'] = 'vf'
new_item['device'] = {"name": pf_name, "vfid": vfid}
new_item.update(_set_vf_fields(vf_name, vlan_id, qos, spoofcheck,
trust, state, macaddr, promisc))
sriov_map.append(new_item)
write_yaml_config(sriov_config._SRIOV_CONFIG_FILE, sriov_map)
def _configure_sriov_config_service():
"""Generate the sriov_config.service
@ -455,14 +496,16 @@ def _configure_sriov_config_service():
def configure_sriov_pfs():
logger.info("Configuring PFs now")
sriov_config.main()
sriov_config.configure_sriov_pf()
_configure_sriov_config_service()
def get_vf_devname(pf_name, vfid, noop):
if noop:
logger.info("NOOP: returning VF name as %s_%d" % (pf_name, vfid))
return "%s_%d" % (pf_name, vfid)
def configure_sriov_vfs():
logger.info("Configuring VFs now")
sriov_config.configure_sriov_vf()
def get_vf_devname(pf_name, vfid):
vf_path = os.path.join(_SYS_CLASS_NET, pf_name, "device/virtfn%d/net"
% vfid)
if os.path.isdir(vf_path):

View File

@ -6,8 +6,9 @@ anyjson>=0.3.3 # BSD
six>=1.9.0 # MIT
eventlet!=0.18.3,>=0.18.2 # MIT
iso8601>=0.1.11 # MIT
netaddr>=0.7.13 #BSD
netaddr>=0.7.13 # BSD
oslo.concurrency>=3.8.0 # Apache-2.0
oslo.utils>=3.20.0 # Apache-2.0
PyYAML>=3.10.0 # MIT
jsonschema>=2.0.0,<3.0.0 # MIT
pyudev>=0.15