Add default VF configs for ovs and ovs_user bridges
OvsBridge requires trust=on and promisc=on for its normal
operation. OvsUserBridge requires trust=on for its normal
operation. Also checks are added to discard any promisc
setting for OvsUserBridge.
Change-Id: I087ece28ea6b3101bb22bfa9b0f208df63b4fb86
Implements: blueprint sriov-vfs-as-network-interface
Signed-off-by: Karthik S <ksundara@redhat.com>
(cherry picked from commit 7194f35c79
)
This commit is contained in:
parent
a3d44b94e0
commit
a884e963e4
|
@ -506,6 +506,8 @@ class OvsBridge(_BaseOpts):
|
||||||
self.ovs_extra = format_ovs_extra(self, ovs_extra)
|
self.ovs_extra = format_ovs_extra(self, ovs_extra)
|
||||||
for member in self.members:
|
for member in self.members:
|
||||||
member.bridge_name = name
|
member.bridge_name = name
|
||||||
|
if isinstance(member, SriovVF):
|
||||||
|
OvsBridge.update_vf_config(member)
|
||||||
if not isinstance(member, OvsTunnel):
|
if not isinstance(member, OvsTunnel):
|
||||||
member.ovs_port = True
|
member.ovs_port = True
|
||||||
if member.primary:
|
if member.primary:
|
||||||
|
@ -517,6 +519,22 @@ class OvsBridge(_BaseOpts):
|
||||||
else:
|
else:
|
||||||
self.primary_interface_name = member.name
|
self.primary_interface_name = member.name
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def update_vf_config(iface):
|
||||||
|
if iface.trust is None:
|
||||||
|
logger.info("Trust is not set for VF %s:%d, defaulting to on"
|
||||||
|
% (iface.device, iface.vfid))
|
||||||
|
iface.trust = "on"
|
||||||
|
if iface.promisc is None:
|
||||||
|
logger.info("Promisc is not set for VF %s:%d, defaulting to on"
|
||||||
|
% (iface.device, iface.vfid))
|
||||||
|
iface.promisc = "on"
|
||||||
|
utils.update_sriov_vf_map(iface.device, iface.vfid, iface.name,
|
||||||
|
vlan_id=iface.vlan_id, qos=iface.qos,
|
||||||
|
spoofcheck=iface.spoofcheck,
|
||||||
|
trust=iface.trust, state=iface.state,
|
||||||
|
macaddr=iface.macaddr, promisc=iface.promisc)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_json(json):
|
def from_json(json):
|
||||||
name = _get_required_field(json, 'name', 'OvsBridge')
|
name = _get_required_field(json, 'name', 'OvsBridge')
|
||||||
|
@ -1040,6 +1058,21 @@ class OvsDpdkPort(_BaseOpts):
|
||||||
self.driver = driver
|
self.driver = driver
|
||||||
self.rx_queue = rx_queue
|
self.rx_queue = rx_queue
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def update_vf_config(iface):
|
||||||
|
if iface.trust is None:
|
||||||
|
logger.info("Trust is not set for VF %s:%d, defaulting to on"
|
||||||
|
% (iface.device, iface.vfid))
|
||||||
|
iface.trust = "on"
|
||||||
|
if iface.promisc is not None:
|
||||||
|
logger.warning("Promisc can't be changed for ovs_dpdk_port")
|
||||||
|
iface.promisc = None
|
||||||
|
utils.update_sriov_vf_map(iface.device, iface.vfid, iface.name,
|
||||||
|
vlan_id=iface.vlan_id, qos=iface.qos,
|
||||||
|
spoofcheck=iface.spoofcheck,
|
||||||
|
trust=iface.trust, state=iface.state,
|
||||||
|
macaddr=iface.macaddr, promisc=iface.promisc)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_json(json):
|
def from_json(json):
|
||||||
name = _get_required_field(json, 'name', 'OvsDpdkPort')
|
name = _get_required_field(json, 'name', 'OvsDpdkPort')
|
||||||
|
@ -1064,11 +1097,14 @@ class OvsDpdkPort(_BaseOpts):
|
||||||
member.update({'nic_mapping': nic_mapping})
|
member.update({'nic_mapping': nic_mapping})
|
||||||
member.update({'persist_mapping': persist_mapping})
|
member.update({'persist_mapping': persist_mapping})
|
||||||
iface = object_from_json(member)
|
iface = object_from_json(member)
|
||||||
if (isinstance(iface, Interface) or
|
if isinstance(iface, Interface):
|
||||||
isinstance(iface, SriovVF)):
|
|
||||||
# TODO(skramaja): Add checks for IP and route not to
|
# TODO(skramaja): Add checks for IP and route not to
|
||||||
# be set in the interface part of DPDK Port
|
# be set in the interface part of DPDK Port
|
||||||
members.append(iface)
|
members.append(iface)
|
||||||
|
elif isinstance(iface, SriovVF):
|
||||||
|
OvsDpdkPort.update_vf_config(iface)
|
||||||
|
members.append(iface)
|
||||||
else:
|
else:
|
||||||
msg = 'OVS DPDK Port should have only interface member'
|
msg = 'OVS DPDK Port should have only interface member'
|
||||||
raise InvalidConfigException(msg)
|
raise InvalidConfigException(msg)
|
||||||
|
|
|
@ -15,10 +15,15 @@
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
import os
|
||||||
|
import random
|
||||||
import six
|
import six
|
||||||
|
import yaml
|
||||||
|
|
||||||
from os_net_config import objects
|
from os_net_config import objects
|
||||||
|
from os_net_config import sriov_config
|
||||||
from os_net_config.tests import base
|
from os_net_config.tests import base
|
||||||
|
from os_net_config import utils
|
||||||
|
|
||||||
|
|
||||||
class TestRoute(base.TestCase):
|
class TestRoute(base.TestCase):
|
||||||
|
@ -301,6 +306,16 @@ class TestVlan(base.TestCase):
|
||||||
|
|
||||||
class TestBridge(base.TestCase):
|
class TestBridge(base.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestBridge, self).setUp()
|
||||||
|
rand = str(int(random.random() * 100000))
|
||||||
|
sriov_config._SRIOV_CONFIG_FILE = '/tmp/sriov_config_' + rand + '.yaml'
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
super(TestBridge, self).tearDown()
|
||||||
|
if os.path.isfile(sriov_config._SRIOV_CONFIG_FILE):
|
||||||
|
os.remove(sriov_config._SRIOV_CONFIG_FILE)
|
||||||
|
|
||||||
def test_from_json_dhcp(self):
|
def test_from_json_dhcp(self):
|
||||||
data = """{
|
data = """{
|
||||||
"type": "ovs_bridge",
|
"type": "ovs_bridge",
|
||||||
|
@ -320,6 +335,174 @@ class TestBridge(base.TestCase):
|
||||||
self.assertTrue(interface1.ovs_port)
|
self.assertTrue(interface1.ovs_port)
|
||||||
self.assertEqual("br-foo", interface1.bridge_name)
|
self.assertEqual("br-foo", interface1.bridge_name)
|
||||||
|
|
||||||
|
def test_ovs_bridge_with_vf_default(self):
|
||||||
|
data = """{
|
||||||
|
"type": "ovs_bridge",
|
||||||
|
"name": "br-foo",
|
||||||
|
"use_dhcp": true,
|
||||||
|
"members": [{
|
||||||
|
"type": "sriov_vf",
|
||||||
|
"device": "em1",
|
||||||
|
"vfid": 1,
|
||||||
|
"vlan_id": 111,
|
||||||
|
"qos": 1,
|
||||||
|
"spoofcheck": false
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
vf_final = [{'device_type': 'vf', 'name': 'em1_1',
|
||||||
|
'device': {'name': 'em1', 'vfid': 1},
|
||||||
|
'vlan_id': 111, 'qos': 1,
|
||||||
|
'spoofcheck': 'off', 'trust': 'on',
|
||||||
|
'promisc': 'on'}]
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
bridge = objects.object_from_json(json.loads(data))
|
||||||
|
self.assertEqual("br-foo", bridge.name)
|
||||||
|
self.assertTrue(bridge.use_dhcp)
|
||||||
|
interface1 = bridge.members[0]
|
||||||
|
self.assertEqual("em1", interface1.device)
|
||||||
|
self.assertTrue(interface1.ovs_port)
|
||||||
|
self.assertEqual("br-foo", interface1.bridge_name)
|
||||||
|
|
||||||
|
contents = utils.get_file_data(sriov_config._SRIOV_CONFIG_FILE)
|
||||||
|
vf_map = yaml.load(contents) if contents else []
|
||||||
|
self.assertListEqual(vf_final, vf_map)
|
||||||
|
|
||||||
|
def test_ovs_bridge_with_vf_param_provided(self):
|
||||||
|
data = """{
|
||||||
|
"type": "ovs_bridge",
|
||||||
|
"name": "br-foo",
|
||||||
|
"use_dhcp": true,
|
||||||
|
"members": [{
|
||||||
|
"type": "sriov_vf",
|
||||||
|
"device": "em1",
|
||||||
|
"vfid": 1,
|
||||||
|
"vlan_id": 111,
|
||||||
|
"qos": 1,
|
||||||
|
"spoofcheck": false,
|
||||||
|
"trust": false,
|
||||||
|
"promisc": false
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
vf_final = [{'device_type': 'vf', 'name': 'em1_1',
|
||||||
|
'device': {'name': 'em1', 'vfid': 1},
|
||||||
|
'vlan_id': 111, 'qos': 1,
|
||||||
|
'spoofcheck': 'off', 'trust': 'off',
|
||||||
|
'promisc': 'off'}]
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
bridge = objects.object_from_json(json.loads(data))
|
||||||
|
self.assertEqual("br-foo", bridge.name)
|
||||||
|
self.assertTrue(bridge.use_dhcp)
|
||||||
|
interface1 = bridge.members[0]
|
||||||
|
self.assertEqual("em1", interface1.device)
|
||||||
|
self.assertTrue(interface1.ovs_port)
|
||||||
|
self.assertEqual("br-foo", interface1.bridge_name)
|
||||||
|
|
||||||
|
contents = utils.get_file_data(sriov_config._SRIOV_CONFIG_FILE)
|
||||||
|
vf_map = yaml.load(contents) if contents else []
|
||||||
|
self.assertListEqual(vf_final, vf_map)
|
||||||
|
|
||||||
|
def test_ovs_user_bridge_with_vf_default(self):
|
||||||
|
data = """{
|
||||||
|
"type": "ovs_user_bridge",
|
||||||
|
"name": "br-foo",
|
||||||
|
"use_dhcp": true,
|
||||||
|
"members": [{
|
||||||
|
"type": "ovs_dpdk_port",
|
||||||
|
"name": "dpdk0",
|
||||||
|
"members": [
|
||||||
|
{
|
||||||
|
"type": "sriov_vf",
|
||||||
|
"device": "em1",
|
||||||
|
"vfid": 1,
|
||||||
|
"vlan_id": 111,
|
||||||
|
"qos": 1,
|
||||||
|
"spoofcheck": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
vf_final = [{'device_type': 'vf', 'name': 'em1_1',
|
||||||
|
'device': {'name': 'em1', 'vfid': 1},
|
||||||
|
'vlan_id': 111, 'qos': 1,
|
||||||
|
'spoofcheck': 'off', 'trust': 'on'
|
||||||
|
}]
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
bridge = objects.object_from_json(json.loads(data))
|
||||||
|
self.assertEqual("br-foo", bridge.name)
|
||||||
|
self.assertTrue(bridge.use_dhcp)
|
||||||
|
dpdk_interface = bridge.members[0]
|
||||||
|
self.assertEqual("dpdk0", dpdk_interface.name)
|
||||||
|
self.assertFalse(dpdk_interface.ovs_port)
|
||||||
|
self.assertEqual("br-foo", dpdk_interface.bridge_name)
|
||||||
|
|
||||||
|
contents = utils.get_file_data(sriov_config._SRIOV_CONFIG_FILE)
|
||||||
|
vf_map = yaml.load(contents) if contents else []
|
||||||
|
self.assertListEqual(vf_final, vf_map)
|
||||||
|
|
||||||
|
def test_ovs_user_bridge_with_param_set(self):
|
||||||
|
data = """{
|
||||||
|
"type": "ovs_user_bridge",
|
||||||
|
"name": "br-foo",
|
||||||
|
"use_dhcp": true,
|
||||||
|
"members": [{
|
||||||
|
"type": "ovs_dpdk_port",
|
||||||
|
"name": "dpdk0",
|
||||||
|
"members": [
|
||||||
|
{
|
||||||
|
"type": "sriov_vf",
|
||||||
|
"device": "em1",
|
||||||
|
"vfid": 1,
|
||||||
|
"vlan_id": 111,
|
||||||
|
"qos": 1,
|
||||||
|
"spoofcheck": false,
|
||||||
|
"trust": false,
|
||||||
|
"promisc": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
vf_final = [{'device_type': 'vf', 'name': 'em1_1',
|
||||||
|
'device': {'name': 'em1', 'vfid': 1},
|
||||||
|
'vlan_id': 111, 'qos': 1,
|
||||||
|
'spoofcheck': 'off', 'trust': 'off'
|
||||||
|
}]
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
bridge = objects.object_from_json(json.loads(data))
|
||||||
|
self.assertEqual("br-foo", bridge.name)
|
||||||
|
self.assertTrue(bridge.use_dhcp)
|
||||||
|
dpdk_interface = bridge.members[0]
|
||||||
|
self.assertEqual("dpdk0", dpdk_interface.name)
|
||||||
|
self.assertFalse(dpdk_interface.ovs_port)
|
||||||
|
self.assertEqual("br-foo", dpdk_interface.bridge_name)
|
||||||
|
|
||||||
|
contents = utils.get_file_data(sriov_config._SRIOV_CONFIG_FILE)
|
||||||
|
vf_map = yaml.load(contents) if contents else []
|
||||||
|
self.assertListEqual(vf_final, vf_map)
|
||||||
|
|
||||||
def test_from_json_dhcp_with_nic1(self):
|
def test_from_json_dhcp_with_nic1(self):
|
||||||
def dummy_mapped_nics(nic_mapping=None):
|
def dummy_mapped_nics(nic_mapping=None):
|
||||||
return {"nic1": "em5"}
|
return {"nic1": "em5"}
|
||||||
|
|
|
@ -18,6 +18,7 @@ import glob
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
import six
|
||||||
import time
|
import time
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
|
@ -446,21 +447,26 @@ def _set_vf_fields(vf_name, vlan_id, qos, spoofcheck, trust, state, macaddr,
|
||||||
vf_configs['name'] = vf_name
|
vf_configs['name'] = vf_name
|
||||||
if vlan_id != 0:
|
if vlan_id != 0:
|
||||||
vf_configs['vlan_id'] = vlan_id
|
vf_configs['vlan_id'] = vlan_id
|
||||||
|
else:
|
||||||
|
vf_configs['vlan_id'] = None
|
||||||
if qos != 0:
|
if qos != 0:
|
||||||
vf_configs['qos'] = qos
|
vf_configs['qos'] = qos
|
||||||
if spoofcheck is not None:
|
else:
|
||||||
vf_configs['spoofcheck'] = spoofcheck
|
vf_configs['qos'] = None
|
||||||
if trust is not None:
|
vf_configs['spoofcheck'] = spoofcheck
|
||||||
vf_configs['trust'] = trust
|
vf_configs['trust'] = trust
|
||||||
if state is not None:
|
vf_configs['state'] = state
|
||||||
vf_configs['state'] = state
|
vf_configs['macaddr'] = macaddr
|
||||||
if macaddr is not None:
|
vf_configs['promisc'] = promisc
|
||||||
vf_configs['macaddr'] = macaddr
|
|
||||||
if promisc is not None:
|
|
||||||
vf_configs['promisc'] = promisc
|
|
||||||
return vf_configs
|
return vf_configs
|
||||||
|
|
||||||
|
|
||||||
|
def _clear_empty_values(vf_config):
|
||||||
|
for (key, val) in list(six.iteritems(vf_config)):
|
||||||
|
if val is None:
|
||||||
|
del vf_config[key]
|
||||||
|
|
||||||
|
|
||||||
def update_sriov_vf_map(pf_name, vfid, vf_name, vlan_id=0, qos=0,
|
def update_sriov_vf_map(pf_name, vfid, vf_name, vlan_id=0, qos=0,
|
||||||
spoofcheck=None, trust=None, state=None, macaddr=None,
|
spoofcheck=None, trust=None, state=None, macaddr=None,
|
||||||
promisc=None):
|
promisc=None):
|
||||||
|
@ -471,6 +477,7 @@ def update_sriov_vf_map(pf_name, vfid, vf_name, vlan_id=0, qos=0,
|
||||||
item['device'].get('vfid') == vfid):
|
item['device'].get('vfid') == vfid):
|
||||||
item.update(_set_vf_fields(vf_name, vlan_id, qos, spoofcheck,
|
item.update(_set_vf_fields(vf_name, vlan_id, qos, spoofcheck,
|
||||||
trust, state, macaddr, promisc))
|
trust, state, macaddr, promisc))
|
||||||
|
_clear_empty_values(item)
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
new_item = {}
|
new_item = {}
|
||||||
|
@ -478,6 +485,7 @@ def update_sriov_vf_map(pf_name, vfid, vf_name, vlan_id=0, qos=0,
|
||||||
new_item['device'] = {"name": pf_name, "vfid": vfid}
|
new_item['device'] = {"name": pf_name, "vfid": vfid}
|
||||||
new_item.update(_set_vf_fields(vf_name, vlan_id, qos, spoofcheck,
|
new_item.update(_set_vf_fields(vf_name, vlan_id, qos, spoofcheck,
|
||||||
trust, state, macaddr, promisc))
|
trust, state, macaddr, promisc))
|
||||||
|
_clear_empty_values(new_item)
|
||||||
sriov_map.append(new_item)
|
sriov_map.append(new_item)
|
||||||
|
|
||||||
write_yaml_config(sriov_config._SRIOV_CONFIG_FILE, sriov_map)
|
write_yaml_config(sriov_config._SRIOV_CONFIG_FILE, sriov_map)
|
||||||
|
|
Loading…
Reference in New Issue