NSX|V: Support QoS ingress rules

Commit Ia13568879c2b6f80fb190ccafe7e19ca05b0c6a8 added the ingress direction
BW rules.
This patch adds this support for the NSX-V QoS driver.

Change-Id: I7bf4715549fc2af26789ecd9e20c444a387ffd77
This commit is contained in:
Adit Sarfaty 2017-07-03 08:46:55 +03:00
parent 63154b510b
commit 71672344cf
4 changed files with 59 additions and 21 deletions

View File

@ -210,17 +210,31 @@ class DvsManager(VCManagerBase):
# Note: openstack refers to the directions from the VM point of view, # Note: openstack refers to the directions from the VM point of view,
# while the NSX refers to the vswitch point of view. # while the NSX refers to the vswitch point of view.
# so open stack egress is actually inShaping here. # so open stack egress is actually inShaping here.
outPol = port_conf.inShapingPolicy inPol = port_conf.inShapingPolicy
if qos_data.bandwidthEnabled: if qos_data.egress.bandwidthEnabled:
inPol.inherited = False
inPol.enabled.inherited = False
inPol.enabled.value = True
inPol.averageBandwidth.inherited = False
inPol.averageBandwidth.value = qos_data.egress.averageBandwidth
inPol.peakBandwidth.inherited = False
inPol.peakBandwidth.value = qos_data.egress.peakBandwidth
inPol.burstSize.inherited = False
inPol.burstSize.value = qos_data.egress.burstSize
else:
inPol.inherited = True
outPol = port_conf.outShapingPolicy
if qos_data.ingress.bandwidthEnabled:
outPol.inherited = False outPol.inherited = False
outPol.enabled.inherited = False outPol.enabled.inherited = False
outPol.enabled.value = True outPol.enabled.value = True
outPol.averageBandwidth.inherited = False outPol.averageBandwidth.inherited = False
outPol.averageBandwidth.value = qos_data.averageBandwidth outPol.averageBandwidth.value = qos_data.ingress.averageBandwidth
outPol.peakBandwidth.inherited = False outPol.peakBandwidth.inherited = False
outPol.peakBandwidth.value = qos_data.peakBandwidth outPol.peakBandwidth.value = qos_data.ingress.peakBandwidth
outPol.burstSize.inherited = False outPol.burstSize.inherited = False
outPol.burstSize.value = qos_data.burstSize outPol.burstSize.value = qos_data.ingress.burstSize
else: else:
outPol.inherited = True outPol.inherited = True
@ -633,7 +647,6 @@ class ClusterManager(VCManagerBase):
def update_cluster_edge_failover(self, resource_id, vm_moids, def update_cluster_edge_failover(self, resource_id, vm_moids,
host_group_names): host_group_names):
"""Updates cluster for vm placement using DRS""" """Updates cluster for vm placement using DRS"""
# DEBUG ADIT edge-id is never used
session = self._session session = self._session
resource = vim_util.get_moref(resource_id, 'ResourcePool') resource = vim_util.get_moref(resource_id, 'ResourcePool')
# TODO(garyk): cache the cluster details # TODO(garyk): cache the cluster details

View File

@ -29,7 +29,8 @@ SUPPORTED_RULES = {
qos_consts.MAX_BURST: { qos_consts.MAX_BURST: {
'type:range': [0, n_consts.DB_INTEGER_MAX_VALUE]}, 'type:range': [0, n_consts.DB_INTEGER_MAX_VALUE]},
qos_consts.DIRECTION: { qos_consts.DIRECTION: {
'type:values': [n_consts.EGRESS_DIRECTION]} 'type:values': [n_consts.EGRESS_DIRECTION,
n_consts.INGRESS_DIRECTION]}
}, },
qos_consts.RULE_TYPE_DSCP_MARKING: { qos_consts.RULE_TYPE_DSCP_MARKING: {
qos_consts.DSCP_MARK: {'type:values': n_consts.VALID_DSCP_MARKS} qos_consts.DSCP_MARK: {'type:values': n_consts.VALID_DSCP_MARKS}

View File

@ -14,6 +14,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from neutron.common import constants as n_consts
from neutron.services.qos import qos_consts from neutron.services.qos import qos_consts
from neutron_lib.plugins import constants as plugin_const from neutron_lib.plugins import constants as plugin_const
from neutron_lib.plugins import directory from neutron_lib.plugins import directory
@ -24,6 +25,15 @@ from oslo_log import log as logging
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
class NsxVQosBWLimits(object):
# Data structure to hold the NSX-V representation
# of the neutron QoS Bandwidth rule
bandwidthEnabled = False
averageBandwidth = 0
peakBandwidth = 0
burstSize = 0
class NsxVQosRule(object): class NsxVQosRule(object):
def __init__(self, context=None, qos_policy_id=None): def __init__(self, context=None, qos_policy_id=None):
@ -32,11 +42,9 @@ class NsxVQosRule(object):
self._qos_plugin = None self._qos_plugin = None
# Data structure to hold the NSX-V representation # Data structure to hold the NSX-V representation
# of the neutron QoS Bandwidth rule # of the neutron QoS Bandwidth rule for both directions
self.bandwidthEnabled = False self.egress = NsxVQosBWLimits()
self.averageBandwidth = 0 self.ingress = NsxVQosBWLimits()
self.peakBandwidth = 0
self.burstSize = 0
# And data for the DSCP marking rule # And data for the DSCP marking rule
self.dscpMarkEnabled = False self.dscpMarkEnabled = False
@ -61,23 +69,26 @@ class NsxVQosRule(object):
policy_obj = plugin.get_policy(context, qos_policy_id) policy_obj = plugin.get_policy(context, qos_policy_id)
if 'rules' in policy_obj and len(policy_obj['rules']) > 0: if 'rules' in policy_obj and len(policy_obj['rules']) > 0:
for rule_obj in policy_obj['rules']: for rule_obj in policy_obj['rules']:
# TODO(asarfaty): for now we support one rule of each type
# This code should be fixed in order to support rules of
# different directions
if (rule_obj['type'] == if (rule_obj['type'] ==
qos_consts.RULE_TYPE_BANDWIDTH_LIMIT): qos_consts.RULE_TYPE_BANDWIDTH_LIMIT):
self.bandwidthEnabled = True # BW limit rule for one of the directions
if rule_obj['direction'] == n_consts.EGRESS_DIRECTION:
dir_obj = self.egress
else:
dir_obj = self.ingress
dir_obj.bandwidthEnabled = True
# averageBandwidth: kbps (neutron) -> bps (nsxv) # averageBandwidth: kbps (neutron) -> bps (nsxv)
self.averageBandwidth = rule_obj['max_kbps'] * 1024 dir_obj.averageBandwidth = rule_obj['max_kbps'] * 1024
# peakBandwidth: a Multiplying on the average BW # peakBandwidth: a Multiplying on the average BW
# because the neutron qos configuration supports # because the neutron qos configuration supports
# only 1 value # only 1 value
self.peakBandwidth = int(round( dir_obj.peakBandwidth = int(round(
self.averageBandwidth * dir_obj.averageBandwidth *
cfg.CONF.NSX.qos_peak_bw_multiplier)) cfg.CONF.NSX.qos_peak_bw_multiplier))
# burstSize: kbps (neutron) -> Bytes (nsxv) # burstSize: kbps (neutron) -> Bytes (nsxv)
self.burstSize = rule_obj['max_burst_kbps'] * 128 dir_obj.burstSize = rule_obj['max_burst_kbps'] * 128
if rule_obj['type'] == qos_consts.RULE_TYPE_DSCP_MARKING: if rule_obj['type'] == qos_consts.RULE_TYPE_DSCP_MARKING:
# DSCP marking rule
self.dscpMarkEnabled = True self.dscpMarkEnabled = True
self.dscpMarkValue = rule_obj['dscp_mark'] self.dscpMarkValue = rule_obj['dscp_mark']

View File

@ -74,6 +74,13 @@ class TestQosNsxVNotification(test_plugin.NsxVPluginV2TestCase,
'max_kbps': 100, 'max_kbps': 100,
'max_burst_kbps': 150, 'max_burst_kbps': 150,
'type': qos_consts.RULE_TYPE_BANDWIDTH_LIMIT}} 'type': qos_consts.RULE_TYPE_BANDWIDTH_LIMIT}}
self.ingress_rule_data = {
'bandwidth_limit_rule': {
'id': uuidutils.generate_uuid(),
'max_kbps': 200,
'max_burst_kbps': 250,
'direction': 'ingress',
'type': qos_consts.RULE_TYPE_BANDWIDTH_LIMIT}}
self.dscp_rule_data = { self.dscp_rule_data = {
'dscp_marking_rule': { 'dscp_marking_rule': {
'id': uuidutils.generate_uuid(), 'id': uuidutils.generate_uuid(),
@ -83,8 +90,13 @@ class TestQosNsxVNotification(test_plugin.NsxVPluginV2TestCase,
self.policy = policy_object.QosPolicy( self.policy = policy_object.QosPolicy(
self.ctxt, **self.policy_data['policy']) self.ctxt, **self.policy_data['policy'])
# egress bw rule
self.rule = rule_object.QosBandwidthLimitRule( self.rule = rule_object.QosBandwidthLimitRule(
self.ctxt, **self.rule_data['bandwidth_limit_rule']) self.ctxt, **self.rule_data['bandwidth_limit_rule'])
# ingress bw rule
self.ingress_rule = rule_object.QosBandwidthLimitRule(
self.ctxt, **self.ingress_rule_data['bandwidth_limit_rule'])
# dscp marking rule
self.dscp_rule = rule_object.QosDscpMarkingRule( self.dscp_rule = rule_object.QosDscpMarkingRule(
self.ctxt, **self.dscp_rule_data['dscp_marking_rule']) self.ctxt, **self.dscp_rule_data['dscp_marking_rule'])
@ -128,7 +140,8 @@ class TestQosNsxVNotification(test_plugin.NsxVPluginV2TestCase,
# Create a policy with a rule # Create a policy with a rule
_policy = policy_object.QosPolicy( _policy = policy_object.QosPolicy(
self.ctxt, **self.policy_data['policy']) self.ctxt, **self.policy_data['policy'])
setattr(_policy, "rules", [self.rule, self.dscp_rule]) setattr(_policy, "rules", [self.rule, self.ingress_rule,
self.dscp_rule])
with mock.patch('neutron.services.qos.qos_plugin.QoSPlugin.' with mock.patch('neutron.services.qos.qos_plugin.QoSPlugin.'
'get_policy', 'get_policy',