Skip to content

Commit

Permalink
Add kernel vrouter.ko datapath plugging support
Browse files Browse the repository at this point in the history
This change adds the missing sections to support kernel TAP device
plugging for the os-vif plugin. Currently this is keyed off the VIF type
passed to the plugin.

Note: this plugin requires a minimum of libvirt 1.3.1.
This is also the minimum version supported in OpenStack Rocky.

* Unit tests have been updated:
  contrail_vrouter os-vif plugin tests only vhostuser plugging
  vrouter os-vif plugin tests both methods

Change-Id: I74dca19a6c8a5676caa6423619b1f593a8cc1b3e
Partial-Bug: #1773981
Signed-off-by: Jan Gutter <jan.gutter@netronome.com>
  • Loading branch information
Jan Gutter committed Jul 2, 2018
1 parent c1354fd commit ed01d31
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 62 deletions.
63 changes: 29 additions & 34 deletions vif_plug_contrail_vrouter/tests/test_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def __init__(self, *args, **kwargs):
subnets=subnets,
vlan=99)

vif_vhostuser_vrouter = objects.vif.VIFVHostUser(
vif_vrouter_vhostuser = objects.vif.VIFVHostUser(
id='40137937-43c3-47d9-be65-d3a13041c5cf',
address='ca:fe:de:ad:be:ef',
network=network_vrouter,
Expand All @@ -92,71 +92,64 @@ def __init__(self, *args, **kwargs):
vif_name='tapXXX'
)

vif_vhostuser_no_path = objects.vif.VIFVHostUser(
vif_vrouter_vhostuser_no_path = objects.vif.VIFVHostUser(
id='f4454d55-ebb1-4bc8-9f92-7ade5e6a3350',
address='ca:fe:de:ad:be:ef',
network=network_vrouter,
mode='client',
vif_name='tapXXX'
)

vif_vrouter = objects.vif.VIFGeneric(
id='a909a869-e967-4c5f-8f54-fbd57dc798a9',
address='ca:fe:de:ad:be:ef',
network=network_vrouter,
vif_name='tap-xxx-yyy-zzz'
)

instance = objects.instance_info.InstanceInfo(
name='Instance 1',
uuid='f0000000-0000-0000-0000-000000000001',
project_id='1'
)

def test_vhostuser_vrouter_plug(self):
def test_vrouter_vhostuser_plug(self):
calls = {
'_vrouter_port_add': [mock.call(self.instance,
self.vif_vhostuser_vrouter)]
self.vif_vrouter_vhostuser)]
}
with mock.patch.object(vrouter.VrouterPlugin,
'_vrouter_port_add') as port_add:
plugin = vrouter.VrouterPlugin.load("contrail_vrouter")
plugin.plug(self.vif_vhostuser_vrouter, self.instance)
plugin.plug(self.vif_vrouter_vhostuser, self.instance)

port_add.assert_has_calls(calls['_vrouter_port_add'])

def test_vhostuser_vrouter_unplug(self):
def test_vrouter_vhostuser_unplug(self):
calls = {
'_vrouter_port_delete': [mock.call(self.instance,
self.vif_vhostuser_vrouter)]
self.vif_vrouter_vhostuser)]
}
with mock.patch.object(vrouter.VrouterPlugin,
'_vrouter_port_delete') as delete_port:
plugin = vrouter.VrouterPlugin.load("contrail_vrouter")
plugin.unplug(self.vif_vhostuser_vrouter, self.instance)
plugin.unplug(self.vif_vrouter_vhostuser, self.instance)

delete_port.assert_has_calls(calls['_vrouter_port_delete'])

def test_vrouter_port_add(self):
def test_vrouter_vhostuser_port_add(self):
ip_addr = '0.0.0.0'
ip6_addr = None
ptype = 'NovaVMPort'
vtype = 'VhostUser'
cmd_args = ("--oper=add",
"--uuid=%s" % self.vif_vhostuser_vrouter.id,
"--uuid=%s" % self.vif_vrouter_vhostuser.id,
"--instance_uuid=%s" % self.instance.uuid,
"--vn_uuid=%s" % self.vif_vhostuser_vrouter.network.id,
"--vn_uuid=%s" % self.vif_vrouter_vhostuser.network.id,
"--vm_project_uuid=%s" % self.instance.project_id,
"--ip_address=%s" % ip_addr,
"--ipv6_address=%s" % ip6_addr,
"--vm_name=%s" % self.instance.name,
"--mac=%s" % self.vif_vhostuser_vrouter.address,
"--tap_name=%s" % self.vif_vhostuser_vrouter.vif_name,
"--mac=%s" % self.vif_vrouter_vhostuser.address,
"--tap_name=%s" % self.vif_vrouter_vhostuser.vif_name,
"--port_type=%s" % ptype,
"--vif_type=%s" % vtype,
"--vhostuser_socket=%s" % self.vif_vhostuser_vrouter.path,
"--vhostuser_socket=%s" % self.vif_vrouter_vhostuser.path,
"--vhostuser_mode=%s" %
_vhu_mode_to_int(self.vif_vhostuser_vrouter.mode),
_vhu_mode_to_int(self.vif_vrouter_vhostuser.mode),
"--tx_vlan_id=%d" % -1,
"--rx_vlan_id=%d" % -1)
calls = {
Expand All @@ -165,62 +158,64 @@ def test_vrouter_port_add(self):

with mock.patch.object(processutils, 'execute') as execute_cmd:
vrouter.VrouterPlugin._vrouter_port_add(
self.instance, self.vif_vhostuser_vrouter
self.instance, self.vif_vrouter_vhostuser
)

execute_cmd.assert_has_calls(calls['execute'])

def test_vrouter_port_delete(self):
def test_vrouter_vhostuser_port_delete(self):
calls = {
'execute': [
mock.call(
'vrouter-port-control',
'--oper=delete',
'--uuid=%s' % self.vif_vhostuser_vrouter.id
'--uuid=%s' % self.vif_vrouter_vhostuser.id
)
]
}

with mock.patch.object(processutils, 'execute') as execute_cmd:
vrouter.VrouterPlugin._vrouter_port_delete(
self.instance, self.vif_vhostuser_vrouter
self.instance, self.vif_vrouter_vhostuser
)

execute_cmd.assert_has_calls(calls['execute'])

def test_unplug_vrouter_with_details(self):
def test_unplug_vrouter_vhostuser(self):
with mock.patch.object(processutils, 'execute') as execute:
plugin = vrouter.VrouterPlugin.load("contrail_vrouter")
plugin.unplug(self.vif_vrouter, self.instance)
plugin.unplug(self.vif_vrouter_vhostuser, self.instance)
execute.assert_called_once_with(
'vrouter-port-control',
'--oper=delete',
'--uuid=a909a869-e967-4c5f-8f54-fbd57dc798a9'
'--uuid=40137937-43c3-47d9-be65-d3a13041c5cf'
)

def test_plug_vrouter_with_details(self):
def test_plug_vrouter_vhostuser(self):
instance = mock.Mock()
instance.name = 'instance-name'
instance.uuid = '46a4308b-e75a-4f90-a34a-650c86ca18b2'
instance.project_id = 'b168ea26fa0c49c1a84e1566d9565fa5'
with mock.patch.object(processutils, 'execute') as execute:
plugin = vrouter.VrouterPlugin.load("contrail_vrouter")
plugin.plug(self.vif_vrouter, instance)
plugin.plug(self.vif_vrouter_vhostuser, instance)
execute.assert_has_calls([
mock.call(
'vrouter-port-control',
'--oper=add',
'--uuid=a909a869-e967-4c5f-8f54-fbd57dc798a9',
'--uuid=40137937-43c3-47d9-be65-d3a13041c5cf',
'--instance_uuid=46a4308b-e75a-4f90-a34a-650c86ca18b2',
'--vn_uuid=f0ff5378-7367-4451-9202-829b068143f3',
'--vm_project_uuid=b168ea26fa0c49c1a84e1566d9565fa5',
'--ip_address=0.0.0.0',
'--ipv6_address=None',
'--vm_name=instance-name',
'--mac=ca:fe:de:ad:be:ef',
'--tap_name=tap-xxx-yyy-zzz',
'--tap_name=tapXXX',
'--port_type=NovaVMPort',
'--vif_type=Vrouter',
'--vif_type=VhostUser',
'--vhostuser_socket=/var/run/openvswitch/vhub679325f-ca',
'--vhostuser_mode=0',
'--tx_vlan_id=-1',
'--rx_vlan_id=-1')
]
Expand Down
4 changes: 4 additions & 0 deletions vif_plug_vrouter/exception.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,7 @@ class VrouterPortControlError(vrouter_exception.ExceptionBase):

class VrouterUnknownVIFError(vrouter_exception.ExceptionBase):
msg_fmt = _('Unknown object type of VIF ID: %(id)s')


class VrouterUnknownPortProfileError(vrouter_exception.ExceptionBase):
msg_fmt = _('Unknown port profile on VIF ID: %(id)s')
1 change: 1 addition & 0 deletions vif_plug_vrouter/privsep.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from oslo_privsep import capabilities as c
from oslo_privsep import priv_context


vif_plug = priv_context.PrivContext(
"vif_plug_vrouter",
cfg_section="vif_plug_vrouter_privileged",
Expand Down
93 changes: 67 additions & 26 deletions vif_plug_vrouter/tests/test_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def __init__(self, *args, **kwargs):
subnets=subnets,
vlan=99)

vif_vhostuser_vrouter = objects.vif.VIFVHostUser(
vif_vrouter_vhostuser = objects.vif.VIFVHostUser(
id='40137937-43c3-47d9-be65-d3a13041c5cf',
address='ca:fe:de:ad:be:ef',
network=network_vrouter,
Expand All @@ -92,7 +92,7 @@ def __init__(self, *args, **kwargs):
vif_name='tapXXX'
)

vif_vhostuser_no_path = objects.vif.VIFVHostUser(
vif_vrouter_vhostuser_no_path = objects.vif.VIFVHostUser(
id='f4454d55-ebb1-4bc8-9f92-7ade5e6a3350',
address='ca:fe:de:ad:be:ef',
network=network_vrouter,
Expand All @@ -113,50 +113,50 @@ def __init__(self, *args, **kwargs):
project_id='1'
)

def test_vhostuser_vrouter_plug(self):
def test_vrouter_vhostuser_plug(self):
calls = {
'_vrouter_port_add': [mock.call(self.instance,
self.vif_vhostuser_vrouter)]
self.vif_vrouter_vhostuser)]
}
with mock.patch.object(vrouter.VrouterPlugin,
'_vrouter_port_add') as port_add:
plugin = vrouter.VrouterPlugin.load("vrouter")
plugin.plug(self.vif_vhostuser_vrouter, self.instance)
plugin.plug(self.vif_vrouter_vhostuser, self.instance)

port_add.assert_has_calls(calls['_vrouter_port_add'])

def test_vhostuser_vrouter_unplug(self):
def test_vrouter_vhostuser_unplug(self):
calls = {
'_vrouter_port_delete': [mock.call(self.instance,
self.vif_vhostuser_vrouter)]
self.vif_vrouter_vhostuser)]
}
with mock.patch.object(vrouter.VrouterPlugin,
'_vrouter_port_delete') as delete_port:
plugin = vrouter.VrouterPlugin.load("vrouter")
plugin.unplug(self.vif_vhostuser_vrouter, self.instance)
plugin.unplug(self.vif_vrouter_vhostuser, self.instance)

delete_port.assert_has_calls(calls['_vrouter_port_delete'])

def test_vrouter_port_add(self):
def test_vrouter_vhostuser_port_add(self):
ip_addr = '0.0.0.0'
ip6_addr = None
ptype = 'NovaVMPort'
vtype = 'VhostUser'
cmd_args = ("--oper=add",
"--uuid=%s" % self.vif_vhostuser_vrouter.id,
"--uuid=%s" % self.vif_vrouter_vhostuser.id,
"--instance_uuid=%s" % self.instance.uuid,
"--vn_uuid=%s" % self.vif_vhostuser_vrouter.network.id,
"--vn_uuid=%s" % self.vif_vrouter_vhostuser.network.id,
"--vm_project_uuid=%s" % self.instance.project_id,
"--ip_address=%s" % ip_addr,
"--ipv6_address=%s" % ip6_addr,
"--vm_name=%s" % self.instance.name,
"--mac=%s" % self.vif_vhostuser_vrouter.address,
"--tap_name=%s" % self.vif_vhostuser_vrouter.vif_name,
"--mac=%s" % self.vif_vrouter_vhostuser.address,
"--tap_name=%s" % self.vif_vrouter_vhostuser.vif_name,
"--port_type=%s" % ptype,
"--vif_type=%s" % vtype,
"--vhostuser_socket=%s" % self.vif_vhostuser_vrouter.path,
"--vhostuser_socket=%s" % self.vif_vrouter_vhostuser.path,
"--vhostuser_mode=%s" %
_vhu_mode_to_int(self.vif_vhostuser_vrouter.mode),
_vhu_mode_to_int(self.vif_vrouter_vhostuser.mode),
"--tx_vlan_id=%d" % -1,
"--rx_vlan_id=%d" % -1)
calls = {
Expand All @@ -165,62 +165,103 @@ def test_vrouter_port_add(self):

with mock.patch.object(processutils, 'execute') as execute_cmd:
vrouter.VrouterPlugin._vrouter_port_add(
self.instance, self.vif_vhostuser_vrouter
self.instance, self.vif_vrouter_vhostuser
)

execute_cmd.assert_has_calls(calls['execute'])

def test_vrouter_port_delete(self):
def test_vrouter_vhostuser_port_delete(self):
calls = {
'execute': [
mock.call(
'vrouter-port-control',
'--oper=delete',
'--uuid=%s' % self.vif_vhostuser_vrouter.id
'--uuid=%s' % self.vif_vrouter_vhostuser.id
)
]
}

with mock.patch.object(processutils, 'execute') as execute_cmd:
vrouter.VrouterPlugin._vrouter_port_delete(
self.instance, self.vif_vhostuser_vrouter
self.instance, self.vif_vrouter_vhostuser
)

execute_cmd.assert_has_calls(calls['execute'])

def test_unplug_vrouter_with_details(self):
def test_unplug_vrouter(self):
with mock.patch.object(processutils, 'execute') as execute:
plugin = vrouter.VrouterPlugin.load("vrouter")
plugin.unplug(self.vif_vrouter, self.instance)
execute.assert_has_calls([
mock.call(
'vrouter-port-control',
'--oper=delete',
'--uuid=a909a869-e967-4c5f-8f54-fbd57dc798a9'
),
])

def test_plug_vrouter(self):
instance = mock.Mock()
instance.name = 'instance-name'
instance.uuid = '46a4308b-e75a-4f90-a34a-650c86ca18b2'
instance.project_id = 'b168ea26fa0c49c1a84e1566d9565fa5'
with mock.patch.object(processutils, 'execute') as execute:
plugin = vrouter.VrouterPlugin.load("vrouter")
plugin.plug(self.vif_vrouter, instance)
execute.assert_has_calls([
mock.call(
'vrouter-port-control',
'--oper=add',
'--uuid=a909a869-e967-4c5f-8f54-fbd57dc798a9',
'--instance_uuid=46a4308b-e75a-4f90-a34a-650c86ca18b2',
'--vn_uuid=f0ff5378-7367-4451-9202-829b068143f3',
'--vm_project_uuid=b168ea26fa0c49c1a84e1566d9565fa5',
'--ip_address=0.0.0.0',
'--ipv6_address=None',
'--vm_name=instance-name',
'--mac=ca:fe:de:ad:be:ef',
'--tap_name=tap-xxx-yyy-zzz',
'--port_type=NovaVMPort',
'--tx_vlan_id=-1',
'--rx_vlan_id=-1')
],
)

def test_unplug_vrouter_vhostuser(self):
with mock.patch.object(processutils, 'execute') as execute:
plugin = vrouter.VrouterPlugin.load("vrouter")
plugin.unplug(self.vif_vrouter_vhostuser, self.instance)
execute.assert_called_once_with(
'vrouter-port-control',
'--oper=delete',
'--uuid=a909a869-e967-4c5f-8f54-fbd57dc798a9'
'--uuid=40137937-43c3-47d9-be65-d3a13041c5cf'
)

def test_plug_vrouter_with_details(self):
def test_plug_vrouter_vhostuser(self):
instance = mock.Mock()
instance.name = 'instance-name'
instance.uuid = '46a4308b-e75a-4f90-a34a-650c86ca18b2'
instance.project_id = 'b168ea26fa0c49c1a84e1566d9565fa5'
with mock.patch.object(processutils, 'execute') as execute:
plugin = vrouter.VrouterPlugin.load("vrouter")
plugin.plug(self.vif_vrouter, instance)
plugin.plug(self.vif_vrouter_vhostuser, instance)
execute.assert_has_calls([
mock.call(
'vrouter-port-control',
'--oper=add',
'--uuid=a909a869-e967-4c5f-8f54-fbd57dc798a9',
'--uuid=40137937-43c3-47d9-be65-d3a13041c5cf',
'--instance_uuid=46a4308b-e75a-4f90-a34a-650c86ca18b2',
'--vn_uuid=f0ff5378-7367-4451-9202-829b068143f3',
'--vm_project_uuid=b168ea26fa0c49c1a84e1566d9565fa5',
'--ip_address=0.0.0.0',
'--ipv6_address=None',
'--vm_name=instance-name',
'--mac=ca:fe:de:ad:be:ef',
'--tap_name=tap-xxx-yyy-zzz',
'--tap_name=tapXXX',
'--port_type=NovaVMPort',
'--vif_type=Vrouter',
'--vif_type=VhostUser',
'--vhostuser_socket=/var/run/openvswitch/vhub679325f-ca',
'--vhostuser_mode=0',
'--tx_vlan_id=-1',
'--rx_vlan_id=-1')
]
Expand Down
Loading

0 comments on commit ed01d31

Please sign in to comment.