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

View File

@ -29,7 +29,8 @@ SUPPORTED_RULES = {
qos_consts.MAX_BURST: {
'type:range': [0, n_consts.DB_INTEGER_MAX_VALUE]},
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.DSCP_MARK: {'type:values': n_consts.VALID_DSCP_MARKS}

View File

@ -14,6 +14,7 @@
# License for the specific language governing permissions and limitations
# under the License.
from neutron.common import constants as n_consts
from neutron.services.qos import qos_consts
from neutron_lib.plugins import constants as plugin_const
from neutron_lib.plugins import directory
@ -24,6 +25,15 @@ from oslo_log import log as logging
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):
def __init__(self, context=None, qos_policy_id=None):
@ -32,11 +42,9 @@ class NsxVQosRule(object):
self._qos_plugin = None
# Data structure to hold the NSX-V representation
# of the neutron QoS Bandwidth rule
self.bandwidthEnabled = False
self.averageBandwidth = 0
self.peakBandwidth = 0
self.burstSize = 0
# of the neutron QoS Bandwidth rule for both directions
self.egress = NsxVQosBWLimits()
self.ingress = NsxVQosBWLimits()
# And data for the DSCP marking rule
self.dscpMarkEnabled = False
@ -61,23 +69,26 @@ class NsxVQosRule(object):
policy_obj = plugin.get_policy(context, qos_policy_id)
if 'rules' in policy_obj and len(policy_obj['rules']) > 0:
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'] ==
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)
self.averageBandwidth = rule_obj['max_kbps'] * 1024
dir_obj.averageBandwidth = rule_obj['max_kbps'] * 1024
# peakBandwidth: a Multiplying on the average BW
# because the neutron qos configuration supports
# only 1 value
self.peakBandwidth = int(round(
self.averageBandwidth *
dir_obj.peakBandwidth = int(round(
dir_obj.averageBandwidth *
cfg.CONF.NSX.qos_peak_bw_multiplier))
# 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:
# DSCP marking rule
self.dscpMarkEnabled = True
self.dscpMarkValue = rule_obj['dscp_mark']

View File

@ -74,6 +74,13 @@ class TestQosNsxVNotification(test_plugin.NsxVPluginV2TestCase,
'max_kbps': 100,
'max_burst_kbps': 150,
'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 = {
'dscp_marking_rule': {
'id': uuidutils.generate_uuid(),
@ -83,8 +90,13 @@ class TestQosNsxVNotification(test_plugin.NsxVPluginV2TestCase,
self.policy = policy_object.QosPolicy(
self.ctxt, **self.policy_data['policy'])
# egress bw rule
self.rule = rule_object.QosBandwidthLimitRule(
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.ctxt, **self.dscp_rule_data['dscp_marking_rule'])
@ -128,7 +140,8 @@ class TestQosNsxVNotification(test_plugin.NsxVPluginV2TestCase,
# Create a policy with a rule
_policy = policy_object.QosPolicy(
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.'
'get_policy',