Merge "[OVN][QOS] QoS for distributed floating IP"
This commit is contained in:
commit
78def98919
|
@ -26,6 +26,7 @@ from oslo_log import log as logging
|
|||
|
||||
from neutron.common.ovn import constants as ovn_const
|
||||
from neutron.common.ovn import utils
|
||||
from neutron.conf.plugins.ml2.drivers.ovn import ovn_conf
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
@ -91,7 +92,7 @@ class OVNClientQosExtension(object):
|
|||
return qos_rules
|
||||
|
||||
@staticmethod
|
||||
def _ovn_qos_rule_match(direction, port_id, ip_address):
|
||||
def _ovn_qos_rule_match(direction, port_id, ip_address, resident_port):
|
||||
if direction == constants.EGRESS_DIRECTION:
|
||||
in_or_out = 'inport'
|
||||
src_or_dst = 'src'
|
||||
|
@ -100,15 +101,15 @@ class OVNClientQosExtension(object):
|
|||
src_or_dst = 'dst'
|
||||
|
||||
match = '%s == "%s"' % (in_or_out, port_id)
|
||||
if ip_address:
|
||||
if ip_address and resident_port:
|
||||
match += (' && ip4.%s == %s && is_chassis_resident("%s")' %
|
||||
(src_or_dst, ip_address,
|
||||
utils.ovn_cr_lrouter_port_name(port_id)))
|
||||
(src_or_dst, ip_address, resident_port))
|
||||
|
||||
return match
|
||||
|
||||
def _ovn_qos_rule(self, rules_direction, rules, port_id, network_id,
|
||||
fip_id=None, ip_address=None, delete=False):
|
||||
fip_id=None, ip_address=None, resident_port=None,
|
||||
delete=False):
|
||||
"""Generate an OVN QoS register based on several Neutron QoS rules
|
||||
|
||||
A OVN QoS register can contain "bandwidth" and "action" parameters.
|
||||
|
@ -129,6 +130,9 @@ class OVNClientQosExtension(object):
|
|||
limit.
|
||||
:param ip_address: (string) IP address, for L3 floating IP bandwidth
|
||||
limit.
|
||||
:param resident_port: (string) for L3 floating IP bandwidth, this is
|
||||
a logical switch port located in the chassis
|
||||
where the floating IP traffic is NATed.
|
||||
:param delete: (bool) defines if this rule if going to be a partial
|
||||
one (without any bandwidth or DSCP information) to be
|
||||
used only as deletion rule.
|
||||
|
@ -142,7 +146,8 @@ class OVNClientQosExtension(object):
|
|||
direction = (
|
||||
'from-lport' if rules_direction == constants.EGRESS_DIRECTION else
|
||||
'to-lport')
|
||||
match = self._ovn_qos_rule_match(rules_direction, port_id, ip_address)
|
||||
match = self._ovn_qos_rule_match(rules_direction, port_id, ip_address,
|
||||
resident_port)
|
||||
|
||||
ovn_qos_rule = {'switch': lswitch_name, 'direction': direction,
|
||||
'priority': OVN_QOS_DEFAULT_RULE_PRIORITY,
|
||||
|
@ -286,12 +291,20 @@ class OVNClientQosExtension(object):
|
|||
if not gw_port_id:
|
||||
return
|
||||
|
||||
if ovn_conf.is_ovn_distributed_floating_ip():
|
||||
# DVR, floating IP GW is in the same compute node as private port.
|
||||
resident_port = floatingip['port_id']
|
||||
else:
|
||||
# Non-DVR, floating IP GW is located where chassisredirect lrp is.
|
||||
resident_port = utils.ovn_cr_lrouter_port_name(gw_port_id)
|
||||
|
||||
qos_rules = self._qos_rules(admin_context, qos_policy_id)
|
||||
for direction, rules in qos_rules.items():
|
||||
ovn_rule = self._ovn_qos_rule(
|
||||
direction, rules, gw_port_id,
|
||||
floatingip['floating_network_id'], fip_id=floatingip['id'],
|
||||
ip_address=floatingip['floating_ip_address'])
|
||||
ip_address=floatingip['floating_ip_address'],
|
||||
resident_port=resident_port)
|
||||
if ovn_rule:
|
||||
txn.add(self._driver._nb_idl.qos_add(**ovn_rule))
|
||||
|
||||
|
|
|
@ -62,6 +62,8 @@ class TestOVNClientQosExtension(test_plugin.Ml2PluginV2TestCase):
|
|||
def setUp(self):
|
||||
cfg.CONF.set_override('extension_drivers', self._extension_drivers,
|
||||
group='ml2')
|
||||
cfg.CONF.set_override('enable_distributed_floating_ip', 'False',
|
||||
group='ovn')
|
||||
extensions.register_custom_supported_check(qos_api.ALIAS, lambda: True,
|
||||
plugin_agnostic=True)
|
||||
super(TestOVNClientQosExtension, self).setUp()
|
||||
|
@ -188,7 +190,7 @@ class TestOVNClientQosExtension(test_plugin.Ml2PluginV2TestCase):
|
|||
direction = constants.INGRESS_DIRECTION
|
||||
rule = {qos_constants.RULE_TYPE_BANDWIDTH_LIMIT: QOS_RULE_BW_1}
|
||||
match = self.qos_driver._ovn_qos_rule_match(
|
||||
direction, 'port_id', ip_address)
|
||||
direction, 'port_id', ip_address, 'resident_port')
|
||||
expected = {'burst': 100, 'rate': 200, 'direction': 'to-lport',
|
||||
'match': match,
|
||||
'priority': qos_extension.OVN_QOS_DEFAULT_RULE_PRIORITY,
|
||||
|
@ -197,7 +199,7 @@ class TestOVNClientQosExtension(test_plugin.Ml2PluginV2TestCase):
|
|||
expected['external_ids'] = {ovn_const.OVN_FIP_EXT_ID_KEY: fip_id}
|
||||
result = self.qos_driver._ovn_qos_rule(
|
||||
direction, rule, 'port_id', 'network_id', fip_id=fip_id,
|
||||
ip_address=ip_address)
|
||||
ip_address=ip_address, resident_port='resident_port')
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
def test__ovn_qos_rule_ingress(self):
|
||||
|
@ -210,14 +212,15 @@ class TestOVNClientQosExtension(test_plugin.Ml2PluginV2TestCase):
|
|||
direction = constants.EGRESS_DIRECTION
|
||||
rule = {qos_constants.RULE_TYPE_DSCP_MARKING: QOS_RULE_DSCP_1}
|
||||
match = self.qos_driver._ovn_qos_rule_match(
|
||||
direction, 'port_id', ip_address)
|
||||
direction, 'port_id', ip_address, 'resident_port')
|
||||
expected = {'direction': 'from-lport', 'match': match,
|
||||
'dscp': 16, 'switch': 'neutron-network_id',
|
||||
'priority': qos_extension.OVN_QOS_DEFAULT_RULE_PRIORITY}
|
||||
if fip_id:
|
||||
expected['external_ids'] = {ovn_const.OVN_FIP_EXT_ID_KEY: fip_id}
|
||||
result = self.qos_driver._ovn_qos_rule(
|
||||
direction, rule, 'port_id', 'network_id', fip_id, ip_address)
|
||||
direction, rule, 'port_id', 'network_id', fip_id=fip_id,
|
||||
ip_address=ip_address, resident_port='resident_port')
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
rule = {qos_constants.RULE_TYPE_BANDWIDTH_LIMIT: QOS_RULE_BW_2,
|
||||
|
@ -228,7 +231,8 @@ class TestOVNClientQosExtension(test_plugin.Ml2PluginV2TestCase):
|
|||
if fip_id:
|
||||
expected['external_ids'] = {ovn_const.OVN_FIP_EXT_ID_KEY: fip_id}
|
||||
result = self.qos_driver._ovn_qos_rule(
|
||||
direction, rule, 'port_id', 'network_id', fip_id, ip_address)
|
||||
direction, rule, 'port_id', 'network_id', fip_id=fip_id,
|
||||
ip_address=ip_address, resident_port='resident_port')
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
def test__ovn_qos_rule_egress(self):
|
||||
|
|
Loading…
Reference in New Issue