Limit exposure of network device types to the guest.

Previously, the 'type' of the hypervisor network device, was exposed to
the guest directly. That does not make sense, as
a.) this leaks needless information into the guest
b.) the guest cannot be reasonably expected to make decisions
    based on a type of link that is present underneath the
    virtual device that is presented to the guest.
c.) guests then are forced to either continuously track these types
    or to assume that unknown type is "phy".

This limits the exposure of types to a specific list. Any other
type will be shown to the guest as 'phy'.

Change-Id: Iea458fba29596cd2773d8d3565451af60b02bcca
Closes-Bug: #1642679
This commit is contained in:
Scott Moser 2017-03-31 17:01:33 -04:00
parent 88bc8dc5ce
commit f559be35a0
3 changed files with 54 additions and 8 deletions

View File

@ -47,6 +47,7 @@ VIF_TYPE_OTHER = 'other'
VIF_TYPE_TAP = 'tap'
VIF_TYPE_MACVTAP = 'macvtap'
VIF_TYPE_BINDING_FAILED = 'binding_failed'
VIF_TYPE_VIF = 'vif'
# Constants for dictionary keys in the 'vif_details' field in the VIF
# class
@ -138,6 +139,18 @@ VIF_MODEL_ALL = (
VIF_MODEL_VMXNET3,
)
# these types have been leaked to guests in network_data.json
LEGACY_EXPOSED_VIF_TYPES = (
VIF_TYPE_BRIDGE,
VIF_TYPE_DVS,
VIF_TYPE_HW_VEB,
VIF_TYPE_HYPERV,
VIF_TYPE_OVS,
VIF_TYPE_TAP,
VIF_TYPE_VHOSTUSER,
VIF_TYPE_VIF,
)
# Constant for max length of network interface names
# eg 'bridge' in the Network class or 'devname' in
# the VIF class

View File

@ -856,16 +856,20 @@ iface eth1 inet static
class TestNetworkMetadata(test.NoDBTestCase):
def setUp(self):
super(TestNetworkMetadata, self).setUp()
self.netinfo = model.NetworkInfo([fake_network_cache_model.new_vif(
{'type': 'ethernet'})])
self.netinfo = self._new_netinfo()
def _new_netinfo(self, vif_type='ethernet'):
netinfo = model.NetworkInfo([fake_network_cache_model.new_vif(
{'type': vif_type})])
# Give this vif ipv4 and ipv6 dhcp subnets
ipv4_subnet = fake_network_cache_model.new_subnet(version=4)
ipv6_subnet = fake_network_cache_model.new_subnet(version=6)
self.netinfo[0]['network']['subnets'][0] = ipv4_subnet
self.netinfo[0]['network']['subnets'][1] = ipv6_subnet
self.netinfo[0]['network']['meta']['mtu'] = 1500
netinfo[0]['network']['subnets'][0] = ipv4_subnet
netinfo[0]['network']['subnets'][1] = ipv6_subnet
netinfo[0]['network']['meta']['mtu'] = 1500
return netinfo
def test_get_network_metadata_json(self):
@ -1193,3 +1197,32 @@ class TestNetworkMetadata(test.NoDBTestCase):
self.netinfo[0]['network']['subnets'].pop(0)
network_json = netutils.get_network_metadata(self.netinfo)
self.assertEqual(expected_json, network_json)
def test_legacy_vif_types_type_passed_through(self):
legacy_types = [
model.VIF_TYPE_BRIDGE,
model.VIF_TYPE_DVS,
model.VIF_TYPE_HW_VEB,
model.VIF_TYPE_HYPERV,
model.VIF_TYPE_OVS,
model.VIF_TYPE_TAP,
model.VIF_TYPE_VHOSTUSER,
model.VIF_TYPE_VIF,
]
link_types = []
for vif_type in legacy_types:
network_json = netutils.get_network_metadata(
self._new_netinfo(vif_type=vif_type))
link_types.append(network_json["links"][0]["type"])
self.assertEqual(legacy_types, link_types)
def test_new_vif_types_get_type_phy(self):
new_types = ["whizbang_nvf", "vswitch9"]
link_types = []
for vif_type in new_types:
network_json = netutils.get_network_metadata(
self._new_netinfo(vif_type=vif_type))
link_types.append(network_json["links"][0]["type"])
self.assertEqual(["phy"] * len(new_types), link_types)

View File

@ -236,10 +236,10 @@ def _get_eth_link(vif, ifc_num):
link_id = 'interface%d' % ifc_num
# Use 'phy' for physical links. Ethernet can be confusing
if vif.get('type') == 'ethernet':
nic_type = 'phy'
else:
if vif.get('type') in model.LEGACY_EXPOSED_VIF_TYPES:
nic_type = vif.get('type')
else:
nic_type = 'phy'
link = {
'id': link_id,