Add sriov_vf type as member of ovs_dpdk_port
SR-IOV VF shall be bound to DPDK driver and added to ovs_user_bridge Implements: blueprint sriov-vfs-as-network-interface Change-Id: Ia212ed153f4feb1e3a7fb48be95c1db63ee4b6f7
This commit is contained in:
parent
420cdede7a
commit
d7436493aa
|
@ -0,0 +1,51 @@
|
|||
{
|
||||
"network_config": [
|
||||
{
|
||||
"type": "sriov_pf",
|
||||
"name": "p2p1",
|
||||
"numvfs": 10,
|
||||
"use_dhcp": false,
|
||||
"promisc": on
|
||||
},
|
||||
{
|
||||
"type": "sriov_vf",
|
||||
"device": "p2p1",
|
||||
"vfid": 5,
|
||||
"addresses": [
|
||||
{
|
||||
"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
|
||||
},
|
||||
{
|
||||
"name": "br-vfs",
|
||||
"type": "ovs_user_bridge",
|
||||
"use_dhcp": false,
|
||||
"members": [
|
||||
{
|
||||
"name": "dpdk0",
|
||||
"type": "ovs_dpdk_port",
|
||||
"members": [
|
||||
{
|
||||
"device": "p5p2",
|
||||
"qos": 2,
|
||||
"spoofcheck": false,
|
||||
"trust": true,
|
||||
"type": "sriov_vf",
|
||||
"vfid": 1,
|
||||
"vlan_id": 116
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
|
||||
|
||||
network_config:
|
||||
# sriov_pf type shall be used to configure the PF's of NICs.
|
||||
# The numvfs configured for the PF's shall be set on the sriov_numvfs of the
|
||||
# sysfs for the corresponding NIC and the persistence of the same across reboots
|
||||
# shall be handled
|
||||
-
|
||||
type: sriov_pf
|
||||
# nic name or nic number of the NIC that needs to be configured for SRIOV
|
||||
name: p2p1
|
||||
# number of VFs required on the particular NIC
|
||||
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
|
||||
# "name" parameter is not required for VF's. It'll be derived from the VF id
|
||||
# and the PF device name.
|
||||
- type: sriov_vf
|
||||
# The PF device needs to be configured via the sriov_pf type
|
||||
# the PF device could be a nic number (ex: nic5) or nic name (ex: ens20f0)
|
||||
device: p2p1
|
||||
# The VF id shall be the VF number between 0 to (numvfs-1), where numvfs
|
||||
# is the member of the sriov_pf type
|
||||
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 user bridge
|
||||
- type: ovs_user_bridge
|
||||
name: br-vfs
|
||||
use_dhcp: false
|
||||
members:
|
||||
- type: ovs_dpdk_port
|
||||
name: dpdk0
|
||||
members:
|
||||
# Specify the type
|
||||
- type: sriov_vf
|
||||
# Required field
|
||||
device: p5p2
|
||||
# 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_user_bridge
|
||||
trust: on
|
||||
# Set spoofcheck to 'off' when attaching to ovs_user_bridge
|
||||
spoofcheck: off
|
||||
# Note: Do not set promisc mode.
|
|
@ -1079,7 +1079,8 @@ class OvsDpdkPort(_BaseOpts):
|
|||
member.update({'nic_mapping': nic_mapping})
|
||||
member.update({'persist_mapping': persist_mapping})
|
||||
iface = object_from_json(member)
|
||||
if isinstance(iface, Interface):
|
||||
if (isinstance(iface, Interface) or
|
||||
isinstance(iface, SriovVF)):
|
||||
# TODO(skramaja): Add checks for IP and route not to
|
||||
# be set in the interface part of DPDK Port
|
||||
members.append(iface)
|
||||
|
|
|
@ -711,7 +711,9 @@ definitions:
|
|||
members:
|
||||
type: array
|
||||
items:
|
||||
- $ref: "#/definitions/interface"
|
||||
oneof:
|
||||
- $ref: "#/definitions/interface"
|
||||
- $ref: "#/definitions/sriov_vf"
|
||||
minItems: 1
|
||||
maxItems: 1
|
||||
primary:
|
||||
|
|
|
@ -219,7 +219,34 @@ class TestCli(base.TestCase):
|
|||
self.assertEqual('', stderr)
|
||||
sanity_devices = ['DEVICE=p2p1',
|
||||
'DEVICE=p2p1_5',
|
||||
'DEVICE=p2p1_1']
|
||||
'DEVICE=p2p1_1',
|
||||
'DEVICE=br-vfs',
|
||||
'TYPE=OVSBridge']
|
||||
for dev in sanity_devices:
|
||||
self.assertIn(dev, stdout_yaml)
|
||||
self.assertEqual(stdout_yaml, stdout_json)
|
||||
|
||||
def test_sriov_vf_with_dpdk_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_ovs_dpdk.yaml')
|
||||
ivs_json = os.path.join(SAMPLE_BASE, 'sriov_pf_ovs_dpdk.json')
|
||||
stdout_yaml, stderr = self.run_cli('ARG0 --provider=ifcfg --noop '
|
||||
'--exit-on-validation-errors '
|
||||
'-c %s' % ivs_yaml)
|
||||
self.assertEqual('', stderr)
|
||||
stdout_json, stderr = self.run_cli('ARG0 --provider=ifcfg --noop '
|
||||
'--exit-on-validation-errors '
|
||||
'-c %s' % ivs_json)
|
||||
self.assertEqual('', stderr)
|
||||
sanity_devices = ['DEVICE=p2p1',
|
||||
'DEVICE=p2p1_5',
|
||||
'DEVICE=br-vfs',
|
||||
'TYPE=OVSUserBridge',
|
||||
'DEVICE=dpdk0',
|
||||
'TYPE=OVSDPDKPort']
|
||||
for dev in sanity_devices:
|
||||
self.assertIn(dev, stdout_yaml)
|
||||
self.assertEqual(stdout_yaml, stdout_json)
|
||||
|
|
|
@ -242,11 +242,31 @@ class TestUtils(base.TestCase):
|
|||
utils.get_vf_devname, "eth1", 1)
|
||||
shutil.rmtree(tmpdir)
|
||||
|
||||
def test_get_vf_devname_vf_dir_found_in_map(self):
|
||||
tmpdir = tempfile.mkdtemp()
|
||||
self.stub_out('os_net_config.utils._SYS_CLASS_NET', tmpdir)
|
||||
|
||||
def test_get_vf_name_from_map(pf_name, vfid):
|
||||
return pf_name + '_' + str(vfid)
|
||||
self.stub_out('os_net_config.utils._get_vf_name_from_map',
|
||||
test_get_vf_name_from_map)
|
||||
|
||||
vf_path = os.path.join(utils._SYS_CLASS_NET, 'eth1/device/virtfn1')
|
||||
os.makedirs(vf_path)
|
||||
|
||||
self.assertEqual(utils.get_vf_devname("eth1", 1), "eth1_1")
|
||||
shutil.rmtree(tmpdir)
|
||||
|
||||
def test_get_vf_devname_vf_dir_not_found(self):
|
||||
tmpdir = tempfile.mkdtemp()
|
||||
self.stub_out('os_net_config.utils._SYS_CLASS_NET', tmpdir)
|
||||
|
||||
vf_path = os.path.join(utils._SYS_CLASS_NET, 'eth1/device/virtfn1/net')
|
||||
def test_get_vf_name_from_map(pf_name, vfid):
|
||||
return None
|
||||
self.stub_out('os_net_config.utils._get_vf_name_from_map',
|
||||
test_get_vf_name_from_map)
|
||||
|
||||
vf_path = os.path.join(utils._SYS_CLASS_NET, 'eth1/device/virtfn1')
|
||||
os.makedirs(vf_path)
|
||||
|
||||
self.assertRaises(utils.SriovVfNotFoundException,
|
||||
|
|
|
@ -483,6 +483,15 @@ def update_sriov_vf_map(pf_name, vfid, vf_name, vlan_id=0, qos=0,
|
|||
write_yaml_config(sriov_config._SRIOV_CONFIG_FILE, sriov_map)
|
||||
|
||||
|
||||
def _get_vf_name_from_map(pf_name, vfid):
|
||||
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):
|
||||
return item['name']
|
||||
|
||||
|
||||
def _configure_sriov_config_service():
|
||||
"""Generate the sriov_config.service
|
||||
|
||||
|
@ -511,8 +520,15 @@ def get_vf_devname(pf_name, vfid):
|
|||
if os.path.isdir(vf_path):
|
||||
vf_nic = os.listdir(vf_path)
|
||||
else:
|
||||
msg = "NIC %s with VF id: %d could not be found" % (pf_name, vfid)
|
||||
raise SriovVfNotFoundException(msg)
|
||||
# if VF devices are bound with other drivers (DPDK) then the path
|
||||
# doesn't exist. In such cases let us retrieve the vf name stored in
|
||||
# the map
|
||||
vf_name = _get_vf_name_from_map(pf_name, vfid)
|
||||
if vf_name is not None:
|
||||
return vf_name
|
||||
else:
|
||||
msg = "NIC %s with VF id: %d could not be found" % (pf_name, vfid)
|
||||
raise SriovVfNotFoundException(msg)
|
||||
if len(vf_nic) != 1:
|
||||
msg = "VF name could not be identified in %s" % vf_path
|
||||
raise SriovVfNotFoundException(msg)
|
||||
|
|
Loading…
Reference in New Issue